從 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

相關文章
相關標籤/搜索