JavaScript 常用模块化规范

JavaScript 模块化规范

1. 模块化概述

1.1 什么时模块化
  • 将程序文件依据一定规则拆分成多个文件,这种编码方式就是模块化的编码方式。
  • 拆分出来每个文件就是一个模块,模块中的数据都是私有的,模块之间相互隔离。
  • 同事也能通过一些手段,可以把模块内的指定数据“交出去”,提供其他模块使用。
1.2 为什么使用模块化

随着应用的复杂度越来越高,其代码量和文件数据都会急剧增加,会逐渐引发一些问题:

  • 全局污染问题。
  • 依赖混乱问题。
  • 数据安全问题。

2. 模块化规范

2.1 CommonJS 模块化规范 — NodeJS 服务器端应用广泛
  • 定义:CommonJS 是服务器端 JavaScript 的模块化规范,主要用于服务器端的 JavaScript 编程。
  • 特点:模块化规范,模块可以直接在 NodeJS 中运行。
  • 如何使用:在 NodeJS 中,通过 require() 方法来加载模块。
2.2 AMD 模块化规范
  • 定义:AMD 是 Asynchronous Module Definition 的缩写,它是 RequireJS 在推广过程中对模块定义的规范化产出。
  • 特点:模块化规范,模块可以直接在浏览器中运行。
  • 如何使用:在浏览器中,通过 require.js 来加载模块。
2.3 ES6 模块化规范 — 浏览器端应用广泛
  • 定义:ES6 模块化规范是 JavaScript 语言的最新版本,它在语言层面上实现了模块化。
  • 特点:模块化规范,模块可以直接在浏览器和 NodeJS 中运行。
  • 如何使用:在浏览器和 NodeJS 中,通过 import 和 export 来加载模块。

3. 导入与导出的概念

模块化的核心思想就是:模块之间是相互隔离的,通过导入和导出进行数据和功能共享。

  • 导出:模块公开其内部的一部分(变量,函数等),使这些内容可以被其他模块使用。
  • 导入:模块引用和使用其他模块导出的内容,以重用代码和功能。

4. CommonJS 模块化规范

4.1 导出数据
  • 导出
// school.js
const name = "JavaScript";

const slogan = "让天下没有难学的技术";

function getTel() {
  return "13888888888";
}

function getCities() {
  return ["北京", "上海", "广州", "深圳"];
}

// 第一种
exports.name = name;
exports.slogan = slogan;
exports.getTel = getTel;

// 第二种
module.exports = {
  name: name,
  slogan: slogan,
  getTel: getTel,
};

注意点:

  1. 每个模块内部的 this, exports, modules.exports 在初始时,都指向同一个空对象,该空对象就是当前模块导出的数据

  2. 无论如何修改导出对象,最终导出的都是 module.exports 对象.

  3. exports 是对 module.exports 的初始引用,仅为了给导出对象添加属性,多疑不能使用 exports = value 的形式导出数据,但是可以使用 module.exports = value 的形式导出数据。

4.2 导入函数
  • 导入
// index.js
// const school = require("./school");

// console.log(school);

// 解构
const { name, slogan, getTel } = require("./school");

// 解构重命名
const { name: stuName, motto, getTel: stuTel } = require("./student");

console.log(name); // "JavaScript"
console.log(slogan); // "让天下没有难学的技术"
console.log(getTel()); // "13888888888"

consol.log(stuName); // "张三"
console.log(motto); // "学而不思则罔,思而不学则殆"
console.log(stuTel()); // "13999999999"
4.3 扩展理解

一个 JS 模块在执行时,是被包裹在一个内置函数中执行的,所以每个模块都有自己的作用域,我们可以通过如下方式验证这一说法

console.log(arguments);
console.log(arguments.callee.toString());

内置函数的形式

(function (exports, require, module, __filename, __dirname) {
  // 模块代码
});
4.4 浏览器端运行

node.js 默认是支持 CommonJS 模块化规范的,但浏览器不支持,所以需要经过编译,步骤如下:

  1. 全局安装 browserify
npm install -g browserify
  1. 编译
browserify index.js -o bundle.js

备注:index.js 是源文件,bundle.js 是输出的目标文件

  1. 在页面中引入使用
<script src="bundle.js">script>

5. ES6 模块化规范

ES6 模块化规范是一个官方标准的规范,它是在语言标准的层面上实现了模块化功能,是目前最流行的模块化规范,且在浏览器和 NodeJS 中都可以运行。

5.1 初体验

查看 5_ES6模块化规范 案例

5.2 Node.js 中使用 ES6 模块化
  1. 修改文件后缀名 .mjs

  2. 添加 package.json 文件

{
  "type": "module"
}
5.3 导出数据
  1. 分别导出
// school.js
export const name = "JavaScript";
export const slogan = "让天下没有难学的技术";
  1. 统一导出
// school.js
const name = "JavaScript";
const slogan = "让天下没有难学的技术";

export { name, slogan };
  1. 默认导出
// school.js
const name = "JavaScript";
const slogan = "让天下没有难学的技术";

export default name;

上述多种导出方法可以同时使用

5.4 导入数据
  1. 导入全部
// index.js
import * as school from "./school";

console.log(school); 
  1. 命名导入 (对应导出方式:分别导出,统一导出)
// index.js
import { name, slogan } from "./school";

console.log(name); // "JavaScript"
console.log(slogan); // "让天下没有难学的技术"
  1. 默认导入 (对应导出方式:默认导出)
// index.js
import school from "./school";

console.log(school); // "JavaScript"
  1. 命名导入 与 默认导入 可以混合使用
// index.js
import school, { name, slogan } from "./school";

console.log(school); // "JavaScript"
console.log(name); // "JavaScript"
console.log(slogan); // "让天下没有难学的技术"
  1. 动态导入
// index.js
if (Math.random() > 0.5) {
  import("./school").then((school) => {
    console.log(school);
  });
} else {
  import("./student").then((student) => {
    console.log(student);
  });
}

const btn = document.getElementById("btn");
btn.onclick = async () => {
  const result = await import("./student.js");
  console.log(result);
};
  1. import 可以不接受任何数据
5.5 扩展理解
  • 模块的导入和导出是静态的,在编译时就已经确定了,运行时无法改变。
  • 模块的导入和导出是异步的,只有等到模块加载完成后,才可以进行导入和导出。
  • 模块的导入和导出是基于文件的,并不依赖于运行环境。
  • 模块的导入和导出是基于命名空间的,不同模块的命名空间互不干扰。

你可能感兴趣的:(JavaScript,javascript,开发语言,ecmascript)