[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"knowledge-\u002Fapi\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fcommon":3,"knowledge-related-\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fcommon":2294,"knowledge-series-\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fcommon":2319},{"source":4,"connector":5,"page":6},"sqlite","better-sqlite3",{"path":7,"title":8,"description":9,"category":10,"tags":11,"date":14,"pinned":15,"draft":15,"body":16,"seo":2290,"stem":2291,"id":2292,"extension":2293},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fcommon","模块化与工程化","ESM、CommonJS 与打包工具（Tree Shaking、代码分割）是前端工程化的基础。入门见 JavaScript 基础 · 模块。","技能小册",[12,13],"javascript","common","2025-06-21",false,{"type":17,"value":18,"toc":2266},"minimark",[19,22,32,37,40,54,58,323,326,329,440,447,492,496,531,538,541,630,636,640,650,654,780,784,895,899,1073,1076,1080,1084,1087,1153,1157,1160,1369,1372,1376,1379,1383,1392,1397,1420,1490,1507,1511,1514,1519,1545,1588,1594,1598,1601,1605,1608,1799,1806,1814,1833,1837,1840,2012,2021,2027,2042,2066,2069,2090,2093,2163,2168,2179,2182,2185,2188,2262],[20,21,8],"h1",{"id":8},[23,24,25,26,31],"p",{},"ESM、CommonJS 与打包工具（Tree Shaking、代码分割）是前端工程化的基础。入门见 ",[27,28,30],"a",{"href":29},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fbasics","JavaScript 基础 · 模块","。",[33,34,36],"h2",{"id":35},"一es6-模块esm","一、ES6 模块（ESM）",[23,38,39],{},"ES6 模块是 ECMAScript 2015 引入的官方模块化方案，具有静态结构、支持异步加载等特点。",[41,42,44,45,49,50,53],"h3",{"id":43},"_1-export-import-基本用法","1. ",[46,47,48],"code",{},"export"," \u002F ",[46,51,52],{},"import"," 基本用法",[55,56,57],"h4",{"id":57},"命名导出与导入",[59,60,65],"pre",{"className":61,"code":62,"language":63,"meta":64,"style":64},"language-js shiki shiki-themes material-theme-lighter github-light github-dark","\u002F\u002F 📁 math.js\nexport const PI = 3.14159;\nexport function add(a, b) { return a + b; }\nexport class Circle { ... }\n\n\u002F\u002F 或集中导出\nconst E = 2.718;\nfunction multiply(a, b) { return a * b; }\nexport { E, multiply };\n\n\u002F\u002F 📁 main.js\nimport { PI, add, multiply } from '.\u002Fmath.js';\nimport * as MathLib from '.\u002Fmath.js'; \u002F\u002F 命名空间导入\n","js","",[46,66,67,76,102,150,169,176,182,198,232,248,253,259,295],{"__ignoreMap":64},[68,69,72],"span",{"class":70,"line":71},"line",1,[68,73,75],{"class":74},"sutJx","\u002F\u002F 📁 math.js\n",[68,77,79,82,86,90,94,98],{"class":70,"line":78},2,[68,80,48],{"class":81},"sVHd0",[68,83,85],{"class":84},"sbsja"," const",[68,87,89],{"class":88},"s_hVV"," PI",[68,91,93],{"class":92},"smGrS"," =",[68,95,97],{"class":96},"srdBf"," 3.14159",[68,99,101],{"class":100},"sP7_E",";\n",[68,103,105,107,110,114,117,120,123,126,129,132,135,139,142,144,147],{"class":70,"line":104},3,[68,106,48],{"class":81},[68,108,109],{"class":84}," function",[68,111,113],{"class":112},"sGLFI"," add",[68,115,116],{"class":100},"(",[68,118,27],{"class":119},"s99_P",[68,121,122],{"class":100},",",[68,124,125],{"class":119}," b",[68,127,128],{"class":100},")",[68,130,131],{"class":100}," {",[68,133,134],{"class":81}," return",[68,136,138],{"class":137},"su5hD"," a",[68,140,141],{"class":92}," +",[68,143,125],{"class":137},[68,145,146],{"class":100},";",[68,148,149],{"class":100}," }\n",[68,151,153,155,158,162,164,167],{"class":70,"line":152},4,[68,154,48],{"class":81},[68,156,157],{"class":84}," class",[68,159,161],{"class":160},"sbgvK"," Circle",[68,163,131],{"class":100},[68,165,166],{"class":92}," ...",[68,168,149],{"class":100},[68,170,172],{"class":70,"line":171},5,[68,173,175],{"emptyLinePlaceholder":174},true,"\n",[68,177,179],{"class":70,"line":178},6,[68,180,181],{"class":74},"\u002F\u002F 或集中导出\n",[68,183,185,188,191,193,196],{"class":70,"line":184},7,[68,186,187],{"class":84},"const",[68,189,190],{"class":88}," E",[68,192,93],{"class":92},[68,194,195],{"class":96}," 2.718",[68,197,101],{"class":100},[68,199,201,204,207,209,211,213,215,217,219,221,223,226,228,230],{"class":70,"line":200},8,[68,202,203],{"class":84},"function",[68,205,206],{"class":112}," multiply",[68,208,116],{"class":100},[68,210,27],{"class":119},[68,212,122],{"class":100},[68,214,125],{"class":119},[68,216,128],{"class":100},[68,218,131],{"class":100},[68,220,134],{"class":81},[68,222,138],{"class":137},[68,224,225],{"class":92}," *",[68,227,125],{"class":137},[68,229,146],{"class":100},[68,231,149],{"class":100},[68,233,235,237,239,241,243,245],{"class":70,"line":234},9,[68,236,48],{"class":81},[68,238,131],{"class":100},[68,240,190],{"class":137},[68,242,122],{"class":100},[68,244,206],{"class":137},[68,246,247],{"class":100}," };\n",[68,249,251],{"class":70,"line":250},10,[68,252,175],{"emptyLinePlaceholder":174},[68,254,256],{"class":70,"line":255},11,[68,257,258],{"class":74},"\u002F\u002F 📁 main.js\n",[68,260,262,264,266,268,270,272,274,276,279,282,286,290,293],{"class":70,"line":261},12,[68,263,52],{"class":81},[68,265,131],{"class":100},[68,267,89],{"class":137},[68,269,122],{"class":100},[68,271,113],{"class":137},[68,273,122],{"class":100},[68,275,206],{"class":137},[68,277,278],{"class":100}," }",[68,280,281],{"class":81}," from",[68,283,285],{"class":284},"sjJ54"," '",[68,287,289],{"class":288},"s_sjI",".\u002Fmath.js",[68,291,292],{"class":284},"'",[68,294,101],{"class":100},[68,296,298,300,303,306,309,312,314,316,318,320],{"class":70,"line":297},13,[68,299,52],{"class":81},[68,301,225],{"class":302},"s39Yj",[68,304,305],{"class":81}," as",[68,307,308],{"class":137}," MathLib ",[68,310,311],{"class":81},"from",[68,313,285],{"class":284},[68,315,289],{"class":288},[68,317,292],{"class":284},[68,319,146],{"class":100},[68,321,322],{"class":74}," \u002F\u002F 命名空间导入\n",[55,324,325],{"id":325},"默认导出与导入",[23,327,328],{},"每个模块最多有一个默认导出。",[59,330,332],{"className":61,"code":331,"language":63,"meta":64,"style":64},"\u002F\u002F 📁 logger.js\nexport default function log(message) {\n  console.log(message);\n}\n\u002F\u002F 也可以 export default class \u002F const\n\n\u002F\u002F 📁 main.js\nimport customName from \".\u002Flogger.js\"; \u002F\u002F 默认导入可以任意命名\ncustomName(\"Hello\");\n",[46,333,334,339,361,381,386,391,395,399,422],{"__ignoreMap":64},[68,335,336],{"class":70,"line":71},[68,337,338],{"class":74},"\u002F\u002F 📁 logger.js\n",[68,340,341,343,346,348,351,353,356,358],{"class":70,"line":78},[68,342,48],{"class":81},[68,344,345],{"class":81}," default",[68,347,109],{"class":84},[68,349,350],{"class":112}," log",[68,352,116],{"class":100},[68,354,355],{"class":119},"message",[68,357,128],{"class":100},[68,359,360],{"class":100}," {\n",[68,362,363,366,369,372,375,377,379],{"class":70,"line":104},[68,364,365],{"class":137},"  console",[68,367,368],{"class":100},".",[68,370,371],{"class":112},"log",[68,373,116],{"class":374},"skxfh",[68,376,355],{"class":137},[68,378,128],{"class":374},[68,380,101],{"class":100},[68,382,383],{"class":70,"line":152},[68,384,385],{"class":100},"}\n",[68,387,388],{"class":70,"line":171},[68,389,390],{"class":74},"\u002F\u002F 也可以 export default class \u002F const\n",[68,392,393],{"class":70,"line":178},[68,394,175],{"emptyLinePlaceholder":174},[68,396,397],{"class":70,"line":184},[68,398,258],{"class":74},[68,400,401,403,406,408,411,414,417,419],{"class":70,"line":200},[68,402,52],{"class":81},[68,404,405],{"class":137}," customName ",[68,407,311],{"class":81},[68,409,410],{"class":284}," \"",[68,412,413],{"class":288},".\u002Flogger.js",[68,415,416],{"class":284},"\"",[68,418,146],{"class":100},[68,420,421],{"class":74}," \u002F\u002F 默认导入可以任意命名\n",[68,423,424,427,429,431,434,436,438],{"class":70,"line":234},[68,425,426],{"class":112},"customName",[68,428,116],{"class":137},[68,430,416],{"class":284},[68,432,433],{"class":288},"Hello",[68,435,416],{"class":284},[68,437,128],{"class":137},[68,439,101],{"class":100},[23,441,442,446],{},[443,444,445],"strong",{},"混合导出","（默认 + 命名）：",[59,448,450],{"className":61,"code":449,"language":63,"meta":64,"style":64},"export default function main() { ... }\nexport const helper = ...;\n\u002F\u002F 导入时：import main, { helper } from '.\u002Fmodule.js';\n",[46,451,452,472,487],{"__ignoreMap":64},[68,453,454,456,458,460,463,466,468,470],{"class":70,"line":71},[68,455,48],{"class":81},[68,457,345],{"class":81},[68,459,109],{"class":84},[68,461,462],{"class":112}," main",[68,464,465],{"class":100},"()",[68,467,131],{"class":100},[68,469,166],{"class":92},[68,471,149],{"class":100},[68,473,474,476,478,481,483,485],{"class":70,"line":78},[68,475,48],{"class":81},[68,477,85],{"class":84},[68,479,480],{"class":88}," helper",[68,482,93],{"class":92},[68,484,166],{"class":92},[68,486,101],{"class":100},[68,488,489],{"class":70,"line":104},[68,490,491],{"class":74},"\u002F\u002F 导入时：import main, { helper } from '.\u002Fmodule.js';\n",[41,493,495],{"id":494},"_2-模块特点","2. 模块特点",[497,498,499,509,519,525],"ul",{},[500,501,502,505,506,508],"li",{},[443,503,504],{},"静态解析","：",[46,507,52],{}," 必须在模块顶层，不能嵌套在条件或函数中；这使构建工具可以进行静态分析（Tree Shaking）。",[500,510,511,514,515,518],{},[443,512,513],{},"实时绑定（live binding）","：导入的是值的",[443,516,517],{},"引用","，当原始模块内的值变化时，导入方会同步更新（与 CommonJS 拷贝不同）。",[500,520,521,524],{},[443,522,523],{},"严格模式自动启用","：模块内自动处于严格模式。",[500,526,527,530],{},[443,528,529],{},"支持异步加载","（见下文动态导入）。",[41,532,534,535],{"id":533},"_3-动态导入-import","3. 动态导入 ",[46,536,537],{},"import()",[23,539,540],{},"返回一个 Promise，可以在运行时按需加载模块，实现代码分割。",[59,542,544],{"className":61,"code":543,"language":63,"meta":64,"style":64},"button.addEventListener(\"click\", async () => {\n  const module = await import(\".\u002Fheavy-module.js\");\n  module.doSomething();\n});\n",[46,545,546,578,607,621],{"__ignoreMap":64},[68,547,548,551,553,556,558,560,563,565,567,570,573,576],{"class":70,"line":71},[68,549,550],{"class":137},"button",[68,552,368],{"class":100},[68,554,555],{"class":112},"addEventListener",[68,557,116],{"class":137},[68,559,416],{"class":284},[68,561,562],{"class":288},"click",[68,564,416],{"class":284},[68,566,122],{"class":100},[68,568,569],{"class":84}," async",[68,571,572],{"class":100}," ()",[68,574,575],{"class":84}," =>",[68,577,360],{"class":100},[68,579,580,583,586,588,591,594,596,598,601,603,605],{"class":70,"line":78},[68,581,582],{"class":84},"  const",[68,584,585],{"class":88}," module",[68,587,93],{"class":92},[68,589,590],{"class":81}," await",[68,592,593],{"class":92}," import",[68,595,116],{"class":374},[68,597,416],{"class":284},[68,599,600],{"class":288},".\u002Fheavy-module.js",[68,602,416],{"class":284},[68,604,128],{"class":374},[68,606,101],{"class":100},[68,608,609,612,614,617,619],{"class":70,"line":104},[68,610,611],{"class":302},"  module",[68,613,368],{"class":100},[68,615,616],{"class":112},"doSomething",[68,618,465],{"class":374},[68,620,101],{"class":100},[68,622,623,626,628],{"class":70,"line":152},[68,624,625],{"class":100},"}",[68,627,128],{"class":137},[68,629,101],{"class":100},[23,631,632,635],{},[443,633,634],{},"适用场景","：路由懒加载、条件加载、按需加载大型依赖。",[33,637,639],{"id":638},"二commonjscjs","二、CommonJS（CJS）",[23,641,642,643,646,647,31],{},"CommonJS 最初为服务器端（Node.js）设计，采用同步加载，使用 ",[46,644,645],{},"require"," 和 ",[46,648,649],{},"module.exports",[41,651,653],{"id":652},"_1-基本语法","1. 基本语法",[59,655,657],{"className":61,"code":656,"language":63,"meta":64,"style":64},"\u002F\u002F 📁 lib.js\nconst privateVar = 42;\nmodule.exports = {\n  publicMethod() { ... },\n  constant: 100\n};\n\u002F\u002F 或者 exports.xxx = ...（exports 是 module.exports 的引用）\n\n\u002F\u002F 📁 main.js\nconst lib = require('.\u002Flib.js');\nconsole.log(lib.constant);\n",[46,658,659,664,678,692,707,718,723,728,732,736,761],{"__ignoreMap":64},[68,660,661],{"class":70,"line":71},[68,662,663],{"class":74},"\u002F\u002F 📁 lib.js\n",[68,665,666,668,671,673,676],{"class":70,"line":78},[68,667,187],{"class":84},[68,669,670],{"class":88}," privateVar",[68,672,93],{"class":92},[68,674,675],{"class":96}," 42",[68,677,101],{"class":100},[68,679,680,683,685,688,690],{"class":70,"line":104},[68,681,682],{"class":302},"module",[68,684,368],{"class":100},[68,686,687],{"class":302},"exports",[68,689,93],{"class":92},[68,691,360],{"class":100},[68,693,694,698,700,702,704],{"class":70,"line":152},[68,695,697],{"class":696},"sVXei","  publicMethod",[68,699,465],{"class":100},[68,701,131],{"class":100},[68,703,166],{"class":92},[68,705,706],{"class":100}," },\n",[68,708,709,712,715],{"class":70,"line":171},[68,710,711],{"class":374},"  constant",[68,713,714],{"class":100},":",[68,716,717],{"class":96}," 100\n",[68,719,720],{"class":70,"line":178},[68,721,722],{"class":100},"};\n",[68,724,725],{"class":70,"line":184},[68,726,727],{"class":74},"\u002F\u002F 或者 exports.xxx = ...（exports 是 module.exports 的引用）\n",[68,729,730],{"class":70,"line":200},[68,731,175],{"emptyLinePlaceholder":174},[68,733,734],{"class":70,"line":234},[68,735,258],{"class":74},[68,737,738,740,743,745,748,750,752,755,757,759],{"class":70,"line":250},[68,739,187],{"class":84},[68,741,742],{"class":88}," lib",[68,744,93],{"class":92},[68,746,747],{"class":112}," require",[68,749,116],{"class":137},[68,751,292],{"class":284},[68,753,754],{"class":288},".\u002Flib.js",[68,756,292],{"class":284},[68,758,128],{"class":137},[68,760,101],{"class":100},[68,762,763,766,768,770,773,775,778],{"class":70,"line":255},[68,764,765],{"class":137},"console",[68,767,368],{"class":100},[68,769,371],{"class":112},[68,771,772],{"class":137},"(lib",[68,774,368],{"class":100},[68,776,777],{"class":137},"constant)",[68,779,101],{"class":100},[41,781,783],{"id":782},"_2-与-esm-的核心差异","2. 与 ESM 的核心差异",[785,786,787,803],"table",{},[788,789,790],"thead",{},[791,792,793,797,800],"tr",{},[794,795,796],"th",{},"特性",[794,798,799],{},"ES6 模块 (ESM)",[794,801,802],{},"CommonJS (CJS)",[804,805,806,818,835,854,865,876],"tbody",{},[791,807,808,812,815],{},[809,810,811],"td",{},"加载时机",[809,813,814],{},"编译时静态分析，运行时可能异步（import()）",[809,816,817],{},"运行时同步加载",[791,819,820,823,829],{},[809,821,822],{},"导出值形式",[809,824,825,828],{},[443,826,827],{},"实时绑定","（引用）",[809,830,831,834],{},[443,832,833],{},"值的拷贝","（浅拷贝）",[791,836,837,843,848],{},[809,838,839,842],{},[46,840,841],{},"this"," 指向",[809,844,845],{},[46,846,847],{},"undefined",[809,849,850,851,853],{},"当前模块的 ",[46,852,687],{}," 对象",[791,855,856,859,862],{},[809,857,858],{},"循环依赖处理",[809,860,861],{},"通过“绑定”可以部分解决（需提前导出）",[809,863,864],{},"在加载时执行，可能得到不完整的导出",[791,866,867,870,873],{},[809,868,869],{},"可静态分析",[809,871,872],{},"是（支持 Tree Shaking）",[809,874,875],{},"否",[791,877,878,881,892],{},[809,879,880],{},"使用环境",[809,882,883,884,887,888,891],{},"浏览器、Node.js（需 ",[46,885,886],{},".mjs"," 或 ",[46,889,890],{},"type: module","）",[809,893,894],{},"Node.js 传统，浏览器需打包",[55,896,898],{"id":897},"导出值拷贝示例cjs","导出值拷贝示例（CJS）：",[59,900,902],{"className":61,"code":901,"language":63,"meta":64,"style":64},"\u002F\u002F counter.js\nlet count = 0;\nmodule.exports = {\n  get count() {\n    return count;\n  }, \u002F\u002F 若想动态获取需用 getter\n  inc() {\n    count++;\n  },\n};\n\u002F\u002F main.js\nconst { count, inc } = require(\".\u002Fcounter.js\");\nconsole.log(count); \u002F\u002F 0\ninc();\nconsole.log(count); \u002F\u002F 0（仍是初始拷贝值，除非用 getter）\n",[46,903,904,909,925,937,949,958,966,975,985,990,994,999,1031,1047,1057],{"__ignoreMap":64},[68,905,906],{"class":70,"line":71},[68,907,908],{"class":74},"\u002F\u002F counter.js\n",[68,910,911,914,917,920,923],{"class":70,"line":78},[68,912,913],{"class":84},"let",[68,915,916],{"class":137}," count ",[68,918,919],{"class":92},"=",[68,921,922],{"class":96}," 0",[68,924,101],{"class":100},[68,926,927,929,931,933,935],{"class":70,"line":104},[68,928,682],{"class":302},[68,930,368],{"class":100},[68,932,687],{"class":302},[68,934,93],{"class":92},[68,936,360],{"class":100},[68,938,939,942,945,947],{"class":70,"line":152},[68,940,941],{"class":84},"  get",[68,943,944],{"class":696}," count",[68,946,465],{"class":100},[68,948,360],{"class":100},[68,950,951,954,956],{"class":70,"line":171},[68,952,953],{"class":81},"    return",[68,955,944],{"class":137},[68,957,101],{"class":100},[68,959,960,963],{"class":70,"line":178},[68,961,962],{"class":100},"  },",[68,964,965],{"class":74}," \u002F\u002F 若想动态获取需用 getter\n",[68,967,968,971,973],{"class":70,"line":184},[68,969,970],{"class":696},"  inc",[68,972,465],{"class":100},[68,974,360],{"class":100},[68,976,977,980,983],{"class":70,"line":200},[68,978,979],{"class":137},"    count",[68,981,982],{"class":92},"++",[68,984,101],{"class":100},[68,986,987],{"class":70,"line":234},[68,988,989],{"class":100},"  },\n",[68,991,992],{"class":70,"line":250},[68,993,722],{"class":100},[68,995,996],{"class":70,"line":255},[68,997,998],{"class":74},"\u002F\u002F main.js\n",[68,1000,1001,1003,1005,1007,1009,1012,1014,1016,1018,1020,1022,1025,1027,1029],{"class":70,"line":261},[68,1002,187],{"class":84},[68,1004,131],{"class":100},[68,1006,944],{"class":88},[68,1008,122],{"class":100},[68,1010,1011],{"class":88}," inc",[68,1013,278],{"class":100},[68,1015,93],{"class":92},[68,1017,747],{"class":112},[68,1019,116],{"class":137},[68,1021,416],{"class":284},[68,1023,1024],{"class":288},".\u002Fcounter.js",[68,1026,416],{"class":284},[68,1028,128],{"class":137},[68,1030,101],{"class":100},[68,1032,1033,1035,1037,1039,1042,1044],{"class":70,"line":297},[68,1034,765],{"class":137},[68,1036,368],{"class":100},[68,1038,371],{"class":112},[68,1040,1041],{"class":137},"(count)",[68,1043,146],{"class":100},[68,1045,1046],{"class":74}," \u002F\u002F 0\n",[68,1048,1050,1053,1055],{"class":70,"line":1049},14,[68,1051,1052],{"class":112},"inc",[68,1054,465],{"class":137},[68,1056,101],{"class":100},[68,1058,1060,1062,1064,1066,1068,1070],{"class":70,"line":1059},15,[68,1061,765],{"class":137},[68,1063,368],{"class":100},[68,1065,371],{"class":112},[68,1067,1041],{"class":137},[68,1069,146],{"class":100},[68,1071,1072],{"class":74}," \u002F\u002F 0（仍是初始拷贝值，除非用 getter）\n",[23,1074,1075],{},"而在 ESM 中，导入的值会随原始模块变化而更新（因为绑定）。",[33,1077,1079],{"id":1078},"三amd-umd简要","三、AMD \u002F UMD（简要）",[41,1081,1083],{"id":1082},"_1-amdasynchronous-module-definition","1. AMD（Asynchronous Module Definition）",[23,1085,1086],{},"代表实现：RequireJS。专为浏览器设计，支持异步加载，语法较复杂。",[59,1088,1090],{"className":61,"code":1089,"language":63,"meta":64,"style":64},"define([\"dependency\"], function (dep) {\n  return { doSomething: () => {} };\n});\n",[46,1091,1092,1124,1145],{"__ignoreMap":64},[68,1093,1094,1097,1100,1102,1105,1107,1110,1112,1114,1117,1120,1122],{"class":70,"line":71},[68,1095,1096],{"class":112},"define",[68,1098,1099],{"class":137},"([",[68,1101,416],{"class":284},[68,1103,1104],{"class":288},"dependency",[68,1106,416],{"class":284},[68,1108,1109],{"class":137},"]",[68,1111,122],{"class":100},[68,1113,109],{"class":84},[68,1115,1116],{"class":100}," (",[68,1118,1119],{"class":119},"dep",[68,1121,128],{"class":100},[68,1123,360],{"class":100},[68,1125,1126,1129,1131,1134,1136,1138,1140,1143],{"class":70,"line":78},[68,1127,1128],{"class":81},"  return",[68,1130,131],{"class":100},[68,1132,1133],{"class":112}," doSomething",[68,1135,714],{"class":100},[68,1137,572],{"class":100},[68,1139,575],{"class":84},[68,1141,1142],{"class":100}," {}",[68,1144,247],{"class":100},[68,1146,1147,1149,1151],{"class":70,"line":104},[68,1148,625],{"class":100},[68,1150,128],{"class":137},[68,1152,101],{"class":100},[41,1154,1156],{"id":1155},"_2-umduniversal-module-definition","2. UMD（Universal Module Definition）",[23,1158,1159],{},"一种兼容性模式，同时支持 AMD、CommonJS 和全局变量挂载。通常由构建工具（如 Rollup、Webpack）生成，用于发布跨环境使用的库。",[59,1161,1163],{"className":61,"code":1162,"language":63,"meta":64,"style":64},"(function (root, factory) {\n  if (typeof define === 'function' && define.amd) { define(['dep'], factory); }\n  else if (typeof module === 'object' && module.exports) { module.exports = factory(require('dep')); }\n  else { root.myLib = factory(root.dep); }\n}(this, function(dep) { ... }));\n",[46,1164,1165,1185,1245,1309,1341],{"__ignoreMap":64},[68,1166,1167,1169,1171,1173,1176,1178,1181,1183],{"class":70,"line":71},[68,1168,116],{"class":137},[68,1170,203],{"class":84},[68,1172,1116],{"class":100},[68,1174,1175],{"class":119},"root",[68,1177,122],{"class":100},[68,1179,1180],{"class":119}," factory",[68,1182,128],{"class":100},[68,1184,360],{"class":100},[68,1186,1187,1190,1192,1195,1198,1201,1203,1205,1207,1210,1212,1214,1217,1220,1223,1225,1227,1229,1231,1233,1235,1237,1239,1241,1243],{"class":70,"line":78},[68,1188,1189],{"class":81},"  if",[68,1191,1116],{"class":374},[68,1193,1194],{"class":92},"typeof",[68,1196,1197],{"class":137}," define",[68,1199,1200],{"class":92}," ===",[68,1202,285],{"class":284},[68,1204,203],{"class":288},[68,1206,292],{"class":284},[68,1208,1209],{"class":92}," &&",[68,1211,1197],{"class":137},[68,1213,368],{"class":100},[68,1215,1216],{"class":137},"amd",[68,1218,1219],{"class":374},") ",[68,1221,1222],{"class":100},"{",[68,1224,1197],{"class":112},[68,1226,1099],{"class":374},[68,1228,292],{"class":284},[68,1230,1119],{"class":288},[68,1232,292],{"class":284},[68,1234,1109],{"class":374},[68,1236,122],{"class":100},[68,1238,1180],{"class":137},[68,1240,128],{"class":374},[68,1242,146],{"class":100},[68,1244,149],{"class":100},[68,1246,1247,1250,1253,1255,1257,1259,1261,1263,1266,1268,1270,1272,1274,1276,1278,1280,1282,1284,1286,1288,1290,1292,1294,1296,1298,1300,1302,1305,1307],{"class":70,"line":104},[68,1248,1249],{"class":81},"  else",[68,1251,1252],{"class":81}," if",[68,1254,1116],{"class":374},[68,1256,1194],{"class":92},[68,1258,585],{"class":302},[68,1260,1200],{"class":92},[68,1262,285],{"class":284},[68,1264,1265],{"class":288},"object",[68,1267,292],{"class":284},[68,1269,1209],{"class":92},[68,1271,585],{"class":302},[68,1273,368],{"class":100},[68,1275,687],{"class":302},[68,1277,1219],{"class":374},[68,1279,1222],{"class":100},[68,1281,585],{"class":302},[68,1283,368],{"class":100},[68,1285,687],{"class":302},[68,1287,93],{"class":92},[68,1289,1180],{"class":112},[68,1291,116],{"class":374},[68,1293,645],{"class":112},[68,1295,116],{"class":374},[68,1297,292],{"class":284},[68,1299,1119],{"class":288},[68,1301,292],{"class":284},[68,1303,1304],{"class":374},"))",[68,1306,146],{"class":100},[68,1308,149],{"class":100},[68,1310,1311,1313,1315,1318,1320,1323,1325,1327,1329,1331,1333,1335,1337,1339],{"class":70,"line":152},[68,1312,1249],{"class":81},[68,1314,131],{"class":100},[68,1316,1317],{"class":137}," root",[68,1319,368],{"class":100},[68,1321,1322],{"class":137},"myLib",[68,1324,93],{"class":92},[68,1326,1180],{"class":112},[68,1328,116],{"class":374},[68,1330,1175],{"class":137},[68,1332,368],{"class":100},[68,1334,1119],{"class":137},[68,1336,128],{"class":374},[68,1338,146],{"class":100},[68,1340,149],{"class":100},[68,1342,1343,1345,1347,1349,1351,1353,1355,1357,1359,1361,1363,1365,1367],{"class":70,"line":171},[68,1344,625],{"class":100},[68,1346,116],{"class":137},[68,1348,841],{"class":302},[68,1350,122],{"class":100},[68,1352,109],{"class":84},[68,1354,116],{"class":100},[68,1356,1119],{"class":119},[68,1358,128],{"class":100},[68,1360,131],{"class":100},[68,1362,166],{"class":92},[68,1364,278],{"class":100},[68,1366,1304],{"class":137},[68,1368,101],{"class":100},[23,1370,1371],{},"如今，随着 ESM 成为标准，新项目推荐直接使用 ESM，UMD 主要用于向后兼容。",[33,1373,1375],{"id":1374},"四打包工具原理以-webpack-rollup-vite-为例","四、打包工具原理（以 Webpack \u002F Rollup \u002F Vite 为例）",[23,1377,1378],{},"打包工具将多个模块合并为一个或多个 bundle，并解决依赖关系。",[41,1380,1382],{"id":1381},"_1-tree-shaking","1. Tree Shaking",[23,1384,1385,1388,1389,1391],{},[443,1386,1387],{},"原理","：基于 ES 模块的静态结构，分析代码中哪些 ",[46,1390,48],{}," 被实际使用，然后剔除未使用的“死代码”。",[23,1393,1394,505],{},[443,1395,1396],{},"条件",[497,1398,1399,1406,1417],{},[500,1400,1401,1402,1405],{},"使用 ESM 语法（静态 ",[46,1403,1404],{},"import\u002Fexport","）。",[500,1407,1408,1409,1412,1413,1416],{},"无副作用（side effect）的模块可被安全删除；可在 ",[46,1410,1411],{},"package.json"," 中用 ",[46,1414,1415],{},"\"sideEffects\": false"," 声明。",[500,1418,1419],{},"生产模式开启优化。",[59,1421,1425],{"className":1422,"code":1423,"language":1424,"meta":64,"style":64},"language-json shiki shiki-themes material-theme-lighter github-light github-dark","\u002F\u002F package.json\n{\n  \"sideEffects\": false, \u002F\u002F 所有模块无副作用\n  \u002F\u002F 或指定有副作用的文件\n  \"sideEffects\": [\".\u002Fpolyfill.js\"]\n}\n","json",[46,1426,1427,1432,1437,1458,1463,1486],{"__ignoreMap":64},[68,1428,1429],{"class":70,"line":71},[68,1430,1431],{"class":74},"\u002F\u002F package.json\n",[68,1433,1434],{"class":70,"line":78},[68,1435,1436],{"class":100},"{\n",[68,1438,1439,1442,1446,1448,1450,1453,1455],{"class":70,"line":104},[68,1440,1441],{"class":302},"  \"",[68,1443,1445],{"class":1444},"sseR_","sideEffects",[68,1447,416],{"class":302},[68,1449,714],{"class":100},[68,1451,1452],{"class":302}," false",[68,1454,122],{"class":100},[68,1456,1457],{"class":74}," \u002F\u002F 所有模块无副作用\n",[68,1459,1460],{"class":70,"line":152},[68,1461,1462],{"class":74},"  \u002F\u002F 或指定有副作用的文件\n",[68,1464,1465,1467,1469,1471,1473,1476,1478,1481,1483],{"class":70,"line":171},[68,1466,1441],{"class":302},[68,1468,1445],{"class":1444},[68,1470,416],{"class":302},[68,1472,714],{"class":100},[68,1474,1475],{"class":100}," [",[68,1477,416],{"class":284},[68,1479,1480],{"class":288},".\u002Fpolyfill.js",[68,1482,416],{"class":284},[68,1484,1485],{"class":100},"]\n",[68,1487,1488],{"class":70,"line":178},[68,1489,385],{"class":100},[23,1491,1492,505,1495,1498,1499,1502,1503,1506],{},[443,1493,1494],{},"示例",[46,1496,1497],{},"import { add } from '.\u002Fmath'"," 只打包 ",[46,1500,1501],{},"add"," 函数，未使用的 ",[46,1504,1505],{},"multiply"," 被移除。",[41,1508,1510],{"id":1509},"_2-代码分割code-splitting","2. 代码分割（Code Splitting）",[23,1512,1513],{},"将代码拆分成多个 chunk，按需加载，减少初始加载体积。",[23,1515,1516,505],{},[443,1517,1518],{},"实现方式",[497,1520,1521,1527,1535],{},[500,1522,1523,1526],{},[443,1524,1525],{},"入口点分割","：多入口配置，每个入口生成独立 bundle。",[500,1528,1529,505,1532,1534],{},[443,1530,1531],{},"动态导入",[46,1533,537],{}," 自动拆分成单独 chunk。",[500,1536,1537,1540,1541,1544],{},[443,1538,1539],{},"共享模块分割","（如 ",[46,1542,1543],{},"SplitChunksPlugin"," 提取公共依赖，避免重复）。",[59,1546,1548],{"className":61,"code":1547,"language":63,"meta":64,"style":64},"\u002F\u002F 路由懒加载（React）\nconst Profile = lazy(() => import(\".\u002FProfile\"));\n",[46,1549,1550,1555],{"__ignoreMap":64},[68,1551,1552],{"class":70,"line":71},[68,1553,1554],{"class":74},"\u002F\u002F 路由懒加载（React）\n",[68,1556,1557,1559,1562,1564,1567,1569,1571,1573,1575,1577,1579,1582,1584,1586],{"class":70,"line":78},[68,1558,187],{"class":84},[68,1560,1561],{"class":88}," Profile",[68,1563,93],{"class":92},[68,1565,1566],{"class":112}," lazy",[68,1568,116],{"class":137},[68,1570,465],{"class":100},[68,1572,575],{"class":84},[68,1574,593],{"class":92},[68,1576,116],{"class":137},[68,1578,416],{"class":284},[68,1580,1581],{"class":288},".\u002FProfile",[68,1583,416],{"class":284},[68,1585,1304],{"class":137},[68,1587,101],{"class":100},[23,1589,1590,1593],{},[443,1591,1592],{},"优势","：缓存友好（公共库单独打包）、首屏加载更快。",[41,1595,1597],{"id":1596},"_3-循环引用处理","3. 循环引用处理",[23,1599,1600],{},"循环依赖指模块 A 依赖 B，B 又依赖 A（直接或间接）。打包工具需要妥善处理。",[55,1602,1604],{"id":1603},"commonjs-中的循环引用","CommonJS 中的循环引用",[23,1606,1607],{},"由于 CommonJS 是运行时同步加载，在模块加载时就会执行代码，可能得到不完整的导出。",[59,1609,1611],{"className":61,"code":1610,"language":63,"meta":64,"style":64},"\u002F\u002F a.js\nexports.a = \"a1\";\nconst b = require(\".\u002Fb.js\");\nconsole.log(\"a 中 b:\", b);\nexports.a = \"a2\";\n\n\u002F\u002F b.js\nexports.b = \"b1\";\nconst a = require(\".\u002Fa.js\");\nconsole.log(\"b 中 a:\", a);\nexports.b = \"b2\";\n",[46,1612,1613,1618,1638,1661,1685,1704,1708,1713,1733,1756,1780],{"__ignoreMap":64},[68,1614,1615],{"class":70,"line":71},[68,1616,1617],{"class":74},"\u002F\u002F a.js\n",[68,1619,1620,1622,1624,1627,1629,1631,1634,1636],{"class":70,"line":78},[68,1621,687],{"class":302},[68,1623,368],{"class":100},[68,1625,1626],{"class":137},"a ",[68,1628,919],{"class":92},[68,1630,410],{"class":284},[68,1632,1633],{"class":288},"a1",[68,1635,416],{"class":284},[68,1637,101],{"class":100},[68,1639,1640,1642,1644,1646,1648,1650,1652,1655,1657,1659],{"class":70,"line":104},[68,1641,187],{"class":84},[68,1643,125],{"class":88},[68,1645,93],{"class":92},[68,1647,747],{"class":112},[68,1649,116],{"class":137},[68,1651,416],{"class":284},[68,1653,1654],{"class":288},".\u002Fb.js",[68,1656,416],{"class":284},[68,1658,128],{"class":137},[68,1660,101],{"class":100},[68,1662,1663,1665,1667,1669,1671,1673,1676,1678,1680,1683],{"class":70,"line":152},[68,1664,765],{"class":137},[68,1666,368],{"class":100},[68,1668,371],{"class":112},[68,1670,116],{"class":137},[68,1672,416],{"class":284},[68,1674,1675],{"class":288},"a 中 b:",[68,1677,416],{"class":284},[68,1679,122],{"class":100},[68,1681,1682],{"class":137}," b)",[68,1684,101],{"class":100},[68,1686,1687,1689,1691,1693,1695,1697,1700,1702],{"class":70,"line":171},[68,1688,687],{"class":302},[68,1690,368],{"class":100},[68,1692,1626],{"class":137},[68,1694,919],{"class":92},[68,1696,410],{"class":284},[68,1698,1699],{"class":288},"a2",[68,1701,416],{"class":284},[68,1703,101],{"class":100},[68,1705,1706],{"class":70,"line":178},[68,1707,175],{"emptyLinePlaceholder":174},[68,1709,1710],{"class":70,"line":184},[68,1711,1712],{"class":74},"\u002F\u002F b.js\n",[68,1714,1715,1717,1719,1722,1724,1726,1729,1731],{"class":70,"line":200},[68,1716,687],{"class":302},[68,1718,368],{"class":100},[68,1720,1721],{"class":137},"b ",[68,1723,919],{"class":92},[68,1725,410],{"class":284},[68,1727,1728],{"class":288},"b1",[68,1730,416],{"class":284},[68,1732,101],{"class":100},[68,1734,1735,1737,1739,1741,1743,1745,1747,1750,1752,1754],{"class":70,"line":234},[68,1736,187],{"class":84},[68,1738,138],{"class":88},[68,1740,93],{"class":92},[68,1742,747],{"class":112},[68,1744,116],{"class":137},[68,1746,416],{"class":284},[68,1748,1749],{"class":288},".\u002Fa.js",[68,1751,416],{"class":284},[68,1753,128],{"class":137},[68,1755,101],{"class":100},[68,1757,1758,1760,1762,1764,1766,1768,1771,1773,1775,1778],{"class":70,"line":250},[68,1759,765],{"class":137},[68,1761,368],{"class":100},[68,1763,371],{"class":112},[68,1765,116],{"class":137},[68,1767,416],{"class":284},[68,1769,1770],{"class":288},"b 中 a:",[68,1772,416],{"class":284},[68,1774,122],{"class":100},[68,1776,1777],{"class":137}," a)",[68,1779,101],{"class":100},[68,1781,1782,1784,1786,1788,1790,1792,1795,1797],{"class":70,"line":255},[68,1783,687],{"class":302},[68,1785,368],{"class":100},[68,1787,1721],{"class":137},[68,1789,919],{"class":92},[68,1791,410],{"class":284},[68,1793,1794],{"class":288},"b2",[68,1796,416],{"class":284},[68,1798,101],{"class":100},[23,1800,1801,1802,1805],{},"执行 ",[46,1803,1804],{},"node a.js"," 输出：",[59,1807,1812],{"className":1808,"code":1810,"language":1811},[1809],"language-text","b 中 a: { a: 'a1' }\na 中 b: { b: 'b2' }\n","text",[46,1813,1810],{"__ignoreMap":64},[23,1815,1816,1817,1820,1821,1823,1824,1827,1828,1830,1831,31],{},"加载 ",[46,1818,1819],{},"b"," 时，",[46,1822,27],{}," 只执行到 ",[46,1825,1826],{},"exports.a = 'a1'"," 就暂停，所以 ",[46,1829,1819],{}," 中看到的是部分 ",[46,1832,27],{},[55,1834,1836],{"id":1835},"esm-中的循环引用","ESM 中的循环引用",[23,1838,1839],{},"ESM 依靠“实时绑定”和“引用”机制，可以处理循环依赖，但需要确保在访问前已经导出。",[59,1841,1843],{"className":61,"code":1842,"language":63,"meta":64,"style":64},"\u002F\u002F a.mjs\nimport { b } from \".\u002Fb.mjs\";\nexport let a = \"a1\";\nconsole.log(\"a 中 b:\", b);\na = \"a2\";\n\n\u002F\u002F b.mjs\nimport { a } from \".\u002Fa.mjs\";\nexport let b = \"b1\";\nconsole.log(\"b 中 a:\", a);\nb = \"b2\";\n",[46,1844,1845,1850,1871,1891,1913,1927,1931,1936,1957,1976,1998],{"__ignoreMap":64},[68,1846,1847],{"class":70,"line":71},[68,1848,1849],{"class":74},"\u002F\u002F a.mjs\n",[68,1851,1852,1854,1856,1858,1860,1862,1864,1867,1869],{"class":70,"line":78},[68,1853,52],{"class":81},[68,1855,131],{"class":100},[68,1857,125],{"class":137},[68,1859,278],{"class":100},[68,1861,281],{"class":81},[68,1863,410],{"class":284},[68,1865,1866],{"class":288},".\u002Fb.mjs",[68,1868,416],{"class":284},[68,1870,101],{"class":100},[68,1872,1873,1875,1878,1881,1883,1885,1887,1889],{"class":70,"line":104},[68,1874,48],{"class":81},[68,1876,1877],{"class":84}," let",[68,1879,1880],{"class":137}," a ",[68,1882,919],{"class":92},[68,1884,410],{"class":284},[68,1886,1633],{"class":288},[68,1888,416],{"class":284},[68,1890,101],{"class":100},[68,1892,1893,1895,1897,1899,1901,1903,1905,1907,1909,1911],{"class":70,"line":152},[68,1894,765],{"class":137},[68,1896,368],{"class":100},[68,1898,371],{"class":112},[68,1900,116],{"class":137},[68,1902,416],{"class":284},[68,1904,1675],{"class":288},[68,1906,416],{"class":284},[68,1908,122],{"class":100},[68,1910,1682],{"class":137},[68,1912,101],{"class":100},[68,1914,1915,1917,1919,1921,1923,1925],{"class":70,"line":171},[68,1916,1626],{"class":137},[68,1918,919],{"class":92},[68,1920,410],{"class":284},[68,1922,1699],{"class":288},[68,1924,416],{"class":284},[68,1926,101],{"class":100},[68,1928,1929],{"class":70,"line":178},[68,1930,175],{"emptyLinePlaceholder":174},[68,1932,1933],{"class":70,"line":184},[68,1934,1935],{"class":74},"\u002F\u002F b.mjs\n",[68,1937,1938,1940,1942,1944,1946,1948,1950,1953,1955],{"class":70,"line":200},[68,1939,52],{"class":81},[68,1941,131],{"class":100},[68,1943,138],{"class":137},[68,1945,278],{"class":100},[68,1947,281],{"class":81},[68,1949,410],{"class":284},[68,1951,1952],{"class":288},".\u002Fa.mjs",[68,1954,416],{"class":284},[68,1956,101],{"class":100},[68,1958,1959,1961,1963,1966,1968,1970,1972,1974],{"class":70,"line":234},[68,1960,48],{"class":81},[68,1962,1877],{"class":84},[68,1964,1965],{"class":137}," b ",[68,1967,919],{"class":92},[68,1969,410],{"class":284},[68,1971,1728],{"class":288},[68,1973,416],{"class":284},[68,1975,101],{"class":100},[68,1977,1978,1980,1982,1984,1986,1988,1990,1992,1994,1996],{"class":70,"line":250},[68,1979,765],{"class":137},[68,1981,368],{"class":100},[68,1983,371],{"class":112},[68,1985,116],{"class":137},[68,1987,416],{"class":284},[68,1989,1770],{"class":288},[68,1991,416],{"class":284},[68,1993,122],{"class":100},[68,1995,1777],{"class":137},[68,1997,101],{"class":100},[68,1999,2000,2002,2004,2006,2008,2010],{"class":70,"line":255},[68,2001,1721],{"class":137},[68,2003,919],{"class":92},[68,2005,410],{"class":284},[68,2007,1794],{"class":288},[68,2009,416],{"class":284},[68,2011,101],{"class":100},[23,2013,2014,2015,887,2017,2020],{},"在 Node.js 中运行 ",[46,2016,886],{},[46,2018,2019],{},"\"type\":\"module\""," 项目时，典型输出类似：",[59,2022,2025],{"className":2023,"code":2024,"language":1811},[1809],"b 中 a: undefined\na 中 b: b1\n",[46,2026,2024],{"__ignoreMap":64},[23,2028,2029,2030,2032,2033,2035,2036,2038,2039,2041],{},"（",[46,2031,1819],{}," 执行时 ",[46,2034,27],{}," 的 ",[46,2037,913],{}," 尚未完成初始化；之后通过绑定可读到更新后的 ",[46,2040,27],{},"。）",[23,2043,2044,2045,2047,2048,1820,2050,2052,2053,2055,2056,2058,2059,2061,2062,2065],{},"注意：在初始化阶段，",[46,2046,1819],{}," 试图访问 ",[46,2049,27],{},[46,2051,27],{}," 尚未赋值（",[46,2054,847],{},"）。但后续 ",[46,2057,27],{}," 改变，",[46,2060,1819],{}," 中通过绑定也能看到新值（如果是在函数内部访问）。",[443,2063,2064],{},"最佳实践","：避免循环依赖，或将共享代码抽离到公共模块。",[55,2067,2068],{"id":2068},"打包工具的处理策略",[497,2070,2071,2084],{},[500,2072,2073,2076,2077,2080,2081,2083],{},[443,2074,2075],{},"Webpack","：通过模块的 ",[46,2078,2079],{},"__webpack_require__"," 和缓存机制，先返回一个不完整的 ",[46,2082,687],{}," 对象，再递归加载。开发者应确保在循环依赖中，不要在初始化阶段直接访问不完整的导出。",[500,2085,2086,2089],{},[443,2087,2088],{},"Rollup","：利用 ESM 实时绑定，支持循环依赖但同样建议避免。",[33,2091,2092],{"id":2092},"总结",[785,2094,2095,2107],{},[788,2096,2097],{},[791,2098,2099,2102,2105],{},[794,2100,2101],{},"模块方案",[794,2103,2104],{},"核心特点",[794,2106,634],{},[804,2108,2109,2122,2137,2150],{},[791,2110,2111,2116,2119],{},[809,2112,2113],{},[443,2114,2115],{},"ESM",[809,2117,2118],{},"静态结构、实时绑定、支持异步导入、Tree Shaking 友好",[809,2120,2121],{},"现代浏览器、Node.js（新项目首选）",[791,2123,2124,2129,2134],{},[809,2125,2126],{},[443,2127,2128],{},"CommonJS",[809,2130,2131,2132],{},"运行时同步、值拷贝、动态 ",[46,2133,645],{},[809,2135,2136],{},"Node.js 传统项目、部分工具脚本",[791,2138,2139,2144,2147],{},[809,2140,2141],{},[443,2142,2143],{},"AMD",[809,2145,2146],{},"浏览器异步加载，回调风格",[809,2148,2149],{},"遗留项目（RequireJS）",[791,2151,2152,2157,2160],{},[809,2153,2154],{},[443,2155,2156],{},"UMD",[809,2158,2159],{},"兼容多种环境，作为库的通用封装格式",[809,2161,2162],{},"发布通用 JavaScript 库",[23,2164,2165,505],{},[443,2166,2167],{},"打包工具原理进阶",[497,2169,2170,2173,2176],{},[500,2171,2172],{},"Tree Shaking 依赖静态 ESM，移除死代码。",[500,2174,2175],{},"代码分割通过动态导入和多入口实现。",[500,2177,2178],{},"循环引用需要警惕初始化阶段的不完整导出，ESM 通过绑定缓解但仍建议避免。",[23,2180,2181],{},"在实际工程中，推荐使用 ESM 编写代码，利用打包工具的优化能力，同时遵循单一职责原则，避免循环依赖，以构建高性能、可维护的应用。",[33,2183,2184],{"id":2184},"参考文献",[23,2186,2187],{},"以下链接在编写时均可正常访问：",[785,2189,2190,2200],{},[788,2191,2192],{},[791,2193,2194,2197],{},[794,2195,2196],{},"资料",[794,2198,2199],{},"说明",[804,2201,2202,2215,2227,2238,2250],{},[791,2203,2204,2212],{},[809,2205,2206],{},[27,2207,2211],{"href":2208,"rel":2209},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FJavaScript\u002FGuide\u002FModules",[2210],"nofollow","MDN：JavaScript 模块",[809,2213,2214],{},"ESM 指南",[791,2216,2217,2224],{},[809,2218,2219],{},[27,2220,2223],{"href":2221,"rel":2222},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FStatements\u002Fimport",[2210],"MDN：import",[809,2225,2226],{},"静态导入",[791,2228,2229,2236],{},[809,2230,2231],{},[27,2232,2235],{"href":2233,"rel":2234},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fzh-CN\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FOperators\u002Fimport",[2210],"MDN：import()",[809,2237,1531],{},[791,2239,2240,2247],{},[809,2241,2242],{},[27,2243,2246],{"href":2244,"rel":2245},"https:\u002F\u002Fnodejs.org\u002Fapi\u002Fesm.html",[2210],"Node.js：Modules",[809,2248,2249],{},"Node ESM（英文）",[791,2251,2252,2259],{},[809,2253,2254],{},[27,2255,2258],{"href":2256,"rel":2257},"https:\u002F\u002Fwebpack.js.org\u002Fguides\u002Ftree-shaking\u002F",[2210],"webpack：Tree Shaking",[809,2260,2261],{},"Tree Shaking（英文）",[2263,2264,2265],"style",{},"html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s99_P, html code.shiki .s99_P{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sVXei, html code.shiki .sVXei{--shiki-light:#E53935;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sseR_, html code.shiki .sseR_{--shiki-light:#9C3EDA;--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":64,"searchDepth":78,"depth":78,"links":2267},[2268,2275,2279,2283,2288,2289],{"id":35,"depth":78,"text":36,"children":2269},[2270,2272,2273],{"id":43,"depth":104,"text":2271},"1. export \u002F import 基本用法",{"id":494,"depth":104,"text":495},{"id":533,"depth":104,"text":2274},"3. 动态导入 import()",{"id":638,"depth":78,"text":639,"children":2276},[2277,2278],{"id":652,"depth":104,"text":653},{"id":782,"depth":104,"text":783},{"id":1078,"depth":78,"text":1079,"children":2280},[2281,2282],{"id":1082,"depth":104,"text":1083},{"id":1155,"depth":104,"text":1156},{"id":1374,"depth":78,"text":1375,"children":2284},[2285,2286,2287],{"id":1381,"depth":104,"text":1382},{"id":1509,"depth":104,"text":1510},{"id":1596,"depth":104,"text":1597},{"id":2092,"depth":78,"text":2092},{"id":2184,"depth":78,"text":2184},{"title":8,"description":9},"knowledge\u002Fbooklet\u002Fweb\u002FJs\u002Fcommon","knowledge\u002Fknowledge\u002Fbooklet\u002Fweb\u002FJs\u002Fcommon.md","md",{"items":2295},[2296,2300,2304,2308,2312,2316],{"path":2297,"title":2298,"description":2299,"category":10,"score":178},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Ferror","错误处理与调试","结构化错误类型、try\u002Fcatch 与全局未捕获处理是健壮应用的基础。",{"path":2301,"title":2302,"description":2303,"category":10,"score":178},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fdom-bom","浏览器相关 API","DOM 事件、存储、fetch、Worker、Observer 等由浏览器提供的 Web API（非 ECMAScript 核心）。HTML 结构见 标签。",{"path":2305,"title":2306,"description":2307,"category":10,"score":178},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fperformance","性能优化","防抖\u002F节流、渲染与内存、资源预加载及引擎行为是前端性能的主要抓手。相关 CSS 见 视觉效果、Head 资源提示。",{"path":2309,"title":2310,"description":2311,"category":10,"score":178},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fscope","执行模型与作用域","执行上下文与词法作用域决定变量在何处可访问、闭包如何形成，以及 var \u002F let \u002F const 的差异。语言概览见 JavaScript 基础。",{"path":2313,"title":2314,"description":2315,"category":10,"score":178},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fmap-set","数据结构与集合增强","Map \u002F Set、WeakMap \u002F WeakSet、数组高阶方法、TypedArray 与 Symbol 等扩展了内置数据结构能力。见 语言基础。",{"path":29,"title":2317,"description":2318,"category":10,"score":178},"JavaScript 基础","JavaScript（ECMAScript）是 Web 页面与 Node.js 等运行时的脚本语言：在浏览器中操作 DOM、发起网络请求；在服务端处理 I\u002FO。语法与 HTML、CSS 配合构成前端技术栈。",{"series":2320,"title":63,"items":2321,"index":78,"prev":2363,"next":2364},"booklet\u002Fweb\u002Fjs",[2322,2326,2328,2329,2333,2335,2337,2341,2345,2347,2349,2353,2357,2361],{"path":2323,"title":2324,"date":2325,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fadvanced","函数进阶","2022-10-24",{"path":29,"title":2317,"date":2327,"pinned":15},"2023-11-24",{"path":7,"title":8,"date":14,"pinned":15},{"path":2330,"title":2331,"date":2332,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fdesign","设计模式","2021-10-05",{"path":2301,"title":2302,"date":2334,"pinned":15},"2025-07-10",{"path":2297,"title":2298,"date":2336,"pinned":15},"2026-06-25",{"path":2338,"title":2339,"date":2340,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fevent-loop","异步编程与事件循环","2020-03-23",{"path":2342,"title":2343,"date":2344,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fexec","正则表达式","2022-05-21",{"path":2313,"title":2314,"date":2346,"pinned":15},"2024-07-10",{"path":2305,"title":2306,"date":2348,"pinned":15},"2025-07-04",{"path":2350,"title":2351,"date":2352,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fprototype","原型与面向对象","2020-04-13",{"path":2354,"title":2355,"date":2356,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fproxy","代理与反射","2022-10-23",{"path":2358,"title":2359,"date":2360,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fweb\u002Fjs\u002Fsafe","安全","2023-06-26",{"path":2309,"title":2310,"date":2362,"pinned":15},"2025-01-29",{"path":29,"title":2317,"date":2327,"pinned":15},{"path":2330,"title":2331,"date":2332,"pinned":15}]