简体   繁体   English

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

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

Normally in Laravel Mix, we can extract all vendors automatically using mix.extract() or extract a list of vendors using mix.extract(['vue','lodash','axios']) .通常在 Laravel Mix 中,我们可以使用mix.extract()自动提取所有供应商或使用mix.extract(['vue','lodash','axios'])提取供应商列表。 Is there a way to extract all vendors except a few?有没有办法提取除少数供应商之外的所有供应商?

For example, I load Pusher, Echo, Chart.js, etc. when they're needed importing dynamic chunks.例如,当需要导入动态块时,我会加载 Pusher、Echo、Chart.js 等。 However, they're still getting added to my vendor.js file.但是,它们仍然被添加到我的vendor.js文件中。

Also, when extracting a list of specific vendors, I end up with about 20 extra chunks due to sharing common code with names like vendors~js/mychunk1~js/mychunk2~js/mychunk3 .此外,在提取特定供应商列表时,由于与vendors~js/mychunk1~js/mychunk2~js/mychunk3等名称共享通用代码,我最终会得到大约 20 个额外的块。

By inserting a console.log in the Extract.js component inside Laravel Mix, I've found that in my current settings the plugin was just inserting these lines in the optimization field of the Webpack Configuration.通过在 Laravel Mix 内的 Extract.js 组件中插入 console.log,我发现在我当前的设置中,插件只是将这些行插入到 Webpack 配置的优化字段中。

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

In order to filter what was going inside the vendor file I had to edit splitChunks like that:为了过滤供应商文件中的内容,我必须像这样编辑 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',
},

After those changes I still had the weird naming you are experiencing, but thanks to this GitHub repo I discovered that I could remove this behavior by adding:在这些更改之后,我仍然有您遇到的奇怪命名,但是由于这个GitHub 存储库,我发现我可以通过添加以下内容来删除此行为:

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

to the CacheGroups field.到 CacheGroups 字段。

So my complete webpackConfig function argument was:所以我完整的 webpackConfig function 参数是:

.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;
         },
       }
     },
   },
 }
})

Be sure to also remove the extract() call in you mix file.请务必同时删除混音文件中的 extract() 调用。

January 2022 Update 2022 年 1 月更新

From Laravel Mix v6 (released Dec 21, 2020), you can have multiple vendor files:从 Laravel Mix v6(2020 年 12 月 21 日发布)开始,您可以拥有多个供应商文件:

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

These will be automatically loaded by webpack as needed.这些将由 webpack 根据需要自动加载。

You can also use the webpack.IgnorePlugin to specifically remove packages from the final build:您还可以使用webpack.IgnorePlugin从最终版本中专门删除软件包:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM