Vue CLI v3 - 它如何知道哪些 JS 文件应该分块到不同的文件中

Vue CLI v3 - How does it know what JS files should be chunked in a different file(s)

我很难全神贯注于新的 CLI 和配置。 在官方文档中,我真的找不到任何关于 CSS 以及如何将其添加为入口点而不是直接将其导入组件或 main.js 文件的信息。

我意识到一些 JS 文件正在从 main.js 分块到单独的文件中,其余的在应该编译的地方编译到 app.js.

我想知道,它怎么知道在后台应该为 JS 将什么存储为 "vendor",但是当我尝试将一些 "vendor" SASS 文件导入 main.js 它没有,它将所有内容合并到一个 app.css 文件中。


任何人都可以告诉我,create/modify 和 vue.config.js 是如何告诉捆绑程序我也希望 app.scss 成为入口点并且 vendor.scss 成为另一个入口点。

我不确定这种目的的最佳实践是什么,但我总是用我自己的 webpack 配置这样做...

下面的部分示例:

entry: {
    vendor: [
        './styles/vendor.scss',
        './scripts/vendor.js'
    ],
    app: [
        './styles/app.scss',
        './scripts/app.js'
    ]
}

编辑 #1

我想我得到了第一个...

“它如何知道 "vendor" 文件中应该分块的内容?

我还没有弄清楚的是......如果我有我的个人 assets/styles/vendor 目录,我 @import 来自 NPM 的那些 SASS 文件并做一些修改变量或其他什么。

在这种情况下,将此文件导入 main.js 不会分块...因此必须有一种方法告诉捆绑程序我想要该目录中的所有内容或 vendor.scss 文件中的所有内容一切都在导入,将被分块。


编辑 #2

我想我可以使用 WebPack 的神奇评论导入主要供应商 SCSS 文件,例如:

import(/* webpackChunkName: "vendor" */ './assets/styles/vendor.scss')

我对此没有问题,但显然捆绑器有问题。它还会生成一个空的 vendor.[hash].js 文件。


编辑 #3

我做了进一步的研究,了解到有一个命令 vue inspect 可以输出 webpack 配置。

因此,在对 vue.config.js 进行调整时,如果存在错误或未按预期工作,我们可以使用此命令查看输出。

此外,我了解到如果我们直接在 vue.config.js 文件中指定 entry,我们将收到无法在配置文件中指定 entry 的错误。

以下禁止这样做,但这是我真正想要实现的...

// vue.config.js
module.exports = {
  entry: {
    app: [
      './src/main.js',
      './src/assets/styles/app.scss'
    ],
    vendor: [
      './src/assets/styles/vendor.scss'
    ]
  }
}

执行此操作的实际正确方法将是我自己问题的答案...

实现这一点的方法是使用 WebPack 的 Chain API。

但是,如果我做的一切都正确,我仍然会看到生成的 vendor.[hash].js 文件有一些 WebPack 模块样板的问题。此 JS 文件也被注入到 index.html 模板中。

这导致与我的 EDIT #2 尝试相同的结果,只是我们不再在 [=15= 中导入我们的 Sass 文件]

为了我这个问题的目的修改入口点,我们可以通过以下方式进行:

// vue.config.js
module.exports = {
  chainWebpack: config => {
    config
      .entry('app')
        .add('./src/assets/styles/app.scss')
        .end()
      .entry('vendor')
        .add('./src/assets/styles/vendor.scss')
      .end()
  }
}

备注

我们没有指定 app 入口 JS 文件,默认情况下是 main.js,因为我们没有覆盖当前入口点。相反,我们正在扩展它,所以一切都按预期工作。


更新

直到 WebPack 在未来的主要版本中解决这个问题,我发现了一个很棒的包 - fqborges/webpack-fix-style-only-entries。它解决了我遇到的这个问题,我建议您使用它。

最终配置如下所示:

const FixStyleOnlyEntries = require('webpack-fix-style-only-entries')

module.exports = {
  chainWebpack: config => {
    config
      .entry('app')
        .add('./src/assets/styles/app.scss')
        .end()
      .entry('vendor')
        .add('./src/assets/styles/vendor.scss')
      .end()
  },

  configureWebpack: {
    plugins: [
      new FixStyleOnlyEntries()
    ]
  }
}

更新#2

在对项目进行进一步调查和使用此类配置后,我意识到我必须在需要覆盖任何 vendor 相关内容的样式中使用 !important

这是因为 WebPack 会在 vendor(JS 和 CSS)之前注入 app,这会导致这样的问题。

即使我们从上面修改配置并将app条目移动到vendor条目下方,它仍然会失败。原因是,因为我们正在修改 vue-cli 配置中默认已经存在的入口点。我们正在向 app 添加更多条目,并且正在添加新的 vendor 条目。

要解决这个排序问题,我们必须完全删除 app,然后自己创建它。

const FixStyleOnlyEntries = require('webpack-fix-style-only-entries')

module.exports = {
  chainWebpack: config => {
    config.entryPoints.delete('app')

    config
      .entry('vendor')
        .add('./src/assets/styles/vendor.scss')
      .end()
      .entry('app')
        .add('./src/main.js')
        .add('./src/assets/styles/app.scss')
      .end()
  },

  configureWebpack: {
    plugins: [
      new FixStyleOnlyEntries()
    ]
  }
}