问题
vite3.0版本热更新无效,所以升级到5.0,项目启动报错:
The CJS build of Vite's Node API is deprecated. See https://vitejs.dev/guide/troubleshooting.html#vite-cjs-node-api-deprecated for more details.
分析
vue5废弃用CJS节点deprecate-cjs-node-api 使用ESM替代
Vite 的 CJS Node API 已弃用。调用时require('vite'),现在会记录弃用警告。您应该更新您的文件或框架以导入 Vite 的 ESM 版本。
在一个基础的Vite项目中,需要保证:
- 文件
vite.config.js内容使用ESM语法。 package.json文件具有"type": "module",或使用.mjs扩展名,例vite.config.mjs。
对于其他项目,有一些通用方法:
- 将 ESM 配置为默认值,如果需要,选择加入 CJS: 添加
"type": "module"到项目中package.json。所有*.js文件现在都解释为 ESM,并且需要使用 ESM 语法。您可以使用扩展名重命名文件.cjs来继续使用 CJS。 - 将 CJS 保留为默认值,如果需要,选择加入 ESM: 如果项目
package.json没有"type": "module",则所有*.js文件都将解释为 CJS。您可以使用扩展名重命名文件.mjs以改用 ESM。 - 动态导入Vite: 如果需要继续使用CJS,改为
import('vite')可以使用动态导入Vite。这要求你的代码是在async上下文中编写的,但仍然应该易于管理,因为Vite的API大部分是异步的。
问题扩展
CommonJS (CJS) 和 ECMAScript Modules (ESM) 是两种不同的 JavaScript 模块化标准,它们在语法和功能上有一些关键区别。
什么是 CJS?
- 主要用途:最初设计用于 Node.js。
- 导出模块:使用 module.exports 或 exports。
- 导入模块:使用 require() 函数。
- 加载方式:同步加载,适合服务端。
示例:
// CJS 导出
// math.js
function add(a, b) {
return a + b;
}
module.exports = { add };
// CJS 导入
// main.js
const math = require('./math.js');
console.log(math.add(2, 3)); // 输出 5
什么是 ESM?
- 主要用途:作为 JavaScript 的官方标准,用于浏览器和现代 Node.js。
- 导出模块:使用 export 关键字。
- 导入模块:使用 import 语句。
- 加载方式:可以是异步的,适合服务端和客户端。
示例:
// ESM 导出
// math.js
export function add(a, b) {
return a + b;
}
// ESM 导入
// main.js
import { add } from './math.js';
console.log(add(2, 3)); // 输出 5
CJS 和 ESM 的区别
- 语法:CJS 使用 require 和 module.exports,而 ESM 使用 import 和 export。
- 加载机制:CJS 是同步的,通常用于服务器端。ESM 支持异步加载,适用于浏览器和服务器。
- 生态系统兼容性:Node.js 最初只支持 CJS,但现在也支持 ESM。ESM 是现代浏览器支持的标准。
- 模块解析:CJS 模块解析时可以省略文件扩展名和目录索引文件,而 ESM 则更严格,通常需要完整的路径和文件扩展名。
随着 JavaScript 生态系统的发展,ESM 正在逐渐成为主流,特别是在前端开发中,由于其支持异步和静态分析的优势。
Vite 为什么弃用 CJS?
Vite 作为一个现代前端构建工具,越来越多地依赖于 ESM 特性,例如更好的静态分析和模块化能力。随着 Vite 的更新,对 CJS 支持逐渐减少,因此旧的 CJS 模块可能不再兼容。
解决
- 在package.json中添加
type:modle
"type": "module",
-
修改
vite.config.js为vite.config.mjs;如果是ts,修改vite.config.ts为vite.config.mts -
修改
tsconfig.json中include:["vite.config.mts"]
参考文献: