Webpack: 链式加载器

4

当我单独使用ejs-loaderhtml-loader时,一切都正常:

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

// compiles to:

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

但是当我把它们链接起来时,我得到的是 JavaScript 代码而不是 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',
        })
    ]

}

你修好了吗? - JRichardsz
1个回答

5

我现在正在为同样的问题而苦苦挣扎,但我找到了答案。

首先,我们需要了解加载器(loaders)的工作原理。简单来说:它们可以接受任何类型的文件作为输入,但是加载器的输出始终是JS代码,Webpack然后执行这些代码以获取最终输出结果。

ejs-loader和html-loader都期望将HTML代码作为其输入。当我们链接多个加载器时,第二个加载器接收到的不再是HTML,而是由第一个加载器返回的javascript代码。因此,我们需要从这段JS代码生成HTML。为此,我编写了一个简单的加载器,需要放在html-loader和ejs-loader之间。

让我们称之为“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始终正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接