外部扩展(externals)

externals 配置选项提供了「从输出的 bundle 中排除依赖」的方法。相反,所创建的 bundle 依赖于那些存在于用户环境(consumer’s environment)中的依赖。此功能通常对 library 开发人员来说是最有用的,然而也会有各种各样的应用程序用到它。

用户(consumer),在这里是指,引用了「使用 webpack 打包的 library」的所有终端用户的应用程序(end user application)。

externals

string object function regex

防止将某些 import 的包(package)打包到 bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖(external dependencies)

例如,从 CDN 引入 jQuery,而不是把它打包:

index.html

  1. <script
  2. src="https://code.jquery.com/jquery-3.1.0.js"
  3. integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="
  4. crossorigin="anonymous">
  5. </script>

webpack.config.js

  1. module.exports = {
  2. //...
  3. externals: {
  4. jquery: 'jQuery'
  5. }
  6. };

这样就剥离了那些不需要改动的依赖模块,换句话,下面展示的代码还可以正常运行:

  1. import $ from 'jquery';
  2. $('.my-element').animate(/* ... */);

具有外部依赖(external dependency)的 bundle 可以在各种模块上下文(module context)中使用,例如 CommonJS, AMD, 全局变量和 ES2015 模块。外部 library 可能是以下任何一种形式:

  • root:可以通过一个全局变量访问 library(例如,通过 script 标签)。
  • commonjs:可以将 library 作为一个 CommonJS 模块访问。
  • commonjs2:和上面的类似,但导出的是 module.exports.default.
  • amd:类似于 commonjs,但使用 AMD 模块系统。

可以接受各种语法……

string

请查看上面的例子。属性名称是 jquery,表示应该排除 import $ from 'jquery' 中的 jquery 模块。为了替换这个模块,jQuery 的值将被用来检索一个全局的 jQuery 变量。换句话说,当设置为一个字符串时,它将被视为全局的(定义在上面和下面)。

array

  1. module.exports = {
  2. //...
  3. externals: {
  4. subtract: ['./math', 'subtract']
  5. }
  6. };

subtract: ['./math', 'subtract'] 转换为父子结构,其中 ./math 是父模块,而 bundle 只引用 subtract 变量下的子集。

object

An object with { root, amd, commonjs, ... } is only allowed for libraryTarget: 'umd'. It’s not allowed for other library targets.

  1. module.exports = {
  2. //...
  3. externals : {
  4. react: 'react'
  5. },
  6. // 或者
  7. externals : {
  8. lodash : {
  9. commonjs: 'lodash',
  10. amd: 'lodash',
  11. root: '_' // 指向全局变量
  12. }
  13. },
  14. // 或者
  15. externals : {
  16. subtract : {
  17. root: ['math', 'subtract']
  18. }
  19. }
  20. };

此语法用于描述外部 library 所有可用的访问方式。这里 lodash 这个外部 library 可以在 AMD 和 CommonJS 模块系统中通过 lodash 访问,但在全局变量形式下用 _ 访问。subtract 可以通过全局 math 对象下的属性 subtract 访问(例如 window['math']['subtract'])。

function

对于 webpack 外部化,通过定义函数来控制行为,可能会很有帮助。例如,webpack-node-externals 能够排除 node_modules 目录中所有模块,还提供一些选项,比如白名单 package(whitelist package)。

基本配置如下:

  1. module.exports = {
  2. //...
  3. externals: [
  4. function(context, request, callback) {
  5. if (/^yourregex$/.test(request)){
  6. return callback(null, 'commonjs ' + request);
  7. }
  8. callback();
  9. }
  10. ]
  11. };

'commonjs'+ request 定义了需要外部化的模块类型。

regex

匹配给定正则表达式的每个依赖,都将从输出 bundle 中排除。

  1. module.exports = {
  2. //...
  3. externals: /^(jquery|\$)$/i
  4. };

这个示例中,所有名为 jQuery 的依赖(忽略大小写),或者 $,都会被外部化。

Combining syntaxes

Sometimes you may want to use a combination of the above syntaxes. This can be done in the following manner:

  1. module.exports = {
  2. //...
  3. externals: [
  4. {
  5. // String
  6. react: 'react',
  7. // Object
  8. lodash : {
  9. commonjs: 'lodash',
  10. amd: 'lodash',
  11. root: '_' // indicates global variable
  12. },
  13. // Array
  14. subtract: ['./math', 'subtract']
  15. },
  16. // Function
  17. function(context, request, callback) {
  18. if (/^yourregex$/.test(request)){
  19. return callback(null, 'commonjs ' + request);
  20. }
  21. callback();
  22. },
  23. // Regex
  24. /^(jquery|\$)$/i
  25. ]
  26. };

关于如何使用此 externals 配置的更多信息,请参考如何编写 library


贡献人员

byzyk byzyk fadysamirsadek fadysamirsadek pksjce pksjce skipjack skipjack sokra sokra zefman zefman