选用 Gulp + PostHTML 是因为纯静态 HTML5 项目无需 Webpack 的模块系统,Gulp 专注文件流处理,PostHTML 轻量精准操作 HTML,适合资源注入、路径修正等优化;二者组合构建快、体积小、逻辑透明。

为什么不用 Webpack 而选 Gulp + PostHTML
因为你要打包的是纯静态 HTML5 项目(无 React/Vue 等框架),Webpack 的模块解析和 runtime 注入反而增加冗余、拖慢构建、干扰相对路径引用。Gulp 本身不介入模块系统,只做文件流处理;PostHTML 是轻量级 HTML 转换器,能精准操作标签、属性、注释,适合做资源注入、路径修正、环境变量替换等静态优化任务——二者组合,构建快、体积小、逻辑透明。
安装与基础 gulpfile.js 结构
先确保已装 Node.js(≥16.x)和 npm。全局只需一次:npm install -g gulp-cli;项目内必须装:npm install --save-dev gulp posthtml posthtml-include posthtml-modules posthtml-expressions。注意不要漏掉 --save-dev,否则 gulp 在 gulpfile.js 中 require('gulp') 会报错。
创建 gulpfile.js,用 ES Module 语法(Node ≥14 默认支持):
import { src, dest, series } from 'gulp';
import posthtml from 'posthtml';
import include from 'posthtml-include';
import modules from 'posthtml-modules';
<p>const html = () => {
return src('src/*.html')
.pipe(posthtml([
include({ root: 'src' }),
modules({ root: 'src', publicPath: './' })
]))
.pipe(dest('dist'));
};</p><p>export default series(html);立即学习“前端免费学习笔记(深入)”;
关键点:
-
include支持<!-- @include file="header.html" -->类型的静态引入,root必须设为src才能正确解析相对路径 -
modules会自动把<link rel="stylesheet" href="css/index.css">中的href值转为带哈希的路径(需配合posthtml-assets插件),但默认不启用,这里仅用于路径规范化 - 若你用
publicPath: './',所有资源路径将保持相对,避免部署到子目录时 404;若部署到根域,可改为'/'
PostHTML 插件链常见踩坑点
PostHTML 是声明式插件链,顺序决定行为。比如 posthtml-include 必须在 posthtml-modules 之前运行,否则被 include 进来的 HTML 片段里的 <script src="...> 不会被模块化处理。
典型错误现象:Uncaught TypeError: Cannot read property 'xxx' of undefined 或资源 404,往往是因为:
- 插件未正确导出函数(如写成
posthtml([include()])却忘了include是个工厂函数,必须调用) -
posthtml-modules的root和实际文件结构不一致,导致它找不到css/或js/目录 - 用了
posthtml-assets但没配assets选项,结果 CSS/JS 文件名没加哈希,缓存失效 - PostHTML 默认不处理
<img src="...">的路径,要额外加posthtml-img-autosize或手动写正则替换
如何让打包后直接双击运行
不能直接双击打开 dist/index.html?99% 是因为路径写死了或用了 fetch/XMLHttpRequest 加载 JSON 数据——浏览器在 file:// 协议下禁止跨文件读取,且相对路径解析规则和 HTTP 不同。
解决办法只有两个:
- 改用
browser-sync启服务:npm install --save-dev browser-sync,然后在gulpfile.js加一个serve任务,server: { baseDir: 'dist' },运行npx gulp serve就能访问http://localhost:3000 - 如果真要双击运行,必须确保:
<script>全部内联、所有src/href都是相对路径(如./js/app.js)、JSON 数据硬编码进 JS、禁用任何动态 import 或 fetch
PostHTML 可以帮你自动补全路径前缀,但无法绕过浏览器对 file:// 的限制——这点容易被忽略,直到上线前才发现 AJAX 请求全失败。



















