Webpack打包Node.js项目的特殊场景解决方案

作者:接口漫谈

时间:2026-10-22

浏览:76

本文介绍在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进行打包的特殊处理方法,希望能对大家有所帮助。如有任何疑问,欢迎留言,我会及时回复。同时也感谢大家对本站的支持!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章