<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>且听书吟</title>
        <link>https://stage.yufan.me</link>
        <description>诗与梦想的远方</description>
        <lastBuildDate>Sat, 09 May 2026 12:39:30 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>WordPress 3.2.1</generator>
        <language>zh-CN</language>
        <image>
            <title>且听书吟</title>
            <url>https://stage.yufan.me/logo.svg</url>
            <link>https://stage.yufan.me</link>
        </image>
        <copyright>All rights reserved 2011, 雨帆</copyright>
        <category>文章</category>
        <category>杂思</category>
        <category>杂谈</category>
        <category>编程</category>
        <category>笔记</category>
        <category>小说</category>
        <atom:link href="https://stage.yufan.me/tags/front-end/feed" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Webpack 介绍：第一部分]]></title>
            <link>https://stage.yufan.me/posts/introduction-to-webpack-part-1</link>
            <guid isPermaLink="false">https://stage.yufan.me/posts/introduction-to-webpack-part-1</guid>
            <pubDate>Thu, 05 May 2016 10:15:29 GMT</pubDate>
            <description><![CDATA[Webpack 是近段时间非常流行的前端流程处理工具，用于实时执行构建任务和预处理你的文件。]]></description>
            <content:encoded><![CDATA[<link rel="preload" as="image" href="https://cat.yufan.me/images/2020/09/2020090419305167.jpg"/><link rel="preload" as="image" href="https://cat.yufan.me/images/2020/09/2020090419235130.png"/><link rel="preload" as="image" href="https://cat.yufan.me/images/2020/09/2020090419234660.jpg"/><img src="https://cat.yufan.me/images/2020/09/2020090419305167.jpg" alt="せばすちゃ - 座って聴く東方文化帳　CDジャケットイラスト"/>
<p>Webpack 是近段时间非常流行的前端流程处理工具，用于实时执行构建任务和预处理你的文件。</p>
<p>你也许会使用 <a href="http://gruntjs.com/" rel="nofollow" target="_blank">Grunt</a> 或者 <a href="http://gulpjs.com/" rel="nofollow" target="_blank">Gulp</a> 来做类似的事情。首先建立一个编译链，然后在上面定义从何处读取代码，将压缩处理好的 CSS 和 JavaScript 等静态资源输出到什么地方。</p>
<p>这些工具都非常流行和好用，然而我却要向你安利另一种实现此类需求的方法，那就是使用 <a href="https://webpack.github.io/" rel="nofollow" target="_blank">Webpack</a>。<em>新技能Get！</em></p>
<h2 id="什么是-webpack">什么是 Webpack？<a href="#什么是-webpack"><span class="icon icon-link"></span></a></h2>
<img src="https://cat.yufan.me/images/2020/09/2020090419235130.png" alt=""/>
<p>Webpack 常被人们定义为“模块打包工具”（module bundler），它读取 JavaScript 模块，分析它们之间的依赖关系，然后用尽可能高效的方式将它们组织在一起，最后生成一个独立的 JS 文件。似乎看起来并没有什么牛逼的技术，像 <a href="http://requirejs.org/" rel="nofollow" target="_blank">RequireJS</a> 在多少年前就能实现相似的功能了。</p>
<p>当然，如果是这样子我就没必要安利你了，相比 RequireJS 之流它还是有自己的特色的。Webpack 能读取的不光是原生的 JavaScript 文件，模块加载器的设计使得它能支持更丰富的格式。</p>
<p>例如，它能分析出你的 JavaScript 模块需要一个 CSS 文件，甚至能分析出这个 CSS 文件需要的图片资源。然后，处理过的资源文件只包含最精简的必须文件。不信？让我们现在来实战体验。</p>
<h2 id="安装">安装<a href="#安装"><span class="icon icon-link"></span></a></h2>
<p>首先必须要安装的是 <a href="https://nodejs.org/en/" rel="nofollow" target="_blank">Node.js</a>，在这里我们假定你已经正确安装并且配置完毕。那么安装 Webpack 所需要做的事，就只剩下输入下面的这条命令：</p>
<pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" icon="&lt;svg viewBox=&quot;0 0 24 24&quot;&gt;&lt;path d=&quot;m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4 Z m 8,14 a 1,1 0 0 0 -1,1 1,1 0 0 0 1,1 h 8 a 1,1 0 0 0 1,-1 1,1 0 0 0 -1,-1 z&quot; fill=&quot;currentColor&quot; /&gt;&lt;/svg&gt;"><code class="language-bash"><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">npm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> install</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> webpack</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -g</span></span></code></pre>
<p>这条命令将全局安装 Webpack，并能在系统的任何路径下执行 <code>webpack</code> 命令。下面我们新建一个文件夹，在里面新建一个基本的 HTML 文件，名为<code>index.html</code>，内容如下：</p>
<pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" icon="&lt;svg viewBox=&quot;0 0 24 24&quot;&gt;&lt;path d=&quot;M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992,3 3,3 h 3 v 11 c 0,0.564129 -0.435871,1 -1,1 H 6 C 5.4358712,21 5,20.564129 5,20 V 4 C 5,3.4358712 5.4358712,3 6,3 Z M 15,3.4140625 18.585937,7 H 16 C 15.435871,7 15,6.5641288 15,6 Z&quot; fill=&quot;currentColor&quot; /&gt;&lt;/svg&gt;"><code class="language-html"><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&lt;!</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">doctype</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> html</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">html</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">head</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    &lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">meta</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> charset</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">&quot;utf-8&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    &lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">title</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&gt;Webpack fun&lt;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">title</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &lt;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">head</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">body</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    &lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">h2</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&gt;&lt;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">h2</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    &lt;</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> src</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">&quot;bundle.js&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&gt;&lt;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">script</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  &lt;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">body</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&gt;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&lt;/</span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D">html</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">&gt;</span></span></code></pre>
<p>需要注意的是，这里定义的<code>bundle.js</code>暂时还不存在，稍后将由 Webpack 帮我们创建。另外，那个空的 H2 标签稍后我们将会使用到。</p>
<p>接下来，在上面文件夹里创建两个 JS 文件，分别叫做：<code>main.js</code>、<code>say-hello.js</code>。<code>main.js</code>你可以理解为 main 方法，也就是我们代码主要的执行入口。<code>say-hello.js</code>是一个简单的模块，它接收一个人名和 DOM 元素，然后在这个 DOM 元素上显示一条包含人名的欢迎信息。</p>
<pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" icon="&lt;svg viewBox=&quot;0 0 24 24&quot;&gt;&lt;path d=&quot;M0 0h24v24H0V0zm22.034 18.276c-.175-1.095-.888-2.015-3.003-2.873-.736-.345-1.554-.585-1.797-1.14-.091-.33-.105-.51-.046-.705.15-.646.915-.84 1.515-.66.39.12.75.42.976.9 1.034-.676 1.034-.676 1.755-1.125-.27-.42-.404-.601-.586-.78-.63-.705-1.469-1.065-2.834-1.034l-.705.089c-.676.165-1.32.525-1.71 1.005-1.14 1.291-.811 3.541.569 4.471 1.365 1.02 3.361 1.244 3.616 2.205.24 1.17-.87 1.545-1.966 1.41-.811-.18-1.26-.586-1.755-1.336l-1.83 1.051c.21.48.45.689.81 1.109 1.74 1.756 6.09 1.666 6.871-1.004.029-.09.24-.705.074-1.65l.046.067zm-8.983-7.245h-2.248c0 1.938-.009 3.864-.009 5.805 0 1.232.063 2.363-.138 2.711-.33.689-1.18.601-1.566.48-.396-.196-.597-.466-.83-.855-.063-.105-.11-.196-.127-.196l-1.825 1.125c.305.63.75 1.172 1.324 1.517.855.51 2.004.675 3.207.405.783-.226 1.458-.691 1.811-1.411.51-.93.402-2.07.397-3.346.012-2.054 0-4.109 0-6.179l.004-.056z&quot; fill=&quot;currentColor&quot; /&gt;&lt;/svg&gt;"><code class="language-javascript"><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// say-hello.js</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">module</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">exports</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> function</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">name</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70">element</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  element.textContent </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> &#x27;Hello &#x27;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> +</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> name </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">+</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> &#x27;!&#x27;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span></code></pre>
<p>定义完 <code>say-hello.js</code> 这个模块后，我们在 <code>main.js</code> 里引用它，引用方法十分简单，只需要下面这两行代码：</p>
<pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" icon="&lt;svg viewBox=&quot;0 0 24 24&quot;&gt;&lt;path d=&quot;M0 0h24v24H0V0zm22.034 18.276c-.175-1.095-.888-2.015-3.003-2.873-.736-.345-1.554-.585-1.797-1.14-.091-.33-.105-.51-.046-.705.15-.646.915-.84 1.515-.66.39.12.75.42.976.9 1.034-.676 1.034-.676 1.755-1.125-.27-.42-.404-.601-.586-.78-.63-.705-1.469-1.065-2.834-1.034l-.705.089c-.676.165-1.32.525-1.71 1.005-1.14 1.291-.811 3.541.569 4.471 1.365 1.02 3.361 1.244 3.616 2.205.24 1.17-.87 1.545-1.966 1.41-.811-.18-1.26-.586-1.755-1.336l-1.83 1.051c.21.48.45.689.81 1.109 1.74 1.756 6.09 1.666 6.871-1.004.029-.09.24-.705.074-1.65l.046.067zm-8.983-7.245h-2.248c0 1.938-.009 3.864-.009 5.805 0 1.232.063 2.363-.138 2.711-.33.689-1.18.601-1.566.48-.396-.196-.597-.466-.83-.855-.063-.105-.11-.196-.127-.196l-1.825 1.125c.305.63.75 1.172 1.324 1.517.855.51 2.004.675 3.207.405.783-.226 1.458-.691 1.811-1.411.51-.93.402-2.07.397-3.346.012-2.054 0-4.109 0-6.179l.004-.056z&quot; fill=&quot;currentColor&quot; /&gt;&lt;/svg&gt;"><code class="language-javascript"><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D">// main.js</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">var</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> sayHello </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">=</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> require</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">&#x27;./say-hello&#x27;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">sayHello</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">&#x27;Guybrush&#x27;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">, document.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">querySelector</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">&#x27;h2&#x27;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">))</span></span></code></pre>
<p>如果现在我们打开前面创建的那个 HTML 文件，你们发现页面上没有显示任何内容。因为我们既没有引用<code>main.js</code>，也没有将其处理成浏览器可执行的代码。接下来，我们使用 Webpack 读取<code>main.js</code>。如果能成功分析它的依赖，将会创建一个名为<code>bundle.js</code>的文件，并能在浏览器中执行。</p>
<p>回到命令行里执行 Webpack，只需简单输入如下命令：</p>
<pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" icon="&lt;svg viewBox=&quot;0 0 24 24&quot;&gt;&lt;path d=&quot;m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4 Z m 8,14 a 1,1 0 0 0 -1,1 1,1 0 0 0 1,1 h 8 a 1,1 0 0 0 1,-1 1,1 0 0 0 -1,-1 z&quot; fill=&quot;currentColor&quot; /&gt;&lt;/svg&gt;"><code class="language-bash"><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">webpack</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> main.js</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> bundle.js</span></span></code></pre>
<p>第一个参数定义了 Webpack 分析依赖的起始文件。首先，它查看起始文件里是否定义了相关的依赖。如果有，它将读入依赖的文件，看看这个文件是否也有其他的依赖。通过这种方式，递归读取完整个程式依赖的全部文件。一旦阅读完毕，它将整个依赖打包为一个文件，名为 <code>bundle.js</code>。</p>
<p>在这个例子里，当你按下回车后，你会看到类似下面的输出：</p>
<pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" icon="&lt;svg viewBox=&quot;0 0 24 24&quot;&gt;&lt;path d=&quot;m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4 Z m 8,14 a 1,1 0 0 0 -1,1 1,1 0 0 0 1,1 h 8 a 1,1 0 0 0 1,-1 1,1 0 0 0 -1,-1 z&quot; fill=&quot;currentColor&quot; /&gt;&lt;/svg&gt;"><code class="language-bash"><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">Hash:</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 3d7d7339a68244b03c68</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">Version:</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> webpack</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> 1.12.12</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">Time:</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> 55ms</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">    Asset</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">     Size</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">  Chunks</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">             Chunk</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> Names</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">bundle.js</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">  1.65</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> kB</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">       0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  [emitted]  main</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">   [0] </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">./main.js</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> 90</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> bytes</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> {</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">0</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">}</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> [built]</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">   [1] </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">./say-hello.js</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> 94</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> bytes</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> {</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">0</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">}</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> [built]</span></span></code></pre>
<p>现在，打开<code>index.html</code>，浏览器将会显示<code>Hello Guybrush!</code></p>
<h2 id="配置">配置<a href="#配置"><span class="icon icon-link"></span></a></h2>
<p>如果每次运行 Webpack 都要指定输入和输出文件的话就太让人讨厌了。当然，开发者早就替我们想好了。其实和 <code>Gulp</code>、<code>Grunt</code>类似，Webpack 需要在我们的项目根目录下创建一个名为<code>webpack.config.js</code>的文件，就可以简化大量重复的命令参数。</p>
<p>在本例中，内容如下：</p>
<pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" icon="&lt;svg viewBox=&quot;0 0 24 24&quot;&gt;&lt;path d=&quot;M0 0h24v24H0V0zm22.034 18.276c-.175-1.095-.888-2.015-3.003-2.873-.736-.345-1.554-.585-1.797-1.14-.091-.33-.105-.51-.046-.705.15-.646.915-.84 1.515-.66.39.12.75.42.976.9 1.034-.676 1.034-.676 1.755-1.125-.27-.42-.404-.601-.586-.78-.63-.705-1.469-1.065-2.834-1.034l-.705.089c-.676.165-1.32.525-1.71 1.005-1.14 1.291-.811 3.541.569 4.471 1.365 1.02 3.361 1.244 3.616 2.205.24 1.17-.87 1.545-1.966 1.41-.811-.18-1.26-.586-1.755-1.336l-1.83 1.051c.21.48.45.689.81 1.109 1.74 1.756 6.09 1.666 6.871-1.004.029-.09.24-.705.074-1.65l.046.067zm-8.983-7.245h-2.248c0 1.938-.009 3.864-.009 5.805 0 1.232.063 2.363-.138 2.711-.33.689-1.18.601-1.566.48-.396-.196-.597-.466-.83-.855-.063-.105-.11-.196-.127-.196l-1.825 1.125c.305.63.75 1.172 1.324 1.517.855.51 2.004.675 3.207.405.783-.226 1.458-.691 1.811-1.411.51-.93.402-2.07.397-3.346.012-2.054 0-4.109 0-6.179l.004-.056z&quot; fill=&quot;currentColor&quot; /&gt;&lt;/svg&gt;"><code class="language-javascript"><span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">module</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">exports</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  entry: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">&#x27;./main.js&#x27;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  output: {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    filename: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">&#x27;bundle.js&#x27;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span></code></pre>
<p>现在，我们只需要输入<code>webpack</code>这个命令，就能实现和之前一样的操作。</p>
<h2 id="开发服务器">开发服务器<a href="#开发服务器"><span class="icon icon-link"></span></a></h2>
<p>首先提个问题：每次你做了一些改动，如果都要手动去执行<code>webpack</code>命令来看结果的话，是不是特傻逼？要知道，<code>Gulp</code>在很早之前就支持定义<code>watch</code>这种监视文件修改的任务了。所以，Webpack也不例外，甚至它还更进一步，提供了一个基于Node.js Express框架的开发服务器。</p>
<pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" icon="&lt;svg viewBox=&quot;0 0 24 24&quot;&gt;&lt;path d=&quot;m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4 Z m 8,14 a 1,1 0 0 0 -1,1 1,1 0 0 0 1,1 h 8 a 1,1 0 0 0 1,-1 1,1 0 0 0 -1,-1 z&quot; fill=&quot;currentColor&quot; /&gt;&lt;/svg&gt;"><code class="language-bash"><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">npm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> install</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> webpack-dev-server</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> -g</span></span></code></pre>
<p>首先运行上面的命令安装开发服务器，然后运行命令<code>webpack-dev-server</code>。这个命令将会启动一个简单的 Web 服务器，以命令执行的路径为静态资源根目录。下面我们打开浏览器，输入<a href="http://localhost:8080/webpack-dev-server/" rel="nofollow" target="_blank">http://localhost:8080/webpack-dev-server/</a>。如果一切正常，你将看到类似下面的内容：</p>
<img src="https://cat.yufan.me/images/2020/09/2020090419234660.jpg" alt=""/>
<p>现在，我们不仅有了一个超赞的轻量级 Web 服务器，我们还有了一个孜孜不倦地监听代码变更的观察者。如果 Webpack 发现我们修改了一个文件，它会自动运行 <code>webpack</code> 命令打包我们的代码并刷新页面。</p>
<p>假想一下，我们可以双屏写代码，一个屏幕放浏览器，一个屏幕开编辑器。浏览器实时刷新结果，无需我们做任何配置和操作，是不是很酷？</p>
<p>现在你可以自己感受一下：修改<code>main.js</code>里面传给<code>sayHello</code>方法的姓名参数，然后保存文件，看看浏览器里面的实时变化。</p>
<h2 id="加载器loaders">加载器（Loaders）<a href="#加载器loaders"><span class="icon icon-link"></span></a></h2>
<p>对于 Webpack 而言，最重要的特性就是<a href="https://webpack.github.io/docs/loaders.html" rel="nofollow" target="_blank">加载器</a>。加载器和<code>Gulp</code> <code>Grunt</code>上的“任务”（tasks）类似。基本上都是读取文件，然后通过某种方式处理文件，最后打包为我们所需的代码。</p>
<p>本文中，我们想在代码中用一些<a href="http://www.ecma-international.org/ecma-262/6.0/" rel="nofollow" target="_blank">ES2015</a>的语法。因为 ES2015 是当前最新的 JavaScript 版本，所以并没有被所有的浏览器支持。可是淫家就想写最新的代码装逼怎么办？那只好先写，写完后将 ES2016 版本的代码转换为老的 ES5 代码。</p>
<p>为了实现这个需求，我们需要使用当下最流行的 <a href="https://github.com/babel/babel-loader" rel="nofollow" target="_blank">Babel Loader</a> 来进行转换。根据官网的教程，我们使用下面的命令进行安装：</p>
<pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" icon="&lt;svg viewBox=&quot;0 0 24 24&quot;&gt;&lt;path d=&quot;m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4 Z m 8,14 a 1,1 0 0 0 -1,1 1,1 0 0 0 1,1 h 8 a 1,1 0 0 0 1,-1 1,1 0 0 0 -1,-1 z&quot; fill=&quot;currentColor&quot; /&gt;&lt;/svg&gt;"><code class="language-bash"><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0">npm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> install</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> babel-loader</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> babel-core</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> babel-preset-es2015</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> --save-dev</span></span></code></pre>
<p>这条命令不仅安装了 Babel 加载器，还包含了它支持 ES2015 时所需要的依赖。</p>
<p>安装完加载器，我们需要告诉 Webpack 使用什么加载器，参考下面的实例更新 <code>webpack.config.js</code> 文件：</p>
<pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" icon="&lt;svg viewBox=&quot;0 0 24 24&quot;&gt;&lt;path d=&quot;M0 0h24v24H0V0zm22.034 18.276c-.175-1.095-.888-2.015-3.003-2.873-.736-.345-1.554-.585-1.797-1.14-.091-.33-.105-.51-.046-.705.15-.646.915-.84 1.515-.66.39.12.75.42.976.9 1.034-.676 1.034-.676 1.755-1.125-.27-.42-.404-.601-.586-.78-.63-.705-1.469-1.065-2.834-1.034l-.705.089c-.676.165-1.32.525-1.71 1.005-1.14 1.291-.811 3.541.569 4.471 1.365 1.02 3.361 1.244 3.616 2.205.24 1.17-.87 1.545-1.966 1.41-.811-.18-1.26-.586-1.755-1.336l-1.83 1.051c.21.48.45.689.81 1.109 1.74 1.756 6.09 1.666 6.871-1.004.029-.09.24-.705.074-1.65l.046.067zm-8.983-7.245h-2.248c0 1.938-.009 3.864-.009 5.805 0 1.232.063 2.363-.138 2.711-.33.689-1.18.601-1.566.48-.396-.196-.597-.466-.83-.855-.063-.105-.11-.196-.127-.196l-1.825 1.125c.305.63.75 1.172 1.324 1.517.855.51 2.004.675 3.207.405.783-.226 1.458-.691 1.811-1.411.51-.93.402-2.07.397-3.346.012-2.054 0-4.109 0-6.179l.004-.056z&quot; fill=&quot;currentColor&quot; /&gt;&lt;/svg&gt;"><code class="language-javascript"><span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">module</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF">exports</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8"> {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  entry: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">&#x27;./main.js&#x27;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  output: {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    filename: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">&#x27;bundle.js&#x27;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  module: {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    loaders: [</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">        test:</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> /</span><span style="--shiki-light:#22863A;--shiki-light-font-weight:bold;--shiki-dark:#85E89D;--shiki-dark-font-weight:bold">\.</span><span style="--shiki-light:#032F62;--shiki-dark:#DBEDFF">js</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">$</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">        exclude:</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF"> /</span><span style="--shiki-light:#032F62;--shiki-dark:#DBEDFF">node_modules</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">        loader: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">&#x27;babel&#x27;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">,</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">        query: {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">          presets: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">&#x27;es2015&#x27;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">],</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">        },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">      },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">    ],</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">  },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">}</span></span></code></pre>
<p>在这个配置示例里，我们需要注意几个地方。首先，<code>test: /\.js$/</code>这行是一个正则表达式，表示文件名满足此正则表达式的文件将会被此加载器处理。这里，我们的定义是全部的JS文件。类似的，<code>exclude: /node_modules/</code>则是告诉 Webpack 忽略<code>node_modules</code>文件夹。<code>loader</code>和<code>query</code>我觉得十分好理解，就是使用Babel loader加载器处理ES2015语法的文件。</p>
<p>重启开发服务器，在命令行里按下<code>ctrl+c</code>，重新输入<code>webpack-dev-server</code>。现在我们来测试一下 ES6 的代码是否能被正确翻译呢？不如试试看将<code>sayHello</code>变量定义为一个常量。</p>
<pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e" tabindex="0" icon="&lt;svg viewBox=&quot;0 0 24 24&quot;&gt;&lt;path d=&quot;M0 0h24v24H0V0zm22.034 18.276c-.175-1.095-.888-2.015-3.003-2.873-.736-.345-1.554-.585-1.797-1.14-.091-.33-.105-.51-.046-.705.15-.646.915-.84 1.515-.66.39.12.75.42.976.9 1.034-.676 1.034-.676 1.755-1.125-.27-.42-.404-.601-.586-.78-.63-.705-1.469-1.065-2.834-1.034l-.705.089c-.676.165-1.32.525-1.71 1.005-1.14 1.291-.811 3.541.569 4.471 1.365 1.02 3.361 1.244 3.616 2.205.24 1.17-.87 1.545-1.966 1.41-.811-.18-1.26-.586-1.755-1.336l-1.83 1.051c.21.48.45.689.81 1.109 1.74 1.756 6.09 1.666 6.871-1.004.029-.09.24-.705.074-1.65l.046.067zm-8.983-7.245h-2.248c0 1.938-.009 3.864-.009 5.805 0 1.232.063 2.363-.138 2.711-.33.689-1.18.601-1.566.48-.396-.196-.597-.466-.83-.855-.063-.105-.11-.196-.127-.196l-1.825 1.125c.305.63.75 1.172 1.324 1.517.855.51 2.004.675 3.207.405.783-.226 1.458-.691 1.811-1.411.51-.93.402-2.07.397-3.346.012-2.054 0-4.109 0-6.179l.004-.056z&quot; fill=&quot;currentColor&quot; /&gt;&lt;/svg&gt;"><code class="language-javascript"><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF"> sayHello</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0"> require</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF">&#x27;./say-hello&#x27;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8">)</span></span></code></pre>
<p>保存后，Webpack应该自动重新编译我们的代码并刷新浏览器，你会发现代码正常执行，什么都没有变。我们用编辑器打开<code>bundle.js</code>文件，你会发现没有<code>const</code>这个单词。</p>
<p>Webpack就是这么叼！</p>
<h2 id="第二部分预告">第二部分预告<a href="#第二部分预告"><span class="icon icon-link"></span></a></h2>
<p>在这篇教程的第二部分，我们将学习使用 Webpack 加载 CSS 和 图片文件，同时让你的网站为部署做好准备。</p>
<h2 id="相关链接">相关链接<a href="#相关链接"><span class="icon icon-link"></span></a></h2>
<ol>
<li><a href="http://code.tutsplus.com/tutorials/introduction-to-webpack-part-1--cms-25791" rel="nofollow" target="_blank">Introduction to Webpack: Part 1</a></li>
<li><a href="https://segmentfault.com/a/1190000003970448" rel="nofollow" target="_blank">详解前端模块化工具-Webpack</a></li>
<li><a href="http://jamesknelson.com/webpack-made-simple-build-es6-less-with-autorefresh-in-26-lines/" rel="nofollow" target="_blank">Webpack Made Simple: Building ES6 &amp; LESS with autorefresh</a></li>
</ol>]]></content:encoded>
            <author>syhily@gmail.com (雨帆)</author>
            <category domain="https://stage.yufan.me/tags/front-end">前端</category>
            <category domain="https://stage.yufan.me/cats/coding">编程</category>
            <enclosure url="https://stage.yufan.me/images/og/introduction-to-webpack-part-1.png" length="0" type="image/png"/>
        </item>
    </channel>
</rss>