作为 JavaScript 和 TypeScript 开发人员,我们在使用不同的模块系统时经常会遇到意外的错误。一个常见问题是“无法在模块外部使用 import 语句”错误。它通常在使用现代 ES 模块 (ESM) 或处理涉及 Webpack、Babel 或 Node.js 环境等捆绑程序的设置时出现。在这篇博客中,我们将探讨导致此错误的原因、发生的原因以及解决该错误的实用解决方案。
“无法在模块外部使用 import 语句”错误是不言自明的:当 JavaScript 遇到有效 ES 模块外部的 import 语句时,就会发生这种情况。在 JavaScript 中,模块系统决定如何拆分代码到多个文件以及它们如何相互交互 ES 模块(导入/导出)和 CommonJS(require/module.exports)是两个主要的模块系统。
如果 JavaScript 无法将您的代码识别为 ES 模块,则会抛出此错误。
这通常发生在 JavaScript/TypeScript 遇到模块上下文之外的 import 语句时。这意味着您尝试导入的文件未被识别为 ES 模块。
以下是可能发生此错误的一些更常见的原因:
Node.js 默认使用 CommonJS:默认情况下,Node.js 使用 CommonJS (CJS) 模块,而不是 ES 模块。这意味着除非指定,否则本机不支持导入/导出语法。
Babel/Webpack 配置错误:捆绑代码时,Babel 或 Webpack 等工具可能无法配置为正确处理 ES 模块,特别是在目标环境本身不支持它们的情况下。
package.json 中缺少 "type": "module":如果您在 Node.js 项目中使用 ES 模块,则需要通过添加 "type" 来显式指定它:package.json中的“模块”。
文件扩展名不匹配:有时,对于 ES 模块使用 .js 而不是 .mjs,反之亦然可能会导致此错误。
以下是修复“无法在模块外部使用 import 语句”错误的一些解决方案:
最常见的情况是当您使用 Node.js 时,它默认为 CommonJS 模块。要启用 ES 模块,请执行以下操作:
方法一:修改package.json:
{ "type": "module" }
通过在 package.json 中添加 "type": "module" ,您可以告诉 Node.js 将所有 .js 文件视为 ES 模块。
方法2:将文件重命名为.mjs:
如果您不想修改 package.json,可以将文件重命名为 .mjs(例如,index.mjs)以明确表明它们是 ES 模块。
如果您使用 Babel 或 Webpack,请确保它们配置为正确处理 ES 模块。对于 Babel,您可以使用 @babel/preset-modules 插件。对于 Webpack,请在配置中将 module 设置为 false。
对于 Babel:更新 .babelrc 或 babel.config.json 文件:
{ "presets": ["@babel/preset-modules"] }
对于 Webpack:更新 webpack.config.js 文件:
module.exports = { module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'] } } } ] } };
确保您的导入路径正确并且使用正确的语法。例如,相对路径应以 ./ 或 ../.
开头如果您从node_modules导入模块,请确保该包支持ES模块。如果没有,您可能需要使用像 Webpack 这样的捆绑器来处理它。
如果您使用 ES 模块,请确保您的文件扩展名与模块类型匹配。 ES 模块使用 .mjs,CommonJS 模块使用 .js。
所以我想到的一件事是 ES 模块和 CommonJS 模块有什么区别?为什么 JavaScript 中有两种不同的模块系统?
ES 模块是 ES6 (ES2015) 中引入的官方 JavaScript 模块系统。他们使用 import 和 export 关键字来定义模块之间的依赖关系。 ES 模块是可静态分析的,这意味着依赖关系在编译时就已解决,从而更容易优化代码。
ES模块是异步加载的,这样可以实现更好的性能和模块的并行加载。它们还支持命名导出、默认导出和循环依赖。 ES 模块在现代浏览器和 Node.js 中得到广泛支持(带有“type”:“module”标志)。
CommonJS 是在 ES 模块引入之前在 Node.js 和其他环境中使用的模块系统。 CommonJS 模块使用 require 函数导入模块并使用 module.exports 或导出来导出值。 CommonJS 模块是同步加载的,这可能会导致性能问题。
浏览器本身不支持 CommonJS 模块,但可以使用 Babel 或 Webpack 等工具将它们转译为 ES 模块。 CommonJS 模块在 Node.js 项目中仍然广泛使用,但 ES 模块由于其更好的性能和静态可分析性而变得越来越流行。
这两个模块系统存在的原因是由于 JavaScript 的发展以及对更现代、标准化的模块系统的需求。 ES 模块是 JavaScript 模块的未来,但 CommonJS 模块仍在现有项目和环境中广泛使用。
如果您已尝试上述所有解决方案,但仍然遇到错误,这里有一些额外的调试技巧:
检查 Node.js 版本:确保您运行的是 Node.js 版本 12.x 或更高版本,因为 ES 模块支持是在 Node.js 12 中原生引入的。在旧版本上,ES 模块将无法工作。通过访问 Node.js 网站更新您的版本。
检查浏览器支持:如果您在浏览器环境中工作,请确保您的浏览器支持 ES 模块。大多数现代浏览器都可以,但旧版本可能不会。
检查拼写错误:有时,代码中的简单拼写错误可能会导致此错误。仔细检查您的代码是否有任何拼写错误或不正确的语法。
使用 npx tsc for TypeScript:如果您使用 TypeScript 并遇到此错误,请运行 npx tsc 将 TypeScript 代码编译为 JavaScript,这可能有助于发现问题。
“无法在模块外部使用 import 语句”错误是 JavaScript/TypeScript 开发人员在使用 ES 模块时面临的常见问题。通过了解发生此错误的原因并遵循本博客中提供的分步解决方案,您可以快速解决该错误并继续构建模块化、可维护的代码。
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3