从 0 到 1 搭建组件库

目标

本篇的目标是:javascript

  1. 实现项目基本架构
  2. 支持多规范打包
  3. 实现按需加载
  4. 发布 npm 包

搭建项目

  1. 初始化项目目录html

    mkdir lyn-comp-lib && cd lyn-comp-lib && npm init -y
    复制代码
  2. 新建 packages 目录java

    packages 目录为组件目录,组件一个文件夹为单位,一个文件夹为一个组件node

    mkdir packages
    复制代码
  3. 新建 /src/index.jswebpack

    /src/index.js 做为 commonjs 规范的打包入口git

    mkdir src && cd src && touch index.js
    复制代码
  4. 新建 webpack.common.jsgithub

    commonjs 规范的 webpack 配置文件web

    touch webpack.common.js
    复制代码
  5. 新建 webpack.umd.jsshell

    umd 规范的 webpack 配置文件npm

    touch webpack.umd.js
    复制代码
  6. 新建 publish.sh

    负责构建项目 和 发布 npm 包

    touch publish.sh
    复制代码
  7. 安装 webpack、webpack-cli

    npm i webpack webpack-cli -D
    复制代码

项目目录结构

开始编码

目前咱们只是为了验证架构设计,因此只会写一些简单的 demo

组件

在 packages 目录中新建两个目录,做为组件目录

其实这个目录结构参考了 element-ui 组件库,为支持 按需加载 作准备

  1. /packages/hello/src/index.js
// hello function
export default function hello (msg) {
    console.log('hello ', msg)
}
复制代码
  1. /packages/log/src/index.js
// log function
export default function log (str) {
    console.log('log: ', str)
}
复制代码

引入并导出组件

在 /src/index.js 中统一引入项目中的组件并导出

// 当组件变得庞大时这部分可自动生成,element-ui 就是采用自动生成的方式
import hello from '../packages/hello/src/index'
import log from '../packages/log/src/index'

export default {
    hello,
    log
}
复制代码

编写 webpack 配置文件

  1. /webpack.common.js

    const path = require('path')
    
    module.exports = {
        entry: './src/index.js',
        // 使用 开发者 模式,目的是为了一下子的调试,实际开发中可改成 production
        mode: 'development',
        output: {
            path: path.join(__dirname, './lib'),
            filename: 'lyn-comp-lib.common.js',
            // commonjs2 规范
            libraryTarget: 'commonjs2',
            // 将 bundle 中的 window 对象替换为 this,否则会报 window is not defined
            globalObject: 'this',
            // 没有该配置项,组件会挂载到 default 属性下,须要 comp.default.xxx 这样使用,不方便
            libraryExport: 'default'
        }
    }
    复制代码
  2. /webpack.umd.js

const path = require('path')

module.exports = {
    // 实际开发时这部分能够自动生成,可采用 element-ui 的方式
    // 按需加载 须要将入口配置为多入口模式,一个组件 一个入口
    entry: {
        log: './packages/log/src/index.js',
        hello: './packages/hello/src/index.js'
    },
    mode: 'development',
    output: {
        path: path.join(__dirname, './lib'),
        filename: '[name].js',
        // umd 规范
        libraryTarget: 'umd',
        globalObject: 'this',
        // 组件库暴露出来的 全局变量,好比 经过 script 方式引入 bundle 时就可使用
        library: 'lyn-comp-lib',
        libraryExport: 'default'
    }
}
复制代码

package.json

{
    "name": "@liyongning/lyn-comp-lib",
    "version": "1.0.0",
    "description": "从 0 到 1 搭建组件库",
    "main": "lib/lyn-comp-lib.common.js",
    "scripts": {
        "build:commonjs2": "webpack --config webpack.common.js",
        "build:umd": "webpack --config webpack.umd.js",
        "build": "npm run build:commonjs2 && npm run build:umd"
    },
    "keywords": ["组件库", "0 到 1"],
    "author": "Li Yong Ning",
    "files": [
      "lib",
      "package.json"
    ],
    "repository": {
      "type": "git",
      "url": "https://github.com/liyongning/lyn-comp-lib.git"
    },
    ...
}
复制代码

