ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CommonJS模块加载方法

2020-11-08 12:31:28  阅读:191  来源: 互联网

标签:ES6 CommonJS counter js 模块 加载


一、 ES6 模块与 CommonJS 模块的差异

有三个重大差异

1、CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。

2、CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。

3、CommonJS 模块的require()是同步加载模块,ES6 模块的import命令是异步加载,有一个独立的模块依赖的解析阶段。

1、第一个差异解释:

CommonJS 模块输出的是值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。
例子:
// lib.js
var counter = 3;
function incCounter() {
  counter++;
}
module.exports = {
  counter: counter,
  incCounter: incCounter,
};

// main.js
var mod = require('./lib');

console.log(mod.counter);   // 3
mod.incCounter();
console.log(mod.counter);   // 3
lib.js模块加载以后,它的内部变化就影响不到输出的mod.counter了。
这是因为mod.counter是一个原始类型的值,会被缓存,除非写成一个函数,才能得到内部变动后的值。
module.exports = {
  get counter() {
    return counter
  },
  incCounter: incCounter,
};
ES6 则相反,原始值变了,import加载的值也会跟着变。


2、第二个差异解释:
因为 CommonJS 加载的是一个对象(即module.exports属性),该对象只有在脚本运行完才会生成。
而 ES6 模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成。



node.js 模块加载方法

CommonJS 模块是 Node.js 专用的,与 ES6 模块不兼容。

语法上面,两者最明显的差异是,CommonJS 模块使用require()和module.exports,ES6 模块使用import和export。

从 Node.js v13.2 版本开始,Node.js 已经默认打开了 ES6 模块支持。
Node.js 要求 ES6 模块采用.mjs后缀文件名。也就是说,只要脚本文件里面使用import或者export命令,那么就必须采用.mjs后缀名。

Node.js 遇到.mjs文件,就认为它是 ES6 模块,默认启用严格模式,不必在每个模块文件顶部指定"use strict"。

如果不希望将后缀名改成.mjs,可以在项目的package.json文件中,指定type字段为module。
一旦设置了以后,该目录里面的 JS 脚本,就被解释用 ES6 模块。

如果这时还要使用 CommonJS 模块,那么需要将 CommonJS 脚本的后缀名都改成.cjs

如果没有type字段,或者type字段为commonjs,则.js脚本会被解释成 CommonJS 模块

注意,ES6 模块与 CommonJS 模块尽量不要混用

CommonJS 的一个模块,就是一个脚本文件。require命令第一次加载该脚本,就会执行整个脚本,
然后在内存生成一个对象。
{
  id: '...',
  exports: { ... },
  loaded: true,
  ...
}
上面代码就是 Node 内部加载模块后生成的一个对象
id属性是模块名
exports属性是模块输出的各个接口
loaded属性是一个布尔值,表示该模块的脚本是否执行完毕
以后需要用到这个模块的时候,就会到exports属性上面取值。即使再次执行require命令,也不会再次执行该模块,而是到缓存之中取值
也就是说,CommonJS 模块无论加载多少次,都只会在第一次加载时运行一次,以后再加载,就返回第一次运行的结果,除非手动清除系统缓存。


// 导入
var util =  require('/utils.js');

//导出;
module.exports = {
    counter: counter,
    incCounter: incCounter,
};

三、package.json 的 main 字段

package.json文件有两个字段可以指定模块的入口文件:main和exports。比较简单的模块,
可以只使用main字段,指定模块加载的入口文件。
{
  "type": "module",
  "main": "./src/index.js"
}

上面代码指定项目的入口脚本为./src/index.js,它的格式为 ES6 模块。
如果没有type字段,index.js就会被解释为 CommonJS 模块。

参考https://es6.ruanyifeng.com/

标签:ES6,CommonJS,counter,js,模块,加载
来源: https://www.cnblogs.com/kgwei520blog/p/13943958.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有