详解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 相关文章推荐
25个优雅的jQuery Tooltip插件推荐
May 25 Javascript
模拟select的代码
Oct 19 Javascript
js 字符串转换成数字的三种方法
Mar 23 Javascript
图片上传判断及预览脚本的效果实例
Aug 07 Javascript
jQuery中通过ajax的get()函数读取页面的方法
Feb 29 Javascript
javaScript给元素添加多个class的简单实现
Jul 20 Javascript
让DIV的滚动条自动滚动到最底部的3种方法(推荐)
Sep 24 Javascript
JavaScript中递归实现的方法及其区别
Sep 12 Javascript
关于JavaScript语句后面的分号问题
Dec 07 Javascript
vue拦截器实现统一token,并兼容IE9验证功能
Apr 26 Javascript
layui问题之模拟select点击事件的实例讲解
Aug 15 Javascript
element-ui 实现响应式导航栏的示例代码
May 08 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分页函数
2006/07/08 PHP
MYSQL 小技巧 -- LAST_INSERT_ID
2009/11/24 PHP
PHP strtok()函数的优点分析
2010/03/02 PHP
php中数组首字符过滤功能代码
2012/07/31 PHP
PHP 循环删除无限分类子节点的实现代码
2013/06/21 PHP
自己写的php curl库实现整站克隆功能
2015/02/12 PHP
php获取文件名后缀常用方法小结
2015/02/24 PHP
利用PHPStorm如何开发Laravel应用详解
2017/08/30 PHP
laravel 解决Eloquent ORM的save方法无法插入数据的问题
2019/10/21 PHP
Javascript SHA-1:Secure Hash Algorithm
2006/12/20 Javascript
DOM下的节点属性和操作小结
2009/05/14 Javascript
GWT中复制到剪贴板 js+flash实现复制 兼容性比较好
2010/03/07 Javascript
jQuery 验证插件 Web前端设计模式(asp.net)
2010/10/17 Javascript
DOM_window对象属性之--clipboardData对象操作代码
2011/02/03 Javascript
JS实现文字向下滚动完整实例
2015/02/06 Javascript
JS中完美兼容各大浏览器的scrolltop方法
2015/04/17 Javascript
jQuery插件FusionCharts实现的2D饼状图效果【附demo源码下载】
2017/03/03 Javascript
Bootstrap fileinput文件上传组件使用详解
2017/06/06 Javascript
JavaScript的数据类型转换原则(干货)
2018/03/15 Javascript
基于vue实现可搜索下拉框定制组件
2020/03/26 Javascript
vue 开发企业微信整合案例分析
2019/12/02 Javascript
[02:12]DOTA2英雄基础教程 变体精灵
2013/12/16 DOTA
Python中MYSQLdb出现乱码的解决方法
2014/10/11 Python
浅谈Python生成器generator之next和send的运行流程(详解)
2017/05/08 Python
使用pandas将numpy中的数组数据保存到csv文件的方法
2018/06/14 Python
linux下安装python3和对应的pip环境教程详解
2019/07/01 Python
Python for i in range ()用法详解
2020/09/18 Python
python中实现栈的三种方法
2020/12/19 Python
HTML5本地数据库基础操作详解
2016/04/26 HTML / CSS
美国羽绒床上用品第一品牌:Pacific Coast
2018/08/25 全球购物
What is EJB
2016/07/22 面试题
跟单文员岗位职责
2014/01/03 职场文书
面试后感谢信
2014/02/01 职场文书
和谐社区口号
2014/06/19 职场文书
2019下半年英语教师的教学工作计划(3篇)
2019/09/25 职场文书
使用Python通过企业微信应用给企业成员发消息
2022/04/18 Python