html模板不能发布为npm包,因其是构建阶段输入资产而非运行时依赖;发布后丧失源码可编辑性,无法触发hmr,且需手动更新版本,违背monorepo“改一处、全链路生效”原则。

Monorepo 里 HTML 公共模板不能靠 npm publish 同步,必须走源码级引用 + 构建时注入,否则跨包修改不生效、本地调试断链。
为什么不能把 HTML 模板发布成 npm 包?
HTML 模板不是运行时依赖,而是构建阶段的输入资产。一旦打包成 npm 包,就失去源码可编辑性,vite build 或 webpack 无法监听其变更触发 HMR;同时版本号更新后,各应用还得手动 npm update,违背 Monorepo “改一处、全链路生效” 的核心价值。
- 构建工具(如 Vite)默认不解析 node_modules 里的 HTML 文件为模块
- TS/JSX 中
import template from 'shared-templates/header.html'在多数配置下会报错或返回 raw string,而非可执行函数 - CI 环境中若未提前
pnpm install,HTML 文件可能因未被pnpm workspace链接而缺失
推荐做法:用 pnpm workspace + 别名 + 构建插件
把 HTML 模板放在 packages/shared-templates 下,通过 pnpm link 自动软链接,并在构建时由插件读取、编译、注入。
- 在根目录
pnpm-workspace.yaml中确保已声明:packages: ['packages/*'] - 在根
tsconfig.json或vite.config.ts中配置别名:"@templates": ["packages/shared-templates/src"] - Vite 用户加插件:
vite-plugin-html或自定义插件,用fs.readFileSync读取@templates/header.html并注入transformIndexHtml钩子 - Webpack 用户可用
html-webpack-plugin的templateContent选项,配合require.resolve('@templates/header.html')
多环境模板如何隔离?
不要靠文件名后缀(如 header.prod.html),而应按用途分目录 + 运行时判断,避免构建产物污染和 CI 缓存失效。
- 结构示例:
packages/shared-templates/src/{base,admin,portal}/header.html - 应用层 import 时明确路径:
import header from '@templates/admin/header.html' - 禁止在模板里写
if (process.env.NODE_ENV === 'production')—— HTML 不参与 JS 打包流程,该判断永远为undefined - 若需动态内容,用占位符(如
{{title}})+ 构建插件传入 data,而非服务端渲染逻辑
真正难的是边界控制:HTML 模板一旦被多个应用直接 import,就隐含了强耦合。必须用 eslint-plugin-import 配合 import/no-restricted-paths 规则,禁止 apps/xxx 直接 import packages/yyy 之外的模板路径——否则一个模板改错,五六个应用一起挂。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











