Library 的打包基礎

當我們要打包一個Library 的時候,比如組件庫或者函數庫的時候,就不是像之前那樣的打包方式了。這裏我們就來試試Library 的打包。

這裏我們來做一個函數庫的打包。

先初始化一個項目(node 項目)

初始化:新建一個文件夾,然後進入這個文件夾 運行命令 npm init -y 然後就可以初始化一個node 項目啦!

初始化後,會在項目跟目錄下,新建一個package.json 文件。內容如下。

{
  "name": "myLibrary",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

我們可以將liscense 改爲MIT,test 這兒暫時不用也可以去掉。

{
  "name": "myLibrary",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
  },
  "keywords": [],
  "author": "",
  "license": "MIT"
}

接下來,我們創建庫代碼。首先,在項目跟目錄下創建目錄src 。然後在src 下創建 math.js , string.js 。

下面是math.js 代碼

export function add (a, b) {
    return a + b
}

export function minus (a, b) {
    return a - b
}

export function multiply (a, b) {
    return a * b
}

export function devision (a, b) {
    return a / b
}

下面是string.js 代碼

export function join(a, b) {
    return a + ' ' + b
}

然後,在項目src 下新建文件 index.js。它是一個公共入口文件。如下。

import * as math from './math'
import * as string from './string'

export default {
    math,
    string
}

下面,開始對這個庫對打包。

首先,我們在項目中安裝webpack 和 webpack-cli

npm install webpack webpack-cli --save

同時,我們在項目中創建一個webpack 的配置文件 webpack.config.js (在項目跟目錄下)

並在package.json 的script 中加入webpack 的命令,如下。

  "scripts": {
    "build": "webpack"
  },

接下來,我們來配置一下webpack 配置文件 webpack.config.js 如下。

const path = require('path')

module.exports = {
    mode: 'production',
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'library.js'
    }
}

然後,我們去運行打包命令。如下生成了 library.js 文件。

如果這是我們的業務代碼,那麼打包到這兒就結束了,但是,我們這兒是一個庫。

外部引入我們的庫:

// 可能使用 ES6 的導入
import library from 'library'

// 可能使用Common JS 導入
const library = require('library')

// 可能使用AMD 方式導入
// ...

如果我們想要我們的庫在外部能正常引用,我們可以在打包的時候做一個配置。在webpack.config.js 中output 配置項中加入‘libraryTarget’ 項,值爲‘umd’。

    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'library.js',
        'libraryTarget': 'umd'
    }

這樣,就能使打包的代碼,對import , require, AMD 的引入方式都能正常運行。

當然,也許還想使用 script 標籤引入這個庫,並通過一個全局變量來使用庫。如下。

<script src="library.js"></script>
<script>
  library.xxx
</script>

這種需求,同樣也可以在webpack 中配置就能達到。在webpack 的output 中配置 ‘library’ 項,值爲‘library’(當使用script 標籤引入後,會創建一個全局變量標誌符爲 library )。如下。

const path = require('path')

module.exports = {
    mode: 'production',
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'library.js',
        library: 'library',
        libraryTarget: 'umd'
    }
}

運行打包命令即可。

我們在項目的dist 目錄下新建一個test.html 如下。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./library.js"></script>
</head>
<body>

</body>
</html>

然後在瀏覽器中打開頁面,在控制檯,我們輸出library 就會發現如下內容了!

上面,我們使用了兩個配置項 output.library, output.libraryTarget 。有時,這兩項是配合着使用的。output.library 是核心,意思是要打包生成一個全局變量,output.libraryTarget 是指這個全局變量掛在哪裏。如果是libraryTarget 是‘umd’,那麼它倆是沒什麼關係的。但如果output.libraryTarget 是‘this’,首先就不支持ES6, Common JS,AMD 方式的引入了,然後library 被掛載到全局的 this 上。

如下。

const path = require('path')

module.exports = {
    mode: 'production',
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'library.js',
        library: 'library',
        libraryTarget: 'this'
    }
}

我們打包,然後重新刷新頁面,在控制檯中輸出this.library (這兒的this 就是window)還是可以看見上面的內容。

libraryTarget 除了‘umd’ / 'this' 外,還可以配置爲 ‘window’ / ‘global’(node中)

一般來說,我們做一個一般的庫,只需配置爲‘umd’, 然後library 取一個想叫的名字就可以了。

下面,我們再看一種情況。在src/string.js 中,我們想使用lodash 的join 來改寫之前的join。那麼應該怎樣更好地打包呢?

先我們在項目中下載lodash 庫。(npm install lodash --save)

我們把string.js 改寫爲如下。

import _ from 'lodash'

export function join(a, b) {
    return _.join([a,b], ' ')
}

運行打包命令,發現打包生成的文件,有71 KB。

而且,如果當外部需要引用我們的庫,同時也要引入lodash 庫在業務代碼中,那麼最終用戶的代碼裏面,就很可能存在兩份lodash 代碼,爲了解決這個問題,我們需要在我們的庫裏面做另外一個配置:externals 。它的值可以是數組或者對象。

const path = require('path')

module.exports = {
    mode: 'production',
    entry: './src/index.js',
    externals: ['lodash'],
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'library.js',
        library: 'library',
        libraryTarget: 'umd'
    }
}

運行打包命令,我們會發現,這時候打包後的代碼又變爲了1.6KB 了!

這是因爲externals:['lodash'] 意味着,打包過程中如果遇到 lodash 庫就直接忽略,不要將它打包到代碼裏。這也意味着,當在外部引入library 時,要使用join 方法就必須在外部引入lodash 庫。

externals 還可以配置爲對象。參考 webpack 官網 documentatone > configuration > externals

 https://webpack.js.org/configuration/externals/

一般來說,設置成如下這種即可。(在外部引用的時候,把lodash 引入 並指定引用名爲lodash)

const path = require('path')

module.exports = {
    mode: 'production',
    entry: './src/index.js',
    externals: {
        lodash: 'lodash'
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'library.js',
        library: 'library',
        libraryTarget: 'umd'
    }
}

當然,做一個大型的庫的打包配置,這些肯定是不夠的,還需要配置 按需加載,tree-shaking ...

佔坑,以後再來填。

先把流程走下去先。

下面,我們要將package.json 中的配置改一改了。我們把入口“main”改爲‘./dist/library.js’ 如下。

{
  "name": "myLibrary",
  "version": "1.0.0",
  "description": "",
  "main": "./dist/library.js",
  "scripts": {
    "build": "webpack"
  },
  "keywords": [],
  "author": "",
  "license": "MIT",
  "dependencies": {
    "lodash": "^4.17.15",
    "webpack": "^4.39.3",
    "webpack-cli": "^3.3.7"
  }
}

接下來,我們需要一個npm 賬號,可以在npm 官網註冊。

然後在命令行輸入

npm adduser

然後,輸入,它要求輸入的信息(用戶名與密碼)

然後,成功後,進入庫項目的目錄,運行命令

npm publish

就可以直接把項目發佈到npm 倉庫中去。

其他人要使用就可以直接npm install 項目的名字 ,就可以啦!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章