关于 import
和 require
的不一样,其实能够理解成 CommonJs 和 ES Module 的区别。这二者都是前端模块化的规范。前端
咱们在 node 里使用的是 CommonJs,在前端页面的时候,用的是 ES Module,这二者的区别,仍是很容易混淆的,因此整理一下 CommonJs 和 ES Moudule 的相关知识点,把这里好好的整理一下。node
1、CommonJses6
1.1 概述json
Nodejs 是 CommonJS 规范的主要实践者,在 CommonJs 里每一个文件就是一个模块,有本身的做用域。在一个文件里面定义的变量、函数、类,都是私有的,对其余文件不可见。CommonJs 提供了四个重要的环境变量为模块化的实现提供支持:module
、exports
、require
、global
。CommonJS 规定,每一个模块内部,module 变量表明当前模块。这个变量是一个对象,它的 exports
属性(即 module.exports
)是对外的接口。加载某个模块,实际上是加载该模块的 module.exports
属性。数组
var x = 5; var addX = function (value) { return value + x; }; module.exports.x = x; module.exports.addX = addX;
而使用 require 方法来引入并加载模块缓存
var example = require('./example.js'); console.log(example.x); // 5 console.log(example.addX(1)); // 6
1.2 CommonJS模块的特色模块化
关于变量:函数
一、module
对象是 node 里的 Module 构造函数的实例,表明当前模块。具备如下属性:ui
二、exportsthis
NodeJs 为每一个模块提供一个 exports
变量,指向 module.exports
在使用的时候,能够直接给 exports
添加属性,就会指向 module.exports
。可是不能给 exports
直接赋值一个变量,这样会切断 exports
和 module.exports
之间的联系。
若是有 exports
和 module.exports
,exports
就会失效,只会输出 module.exports
的,由于 module.exports
被从新赋值了。
三、global
这是一个全局变量声明方式,就能够全局用这个 warning 变量了。
global.warning = true;
四、require
require
命令用于加载模块文件。
require
命令的基本功能是,读入并执行一个 JavaScript 文件,而后返回该模块的 exports
对象
加载规则:
require函数及其辅助方法主要以下。
关于缓存:
在屡次加载某个相同的模块时,若是前面的模块已经操做了,后面调用时,拿到就再也不是最初时的数据了,就是通过前面操做事后的数据了。
全部缓存的模块保存在 require.cache
之中,若是想删除模块的缓存,能够像下面这样写。
// 删除指定模块的缓存 delete require.cache\[moduleName\]; // 删除全部模块的缓存 Object.keys(require.cache).forEach(function(key) { delete require.cache\[key\]; })
注意:缓存是根据绝对路径识别模块的,若是一样的模块名,可是保存在不一样的路径,require
命令仍是会从新加载该模块。
1.3 模块的加载机制
CommonJS 模块的加载机制是,输入的是被输出的值的拷贝。也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。
2、ES Module
2.1 概述
ES6 模块的设计思想是尽可能的静态化,使得编译时就能肯定模块的依赖关系,以及输入和输出的变量。因此ES6 模块不是对象,而是经过 export
命令显式指定输出的代码,再经过 import
命令输入。这种加载称为“编译时加载”或者静态加载,即 ES6 能够在编译时就完成模块加载,效率要比 CommonJS 模块的加载方式高。固然,这也致使了无法引用 ES6 模块自己,由于它不是对象。
2.2 ES Module的特色:
ES6 的模块功能主要由两个命令构成:export
和 import
。 export
命令用于规定模块的对外接口。import
命令用于输入 其余模块提供的功能。
一、export命令
二、import命令
三、export default 命令
3、CommonJs 和 ES Module的区别
es6 { export : ‘能够输出多个,输出方式为 {}’ , export default : ‘ 只能输出一个 ,能够与 export 同时输出,可是不建议这么作’, 解析阶段肯定对外输出的接口,解析阶段生成接口, 模块不是对象,加载的不是对象, 能够单独加载其中的某个接口(方法), 静态分析,动态引用,输出的是值的引用,值改变,引用也改变,即原来模块中的值改变则该加载的值也改变, this 指向 undefined } commonJS { module.exports = … : ‘只能输出一个,且后面的会覆盖上面的’ , exports. … : ‘ 能够输出多个’, 运行阶段肯定接口,运行时才会加载模块, 模块就是对象,加载的是该对象, 加载的是整个模块,即将全部的接口所有加载进来, 输出的是值的拷贝,即原来模块中的值改变不会影响已经加载的该值, this 指向当前模块 }