Nodejs和ES6模块机制
Nodejs
1. exports
-
每个文件就是一个模块,每个模块都有一个module对象
-
node的模块分为核心模块和文件模块(用户编写的文件)
-
导出的是运行时对象——module.exports
-
module的属性如下:
{ id: '<repl>', // 模块标识符 exports: {}, // 模块导出的内容 parent: undefined, // 最先引用该模块的模块 filename: null, // 模块文件名 loaded: false, // 该模块是否已经加载完毕 children: [], // 该模块引用的模块 paths: // 该模块的搜索路径 [ '/Users/ces/repl/node_modules', '/Users/ces/node_modules', '/Users/node_modules', '/node_modules', '/Users/ces/.node_modules', '/Users/ces/.node_libraries', '/usr/local/lib/node' ] }
-
模块文件中的
exports
变量是对module.exports
的引用,即:module.exports === exports; //true
2.require
- require()的参数可以是:
- 模块标识符
- 相对路径
.
、..
- 绝对路径
\
- 模块引入分三步:
- 路径分析
- 文件定位
- 编译执行
- require()的参数可以没有后缀名,node会使用
.js
、.json
、.node
去定位文件 - node会缓存已经导入的模块,因此后续导入会优先从缓存中查找
- 导入的是输出值的复制,即模块内部的变化不会影响到导入后的变量
ES6
1. 浏览器加载
-
传统加载js文件的方式
<!-- 页面内嵌的脚本 --> <script type="application/javascript"> // module code </script> <!-- 外部脚本 --> <script type="application/javascript" src="path/to/myjs.js"> </script>
- 其中,
<script/>
标签可以有defer
和async
两个属性- defer表示异步加载js文件,页面渲染完毕之后,再去执行js文件,多个defer的js文件会按照标签顺序依次执行
- async表示异步加载js文件,加载完成之后,停止页面渲染,转而去执行js文件,无法保证js文件的执行顺序
- 其中,
-
es6模块的加载方式
// 外部模块文件 <script type="module" src="path/to/myModule.js" /> // 内嵌模块 <script type="module"> import utils from "./utils.js"; // other code </script>
- 加载es6模块都是异步的,相当于添加了
defer
属性。也可以添加async
属性改变为"加载完立即执行"
- 加载es6模块都是异步的,相当于添加了
2. export
-
导出的是模块输出的值的引用
-
export
的语法如下:// myModule.js export var n = 1; export class Person{} export function add(){} // 默认导出,每个模块最多有一个默认导出 export default "m"; // export default function(){} // export default class Person{} // 一次导出多个 export {n, Person, add}; // 对输出重命名 export {n as nn, Person as People, add as plus};
3. import
-
导入的在编译时进行的,导入的是编译时的输出接口,是对模块值的引用
-
import
的语法如下:// 花括号中的变量名必须与模块文件中的变量名一致 import {n, Person, add} from "myModule.js"; // 导入的变量可以重命名 import {n as nn, Person as People, add as plus} from "myModule.js"; // 默认导入不加花括号,名称可以任意指定 import m, {n, Person, add} from "myModule.js"; // 一次性导入,模块文件中导出的变量成为重命名变量的属性 import {* as myModule} from "myModule.js";
-
导入和导出同时使用:
export {n, Person, add} from "myModule.js"
Nodejs与ES6的混用
-
用
import
导入nodejs(commonjs)模块:-
会将
module.exports
作为默认导出// myModule.js module.exports = { foo: "foo", bar: "bar" } // 等同于 export default { foo: "foo", bar: "bar" } // 导入 import baz from 'myModule.js'; // baz = {foo: "foo", bar: "bar"};
-
-
用
require()
导入es6模块:-
es6模块导出的所有接口都会成为输入对象的属性,默认导出会成为
default
属性// util.js 直接作为exports对象导出 module.exports = function util(){ console.log('bar'); } // index.js import util from './util.js' console.dir(util); //[Function: util] // util.js 作为exports对象的属性导出 module.exports = { foo: function(){} } //index.js import util from './util.js'; console.dir(util); //{ foo: [Function: util] }
-
网友评论