Webpack将我的文件打包成错误的顺序(CommonsChunkPlugin)

30

我想通过Webpack的CommonsChunkPlugin按特定顺序捆绑我的JavaScript供应商文件。

我正在使用Webpack的CommonsChunkPlugin官方文档的用法很简单明了,它可以正常工作,但我认为该插件按字母顺序捆绑我的文件(可能是错误的)。该插件没有选项来指定它们应该被捆绑的顺序。

注意:对于不熟悉Bootstrap 4的人来说,它当前需要一个名为Tether的JavaScript库依赖项。在加载Bootstrap之前必须加载Tether。

webpack.config.js

module.exports = {
  entry: {
    app: './app.jsx',
    vendor: ['jquery', 'tether', 'bootstrap', 'wowjs'],
  },

  output: {
    path: __dirname + '/dist',
    filename: 'bundle.js',
  },

  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
        name: 'vendor',
        filename: 'vendor.bundle.js'
    }),

    new webpack.optimize.UglifyJsPlugin(),
  ],
};

这里发生了两件事情:
  1. vendor.bundle.js 包含 bootstrap, jquery, tether, wowjs
  2. bundle.js 包含我应用的其余部分
打包顺序:
正确: jquery, tether, bootstrap, wowjs
错误: bootstrap, jquery, tether, wowjs 请注意,在我的 webpack.config.js 文件中,我按照正确的顺序排列它们,但是它们被捆绑在了 错误 的顺序中。无论我随机重新排列它们,结果都是相同的。
在使用 Webpack 构建我的应用程序后,vendor.bundle.js 显示了错误的顺序。
我知道它们被捆绑在错误的顺序中,因为 Chrome 开发工具告诉我存在依赖问题。当我通过该工具和我的 IDE 查看文件时,它们被捆绑在错误的顺序中。

我的另一种方法也遇到了同样的问题

我还尝试在我的入口文件(在此例中为app.jsx)中使用importrequire,没有使用CommonChunkPlugin,不知何故这也按字母顺序加载我的JavaScript库。

webpack.config.js

module.exports = {
  entry: './app.jsx',

  output: {
    path: __dirname + '/dist',
    filename: 'bundle.js',
  },

  plugins: [
    new webpack.optimize.UglifyJsPlugin(),
  ],
};

app.jsx (入口)

import './node_modules/jquery/dist/jquery.min';
import './node_modules/tether/dist/js/tether.min';
import './node_modules/bootstrap/dist/js/bootstrap.min';
import './node_modules/wowjs/dist/wow.min';

或者

require('./node_modules/jquery/dist/jquery.min');
require('./node_modules/tether/dist/js/tether.min');
require('./node_modules/bootstrap/dist/js/bootstrap.min');
require('./node_modules/wowjs/dist/wow.min');

结果?
Bootstrap > jQuery > Tether > wowjs


如何按正确顺序加载供应商文件?

字母顺序是否有错?这是有意为之,以便顺序不影响内容。“因为Chrome Dev. Tools告诉我存在依赖问题。”--- 有关此事的详细信息是什么? - zerkms
3
如果按字母顺序排序,会出现很大的问题。其中一个问题是 Bootstrap 要求在它之前加载 jQuery 和 Tether,否则它无法正常运行。 - Ollie Cee
捆绑包中的放置顺序不会以任何方式影响它们在运行时的加载顺序。你遇到的问题是由其他原因引起的。 - zerkms
我有同样的问题,但是我该如何理解我的软件包加载顺序? - Vegas97
4个回答

20

成功!

webpack.config.js

module.exports = {
  entry: {
    app: './app.jsx',
    vendor: [
        "script-loader!uglify-loader!jquery",
        "script-loader!uglify-loader!tether",
        "script-loader!uglify-loader!bootstrap",
        "script-loader!uglify-loader!wowjs",
    ]
  },

  output: {
    path: __dirname + '/dist',
    filename: 'bundle.js',
  },

  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
        name: 'vendor',
        filename: 'vendor.bundle.js'
    }),

    new webpack.optimize.UglifyJsPlugin(),
  ],
};

这里发生了什么神奇的事情?

  1. Webpack通过压缩和捆绑我的供应商文件创建vendor.bundle.js,这些文件现在在全局上下文中执行。
  2. Webpack创建包含所有应用程序代码的bundle.js

入口文件 (在这种情况下为app.jsx)

import './script';

这个脚本仅仅是使用了jQuery,Bootstrap,Tether和wowjs的自定义JavaScript。它在vendor.bundle.js之后执行,使其能够成功运行。

我在尝试执行我的script.js时犯了一个错误,我认为它必须处于全局上下文中。因此,我像这样使用script-loader导入它:import './script-loader!script';。最终,你不需要这样做,因为如果你通过入口文件导入,它最终会出现在捆绑文件中。


一切都很好。

感谢@Ivan提供的script-loader建议。我还注意到CommonsChunkPlugin正在拉取非最小化的供应商版本,所以我在过程中链接了uglify-loader

虽然,我相信一些.min.js被创建得与众不同,以消除额外的膨胀。虽然这是我要解决的问题。谢谢!


我有同样的问题,但是我该如何理解我的软件包以哪种顺序加载?@itamar 和 Ollie Cee - Vegas97

8

有趣的是,我使用了 script-loader,但它将所有内容都捆绑在一起了。我决定 git clone 不同的 React 样板和示例来测试 script-loaderCommonsChunkPluginimport / require 语句,但它们都遇到了同样的问题。 - Ollie Cee
所以我严格使用了script-loader,它确实有效,但最后的结果是一个包含所有JS的捆绑文件。我希望避免只有一个大文件,因为通过异步加载2个小文件(一个供应商库和一个应用程序)会更理想。我将继续尝试使用script-loader进行拆分/分块,看能否实现这个结果。 - Ollie Cee
2
@OllieCee,将需要定义全局变量并在所有其他包之前单独加载的库制作成单独的捆绑包并不难。当然,您将在其他包中具有隐式(无需 requireimport)依赖项,例如 jquery。 - Ivan
1
更新的链接:https://webpack.js.org/guides/shimming/#other-utilities或者https://webpack.js.org/loaders/script-loader/ - Andrew

2

从官方教程学习并使用htmlWebpackPlugin,将entry键的顺序更改为vendor然后是app

webpack.config.js文件中。

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: {
      vendor: [
          'angular'
      ],
      app: [
          './src/index.js',
          './src/users/users.controller.js',
          './src/users/users.directive.js',
      ]
  },
   plugins: [
       new CleanWebpackPlugin(['dist']),
       new HtmlWebpackPlugin({
           template: './src/index-dev.html'
       }),
       new webpack.NamedModulesPlugin()
  ...
}

现在在生成的 index.html 文件中,我有了正确的顺序。
<script src='vendor.bundle.js'></script>
<script src='app.bundle.js'></scrip

0

这对我有用 https://www.npmjs.com/package/webpack-cascade-optimizer-plugin

const CascadeOptimizer = require('webpack-cascade-optimizer-plugin');

module.exports = {
  entry: {
    app: './app.jsx',
    vendor: ['jquery', 'tether', 'bootstrap', 'wowjs'],
  },

  output: {
    path: __dirname + '/dist',
    filename: 'bundle.js',
  },

  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
        name: 'vendor',
        filename: 'vendor.bundle.js'
    }),

    new webpack.optimize.UglifyJsPlugin(),

    new CascadeOptimizer({
        fileOrder: ['jquery', 'tether', 'bootstrap', 'wowjs']
    })
  ],
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接