详解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 相关文章推荐
jQuery实现图片信息的浮动显示实例代码
Aug 28 Javascript
js判断60秒以及倒计时示例代码
Jan 24 Javascript
extJS中常用的4种Ajax异步提交方式
Mar 07 Javascript
js中定义一个变量并判断其是否为空的方法
May 13 Javascript
Node.js实现简单聊天服务器
Jun 20 Javascript
javascript实现图片自动和可控的轮播切换特效
Apr 13 Javascript
JavaScript浏览器对象模型BOM(BrowserObjectModel)实例详解
Nov 29 Javascript
node中koa中间件机制详解
Aug 22 Javascript
对vuejs的v-for遍历、v-bind动态改变值、v-if进行判断的实例讲解
Aug 27 Javascript
js序列化和反序列化的使用讲解
Jan 19 Javascript
深入浅析nuxt.js基于ssh的vue通用框架
May 21 Javascript
小程序api实现promise封装过程解析
Nov 21 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中使用Oracle数据库(4)
2006/10/09 PHP
在php中判断一个请求是ajax请求还是普通请求的方法
2011/06/28 PHP
Zend Framework教程之Zend_Layout布局助手详解
2016/03/04 PHP
浅谈php中curl、fsockopen的应用
2016/12/10 PHP
详解php中serialize()和unserialize()函数
2017/07/08 PHP
php微信公众号开发之图片回复
2018/10/20 PHP
Laravel框架自定义验证过程实例分析
2019/02/01 PHP
PHP精确到毫秒秒杀倒计时实例详解
2019/03/14 PHP
php使用redis的有序集合zset实现延迟队列应用示例
2020/02/20 PHP
建立良好体验度的Web注册系统ajax
2007/07/09 Javascript
javascript实现的网页局布刷新效果
2008/12/01 Javascript
jQuery+ajax实现动态执行脚本的方法
2015/01/27 Javascript
基于js实现二级下拉联动
2016/12/17 Javascript
深究AngularJS——ng-checked(回写:带真实案例代码)
2017/06/13 Javascript
jQuery实现打开网页自动弹出遮罩层或点击弹出遮罩层功能示例
2017/10/19 jQuery
基于vue2.x的电商图片放大镜插件的使用
2018/01/22 Javascript
微信小程序云开发如何实现数据库自动备份实现
2019/08/16 Javascript
Jquery动态列功能完整实例
2019/08/30 jQuery
jQuery实现高度灵活的表单验证功能示例【无UI】
2020/04/30 jQuery
element-ui中el-upload多文件一次性上传的实现
2020/12/02 Javascript
微信小程序自定义支持图片的弹窗
2020/12/21 Javascript
Vue多选列表组件深入详解
2021/03/02 Vue.js
关于Django显示时间你应该知道的一些问题
2017/12/25 Python
Python3中内置类型bytes和str用法及byte和string之间各种编码转换 问题
2018/09/27 Python
python 制作自定义包并安装到系统目录的方法
2018/10/27 Python
python计算两个矩形框重合百分比的实例
2018/11/07 Python
简单了解python的break、continue、pass
2019/07/08 Python
python 并发编程 阻塞IO模型原理解析
2019/08/20 Python
利用python实现逐步回归
2020/02/24 Python
Python操作dict时避免出现KeyError的几种解决方法
2020/09/20 Python
英国最大的滑板品牌选择:Route One
2019/09/22 全球购物
宿舍违规检讨书
2014/01/12 职场文书
试用期自我鉴定范文
2014/03/20 职场文书
2015年项目经理工作总结
2015/04/30 职场文书
Mysql中@和@@符号的详细使用指南
2022/06/05 MySQL
CSS中理解层叠性及权重如何分配
2022/12/24 HTML / CSS