Node+Express+Babel项目启动报错:Cannot use 'import.meta' outside a module
解决方法
方案1:将编译产物改为ES模块(推荐,保留import.meta.url)
这个方案让Node以ES模块模式运行编译后的代码,直接支持import.meta.url,同时源码继续使用ES6语法。
步骤:
- 修改
package.json,添加"type": "module",告知Node当前项目采用ES模块规范:
{ "type": "module", "scripts": { "dev": "...", "build": "...", "start": "node build/index.js" } }
- 调整Babel配置(
.babelrc.js),确保编译目标为ES模块而非CommonJS:
module.exports = { presets: [ ['@babel/preset-env', { targets: { node: 'current' }, modules: false // 关键:不转换ES模块语法为CommonJS }] ] };
- 重新编译并启动项目:
npm run build npm start
编译后的代码会保留ES模块语法和import.meta.url,Node以ES模块模式运行时可正常识别。
方案2:将import.meta.url转换为CommonJS兼容写法
如果需要编译产物保持CommonJS模式,可以把import.meta.url替换为CommonJS环境支持的等价代码,同时保留源码ES6语法。
手动替换写法:
将源码中获取当前文件目录的代码,改成兼容ES模块和CommonJS的版本:
import path from 'path'; // 兼容两种模块规范的__dirname获取 const __dirname = typeof __dirname !== 'undefined' ? __dirname : path.dirname(new URL(import.meta.url).pathname);
用Babel插件自动转换:
- 安装转换插件:
npm install babel-plugin-transform-import-meta --save-dev
- 修改Babel配置,添加该插件:
module.exports = { presets: [ ['@babel/preset-env', { targets: { node: 'current' }, modules: 'commonjs' // 保持编译为CommonJS }] ], plugins: ['babel-plugin-transform-import-meta'] };
插件会自动将import.meta.url转换为CommonJS环境的等价代码,无需手动修改源码。
- 重新编译启动:
npm run build npm start
方案3:直接使用项目根目录(需求允许时)
如果资源路径基于项目根目录而非当前文件目录,可直接用process.cwd()获取项目启动时的工作目录:
const projectRoot = process.cwd(); // 示例:访问项目根目录下的assets资源 const assetPath = path.join(projectRoot, 'assets', 'logo.png');
这种写法无需依赖import.meta.url或__dirname,同时兼容ES模块和CommonJS。
内容的提问来源于stack exchange,提问作者davidesp
相关产品推荐
相关产品推荐

