當我們要打包一個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 項目的名字 ,就可以啦!