簡體   English   中英

如何單獨捆綁供應商腳本並根據需要使用Webpack?

[英]How to bundle vendor scripts separately and require them as needed with Webpack?

我正在嘗試做一些我認為應該可行的事情,但我真的無法理解如何從webpack文檔中做到這一點。

我正在編寫一個包含多個模塊的JavaScript庫,這些模塊可能相互依賴或不相互依賴。 最重要的是,jQuery被所有模塊使用,其中一些可能需要jQuery插件。 然后,該庫將用於幾個可能需要部分或全部模塊的不同網站。

定義我的模塊之間的依賴關系非常簡單,但定義他們的第三方依賴關系似乎比我預期的更難。

我想要實現的目標 :對於每個應用程序,我希望有兩個捆綁文件,一個包含必要的第三方依賴項,另一個包含我庫中的必要模塊。

示例 :假設我的庫具有以下模塊:

  • a(需要:jquery,jquery.plugin1)
  • b(要求:jquery,a)
  • c(要求:jquery,jquery.ui,a,b)
  • d(需要:jquery,jquery.plugin2,a)

我有一個應用程序(將其視為唯一的條目文件),需要模塊a,b和c。 此案例的Webpack應生成以下文件:

  • 供應商包 :使用jquery,jquery.plugin1和jquery.ui;
  • 網站包 :模塊a,b和c;

最后,我更喜歡將jQuery作為全局文件,因此我不需要在每個文件上都需要它(例如,我只需要在主文件上使用它)。 並且jQuery插件只是在需要時擴展$ global(如果它們可用於不需要它們的其他模塊則不是問題)。

假設這是可能的,那么這個案例的webpack配置文件的例子是什么? 我在我的配置文件上嘗試了幾種加載器,外部和插件的組合,但我並沒有真正了解他們正在做什么以及我應該使用哪些。 謝謝!

在我的webpack.config.js(版本1,2,3)文件中,我有

function isExternal(module) {
  var context = module.context;

  if (typeof context !== 'string') {
    return false;
  }

  return context.indexOf('node_modules') !== -1;
}

在我的插件數組中

plugins: [
  new CommonsChunkPlugin({
    name: 'vendors',
    minChunks: function(module) {
      return isExternal(module);
    }
  }),
  // Other plugins
]

現在我有一個文件,只根據需要將第三方庫添加到一個文件中。

如果您希望在分離供應商和入口點文件時更精細:

plugins: [
  new CommonsChunkPlugin({
    name: 'common',
    minChunks: function(module, count) {
      return !isExternal(module) && count >= 2; // adjustable
    }
  }),
  new CommonsChunkPlugin({
    name: 'vendors',
    chunks: ['common'],
    // or if you have an key value object for your entries
    // chunks: Object.keys(entry).concat('common')
    minChunks: function(module) {
      return isExternal(module);
    }
  })
]

請注意,插件的順序很重要。

此外,這將在版本4中發生變化。當這是官方的時候,我更新了這個答案。

更新: indexOf為Windows用戶搜索更改

我不確定我是否完全理解你的問題,但由於我最近有類似的問題,我會盡力幫助你。

供應商捆綁。

你應該使用CommonsChunkPlugin 在配置中,您可以指定塊的名稱(例如vendor ),以及將生成的文件名( vendor.js )。

new webpack.optimize.CommonsChunkPlugin("vendor", "vendor.js", Infinity),

現在重要的是,您必須現在指定vendor庫的含義,並在條目部分中執行此操作。 還有一個項目到條目列表,其名稱與新聲明的塊名稱相同(在本例中為“供應商”)。 該條目的值應該是您要移動到vendor包的所有模塊的列表。 在你的情況下,它應該看起來像:

entry: {
    app: 'entry.js',
    vendor: ['jquery', 'jquery.plugin1']
}

JQuery作為全球性的

遇到了同樣的問題並用ProvidePlugin解決了它。 在這里,您不是要定義全局對象,而是模塊化的類型。 即你可以這樣配置:

new webpack.ProvidePlugin({
    $: "jquery"
})

現在你可以在代碼中的任何地方使用$ - webpack會自動將其轉換為

require('jquery')

我希望它有所幫助。 你也可以看看我在這里的 webpack配置文件

我喜歡webpack,但我同意這個文檔並不是世界上最好的文檔...但是嘿..人們在開始時對Angular文檔說了同樣的話:)


編輯:

要使入口點特定的供應商塊多次使用CommonsChunkPlugins:

new webpack.optimize.CommonsChunkPlugin("vendor-page1", "vendor-page1.js", Infinity),
new webpack.optimize.CommonsChunkPlugin("vendor-page2", "vendor-page2.js", Infinity),

然后為不同的文件聲明不同的extenral庫:

entry: {
    page1: ['entry.js'],
    page2: ['entry2.js'],
    "vendor-page1": [
        'lodash'
    ],
    "vendor-page2": [
        'jquery'
    ]
},

如果某些庫在入口點之間重疊(對於大多數庫),那么您可以使用相同的插件將它們提取到公共文件,只是使用不同的配置。 這個例子。

如果您有興趣將自己的腳本與供應商分開自動捆綁:

var webpack = require('webpack'),
    pkg     = require('./package.json'),  //loads npm config file
    html    = require('html-webpack-plugin');

module.exports = {
  context : __dirname + '/app',
  entry   : {
    app     : __dirname + '/app/index.js',
    vendor  : Object.keys(pkg.dependencies) //get npm vendors deps from config
  },
  output  : {
    path      : __dirname + '/dist',
    filename  : 'app.min-[hash:6].js'
  },
  plugins: [
    //Finally add this line to bundle the vendor code separately
    new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.min-[hash:6].js'),
    new html({template : __dirname + '/app/index.html'})
  ]
};

您可以在官方文檔中閱讀有關此功能的更多信息。

還不確定我是否完全理解您的情況,但這里是配置片段為每個捆綁包創建單獨的供應商塊:

entry: {
  bundle1: './build/bundles/bundle1.js',
  bundle2: './build/bundles/bundle2.js',
  'vendor-bundle1': [
    'react',
    'react-router'
  ],
  'vendor-bundle2': [
    'react',
    'react-router',
    'flummox',
    'immutable'
  ]
},

plugins: [
  new webpack.optimize.CommonsChunkPlugin({
    name: 'vendor-bundle1',
    chunks: ['bundle1'],
    filename: 'vendor-bundle1.js',
    minChunks: Infinity
  }),
  new webpack.optimize.CommonsChunkPlugin({
    name: 'vendor-bundle2',
    chunks: ['bundle2'],
    filename: 'vendor-bundle2-whatever.js',
    minChunks: Infinity
  }),
]

並鏈接到CommonsChunkPlugin文檔: httpCommonsChunkPlugin

暫無
暫無

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

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