<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Babel on Liangweidong's blog</title><link>https://liangweidonggood.github.io/tags/babel/</link><description>Recent content in Babel on Liangweidong's blog</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Wed, 15 Aug 2018 00:00:00 +0800</lastBuildDate><atom:link href="https://liangweidonggood.github.io/tags/babel/index.xml" rel="self" type="application/rss+xml"/><item><title>前端工程化基石：Webpack 5 与 Babel 编译</title><link>https://liangweidonggood.github.io/p/webpack-babel-engineering/</link><pubDate>Wed, 15 Aug 2018 00:00:00 +0800</pubDate><guid>https://liangweidonggood.github.io/p/webpack-babel-engineering/</guid><description>&lt;img src="https://liangweidonggood.github.io/p/webpack-babel-engineering/image/cover.jpg" alt="Featured image of post 前端工程化基石：Webpack 5 与 Babel 编译" /&gt;
 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;为什么写这篇&lt;/strong&gt;：Webpack 4 在 2018-02 正式发布（zero-config 概念），5 在 2018 之后逐步成为标准。即使 2024 年 Vite/Rspack 已经在性能上超越 Webpack，老项目的维护、monorepo 工具链、底层 loader 插件开发仍离不开它。理解 Webpack 的&amp;quot;打包图&amp;quot;思想，是所有前端工程化工具的根。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;适用读者&lt;/strong&gt;：刚开始接触前端构建工具的同学；想从零跑通&amp;quot;写 ES6 → 浏览器能跑&amp;quot;全流程的初学者。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;前置知识&lt;/strong&gt;：会写 &lt;code&gt;npm install&lt;/code&gt;、了解 &lt;code&gt;package.json&lt;/code&gt;、写过简单 HTML/JS。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="目录"&gt;目录
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;a class="link" href="#1-%e4%bb%80%e4%b9%88%e6%98%af-webpack" &gt;什么是 Webpack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="#2-%e6%9c%80%e5%b0%8f%e5%8f%af%e8%b7%91-demo" &gt;最小可跑 demo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="#3-babel%e8%ae%a9%e6%96%b0%e8%af%ad%e6%b3%95%e8%b7%91%e5%88%b0%e8%80%81%e6%b5%8f%e8%a7%88%e5%99%a8" &gt;Babel：让&amp;quot;新语法&amp;quot;跑到&amp;quot;老浏览器&amp;quot;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="#4-%e4%b8%ba%e4%bb%80%e4%b9%88%e9%9c%80%e8%a6%81---save-%e5%92%8c---save-dev" &gt;为什么需要 &amp;ndash;save 和 &amp;ndash;save-dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="#5-%e5%b8%b8%e8%a7%81-loader--plugin-%e4%b8%80%e8%a7%88" &gt;常见 loader / plugin 一览&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="#6-%e4%bb%8e-webpack-1-%e5%88%b0-5%e6%a0%b8%e5%bf%83%e6%bc%94%e8%bf%9b" &gt;从 Webpack 1 到 5：核心演进&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="#7-%e5%b8%b8%e8%a7%81%e9%97%ae%e9%a2%98%e4%b8%8e%e6%8e%92%e9%94%99" &gt;常见问题与排错&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="1-什么是-webpack"&gt;1. 什么是 Webpack
&lt;/h2&gt;&lt;p&gt;Webpack 是一个&lt;strong&gt;静态模块打包器（static module bundler）&lt;/strong&gt;。它从入口文件（entry）出发，递归解析所有 &lt;code&gt;import&lt;/code&gt;/&lt;code&gt;require&lt;/code&gt;，把 JS、CSS、图片、字体等所有静态资源当作&amp;quot;模块&amp;quot;处理，最终输出浏览器能直接加载的静态文件（bundle）。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;核心思想&lt;/strong&gt;：一切皆模块。&lt;code&gt;import './style.css'&lt;/code&gt; 在 Webpack 眼里和 &lt;code&gt;import './utils.js'&lt;/code&gt; 一样——只是需要不同的 loader 来&amp;quot;翻译&amp;quot;。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;Webpack 4 大核心概念：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;概念&lt;/th&gt;
					&lt;th&gt;一句话&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Entry&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;入口，Webpack 从哪个文件开始构建依赖图&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;打包后的文件输出到哪里&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Loader&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;让 Webpack 能处理非 JS 文件（CSS/图片/TS/Vue 等）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Plugin&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;解决 loader 之外的所有事（压缩、热更新、清理 dist、环境变量注入…）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="2-最小可跑-demo"&gt;2. 最小可跑 demo
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mkdir webpack-demo1 &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; webpack-demo1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm init -y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm install webpack webpack-cli --save-dev
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm install --save lodash
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npx webpack
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;跑完会生成 &lt;code&gt;dist/main.js&lt;/code&gt;。完整目录：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;webpack-demo1/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── dist/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └── main.js # 打包后的产物
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── node_modules/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── package.json
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── package-lock.json
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└── src/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └── index.js # 你的入口文件
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;src/index.js&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;_&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;lodash&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;div&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Hello&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;webpack&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;跑 &lt;code&gt;npx webpack&lt;/code&gt; 时，Webpack 会自动：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;把 &lt;code&gt;src/index.js&lt;/code&gt; 当作入口&lt;/li&gt;
&lt;li&gt;解析 &lt;code&gt;import _ from 'lodash'&lt;/code&gt; → 把 lodash 整包也打进来&lt;/li&gt;
&lt;li&gt;把 &lt;code&gt;dist/main.js&lt;/code&gt; 作为默认输出&lt;/li&gt;
&lt;/ol&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;默认约定&lt;/strong&gt;：Webpack 4+ 引入 zero-config 概念，不写 &lt;code&gt;webpack.config.js&lt;/code&gt; 也能跑——entry 默认为 &lt;code&gt;src/index.js&lt;/code&gt;，output 默认为 &lt;code&gt;dist/main.js&lt;/code&gt;，mode 默认为 &lt;code&gt;production&lt;/code&gt;。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="3-babel让新语法跑到老浏览器"&gt;3. Babel：让&amp;quot;新语法&amp;quot;跑到&amp;quot;老浏览器&amp;quot;
&lt;/h2&gt;&lt;p&gt;Babel 是一个 &lt;strong&gt;JavaScript 编译器&lt;/strong&gt;（准确说叫&amp;quot;转译器&amp;quot; transpiler）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;输入&lt;/strong&gt;：用下一代 JavaScript 语法（ES2015+、JSX、TypeScript）写的代码&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;输出&lt;/strong&gt;：浏览器能兼容的 JavaScript 代码&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 输入（你写的）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;greet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="sb"&gt;`Hello, &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;!`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 输出（babel 编译后）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;greet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Hello, &amp;#39;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;!&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;Why&lt;/strong&gt;：浏览器的 JavaScript 引擎对新语法的支持永远滞后于规范。2015 年 ES2015 发布时，主流浏览器（IE11、UC、老 Safari）都不支持 &lt;code&gt;const&lt;/code&gt; / 箭头函数 / &lt;code&gt;class&lt;/code&gt;。Babel 让开发者能写&amp;quot;未来语法&amp;quot;，由它编译到&amp;quot;老语法&amp;quot;。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h3 id="31-webpack-集成-babel-7"&gt;3.1 Webpack 集成 Babel 7
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm install -D babel-loader @babel/core @babel/preset-env
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;webpack.config.js&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;rules&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/\.js$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;exclude&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/node_modules/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;loader&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;babel-loader&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;presets&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;@babel/preset-env&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;@babel/preset-env&lt;/code&gt; 是&amp;quot;智能预设&amp;quot;——你告诉它目标浏览器范围（&lt;code&gt;browserslist&lt;/code&gt; 配置），它自动决定要转译哪些语法。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;package.json&lt;/code&gt; 加上 browserslist：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;browserslist&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;gt; 1%&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;last 2 versions&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;not dead&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;ie &amp;gt;= 11&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;小贴士&lt;/strong&gt;：现代项目（Chrome 90+、Node 18+）可以直接在 browserslist 里写 &lt;code&gt;&amp;quot;defaults, not IE 11&amp;quot;&lt;/code&gt;，Babel 就只对真正需要的目标做 polyfill，bundle 体积能少 30%+。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="4-为什么需要-save-和-save-dev"&gt;4. 为什么需要 &amp;ndash;save 和 &amp;ndash;save-dev
&lt;/h2&gt;&lt;p&gt;这是新人最容易搞混的概念：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;命令&lt;/th&gt;
					&lt;th&gt;写入 &lt;code&gt;package.json&lt;/code&gt; 哪个字段&lt;/th&gt;
					&lt;th&gt;含义&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;npm install --save&lt;/code&gt;（&lt;code&gt;-S&lt;/code&gt;）&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;dependencies&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;生产环境&lt;/strong&gt;需要的包（运行时被打进 bundle）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;npm install --save-dev&lt;/code&gt;（&lt;code&gt;-D&lt;/code&gt;）&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;devDependencies&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;开发环境&lt;/strong&gt;才需要的包（构建、测试、代码检查）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm install webpack webpack-cli --save-dev &lt;span class="c1"&gt;# 构建工具，上线不需要&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm install lodash --save &lt;span class="c1"&gt;# 运行时要用 lodash&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;执行 &lt;code&gt;npm install&lt;/code&gt;（不带包名）时，npm 会同时安装 &lt;code&gt;dependencies&lt;/code&gt; 和 &lt;code&gt;devDependencies&lt;/code&gt; 中的所有模块。生产环境（&lt;code&gt;npm install --production&lt;/code&gt; 或 &lt;code&gt;NODE_ENV=production&lt;/code&gt;）只装 &lt;code&gt;dependencies&lt;/code&gt;。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;小贴士&lt;/strong&gt;：Vue/React 框架本身（&lt;code&gt;vue&lt;/code&gt;、&lt;code&gt;react&lt;/code&gt;、&lt;code&gt;react-dom&lt;/code&gt;）要 &lt;code&gt;--save&lt;/code&gt;，而 &lt;code&gt;vue-loader&lt;/code&gt;、&lt;code&gt;@babel/preset-env&lt;/code&gt;、&lt;code&gt;webpack&lt;/code&gt;、&lt;code&gt;eslint&lt;/code&gt; 都要 &lt;code&gt;--save-dev&lt;/code&gt;。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="5-常见-loader--plugin-一览"&gt;5. 常见 loader / plugin 一览
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;类别&lt;/th&gt;
					&lt;th&gt;名称&lt;/th&gt;
					&lt;th&gt;用途&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;JS&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;babel-loader&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;配合 Babel 转译 JS/JSX/TS&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;ts-loader&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;直接用 TypeScript 编译器&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;CSS&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;css-loader&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;把 CSS 变成 JS 模块（&lt;code&gt;import './style.css'&lt;/code&gt;）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;style-loader&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;把 CSS 注入到 &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; 标签&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;postcss-loader&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;自动加浏览器前缀、CSS 嵌套等&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;sass-loader&lt;/code&gt; / &lt;code&gt;less-loader&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;编译 SCSS / Less&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;图片/字体&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;asset/resource&lt;/code&gt; (Webpack 5 内置)&lt;/td&gt;
					&lt;td&gt;输出文件，导出 URL&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;asset/inline&lt;/code&gt; (Webpack 5 内置)&lt;/td&gt;
					&lt;td&gt;内联为 base64（小图）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;框架&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;vue-loader&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;解析 &lt;code&gt;.vue&lt;/code&gt; 单文件组件&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;文件&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;file-loader&lt;/code&gt;（已废弃）&lt;/td&gt;
					&lt;td&gt;旧版输出文件（Webpack 5 用 asset/resource）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;压缩&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;terser-webpack-plugin&lt;/code&gt;（Webpack 5 默认）&lt;/td&gt;
					&lt;td&gt;压缩 JS&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;css-minimizer-webpack-plugin&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;压缩 CSS&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;compression-webpack-plugin&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;生成 &lt;code&gt;.gz&lt;/code&gt; 文件&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;其他&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;html-webpack-plugin&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;自动生成 HTML 并注入 bundle&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;clean-webpack-plugin&lt;/code&gt; / &lt;code&gt;output.clean&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;每次构建清空 dist&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;mini-css-extract-plugin&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;CSS 抽离成独立文件（不再内联到 JS）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;webpack-dev-server&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;启动开发服务器 + HMR 热更新&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;webpack-bundle-analyzer&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;可视化分析 bundle 体积&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;Webpack 5 重要变化&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;资源模块（Asset Modules）&lt;/strong&gt; 内置了 4 种类型（&lt;code&gt;asset/resource&lt;/code&gt; / &lt;code&gt;asset/inline&lt;/code&gt; / &lt;code&gt;asset/source&lt;/code&gt; / &lt;code&gt;asset&lt;/code&gt;），不再需要 &lt;code&gt;file-loader&lt;/code&gt; / &lt;code&gt;url-loader&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;持久化缓存&lt;/strong&gt; 默认开启，构建速度提升 5-10 倍&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Module Federation&lt;/strong&gt; 微前端方案正式 GA&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tree Shaking&lt;/strong&gt; 加强，对 CommonJS、&lt;code&gt;sideEffects&lt;/code&gt; 字段支持更好&lt;/li&gt;
