详解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 相关文章推荐
javascript Array.remove() 数组删除
Aug 06 Javascript
extjs tabpanel限制选项卡数量实现思路及代码
Apr 02 Javascript
jquery如何获取复选框的值
Dec 12 Javascript
jqGrid随窗口大小变化自适应大小的示例代码
Dec 28 Javascript
javascript 判断一个对象为数组的方法
May 03 Javascript
详解Javascript获取缓存和清除缓存API
May 25 Javascript
JavaScript实现获取用户单击body中所有A标签内容的方法
Jun 05 Javascript
新手vue构建单页面应用实例代码
Sep 18 Javascript
推荐10款扩展Web表单的JS插件
Dec 25 Javascript
关于vuejs中v-if和v-show的区别及v-show不起作用问题
Mar 26 Javascript
JS/HTML5游戏常用算法之碰撞检测 地图格子算法实例详解
Dec 12 Javascript
JavaScript实现与使用发布/订阅模式详解
Jan 19 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具体实现代码
2010/10/12 PHP
跟我学Laravel之视图 & Response
2014/10/15 PHP
php面向对象值单例模式
2016/05/03 PHP
PHP设计模式之装饰器(装饰者)模式(Decorator)入门与应用详解
2019/12/13 PHP
在一个浏览器里呈现所有浏览器测试结果的前端测试工具的思路
2010/03/02 Javascript
javascript+iframe 实现无刷新载入整页的代码
2010/03/17 Javascript
一个可拖拽列宽表格实例演示
2012/11/26 Javascript
js 获取和设置css3 属性值的实现方法
2013/05/06 Javascript
js渐变显示渐变消失示例代码
2013/08/01 Javascript
再JavaScript的jQuery库中编写动画效果的指南
2015/08/13 Javascript
JQuery手速测试小游戏实现思路详解
2016/09/20 Javascript
JS+canvas画一个圆锥实例代码
2017/12/13 Javascript
vue-router路由懒加载的实现(解决vue项目首次加载慢)
2018/08/28 Javascript
微信小程序缓存过期时间的使用详情
2019/05/12 Javascript
Vue+Typescript中在Vue上挂载axios使用时报错问题
2019/08/07 Javascript
Vue分页效果与购物车功能
2019/12/13 Javascript
JS实现随机点名器
2020/04/12 Javascript
[03:51]吞吞映像 每周精彩击杀top10第二弹
2014/06/25 DOTA
[52:52]DOTA2上海特级锦标赛C组资格赛#1 OG VS LGD第三局
2016/02/27 DOTA
详解Python中for循环的使用方法
2015/05/14 Python
Python实现在线音乐播放器
2017/03/03 Python
python redis 删除key脚本的实例
2019/02/19 Python
详解Python给照片换底色(蓝底换红底)
2019/03/22 Python
Python3.5内置模块之random模块用法实例分析
2019/04/26 Python
基于python的selenium两种文件上传操作实现详解
2019/09/19 Python
Python绘制三角函数图(sin\cos\tan)并标注特定范围的例子
2019/12/04 Python
python文件绝对路径写法介绍(windows)
2019/12/25 Python
Python collections.deque双边队列原理详解
2020/10/05 Python
Python实例教程之检索输出月份日历表
2020/12/16 Python
css3一个简易的 LED 数字时钟实现方法
2020/01/15 HTML / CSS
美国时尚大码女装购物网站:Avenue
2019/05/24 全球购物
团队口号大全
2014/06/06 职场文书
个人年终总结怎么写
2015/03/09 职场文书
深入浅出讲解Java8函数式编程
2022/01/18 Java/Android
Python绘画好看的星空图
2022/03/17 Python
MySQL数据库安装方法与图形化管理工具介绍
2022/05/30 MySQL