本来以为使用了html-loader之后,所有的问题都解决了。但是,后来,无情的发现,html-loaderhtml-webpack-plugin是冲突的。使用了html-loader之后,html-webpack-plugin<%= %>功能就全部失效了,也就是说失去了ejs的解析能力。套用抖音上的一句话就是:“TMD我心态崩了”。

苏南大叔:webpack4系列教程,是否应该使用html-loader? - webpack-html-ways
webpack4系列教程,是否应该使用html-loader?(图4-1)

本文测试环境:win10node@14.2.0npm@6.14.4webpack@4.43.0html-loader@1.1.0html-webpack-plugin@4.3.0。据说,问题的根源是html-webpack-plugin发现有loader处理过的话,就会拒绝做进一步处理(ejs)。

方案一:舍弃html-webpack-pluginejs功能

html-webpack-pluginhtml-loader那边,都有大量讨论此话题的帖子。也有人提出了很多修改意见,不过,苏南大叔尝试让两者共存后,都基本上失败了。这是个非常悲伤的故事。

目前的情况是这样的,webpack.config.js试图让两者共存的方案:

//...
module.exports = {
    //...
    plugins: [
        new HtmlWebpackPlugin({
            template: "html-loader!./html/index.html", // 根据 目标文件生成 html
        }),
    ]
}
//...
module.exports = {
    //...
    plugins: [
        new HtmlWebpackPlugin({
            template: "./html/index.html", // 根据 目标文件生成 html
        }),
    ],
    module: {
        rules: [
            {
                 test: /\.html$/i,
                 use:  [ "html-loader"],
                 // loader: 'html-loader',
            }
            //...
        ]
    }
}

这两种方案,都存在着<%= %>,不能解析的问题。如果,您的模板页面,就是那种纯正的html静态页面的话,完全不需要ejs能力的话,不妨就试试目前的这种方案。

苏南大叔:webpack4系列教程,是否应该使用html-loader? - ejs-template
webpack4系列教程,是否应该使用html-loader?(图4-2)

方案二:部分保留ejs能力

这个方案是不咋滴的,苏南大叔不推荐。

首先,配置文件webpack.config.js中,不配置.html文件关联到html-loader。仅仅常规配置html-webpack-plugin
webpack.config.js:

//...
module.exports = {
    //...
    plugins: [
        new HtmlWebpackPlugin({
            template: ./html/index.html", // 根据 目标文件生成 html
        }),
    ]
}

然后,在index.html内部,使用下面类似的语法:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
    <%= require('html-loader!./body.html')  %>
</body>
</html>

关键点是:

<%= require('html-loader!./body.html')  %>

苏南大叔:webpack4系列教程,是否应该使用html-loader? - ejs-template-2
webpack4系列教程,是否应该使用html-loader?(图4-3)

在这种情况下,如果能保证,需要转换的属性(比如imgsrc),都在上面的body.html里面的话,这个事情就是成功的。需要非常精确的区分,ejs`功能和普通页面之间出现的位置。

在上述例子中,body.html之外,具有ejs能力,body.html内部,没有ejs能力。使用html-loader!引用body.html

方案三:彻底放弃html-loader

这个也是网上大家讨论的最终方案,听起来也确实是个不错的解决方案。

这个方案中,还是仅仅配置html-webpack-plugin
webpack.config.js:

//...
module.exports = {
    //...
    plugins: [
        new HtmlWebpackPlugin({
            template: ./html/index.html", // 根据 目标文件生成 html
        }),
    ],
    module: {
        rules: [
           {
                test: /\.(png|jpg|gif|jpeg|svg)$/,
                use: [
                    {
                        loader: "url-loader",
                        options: {
                            name: "[name].[hash:5].[ext]",
                            limit: 1024, // size <= 1kib
                            outputPath: "img",
                            // publicPath: "../img",
                        }
                    }
                ]
            },
            //...
        ]
    }
}

index.html中,对于所有的需要处理的图片(或者其它文件)地址,都使用下面的语法进行替代:

<img src="<%= require('../src/bg.png')%>" />
<video poster="<%= require('../src/bg2.png')%>"></video>

苏南大叔:webpack4系列教程,是否应该使用html-loader? - ejs-template-3
webpack4系列教程,是否应该使用html-loader?(图4-4)

这个方案下,处理哪个属性,不处理哪个属性,其实也是非常方便的。唯一的问题就是:需要大家用这种不太习惯的方式,修改模版文件。暂且就这样吧。您说呢?

相关链接

总结

总结不出来啥,方案都不是特别完美,所以也没有啥太好说的。大家自己选个适合自己的方案吧。或者,您有更好的方案的话,请留言给苏南大叔。谢谢!

更多webpack经验文字,请点击下方的链接:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。
本站采用创作共用版权协议, 要求署名、非商业用途和相同方式共享。
转载本站内容必须也遵循“署名-非商业用途-相同方式共享”的创作共用协议。
未经许可,规模化镜像抄袭本站内容的行为,将会根据有关法律法规进行维权。
程序如此灵动~》下所有原创文章,如被用于商业用途,请您按规定支付稿费。

 【加群】加入QQ群【175454274】和大家一起讨论这个问题

 【源码】本文代码片段及相关软件,请点此获取

 【绝密】秘籍文章入口,仅传授于有缘之人   webpack

本站的忠实读者小伙伴,正在阅读下面这些文章: