【问题标题】:Webpack bundles my files in the wrong order (CommonsChunkPlugin)Webpack 以错误的顺序捆绑我的文件 (CommonsChunkPlugin)
【发布时间】:2017-08-16 17:34:00
【问题描述】:

我想要的是通过来自 Webpack 的 CommonsChunkPlugin 以特定顺序捆绑我的 JavaScript 供应商文件。

我正在为 Webpack 使用 CommonsChunkPluginofficial documentation 的用法简单明了。它按预期工作,但我相信插件按字母顺序捆绑我的文件(可能是错误的)。插件没有选项来指定它们应该捆绑的顺序。

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

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 包含 bootstrapjquerytether
  2. bundle.js 包含我的应用程序的其余部分

捆绑顺序:
正确: jquerytetherbootstrapwowjs
错误: bootstrap、@ 987654332@,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 开发工具告诉我存在依赖性问题。” --- 有什么细节吗?
  • @zerkms 好吧,如果按字母顺序完成,会有很大的问题。一个是 Bootstrap 需要先加载 jQuery 和 Tether,否则它无法正常运行。
  • bundle 中的放置顺序不会以任何方式影响它们在运行时加载的顺序。您遇到的问题是由其他原因引起的。
  • 我有同样的问题,但是我怎么知道我的包是按什么顺序加载的?

标签: javascript webpack webpack-2 uglifyjs


【解决方案1】:

成功了!

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 时犯的一个错误是我认为它必须在全局上下文中。所以我用这样的脚本加载器导入它:import './script-loader!script';。最后,您不需要这样做,因为如果您通过入口文件导入,无论如何它都会在捆绑文件中结束。


一切都很好。

感谢@Ivan 的script-loader 建议。我还注意到CommonsChunkPlugin 正在拉取未缩小的供应商版本,因此我将uglify-loader 链接到该过程中。

尽管如此,我确实相信一些 .min.js 的创建方式不同,以消除额外的臃肿。虽然这是我自己想办法。谢谢!

【讨论】:

  • 我有同样的问题,但是我怎么知道我的包是按什么顺序加载的? @itamar 和 Ollie Cee
【解决方案2】:

你可以试试https://webpack.js.org/guides/shimming/#script-loader - 它看起来会在全局上下文中按顺序执行脚本。

【讨论】:

  • 有趣的是,我使用了script-loader,它错误地捆绑了所有内容。我决定 git clone 各种 React 样板和示例来测试 script-loaderCommonsChunkPluginimport / require 语句,但它们都属于同一个问题。
  • 所以我严格使用script-loader,它确实有效,但最终结果是 1 个与我所有的 JS 捆绑在一起的文件。我想避免有 1 个大文件,因为通过异步加载的 2 个小文件(1 个供应商库和 1 个应用程序)会更理想。我将继续尝试使用 script-loader 进行拆分/分块,看看是否可以获得该结果
  • @OllieCee 从必须定义全局变量并在所有其他包之前单独加载的库中制作一个单独的包并不难。当然,您将隐含(没有requireimport)依赖于例如其他捆绑包中的 jquery
【解决方案3】:

使用官方教程中的 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

【讨论】:

    【解决方案4】:

    这对我有用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']
        })
      ],
    };
    

    【讨论】:

      猜你喜欢
      • 2016-08-16
      • 1970-01-01
      • 1970-01-01
      • 2017-02-05
      • 2018-08-23
      • 2019-11-20
      • 2017-01-15
      • 2018-09-09
      • 2018-02-21
      相关资源
      最近更新 更多