msforest / notebook

好记性不如烂笔头,记录知识的点点滴滴。
https://github.com/msforest/notebook/wiki
0 stars 0 forks source link

js笔记收录(2) #22

Open msforest opened 6 years ago

msforest commented 6 years ago

node内存 node模块 vs es6模块

node 关于内存

node memory

chrome devtools

msforest commented 6 years ago

node module(CommonJS) vs es6 module

node module es6 module
this module.exports undefined
加载 运行时加载(动态加载) 编译时加载(静态加载)
export 输出值的拷贝 输出值的引用

nodejs模块加载机制采用CommonJS的模块加载机制,因此比较的也就是CommonJS 🆚ESM

1. 使用

CommonJS

// dep.js
dep = {
    foo: function(){},
    bar: 22
}
module.exports = dep;

// app.js
var dep = require("dep");
console.log(dep.bar);
dep.foo();

ES Module

// dep.js
export function foo(){};
export const bar = 22;

// app.js
import {foo, bar} from "dep";
console.log(bar);
foo();

2.加载机制

当node加载模块的时候,会再模块外面加一层函数作用域。加载dep.js时编译后的代码如下

function (exports, require, module, __filename, __dirname) {
  const m = 1;
  module.exports.m = m;
}

因此模块本身就能直接使用__filename, __dirname, module等变量,这些变量不属于全局变量,但模块内部都能直接使用。

node实际上加载模块有5个步骤:

因此,node只有再运行时才知道模块的内容,这也是与es6最大的不同,es6是基于词法分析的。

解析es6模块的时候,在VM运行之前就已经被解析好了,此时,有一个名为Module Record的数据结构,它保存的就是各个import 的引用。当import {f} from 'foo'时,MR就有指向f的引用

Related: https://nodesource.com/blog/es-modules-and-node-js-hard-choices/

变量未定义时的区别

// es6 module
<script type="module">
a = 1;  //此行会报错,提示a未定义
</script>
// node
a = 1; // 会变成global的属性