簡體   English   中英

Webpack 和外部庫:ProvidePlugin vs 入口 vs 全局導入?

[英]Webpack and External Libs: ProvidePlugin vs entry vs global import?

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: [...]

當我在這篇 gist 中發現這種方法時,我對它感到有些驚訝,但它也同樣有效。

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

👍 優點

  • 有用。
  • 我可以完全刪除ProvidePlugin()

👎 缺點

  • 需要在 Webpack 配置中跟蹤全局庫。

3.頂級import

這個很簡單,看這個app.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

ProvidePlugin不會在全局上公開jQuery,並且實際上是為了修復錯誤依賴於全局模塊存在的第三方模塊,所以我不建議這樣做,例如

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

有效地轉化為:

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

進入和頂級進口

這些方法不適用於常規的UMD模塊,例如jQuery,因為jQuery足夠智能,在被commonjs / amd / es6識別加載器加載時不會在全局上暴露自己。

然而,這兩種方法對於具有副作用的模塊是理想的,例如babel-polyfill whatwg-fetch / 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'一次import 'jquery' ,然后依賴其他模塊中的全局。

然而,正如我所說的,如果您不需要公開模塊,那么即使您恰好在其他模塊中使用它也是不可取的。

如果您在使用 ProvidePlugin 時在一頁中包含多個包(入口點),只需發現提供的 lib 將被覆蓋。 示例適用於 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 只是在每個入口點導入庫。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM