Library 的打包基础

本文详细介绍如何使用Node.js和Webpack构建、配置和发布库,包括设置项目结构、使用ES6模块、配置Webpack以支持不同引入方式、使用externals排除第三方依赖以及发布到npm仓库的全过程。

当我们要打包一个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 项目的名字 ,就可以啦!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值