解释

  1. name

    在 包 名称前加本身的 npm 帐户名,采用 npm scope 的方式,包目录的组织方式和普通包不同,并且能够有效的避免和他人的包名冲突

  2. main

    告诉使用程序 ( import hello from '@liyongning/lyn-comp-lib' ) 去哪里加载组件库

  3. script

    构建命令

  4. files

    发布 npm 包时告诉发布程序只将 files 中指定的 文件 和 目录 上传到 npm 服务器

  5. repository

    代码仓库地址,选项不强制,能够没有,不过通常都会提供,和他人共享

构建发布脚本 publish.sh

shell 脚本,负责构建组件库和发布组件库到 npm

#!/bin/bash

echo '开始构建组件库'

npm run build

echo '组件库构建完成,开发发布'

npm publish --access public
复制代码

README.md

一个项目可少的文件,readme.md,负责告诉别人,如何使用咱们的组件库

构建、发布

到这一步,不出意外,开篇定的目标就要完成了,接下来执行脚本,构建和发布组件库,固然发布以前你应该有一个本身的 npm 帐户

sh publish.sh
复制代码

执行脚本过程当中没有报错,并最后出现如下内容,则表示发布 npm 包成功,也能够去 npm 官网 查看

...
npm notice total files:   5                                       
npm notice 
+ @liyongning/lyn-comp-lib@1.0.0
复制代码

测试

接下来咱们新建一个测试项目去实际使用刚才发布的组件库,去验证其是否可用以及是否达到咱们的预期目标

新建项目

  1. 初始化项目目录

    mkdir test && cd test && npm init -y && npm i webpack webpack-cli -D && npm i @liyongning/lyn-comp-lib -S
    复制代码

    查看 日志 或者 package.json 会发现 组件库 已经安装成功,接下来就是使用了

  2. 新建 /src/index.js

    import { hello } from '@liyongning/lyn-comp-lib'
    console.log(hello('lyn comp lib'))
    复制代码
  3. 构建

    npx webpack-cli --mode development
    复制代码

    在 /dist 目录会生成打包后的文件 mian.js,而后在 /dist 目录新建 index.html 文件并引入 main.js,而后在浏览器打开,打开控制台,会发现输出以下内容:

  1. 是否按需加载

    咱们在 /src/index.js 中只引入和使用了 hello 方法,在 main.js 中搜索 hello functionlog function 会发现都能搜到,说明如今是全量引入,接下来根据 使用文档(README.md) 配置按需加载

    从这张图上也能看出,引入是 commonjs 的包,而不是 "./node_modules/@liyongning/lyn-comp-lib/lib/hello.js

  2. 根据组件库的使用文档配置按需加载

    安装 babel-plugin-component

    安装 babel-loader、@babel/core

    npm install --save-dev babel-loader @babel/core
    复制代码
    // webpack.config.js
    const path = require('path')
    
    module.exports = {
      entry: './src/index.js',
      mode: 'development',
      output: {
        path: path.resolve(__dirname, './dist'),
        filename: 'main.js'
      },
      module: {
        rules: [
          {
            test: /\.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader'
          }
        ]
      }
    }
    复制代码

    安装 @babel/preset-env

    {
      "presets": ["@babel/preset-env"],
      "plugins": [
        [
          "component",
          {
            "libraryName": "@liyongning/lyn-comp-lib",
            "style": false
          }
        ]
      ]
    }
    复制代码
6. 配置 package.json 的 script

   ```json
   {
       ...
       scripts: {
           "build": "webpack --config webpack.config.js"
       }
       ...
   }
复制代码
  1. 执行构建命令

    npm run build
    复制代码
  2. 重复上面的第 4 步,会发现打包后的文件只有 hello function,没有 log function

    并且实际的包体积也小了

OK,目标完成!!若有疑问欢迎提问,共同进步

github

相关文章
相关标签/搜索