javascript模块化开发有哪些主流方案【教程】

12次阅读

javaScript模块化无唯一主流方案:浏览器端优先ES Module(需type=”module”和.js后缀),node.js v14+默认支持但需配置”type”:”module”或.mjs,CommonJS仍广泛用于工具链动态加载,混用时存在兼容限制。

javascript模块化开发有哪些主流方案【教程】

javascript 模块化开发没有“唯一主流方案”,只有不同场景下更合适的选择:浏览器端优先用 ES Module(原生支持、静态分析强),Node.js 从 v14+ 起也默认支持 ES Module,但仍有大量旧项目依赖 CommonJS;构建工具链中 Rollup 偏爱 ESM 输出,webpack 则两者都兼容但默认处理 CommonJS 更成熟。

浏览器里直接用 import/export 就行,但要注意 .js 后缀和 type=”module”

现代浏览器(chrome 61+、firefox 60+、safari 11.1+)原生支持 ES Module,但必须满足两个硬性条件:

  • 标签要加 type="module" 属性,否则会忽略 import/export
  • import 路径必须是完整 URL 或带后缀的相对路径,比如 import { foo } from './utils.js' —— 缺少 .js 会报 404,不支持 Node 风格的自动解析
  • 顶层 thisundefined,且模块作用域天然严格模式,无法用 var 声明全局变量

示例:

node.js 里用 ES Module 要注意 package.json 的 “type” 字段

Node.js 默认把 .js 文件当 CommonJS 处理。启用 ES Module 有两种方式:

立即学习Java免费学习笔记(深入)”;

  • package.json 中声明 "type": "module",此后所有 .js 文件按 ESM 解析(包括 require() 会报错)
  • 或用 .mjs 扩展名,无需改配置,Node 会强制按 ESM 加载
  • import 路径不能省略扩展名(./utils 不行,得写 ./utils.js./utils.mjs),也不能用 Node 内置模块简写(import fs from 'fs' 会失败,得用 import * as fs from 'fs'

CommonJS 还没淘汰,尤其在 require() 动态加载和工具脚本里很常见

CommonJSmodule.exports/require())仍是很多 Node 工具链的底层选择,比如 webpack.config.jsjest.config.js 默认是 CJS 模块,因为支持动态路径拼接和运行时条件判断:

const env = process.env.NODE_ENV; const config = require(`./webpack.${env}.js`); // ✅ CommonJS 支持

ES Moduleimport 必须是静态字符串,上面这种写法会报 Cannot use import statement outside a module 错误。另外,CJS 模块的 require.resolve()require.cache 在插件开发中仍不可替代。

混用 ESM 和 CommonJS 时,__dirname、__filename 和 require 不可用

一旦用了 type="module".mjs,Node 就禁用 __dirname__filename 和全局 require。想获取当前目录需改用:

  • import { fileURLToPath } from 'url';
  • const __filename = fileURLToPath(import.meta.url);
  • const __dirname = path.dirname(__filename);

想在 ESM 中加载 CJS 模块(如 lodash),可以用 import _ from 'lodash'(Node 自动适配),但反过来——在 CJS 里 require() 一个 ESM 文件——会直接报错:ERR_REQUIRE_ESM。这时只能靠构建工具(如 esbuild)提前转译,或改用 dynamic import()(返回 promise)。

真正容易被忽略的是:模块解析规则在不同环境间不一致——浏览器不认 node_modules 自动查找,Node 的 exports 字段又可能屏蔽 ESM 入口,而 Webpack/vite 的别名配置又各自为政。选方案前,先确认你的运行时环境、依赖包的导出方式(看它的 package.jsonexportsmain/module 字段),比盲目套教程更重要。

text=ZqhQzanResources