前端学习

前端基础整理 | require / exports / imp

2019-07-18  本文已影响0人  格致匠心

一、 模块规范

一句话总结:CommonJs用于服务端Node.js中,AMD和CMD是针对客户端的规范,为了不让引入依赖阻塞了代码进行,使用了异步加载模块。

1. CommonJs:

module.exports 基础用法

/* export.js */
const a = 1
module.exports = a
/* import.js */
var a = require('./export')
// a = 1

exports 基础用法

/* export.js */
exports.a = 1 // 不能改变引用, exports = {a:1}🙅
/* import.js */
var a = require('./export')
// a = {a:1}

可以使用es6的特性 - 解构赋值

/* export.js */
exports.a = 1
/* import.js */
var {a} = require('./export')
// a = 1
var _ = require('./loadsh')
_.map([1,2,3], square)

如上面👆所示,如果loadsh这个库由于网络原因加载得很慢的话,那么它便阻塞了后面代码的运行,这样对用户体验牺牲很大。
这时候AMD就有了诞生的需求了。

2. AMD:

AMD是”Asynchronous Module Definition”的缩写,意思就是”异步模块定义”。它采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。

// id:模块名(可选),dependencies:依赖库(可选),factory工厂方法,返回一个模版函数
define(id?, [dependencies?], factory)
// demo
define(['Lib'], function(Lib){
  function foo(){
    Lib.doSomething();
  }
  return {
    foo : foo
  };
});
// module:加载的模块数组, callback:加载成功后再执行的回调函数
require([module], callback);
// demo
require([loadsh], loadsh.map([1,2,3],square))

目前,主要有两个Javascript库实现了AMD规范:require.jscurl.js

3. CMD:

CMD (Common Module Definition), 是seajs推崇的规范。它与AMD最大的区别是它推崇依赖就近。

// id:模块名(可选),dependencies:依赖库(可选),factory工厂方法,返回一个模版函数
define(id?, [dependencies?], factory)
// 不同点:它可以在工厂函数中导出导入(也是通常的做法),也是它推崇的导出导入方式
define(function(require, exports, module) {
// 模块代码
  var $ = require('jquery.js')
  $('div').addClass('active');
});
// 加载模块
seajs.use(['myModule.js'], function(my){
});

二. ES6

这里主要介绍:

1. 基本用法

/* export.js */
export const a = 1
/* import.js */
import { a } from './export'
// a = 1

经过babel的转换。可以看到转化为exports->require,并且给exports添加了一个__esModule的属性。

/* export.js */
"use strict";
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.a = void 0;
const a = 1;
exports.a = a;
/* import.js */
"use strict";
var _export = require("./export");
console.log(_export.a);

export default

// export.js
const b = 2
export default b
// import.js
import b from './export'
console.log(b)

通过babel转化,使用exports.default进行导出。

/* export.js */
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
const b = 2;
var _default = b;
exports.default = _default;

⚠️注意:不能认为 import { b } from './export' 是用了解构赋值。当执行以下代码是不行的。import 语句中的"解构赋值"并不是解构赋值,而是 named imports。

// import.js
import { {a} } from './export' // 语法错误
console.log(a)
// export.js
export const b = { a: 1 }

named imports,语法上和解构赋值很像,但还是有所差别,比如下面的例子。

import { b as a } from './export' // 解构赋值中不能用 as

因此还是得老老实实把值接下来,然后再去处理。或者你可以和CommonJs混用来达到类似解构赋值的效果。

2. 与CommonJs混用

由于babel解析的时候也是解析成exports->require形式的,因此可以和commonJs混用。

// import.js
var { b } = require('./export').default
console.log(b)
// export.js
export default {
  b: 2
}
// import.js
import { a } from './export'
console.log(a)
// export.js
module.exports = {
  a: 1
}
上一篇 下一篇

猜你喜欢

热点阅读