详解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 对Cookie 操作的封装小结
Dec 31 Javascript
Extjs入门之动态加载树代码
Apr 09 Javascript
jquery 面包屑导航 具体实现
Jun 05 Javascript
禁止空格提交表单的js代码
Nov 17 Javascript
随鼠标上下滚动的jquery代码
Dec 05 Javascript
浅谈Javascript变量作用域问题
Dec 16 Javascript
zepto.js中tap事件阻止冒泡的实现方法
Feb 12 Javascript
Vuejs第十二篇之动态组件全面解析
Sep 09 Javascript
JavaScript字符串对象
Jan 14 Javascript
如何用input标签和jquery实现多图片的上传和回显功能
May 16 jQuery
vue父子组件间引用之$parent、$children
May 20 Javascript
Vue登录拦截 登录后继续跳转指定页面的操作
Aug 04 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通过COM使用ADODB的简单例子
2006/12/31 PHP
.htaccess文件保护实例讲解
2011/02/06 PHP
PHP之图片上传类实例代码(加了缩略图)
2016/06/30 PHP
FF IE兼容性的修改小结
2009/09/02 Javascript
基于jQuery制作迷你背词汇工具
2010/07/27 Javascript
让浏览器非阻塞加载javascript的几种方法小结
2011/04/25 Javascript
在每个匹配元素的外部插入新元素的方法
2013/12/20 Javascript
SeaJS入门教程系列之使用SeaJS(二)
2014/03/03 Javascript
JavaScript的arguments对象应用示例
2014/09/15 Javascript
js父页面与子页面不同时显示的方法
2014/10/16 Javascript
Angularjs全局变量被作用域监听的正确姿势
2016/02/06 Javascript
微信小程序 loading(加载中提示框)实例
2016/10/28 Javascript
JS重载实现方法分析
2016/12/16 Javascript
nodejs入门教程四:URL相关模块用法分析
2017/04/24 NodeJs
ng-events类似ionic中Events的angular全局事件
2018/09/05 Javascript
微信小程序获取用户openid的实现
2018/12/24 Javascript
在element-ui的select下拉框加上滚动加载
2019/04/18 Javascript
react中hook介绍以及使用教程
2020/12/11 Javascript
[01:32]dota2拉比克至宝(222)
2018/12/20 DOTA
如何在Django配置文件里配置session链接
2019/08/06 Python
win10安装tensorflow-gpu1.8.0详细完整步骤
2020/01/20 Python
浅谈pycharm导入pandas包遇到的问题及解决
2020/06/01 Python
Tensorflow--取tensorf指定列的操作方式
2020/06/30 Python
CSS3 渐变(Gradients)之CSS3 径向渐变
2016/07/08 HTML / CSS
网络编程中设计并发服务器,使用多进程与多线程,请问有什么区别?
2016/03/27 面试题
abstract 可以和 virtual 一起使用吗?可以和 override 一起使用吗?
2012/10/15 面试题
国窖1573广告词
2014/03/21 职场文书
《画杨桃》教学反思
2014/04/13 职场文书
车队司机个人自我鉴定
2014/04/17 职场文书
园林专业毕业生自荐信
2014/07/04 职场文书
四风自我剖析材料
2014/09/30 职场文书
老龙头导游词
2015/02/11 职场文书
2016高考冲刺决心书
2015/09/23 职场文书
酒店工程部的岗位职责汇总大全
2019/10/23 职场文书
Nginx源码编译安装过程记录
2021/11/17 Servers
Nginx流量拷贝ngx_http_mirror_module模块使用方法详解
2022/04/07 Servers