创建 library 示例

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"
}

参考来源