为什么 ES6 import 可以直接导入commonJS的模块

新手上路,请多包涵

一个CommonJS规范编写的包, 比如node_modules中很多包时commonJS规范的,但是可以直接用 import xxx from 'xxx'的形式,不是说CommonJS规范编写的包只能用require吗,而ES6模块化的包才能用import吗

阅读 4.9k
2 个回答

不能混用,你觉得能混用只是因为这个包它同时提供了两种导出,既提供了CommonJS的exports,也提供了ES6的export,在package.json里它是这么写的:

{
    "main": "aaa.js",
    "module": "aaa.module.js"
}

如果你用require,那么它就用aaa.js,如果你用import,那么它就用aaa.module.js,这都是在webpack编译时决定的。

我也是跟这儿学的: https://blog.csdn.net/huzhenv...


已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。

基于

我也是跟这儿学的: https://blog.csdn.net/huzhenv...

补充一些细节。

我们先抛开构建工具,面向node环境。

node<12时,我们在node使用esm语法,node显式地要求你需要使用.mjs 文件后缀
Node.js 12 has full ESM support! 当 package.json 设置为 type:"module"。我们就不需要mjs后缀了。

但是node模块化机制严格使我们确实是无法同时使用esm与commonjs的,并且会有很明显的错误提示

面向构建工具

webpack

对于webpack而言,import require都是引用/依赖关系的关键词
webpack的模块化模型,决定了它最后会将import require 转化为自己的运行时方法
例如我们产物中常见的__webpack_require__
所以在这个情况下仍然是webpack帮我们做了转化兼容,且基于webpack运行时模块化模型,无需任何插件,无需babel转换,webpack天生就可以实现这一点(import 一个commonjs模块)

额外的tips:
在webpack中,模块混用有额外的定义,即单模块内的模块混用。
eg.

// a wrong/error file
import X from "./xxx"
exports.xxx
module.exports={xxx}

但是这个仍然是由于自身的模块化模型的限制,webpack会为不同的模块使用不同的产物生成模版,例如umd template esm template commonjs template

rollup

https://www.npmjs.com/package... 插件的转换使得我们可以import 一个commonjs模块

vite

esbuild 依赖预构建 使得我们可以import 一个commonjs模块

额...再总结一点吧。综上所述。
你提问的import a commonjs file 与 package.json的field 字段无关。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题