详解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控制代码暂停的实现方法分享
Oct 11 Javascript
jQuery制作简洁的图片轮播效果
Apr 03 Javascript
javascript性能优化之事件委托实例详解
Dec 12 Javascript
详解MVC如何使用开源分页插件(shenniu.pager.js)
Dec 16 Javascript
jQuery插件HighCharts绘制的2D堆柱状图效果示例【附demo源码下载】
Mar 14 Javascript
JavaScript中undefined和null的区别
May 03 Javascript
JavaScript设计模式之代理模式详解
Jun 09 Javascript
vue弹窗消息组件的使用方法
Sep 24 Javascript
webpack4简单入门实例
Sep 06 Javascript
探索JavaScript中私有成员的相关知识
Jun 13 Javascript
js如何获取访问IP、地区、当前操作浏览器
Jul 23 Javascript
基于layui的下拉列表的数据回显方法
Sep 24 Javascript
详解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弹出错误警告函数扩展性强
2014/01/17 PHP
PHP实现定时执行任务的方法
2014/10/05 PHP
InnerHtml和InnerText的区别分析
2009/03/13 Javascript
再谈ie和firefox下的document.all属性
2009/10/21 Javascript
Jvascript学习实践案例(开发常用)
2012/06/25 Javascript
EasyUI修改DateBox和DateTimeBox的默认日期格式示例
2017/01/18 Javascript
JS常用正则表达式总结【经典】
2017/05/12 Javascript
基于Bootstrap模态对话框只加载一次 remote 数据的解决方法
2017/07/09 Javascript
浅谈原生JS中的延迟脚本和异步脚本
2017/07/12 Javascript
Vue+Element使用富文本编辑器的示例代码
2017/08/14 Javascript
ES6学习教程之块级作用域详解
2017/10/09 Javascript
react-native使用leanclound消息推送的方法
2018/08/06 Javascript
你应该了解的JavaScript Array.map()五种用途小结
2018/11/14 Javascript
tweenjs缓动算法的使用实例分析
2019/08/26 Javascript
JavaScript设计模式之门面模式原理与实现方法分析
2020/03/09 Javascript
[02:39]DOTA2国际邀请赛助威团西雅图第一天
2013/08/08 DOTA
[03:48]显微镜下的DOTA2第四期——TP动作
2014/06/20 DOTA
[02:34]肉山说——泡妞篇
2014/09/16 DOTA
python中redis的安装和使用
2016/12/04 Python
Python基础语言学习笔记总结(精华)
2017/11/14 Python
单利模式及python实现方式详解
2018/03/20 Python
Python实现找出数组中第2大数字的方法示例
2018/03/26 Python
Python简单实现阿拉伯数字和罗马数字的互相转换功能示例
2018/04/17 Python
matplotlib 输出保存指定尺寸的图片方法
2018/05/24 Python
浅谈numpy生成数组的零值问题
2018/11/12 Python
Python爬虫实现爬取百度百科词条功能实例
2019/04/05 Python
Python Datetime模块和Calendar模块用法实例分析
2019/04/15 Python
Django使用消息提示简单的弹出个对话框实例
2019/11/15 Python
Python爬虫实战案例之爬取喜马拉雅音频数据详解
2020/12/07 Python
python实现模拟器爬取抖音评论数据的示例代码
2021/01/06 Python
android面试问题与答案
2016/12/27 面试题
喜之郎果冻广告词
2014/03/20 职场文书
中秋晚会策划方案
2014/06/12 职场文书
教师培训学习心得体会
2016/01/21 职场文书
浅谈MySql整型索引和字符串索引失效或隐式转换问题
2021/11/20 MySQL
Python测试框架pytest核心库pluggy详解
2022/08/05 Golang