Skip to content

使用multi-page模式时chunks无法注入script #4944

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
zwlijun opened this issue Dec 10, 2019 · 9 comments
Closed

使用multi-page模式时chunks无法注入script #4944

zwlijun opened this issue Dec 10, 2019 · 9 comments
Labels
needs reproduction This issue is missing a minimal runnable reproduction, provided by the author

Comments

@zwlijun
Copy link

zwlijun commented Dec 10, 2019

Version

3.11.0

Environment info

windows 10

Steps to reproduce

  1. 安装 vue-cli 工具
  2. 使用cli创建一个工程
  3. 配置pages参数
const path = require('path');
const fs = require('fs');
const glob = require('glob');

const mode = require('./mode.config');

function resolve(dir) {
    return path.join(__dirname, dir);
}
const ROOT_PATH = resolve('../src/modules');

const entries = glob.sync(`${ROOT_PATH}/**/main.js`) || [];
const useMultiplePages = ((entries.length > 0) && (mode.multiple === true));
const _pages = useMultiplePages ? {} : undefined;

console.log('PAGE MODE', useMultiplePages ? 'multi-page' : 'single');

if (useMultiplePages) {
    // 默认入口文件
    _pages.app = {
        // page 的入口
        entry: resolve('../src/main.js'),
        // 模板来源
        template: resolve('../public/index.html'),
        // 在 dist/index.html 的输出
        filename: 'index.html',
        // 当使用 title 选项时,
        // template 中的 title 标签需要是 <title><%= htmlWebpackPlugin.options.title %></title>
        title: '',
        // 在这个页面中包含的块,默认情况下会包含
        // 提取出来的通用 chunk 和 vendor chunk。
        // chunks: ['vendors', 'chunk-vendors', 'chunk-common', 'app'],
    };

    // 子模块入口文件
    entries.forEach((item, index) => {
        const name = path.basename(path.dirname(item));
        const template = path.join(path.dirname(item), 'public/index.html');
        const title = path.join(path.dirname(item), 'title');

        console.log(fs.readFileSync(title));

        _pages[name] = {
            // page 的入口
            entry: item,
            // 模板来源
            template: fs.existsSync(template) ? template : resolve('../public/index.html'),
            // 在 dist/index.html 的输出
            filename: `${name}/index.html`,
            // 当使用 title 选项时,
            // template 中的 title 标签需要是 <title><%= htmlWebpackPlugin.options.title %></title>
            title: fs.existsSync(title) ? fs.readFileSync(title, { encoding: 'utf8' }).replace(/^([\s]+)|([\s]+)$/g, '') : '',
            // 在这个页面中包含的块,默认情况下会包含
            // 提取出来的通用 chunk 和 vendor chunk。
            // chunks: ['vendors', 'chunk-vendors', 'chunk-common', name],
        };
    });

    console.log(_pages);
}

const pages = _pages;

// 多页配置
module.exports = pages;
  1. 执行 serve 或 build

What is expected?

能够正常渲染出页面

What is actually happening?

  1. chunks 没有注入到 HTML 页面中
  2. 由于第1点,导致页面不能渲染显示。

在使用vue-cli创建一个工程时,使用multi-page模式。配置 pages 参数。
通执 serve 和 build 后,页面相关的 chunks 不会被注入到 HTML文件中,导致页面无法执行渲染。
在排查过程中,发现 html-webpack-plugin 插件在处理 chunks 参数时采用的是 绝对匹配 的方式来过滤 chunk。 我在 html-webpack-plugin ##的github也提了issue( #jantimon/html-webpack-plugin#1319 ),如果 html-webpack-plugin的作者不采纳,cli 这边能否实现呢?

@haoqunjiang
Copy link
Member

很抱歉,请问能否更详细地描述一下你碰到的问题,以及需要我们实现什么功能?
目前的 issue 内容太过简略了,我无法理解到底是什么问题。

另外,对于 Bug 反馈,我们是要求必须提供可以运行的复现代码的(最好是一个 Git 仓库)

@haoqunjiang haoqunjiang added the needs reproduction This issue is missing a minimal runnable reproduction, provided by the author label Dec 10, 2019
@zwlijun
Copy link
Author

zwlijun commented Dec 12, 2019

@sodatea 内容已更新,请看一下。谢谢

@jadepam
Copy link

jadepam commented Dec 13, 2019

chunks: ['vendors', 'chunk-vendors', 'chunk-common', name],
这个配置不能注释,他的作用就是在HTML注入提取出来的通用 chunk 和 vendor chunk、当前单页js

@Maorey
Copy link

Maorey commented Dec 16, 2019

chunks: ['vendors', 'chunk-vendors', 'chunk-common', 'app'] 是配置要注入到html的chunk
如果你保留的Preload的话,俺这儿有个插件,可以自动注入Preload的资源(因为Preload插件已经确定好了这个html需要的资源(有序)),就不用填这个选项了,然后你就可以随意拆分chunk了

@zwlijun
Copy link
Author

zwlijun commented Dec 16, 2019

chunks: ['vendors', 'chunk-vendors', 'chunk-common', name],
这个配置不能注释,他的作用就是在HTML注入提取出来的通用 chunk 和 vendor chunk、当前单页js

