详解Node.js如何处理ES6模块


Posted in Javascript onMay 15, 2021

一、两种模块的差异

ES6 模块和 CommonJS 模块有很大的差异。

语法上面,CommonJS 模块使用require()加载和module.exports输出,ES6 模块使用import和export。

用法上面,require()是同步加载,后面的代码必须等待这个命令执行完,才会执行。import命令则是异步加载,或者更准确地说,ES6 模块有一个独立的静态解析阶段,依赖关系的分析是在那个阶段完成的,最底层的模块第一个执行。

二、Node.js 的区分

Node.js 要求 ES6 模块采用.mjs后缀文件名。也就是说,只要脚本文件里面使用import或者export命令,那么就必须采用.mjs后缀名。Node.js 遇到.mjs文件,就认为它是 ES6 模块,默认启用严格模式,不必在每个模块文件顶部指定"use strict"。

如果不希望将后缀名改成.mjs,可以在项目的package.json文件中,指定type字段为module。

{
   "type": "module"
}

一旦设置了以后,该目录里面的 JS 脚本,就被解释用 ES6 模块。

# 解释成 ES6 模块

$ node my-app.js

如果这时还要使用 CommonJS 模块,那么需要将 CommonJS 脚本的后缀名都改成.cjs。如果没有type字段,或者type字段为commonjs,则.js脚本会被解释成 CommonJS 模块。

总结为一句话:.mjs文件总是以 ES6 模块加载,.cjs文件总是以 CommonJS 模块加载,.js文件的加载取决于package.json里面type字段的设置。

注意,ES6 模块与 CommonJS 模块尽量不要混用。require命令不能加载.mjs文件,会报错,只有import命令才可以加载.mjs文件。反过来,.mjs文件里面也不能使用require命令,必须使用import。

三、CommonJS 模块加载 ES6 模块

CommonJS 的require()命令不能加载 ES6 模块,会报错,只能使用import()这个方法加载。

(async () => {
  await import('./my-app.mjs');
})();

上面代码可以在 CommonJS 模块中运行。

require()不支持 ES6 模块的一个原因是,它是同步加载,而 ES6 模块内部可以使用顶层await命令,导致无法被同步加载。

四、ES6 模块加载 CommonJS 模块

ES6 模块的import命令可以加载 CommonJS 模块,但是只能整体加载,不能只加载单一的输出项。

// 正确
import packageMain from 'commonjs-package';

// 报错
import { method } from 'commonjs-package';

这是因为 ES6 模块需要支持静态代码分析,而 CommonJS 模块的输出接口是module.exports,是一个对象,无法被静态分析,所以只能整体加载。

加载单一的输出项,可以写成下面这样。

import packageMain from 'commonjs-package';
const { method } = packageMain;

五、同时支持两种格式的模块

一个模块同时要支持 CommonJS 和 ES6 两种格式,也很容易。

如果原始模块是 ES6 格式,那么需要给出一个整体输出接口,比如export default obj,使得 CommonJS 可以用import()进行加载。

如果原始模块是 CommonJS 格式,那么可以加一个包装层。

import cjsModule from '../index.js';
export const foo = cjsModule.foo;

上面代码先整体输入 CommonJS 模块,然后再根据需要输出具名接口。

你可以把这个文件的后缀名改为.mjs,或者将它放在一个子目录,再在这个子目录里面放一个单独的package.json文件,指明{ type: "module" }。

另一种做法是在package.json文件的exports字段,指明两种格式模块各自的加载入口。

"exports":{ 
    "require": "./index.js",
    "import": "./esm/wrapper.js" 
}

上面代码指定require()和import,加载该模块会自动切换到不一样的入口文件。

