在 Laravel Mix 中,是否可以提取除软件包列表之外的所有供应商?

In Laravel Mix, is it possible to extract all vendors except a list of packages?

通常在Laravel Mix中,我们可以使用自动提取所有供应商 mix.extract() 或使用 mix.extract(['vue','lodash','axios']) 提取供应商列表。有没有办法提取除少数供应商之外的所有供应商?

例如,当需要导入动态块时,我会加载 Pusher、Echo、Chart.js 等。但是,它们仍在添加到我的 vendor.js 文件中。

此外,在提取特定供应商的列表时,由于使用 vendors~js/mychunk1~js/mychunk2~js/mychunk3.

等名称共享通用代码,我最终得到了大约 20 个额外的块

通过在 Laravel Mix 的 Extract.js 组件中插入 console.log,我发现在我当前的设置中,插件只是将这些行插入到优化字段中Webpack 配置。

optimization: {
  runtimeChunk: { name: '/js/manifest' },
  splitChunks: {
    cacheGroups: {},
    chunks: 'all',
    name: '/js/vendor',
  },
},

为了过滤供应商文件中的内容,我不得不像这样编辑 splitChunks:

splitChunks: {
  cacheGroups: {
    vendor: {
      // moved name and chunks here
      name: 'js/vendor',
      chunks: 'all',
        // you can pass a RegExp to test, but also a function
        test(module/* , chunk */) {
          if (module.context) {
            // node_modules are needed
            const isNodeModule = module.context.includes('node_modules');
            // but only specific node_modules
            const nodesToBundle = [
             'vue',
             'lodash',
             'axios',
            ].some(str => module.context.includes(str));
            if (isNodeModule && nodesToBundle) {
              return true;
            }
         }
         return false;
       },
     }
  },
  // removed name and chunks from here  
  // chunks: 'all',
  // name: '/js/vendor',
},

在这些更改之后,我仍然遇到您遇到的奇怪命名,但是由于这个 GitHub repo 我发现我可以通过添加以下内容来删除此行为:

default: false, // disable default groups
vendors: false, // disable vendors group

到 CacheGroups 字段。

所以我完整的 webpackConfig 函数参数是:

.webpackConfig({
  output: {
    // with other settings
  },
  optimization: {
    runtimeChunk: { name: '/js/manifest' },
    splitChunks: {
      cacheGroups: {
        default: false,
        vendors: false,
        vendor: {
          name: 'js/vendor',
          chunks: 'all',
          // you can pass a RegExp to test, but also a function
          test(module/* , chunk */) {
            if (module.context) {
              // node_modules are needed
              const isNodeModule = module.context.includes('node_modules');
              // but only specific node_modules
              const nodesToBundle = [
                'vue',
                'lodash',
                'axios',
              ].some(str => module.context.includes(str));
              if (isNodeModule && nodesToBundle) {
                return true;
              }
           }
           return false;
         },
       }
     },
   },
 }
})

确保同时删除混合文件中的 extract() 调用。

2022 年 1 月更新

从 Laravel Mix v6(2020 年 12 月 21 日发布)开始,您可以拥有多个供应商文件:

mix.extract(['vue','lodash','axios'], 'vendor-main.js');
mix.extract(); // everything else

这些将根据需要由 webpack 自动加载。

您还可以使用 webpack.IgnorePlugin 从最终版本中专门删除包:

const webpack = require('webpack')
mix.webpackConfig({
    optimization: {
        splitChunks: {chunks: 'all'}
    },
    plugins: [
        // Ignore unnecessary package modules
        new webpack.IgnorePlugin({
            resourceRegExp: /^\.\/locale$/,
            contextRegExp: /moment$/,
        })
    ]
});