模块的使用

本文详细介绍了ES6模块与CommonJS模块的区别,包括静态加载、导出与导入方式。ES6模块强调静态化,利于编译时优化,而CommonJS模块是运行时加载。文中还举例说明了export default和export的不同用法,以及CMD规范中的define函数和工厂函数。
摘要由CSDN通过智能技术生成

ES6模块的使用

ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS 和 AMD 模块,都只能在运行时确定这些东西。比如,CommonJS 模块就是对象,输入时必须查找对象属性。

// CommonJS模块
let { stat, exists, readfile } = require('fs');

// 等同于
let _fs = require('fs');
let stat = _fs.stat;
let exists = _fs.exists;
let readfile = _fs.readfile;

上面代码的实质是整体加载fs模块(即加载fs的所有方法),生成一个对象(_fs),然后再从这个对象上面读取 3 个方法。这种加载称为“运行时加载”,因为只有运行时才能得到这个对象,导致完全没办法在编译时做“静态优化”

https://www.jianshu.com/p/9e5f39e4792b

export default

/*****test.js*******************导出**********************/
export default {
    myFn(){
        return "默认导出一个方法"
    },
    myName:"laowang"
}
/******************************引入**********************/
import myObj from "./test.js";    //myObj是自定义的导入对象名
console.log(myObj.myFn(),myObj.myName);//默认导出一个方法 

// 正确
var a = 1;
export default a;//因为export default命令其实只是输出一个叫做default的变量
//export default a的含义是将变量a的值赋给变量default。

export

let myName="laowang";
let myAge=90;
let myfn=function(){
    return "我是"+myName+"!今年"+myAge+"岁了"
}
export {
    myName as name,
    myAge as age,
    myfn as fn
}
/******************************接收的代码调整为**********************/
import {fn,age,name} from "./test.js";
console.log(fn());//我是laowang!今年90岁了
console.log(age);//90
console.log(name);//laowang

除了指定加载某个输出值,还可以使用整体加载,即用星号(*)表示一个对象,

export 和 export default的区别

  1. export与export default均可用于导出常量、函数、文件、模块等
  2. 在一个文件或模块中,export、import可以有多个,export default仅有一个
  3. 通过export方式导出,在导入时要加{ },export default则不需要
  4. export能直接导出变量表达式,export default不行。

CMD规范

define函数

在CMD规范中,一个模块就是一个文件,通过define关键字来定义

define(factory)

factory可以是一个函数,也可以是一个对象或字符串。

当factory为对象、字符串时,表示模块的接口就是该对象、字符串。

比如可以如下定义一个JSON数据模块:

define({ "foo": "bar" });

当factory为函数时,表示是模块的构造方法。执行该构造方法,可以得到模块向外提供的接口。

当factory方法在执行时,默认会传入三个参数:require、exports和module:

define(function(require, exports, module) {
    // 模块代码
});

define也可以接受两个以上的参数,进阶的格式是:

define(id, deps, factory); // id是模块标识字符串,deps是模块依赖数组

参数中,字符串id表示模块标注,数组deps表示模块依赖。

define('helloworld', ['jquery'], function(require, exports, module) {
    // 模块代码
});

id和deps参数是可以省略的,省略时可以通过构建工具自动生成。注意的是带id和deps参数的define用法不属于CMD规范,而属于Modules/Transport规范。

define函数带有成员属性cmd,是一个空对象,可用来判断当前页面是否有CMD模块加载器。

if (typeof define === "function" && define.cmd) {
    // 有 Sea.js 等 CMD 模块加载器存在时的逻辑代码
}

factory函数

require

require是factory函数的第一个参数,它有下列的用法:

require(id),通过接受模块标识作为唯一参数,用来获取其他模块提供的接口。

define(function(require, exports) {
    // 获取模块 a 的接口
    var a = require('./helloworlda');

    // 调用模块 helloworld  的方法
    a.doSomething();
});

require.resolve(id),使用模块系统内部的路径解析机制来解析并返回模块路径,该函数并不会加载模块,只返回解析后的绝对路径。

define(function(require, exports) {
    console.log(require.resolve('./b'));// http://path/b.js
});

exports

exports是一个对象,是factory函数的参数之一,用来向外提供模块接口。

define(function(require, exports) {
    // 对外提供 foo 属性
    exports.foo = 'bar';

    // 对外提供 doSomething 方法
    exports.doSomething = function() {};
});

除了给exports对象增加成员,还可以使用return直接向外提供接口。

define(function(require) {
    // 通过 return 直接提供接口
    return {
        foo: 'bar',
        doSomething: function() {}
    };

module对象

module是一个对象,存储与当前模块相关的一些属性和方法。

module.id,模块的唯一标识。

define('yanggb', [], function(require, exports, module) {
    // 模块代码
    console.log(module.id); // yanggb
});

module.uri,模块的绝对路径,根据模块系统的路径解析规则得到。

define(function(require, exports, module) {
    // 模块代码
    console.log(module.uri); // http://path/file.js
});

一般情况下(没有在define函数中自定义id参数),module.id的值就是module.uri的值。

module.dependencies,模块的依赖,是一个数组。

module.exports,模块对外提供的接口。

传给factory函数的exports参数是module.exports对象的一个引用。只通过exports参数来提供接口,有时无法满足开发者的所有需求。例如当模块的接口是某个类的实例时,就需要通过module.exports来实现:

define(function(require, exports, module) {
    // exports 是 module.exports 的一个引用
    console.log(module.exports === exports); // true

    // 重新给 module.exports 赋值
    module.exports = new SomeClass();

    // exports 不再等于 module.exports
    console.log(module.exports === exports); // false
});

要注意的是,对module.exports的赋值必须要同步执行,不能放到回调函数里(异步)。

// x.js
define(function(require, exports, module) {
    // 错误用法
    setTimeout(function() {
        module.exports = {a: "hello"};
    }, 0);
});

// y.js,在 y.js 里有调用到上面的 x.js:
define(function(require, exports, module) {
    var x = require('./x');

    // 无法立刻得到模块 x 的属性 a (有延迟)
    console.log(x.a); // undefined
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值