CommonJS NodeJs
ES6 Module
基本规则或特点
- 每个模块只加载一次,每一个JS只执行一次,如果下次再去加载同目录下同文件,直接从内存中读取。一个模块就是一个单例,或者说就是一个对象;
- 每一个模块内声明的变量都是局部变量,不会污染全局作用域;
- 模块内部的变量或函数可以通过export导出;
- 一个模块可以导入别的模块。
import 和 export 命令
举例
a.js
var x = 1
import {xx, yy } from './b.js'
import {fun} from './b.js'
var y = 2
console.log(x,y)
console.log(xx,yy)
fun()
export {x,y}
b.js
export var xx = 11
import {x,y} from './a.js'
export var yy = 22
console.log(xx,yy)
console.log(x,y)
export function fun(){
console.log('this is b module fun method')
}
输出结果
11 22
b.js:6 undefined undefined
a.js:4 1 2
a.js:5 11 22
b.js:8 this is b module fun method
- 整个流程是:预编译a.js -> 发现关键词import -> 预编译b.js -> 执行b.js -> 执行a.js
- import命令具有提升效果,会提升到整个模块的头部,首先执行(是在编译阶段执行的) -import {fun} from './b.js'' 这行代码被Js引擎编译时,将b模块的属性fun指向对应模块的export function fun()方法上,这里只是做了指针指向,并不是执行fs模块。当执行readFile()时,就会去找指针指向的代码并执行。 将a.js文件中的xx换成xxx,会报语法错误
SyntaxError: The requested module './b.js' does not provide an export named 'xxx'
- 代码运行前会有一个编译阶段
import()函数
import 和 export命令只能在模块的顶层,不能在代码块之中。否则会出现语法错误。这样的设计,可以提高编译器效率,但是没有办法实现运行时加载。
因为require()是运行时加载,所以 import命令没有办法代替require的动态加载功能。所以,es6模块方案引入了import()函数。完成动态加载。
webpack Module
原理
- 使用一个缓存对象__webpack_module_cache__缓存已经加载的模块
- 使用webpack自定义方法__webpack_require__加载模块
- 先判断缓存对象__webpack_module_cache__中是否已缓存需要加载的模块
- 已缓存,则直接返回exports对象;
- 没有缓存,则new一个module,并放入缓存
- 缓存的key是路径标识符;value是一个对象,里面有一个exports属性
es6 import和export被webpack打包后的样式
- 最外层是一个立即执行函数
(()=>{
})();
- 第一行代码是 "use strict"
- 内部代码简化后如下:
// a.js文件转化为函数moduleA
function moduleA(__unused_webpack_module, __webpack_exports__, __webpack_require__){
var _b__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/pages/b.js");
var x = 1
var y = 2;
var z = 3
__webpack_exports__[Symbol.toStringTag] = 'Module'
__webpack_exports__.__esModule = true
__webpack_exports__.default = {x,y,z}
return __webpack_exports__;
}
function moduleB(__unused_webpack_module, __webpack_exports__, __webpack_require__){
var x = 11
__webpack_exports__[Symbol.toStringTag] = 'Module'
__webpack_exports__.__esModule = true
__webpack_exports__.default = {x}
return __webpack_exports__;
}
var __webpack_modules__ = {
'./src/pages/a.js': moduleA,
'./src/pages/b.js':moduleB
}
var __webpack_module_cache__ = {};
function __webpack_require__(moduleId) {
var cachedModule = __webpack_module_cache__[moduleId];
if (cachedModule !== undefined) {
return cachedModule.exports;
}
var module = __webpack_module_cache__[moduleId] = {
exports: {}
}
__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
return module.exports
}
var __webpack_exports__ = __webpack_require__('./src/pages/a.js')
- 一个__webpack_modules__对象;后面简称为modules,该modules是一个对象;长度为2。
- 第一个key是"./src/pages/a.js"
- 第二个key是"./src/pages/b.js"
- 一个__webpack_module_cache__对象;
- 一个__webpack_require__方法;用于加载模块
- 使用Object.defineProperty的get获取模块里面的属性和方法,不能修改模块内的变量和方法