&lt;/ol&gt;

 &lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="6-从-webpack-1-到-5核心演进"&gt;6. 从 Webpack 1 到 5：核心演进
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;版本&lt;/th&gt;
					&lt;th&gt;年份&lt;/th&gt;
					&lt;th&gt;关键特性&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;1.x&lt;/td&gt;
					&lt;td&gt;2014&lt;/td&gt;
					&lt;td&gt;第一版，配置繁琐但改变前端&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;2.x&lt;/td&gt;
					&lt;td&gt;2017&lt;/td&gt;
					&lt;td&gt;引入 tree shaking、scope hosting&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;3.x&lt;/td&gt;
					&lt;td&gt;2017&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;Scope Hoisting&lt;/code&gt;、魔法注释 &lt;code&gt;/* webpackChunkName */&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;4.x&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;2018-02&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;zero-config&lt;/strong&gt;（默认 entry/output）、mode、sideEffects&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;5.x&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;2020-10&lt;/td&gt;
					&lt;td&gt;资源模块、持久化缓存、Module Federation、长期缓存&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;大版本迁移痛点&lt;/strong&gt;：Webpack 4 → 5 主要是 &lt;code&gt;file-loader&lt;/code&gt;/&lt;code&gt;url-loader&lt;/code&gt;/&lt;code&gt;raw-loader&lt;/code&gt; 替换为 asset modules，以及 &lt;code&gt;node-polyfill-webpack-plugin&lt;/code&gt; 处理内置模块的 polyfill（如 &lt;code&gt;crypto&lt;/code&gt;、&lt;code&gt;buffer&lt;/code&gt;）。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="7-常见问题与排错"&gt;7. 常见问题与排错
