概念:module.exports和exports是属于commonJs规范,export和export default是ES6模块规范。
(一) commonJs:
exports 等于 module.exports,相当于在js文件头部,有一个module对象,module.exports = exports;
exports是一个对象,所以可以exports多个值
// 暴露.js
exports.fn1;
exports.fn2;
exports.fn3;
// 引用.js
var fns = require('暴露.js');
fns.fn1(); ...
// 相当于
exports = {fn1,fn2,fn3}
// 相当于
modules.exports = {fn1, fn2,fn3}
*以webapck举例*
// 暴露.js
module.exports = {
context: path.resolve(__dirname, '../'),
entry: {
app: ['babel-polyfill', './src/main.js']
},
output: {},
resolve: {
extensions: ['.js', '.vue', '.json', '.scss', '.less'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
'styles': resolve('src/assets/styles'),
'images': resolve('src/assets/images'),
'components': resolve('src/components')
}
},
module: {}
};
// 引用.js
const configs = require('../config');
1、对于要导出的属性,可以简单直接挂到exports对象上
exports.name = function() {
console.log('My name is Lemmy Kilmister');
};
2、对于类,为了直接使导出的内容作为类的构造器可以让调用者使用new操作符创建实例对象,应该把构造函数挂到module.exports对象上,不要和导出属性值混在一起
// 暴露.js
module.exports = function(name, age) {
this.name = name;
this.age = age;
this.about = function() {
console.log(this.name +' is '+ this.age +' years old');
};
};
var A = require('暴露.js'); var a = newA(name, age);
module.exports 初始值为一个空对象 {}
exports 是指向的 module.exports 的引用
require() 返回的是 module.exports 而不是 exports
也就是: exports = module.exports = {}, exports和module.exports都指向一个引用地址{},如果exports.name = 'xxx',那module.exports = {name:'xxx'},引用对象改变,两者又是同时指向一个对象,所以都改变了。
(二) ES6规范
1:每一个模块只加载一次, 每一个JS只执行一次, 如果下次再去加载同目录下同文件,直接从内存中读取。 一个模块就是一个单例,或者说就是一个对象;
2:每一个模块内声明的变量都是局部变量, 不会污染全局作用域;
3:模块内部的变量或者函数可以通过export导出;
4:一个模块可以导入别的模块
es6有多种写法:
(1)、export { xx, xx}与import {xx, xx} from '../../xxx.js'
// 暴露.js
let name = 'xiaoming';
let age = 18;
export {name, age}
// 引用.js
import {name, age} from '暴露.js';
(2)、在export接口的时候, 我们可以使用 XX as YY, 把导出的接口名字改了, 比如:** fn1(实际export) as SayHi(别名) **, 把这些接口名字改成不看文档就知道干什么的:在引用文件这样用 import {SayHi} from '../../xx.js';
// 暴露.js
let fn1 = function() {console.log('sayHi')};
export { fn1 as sayHi };
// 引用.js
import { sayHi } from '暴露.js'
(3)、直接在export的地方定义导出的函数,或者变量:export const foo = xxx; 引用 import { foo } from '../../xx'
// 举个vue组件懒加载的例子
export const Index = () => import('@modules/index/index');
(4)、export default导出,这种导出的方式不需要知道变量的名字, 相当于是匿名的;
// 如果一个js模块文件就只有一个功能, 那么就可以使用export default导出
// 暴露.js
export default {
name: 'xiaoming',
age: 18
};
// 引用.js
import person from '暴露.js'
(6)、通配符导入
// 暴露.js
export fn1;
export fn2;
export fn3;
// 引用.js
import * as fns from '暴露.js';
在import的时候可以使用通配符*导入外部的模块:
import * as xxx from ‘xxx’: 会将若干export导出的内容组合成一个对象返回;
import xxx from ‘xxx’:(export default Din)只会导出这个默认的对象作为一个对象;
以上。