【问题标题】:Webpack: chaining loadersWebpack:链接加载器
【发布时间】:2019-06-23 18:00:39
【问题描述】:

当我分别使用ejs-loaderhtml-loader 时一切正常:

<body>
    <%= require('./header.html')({x:1})  %>
</body>

// compiles to:

<body>
    <header><div>1</div></header>
</body>

但是当我链接它们时,我得到的是 js 代码而不是 html:

module.exports = function (obj) {
obj || (obj = {});
var __t, __p = '';
with (obj) {
__p += '\n<body>\n  ' +
((__t = ( require('./header.html')({x:1})  )) == null ? '' : __t) +
'\n</body>';

}
return __p
}

发生了什么,我该如何解决?

这是我的配置:

const config = {
    //...
    module: {
        rules: [
            {
                test: /\.html$/,
                use: ['html-loader', 'ejs-loader']
            }
        ]
    },
    //...
    plugins: [
        new HtmlWebpackPlugin({
            filename: 'index.html',
            template: './src/index.html',
        })
    ]

}

【问题讨论】:

  • 你修好了吗?

标签: webpack


【解决方案1】:

我现在正在努力解决同样的问题并找到了答案。

首先,我们需要了解加载器的工作原理。简而言之:它们将任何文件类型作为输入,但加载器的输出始终是 JS,然后 webpack 执行该 JS 以获得最终输出。

ejs-loader 和 html-loader 都期望 html 代码作为它们的输入。当我们链接加载器时,第二个加载器接收的不是 HTML,而是第一个加载器返回的 javascript。所以我们需要从那个 JS 中生成 HTML。为此,我编写了一个简单的加载器,它需要放在 html- 和 ejs- 加载器之间。

我们称它为“loader.js”:

module.exports = function (source) {
    let x = eval(source);
    let z = x();
    return z;
}

Webpack 配置将是:

module: {
    rules: [
        {
            test: /\.html$/,
            use: ['html-loader', path.resolve('loader.js'), 'ejs-loader']
        }
    ]
},

重要提示:顺序或装载程序很重要。如果我在链中交换 ejs 和 html 加载器,则 eval 失败,因为 html-loader 返回 js 代码,其中包含 eval 无法解析的其他导入。然而,ejs-loader 返回纯自包含代码,该代码使用 eval() 成功评估。

所以,因为加载器以相反的顺序执行,我们将 ejs 放在首位(意思是 - 在数组的末尾),然后是我们的中间加载器,而 html-loader 放在最后(在数组的开头)

更新:有一个即用型加载器可以完成这项工作,称为extract-loader。简单的eval 在很多情况下都会失败,而extract-loader 总是可以正常工作。

【讨论】:

    猜你喜欢
    • 2018-09-11
    • 2018-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-24
    • 1970-01-01
    • 2016-03-06
    • 2020-07-21
    相关资源
    最近更新 更多