service worker 无法实现运行时自动转译 cjs 模块,因其不参与模块解析与 ast 转换;可行方案是构建时转换为 esm 并正确加载,sw 仅能辅助缓存分发与路径重定向。

旧版构建工具(如 Webpack 4、Browserify 或早期 Rollup)本身不原生支持 ESM,但大量第三方库仍以 CommonJS(CJS)形式发布。要让这些库在旧构建环境中正确导出并被消费,关键不是“转译语法”,而是解决模块解析、导出识别和默认导出映射这三层适配问题。
明确第三方库的导出形态
很多 CJS 库(如 lodash、moment)的 package.json 中没有 module 字段,其 main 指向的是 CJS 文件(如 index.js)。构建工具需能识别这种文件,并将其视为可导入模块。常见情况包括:
- 导出为对象:
module.exports = { foo: () => {} }→ 可用import * as lib from 'lib'或const lib = require('lib') - 导出为函数/类:
module.exports = class A {}→import A from 'lib'会失败,除非配置默认导出补全 - 混合导出:
exports.default = ...; exports.foo = ...→ 需兼容import X, { foo } from 'lib'
配置构建工具识别 CJS 入口与默认导出
Webpack 4 默认将 main 字段作为入口,但对 CJS 的 default 处理较弱。需显式启用或补全:
用于端到端视频本地化流程的轻量编排器,路由至四个专注子技能——/wjs-transcribing-audio、/wjs-translating-subtitles...
- 在
resolve.alias或resolve.mainFields中确保优先读取"main"(而非"module"),避免跳过 CJS 版本 - 启用
resolve.exportsFields: ["exports"](Webpack 5+),但旧版需退回到mainFields: ["main"] - 对无
default的 CJS 库,可通过imports-loader或exports-loader手动注入:import _ from "exports-loader?default=exports&named=exports?_!lodash"
处理 require 动态路径与条件加载
旧工具链中,CJS 的运行时 require(xxx) 可能含变量或拼接路径(如 require('./' + name)),这类写法无法被静态分析。适配建议:
- 避免在 CJS 模块中使用动态
require;若必须,改用require.context(Webpack)显式声明可解析范围 - 对
if (process.env.NODE_ENV === 'dev') require('./debug')类逻辑,用 DefinePlugin 注入常量,让 Uglify/terser 在压缩时直接移除 dead code - 第三方库内部的动态 require,通常由构建工具自动处理(如 Webpack 的
require.ensure替换),无需手动干预
外置(external)与按需加载的边界控制
当第三方库体积大且确定不修改时,应设为 external,防止被打包进 bundle:
- Webpack 中配置
externals: { lodash: '_' },并在 HTML 中通过<script></script>引入全局变量 - Browserify 使用
--external lodash,配合--require单独打包依赖 - 注意:external 后,
import _ from 'lodash'仍有效,但实际引用的是全局_,需确保环境已提供
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










