8

Webpack 配置是 Vue CLI 设置的一部分(可以使用 进行检查vue inspect)。这是其中的一个相关部分:

  entry: {
    foo: [
      '.../src/foo.js'
    ],
    barWidget: [
      '.../src/barWidget.js'
    ],
  },
  optimization: {
    splitChunks: {
      cacheGroups: {
        vendors: {
          name: 'chunk-vendors',
          test: /[\\/]node_modules[\\/]/,
          priority: -10,
          chunks: 'initial'
        },
        common: {
          name: 'chunk-common',
          minChunks: 2,
          priority: -20,
          chunks: 'initial',
          reuseExistingChunk: true
        }
      }
    },
    ...

HTML 输出为:

<script type="text/javascript" src="/assets/js/chunk-vendors.[HASH].js"></script>
<script type="text/javascript" src="/assets/js/foo.[HASH].js"></script>

<script type="text/javascript" src="/assets/js/chunk-vendors.[HASH].js"></script>
<script type="text/javascript" src="/assets/js/barWidget.[HASH].js"></script>

foo根据需要拥有尽可能多的脚本标签是没有问题的,但barWidget它是应该立即加载的小部件入口点,没有初始块依赖关系。我的意图是barWidget加载一行代码(为此目的可能会禁用哈希):

<script type="text/javascript" src="/assets/js/barWidget.js"></script>

但在当前状态下,如果chunk-vendors省略,则无法加载。

我更喜欢保持vendorscommon块原样,因为它们以合理的方式拆分,并且可以在入口点之间的客户端重用,但我需要barWidget自动加载它依赖的块。一种不太可取的方法是禁用块,但barWidget仅在其他入口点中的块拆分应保持不变。

一种重现它的方法基本上是一个添加了 2 个入口点的新 Vue CLI 项目,或者任何具有类似配置拆分的 Webpack 项目。

这是项目(为了完整性而列出):

包.json

{
  "name": "foobar",
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build"
  },
  "dependencies": {
    "core-js": "^3.6.5",
    "vue": "^3.0.0"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~4.5.0",
    "@vue/cli-service": "~4.5.0",
    "@vue/compiler-sfc": "^3.0.0"
  }
}

vue.config.js

module.exports = {
  pages: {
    foo: {
      entry: 'src/foo.js',
      template: 'public/foo.html',
      filename: 'foo.html'
    },
    barWidget: {
      entry: 'src/barWidget.js',
      template: 'public/barWidget.html',
      filename: 'barWidget.html'
    },
  },
};

公共/foo.html

公共/barWidget.html

<!DOCTYPE html>
<html>
  <body>
    <div id="app"></div>
  </body>
</html>

src/foo.js

import { createApp } from 'vue'
import Foo from './Foo.vue'

createApp(Foo).mount('#app')

Foo.vue

<template>
  <HelloWorld msg="Foo"/>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  components: {
    HelloWorld
  }
}
</script>

src/barWidget.js

import { createApp } from 'vue'
import BarWidget from './BarWidget.vue'

createApp(BarWidget).mount('#app')

BarWidget.vue

<template>
  <HelloWorld msg="Bar widget"/>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  components: {
    HelloWorld
  }
}
</script>
  • 是否可以通过 WebpackbarWidget强制自动加载chunk-vendors.[HASH].js,而无需在使用的地方显式加载barWidget.[HASH].js

  • 是否可以barWidget强制入口点不使用其他初始块(chunk-vendors等)并输出自给自足的barWidget.js捆绑包,而不影响拆分在其他入口点的工作方式?

  • 描述的场景还有其他选择吗?

4

2 回答 2

3

您可以使用函数来过滤块。请参阅此Webpack 问题

vue.confi.js

module.exports = {
  pages: {
    foo: {
      entry: 'src/foo.js',
      template: 'public/foo.html',
      filename: 'foo.html'
    },
    barWidget: {
      entry: 'src/barWidget.js',
      template: 'public/barWidget.html',
      filename: 'barWidget.html',
      chunks: ['barWidget']
    },
  },
  chainWebpack: config => {
    if (process.env.NODE_ENV !== 'test') {
      config.optimization.splitChunks({
        cacheGroups: {
          defaultVendors: {
            name: `chunk-vendors`,
            test: /[\\/]node_modules[\\/]/,
            priority: -10,
            chunks: chunk => chunk.name !== "barWidget"
          },
          common: {
            name: `chunk-common`,
            minChunks: 2,
            priority: -20,
            chunks: 'initial',
            reuseExistingChunk: true
          }
        }
      })
    }
  }
}

请注意pages.barWidget.chunks- 它是必需的,因为否则 HtmlWebpackPlugin 包含供应商块,barWidget.html即使它根本不需要......

结果: 结果

于 2021-04-08T15:34:57.420 回答
3

我认为你想要的是这个webpack 问题回复中描述的内容

回复使用一个函数将特定入口点的依赖项排除在块中:

  optimization: {
    splitChunks: {
      cacheGroups: {
          vendors: {
            // ... your current config, just change the chunks property            

            // Exclude pre-main dependencies going into vendors, as doing so
            // will result in webpack only loading pre-main once vendors loaded.
            // But pre-main is the one loading vendors.
            // Currently undocument feature:  https://github.com/webpack/webpack/pull/6791
            chunks: chunk => chunk.name !== "barWidget"
          }
      }
    }
  },

使用 vue 执行此操作只需更改 vue.config.js 文件中的 webpack 配置,如下所示:

module.exports = {
  configureWebpack: config => {
     config.optimization.splitChunks.cacheGroups.vendors.chunks = 
       chunk => chunk.name !== "barWidget";
  }
}

我还没有尝试过,但我认为它应该按原样工作或进行一些最小的调整

于 2021-04-08T15:14:19.853 回答