JS模块化,require、import和export

require

遵循AMD规范,在运行时加载,可以将js文件以模块的方式引入。

1
2
3
4
5
// 引入hello模块
const hello = require('./hello');

// 调用hello模块中使用exports暴露的world()方法
hello.world();

export 导出模块

导出模块,export语法声明用于导出函数、对象、指定文件(或模块)的原始值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 导出单个特性
export let name1, name2, …, nameN; // also var, const
export let name1 = …, name2 = …, …, nameN; // also var, const
export function FunctionName(){...}
export class ClassName {...}

// 导出列表
export { name1, name2, …, nameN };

// 重命名导出
export { variable1 as name1, variable2 as name2, …, nameN };

// 解构导出并重命名
export const { name1, name2: bar } = o;

// 默认导出
export default expression;
export default function () { … } // also class, function*
export default function name1() { … } // also class, function*
export { name1 as default, … };

// 导出模块合集
export * from …; // 不设置默认导出
export * as name1 from …;
export { name1, name2, …, nameN } from …;
export { import1 as name1, import2 as name2, …, nameN } from …;
export { default } from …;

nameN 要导出的标识符,以便在其他文件通过 import 引用。

from 从已经存在的模块、脚本文件…导出。

export有两种模块导出方式:命名式导出(名称导出)和默认导出(定义式导出),命名式导出每个模块可以多个,而默认导出每个模块仅一个。

命名导出:

1
2
3
4
5
6
7
// 导出事先定义的特性
export { myFunction,myVariable };

// 导出单个特性(可以导出var,let,
//const,function,class)
export let myVariable = Math.sqrt(2);
export function myFunction() { ... };

默认导出:

1
2
3
4
5
6
7
8
// 导出事先定义的特性作为默认值
export { myFunction as default };

// 导出单个特性作为默认值
export default function () { ... }
export default class { .. }

// 每个导出都覆盖前一个导出

在导出多个值时,命名导出非常有用。在导入期间,必须使用相应对象的相同名称,但是,可以使用任何名称导入默认导出。

exports和module.exports

module.exports 对象是由模块系统创建的,在我们自己写模块的时候,需要在模块最后写好模块接口,声明这个模块对外暴露什么内容,module.exports 提供了暴露接口的方法。

返回JSON对象:

1
2
3
4
5
6
7
8
var app = {
name: 'app',
version: '1.0.0',
sayName: function(name){
console.log(this.name);
}
}
module.exports = app;

这种方法可以返回全局共享的变量或者方法。

调用:

1
2
var app = require('./app.js');
app.sayName('hello');

返回函数:

1
2
3
4
5
6
7
8
9
10
11

var func1 = function() {
console.log("func1");
};

var func2 = function() {
console.log("func2");
};

exports.function1 = func1;
exports.function2 = func2;

调用:

1
2
3
var functions = require("./functions");
functions.function1();
functions.function2();

返回一个构造函数:

1
2
3
4
var CLASS = function(args){
this.args = args;
}
module.exports = CLASS;

调用:

1
2
var CLASS = require('./CLASS.js');
varc = new CLASS('arguments');

返回一个实例对象:

1
2
3
4
5
6
7
8
//CLASS.js
var CLASS = function(){
this.name = "class";
}
CLASS .prototype.func = function(){
alert(this.name);
}
module.exports = new CLASS();

调用:

1
2
var c = require('./CLASS.js');
c.func();

两者区别:

1
2
3
4
5
// exports 返回的是模块函数,方法可以直接调用
exports.[function name] = [function name]

// moudle.exports 返回的是模块对象本身,返回的是一个类,需要new对象之后才可以调用
moudle.exports = [function name]

import 引入模块

import语法声明用于从已导出的模块、脚本中导入函数、对象、指定文件(或模块)的原始值。

import模块导入与export模块导出功能相对应,也存在两种模块导入方式:命名式导入(名称导入)和默认导入(定义式导入)。

import的语法跟require不同,而且import必须放在文件的最开始,且前面不允许有其他逻辑代码,这和其他所有编程语言风格一致。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import defaultExport from "module-name";

// 导入整个模块的内容
import * as name from "module-name";

// 导入单个接口
import { export } from "module-name";
import { export as alias } from "module-name";

// 导入多个接口
import { export1 , export2 } from "module-name";
import { foo , bar } from "module-name/path/to/specific/un-exported/file";

import { export1 , export2 as alias2 , [...] } from "module-name";
import defaultExport, { export [ , [...] ] } from "module-name";
import defaultExport, * as name from "module-name";
import "module-name";

defaultExport 导入模块的默认导出接口的引用名。

module-name 要导入的模块。通常是包含目标模块的.js文件的相对或绝对路径名,可以不包括.js扩展名。某些特定的打包工具可能允许或需要使用扩展或依赖文件,它会检查比对你的运行环境。只允许单引号和双引号的字符串。

name 导入模块对象整体的别名,在引用导入模块时,它将作为一个命名空间来使用。

export, exportN 被导入模块的导出接口的名称。

alias, aliasN 将引用指定的导入的名称。

文章参考

CSDN: 终于讲清楚了nodejs中exports和module.exports的区别_嘿嘿-CSDN博客

MDN文档: import - JavaScript | MDN (mozilla.org)

MDN文档: export - JavaScript | MDN (mozilla.org)

END

JS模块化,require、import和export

http://example.com/index/9169/

作者

WZJ

发布于

2021-05-13

许可协议

评论