&lt;/h2&gt;&lt;h3 id="71-报错-module-not-found"&gt;7.1 报错 &amp;ldquo;Module not found&amp;rdquo;
&lt;/h3&gt;&lt;p&gt;99% 是路径写错。Webpack 5 默认不允许绝对路径，必须写相对路径或配 &lt;code&gt;resolve.alias&lt;/code&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// webpack.config.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;alias&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;@&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;src&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="72-报错-cant-resolve-vue-in-"&gt;7.2 报错 &amp;ldquo;Can&amp;rsquo;t resolve &amp;lsquo;vue&amp;rsquo; in &amp;hellip;&amp;rdquo;
&lt;/h3&gt;&lt;p&gt;依赖没装对版本，或在 &lt;code&gt;vue.config.js&lt;/code&gt; 配了 externals 但忘记在 HTML 里用 CDN 引。&lt;strong&gt;先 &lt;code&gt;rm -rf node_modules &amp;amp;&amp;amp; npm install&lt;/code&gt; 排除 80% 情况&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="73-构建慢--体积大"&gt;7.3 构建慢 / 体积大
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;优化项&lt;/th&gt;
					&lt;th&gt;作用&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;mode: 'production'&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;自动启用 tree shaking + 压缩&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;optimization.splitChunks&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;把 node_modules 抽成 vendor，浏览器缓存更久&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;externals: { vue: 'Vue' }&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;通过 CDN 引入 Vue/React，业务 bundle 体积减半&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;productionSourceMap: false&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;不生成 .map 文件（生产环境不需要）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;terser-webpack-plugin&lt;/code&gt; 配 &lt;code&gt;parallel: true&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;多进程压缩&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;升级到 Webpack 5&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;持久化缓存，开机慢、增量快&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="74-浏览器缓存命中低"&gt;7.4 浏览器缓存命中低
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;output&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;filename&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;[name].[contenthash:8].js&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;chunkFilename&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;[name].[contenthash:8].chunk.js&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;contenthash&lt;/code&gt; 是内容哈希——文件没变，文件名不变，浏览器强缓存命中；文件改了，文件名变，强制刷新。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="小结webpack-学习路线"&gt;小结：Webpack 学习路线
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;会用&lt;/strong&gt;：跑通 &lt;code&gt;npx webpack&lt;/code&gt; 跑一个 demo → 配 &lt;code&gt;webpack.config.js&lt;/code&gt; 加上 babel/css-loader&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;会配&lt;/strong&gt;：理解 entry/output/loader/plugin/mode 五大件&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;会调&lt;/strong&gt;：会用 &lt;code&gt;splitChunks&lt;/code&gt; / &lt;code&gt;contenthash&lt;/code&gt; / &lt;code&gt;analyzer&lt;/code&gt; 优化产物体积&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;会写 loader/plugin&lt;/strong&gt;：读懂 Webpack 的 tapable 钩子系统，写一个自定义插件&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;会迁移&lt;/strong&gt;：Webpack 4 → 5，老项目升级&lt;/li&gt;
&lt;/ol&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;下一步&lt;/strong&gt;：2024 年起，更多新项目直接用 &lt;strong&gt;Vite&lt;/strong&gt;（开发时按需 ESM、生产时 Rollup 打包），启动速度比 Webpack 快 10-100 倍。但 Vite 的生产构建底层还是 Rollup，且大量 Vite 插件的接口与 Webpack 兼容。本文讲的 loader/plugin 思想 100% 适用。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="参考资料"&gt;参考资料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.webpackjs.com/concepts/" target="_blank" rel="noopener"
 &gt;Webpack 官方文档（中文）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.babeljs.cn/docs/" target="_blank" rel="noopener"
 &gt;Babel 官方文档&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://webpack.js.org/blog/2020-10-10-webpack-5-release/" target="_blank" rel="noopener"
 &gt;Webpack 5 Release Notes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/fouber/blog" target="_blank" rel="noopener"
 &gt;《前端工程化：体系化的前端工程实践》— 张云龙&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>