美文网首页
Webpack5 踩坑之(html-webpack-plugin

Webpack5 踩坑之(html-webpack-plugin

作者: vv_小虫虫 | 来源:发表于2021-02-18 13:42 被阅读0次

    2021 开工第一天就给我个大大的惊喜。

    起因

    今天起了个大早,怀着无比激动的心情来到了公司,一切还是跟往常一样,当我打开电脑并打开项目,就出现了下面的场景了:

    1-1.png
    
    ERROR in   Error: The loader "/home/project/vue3-demo/node_modules/html-webpack-plugin/lib/loader.js!/home/project/vue3-demo/public/index.html" didn't return html.
      
      - index.js:339 HtmlWebpackPlugin.evaluateCompilationResult
        [vue3-demo]/[html-webpack-plugin]/index.js:339:24
      
      - index.js:243 
        [vue3-demo]/[html-webpack-plugin]/index.js:243:22
      
      - task_queues.js:93 processTicksAndRejections
        internal/process/task_queues.js:93:5
      
      - async Promise.all
      
      - async Promise.all
    

    心态崩了呀,之前还是好好的,咋就凉了呢?

    经过

    bug 的过程比较漫长,我就不在这里描述了~

    原因

    环境

    • webpack:v5.22.0
    • html-webpack-plugin:v4.5.1

    由于 webpack5.22.0 版本中修改了 library 的生成方式,具体代码在 webpack5.22.0 源码文件 webpack/lib/library/AssignLibraryPlugin.js279 行:

    ...
        result.add(
                    `${accessWithInit(
                        fullNameResolved,
                        this._getPrefix(compilation).length,
                        false
                    )} = __webpack_exports__${exportAccess};\n`
                );
    ...
    

    webpack5.22.0 源码文件 webpack/lib/library/AssignLibraryPlugin.js212 行:

    render(source, { chunk }, { options, compilation }) {
            ...
                source = new ConcatSource(`${this.declare} ${base};\n`, source);
    }
    

    这样说可能有点抽象,大家可以在 node 环境中运行一下下面这段代码:

    // let source = `var HTML_WEBPACK_PLUGIN_RESULT;HTML_WEBPACK_PLUGIN_RESULT="hello"`; // webpack 5.22.0 以下版本
    let source = `var HTML_WEBPACK_PLUGIN_RESULT;(function(){HTML_WEBPACK_PLUGIN_RESULT="hello"})()`; // webpack 5.22.0 版本
    const vm = require("vm");
    const vmContext = vm.createContext({ HTML_WEBPACK_PLUGIN: true, require: require, module, console: console ,...global});
    const vmScript = new vm.Script(source);
    // Evaluate code and cast to string
    let newSource;
    try {
        newSource = vmScript.runInContext(vmContext);
    } catch (e) {
        return Promise.reject(e);
    }
    console.log(newSource);
    

    这是模拟的 webpack 5.22.0 版本下的 html-webpack-plugin 插件,运行后可以发现返回的是:

    undefined
    

    然后我们模拟一下 webpack 5.22.0 以下版本的 html-webpack-plugin 插件,运行后可以发现返回的是:

    hello
    

    当然,我这只是模拟一下 html-webpack-plugin 插件,真正返回的可不是 hello 字符串。

    报错的原因正是因为 webpack 5.22.0 版本下的 html-webpack-plugin 插件返回的是 undifined 而不是 hello

    我们可以试着改一下上面的 webpack 5.22.0 版本下的 html-webpack-plugin 插件代码:

    // let source = `var HTML_WEBPACK_PLUGIN_RESULT;HTML_WEBPACK_PLUGIN_RESULT="hello"`; // webpack 5.22.0 以下版本
    let source = `var HTML_WEBPACK_PLUGIN_RESULT;(function(){HTML_WEBPACK_PLUGIN_RESULT="hello"})()`; // webpack 5.22.0 版本
    const vm = require("vm");
    const vmContext = vm.createContext({ HTML_WEBPACK_PLUGIN: true, require: require, module, console: console ,...global});
    const vmScript = new vm.Script(source);
    // Evaluate code and cast to string
    let newSource;
    try {
        vmScript.runInContext(vmContext);
    } catch (e) {
        return Promise.reject(e);
    }
    newSource = vmContext.HTML_WEBPACK_PLUGIN_RESULT;
    console.log(newSource);
    

    可以看到,我们加了下面这一行代码:

    newSource = vmContext.HTML_WEBPACK_PLUGIN_RESULT;
    

    我们再次运行后会发现,代码正常返回了 hello 字符串。

    解决方法

    1. 对项目的 webpack 版本进行降级,降到 v5.22.0 以下。

    2. 修改本地的 html-webpack-plugin 源码,找到你本地的 xxx/node_modules/html-webpack-plugin/index.js325 行:

       // Evaluate code and cast to string
          let newSource;
          try {
            // fix issues: https://github.com/jantimon/html-webpack-plugin/issues/1603
            // newSource = vmScript.runInContext(vmContext);
            vmScript.runInContext(vmContext);
          } catch (e) {
            return Promise.reject(e);
          }
          // see issues: https://github.com/jantimon/html-webpack-plugin/issues/1603
          newSource = vmContext.HTML_WEBPACK_PLUGIN_RESULT;
      

    结果

    首先肯定是不能去骂 webpack,毕竟别人是大哥大,他会说 “我是不会改的,你爱用不用”,所以就只能委屈一下 html-webpack-plugin 了,于是我点开了html-webpack-plugingithubissues ,太哇塞了呀,已经有很多人在讨论了 Webpack v5.22.0` breaks HtmlWebpackLoader #1603

    于是我赶紧在底下贴上我的解决方案并附上(you can do this):

    1-2.png

    然后赶紧去给作者提个 pr 蹭个 contributor,哈哈,毕竟别人是几千 k 的 star 项目。

    相关文章

      网友评论

          本文标题:Webpack5 踩坑之(html-webpack-plugin

          本文链接:https://www.haomeiwen.com/subject/byngxltx.html