You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 13 .mjs构建包使用require()及切回.js扩展方案咨询

ng-packagr 13 构建兼容方案

切回.js扩展构建产物的实现方式

ng-packagr 13 遵循 Angular 13 新版APF包规范,默认输出ESM格式的.mjs产物,官方没有提供直接修改输出扩展名的配置项,可通过构建后置流程适配,无需全量替换现有require()写法:

  • 编写轻量Node.js脚本作为构建后置钩子:在ng build执行完成后,遍历构建输出目录,将所有.mjs后缀文件重命名为.js,同步批量替换所有文件内容中引用路径里的.mjs后缀为.js;同时将配套的.mjs.map sourcemap文件重命名为.js.map,修改map文件内file字段对应的后缀值,避免调试时sourcemap失效。
  • 调整包配置:如果项目根目录package.json中设置了"type": "module",需在构建输出目录下新增单独的package.json文件,写入{"type": "commonjs"},让Node环境识别输出的.js文件为CommonJS格式,保证require()可正常加载;同步修改package.json中的main、module、exports字段,将原指向.mjs的入口路径替换为重命名后的.js路径。

注意:不要通过降级ng-packagr版本的方式回退产物格式,会和Angular 13的Ivy编译器版本不兼容,抛出编译错误。

可选依赖动态导入的构建兼容方案

直接将require()替换为静态import或固定路径的动态import()时,构建工具会做静态依赖分析,找不到对应文件就会在编译阶段抛错,无法适配可选依赖按需加载的场景,可通过两种方式解决:

  • 保留原有require()写法:在项目tsconfig.json中开启"esModuleInterop": true、"allowSyntheticDefaultImports": true配置,在使用require()的文件顶部添加declare const require: (path: string) => any;类型声明绕开TS校验。ng-packagr 13 不会对这种显式声明的CommonJS require做强制ESM转换,配合前面的.js产物适配,运行时会保留原有的按需加载逻辑,不会在构建阶段校验可选依赖是否存在。
  • 使用ESM原生动态导入写法:不要传入固定字符串作为import()的参数,将包名存为变量传入,同时添加构建忽略注释,示例代码如下:
let optionalService = null;
const pkgName = 'your-optional-package';
try {
  // 该注释会告知底层rollup构建工具跳过静态分析
  optionalService = await import(/* @rollup-ignore */ pkgName);
} catch (err) {
  // 可选包未安装时走降级逻辑
}

这种写法完全符合ESM规范,构建阶段不会校验对应包是否存在,行为和CommonJS的require()一致。

内容的提问来源于stack exchange,提问作者vp310

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 21:57:24