前言
本篇文章只是浅聊一下commonjs和esm的使用、不涉及原理讲解相关,高手请划过。
那些年,没有模块化开发的日子
早期在做多人协同开发的时候,各自写各自的脚本文件,脚本文件里的变量名也是各自维护编写,这就带来一个问题,有可能你的脚本里可能声明了别人使用的变量名,这就是臭名昭著的变量污染(全局污染)。当然,使用匿名函数自执行的方式形成独立的块级作用域能解决这类问题,但是随着业务的复杂,我们在实际开发中遇到的情况可能会更加复杂,所以模块化开发标准诞生了。当然催生模块化开发标准诞生的条件远不止全局污染这一个问题,还有依赖的管理问题。
当前的模块化标准
由于javascript本身的一些问题,造成了今日它模块化标准的百花齐放,百家争鸣。关于javascript的模块化标准,主要有如下这几个:commonjs、amd、umd、system、esm(es6/es2015、es2020、es2022、esnext)、node12、nodenext。
CommonJs标准
CommonJs是最早提出的模块化标准解决方案,nodejs借鉴CommonJs的规范,实现了很好的模块化管理。目前CommonJs主要用在以下几个场景:
- Node是CommonJs在服务端的具有代表性的实现。
- Browserify是CommonJs在浏览器的实现。
- webpack使得前端应用可以在编译前使用CommonJs标准的库进行开发。
commonjs模块的导出和导入
// add.js
const add = (a,b)=>{
return a+b;
}
module.exports = {
add,
newAdd:add // 导出时重命名
}
// index.js
const { add, newAdd } = require("./add");
console.log("add", add(1, 2)); // 3
console.log("newAdd", newAdd(1, 2)); // 3
从外部导入一个模块并重新导出
// add.js
const add = (a,b)=>{
return a+b;
}
module.exports = {
add,
newAdd:add // 导出时重命名
}
// util.js
const addModule = require("./add");
module.exports={
...addModule
}
// index.js
const { add, newAdd } = require("./util");
console.log("add", add(1, 2));
console.log("newAdd", newAdd(1, 2));
使用exports导出一个commonjs模块
const printf = (text)=>{console.log(text)};
const text = 'Hello CommonJs';
// 错误导出,why?请等待下期文章出来
exports = {
printf,
text
}
//正确导出
exports.printf = printf;
exports.text = text;
注意事项,如果在commonjs模块中使用了exports导出属性就无法再使用module.exports默认导出了,如果使用了将会覆盖exports导出的属性
let a = 'a';
let b = 'b';
exports.a = a;
exports.b = b;
module.exports = { }; // 那么最终被导出去的是{ }
ESM标准
ESM是ECMAScript Module的缩写。ES6就是ESM的实现,从ES6开始javascript才真正意义上有了自己的模块化标准。
使用export导出一个ES模块
// hello.js
export const text = "Hello ESM!";
使用import导入一个ES模块
// 如果使用的是export的导出,则导入时需要被解构
import {text} from "./hello.js";
console.log(text);//"Hello ESM!"
使用export default导出一个ES模块
// hello.js
const text = "Hello ESM!";
export default text;
导入一个由export default导出的ES模块
imoprt text from './hello.js';
console.log(text);
导出时重命名
// util.js
const add = (a, b) => {
return a + b;
};
export { add as Add };
// index.js
import { Add } from "./util.js";
console.log("add", Add(1, 2));
引入一个外部模块重新导出
// add.js
const add = (a, b) => {
return a + b;
};
export { add as Add };
export default 'add';
// sub.js
const sub = (a, b) => {
return a - b;
};
export { sub as Sub };
// util.js
export * from "./add.js";
export * from "./sub.js";
export { Add as newAdd } from "./add.js";
export { default as str } from "./add.js";
// index.js
import { Add, newAdd, str } from "./util.js";
console.log("add", Add(1, 2)); // 3
console.log("newAdd",newAdd(1,2)); //3
console.log("str",str); // add
CommonJs与ESM导入导出的关键字表
关键字 | CommonJs | ESM |
---|---|---|
导出 | exports、module.exports | export、export default |
导入 | require(xx) | import xx from xx |