Webpack 和外部库:提供插件 vs entry vs 全局导入



1. ProvidePlugin()

看起来像一种常用的方法。有一个要点,展示了如何将whatwg-fetch polyfill包含在Webpack构建中。StackOverflow上的许多答案都在这里和这里使用它。

new webpack.ProvidePlugin({
  '$': 'jquery',
  'jQuery': 'jquery',
  'fetch': 'imports?this=>global!exports?global.fetch!whatwg-fetch'
})

👍 优点

  • 它有效。(如果我遗漏了什么,请更新此列表(

👎 缺点

  • 需要在 Webpack 配置中跟踪全局库。

2. entry: [...]

当我在这个要点中发现这种方法时,我对这种方法有点惊讶,但它也同样有效。

entry: [
    'babel-polyfill',
    'whatwg-fetch',
    'jquery',
    'webpack-hot-middleware/client',
    path.join(process.cwd(), 'app/app.js')
],

👍 优点

  • 它有效。
  • 我可以完全放弃ProvidePlugin()

👎 缺点

  • 需要在 Webpack 配置中跟踪全局库。

3. 顶级import

这个非常简单,请参阅此应用程序.js示例。此文件是 React 应用程序的入口点。

/**
 * app.js
 */
import 'whatwg-fetch';
import 'babel-polyfill';
import 'jquery';

👍 优点

  • 它同样有效。
  • 轻松添加/删除。无需触摸 Webpack 配置。

👎 缺点

  • 看起来这种方法本身不适用于jQuery插件,例如bootstrap.js

观察:在所有三种方法之间,我没有注意到捆绑包大小的任何变化。

有没有一种推荐的方式来处理 Webpack(和 React(的全局库?这些解决方案中的任何一个都会在服务器端渲染方面造成问题吗?

谢谢!

我不建议将库公开为全局库,除非您确实需要它,即模块系统的重点是显式声明依赖项,例如

// app.js
import $ from 'jquery';
$.ajax(...);

如果您确实需要全局 jQuery,因为第三方脚本在您的页面上需要它,或者可能需要在控制台中进行调试,那么这里有一些有关您列出的方法的信息:

提供插件

ProvidePlugin 不会在全局上公开 jQuery,并且真正旨在修复错误地依赖于全局模块存在的第三方模块,所以我不建议这样做,例如

// app.js
$.ajax(...);

有效地转换为:

// app.js
require('jquery').ajax(...);

入门级和顶级导入

这些方法不适用于常规的UMD模块,例如jQuery,因为jQuery足够智能,在由commonjs/amd/es6感知加载器加载时不会在全局上暴露自己。

然而,这两种方法对于具有副作用的模块(例如babel-polyfill/whatwg-fetch(是理想的,因为它们不会导出任何东西,它们本质上会改变全球环境。


因此,我对jQuery的建议是使用旨在全局公开模块导出的expose-loader,例如

// webpack.config.js
{
    module: {
        loaders: [
            test: require.resolve('jquery'),
            loader: 'expose-loader?jQuery!expose-loader?$'
        ]
    }
}

然后,您仍需要在应用代码中导入它:

// app.js
import $ from 'jquery';
$.ajax(...)

但是,如果绝对必要,可以在全局上供页面上的其他脚本访问:

// console
window.$
window.jQuery

注意:从技术上讲,在使用公开加载程序时,您可以在入口点import 'jquery'一次,然后依赖其他模块中的全局。

然而,正如我所说,如果你不需要,即使你碰巧在所有其他模块中使用它,也不太建议公开一个模块。

只要发现提供的lib将被覆盖,如果你在使用ProvidePlugin时在一个页面中包含多个包(入口点(。RoR和Webpacker的例子,但我认为这无关紧要。

例如,您在布局中具有:

  javascript_pack_tag 'application',
                      'metronic'

在配置中,您有:

  environment.plugins.append('Provide', new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery',
      "window.jQuery": "jquery",
      "window.$": "jquery",
      _: 'underscore',
      Handlebars: 'handlebars'
  }));

如果在application.js中你需要改变JQuery的库,那么你将在metronic.js和浏览器中丢失所有这些突变,即使你使用暴露加载器公开JQuery。

如果我错了,请纠正我,可能 ProvidePlugin 只是在每个入口点导入库。

最新更新