Webpack打包Node.js项目的特殊场景解决方案
本文介绍在Node.js后端使用EJS模板且无独立HTML文件时,利用Webpack进行打包的特殊处理方法。通过将EJS后缀改为HTML并配置HtmlWebpackPlugin,解决locals未定义及静态资源路径错误问题,实现代码压缩与资源正确引用。
适用场景说明
适用场景说明
首先需要明确,本文讨论的情况并不具备普遍性。如果你的项目背景与作者类似,希望这篇文章能为你提供有效的帮助。
具体项目背景如下:后端采用Node.js构建,模板引擎选用EJS。整个页面由单个EJS文件构成,Node.js负责渲染数据并返回完整的HTML页面给用户。
这种架构在打包过程中会引发以下具体问题:
第一,项目不包含独立的HTML文件,EJS也不用于引入公共组件,而是直接生成完整页面。Webpack中处理EJS的Loader返回的是一个函数,这会导致后续处理出现异常。
第二,Node.js配置了静态资源目录public,而视图目录与public同级。Webpack在处理图像等静态资源路径时,容易产生命径解析错误。
第三,如果强行设置publicPath,Node.js运行时将无法找到资源,因为静态资源目录的配置已经固定。
如果你也遇到了上述类似的问题,希望能在本文中找到可行的解决方案。
补充说明:不要认为我的项目结构奇怪。这是因为在开发初期知识储备不足,等到发现问题时,重构成本过高。
由于修改起来过于繁琐,最终决定沿用现有方案,即“将错就错”。
解决方案概述
解决方案概述
针对EJS处理问题
针对EJS处理问题
我在各大论坛和官方网站搜索了很久,始终未能找到能直接处理这种特定情况的Loader。
无奈之下,只能转换思路:先将EJS文件转换为HTML文件,再进行后续处理。
既然需要修改文件,就必须调整服务器的模板引擎配置(即修改app.js文件)。

具体修改目标是:让Node.js继续使用EJS作为模板引擎,但通过HTML文件来进行渲染。
这里我们需要利用Express中的app.engine方法来注册一个新的引擎映射。
具体配置代码如下:
app.set('views',path.join(__dirname,'views'));//设置模板引擎的目录
app.engine('html', require('ejs').renderFile);
app.set('view engine','html');
通过上述配置,我们可以将原本views视图目录中的EJS文件后缀直接修改为.html。
接下来处理Webpack对HTML文件的打包
接下来处理Webpack对HTML文件的打包
首先想到的Webpack插件是HtmlWebpackPlugin。
我查阅了许多文章,发现所有处理HTML文件的方案都无一例外地使用了这个插件。
既然被广泛使用,其功能强大是毋庸置疑的。
然而,配置完成后运行Webpack,却报出了“locals未定义”的错误。
错误详情如下:

这是因为locals是由Express中的res.render()方法传递给页面的数据,而在Webpack打包阶段,这些数据尚未生成,因此必然报错。
那么,如何解决这个问题呢?
目前的困境是:既需要Webpack处理HTML中的资源,又希望Webpack忽略EJS语法并继续压缩代码。这似乎是一个两难的境地。
在长时间搜索无果后,一篇偶然发现的文章给了我启发。

该文章博主的目的是将EJS引入的模板打包到一个页面中,而我的需求恰恰相反:我需要Webpack完全忽略EJS代码。
基于此,解决方案逐渐清晰。
首先,我将原本HTML中的JavaScript代码抽离出来,保存为test.js文件。
然后,以这个JS文件作为入口文件,以原本的HTML文件作为模板。
最后,使用HtmlWebpackPlugin生成压缩后的HTML文件。
具体解决代码如下:
webpack.config.js配置文件
'use strict';
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
//打包ejs
module.exports = {
entry: {
test: './test.js',//入口文件 即一般来说app.js
},
mode:"production",//生产环境
output: {
path: path.resolve(__dirname,'build'),//输出路径
filename: 'js/[name]/[name].js'//输出后的文件名
},
externals: {
jquery:'window.jQuery'
},//外部加载的资源 这些都是不需要进行打包的
module: {
rules: [//设置处理js文件的loader
{test:/\.js$/,use:'babel-loader',exclude:/node_modules/},
{test:/\.css$/,use:["style-loader","css-loader"]},
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: 'images/[name].[ext]'
}
}
]
},
{
test: /\.(html)$/,
use: {
loader: 'html-loader',
options: {
attrs: [':data-src']
}
}
}
]
},
plugins:[
new HtmlWebpackPlugin({
name:'test',
template:'./public/init.html',//模板文件
filename:'views/test.html',//目标文件
minify:{
collapseWhitespace:true,
collapseInlineTagWhitespace:true,
conservativeCollapse:true,
minifyCSS:true,
minifyJS: true,
removeComments:true,
trimCustomFragments:true
}
})
],
optimization: {
minimize: true//是否压缩代码
}
};
上述配置中的minify参数主要用于控制HTML压缩行为。
入口文件test.js
该文件中不包含任何Webpack相关代码,仅包含项目的业务逻辑,因此此处不再赘述。
运行Webpack后,打包过程顺利完成。

让我们对比一下打包前后的HTML文件。
打包前的HTML结构:

打包后的HTML结构:

文件大小对比结果:

最后,启动Node.js服务器进行测试。

总结
以上介绍了在Node.js项目中利用Webpack进行打包的特殊处理方法,希望能对大家有所帮助。如有任何疑问,欢迎留言,我会及时回复。同时也感谢大家对本站的支持!
全栈开发中JavaScript与Java怎么协作?前后端技术栈配合解析
2026-11-04 11:08:24
Node.js官网访问慢?国内镜像加速下载方案
2026-11-03 18:57:24
Node.js 连接 MySQL 数据库实现增删改查操作
2026-11-03 14:31:14
Windows系统安装Node.js:下载、配置与环境验证
2026-11-03 14:15:56
Linux (Ubuntu/CentOS) 环境下安装Node.js的常用方法
2026-11-03 10:18:39
