前言
虽然先前有过使用 webpack 构建包的经验,但是最近同事问我 library 相关知识时,还是支支吾吾答不上来。想了想,知其然而不知其所以然,这和没学没有什么区别啊。所以,经过一番努力,总结了一点关于 library 的知识,这里就做个笔记,以做备忘吧。
配置目的
在开发 npm 库时,我们有时候需要考虑配置多场景的引入方式,比如: AMD、CommonJS、ES6 Moudule、NodeJs/Window 等等。那么为了能够支持这么些引入方式,library 便是 webpack 为我们提供的简化打包策略的方法,使用 library 的配置方式可以让我们专注于 ES6 的写法,而编译部分就不做过多考虑了。
由于 ECMAScript 越来越普及,此处仅介绍 ECMAScript 模块语法配置需要注意的问题。
文件配置
单文件配置
单文件 library 的配置就非常简单了,官方就有很好的例子,这里就先贴一下:
1 | var path = require('path'); |
对于如今的项目来说,如果不是对引入方式有特别要求,建议使用 umd 方式;如果有明确指定环境时,再换成对应配置即可。
多文件配置
多文件配置唯一注意的是文件的引入,以及默认 library 名同样需要设置成动态的。
1 | var path = require('path'); |
属性详解
其实配置什么的,随便在网上查查,再根据自身的理解尝试,都能有所成效。但是知其然我们也得知其所以然,这里我们就看看大家所关注的 library、libraryTarget、libraryExport 此三属性吧。
library
library 可设置的类型有两种,分别是:string
和 object
。
当我们需要对不同环境设置不太一样的导出名时,我们才可能用到 object
,例如:
1 | // 仅此三属性 |
自测 demo 结果展示:
1 | (function e(t, n) { |
否则直接使用 string 模式即可。
注意,library 对象模式必须设置 libraryTarget 为 umd 模式;此外 library 名称最好使用驼峰式,毕竟生成的是变量。
疑问: umd 模式无论如何配置 amd,打包出的内容 amd 部分基本都是 define([], n);
,即使配置成驼峰式的值,此外官方的例子上也没有对应值,不清楚是什么问题;但 amd 模式单独打包则有对应的配置名称。
此 amd 的配置与 amd-require 的结果很相似。
libraryTarget
libraryTarget
属性主要配置如何暴露我们的 library
名。其支持的值如下:
变量类型:
- var(默认)
- assign(产生隐含的全局变量,慎用)
对象类型:
- this(绑定至 this 对象上)
- window(浏览器环境的全局对象 )
- global(node 环境的全局对象)
- commonjs(绑定至 export 对象)
- self(绑定至 self 对象)
模块类型:
- amd(amd 引入模式)
- umd(多模式并存)
- commonjs-module(module.exports)
- commonjs2(commonjs-module 的模块导出 + commonjs 对象,会忽略 library 名)
- amd-require(立即加载版的 amd,会忽略 library 名)
- system(systemJs 引入)
- umd2
其他类型:
- jsonp(library 为名的 jsonp 容器)
一般根据情况选取合适的 target 方式,通常来看 umd 已经能解决绝大多数通用的引入模式了。
umd2 结果和 umd 貌似差不多,个人暂未找到相应的解释
libraryExport
该属性主要是用于配置经由 libraryTarget
公开那些模块,默认为 undefined
。
默认情况下(假设 libraryTarget
为 var
),变量导出的格式为:
1 | var MyDefaultModule = _entry_return_; |
如果需要显示表明导出哪些模块,我们可以这么配置:
1 | // 指定模块 |
一般并不需要配置此属性,有一种情况是:当我们使用 ES6 编写模块时,有时候打包生成的文件在引入时,其内容呈现为:
1 | { |
毕竟 ES6 的 export default
其 default
严格上来说也是一个变量名,因此为了修复此问题,我们可以配置 libraryExport: 'default'
,将默认导出分配给库目标
测试例子
该部分内容还是自己动手,配合官方文档理解起来会更快,可以拷贝该 测试 Demo 进行尝试。