在前端开发内容学习中,ES模块和commonJS两种标准下中实现__dirname?一篇文章教你理清楚是常见主题。很多人在阅读时会遇到概念分散、步骤不清和注意点难以归纳的问题。本文按照基础概念、操作流程和关键细节,对相关内容进行整理。
开头先了解一下console.log(import.meta)的输出结果和node版本 node-v 指令 以便更好了解。
"type":"module")无需导入任何模块,文件内原生存在 __dirname / __filename
js
// webpack.config.cjs / index.js(CJS)
const path = require('path');
// 当前文件所在文件夹绝对路径
console.log(__dirname);
// 当前文件完整绝对路径
console.log(__filename);
module.exports = {
output: {
path: path.resolve(__dirname, 'dist')
}
};
.js 文件默认识别为 CJS__dirname、__filename,零配置require()、module.exports / exportswebpack 学习、后端 Node 脚本、旧项目,最推荐新手
"type": "module").js 文件都是 ES Module__dirname、__filename,必须手动计算import / export default,不能用 require、module.exports依赖内置 url + path 模块,import.meta.url 是文件自带 file:// 协议地址
js
// webpack.config.js(ESM)
import path from 'path';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
// 把 file:// 链接转为本地文件绝对路径,这里取__filename1,避免混淆
const __filename1 = fileURLToPath(import.meta.url);
// 从文件路径取出所在目录 = __dirname
const __dirname = dirname(__filename1);
export default {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist')
}
};
fileURLToPath 只能接收 import.meta.urlimport.meta.dirname(已经是字符串,会报 URL 协议错误)Node20 新增 import.meta.dirname 语法糖,直接等价上面整套代码
js
import path from 'path';
const __dirname = import.meta.dirname;
export default {
output: {
path: path.resolve(__dirname, 'dist')
}
};
换 Node18/16 环境直接报错,不适合通用项目
Cannot use import statement outside a modulepackage.json 没加 "type":"module",但文件用了 import → 切换 CJS 或开启 type:module
__dirname is not defined开启 type:module 后,原生全局变量消失,必须手动用 fileURLToPath 生成
ERR_INVALID_URL_SCHEME错误写法:fileURLToPath(import.meta.dirname)原因:import.meta.dirname 是本地路径字符串,不是 file:// URL,只能传 import.meta.url
表格
| 对比项 | CommonJS(无 type:module) | ESM("type":"module") |
|---|---|---|
__dirname | 全局自带,直接用 | 无,需手动计算 |
| 导入导出 | require() / module.exports | import / export default |
| 路径获取 | __dirname | fileURLToPath(import.meta.url) |
| Node 版本兼容 | 全版本兼容 | Node14.13+ 完整支持 |
| webpack 配置推荐度 | ⭐⭐⭐⭐⭐ 新手首选 | ⭐⭐⭐ 需额外处理路径 |
| 浏览器代码能否用 Node 模块 | 同样不能 | 同样不能 |