Shimming

webpack 作为模块打包工具可以支持 ES2015 模块,根据 CommonJS 或者 AMD 规范编写的模块。但是很多时候,当使用第三方 library 的时候,可以看出我们还期望有一些全局依赖,比如对于大家都知道 jquery$。这可能也会创建一些需要被导出的全局变量。在此,我们会看到通过不同的方式去帮助 webpack 支持这些彼此割裂的模块

未压缩的 CommonJS/AMD 文件优先于 dist 打包版本。

多数模块会在 package.jsonmain 字段中链接到 library 的 dist 版本。虽然对多数开发者来说这是有用的,但对于 webpack 来说更好的方式是链接到 src 版本的别名上,因为这样 webpack 能够更好地优化依赖。然而多数情况下 dist 版本也能正常运行。

// webpack.config.js

module.exports = {
    ...
    resolve: {
        alias: {
            jquery: "jquery/src/jquery"
        }
    }
};

ProvidePlugin

ProvidePlugin 可以将模块作为一个变量,被 webpack 在其他每个模块中引用。只有你需要使用此变量的时候,这个模块才会被 require 进来。 多数之前遗留的模块,会依赖于已存在的某些特定全局变量,比如 jQuery 插件中的 $ 或者 jQuery。在这种场景,你可以在每次遇到全局标识符 $ 的时候,在 webpack 中预先设置 var $ = require(“jquery”)

module.exports = {
  plugins: [
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery'
    })
  ]
};

此插件还能够通过使用以下格式,通过配置一个路径数组,提供导出某个模块:[module, child, ...children?]

以下配置将正确从 TypeScript 的 tslib package 包中导入函数 __assign,并将其提供给调用之处。

module.exports = {
  plugins: [
    new webpack.ProvidePlugin({
      __assign: ['tslib', '__assign'],
      __extends: ['tslib', '__extends'],
    })
  ]
};

imports-loader

imports-loader 在引用了之前的遗留模块中,插入必需的全局变量。 例如,某些遗留模块依赖于 this 作为 window 对象,而在 CommonJS 上下文中执行的 this 等同于 module.exports。在这种情况下,你可以使用 imports-loader 来替换重写 this

webpack.config.js

module.exports = {
  module: {
    rules: [{
      test: require.resolve("some-module"),
      use: 'imports-loader?this=>window'
    }]
  }
};

webpack 中的模块支持不同的模块风格,比如AMD, CommonJS 以及之前的遗留模块。然而,通常会先检查 define,然后使用一些比较怪异的代码来导出属性。在这些情况下,可以通过设置 define = false,有助于强制使用 CommonJS 路径:

webpack.config.js

module.exports = {
  module: {
    rules: [{
      test: require.resolve("some-module"),
      use: 'imports-loader?define=>false'
    }]
  }
};

exports-loader

比如说,一个 library 创建了一个全局变量,它期望使用者通过全局变量去使用;在这种情况下,我们能够使用 exports-loader,将全局变量导出为 CommonJS 格式。比如,为了将 file 导出为 file 以及将 helpers.parse 导出为 parse

webpack.config.js

module.exports = {
  module: {
    rules: [{
      test: require.resolve("some-module"),
      use: 'exports-loader?file,parse=helpers.parse'
      // 在文件的源码中加入以下代码
      //  exports["file"] = file;
      //  exports["parse"] = helpers.parse;
    }]
  }
};

script-loader

script-loader 在全局上下文中执行代码,如同你在 script 标签中加入代码。在这种模式下,普通的 library 都能够正常运行。访问 require, module 等变量则是 undefined。

文件作为字符串添加到 bundle 中。它不会被 webpack 压缩,因此如果使用了一个压缩后的版本,没有开发工具支持调试此 loader 添加的 library。

假设你有一个 legacy.js 文件包含……

GLOBAL_CONFIG = {};

...使用 script-loader...

require('script-loader!legacy.js');

...基本上会生成:

eval("GLOBAL_CONFIG = {};");

noParse 选项

当模块没有 AMD/CommonJS 的版本时,并且你希望直接引入 dist版本,你可以将这个模块标记为 noParse。然后 webpack 将会直接引入这个模块并且不会解析它,这样可以用来改善构建时间。

任何用到 AST 特性(比如 ProvidePlugin)都不会工作。

module.exports = {
  module: {
    noParse: /jquery|backbone/
  }
};

Node 内置

Node 内置(如 process),可以直接从配置文件(configuration file)进行正确的 polyfill,而无需使用任何专门的 loader 或插件。有关更多信息和示例,请查看node 配置页面


原文:https://webpack.js.org/guides/shimming/

results matching ""

    No results matching ""