JavaScript Module 是什么
一个 JavaScript module 模块准确的说就是一个文件,它允许你把代码 export 导出来复用,这样别的 JavaScript 文件可以 import 这个文件把它作为库文件来使用了。
模块主要是用在工程文件中,用来把代码共享给其他文件用,javascipt 的模块可以说是满天飞。
这里呢讨论的是前端的部分,即是运行在浏览器中的 javascripts module 部分,而不是运行在后端的 Node.js 的部分,后端现在已经向前端靠拢了。
ES6标准发布后,module成为标准,标准使用是以export指令导出接口,以import引入模块,但是在我们一贯的node模块中,我们依然采用的是CommonJS规范,使用require引入模块,使用module.exports导出接口。这点也理解清楚。
我们从零来一步步开始吧
如何把一个 JavaScript 文件转换为 ES 的 module
1: 创建一个 project 目录
这个目录用来放 HTML 和 JavaScript 文件
2: 建立你的 code 代码文件
在 project 文件夹中建立2个文件:
index.html
index.js
3: 添加 JavaScript 文件的引用到 HTML 文件中
打开index.html
编辑它:
1<!DOCTYPE html>
2<html>
3 <head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <title>ES Module - zhang ranrui</title>
7 </head>
8 <body>
9 <h1>ES Module Tutorial</h1>
10
11 <!-- Add the "index.js" JavaScript file to this HTML document -->
12 <script type="module" src="index.js"></script>
13 </body>
14</html>
上面的代码中,我们引用了 index.js , 并定义它 type=“module”,这显式指明了 index.js 是一个 ES 的module。
那么,如果有了一个 ES 的 module,如何使用它呢,也举个例子:
如何使用一个 ES 的 Module
1: 建立一个 project 目录
同样是放 html 和 module 文件的。
2: 建立 code 文件
在 project 文件夹下建立如下文件:
index.html
module-1.js
module-2.js
3: 增加 modules 文件的引用到 HTML 文件
编辑 index.html
文件,增加对 module 的引用:
1<!DOCTYPE html>
2<html>
3 <head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <title>ES Module - zhang ranrui</title>
7 </head>
8 <body>
9 <h1>ES Module Tutorial</h1>
10 <h2>Check the console</h2>
11
12 <script type="module" src="module-1.js"></script>
13 <script type="module" src="module-2.js"></script>
14 </body>
15</html>
4: 浏览你的 index.html
注意,这里只能在 localhost 的服务器上浏览,直接浏览本地文件会报 cors 的错。
怎么 Export 导出一个 Module 中的代码
有两种使用方法
- 在代码前使用
export
关键字 - 使用 export 声明语句
一、在代码前使用 export
关键字
注意:是在正式代码之前
1// module-1.js
2
3// Export the "bestClub" variable:
4export const bestClub = "Your Club";
另外一个例子:
1// Export the "multiply" function:
2export function multiply(x, y) {
3 return x * y;
4}
二、使用 export 声明语句
另一种方法是使用 export 声明语句,这种方式用 {} 包裹 要导出的变量,中间的变量名用逗号来隔开。
1// Create a variable named "bestClub":
2const bestClub = "Your Club";
3
4// Create a function named "multiply":
5function multiply(x, y) {
6 return x * y;
7}
8
9// Create an array named "fruits":
10const fruits = ["Mango", "Apple", "Orange", "Lemon"];
11
12// Export the three statements above:
13export { bestClub, multiply, fruits };
导出有了,怎样导入别的模块 Exported 的代码呢?
接上的例子,只导入一个变量:
1// module-2.js
2
3import { bestClub } from "./module-1.js";
导入所有变量
1// Import three items from the module-1.js file:
2import { bestClub, multiply, fruits } from "./module-1.js";
注意./
是表示当前路径,如果路径不对,有可能需要全路径导入
1// Import three items from the module-1.js file:
2import { bestClub, multiply, fruits } from "/codesweetly/blog/notes/modular-javascript/es-modules/module-1.js";
注意在后端 Node.js 和 module bundlers 中,是允许你不写文件名后缀的,比如下面
1// Import three items from the module-1.js file:
2import { bestClub, multiply, fruits } from "module-1";
但是,在 ES modules 中,不允许省略文件后缀。
如何使用从别的模块 Imported 导入的代码
1// module-2.js
2
3import { bestClub } from "./module-1.js";
4
5const myBestClub = bestClub + " " + "is my best club.";
6
7console.log(myBestClub);
注意:
import
关键字只能出现在 modules 文件中,不能出现在通常的 JavaScript 程序文件中。- 一个被 imported 导入的模块只能作用于本文件中,而不是全局可用。你只能在这个文件中使用。
- JavaScript 会自动提升 import 语句的作用域,所以你可以在任何地方使用 import ,甚至在使用其中代码之后。
- Imported 导入的模块缺省处于 strict 严格模式下。
如何将 Exports 和 Imports 导入导出的模块重命名
用 as
即可:
1// module-1.js
2
3// Create a variable named "bestClub":
4const bestClub = "Your Club";
5
6// Export the bestClub variable as "favoriteTeam":
7export { bestClub as favoriteTeam };
接下来使用就不能是 bestclub , 而是 favoriteTeam 了:
1// module-2.js
2
3import { favoriteTeam } from "./module-1.js";
4
5const myBestClub = favoriteTeam + " " + "is my best club.";
6
7console.log(myBestClub);
同样可以在 import 的时候使用 as
1// module-1.js
2// Create a variable named "bestClub":
3const bestClub = "Your Club";
4// Export the bestClub variable:
5export { bestClub };
6
7// module-2.js
8import { bestClub as favoriteTeam } from "./module-1.js";
9const myBestClub = favoriteTeam + " " + "is my best club.";
10console.log(myBestClub);
如何在 ES Module 中重命名多个 Exports 导出
很简单,用as加上逗号分割符号
1// module-1.js
2
3const bestClub = "Your Club";
4const fruits = ["Grape", "Apple", "Pineapple", "Lemon"];
5
6function multiply(x, y) {
7 return x * y;
8}
9
10// Export the three statements above:
11export {
12 bestClub as favoriteTeam,
13 fruits as crops,
14 multiply as product
15};
16// module-2.js
17
18import { favoriteTeam, crops, product } from "./module-1.js";
19
20const bestClub = `I bought ${product(2, 11)} ${crops[2]}s at ${favoriteTeam}.`;
21
22console.log(bestClub);
如何在 ES Module 中重命名多个 Import 导入
跟上面一样:
1// module-1.js
2
3const bestClub = "Your Club";
4const fruits = ["Grape", "Apple", "Pineapple", "Lemon"];
5function multiply(x, y) {
6 return x * y;
7}
8
9// Export the three statements above:
10export { bestClub, fruits, multiply };
11// module-2.js
12
13import {
14 bestClub as favoriteTeam,
15 fruits as crops,
16 multiply as product
17} from "./module-1.js";
18
19const bestClub = `I bought ${product(2, 11)} ${crops[2]}s at ${favoriteTeam}.`;
20
21console.log(bestClub);
如何在 ES Module 一句话 import 导入所有导出变量
用*号:
1// Import all exportable features from the "countries.js" module:
2import * as allCountries from "./countries.js";
例子如下:
1// module-1.js
2
3const bestClub = "Your Club";
4const fruits = ["Grape", "Apple", "Pineapple", "Lemon"];
5function multiply(x, y) {
6 return x * y;
7}
8
9// Export the three statements above:
10export { bestClub, fruits, multiply };
11// module-2.js
12
13import * as firstModule from "./module-1.js";
14
15const bestClub = `I bought ${firstModule.multiply(2, 11)} ${firstModule.fruits[2]}s at ${firstModule.bestClub}.`;
16
17console.log(bestClub);
如何在 ES Module 中 Export 指定 default 缺省导出
如果导出的时候指定 default ,就是缺省导出。Default export
1// module-1.js
2
3const bestClub = "Your Club";
4
5// Export the bestClub variable as a default export:
6export default bestClub;
注意:default 两边没有花括号,因为 default 只能有一个,而且缺省导出不能是 var , let 或者 const
如何 import 导入缺省导出
依然两种方法:
- 使用
default as
的语法 - 直接命名缺省导出
一、使用 default as
语法
1import { default as newName } from "./module-relative-path.js";
例子:
1// module-1.js
2
3// Export the string value as a default export:
4export default "Your Club";
5// module-2.js
6
7import { default as favoriteTeam } from "./module-1.js";
8
9const bestClub = favoriteTeam + " " + "is my best club.";
10
11console.log(bestClub);
二、直接命名缺省导出
这种方式,可以看作是第一种去掉花括号,去掉 default as 后的简略写法:
1import newName from "./module-relative-path.js";
例子:
1// module-1.js
2
3// Export the string value as a default export:
4export default "Your Club";
5// module-2.js
6
7import favoriteTeam from "./module-1.js";
8
9const bestClub = favoriteTeam + " " + "is my best club.";
10
11console.log(bestClub);
over,这么多,大家应该会了吧。回头会另开一篇说说如何把模块都压到一起,那就是 webpack 的功能了。