可以不设置,如果这里没有设置,那么会有一个默认值会处理这个参数

@zwlijun
Copy link
Author

zwlijun commented Dec 16, 2019

chunks: ['vendors', 'chunk-vendors', 'chunk-common', 'app'] 是配置要注入到html的chunk
如果你保留的Preload的话,俺这儿有个插件,可以自动注入Preload的资源(因为Preload插件已经确定好了这个html需要的资源(有序)),就不用填这个选项了,然后你就可以随意拆分chunk了

这一个的问题是 html-webpack-plugin 这个插件处理问题

@haoqunjiang haoqunjiang removed the needs reproduction This issue is missing a minimal runnable reproduction, provided by the author label Dec 16, 2019
@haoqunjiang
Copy link
Member

  1. 你提供的代码仍然不能直接运行,我还是不太明白你碰到的问题是什么
  2. 究竟是什么 chunks 没有注入到页面?具体改了哪些配置?是另外配置了 splitChunks 然后再改 pages 设置后出的问题吗?
  3. 如果 html-webpack-plugin的作者不采纳,cli 这边能否实现呢

这里我也没懂你要 CLI 实现什么……

@haoqunjiang haoqunjiang added the needs reproduction This issue is missing a minimal runnable reproduction, provided by the author label Dec 16, 2019
@zwlijun
Copy link
Author

zwlijun commented Dec 16, 2019

3. > 如果 html-webpack-plugin的作者不采纳,cli 这边能否实现呢

@sodatea 是所有的chunks都没有注入到页面。
关于第3点意思就是如果 html-webpack-plugin 里的filterChunks方法不调整过滤匹配规则,cli工具能否继承html-webpack-plugin,在他的基础上实现宽松的匹配规则(实现分支:https://github.com/zwlijun/html-webpack-plugin/tree/feature/multi-page-chunks)。这个修改我也在html-webpack-plugin的github上提交了pull requests,不过现在没有反应。
html-webpack-plugin 修改:
修改前的代码

  /**
   * Return all chunks from the compilation result which match the exclude and include filters
   * @param {any} chunks
   * @param {string[]|'all'} includedChunks
   * @param {string[]} excludedChunks
   */
  filterChunks (chunks, includedChunks, excludedChunks) {
    return chunks.filter(chunkName => {
      // Skip if the chunks should be filtered and the given chunk was not added explicity
      if (Array.isArray(includedChunks) && includedChunks.indexOf(chunkName) === -1) {
        return false;
      }
      // Skip if the chunks should be filtered and the given chunk was excluded explicity
      if (Array.isArray(excludedChunks) && excludedChunks.indexOf(chunkName) !== -1) {
        return false;
      }
      // Add otherwise
      return true;
    });
  }

修改后的代码:

  /**
   * Return all chunks from the compilation result which match the exclude and include filters
   * @param {any} chunks
   * @param {string[]|{test(chunkName: string): boolean}|((chunkName: string) => boolean)|'all'} includedChunks
   * @param {string[]|{test(chunkName: string): boolean}|((chunkName: string) => boolean)} excludedChunks
   */
  filterChunks (chunks, includedChunks, excludedChunks) {
    return chunks.filter(chunkName => {
      // Skip if the chunks should be filtered and the given chunk was not added explicity
      if (Array.isArray(includedChunks) && includedChunks.indexOf(chunkName) === -1) { // chunks: Array
        return false;
      } else if (includedChunks instanceof RegExp) { // chunks: RegExp
        return includedChunks.test(chunkName);
      } else if (typeof includedChunks === 'function') { // chunks: Function
        return includedChunks(chunkName);
      }
      // if (Array.isArray(includedChunks) && includedChunks.indexOf(chunkName) === -1) {
      //   return false;
      // }

      // Skip if the chunks should be filtered and the given chunk was excluded explicity
      if (Array.isArray(excludedChunks) && excludedChunks.indexOf(chunkName) !== -1) { // chunks: Array
        return false;
      } else if (excludedChunks instanceof RegExp) { // chunks: RegExp
        return !excludedChunks.test(chunkName);
      } else if (typeof excludedChunks === 'function') { // chunks: Function
        return excludedChunks(chunkName);
      }
      // if (Array.isArray(excludedChunks) && excludedChunks.indexOf(chunkName) !== -1) {
      //   return false;
      // }
      // Add otherwise
      return true;
    });
  }

@haoqunjiang
Copy link
Member

haoqunjiang commented Dec 17, 2019

我大概懂你的问题了(虽然还是没明白什么情况下才会出现这个问题)

但既然是上游插件的问题的话,我认为 Vue CLI 不应该为了修一个小 bug 而直接 fork 过来改。我们没有这个精力保证后续的持续维护。

如果你实在有需要,可以自己在 package.json 里添加 resolutions 字段,把 html-webpack-plugin 指向你 fork 修改后的 GitHub 仓库 (yarn 直接支持解析 resolutions,npm 可以用 https://www.npmjs.com/package/npm-force-resolutions)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs reproduction This issue is missing a minimal runnable reproduction, provided by the author
Projects
None yet
Development

No branches or pull requests

4 participants