[{"data":1,"prerenderedAt":2283},["ShallowReactive",2],{"doc-\u002Fdocs\u002Fwebpack-basics":3,"docs-all":2105},{"id":4,"title":5,"body":6,"category":2089,"date":2090,"description":2091,"draft":2092,"extension":2093,"meta":2094,"navigation":432,"path":2095,"seo":2096,"source":2097,"stem":2098,"tags":2099,"__hash__":2104},"docs\u002Fdocs\u002Fwebpack-basics.md","Webpack 4 配置与开发服务器笔记",{"type":7,"value":8,"toc":2074},"minimark",[9,14,27,31,34,94,97,100,103,161,168,285,303,307,350,357,361,364,705,731,738,741,752,987,998,1002,1008,1061,1064,1068,1075,1316,1328,1331,1377,1392,1395,1402,1613,1616,1766,1769,1773,1780,1787,2001,2004,2007,2010,2070],[10,11,13],"h1",{"id":12},"webpack-4-配置笔记","Webpack 4 配置笔记",[15,16,17,18,22,23,26],"p",{},"本篇对应原课程 Webpack 4.43、webpack-cli 3.3、webpack-dev-server 3.11。代码均为文档示例，不包含完整 Node 工程。",[19,20,21],"code",{},"contentBase","、",[19,24,25],{},"before"," 等按旧版本记录，不可直接照搬到其他大版本。",[28,29,30],"h2",{"id":30},"模块打包与工具分工",[15,32,33],{},"Webpack 从入口建立模块依赖图，按配置转换和输出资源；开发服务器可以提供静态资源、监听与重新编译。",[35,36,37,50],"table",{},[38,39,40],"thead",{},[41,42,43,47],"tr",{},[44,45,46],"th",{},"工具",[44,48,49],{},"本课程中的定位",[51,52,53,62,70,78,86],"tbody",{},[41,54,55,59],{},[56,57,58],"td",{},"npm scripts",[56,60,61],{},"用命令串联工具",[41,63,64,67],{},[56,65,66],{},"Gulp",[56,68,69],{},"显式配置文件处理任务和流",[41,71,72,75],{},[56,73,74],{},"Webpack",[56,76,77],{},"根据模块依赖组织构建",[41,79,80,83],{},[56,81,82],{},"Rollup",[56,84,85],{},"另一种模块打包工具，常见于库构建",[41,87,88,91],{},[56,89,90],{},"FIS3",[56,92,93],{},"课程提到的历史工具名称，本目录没有相关实现",[15,95,96],{},"工具各有场景，原文“某工具只适合上线前”“某工具只能打包 JS”过于绝对。Webpack 可解析 JavaScript 和 JSON，其他资源可经 loader 接入。",[28,98,99],{"id":99},"命令与基本配置",[15,101,102],{},"独立课程环境的安装与调用示意：",[104,105,110],"pre",{"className":106,"code":107,"language":108,"meta":109,"style":109},"language-sh shiki shiki-themes github-light github-dark","npm install --save-dev webpack@4 webpack-cli@3 webpack-dev-server@3\nnpx webpack --mode development\nnpx webpack-dev-server\n","sh","",[19,111,112,138,153],{"__ignoreMap":109},[113,114,117,121,125,129,132,135],"span",{"class":115,"line":116},"line",1,[113,118,120],{"class":119},"sScJk","npm",[113,122,124],{"class":123},"sZZnC"," install",[113,126,128],{"class":127},"sj4cs"," --save-dev",[113,130,131],{"class":123}," webpack@4",[113,133,134],{"class":123}," webpack-cli@3",[113,136,137],{"class":123}," webpack-dev-server@3\n",[113,139,141,144,147,150],{"class":115,"line":140},2,[113,142,143],{"class":119},"npx",[113,145,146],{"class":123}," webpack",[113,148,149],{"class":127}," --mode",[113,151,152],{"class":123}," development\n",[113,154,156,158],{"class":115,"line":155},3,[113,157,143],{"class":119},[113,159,160],{"class":123}," webpack-dev-server\n",[15,162,163,164,167],{},"CommonJS ",[19,165,166],{},"webpack.config.js","：",[104,169,173],{"className":170,"code":171,"language":172,"meta":109,"style":109},"language-js shiki shiki-themes github-light github-dark","const path = require('path');\nmodule.exports = {\n  mode: 'development',\n  entry: '.\u002Fsrc\u002Fmain.js',\n  output: {\n    filename: 'build.js',\n    path: path.resolve(__dirname, 'dist')\n  }\n};\n","js",[19,174,175,200,216,227,238,244,255,273,279],{"__ignoreMap":109},[113,176,177,181,184,187,190,194,197],{"class":115,"line":116},[113,178,180],{"class":179},"szBVR","const",[113,182,183],{"class":127}," path",[113,185,186],{"class":179}," =",[113,188,189],{"class":119}," require",[113,191,193],{"class":192},"sVt8B","(",[113,195,196],{"class":123},"'path'",[113,198,199],{"class":192},");\n",[113,201,202,205,208,211,213],{"class":115,"line":140},[113,203,204],{"class":127},"module",[113,206,207],{"class":192},".",[113,209,210],{"class":127},"exports",[113,212,186],{"class":179},[113,214,215],{"class":192}," {\n",[113,217,218,221,224],{"class":115,"line":155},[113,219,220],{"class":192},"  mode: ",[113,222,223],{"class":123},"'development'",[113,225,226],{"class":192},",\n",[113,228,230,233,236],{"class":115,"line":229},4,[113,231,232],{"class":192},"  entry: ",[113,234,235],{"class":123},"'.\u002Fsrc\u002Fmain.js'",[113,237,226],{"class":192},[113,239,241],{"class":115,"line":240},5,[113,242,243],{"class":192},"  output: {\n",[113,245,247,250,253],{"class":115,"line":246},6,[113,248,249],{"class":192},"    filename: ",[113,251,252],{"class":123},"'build.js'",[113,254,226],{"class":192},[113,256,258,261,264,267,270],{"class":115,"line":257},7,[113,259,260],{"class":192},"    path: path.",[113,262,263],{"class":119},"resolve",[113,265,266],{"class":192},"(__dirname, ",[113,268,269],{"class":123},"'dist'",[113,271,272],{"class":192},")\n",[113,274,276],{"class":115,"line":275},8,[113,277,278],{"class":192},"  }\n",[113,280,282],{"class":115,"line":281},9,[113,283,284],{"class":192},"};\n",[15,286,287,290,291,294,295,298,299,302],{},[19,288,289],{},"output.path"," 是绝对文件系统路径。",[19,292,293],{},"development"," 便于开发调试，",[19,296,297],{},"production"," 启用生产优化；Webpack 4 还支持 ",[19,300,301],{},"none","，并非只有课程讲的两个取值。",[304,305,306],"h3",{"id":306},"单入口与多入口",[35,308,309,319],{},[38,310,311],{},[41,312,313,316],{},[44,314,315],{},"entry 写法",[44,317,318],{},"说明",[51,320,321,330,340],{},[41,322,323,327],{},[56,324,325],{},[19,326,235],{},[56,328,329],{},"单个入口模块",[41,331,332,337],{},[56,333,334],{},[19,335,336],{},"['.\u002Fsrc\u002Fa.js', '.\u002Fsrc\u002Fmain.js']",[56,338,339],{},"同一入口中包含多个模块",[41,341,342,347],{},[56,343,344],{},[19,345,346],{},"{ app: '.\u002Fsrc\u002Fapp.js', main: '.\u002Fsrc\u002Fmain.js' }",[56,348,349],{},"多个命名入口",[15,351,352,353,356],{},"多入口应使用区分名称的输出，如 ",[19,354,355],{},"filename: '[name]_[chunkhash:8].js'","。实际输出还可能包括异步 chunk、资源等，不能把“单入口”理解为永远只有一个文件。",[28,358,360],{"id":359},"loader-与-plugin","loader 与 plugin",[15,362,363],{},"loader 转换匹配模块，plugin 参与更广的构建流程。以下根据 006 课配置整理，依赖原课的 babel-loader 8、file-loader 6、html-webpack-plugin 4、clean-webpack-plugin 3 及 Babel 7。",[104,365,367],{"className":170,"code":366,"language":172,"meta":109,"style":109},"const path = require('path');\nconst HtmlWebpackPlugin = require('html-webpack-plugin');\nconst { CleanWebpackPlugin } = require('clean-webpack-plugin');\n\nmodule.exports = {\n  mode: 'development',\n  entry: '.\u002Fsrc\u002Fmain.js',\n  output: {\n    filename: 'out.js',\n    path: path.resolve(__dirname, 'dist')\n  },\n  module: {\n    rules: [\n      {\n        test: \u002F\\.js$\u002F,\n        exclude: \u002Fnode_modules\u002F,\n        use: {\n          loader: 'babel-loader',\n          options: { presets: ['@babel\u002Fpreset-env'] }\n        }\n      },\n      { test: \u002F\\.(png|jpe?g|gif|svg)$\u002Fi, use: 'file-loader' }\n    ]\n  },\n  plugins: [\n    new CleanWebpackPlugin(),\n    new HtmlWebpackPlugin({ template: '.\u002Findex.html', filename: 'home.html' })\n  ]\n};\n",[19,368,369,385,403,428,434,446,454,462,466,475,488,494,500,506,512,536,551,557,568,580,586,592,643,649,654,660,672,694,700],{"__ignoreMap":109},[113,370,371,373,375,377,379,381,383],{"class":115,"line":116},[113,372,180],{"class":179},[113,374,183],{"class":127},[113,376,186],{"class":179},[113,378,189],{"class":119},[113,380,193],{"class":192},[113,382,196],{"class":123},[113,384,199],{"class":192},[113,386,387,389,392,394,396,398,401],{"class":115,"line":140},[113,388,180],{"class":179},[113,390,391],{"class":127}," HtmlWebpackPlugin",[113,393,186],{"class":179},[113,395,189],{"class":119},[113,397,193],{"class":192},[113,399,400],{"class":123},"'html-webpack-plugin'",[113,402,199],{"class":192},[113,404,405,407,410,413,416,419,421,423,426],{"class":115,"line":155},[113,406,180],{"class":179},[113,408,409],{"class":192}," { ",[113,411,412],{"class":127},"CleanWebpackPlugin",[113,414,415],{"class":192}," } ",[113,417,418],{"class":179},"=",[113,420,189],{"class":119},[113,422,193],{"class":192},[113,424,425],{"class":123},"'clean-webpack-plugin'",[113,427,199],{"class":192},[113,429,430],{"class":115,"line":229},[113,431,433],{"emptyLinePlaceholder":432},true,"\n",[113,435,436,438,440,442,444],{"class":115,"line":240},[113,437,204],{"class":127},[113,439,207],{"class":192},[113,441,210],{"class":127},[113,443,186],{"class":179},[113,445,215],{"class":192},[113,447,448,450,452],{"class":115,"line":246},[113,449,220],{"class":192},[113,451,223],{"class":123},[113,453,226],{"class":192},[113,455,456,458,460],{"class":115,"line":257},[113,457,232],{"class":192},[113,459,235],{"class":123},[113,461,226],{"class":192},[113,463,464],{"class":115,"line":275},[113,465,243],{"class":192},[113,467,468,470,473],{"class":115,"line":281},[113,469,249],{"class":192},[113,471,472],{"class":123},"'out.js'",[113,474,226],{"class":192},[113,476,478,480,482,484,486],{"class":115,"line":477},10,[113,479,260],{"class":192},[113,481,263],{"class":119},[113,483,266],{"class":192},[113,485,269],{"class":123},[113,487,272],{"class":192},[113,489,491],{"class":115,"line":490},11,[113,492,493],{"class":192},"  },\n",[113,495,497],{"class":115,"line":496},12,[113,498,499],{"class":192},"  module: {\n",[113,501,503],{"class":115,"line":502},13,[113,504,505],{"class":192},"    rules: [\n",[113,507,509],{"class":115,"line":508},14,[113,510,511],{"class":192},"      {\n",[113,513,515,518,521,525,528,531,534],{"class":115,"line":514},15,[113,516,517],{"class":192},"        test:",[113,519,520],{"class":123}," \u002F",[113,522,524],{"class":523},"snhLl","\\.",[113,526,172],{"class":527},"sA_wV",[113,529,530],{"class":179},"$",[113,532,533],{"class":123},"\u002F",[113,535,226],{"class":192},[113,537,539,542,544,547,549],{"class":115,"line":538},16,[113,540,541],{"class":192},"        exclude:",[113,543,520],{"class":123},[113,545,546],{"class":527},"node_modules",[113,548,533],{"class":123},[113,550,226],{"class":192},[113,552,554],{"class":115,"line":553},17,[113,555,556],{"class":192},"        use: {\n",[113,558,560,563,566],{"class":115,"line":559},18,[113,561,562],{"class":192},"          loader: ",[113,564,565],{"class":123},"'babel-loader'",[113,567,226],{"class":192},[113,569,571,574,577],{"class":115,"line":570},19,[113,572,573],{"class":192},"          options: { presets: [",[113,575,576],{"class":123},"'@babel\u002Fpreset-env'",[113,578,579],{"class":192},"] }\n",[113,581,583],{"class":115,"line":582},20,[113,584,585],{"class":192},"        }\n",[113,587,589],{"class":115,"line":588},21,[113,590,591],{"class":192},"      },\n",[113,593,595,598,600,602,605,608,611,614,617,619,622,624,627,629,631,634,637,640],{"class":115,"line":594},22,[113,596,597],{"class":192},"      { test:",[113,599,520],{"class":123},[113,601,524],{"class":523},[113,603,604],{"class":527},"(png",[113,606,607],{"class":179},"|",[113,609,610],{"class":527},"jpe",[113,612,613],{"class":179},"?",[113,615,616],{"class":527},"g",[113,618,607],{"class":179},[113,620,621],{"class":527},"gif",[113,623,607],{"class":179},[113,625,626],{"class":527},"svg)",[113,628,530],{"class":179},[113,630,533],{"class":123},[113,632,633],{"class":179},"i",[113,635,636],{"class":192},", use: ",[113,638,639],{"class":123},"'file-loader'",[113,641,642],{"class":192}," }\n",[113,644,646],{"class":115,"line":645},23,[113,647,648],{"class":192},"    ]\n",[113,650,652],{"class":115,"line":651},24,[113,653,493],{"class":192},[113,655,657],{"class":115,"line":656},25,[113,658,659],{"class":192},"  plugins: [\n",[113,661,663,666,669],{"class":115,"line":662},26,[113,664,665],{"class":179},"    new",[113,667,668],{"class":119}," CleanWebpackPlugin",[113,670,671],{"class":192},"(),\n",[113,673,675,677,679,682,685,688,691],{"class":115,"line":674},27,[113,676,665],{"class":179},[113,678,391],{"class":119},[113,680,681],{"class":192},"({ template: ",[113,683,684],{"class":123},"'.\u002Findex.html'",[113,686,687],{"class":192},", filename: ",[113,689,690],{"class":123},"'home.html'",[113,692,693],{"class":192}," })\n",[113,695,697],{"class":115,"line":696},28,[113,698,699],{"class":192},"  ]\n",[113,701,703],{"class":115,"line":702},29,[113,704,284],{"class":192},[15,706,707,710,711,714,715,718,719,722,723,730],{},[19,708,709],{},"test"," 匹配文件，",[19,712,713],{},"include","／",[19,716,717],{},"exclude"," 控制范围，",[19,720,721],{},"use"," 可写字符串、对象或数组。loader 数组的普通转换阶段从右向左执行。",[724,725,729],"a",{"href":726,"rel":727},"https:\u002F\u002Fv4.webpack.js.org\u002Fconcepts\u002Floaders\u002F",[728],"nofollow","Webpack 4 loader 文档","。",[15,732,733,734,737],{},"HTML 模板只需页面结构；由 HtmlWebpackPlugin 注入产物脚本时，应移除原模板手写的 ",[19,735,736],{},"dist\u002Fbuild.js","，否则容易重复或引用旧产物。",[304,739,740],{"id":740},"图片模块与路径",[15,742,743,744,747,748,751],{},"原代码跨目录引用 ",[19,745,746],{},"..\u002F..\u002F01_gulp\u002Fimages\u002F2.jpg","，再手动拼接 ",[19,749,750],{},"dist\u002F","。整理为同一示例目录中的资源路径；文件名代表使用者提供的图片，不随博客迁入。",[104,753,755],{"className":170,"code":754,"language":172,"meta":109,"style":109},"import imageUrl from '.\u002Fimages\u002F2.jpg';\n\nconst image = new Image();\nconst timer = setTimeout(() => finish(new Error('图片加载超时')), 5000);\nfunction finish(error) {\n  clearTimeout(timer);\n  image.onload = null;\n  image.onerror = null;\n  if (error) console.error(error.message);\n  else document.body.append(image);\n}\nimage.alt = '课程示例图片';\nimage.onload = () => finish();\nimage.onerror = () => finish(new Error('图片加载失败'));\nimage.src = imageUrl;\n",[19,756,757,774,778,796,838,854,862,874,885,898,912,917,929,948,977],{"__ignoreMap":109},[113,758,759,762,765,768,771],{"class":115,"line":116},[113,760,761],{"class":179},"import",[113,763,764],{"class":192}," imageUrl ",[113,766,767],{"class":179},"from",[113,769,770],{"class":123}," '.\u002Fimages\u002F2.jpg'",[113,772,773],{"class":192},";\n",[113,775,776],{"class":115,"line":140},[113,777,433],{"emptyLinePlaceholder":432},[113,779,780,782,785,787,790,793],{"class":115,"line":155},[113,781,180],{"class":179},[113,783,784],{"class":127}," image",[113,786,186],{"class":179},[113,788,789],{"class":179}," new",[113,791,792],{"class":119}," Image",[113,794,795],{"class":192},"();\n",[113,797,798,800,803,805,808,811,814,817,819,822,825,827,830,833,836],{"class":115,"line":229},[113,799,180],{"class":179},[113,801,802],{"class":127}," timer",[113,804,186],{"class":179},[113,806,807],{"class":119}," setTimeout",[113,809,810],{"class":192},"(() ",[113,812,813],{"class":179},"=>",[113,815,816],{"class":119}," finish",[113,818,193],{"class":192},[113,820,821],{"class":179},"new",[113,823,824],{"class":119}," Error",[113,826,193],{"class":192},[113,828,829],{"class":123},"'图片加载超时'",[113,831,832],{"class":192},")), ",[113,834,835],{"class":127},"5000",[113,837,199],{"class":192},[113,839,840,843,845,847,851],{"class":115,"line":240},[113,841,842],{"class":179},"function",[113,844,816],{"class":119},[113,846,193],{"class":192},[113,848,850],{"class":849},"s4XuR","error",[113,852,853],{"class":192},") {\n",[113,855,856,859],{"class":115,"line":246},[113,857,858],{"class":119},"  clearTimeout",[113,860,861],{"class":192},"(timer);\n",[113,863,864,867,869,872],{"class":115,"line":257},[113,865,866],{"class":192},"  image.onload ",[113,868,418],{"class":179},[113,870,871],{"class":127}," null",[113,873,773],{"class":192},[113,875,876,879,881,883],{"class":115,"line":275},[113,877,878],{"class":192},"  image.onerror ",[113,880,418],{"class":179},[113,882,871],{"class":127},[113,884,773],{"class":192},[113,886,887,890,893,895],{"class":115,"line":281},[113,888,889],{"class":179},"  if",[113,891,892],{"class":192}," (error) console.",[113,894,850],{"class":119},[113,896,897],{"class":192},"(error.message);\n",[113,899,900,903,906,909],{"class":115,"line":477},[113,901,902],{"class":179},"  else",[113,904,905],{"class":192}," document.body.",[113,907,908],{"class":119},"append",[113,910,911],{"class":192},"(image);\n",[113,913,914],{"class":115,"line":490},[113,915,916],{"class":192},"}\n",[113,918,919,922,924,927],{"class":115,"line":496},[113,920,921],{"class":192},"image.alt ",[113,923,418],{"class":179},[113,925,926],{"class":123}," '课程示例图片'",[113,928,773],{"class":192},[113,930,931,934,937,939,942,944,946],{"class":115,"line":502},[113,932,933],{"class":192},"image.",[113,935,936],{"class":119},"onload",[113,938,186],{"class":179},[113,940,941],{"class":192}," () ",[113,943,813],{"class":179},[113,945,816],{"class":119},[113,947,795],{"class":192},[113,949,950,952,955,957,959,961,963,965,967,969,971,974],{"class":115,"line":508},[113,951,933],{"class":192},[113,953,954],{"class":119},"onerror",[113,956,186],{"class":179},[113,958,941],{"class":192},[113,960,813],{"class":179},[113,962,816],{"class":119},[113,964,193],{"class":192},[113,966,821],{"class":179},[113,968,824],{"class":119},[113,970,193],{"class":192},[113,972,973],{"class":123},"'图片加载失败'",[113,975,976],{"class":192},"));\n",[113,978,979,982,984],{"class":115,"line":514},[113,980,981],{"class":192},"image.src ",[113,983,418],{"class":179},[113,985,986],{"class":192}," imageUrl;\n",[15,988,989,990,993,994,730],{},"file-loader 导入值用于浏览器访问资源，部署子路径时由 ",[19,991,992],{},"output.publicPath"," 等配置配合，避免在业务代码里硬编码构建目录前缀。CommonJS 和 ES Module 的源模块示例见 ",[724,995,997],{"href":996},"\u002Fdocs\u002Fjs-module-systems","模块化",[28,999,1001],{"id":1000},"source-map","source map",[15,1003,1004,1007],{},[19,1005,1006],{},"devtool"," 决定 source map 生成方式，影响构建速度、调试映射质量和产物大小。",[35,1009,1010,1020],{},[38,1011,1012],{},[41,1013,1014,1017],{},[44,1015,1016],{},"课程配置",[44,1018,1019],{},"调试信息",[51,1021,1022,1032,1042,1052],{},[41,1023,1024,1029],{},[56,1025,1026],{},[19,1027,1028],{},"eval",[56,1030,1031],{},"便于定位生成后的模块代码",[41,1033,1034,1039],{},[56,1035,1036],{},[19,1037,1038],{},"cheap-eval-source-map",[56,1040,1041],{},"行级映射，通常不追溯 loader 原始源码",[41,1043,1044,1049],{},[56,1045,1046],{},[19,1047,1048],{},"cheap-module-eval-source-map",[56,1050,1051],{},"行级映射并利用 loader 的映射信息",[41,1053,1054,1058],{},[56,1055,1056],{},[19,1057,1000],{},[56,1059,1060],{},"单独输出较完整的 source map 文件",[15,1062,1063],{},"以上拼写按 Webpack 4。生成代码、转换后的代码和原始代码不是同一层级，映射到原始代码还需要 loader 提供相应信息。",[28,1065,1067],{"id":1066},"开发服务器mock-与代理","开发服务器、Mock 与代理",[15,1069,1070,1071,1074],{},"下面是放入配置的 ",[19,1072,1073],{},"devServer"," 片段，针对 webpack-dev-server 3：",[104,1076,1078],{"className":170,"code":1077,"language":172,"meta":109,"style":109},"const path = require('path');\nconst devServer = {\n  contentBase: path.resolve(__dirname, 'dist'),\n  host: 'localhost',\n  port: 4000,\n  compress: true,\n  open: false,\n  before(app) {\n    app.get('\u002Fuser', (req, res) => {\n      res.json({ uname: 'kevin', age: 12 });\n    });\n  },\n  proxy: {\n    '\u002Fowner': {\n      target: 'http:\u002F\u002Flocalhost:5000',\n      changeOrigin: true,\n      pathRewrite: { '^\u002Fowner': '' },\n      proxyTimeout: 5000,\n      timeout: 5000\n    }\n  }\n};\n",[19,1079,1080,1096,1107,1121,1131,1141,1151,1161,1173,1205,1228,1233,1237,1242,1250,1260,1269,1286,1295,1303,1308,1312],{"__ignoreMap":109},[113,1081,1082,1084,1086,1088,1090,1092,1094],{"class":115,"line":116},[113,1083,180],{"class":179},[113,1085,183],{"class":127},[113,1087,186],{"class":179},[113,1089,189],{"class":119},[113,1091,193],{"class":192},[113,1093,196],{"class":123},[113,1095,199],{"class":192},[113,1097,1098,1100,1103,1105],{"class":115,"line":140},[113,1099,180],{"class":179},[113,1101,1102],{"class":127}," devServer",[113,1104,186],{"class":179},[113,1106,215],{"class":192},[113,1108,1109,1112,1114,1116,1118],{"class":115,"line":155},[113,1110,1111],{"class":192},"  contentBase: path.",[113,1113,263],{"class":119},[113,1115,266],{"class":192},[113,1117,269],{"class":123},[113,1119,1120],{"class":192},"),\n",[113,1122,1123,1126,1129],{"class":115,"line":229},[113,1124,1125],{"class":192},"  host: ",[113,1127,1128],{"class":123},"'localhost'",[113,1130,226],{"class":192},[113,1132,1133,1136,1139],{"class":115,"line":240},[113,1134,1135],{"class":192},"  port: ",[113,1137,1138],{"class":127},"4000",[113,1140,226],{"class":192},[113,1142,1143,1146,1149],{"class":115,"line":246},[113,1144,1145],{"class":192},"  compress: ",[113,1147,1148],{"class":127},"true",[113,1150,226],{"class":192},[113,1152,1153,1156,1159],{"class":115,"line":257},[113,1154,1155],{"class":192},"  open: ",[113,1157,1158],{"class":127},"false",[113,1160,226],{"class":192},[113,1162,1163,1166,1168,1171],{"class":115,"line":275},[113,1164,1165],{"class":119},"  before",[113,1167,193],{"class":192},[113,1169,1170],{"class":849},"app",[113,1172,853],{"class":192},[113,1174,1175,1178,1181,1183,1186,1189,1192,1195,1198,1201,1203],{"class":115,"line":281},[113,1176,1177],{"class":192},"    app.",[113,1179,1180],{"class":119},"get",[113,1182,193],{"class":192},[113,1184,1185],{"class":123},"'\u002Fuser'",[113,1187,1188],{"class":192},", (",[113,1190,1191],{"class":849},"req",[113,1193,1194],{"class":192},", ",[113,1196,1197],{"class":849},"res",[113,1199,1200],{"class":192},") ",[113,1202,813],{"class":179},[113,1204,215],{"class":192},[113,1206,1207,1210,1213,1216,1219,1222,1225],{"class":115,"line":477},[113,1208,1209],{"class":192},"      res.",[113,1211,1212],{"class":119},"json",[113,1214,1215],{"class":192},"({ uname: ",[113,1217,1218],{"class":123},"'kevin'",[113,1220,1221],{"class":192},", age: ",[113,1223,1224],{"class":127},"12",[113,1226,1227],{"class":192}," });\n",[113,1229,1230],{"class":115,"line":490},[113,1231,1232],{"class":192},"    });\n",[113,1234,1235],{"class":115,"line":496},[113,1236,493],{"class":192},[113,1238,1239],{"class":115,"line":502},[113,1240,1241],{"class":192},"  proxy: {\n",[113,1243,1244,1247],{"class":115,"line":508},[113,1245,1246],{"class":123},"    '\u002Fowner'",[113,1248,1249],{"class":192},": {\n",[113,1251,1252,1255,1258],{"class":115,"line":514},[113,1253,1254],{"class":192},"      target: ",[113,1256,1257],{"class":123},"'http:\u002F\u002Flocalhost:5000'",[113,1259,226],{"class":192},[113,1261,1262,1265,1267],{"class":115,"line":538},[113,1263,1264],{"class":192},"      changeOrigin: ",[113,1266,1148],{"class":127},[113,1268,226],{"class":192},[113,1270,1271,1274,1277,1280,1283],{"class":115,"line":553},[113,1272,1273],{"class":192},"      pathRewrite: { ",[113,1275,1276],{"class":123},"'^\u002Fowner'",[113,1278,1279],{"class":192},": ",[113,1281,1282],{"class":123},"''",[113,1284,1285],{"class":192}," },\n",[113,1287,1288,1291,1293],{"class":115,"line":559},[113,1289,1290],{"class":192},"      proxyTimeout: ",[113,1292,835],{"class":127},[113,1294,226],{"class":192},[113,1296,1297,1300],{"class":115,"line":570},[113,1298,1299],{"class":192},"      timeout: ",[113,1301,1302],{"class":127},"5000\n",[113,1304,1305],{"class":115,"line":582},[113,1306,1307],{"class":192},"    }\n",[113,1309,1310],{"class":115,"line":588},[113,1311,278],{"class":192},[113,1313,1314],{"class":115,"line":594},[113,1315,284],{"class":192},[15,1317,1318,1320,1321,1323,1324,1327],{},[19,1319,21],{}," 提供静态文件；构建产物通常由开发中间件在内存中提供，不代表磁盘一定出现新的 dist。源文件变化会触发重新构建；",[19,1322,25],{}," 可增加开发阶段的模拟接口。",[19,1325,1326],{},"open"," 控制是否启动浏览器，这里设为 false。",[15,1329,1330],{},"请求关系：",[35,1332,1333,1343],{},[38,1334,1335],{},[41,1336,1337,1340],{},[44,1338,1339],{},"浏览器请求",[44,1341,1342],{},"开发服务器处理",[51,1344,1345,1355,1368],{},[41,1346,1347,1352],{},[56,1348,1349],{},[19,1350,1351],{},"http:\u002F\u002Flocalhost:4000\u002Fuser",[56,1353,1354],{},"由 before 注册的模拟接口响应",[41,1356,1357,1362],{},[56,1358,1359],{},[19,1360,1361],{},"http:\u002F\u002Flocalhost:4000\u002Fowner\u002Fgetdata",[56,1363,1364,1365],{},"去掉前缀后代理至 ",[19,1366,1367],{},"http:\u002F\u002Flocalhost:5000\u002Fgetdata",[41,1369,1370,1374],{},[56,1371,1372],{},[19,1373,1367],{},[56,1375,1376],{},"绕过代理直接访问另一来源，需要后端满足浏览器跨源要求",[15,1378,1379,1382,1383,1386,1387,730],{},[19,1380,1381],{},"changeOrigin"," 改写发送给目标服务的 Host 信息，不是“关闭浏览器同源策略”。",[19,1384,1385],{},"pathRewrite"," 使用开头锚点，仅移除前缀。",[724,1388,1391],{"href":1389,"rel":1390},"https:\u002F\u002Fv4.webpack.js.org\u002Fconfiguration\u002Fdev-server\u002F",[728],"Webpack 4 开发服务器文档",[304,1393,1394],{"id":1394},"后端代码片段",[15,1396,1397,1398,1401],{},"原 ",[19,1399,1400],{},"server\u002Fserver.js"," 使用 Express，但对应 package 未显式列出 Express。这里只保存接口示例，不启动服务；运行片段需要独立环境具备 Express。",[104,1403,1405],{"className":170,"code":1404,"language":172,"meta":109,"style":109},"const express = require('express');\nconst app = express();\napp.get('\u002Fgetdata', (req, res) => {\n  res.json({\n    msg: '成功',\n    code: 23,\n    list: [\n      { id: 1, title: 'title1', desc: '简介1' },\n      { id: 2, title: 'title2', desc: '简介2' }\n    ]\n  });\n});\nconst server = app.listen(5000, '127.0.0.1');\nserver.on('error', error => console.error('服务启动失败：', error.message));\n",[19,1406,1407,1425,1438,1464,1474,1484,1494,1499,1521,1540,1544,1549,1554,1580],{"__ignoreMap":109},[113,1408,1409,1411,1414,1416,1418,1420,1423],{"class":115,"line":116},[113,1410,180],{"class":179},[113,1412,1413],{"class":127}," express",[113,1415,186],{"class":179},[113,1417,189],{"class":119},[113,1419,193],{"class":192},[113,1421,1422],{"class":123},"'express'",[113,1424,199],{"class":192},[113,1426,1427,1429,1432,1434,1436],{"class":115,"line":140},[113,1428,180],{"class":179},[113,1430,1431],{"class":127}," app",[113,1433,186],{"class":179},[113,1435,1413],{"class":119},[113,1437,795],{"class":192},[113,1439,1440,1443,1445,1447,1450,1452,1454,1456,1458,1460,1462],{"class":115,"line":155},[113,1441,1442],{"class":192},"app.",[113,1444,1180],{"class":119},[113,1446,193],{"class":192},[113,1448,1449],{"class":123},"'\u002Fgetdata'",[113,1451,1188],{"class":192},[113,1453,1191],{"class":849},[113,1455,1194],{"class":192},[113,1457,1197],{"class":849},[113,1459,1200],{"class":192},[113,1461,813],{"class":179},[113,1463,215],{"class":192},[113,1465,1466,1469,1471],{"class":115,"line":229},[113,1467,1468],{"class":192},"  res.",[113,1470,1212],{"class":119},[113,1472,1473],{"class":192},"({\n",[113,1475,1476,1479,1482],{"class":115,"line":240},[113,1477,1478],{"class":192},"    msg: ",[113,1480,1481],{"class":123},"'成功'",[113,1483,226],{"class":192},[113,1485,1486,1489,1492],{"class":115,"line":246},[113,1487,1488],{"class":192},"    code: ",[113,1490,1491],{"class":127},"23",[113,1493,226],{"class":192},[113,1495,1496],{"class":115,"line":257},[113,1497,1498],{"class":192},"    list: [\n",[113,1500,1501,1504,1507,1510,1513,1516,1519],{"class":115,"line":275},[113,1502,1503],{"class":192},"      { id: ",[113,1505,1506],{"class":127},"1",[113,1508,1509],{"class":192},", title: ",[113,1511,1512],{"class":123},"'title1'",[113,1514,1515],{"class":192},", desc: ",[113,1517,1518],{"class":123},"'简介1'",[113,1520,1285],{"class":192},[113,1522,1523,1525,1528,1530,1533,1535,1538],{"class":115,"line":281},[113,1524,1503],{"class":192},[113,1526,1527],{"class":127},"2",[113,1529,1509],{"class":192},[113,1531,1532],{"class":123},"'title2'",[113,1534,1515],{"class":192},[113,1536,1537],{"class":123},"'简介2'",[113,1539,642],{"class":192},[113,1541,1542],{"class":115,"line":477},[113,1543,648],{"class":192},[113,1545,1546],{"class":115,"line":490},[113,1547,1548],{"class":192},"  });\n",[113,1550,1551],{"class":115,"line":496},[113,1552,1553],{"class":192},"});\n",[113,1555,1556,1558,1561,1563,1566,1569,1571,1573,1575,1578],{"class":115,"line":502},[113,1557,180],{"class":179},[113,1559,1560],{"class":127}," server",[113,1562,186],{"class":179},[113,1564,1565],{"class":192}," app.",[113,1567,1568],{"class":119},"listen",[113,1570,193],{"class":192},[113,1572,835],{"class":127},[113,1574,1194],{"class":192},[113,1576,1577],{"class":123},"'127.0.0.1'",[113,1579,199],{"class":192},[113,1581,1582,1585,1588,1590,1593,1595,1597,1600,1603,1605,1607,1610],{"class":115,"line":508},[113,1583,1584],{"class":192},"server.",[113,1586,1587],{"class":119},"on",[113,1589,193],{"class":192},[113,1591,1592],{"class":123},"'error'",[113,1594,1194],{"class":192},[113,1596,850],{"class":849},[113,1598,1599],{"class":179}," =>",[113,1601,1602],{"class":192}," console.",[113,1604,850],{"class":119},[113,1606,193],{"class":192},[113,1608,1609],{"class":123},"'服务启动失败：'",[113,1611,1612],{"class":192},", error.message));\n",[15,1614,1615],{},"前端 Axios 请求片段，放在开发服务器提供的页面中，并由打包环境解析依赖：",[104,1617,1619],{"className":170,"code":1618,"language":172,"meta":109,"style":109},"const axios = require('axios');\nasync function load() {\n  try {\n    const user = await axios.get('\u002Fuser', { timeout: 5000 });\n    const data = await axios.get('\u002Fowner\u002Fgetdata', { timeout: 5000 });\n    console.log(user.data, data.data);\n  } catch (error) {\n    console.error('请求失败：', error.message);\n  }\n}\nload();\n",[19,1620,1621,1639,1653,1660,1689,1715,1726,1737,1751,1755,1759],{"__ignoreMap":109},[113,1622,1623,1625,1628,1630,1632,1634,1637],{"class":115,"line":116},[113,1624,180],{"class":179},[113,1626,1627],{"class":127}," axios",[113,1629,186],{"class":179},[113,1631,189],{"class":119},[113,1633,193],{"class":192},[113,1635,1636],{"class":123},"'axios'",[113,1638,199],{"class":192},[113,1640,1641,1644,1647,1650],{"class":115,"line":140},[113,1642,1643],{"class":179},"async",[113,1645,1646],{"class":179}," function",[113,1648,1649],{"class":119}," load",[113,1651,1652],{"class":192},"() {\n",[113,1654,1655,1658],{"class":115,"line":155},[113,1656,1657],{"class":179},"  try",[113,1659,215],{"class":192},[113,1661,1662,1665,1668,1670,1673,1676,1678,1680,1682,1685,1687],{"class":115,"line":229},[113,1663,1664],{"class":179},"    const",[113,1666,1667],{"class":127}," user",[113,1669,186],{"class":179},[113,1671,1672],{"class":179}," await",[113,1674,1675],{"class":192}," axios.",[113,1677,1180],{"class":119},[113,1679,193],{"class":192},[113,1681,1185],{"class":123},[113,1683,1684],{"class":192},", { timeout: ",[113,1686,835],{"class":127},[113,1688,1227],{"class":192},[113,1690,1691,1693,1696,1698,1700,1702,1704,1706,1709,1711,1713],{"class":115,"line":240},[113,1692,1664],{"class":179},[113,1694,1695],{"class":127}," data",[113,1697,186],{"class":179},[113,1699,1672],{"class":179},[113,1701,1675],{"class":192},[113,1703,1180],{"class":119},[113,1705,193],{"class":192},[113,1707,1708],{"class":123},"'\u002Fowner\u002Fgetdata'",[113,1710,1684],{"class":192},[113,1712,835],{"class":127},[113,1714,1227],{"class":192},[113,1716,1717,1720,1723],{"class":115,"line":246},[113,1718,1719],{"class":192},"    console.",[113,1721,1722],{"class":119},"log",[113,1724,1725],{"class":192},"(user.data, data.data);\n",[113,1727,1728,1731,1734],{"class":115,"line":257},[113,1729,1730],{"class":192},"  } ",[113,1732,1733],{"class":179},"catch",[113,1735,1736],{"class":192}," (error) {\n",[113,1738,1739,1741,1743,1745,1748],{"class":115,"line":275},[113,1740,1719],{"class":192},[113,1742,850],{"class":119},[113,1744,193],{"class":192},[113,1746,1747],{"class":123},"'请求失败：'",[113,1749,1750],{"class":192},", error.message);\n",[113,1752,1753],{"class":115,"line":281},[113,1754,278],{"class":192},[113,1756,1757],{"class":115,"line":477},[113,1758,916],{"class":192},[113,1760,1761,1764],{"class":115,"line":490},[113,1762,1763],{"class":119},"load",[113,1765,795],{"class":192},[15,1767,1768],{},"原例访问外部课程接口的请求用本地 Mock 替代，不依赖第三方站点可用性。",[28,1770,1772],{"id":1771},"reactcssless-配置摘录","React、CSS、Less 配置摘录",[15,1774,1775,1776,1779],{},"原目录使用 React 16.13.1，",[19,1777,1778],{},"src\u002Fmain.js"," 为空，HTML 也没有应用内容。能收录的是 Babel preset 与资源 loader 配置；不据此补造 React 应用。",[15,1781,1782,1783,1786],{},"以下数组放到前面配置的 ",[19,1784,1785],{},"module.rules","，并配合已有 HtmlWebpackPlugin、CleanWebpackPlugin：",[104,1788,1790],{"className":170,"code":1789,"language":172,"meta":109,"style":109},"const rules = [\n  {\n    test: \u002F\\.jsx?$\u002F,\n    exclude: \u002Fnode_modules\u002F,\n    use: {\n      loader: 'babel-loader',\n      options: { presets: ['@babel\u002Fpreset-env', '@babel\u002Fpreset-react'] }\n    }\n  },\n  { test: \u002F\\.css$\u002F, use: ['style-loader', 'css-loader'] },\n  { test: \u002F\\.less$\u002F, use: ['style-loader', 'css-loader', 'less-loader'] },\n  {\n    test: \u002F\\.(png|jpe?g|gif|svg)$\u002Fi,\n    use: { loader: 'url-loader', options: { limit: 8192 } }\n  }\n];\n",[19,1791,1792,1804,1809,1828,1841,1846,1855,1869,1873,1877,1907,1937,1941,1975,1992,1996],{"__ignoreMap":109},[113,1793,1794,1796,1799,1801],{"class":115,"line":116},[113,1795,180],{"class":179},[113,1797,1798],{"class":127}," rules",[113,1800,186],{"class":179},[113,1802,1803],{"class":192}," [\n",[113,1805,1806],{"class":115,"line":140},[113,1807,1808],{"class":192},"  {\n",[113,1810,1811,1814,1816,1818,1821,1824,1826],{"class":115,"line":155},[113,1812,1813],{"class":192},"    test:",[113,1815,520],{"class":123},[113,1817,524],{"class":523},[113,1819,1820],{"class":527},"jsx",[113,1822,1823],{"class":179},"?$",[113,1825,533],{"class":123},[113,1827,226],{"class":192},[113,1829,1830,1833,1835,1837,1839],{"class":115,"line":229},[113,1831,1832],{"class":192},"    exclude:",[113,1834,520],{"class":123},[113,1836,546],{"class":527},[113,1838,533],{"class":123},[113,1840,226],{"class":192},[113,1842,1843],{"class":115,"line":240},[113,1844,1845],{"class":192},"    use: {\n",[113,1847,1848,1851,1853],{"class":115,"line":246},[113,1849,1850],{"class":192},"      loader: ",[113,1852,565],{"class":123},[113,1854,226],{"class":192},[113,1856,1857,1860,1862,1864,1867],{"class":115,"line":257},[113,1858,1859],{"class":192},"      options: { presets: [",[113,1861,576],{"class":123},[113,1863,1194],{"class":192},[113,1865,1866],{"class":123},"'@babel\u002Fpreset-react'",[113,1868,579],{"class":192},[113,1870,1871],{"class":115,"line":275},[113,1872,1307],{"class":192},[113,1874,1875],{"class":115,"line":281},[113,1876,493],{"class":192},[113,1878,1879,1882,1884,1886,1889,1891,1893,1896,1899,1901,1904],{"class":115,"line":477},[113,1880,1881],{"class":192},"  { test:",[113,1883,520],{"class":123},[113,1885,524],{"class":523},[113,1887,1888],{"class":527},"css",[113,1890,530],{"class":179},[113,1892,533],{"class":123},[113,1894,1895],{"class":192},", use: [",[113,1897,1898],{"class":123},"'style-loader'",[113,1900,1194],{"class":192},[113,1902,1903],{"class":123},"'css-loader'",[113,1905,1906],{"class":192},"] },\n",[113,1908,1909,1911,1913,1915,1918,1920,1922,1924,1926,1928,1930,1932,1935],{"class":115,"line":490},[113,1910,1881],{"class":192},[113,1912,520],{"class":123},[113,1914,524],{"class":523},[113,1916,1917],{"class":527},"less",[113,1919,530],{"class":179},[113,1921,533],{"class":123},[113,1923,1895],{"class":192},[113,1925,1898],{"class":123},[113,1927,1194],{"class":192},[113,1929,1903],{"class":123},[113,1931,1194],{"class":192},[113,1933,1934],{"class":123},"'less-loader'",[113,1936,1906],{"class":192},[113,1938,1939],{"class":115,"line":496},[113,1940,1808],{"class":192},[113,1942,1943,1945,1947,1949,1951,1953,1955,1957,1959,1961,1963,1965,1967,1969,1971,1973],{"class":115,"line":502},[113,1944,1813],{"class":192},[113,1946,520],{"class":123},[113,1948,524],{"class":523},[113,1950,604],{"class":527},[113,1952,607],{"class":179},[113,1954,610],{"class":527},[113,1956,613],{"class":179},[113,1958,616],{"class":527},[113,1960,607],{"class":179},[113,1962,621],{"class":527},[113,1964,607],{"class":179},[113,1966,626],{"class":527},[113,1968,530],{"class":179},[113,1970,533],{"class":123},[113,1972,633],{"class":179},[113,1974,226],{"class":192},[113,1976,1977,1980,1983,1986,1989],{"class":115,"line":508},[113,1978,1979],{"class":192},"    use: { loader: ",[113,1981,1982],{"class":123},"'url-loader'",[113,1984,1985],{"class":192},", options: { limit: ",[113,1987,1988],{"class":127},"8192",[113,1990,1991],{"class":192}," } }\n",[113,1993,1994],{"class":115,"line":514},[113,1995,278],{"class":192},[113,1997,1998],{"class":115,"line":538},[113,1999,2000],{"class":192},"];\n",[15,2002,2003],{},"CSS 先经 css-loader 解析，再由 style-loader 插入页面；Less 在此前先编译为 CSS。url-loader 按大小阈值决定是否内联，超过阈值的回退处理还需要相应 file-loader 依赖。原依赖里有 less-loader，但未直接列出 Less 编译器，也需在独立环境中配齐。",[15,2005,2006],{},"课程列出的依赖按职责理解即可：webpack\u002Fcli\u002Fdev-server 提供构建与服务，Babel core\u002Fenv\u002Freact 提供转译，各 loader 处理资源，React\u002FReactDOM 提供应用运行时。现代项目不能只复制这份历史版本配置就假设兼容。",[28,2008,2009],{"id":2009},"来源记录",[2011,2012,2013,2020,2037,2049,2061],"ul",{},[2014,2015,2016,2019],"li",{},[19,2017,2018],{},"004_es6\u002Fcode\u002Fwebpack.config.js","：模块入口、输出、静态目录和 9000 端口示例，合并至基本配置与 devServer。",[2014,2021,2022,22,2025,22,2028,22,2030,22,2033,2036],{},[19,2023,2024],{},"006_webpack\u002Fcode\u002F02_webpack\u002Fwebpack.config.js",[19,2026,2027],{},"index.html",[19,2029,1778],{},[19,2031,2032],{},"src\u002Fjs\u002Fa.js",[19,2034,2035],{},"b.js","：模块、图片、Babel、插件和输出模板。",[2014,2038,2039,22,2042,22,2044,22,2046,2048],{},[19,2040,2041],{},"007_webpack\u002Fcode\u002Fwebpack.config.js",[19,2043,1778],{},[19,2045,2032],{},[19,2047,1400],{},"：开发模式、source map、Mock 与代理。",[2014,2050,2051,22,2054,2057,2058,2060],{},[19,2052,2053],{},"007_webpack\u002Freact-env\u002Fwebpack.config.js",[19,2055,2056],{},"public\u002Findex.html","、空的 ",[19,2059,1778],{},"：仅保留有内容的构建配置。",[2014,2062,2063,22,2066,2069],{},[19,2064,2065],{},"006_webpack\u002Fcode\u002Freadme.md",[19,2067,2068],{},"007_webpack\u002Fcode\u002Freadme.md","：去重复习后归入对应章节；包配置和锁文件只用于版本判断。",[2071,2072,2073],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}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 .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .snhLl, html code.shiki .snhLl{--shiki-default:#22863A;--shiki-default-font-weight:bold;--shiki-dark:#85E89D;--shiki-dark-font-weight:bold}html pre.shiki code .sA_wV, html code.shiki .sA_wV{--shiki-default:#032F62;--shiki-dark:#DBEDFF}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":109,"searchDepth":155,"depth":155,"links":2075},[2076,2077,2080,2083,2084,2087,2088],{"id":30,"depth":140,"text":30},{"id":99,"depth":140,"text":99,"children":2078},[2079],{"id":306,"depth":155,"text":306},{"id":359,"depth":140,"text":360,"children":2081},[2082],{"id":740,"depth":155,"text":740},{"id":1000,"depth":140,"text":1001},{"id":1066,"depth":140,"text":1067,"children":2085},[2086],{"id":1394,"depth":155,"text":1394},{"id":1771,"depth":140,"text":1772},{"id":2009,"depth":140,"text":2009},"toolchain","2023-04-26","课程中的入口出口、loader、plugin、source map、开发代理以及 React 环境配置片段。",false,"md",{},"\u002Fdocs\u002Fwebpack-basics",{"title":5,"description":2091},"尚学堂 ES6 课程 004_es6、006_webpack、007_webpack 学习笔记与代码","docs\u002Fwebpack-basics",[2100,2101,2102,2103],"webpack","javascript","nodejs","notes","SgZDok4dx5NmZd_ya0ZM9qwVWYvUtiVJU4peemPtOKk",[2106,2113,2119,2124,2129,2138,2148,2155,2161,2171,2178,2187,2192,2199,2204,2209,2215,2222,2229,2236,2243,2249,2255,2260,2265,2270,2275,2277],{"path":2107,"title":2108,"description":2109,"date":2110,"category":2089,"tags":2111},"\u002Fdocs\u002Fbabel-basics","Babel 转译基础与构建集成","Babel 7 的 CLI、preset、plugin、目标环境以及 Gulp、Webpack 和 JSX 转译配置摘录。","2026-09-09",[2101,2112,2100,2103],"es6",{"path":2114,"title":2115,"description":2116,"date":2110,"category":2117,"tags":2118},"\u002Fdocs\u002Fes6-arrays-objects","ES6 数组与对象扩展","展开运算符、Array.from、Object.assign、属性描述符与图片预加载示例。","fundamentals",[2101,2112,2103],{"path":2120,"title":2121,"description":2122,"date":2110,"category":2117,"tags":2123},"\u002Fdocs\u002Fes6-basics","ES6 基础：作用域、解构与模板字符串","从课程示例整理 let、const、暂时性死区、全局对象、数组与对象解构及模板字符串。",[2101,2112,2103],{"path":2125,"title":2126,"description":2127,"date":2110,"category":2117,"tags":2128},"\u002Fdocs\u002Fjs-promise-async","Promise、Generator 与 async\u002Fawait","从回调到 Promise 链、组合方法、Generator 执行与 async 错误处理的课程示例整理。",[2101,2112,2103],{"path":2130,"title":2131,"description":2132,"date":2133,"category":2089,"tags":2134},"\u002Fdocs\u002Flinux-commands-cheatsheet","Linux 常用命令与权限管理速查","cp\u002Fmv\u002Frm、目录导航、查找、压缩、网络等基础命令速查，以及 chmod\u002Fchown 的数字与符号写法、常用组合和 WSL 下的坑。","2026-05-28",[2135,2136,2137],"linux","wsl2","cheatsheet",{"path":2139,"title":2140,"description":2141,"date":2142,"category":2143,"tags":2144},"\u002Fdocs\u002Ffrontend-coding-standards","前端团队编码规范","HTML \u002F CSS \u002F JavaScript 三端统一的团队编码约定，含缩进、命名、语法与禁用项，可直接作为 Code Review 依据。","2025-12-17","standards",[2145,1888,2101,2112,2146,2147],"html","best-practice","guide",{"path":2149,"title":2150,"description":2151,"date":2152,"category":2089,"tags":2153},"\u002Fdocs\u002Fwindows-mklink","Windows mklink 符号链接用法","mklink 各参数区别与实用场景：目录联接、符号链接与硬链接的选择。","2024-12-18",[2154,2137],"windows",{"path":2156,"title":2157,"description":2158,"date":2159,"category":2089,"tags":2160},"\u002Fdocs\u002Frandom-color-utils","JS 随机颜色生成方法","几种生成随机 RGB \u002F HEX 颜色的实现方式与各自适用场景。","2024-12-11",[2101,2137],{"path":2162,"title":2163,"description":2164,"date":2165,"category":2166,"tags":2167},"\u002Fdocs\u002Fcanvas-vs-svg","Canvas 与 SVG 绘图方案选型","对比 Canvas 与 SVG 两种绘图方案的优缺点与适用场景，给出选型判断依据。","2024-12-09","visualization",[2168,2169,2170,2146],"canvas","svg","performance",{"path":2172,"title":2173,"description":2174,"date":2175,"category":2089,"tags":2176},"\u002Fdocs\u002Ffree-commercial-fonts","免费可商用字体整理","整理思源黑体、思源宋体等可商用中文字体，规避字体版权风险。","2024-11-03",[2177,1888,2103],"font",{"path":2179,"title":2180,"description":2181,"date":2175,"category":2182,"tags":2183},"\u002Fdocs\u002Finterview-browser-network","浏览器与网络考点","从输入 URL 到页面呈现的完整链路，涵盖渲染流程、回流重绘、HTTP 报文与状态码、跨域同源策略与常见攻击方式。","interview",[2184,2185,2186,2170,2103],"browser","http","network",{"path":2188,"title":2189,"description":2190,"date":2175,"category":2182,"tags":2191},"\u002Fdocs\u002Finterview-css-layout","CSS 与布局考点","em 与 rem 的区别、移动端三种适配方案对比、viewport 标准设置与 REM 布局的媒体查询实现。",[1888,2145,2146,2103],{"path":2193,"title":2194,"description":2195,"date":2175,"category":2182,"tags":2196},"\u002Fdocs\u002Finterview-framework-tooling","框架与工程化考点","React diff 与 setState 机制、Redux 核心组成、Vue 常考清单，以及 Webpack、Vite、Git 的面试要点。",[2197,2101,2100,2198,2103],"vue","vite",{"path":2200,"title":2201,"description":2202,"date":2175,"category":2182,"tags":2203},"\u002Fdocs\u002Finterview-javascript-core","JavaScript 核心考点","数据类型、this 绑定、闭包、原型链、异步与数组方法，前端面试中 JS 部分的高频考点与代码示例。",[2101,2112,2103],{"path":996,"title":2205,"description":2206,"date":2175,"category":2117,"tags":2207},"JavaScript 模块化方案","梳理 CommonJS、AMD、ES Module 等模块化方案的差异与使用方式。",[2101,2208,2112,2103],"module-system",{"path":2210,"title":2211,"description":2212,"date":2175,"category":2117,"tags":2213},"\u002Fdocs\u002Fwebsocket-basics","WebSocket 基础","WebSocket 全双工通信协议的事件、方法与基本用法整理。",[2214,2186,2101,2103],"websocket",{"path":2216,"title":2217,"description":2218,"date":2219,"category":2089,"tags":2220},"\u002Fdocs\u002Fmarkdown-syntax","Markdown 语法速查","Markdown 标题、强调、列表、区块引用、代码、表格、转义与 Mermaid 图表语法整理。","2024-10-18",[2221,2137,2103],"markdown",{"path":2223,"title":2224,"description":2225,"date":2226,"category":2166,"tags":2227},"\u002Fdocs\u002Fgojs-getting-started","GoJS 入门实战","从引入方式、画布初始化到节点模板与数据绑定，一份可直接上手的 GoJS 流程图开发笔记。","2024-08-22",[2228,2101,2103],"gojs",{"path":2230,"title":2231,"description":2232,"date":2233,"category":2166,"tags":2234},"\u002Fdocs\u002Fecharts-options-notes","ECharts 配置项速查","整理 ECharts 常用 option 配置：数据格式、坐标轴、图例与交互项的实际用法。","2024-08-09",[2235,2101,2137],"echarts",{"path":2237,"title":2238,"description":2239,"date":2240,"category":2089,"tags":2241},"\u002Fdocs\u002Fyarn-npm-install-errors","yarn \u002F npm 安装报错处理","yarn 引擎版本不兼容时的 ignore-engines 绕过、Windows 刷新 DNS 解析缓存、npm 缓存清理与校验。","2024-08-06",[120,2102,2154,2242],"troubleshooting",{"path":2244,"title":2245,"description":2246,"date":2247,"category":2166,"tags":2248},"\u002Fdocs\u002Fgojs-grid-panel","GoJS 网格面板用法","Diagram.grid 默认网格与网格捕捉、单元格尺寸定制，用 LineH\u002FLineV\u002FBarH\u002FBarV 自定义网格样式，以及把 Grid 面板当作节点元素使用。","2024-07-01",[2228,2101,2103],{"path":2250,"title":2251,"description":2252,"date":2253,"category":2117,"tags":2254},"\u002Fdocs\u002Fhttp-status-codes","HTTP 响应状态码详解","按 1xx 到 5xx 分类梳理 HTTP 状态码的含义与典型使用场景。","2024-06-27",[2185,2186,2137],{"path":2256,"title":2257,"description":2258,"date":2090,"category":2117,"tags":2259},"\u002Fdocs\u002Fes6-functions-classes","ES6 函数与 Class","默认参数、rest、箭头函数的 this、Class 方法、访问器、静态成员与继承。",[2101,2112,2103],{"path":2261,"title":2262,"description":2263,"date":2090,"category":2089,"tags":2264},"\u002Fdocs\u002Fgulp-basics","Gulp 4 任务与文件流","Gulp 任务完成信号、串并行组合、文件流、资源处理、分阶段输出和文件监听。",[2101,2102,2103],{"path":2266,"title":2267,"description":2268,"date":2090,"category":2117,"tags":2269},"\u002Fdocs\u002Fjs-proxy-reflect","Proxy 与 Reflect 入门","通过属性读取和赋值示例理解 Proxy、Reflect、receiver 与拦截限制。",[2101,2112,2103],{"path":2271,"title":2272,"description":2273,"date":2090,"category":2089,"tags":2274},"\u002Fdocs\u002Fless-basics","Less 语法与编译笔记","变量、嵌套、混合、extend、导入、内置函数和递归生成列的课程示例。",[1888,2103,2137],{"path":2095,"title":5,"description":2091,"date":2090,"category":2089,"tags":2276},[2100,2101,2102,2103],{"path":2278,"title":2279,"description":2280,"date":2281,"category":2117,"tags":2282},"\u002Fdocs\u002Fhtml-basics","HTML 基础笔记","HTML 语法规范、常用标签、表格、表单、Canvas 入门与 JavaScript 输出方式速查。","2022-06-10",[2145,2103,2137],1789635934468]