以上就是详解Node.js如何处理ES6模块的详细内容,更多关于Node.js如何处理 ES6 模块的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
一款js和css代码压缩工具[附JAVA环境配置方法]
Apr 16 Javascript
IE与FireFox中的childNodes区别
Oct 20 Javascript
刷新页面的几种方法小结(JS,ASP.NET)
Jan 07 Javascript
window.location不跳转的问题解决方法
Apr 17 Javascript
原生js实现可爱糖果数字时间特效
Dec 30 Javascript
javascript实现循环广告条效果
Dec 12 Javascript
Vue配合iView实现省市二级联动的示例代码
Jul 27 Javascript
vue开发环境配置跨域的方法步骤
Jan 16 Javascript
使用vue for时为什么要key【推荐】
Jul 11 Javascript
微信小程序如何实现点击图片放大功能
Jan 21 Javascript
原生JS封装拖动验证滑块的实现代码示例
Jun 01 Javascript
jQuery实现飞机大战小游戏
Jul 05 jQuery
详解vue中v-for的key唯一性
解读Vue组件注册方式
May 15 #Vue.js
如何理解Vue简单状态管理之store模式
May 15 #Vue.js
Vue如何实现组件间通信
May 15 #Vue.js
详解Vue的sync修饰符
May 15 #Vue.js
深入理解Vue的数据响应式
May 15 #Vue.js
详解Vue的options
May 15 #Vue.js
You might like
PHP脚本的10个技巧(1)
2006/10/09 PHP
php面向对象全攻略 (二) 实例化对象 使用对象成员
2009/09/30 PHP
win7 64位系统 配置php最新版开发环境(php+Apache+mysql)
2014/08/15 PHP
PHP文字转图片功能原理与实现方法分析
2017/08/31 PHP
PHP实现求连续子数组最大和问题2种解决方法
2017/12/26 PHP
javascript基本语法分析说明
2008/06/15 Javascript
checkbox 多选框 联动实现代码
2008/10/22 Javascript
JavaScript调用Activex控件的事件的实现方法
2010/04/11 Javascript
基于jquery的修改当前TAB显示标题的代码
2010/12/11 Javascript
使用jquery为table动态添加行的实现代码
2011/03/30 Javascript
JS上传图片前的限制包括(jpg jpg gif及大小高宽)等
2012/12/19 Javascript
js控制table合并具体实现
2014/02/20 Javascript
JavaScript实现基于Cookie的存储类实例
2015/04/10 Javascript
javascript实现网页子页面遍历回调的方法(涉及 window.frames、递归函数、函数上下文)
2015/07/27 Javascript
jQuery EasyUI框架中的Datagrid数据表格组件结构详解
2016/06/09 Javascript
javascript时间差插件分享
2016/07/18 Javascript
AngularJS实现单独作用域内的数据操作
2016/09/05 Javascript
jQuery实现大图轮播
2017/02/13 Javascript
jQuery中ajax请求后台返回json数据并渲染HTML的方法
2018/08/08 jQuery
Vue CLI3创建项目部署到Tomcat 使用ngrok映射到外网
2019/05/16 Javascript
使用Python获取CPU、内存和硬盘等windowns系统信息的2个例子
2014/04/15 Python
python中os模块详解
2016/10/14 Python
如何利用python查找电脑文件
2018/04/27 Python
通过cmd进入python的实例操作
2019/06/26 Python
python按行读取文件并找出其中指定字符串
2019/08/08 Python
django为Form生成的label标签添加class方式
2020/05/20 Python
Python类的继承super相关原理解析
2020/10/22 Python
Python日志打印里logging.getLogger源码分析详解
2021/01/17 Python
印度尼西亚最大和最全面的网络商城:Blibli.com
2017/10/04 全球购物
联想中国官方商城:Lenovo China
2017/10/18 全球购物
结构工程个人自荐信范文
2013/11/30 职场文书
五一劳动节活动记录
2014/03/23 职场文书
槐乡的孩子教学反思
2014/04/27 职场文书
装修安全责任协议书
2016/03/22 职场文书
Vue3中toRef与toRefs的区别
2022/03/24 Vue.js
react中useState使用:如何实现在当前表格直接更改数据
2022/08/05 Javascript