Day 07 - ES 模块化今天学完你能做什么用import/export组织现代 JS/TS 代码理解 ES Module 和 CommonJS 的区别用typemodule在浏览器和 Node.js 中使用一、CommonJS 和 ES Module 一句话区分// CommonJSNode.js 传统 ES Module现代标准constmathrequire(./math);import{add}from./math;module.exports{add};exportfunctionadd(){}// 同步运行时加载 静态编译时确定ES Module 是 ECMAScript 官方标准是未来。二、导出 export2.1 命名导出——导出多个// math.tsexportfunctionadd(a:number,b:number):number{returnab;}exportfunctionmultiply(a:number,b:number):number{returna*b;}exportconstPI3.14159;// 也可以先定义再统一导出functionsubtract(a:number,b:number):number{returna-b;}export{subtract};2.2 默认导出——导出一个主力// calculator.tsexportdefaultclassCalculator{add(a:number,b:number){returnab;}sub(a:number,b:number){returna-b;}}// 一个文件只能有一个 export default2.3 重命名导出// utils.tsfunctionformatDate(date:Date):string{returndate.toISOString();}// 导出时改名export{formatDateastoDateString};三、导入 import3.1 导入命名导出// 按需导入import{add,multiply,PI}from./math;console.log(add(1,2));// 3console.log(multiply(3,4));// 12console.log(PI);// 3.14159// 起别名import{addassum}from./math;console.log(sum(5,5));// 10// 全部导入到一个命名空间import*asMathfrom./math;console.log(Math.add(1,2));console.log(Math.PI);3.2 导入默认导出// 默认导出可以用任意名字接收importCalcfrom./calculator;constcalcnewCalc();console.log(calc.add(10,5));// 153.3 混合导入// 同时导入默认和命名导出importCalculator,{add,PI}from./math;// 或者分开写importCalculatorfrom./calculator;import{add}from./math;3.4 只执行模块不导入任何东西// 比如初始化全局配置import./init;// 执行 init.ts 中的代码但不导入值四、ES Module vs CommonJS 对比表特性CommonJSES Module关键词require/module.exportsimport/export加载时机运行时编译时静态分析加载方式同步异步浏览器/ 同步NodeTree Shaking❌ 不支持✅ 支持打包时可删除未用代码默认导出整个module.exportsexport default顶层 this指向module.exportsundefined动态导入require可以在任何地方import()函数返回 Promise使用环境Node.js浏览器 Node.js五、动态 import() —— 按需加载// 普通 import 是静态的必须写在文件顶部// import { heavyFunction } from ./heavy-module;// 动态 import() 可以用在需要的时候才加载asyncfunctionloadHeavyModule(){constmoduleawaitimport(./heavy-module);module.heavyFunction();}// 条件加载asyncfunctionloadLocale(lang:string){letmessages;if(langzh){messagesawaitimport(./locales/zh);}else{messagesawaitimport(./locales/en);}returnmessages.default;}六、在浏览器和 Node.js 中使用浏览器!-- 必须加 typemodule --scripttypemoduleimport{add}from./math.js;console.log(add(1,2));/scriptNode.js// package.json{type:module// 整个项目用 ES Module}或者文件用.mjs扩展名。七、实际项目中的最佳实践// 分层导出模式 // 1. 每个模块写好自己的功能// utils/format.tsexportfunctionformatDate(date:Date):string{/* ... */}exportfunctionformatMoney(amount:number):string{/* ... */}// utils/validate.tsexportfunctionisEmail(value:string):boolean{/* ... */}exportfunctionisPhone(value:string):boolean{/* ... */}// 2. 用 index.ts 做桶文件统一导出// utils/index.tsexport{formatDate,formatMoney}from./format;export{isEmail,isPhone}from./validate;// 3. 使用时只需 import 一个路径import{formatDate,isEmail}from./utils;八、CommonJS → ES Module 迁移速查// CommonJS → ES Moduleconstxrequire(./x);importxfrom./x;const{a,b}require(./x);import{a,b}from./x;module.exports{a,b};export{a,b};module.exportssingle;exportdefaultsingle;exports.afunction(){};exportfunctiona(){}今日小结┌──────────────────────────────────────────────┐ │ │ │ export { a, b } → 命名导出可多个 │ │ export default X → 默认导出只一个 │ │ │ │ import { a } from → 按需导入 │ │ import X from → 导入默认 │ │ import * as N from → 全部导入到命名空间 │ │ │ │ import() → 动态导入返回 Promise │ │ │ │ ES Module 是标准CommonJS 在慢慢退出 │ │ │ │ 口诀export 往外给import 往里拿 │ │ │ └──────────────────────────────────────────────┘