前端模块化指南:CJS 与 ESM 的区别与混用

1. 核心概念

  • CJS (CommonJS) :Node.js 的原生模块系统。
    • 语法require() 导入,module.exports 导出。
    • 特点:同步加载,主要用于服务端。
  • ESM (ECMAScript Modules) :JavaScript 的官方标准模块系统。
    • 语法import 导入,export 导出。
    • 特点:静态分析,异步加载,现代浏览器和前端开发的标准。

2. 如何判断项目类型?

查看项目根目录下的 package.json 文件:

  • "type": "module" :项目为 ESM 模式。
    • .js 文件被视为 ESM,必须使用 import/export
    • 如需使用 CJS,文件后缀必须改为 .cjs
  • 未设置 type"type": "commonjs" :项目为 CJS 模式(默认)。
    • .js 文件被视为 CJS,必须使用 require/module.exports
    • 如需使用 ESM,文件后缀必须改为 .mjs

3. 为什么 Vue 2 项目是 CJS,却能用 import?

这是最容易混淆的地方。项目分为两个"世界":

A. Node.js 构建环境

  • 运行者:Node.js 进程。
  • 受影响文件 :根目录配置文件(如 vue.config.js)、构建脚本(如 build/index.js)。
  • 规则 :受 package.jsontype 控制。如果是默认 CJS 项目,这些文件必须使用 require

B. 浏览器运行环境

  • 运行者:用户的浏览器。
  • 中间人:Webpack / Vite(构建工具)。
  • 受影响文件src/ 目录下的所有源码(.vue, .js 等)。
  • 规则 :不受 Node.js type 控制。构建工具会读取 src 下的代码,将 import 翻译成浏览器可执行的代码。因此,src 下请尽情使用 import

4. 实战判断法则:哪些文件能用 import?

不需要死记硬背,遵循以下逻辑:

法则一:看位置

  • src/ 目录下 :✅ 能用 import
    • 这是前端源码,由 Webpack/Vite 处理,默认支持 ESM。
  • 根目录配置文件 (如 vue.config.js):❌ 不能用 import
    • 这是 Node.js 脚本,受 package.json 控制。默认 CJS 下必须用 require

法则二:看后缀

  • .mjs :强制视为 ESM,必须用 import
  • .cjs :强制视为 CJS,必须用 require
  • .js :看 package.jsontype 设置(默认是 CJS)。

法则三:看报错(兜底)

  • 如果报错 SyntaxError: Cannot use import statement outside a ES module
    • 说明该文件由 Node.js 直接运行且处于 CJS 模式。
    • 解决 :将 import 改回 require,或者将文件后缀改为 .mjs(并在 package.json 开启 ESM)。

5. 图片导入总结

类型 位置 引用方式 说明
本地图片 src/assets import img from '...' 推荐。Webpack 会处理路径和优化。
静态资源 public/ /filename.ext 绝对路径,原封不动复制到 dist。
网络图片 服务器 'http://...' 直接绑定字符串 URL。

一句话总结

在 Vue 2 / Webpack 项目中,src 里写 import,根目录配置写 require 。如果不确定,试着用 import,报错了就改回来。

相关推荐
小码哥_常1 小时前
安卓开发秘籍:解锁10大性能优化秘诀
前端
try2find2 小时前
打印ascii码报错问题
java·linux·前端
郑州光合科技余经理2 小时前
同城O2O海外版二次开发实战:从支付网关到配送算法
开发语言·前端·后端·算法·架构·uni-app·php
冰暮流星3 小时前
javascript事件案例-全选框案例
服务器·前端·javascript
Csvn4 小时前
前端性能优化实战指南
前端
Moment4 小时前
2026 年,AI 全栈时代到了,前端简历别再只写前端技术了 🫠🫠🫠
前端·后端·面试
糯米团子7494 小时前
Web Worker
开发语言·前端·javascript
freewlt4 小时前
React Server Components 深度解析
前端·react.js·前端框架
wordbaby4 小时前
一次跨端 Loading 卡死复盘:把请求计数从 Axios 拦截器迁到 try/catch/finally
前端·axios
我命由我123454 小时前
JavaScript 开发 - 获取函数名称、获取函数参数数量、获取函数参数名称
开发语言·前端·javascript·css·html·html5·js