libraryTarget
var:作为一个全局变量,通过 script 标签来访问(libraryTarget:’var’)。 this:通过 this 对象访问(libraryTarget:’this’)。 window:通过 window 对象访问,在浏览器中(libraryTarget:’window’)。 UMD:在 AMD 或 CommonJS 的 require 之后可访问(libraryTarget:’umd’)。
webpack.config.js
var path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'webpack-numbers.js',
library: 'webpackNumbers',
libraryTarget: 'umd'
},
externals: {
lodash: {
commonjs: 'lodash',
commonjs2: 'lodash',
amd: 'lodash',
root: '_'
}
}
};
index.js
import _ from 'lodash';
export function wordToNum(word) {
...
};
生成库的使用方式
// ES2015 模块引入
import * as webpackNumbers from 'webpack-numbers';
// CommonJS 模块引入
var webpackNumbers = require('webpack-numbers');
// ...
// ES2015 和 CommonJS 模块调用
webpackNumbers.wordToNum('Two');
// ...
// AMD 模块引入
require(['webpackNumbers'], function ( webpackNumbers) {
// ...
// AMD 模块调用
webpackNumbers.wordToNum('Two');
// ...
});
library
output.library 的值的作用,取决于output.libraryTarget 选项的值;
注意,output.libraryTarget 的默认选项是 var,所以如果使用以下配置选项:
output: {
library: "MyLibrary"
}
如果生成的输出文件,是在 HTML 页面中作为一个 script 标签引入,则变量 MyLibrary 将与入口文件的返回值绑定。
libraryTarget
配置如何暴露 library。可以使用下面的选项中的任意一个。注意,此选项与分配给 output.library 的值一同使用。 注意,下面的示例代码中的 entry_return 是入口起点返回的值。 在 bundle 本身中,它是从入口起点、由 webpack 生成的函数的输出结果。 对于下面的所有示例,都假定将 output.library 的值配置为 MyLibrary。
暴露为一个变量
当使用此选项时,将 output.library 设置为空,会因为没有变量导致无法赋值。
var MyLibrary = _entry_return_;
// 在一个单独的 script……
MyLibrary.doSomething();
通过在对象上赋值暴露
这些选项将入口起点的返回值(例如,入口起点的任何导出值)赋值给一个特定对象的属性(此名称由 output.library 定义)下。
如果 output.library 未赋值为一个非空字符串,则默认行为是,将入口起点返回的所有属性都赋值给一个对象(此对象由 output.libraryTarget 特定),通过如下代码片段:
(function(e, a) { for(var i in a) e[i] = a[i]; }(${output.libraryTarget}, _entry_return_)
libraryTarget: "this" - 入口起点的返回值将分配给 this 的一个属性(此名称由 output.library 定义)下,this 的含义取决于你:
this["MyLibrary"] = _entry_return_;
// 在一个单独的 script……
this.MyLibrary.doSomething();
MyLibrary.doSomething(); // 如果 this 是 window
libraryTarget: "window" - 入口起点的返回值将使用 output.library 中定义的值,分配给 window 对象的这个属性下。
window["MyLibrary"] = _entry_return_;
window.MyLibrary.doSomething();
libraryTarget: "global" - 入口起点的返回值将使用 output.library 中定义的值,分配给 global 对象的这个属性下。
global["MyLibrary"] = _entry_return_;
global.MyLibrary.doSomething();
libraryTarget: "commonjs" - 入口起点的返回值将使用 output.library 中定义的值,分配给 exports 对象。这个名称也意味着,模块用于 CommonJS 环境:
exports["MyLibrary"] = _entry_return_;
require("MyLibrary").doSomething();
模块定义系统
这些选项将导致 bundle 带有更完整的模块头部,以确保与各种模块系统的兼容性。根据 output.libraryTarget 选项不同,output.library 选项将具有不同的含义。
libraryTarget: "commonjs2" - 入口起点的返回值将分配给 module.exports 对象。这个名称也意味着模块用于 CommonJS 环境:
module.exports = _entry_return_;
require("MyLibrary").doSomething();
注意,output.library 会被省略,因此对于此特定的 output.libraryTarget,无需再设置 output.library 。
libraryTarget: "amd" - 将你的 library 暴露为 AMD 模块。
AMD 模块要求入口 chunk(例如使用 <script> 标签加载的第一个脚本)通过特定的属性定义,例如 define 和 require,它们通常由 RequireJS 或任何兼容的模块加载器提供(例如 almond)。否则,直接加载生成的 AMD bundle 将导致报错,如 define is not defined。
所以,使用以下配置……
output: {
library: "MyLibrary",
libraryTarget: "amd"
}
生成的 output 将会使用 "MyLibrary" 作为模块名定义,即
define("MyLibrary", [], function() {
return _entry_return_; // 此模块返回值,是入口 chunk 返回的值
});
可以在 script 标签中,将 bundle 作为一个模块整体引入,并且可以像这样调用 bundle:
require(['MyLibrary'], function(MyLibrary) {
// 使用 library 做一些事……
});
如果 output.library 未定义,将会生成以下内容。
define([], function() {
return _entry_return_; // 此模块返回值,是入口 chunk 返回的值
});
如果直接加载 <script> 标签,此 bundle 无法按预期运行,或者根本无法正常运行(在 almond loader 中)。只能通过文件的实际路径,在 RequireJS 兼容的异步模块加载器中运行,因此在这种情况下,如果这些设置直接暴露在服务器上,那么 output.path 和 output.filename 对于这个特定的设置可能变得很重要。
libraryTarget: "umd" - 将你的 library 暴露为所有的模块定义下都可运行的方式。它将在 CommonJS, AMD 环境下运行,或将模块导出到 global 下的变量。了解更多请查看 UMD 仓库。
在这个例子中,你需要 library 属性来命名你的模块:
output: {
library: "MyLibrary",
libraryTarget: "umd"
}
最终输出如下:
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["MyLibrary"] = factory();
else
root["MyLibrary"] = factory();
})(typeof self !== 'undefined' ? self : this, function() {
return _entry_return_; // 此模块返回值,是入口 chunk 返回的值
});
注意,省略 library 会导致将入口起点返回的所有属性,直接赋值给 root 对象,就像对象分配章节。例如:
output: {
libraryTarget: "umd"
}
输出结果如下:
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else {
var a = factory();
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
}
})(typeof self !== 'undefined' ? self : this, function() {
return _entry_return_; // 此模块返回值,是入口 chunk 返回的值
});
从 webpack 3.1.0 开始,你可以将 library 指定为一个对象,用于给每个 target 起不同的名称:
output: {
library: {
root: "MyLibrary",
amd: "my-library",
commonjs: "my-common-library"
},
libraryTarget: "umd"
}