模块化 CommonJS ES Module

一、模块化

1、没有模块化的时候

xiaoming/index.js

// 我们把它写到函数里面,函数有自己的作用域
// function foo() {
//   var name = "why";
//   var isFlag = false;
// }
// foo();

// 但是上面的写法还要写foo()执行它,自执行函数可以替换
var moduleA = (function () {
  var name = "chen";
  var isFlag = true;

  // 把对象返回出去,使用变量接收
  return {
    name: name,
    isFlag: isFlag,
  };
})()

xiaoming/chen.js

(function () {
  if (moduleA.isFlag) {
    console.log("我的名字是" + moduleA.name);
  }
})()

xiaohong/index.js

(function () {
  var name = "chen";
  var isFlag = false;
})()

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script src="./xiaohong/index.js"></script>
    <script src="./xiaoming/index.js"></script>
    <script src="./xiaoming/chen.js"></script>
  </body>
</html>

2、CommonJS - module.exports导出方式*

在这里插入图片描述
chen.js

const name = "chen123";
const age = 23;

function sum(num1, num2) {
  return num1 + num2;
}

// 导出
// 导出方案: 1、module.exports
// module本身也是一个对象,exports也是
module.exports = {
  aaa: "aaaa",
  bbb: "bbb",
  name: name,
  age: age,
  sum: sum,
  // es6增强写法:
  // name, age,sum
};

// 导出方案: 2、exports

main.js

// 使用另一个模块导出的对象,那么就需要进行导入 require,函数可以跟不同的参数
const chen = require("./chen.js"); //require后面跟路径, 这个require函数会返回一个对象
const { aaa, bbb } = require("./chen.js"); // 返回的是一个对象,可以结构

console.log(chen.aaa);
console.log(aaa);
console.log(bbb);

console.log(chen.name);
console.log(chen.age);
console.log(chen.sum(20, 30));

3、CommonJS内部原理

他们是同一个对象, 三个引用指向同一个对象

在这里插入图片描述
chen.js

const info = {
  name: "chen",
  age: 23,
  foo: function () {
    console.log("foo函数~");
  },
};

setTimeout(() => {
  info.name = '天选之子'
}, 1000)
module.exports = info;

main.js

const chen = require('./chen.js');

console.log(chen);

setTimeout(() => {
  console.log(chen);
}, 2000)

3、exports导出方式
chen.js

const name = "chen123";
const age = 23;

function sum(num1, num2) {
  return num1 + num2;
}

// exports源码里面是这么实现的
// module.exports = {};
// exports = module.exports;

// 第二种导出方式
exports.age = age;
exports.name = name;
exports.sum = sum;
// 最终导出的一定是module.exports
// 下面的写法是无法导出的
// exports = {
//   name: name,
//   age: age,
// };

main.js

const chen = require('./chen.js');

console.log(chen.name);
console.log(chen.age);
console.log(chen.sum);

4、require查找规则

// 情况一:核心模块, node模块path
const path = require("path");
path.resolve();

// 情况二:路径。如果是文件夹,会使用文件夹/index.js
require("./abc");

// 情况三:不是核心模块也不是路径
const chen = require("chen"); // 查找的是main.js所在目录下面的node_modules
// console.log(module.paths);

5、模块加载细节

在这里插入图片描述
6、CommonJS弊端
在这里插入图片描述

二、ES Module 及原理

在这里插入图片描述

1、ES Module基本使用**

**三种导入跟三种导出**

foo.js

// 第二种方式: export 导出 和 声明分开
const name = "chen123";
const age = 23;
function foo() {
  console.log("foo function");
}

// export {} 这里不是对象,{}是语法。
export {
  name,
  age,
  foo,
  // 不能这么写: name: name
};


// 第三种方式: 第二种导出时起别名
export {
  name as fName,
  age as fAge,
  foo as Ffoo,
};

main.js

// 1、导入方式一:普通的导入
// import { name, age, foo } from "./foo.js";
// import { fName, fAge, Ffoo } from "./foo.js";
// console.log(name);
// console.log(age);

// 2、导入方式二:起别名
// import { name as fName, age as fAge, foo as ffoo } from "./foo.js";

// 3、导入方式三:将导出的所有内容放到一个标识符中
import * as foo from "./foo.js";

console.log(foo.name);
console.log(foo.age);


index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <!-- 这里会被当前普通的js,不允许里面有import。我们必须加上type属性,说明这是一个模块 -->
    <script src="./main.js" type="module"></script>
  </body>
</html>

注意:
在这里插入图片描述

2、ES Module结合使用**

format.js

function timeFormat() {
  return "2022-02-10";
}

function priceFormat() {
  return "222";
}

export { timeFormat, priceFormat };

math.js

function add(num1, num2) {
  return num1 + num2;
}

function sub(num1, num2) {
  return num1 - num2;
}

export { add, sub };

index.js

// 1、导出方式一:
// import { add, sub } from "./math.js";
// import { priceFormat, timeFormat } from "./format.js";

// export {
//   add,
//   sub,
//   priceFormat,
//   timeFormat
// }

// 2、导出方式二:
// export { add, sub } from "./math.js";
// export { priceFormat, timeFormat } from "./format.js";

// 2、导出方式三:
export * from "./math.js";
export * from "./format.js";

main.js

import { add, sub, priceFormat, timeFormat } from "./utils/index.js";

const sum = add(1,30)
console.log(sum);

3、ES Module - Default**

foo.js

const name = "chen";
const age = 23;

const foo = "foo value is";

// 1.默认导出的方式一:
// export { name, age, foo as default };

// 2、默认导出的方式二: 常见
export default foo;

main.js

// export{} 导出,这里的名字必须和导出的一致,name,age
// import { name, age } from "./foo.js";


// 导入语句: 导入的是默认的导出
import chen from './foo.js'
console.log(chen);

// 注意: 默认导出只能有一个

4、ES Module - import函数
foo.js

const name = "chen";
const age = 23;

const foo = "foo value is";

export { name, age, foo };

main.js

// 这种是同步代码,如果不想解析完解析完,不阻塞后面的代码,可以当成函数使用
// import { name, age, foo } from "./foo.js";

// import 函数返回的是一个Promise。整个代码是异步的,不会影响后面代码的运行
import('./foo.js').then(res => {
  // 拿到的res,其实就是整个的{ name, age, foo }
  console.log(res, res.age);
})

// console.log(name);
// 在import导入之前,后面的代码是不会执行的,相当与同步的代码
console.log("后续的代码");


// ES11新增的特性
// meta属性本身就是一个对象,{url: '当前模块所在的路径'}
console.log(import.meta);

5、ES Module原理

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值