<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>老衲是基佬</title>
  
  <link href="/atom.xml" rel="self"/>
  
  <link href="https://laoona.com/"/>
  <updated>2024-07-21T05:42:21.228Z</updated>
  <id>https://laoona.com/</id>
  
  <author>
    <name>laoona</name>
    
  </author>
  
  <generator uri="http://hexo.io/">Hexo</generator>
  
  <entry>
    <title>package.json 版本号说明</title>
    <link href="https://laoona.com/post/f56b394f.html"/>
    <id>https://laoona.com/post/f56b394f.html</id>
    <published>2021-11-11T14:42:05.000Z</published>
    <updated>2024-07-21T05:42:21.228Z</updated>
    
    <content type="html">&lt;h3 id=&quot;版本号基本格式&quot;&gt;&lt;a href=&quot;#版本号基本格式&quot; class=&quot;headerlink&quot; title=&quot;版本号基本格式&quot;&gt;&lt;/a&gt;版本号基本格式&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;主号.次号.修补号&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;dependency-版本更新规则-dependency-version-update-rule&quot;&gt;&lt;a href=&quot;#dependency-版本更新规则-dependency-version-update-rule&quot; class=&quot;headerlink&quot; title=&quot;dependency 版本更新规则 (dependency version update rule)&quot;&gt;&lt;/a&gt;dependency 版本更新规则 (dependency version update rule)&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;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;version&lt;/td&gt;
&lt;td&gt;完全匹配当前版本&lt;/td&gt;
&lt;td&gt;1.0.0&lt;/td&gt;
&lt;td&gt;1.0.0&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;^version&lt;/td&gt;
&lt;td&gt;兼容版本(不超过最左边非零数字)&lt;/td&gt;
&lt;td&gt;^1.2.3 &lt;br&gt; ^0.2.3 &lt;br&gt; ^0.0.3  &lt;br&gt;^1&lt;/td&gt;
&lt;td&gt;&lt;div style=&quot;width:180px&quot;&gt;&lt;/div&gt; &amp;gt;=1.2.3 &amp;lt;2.0.0-0 &lt;br&gt;&amp;gt;=0.2.3 &amp;lt;0.3.0-0 &lt;br&gt; &amp;gt;=0.0.3 &amp;lt;0.0.4-0 &lt;br&gt; &amp;gt;=1.0.0 &amp;lt;2.0.0-0&lt;/td&gt;
&lt;td&gt;缺失.minor 或.patch 会默认用 0 代替&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;~version&lt;/td&gt;
&lt;td&gt;最接近匹配版本&lt;/td&gt;
&lt;td&gt;~1.2.3 &lt;br&gt;  ~1.2 &lt;br&gt; ~1&lt;/td&gt;
&lt;td&gt;&amp;gt;=1.2.3 &amp;lt;1.3.0 &lt;br&gt; &amp;gt;=1.2.0 &amp;lt;1.3.0 &lt;br&gt; &amp;gt;=1.0.0 &amp;lt;2.0.0&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;gt;version&lt;/td&gt;
&lt;td&gt;大于当前版本&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;gt;=version&lt;/td&gt;
&lt;td&gt;大于等于当前版本&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;lt;version&lt;/td&gt;
&lt;td&gt;小于当前版本&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;lt;=version&lt;/td&gt;
&lt;td&gt;小于等于当前版本&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;*&lt;/td&gt;
&lt;td&gt;匹配任意版本&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;latest&lt;/td&gt;
&lt;td&gt;已发布的最新版本&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;version1-version2&lt;/td&gt;
&lt;td&gt;version1 到 version2 的任意版本(包括本身)&lt;/td&gt;
&lt;td&gt;1.0.0-2.0.0&lt;/td&gt;
&lt;td&gt;&amp;gt;=1.0.0 &amp;lt;=2.0.0&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;range1 &amp;#124;&amp;#124; range2&lt;/td&gt;
&lt;td&gt;多个范围内的版本&lt;/td&gt;
&lt;td&gt;&amp;lt; 1.0.0 &amp;#124;&amp;#124; &amp;gt;2.0.0&lt;/td&gt;
&lt;td&gt;&amp;lt;1.0.0 或者 &amp;gt;2.0.0&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;version.x&lt;/td&gt;
&lt;td&gt;x 的位置表示任意版本&lt;/td&gt;
&lt;td&gt;1.2.x&lt;/td&gt;
&lt;td&gt;&amp;gt;=1.2.0 &amp;lt;1.3.&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&quot;版本号规则&quot;&gt;&lt;a href=&quot;#版本号规则&quot; class=&quot;headerlink&quot; title=&quot;版本号规则&quot;&gt;&lt;/a&gt;版本号规则&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;1. version  指定版本号&lt;/strong&gt;&lt;br&gt;“vue-clipboard2”: “0.0.8”   //指定所依赖的该组件必须是 0.0.8 版本的&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. &amp;gt;version 大于该版本号&lt;/strong&gt;&lt;br&gt;“vue-clipboard2”: “&amp;gt;0.0.8”   //指定所依赖的该组件必须是大于 0.0.8 版本的&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. &amp;gt;=version 大于等于该版本号&lt;/strong&gt;&lt;br&gt;“vue-clipboard2”: “&amp;gt;=0.0.8”   //指定所依赖的该组件必须是 大于或等于0.0.8 版本的&lt;br&gt;&lt;a id=&quot;more&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. &amp;lt;version 小于该版本号&lt;/strong&gt;&lt;br&gt;“vue-clipboard2”: “&amp;lt;0.0.8”   //指定所依赖的该组件必须是小于 0.0.8 版本的&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5. &amp;lt;=version 小于等于该版本号&lt;/strong&gt;&lt;br&gt;“vue-clipboard2”: “&amp;lt;=0.0.8”   //指定所依赖的该组件必须是小于等于 0.0.8 版本的&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;6. ~version 右侧任意&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“vue-clipboard2”: “~0.2.1”   //该组件版本号 要&amp;gt;=0.2.1，并修补号为 &amp;gt;=1 的任意值&lt;/li&gt;
&lt;li&gt;“vue-clipboard2”: “~0.2”   //该组件版本号 要&amp;gt;=0.2，并修补号为 &amp;gt;=0 的任意值&lt;/li&gt;
&lt;li&gt;“vue-clipboard2”: “~1”   //该组件版本号 要&amp;gt;=1.0.0，次版本号任意，并修补号任意&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;7. ^version 非0右侧任意&lt;/strong&gt;&lt;br&gt;从左向右，第一个非0号的右侧任意&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“vue-clipboard2”: “^0.1.2”   //该组件版本号 要&amp;gt;=0.1.2 主版本号为0固定，次版本号为 1 固定，并修补号 &amp;gt;=2 任意值&lt;/li&gt;
&lt;li&gt;“vue-clipboard2”: “^1.1.2”   //该组件版本号 要&amp;gt;=1.1.2 主版本号为1固定，次版本号为 &amp;gt;=1任意值，并修补号为任意值，但次版本号为1时，修补号要&amp;gt;=2，即要满足总版本号&amp;gt;=1.1.2&lt;/li&gt;
&lt;li&gt;“vue-clipboard2”: “^0.1”   //该组件版本号 要&amp;gt;=0.1 缺少的版本号位位置为任意值&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;8. x-version x位置任意&lt;/strong&gt;&lt;br&gt;“vue-clipboard2”: “0.1.x”   //x位置任意&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;9. “”|| *    version 表示版本任意&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“vue-clipboard2”: “”   //版本任意&lt;/li&gt;
&lt;li&gt;“vue-clipboard2”: “*”   //版本任意&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;10. version1-version2 表示版本区间范围 包含首尾版本号&lt;/strong&gt;&lt;br&gt;“vue-clipboard2”: “1.1.1-1.2.9”   //版本要求 1.1.1&amp;lt;=版本号&amp;lt;=1.2.9&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;11. version1||version2||…version 表示或，或version1或version2，支持多个&lt;/strong&gt;&lt;br&gt;“vue-clipboard2”: “1.1.1-1.2.9 || &amp;gt;=3.5.0 || ^0.1.2”   //版本要求满足其一即可&lt;/p&gt;
</content>
    
    <summary type="html">
    
      package_version
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>Mongo 常用操作</title>
    <link href="https://laoona.com/post/effa6b88.html"/>
    <id>https://laoona.com/post/effa6b88.html</id>
    <published>2021-11-05T10:39:12.000Z</published>
    <updated>2024-07-21T05:42:21.228Z</updated>
    
    <content type="html">&lt;h3 id=&quot;两种方式连接MongoDB&quot;&gt;&lt;a href=&quot;#两种方式连接MongoDB&quot; class=&quot;headerlink&quot; title=&quot;两种方式连接MongoDB&quot;&gt;&lt;/a&gt;两种方式连接MongoDB&lt;/h3&gt;&lt;h4 id=&quot;1-类似Mysql一样连接&quot;&gt;&lt;a href=&quot;#1-类似Mysql一样连接&quot; class=&quot;headerlink&quot; title=&quot;1. 类似Mysql一样连接&quot;&gt;&lt;/a&gt;1. 类似Mysql一样连接&lt;/h4&gt;&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;mongo --host 10.10.18.11 -u &lt;span class=&quot;string&quot;&gt;&quot;myUserAdmin&quot;&lt;/span&gt; --authenticationDatabase &lt;span class=&quot;string&quot;&gt;&quot;admin&quot;&lt;/span&gt; -p&lt;span class=&quot;string&quot;&gt;&#39;abc123&#39;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;a id=&quot;more&quot;&gt;&lt;/a&gt;
&lt;h4 id=&quot;2-登录后进行验证&quot;&gt;&lt;a href=&quot;#2-登录后进行验证&quot; class=&quot;headerlink&quot; title=&quot;2. 登录后进行验证&quot;&gt;&lt;/a&gt;2. 登录后进行验证&lt;/h4&gt;&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# 先连接&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;mongo --host 10.10.18.11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# 进行验证&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;rs0:PRIMARY&amp;gt; use admin&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;switched to db admin&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;rs0:PRIMARY&amp;gt; db.auth(&lt;span class=&quot;string&quot;&gt;&quot;myUserAdmin&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;abc123&quot;&lt;/span&gt; )&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h3 id=&quot;创建用户&quot;&gt;&lt;a href=&quot;#创建用户&quot; class=&quot;headerlink&quot; title=&quot;创建用户&quot;&gt;&lt;/a&gt;创建用户&lt;/h3&gt;&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;#1.一定要先选择要创建用户的库!&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;use test_db&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt; &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;#2.执行创建用户命令并设置角色权限&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;db.createUser(&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    user:&lt;span class=&quot;string&quot;&gt;&quot;user&quot;&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;built_in&quot;&gt;pwd&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;password&quot;&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    roles:[&amp;#123;role:&lt;span class=&quot;string&quot;&gt;&quot;readWrite&quot;&lt;/span&gt;,db:&lt;span class=&quot;string&quot;&gt;&quot;test_db&quot;&lt;/span&gt;&amp;#125;]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;)&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;blockquote&gt;
&lt;p&gt;user：用户名&lt;br&gt;pwd：密码&lt;br&gt;db：指定该用户的数据库，admin是用于权限控制的数据库，如果没有需要新建一个&lt;br&gt;roles：指定用户的角色，可以用一个空数组给新用户设定空角色；在roles字段,可以指定内置角色和用户定义的角色。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;具体角色的功能&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Read：允许用户读取指定数据库&lt;/li&gt;
&lt;li&gt;readWrite：允许用户读写指定数据库&lt;/li&gt;
&lt;li&gt;dbAdmin：允许用户在指定数据库中执行管理函数，如索引创建、删除，查看统计或访问system.profile&lt;/li&gt;
&lt;li&gt;userAdmin：允许用户向system.users集合写入，可以找指定数据库里创建、删除和管理用户&lt;/li&gt;
&lt;li&gt;clusterAdmin：只在admin数据库中可用，赋予用户所有分片和复制集相关函数的管理权限。&lt;/li&gt;
&lt;li&gt;readAnyDatabase：只在admin数据库中可用，赋予用户所有数据库的读权限&lt;/li&gt;
&lt;li&gt;readWriteAnyDatabase：只在admin数据库中可用，赋予用户所有数据库的读写权限&lt;/li&gt;
&lt;li&gt;userAdminAnyDatabase：只在admin数据库中可用，赋予用户所有数据库的userAdmin权限&lt;/li&gt;
&lt;li&gt;dbAdminAnyDatabase：只在admin数据库中可用，赋予用户所有数据库的dbAdmin权限。&lt;/li&gt;
&lt;li&gt;root：只在admin数据库中可用。超级账号，超级权限&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;备份&quot;&gt;&lt;a href=&quot;#备份&quot; class=&quot;headerlink&quot; title=&quot;备份&quot;&gt;&lt;/a&gt;备份&lt;/h3&gt;&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;-u 用户&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;-p 密码&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;-d 备份的库&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;-o 备份存储目标位置&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;/var/www/mongodb/bin/mongodump -u dba  -p password  -d leanote -o /var/www/data/&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h3 id=&quot;导入&quot;&gt;&lt;a href=&quot;#导入&quot; class=&quot;headerlink&quot; title=&quot;导入&quot;&gt;&lt;/a&gt;导入&lt;/h3&gt;&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;-d 目标库&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;./leanote json文件&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--drop 清空原库表&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;mongorestore -d yapi ./leanote --drop --noIndexRestore&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
</content>
    
    <summary type="html">
    
      mongodb
    
    </summary>
    
    
      <category term="db" scheme="https://laoona.com/tags/db/"/>
    
  </entry>
  
  <entry>
    <title>浏览器何时会发送一个 options 请求</title>
    <link href="https://laoona.com/post/226b3712.html"/>
    <id>https://laoona.com/post/226b3712.html</id>
    <published>2018-06-04T16:08:02.000Z</published>
    <updated>2024-07-21T05:42:21.228Z</updated>
    
    <content type="html">&lt;h2 id=&quot;浏览器出现-http-method-options-请求的作用是什么？&quot;&gt;&lt;a href=&quot;#浏览器出现-http-method-options-请求的作用是什么？&quot; class=&quot;headerlink&quot; title=&quot;浏览器出现 http method options 请求的作用是什么？&quot;&gt;&lt;/a&gt;浏览器出现 http method options 请求的作用是什么？&lt;/h2&gt;&lt;p&gt;主要的作用有两个&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;获取服务器支持的 http 请求方法&lt;/li&gt;
&lt;li&gt;用来检查服务器的性能&lt;/li&gt;
&lt;/ul&gt;
&lt;a id=&quot;more&quot;&gt;&lt;/a&gt;
&lt;h2 id=&quot;谈到-options-请求，不得不说的就是-cors（跨域资源共享）&quot;&gt;&lt;a href=&quot;#谈到-options-请求，不得不说的就是-cors（跨域资源共享）&quot; class=&quot;headerlink&quot; title=&quot;谈到 options 请求，不得不说的就是 cors（跨域资源共享）&quot;&gt;&lt;/a&gt;谈到 options 请求，不得不说的就是 cors（跨域资源共享）&lt;/h2&gt;&lt;p&gt;CORS 是一种网络浏览器的技术规范，它为 Web 服务器定义了一种方式，允许网页从不同的域访问其资源。而这种访问是被同源策略所禁止的。CORS 系统定义了一种浏览器和服务器交互的方式来确定是否允许跨域请求。&lt;/p&gt;
&lt;p&gt;使用 CORS 的方式非常简单，但是需要同时对前端和服务器端做相应处理。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;前端&lt;br&gt;客户端使用 XmlHttpRequest 发起 ajax 请求，当前绝大部分浏览器已经支持 cors 方式，且主流浏览器均提供了对跨域资源共享的支持。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;服务器端&lt;br&gt;如果服务器端未做任何配置，则前端发起 ajax 请求后，会得到 cors access deny，即跨域访问被拒绝。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Preflighted Requests 是 CORS 中一种透明服务器验证机制。预检请求首先需要向另外一个域名的资源发送一个 HTTP OPTIONS 请求头，其目的就是为了判断实际发送的请求是否是安全的。&lt;/p&gt;
&lt;p&gt;下面的情况需要进行预检：&lt;br&gt;&lt;img src=&quot;https://data.laoono.com/blog/date/2018-06/8f7496c3dd67cdd51497f5dd6f1500a4.jpg&quot; alt=&quot;options 请求&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;一个简单的请求如下：&quot;&gt;&lt;a href=&quot;#一个简单的请求如下：&quot; class=&quot;headerlink&quot; title=&quot;一个简单的请求如下：&quot;&gt;&lt;/a&gt;一个简单的请求如下：&lt;/h2&gt;&lt;p&gt;HTTP 方法是下列之一&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HEAD&lt;/li&gt;
&lt;li&gt;GET&lt;/li&gt;
&lt;li&gt;POST&lt;br&gt;HTTP 头包含&lt;/li&gt;
&lt;li&gt;Accept&lt;/li&gt;
&lt;li&gt;Accept-Language&lt;/li&gt;
&lt;li&gt;Content-Language&lt;/li&gt;
&lt;li&gt;Last-Event-ID&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Content-Type，但仅能是下列之一&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;application/x-www-form-urlencoded&lt;/li&gt;
&lt;li&gt;multipart/form-data&lt;/li&gt;
&lt;li&gt;text/plain&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;任何一个不满足上述要求的请求，即被认为是复杂请求。一个复杂请求不仅有包含通信内容的请求，同时也包含预请求&lt;/em&gt; （preflight request）。&lt;/p&gt;
</content>
    
    <summary type="html">
    
      request-option
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>js 动态插入脚本和插入引用外部链接脚本</title>
    <link href="https://laoona.com/post/d350326d.html"/>
    <id>https://laoona.com/post/d350326d.html</id>
    <published>2018-05-21T16:07:05.000Z</published>
    <updated>2024-07-21T05:42:21.228Z</updated>
    
    <content type="html">&lt;p&gt;在日常开发中，经常遇到 &lt;strong&gt;js 动态插入脚本&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;什么是 &lt;strong&gt;js 动态插入脚本&lt;/strong&gt; ?&lt;/p&gt;
&lt;p&gt;指的是在页面加载时不存在，但将来的某一时刻通过修改该 DOM 动态添加的脚本。和操作 HTML 元素一样。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;js 动态插入脚本&lt;/strong&gt; 也有两种方式：插入 JavaScript 代码和插入外部文件。&lt;/p&gt;
&lt;h2 id=&quot;一、直接插入-javascript-代码&quot;&gt;&lt;a href=&quot;#一、直接插入-javascript-代码&quot; class=&quot;headerlink&quot; title=&quot;一、直接插入 javascript 代码&quot;&gt;&lt;/a&gt;一、直接插入 javascript 代码&lt;/h2&gt;&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&amp;lt;script type=&lt;span class=&quot;string&quot;&gt;&#39;text/javascript&#39;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;sayHi&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    alert(&lt;span class=&quot;string&quot;&gt;&#39;hi&#39;&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;lt;&lt;span class=&quot;regexp&quot;&gt;/script&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;a id=&quot;more&quot;&gt;&lt;/a&gt;
&lt;p&gt;从逻辑上讲，下面的 DOM 代码是有效的：&lt;/p&gt;
&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; script = &lt;span class=&quot;built_in&quot;&gt;document&lt;/span&gt;.createElement(&lt;span class=&quot;string&quot;&gt;&#39;script&#39;&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;script.type = &lt;span class=&quot;string&quot;&gt;&#39;text/javascript&#39;&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;script.appendChild(&lt;span class=&quot;built_in&quot;&gt;document&lt;/span&gt;.createTextNode(&lt;span class=&quot;string&quot;&gt;&#39;function sayHi() &amp;#123;alert(&#39;&lt;/span&gt;hi&lt;span class=&quot;string&quot;&gt;&#39;);&amp;#125;&#39;&lt;/span&gt;));&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;document&lt;/span&gt;.body.appendChild(script);&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;在 Firefox、Safari、Chrome 和 Opera 中，这些 DOM 代码可以正常运行。但在 IE 中，则会导致错误。IE 将 &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; 视为一个特殊的元素，不允许 DOM 访问其子节点。不过，可以使用&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;元素的 text 属性来指定 JavaScript 代码，想下面的例子这样：&lt;/p&gt;
&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; script = &lt;span class=&quot;built_in&quot;&gt;document&lt;/span&gt;.creatElement(&lt;span class=&quot;string&quot;&gt;&#39;script&#39;&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;script.type = &lt;span class=&quot;string&quot;&gt;&#39;text/javascript&#39;&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;script.text = &lt;span class=&quot;string&quot;&gt;&#39;function sayHi() &amp;#123;alert(&#39;&lt;/span&gt;hi&lt;span class=&quot;string&quot;&gt;&#39;);&amp;#125;&#39;&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;document&lt;/span&gt;.body.appendChild(script);&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;经过修改之后的代码可以在 IE、Firefox、Opera 和 Safari3.0 中运行。Safari3.0 之前的版本虽然不能正确的支持 text 属性，但却允许使用文本节点技术来指定代码。如果需要兼容早期版本的 Safari，可以使用下列代码：&lt;/p&gt;
&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; script = &lt;span class=&quot;built_in&quot;&gt;document&lt;/span&gt;.createElement(&lt;span class=&quot;string&quot;&gt;&#39;script&#39;&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;script.type = &lt;span class=&quot;string&quot;&gt;&#39;type/javascript&#39;&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; code = &lt;span class=&quot;string&quot;&gt;&#39;function sayHi() &amp;#123;alert(&#39;&lt;/span&gt;hi&lt;span class=&quot;string&quot;&gt;&#39;);&amp;#125;&#39;&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;try&lt;/span&gt; &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    script.appendChild(&lt;span class=&quot;built_in&quot;&gt;document&lt;/span&gt;.createTextNode(code));&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125; &lt;span class=&quot;keyword&quot;&gt;catch&lt;/span&gt; (ex) &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    script.text = code;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;document&lt;/span&gt;.body.appendChild(script)&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;这里首先尝试标准的 DOM 文本节点方法，因为除了 IE（在 IE 中会导致抛出错误），所有的浏览器都支持之中方式。如果这行代码抛出了错误，那么说明是 IE，于是就必须使用 text 属性了，整个过程可以用以下函数来表示：&lt;/p&gt;
&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;unction loadScriptString(code) &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; script = &lt;span class=&quot;built_in&quot;&gt;document&lt;/span&gt;.createElement(&lt;span class=&quot;string&quot;&gt;&#39;script&#39;&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    script.type = &lt;span class=&quot;string&quot;&gt;&#39;text/javascript&#39;&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;try&lt;/span&gt; &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        script.appendChild(&lt;span class=&quot;built_in&quot;&gt;document&lt;/span&gt;.createTextNode(code));&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;#125; &lt;span class=&quot;keyword&quot;&gt;catch&lt;/span&gt; (ex) &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        script.text = code;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;built_in&quot;&gt;document&lt;/span&gt;.body.appendChild(script);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;loadScriptString(&lt;span class=&quot;string&quot;&gt;&#39;function sayHi() &amp;#123;alert(&#39;&lt;/span&gt;hi&lt;span class=&quot;string&quot;&gt;&#39;);&amp;#125;&#39;&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h2 id=&quot;二、插入引用外部文件&quot;&gt;&lt;a href=&quot;#二、插入引用外部文件&quot; class=&quot;headerlink&quot; title=&quot;二、插入引用外部文件&quot;&gt;&lt;/a&gt;二、插入引用外部文件&lt;/h2&gt;&lt;p&gt;动态加载外的外部 JavaScript 文件能够立即运行，比如下面的 &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; 元素。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;client.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;br&gt;而创建这个节点的 DOM 代码如下所示：&lt;/p&gt;
&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; script = &lt;span class=&quot;built_in&quot;&gt;document&lt;/span&gt;.createElement(&lt;span class=&quot;string&quot;&gt;&#39;script&#39;&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;script.type = &lt;span class=&quot;string&quot;&gt;&#39;text/javascript&#39;&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;script.src = &lt;span class=&quot;string&quot;&gt;&#39;client.js&#39;&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;document&lt;/span&gt;.body.appendChild(script);&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;显然这里的 DOM 如实的反映了相应的 HTML 代码。不过执行最后一行代码把 &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; 元素添加到页面之前，是不会下载外部文件的。也可以把这个元素添加到 &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; 元素中效果相同。&lt;/p&gt;
&lt;p&gt;但是怎么知道这个脚本文件加载完成了呢，因为我们有些函数需要在脚本加载完成生效后才能开始执行。&lt;/p&gt;
&lt;p&gt;经过对网络上资源的搜索，我发现在 IE 浏览器中可以使用 &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; 元素的 &lt;code&gt;onreadystatechange&lt;/code&gt; 来监控加载状态的改变，并通过判断它的 &lt;code&gt;readyState&lt;/code&gt; 是 &lt;code&gt;loaded&lt;/code&gt; 或 &lt;code&gt;complete&lt;/code&gt; 来判断脚本是否加载完成。而非 IE 浏览器可以使用 &lt;code&gt;onload&lt;/code&gt; 来直接判断脚本是否加载完成。&lt;/p&gt;
&lt;p&gt;所以一个简单的实现过程看上去是下面这样的：&lt;/p&gt;
&lt;p&gt;IE 下：&lt;/p&gt;
&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; script = &lt;span class=&quot;built_in&quot;&gt;document&lt;/span&gt;.createElement(&lt;span class=&quot;string&quot;&gt;&#39;script&#39;&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; url = &lt;span class=&quot;string&quot;&gt;&#39;http:&#39;&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;script.setAttribute(&lt;span class=&quot;string&quot;&gt;&#39;type&#39;&lt;/span&gt;,&lt;span class=&quot;string&quot;&gt;&#39;text/javascript&#39;&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;script.onreadystatechange = &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;(&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.readyState == &lt;span class=&quot;string&quot;&gt;&#39;loaded&#39;&lt;/span&gt; || &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.readyState == &lt;span class=&quot;string&quot;&gt;&#39;complete&#39;&lt;/span&gt;)&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        alert(&lt;span class=&quot;string&quot;&gt;&#39;加载成功啦！&#39;&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;script.setAttribute(&lt;span class=&quot;string&quot;&gt;&#39;src&#39;&lt;/span&gt;, url);&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;Opera、FF、Chrome 等：&lt;/p&gt;
&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; script = &lt;span class=&quot;built_in&quot;&gt;document&lt;/span&gt;.createElement(&lt;span class=&quot;string&quot;&gt;&#39;script&#39;&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; url = &lt;span class=&quot;string&quot;&gt;&#39;http&#39;&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;script.setAttribute(&lt;span class=&quot;string&quot;&gt;&#39;type&#39;&lt;/span&gt;,&lt;span class=&quot;string&quot;&gt;&#39;text/javascript&#39;&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;script.onload = &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    alert(&lt;span class=&quot;string&quot;&gt;&#39;加载成功啦！&#39;&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;script.setAttribute(&lt;span class=&quot;string&quot;&gt;&#39;src&#39;&lt;/span&gt;,url);&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;最后可以合并一个 &lt;strong&gt;js 动态插入脚本&lt;/strong&gt; 的&lt;code&gt;function&lt;/code&gt;;&lt;/p&gt;
&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;20&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;loadScript&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;url, callback&lt;/span&gt;) &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  callback = &lt;span class=&quot;keyword&quot;&gt;typeof&lt;/span&gt; callback === &lt;span class=&quot;string&quot;&gt;&#39;function&#39;&lt;/span&gt; ? callback : &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;&amp;#123;&amp;#125;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; head = &lt;span class=&quot;built_in&quot;&gt;document&lt;/span&gt;.getElementsByTagName(&lt;span class=&quot;string&quot;&gt;&#39;head&#39;&lt;/span&gt;)[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;];&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; script = &lt;span class=&quot;built_in&quot;&gt;document&lt;/span&gt;.createElement(&lt;span class=&quot;string&quot;&gt;&#39;script&#39;&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  script.type = &lt;span class=&quot;string&quot;&gt;&#39;text/javascript&#39;&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  script.src = url;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (script.readyState) &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    script.onreadystatechange = &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;      &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;(&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.readyState == &lt;span class=&quot;string&quot;&gt;&#39;loaded&#39;&lt;/span&gt; || &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.readyState == &lt;span class=&quot;string&quot;&gt;&#39;complete&#39;&lt;/span&gt;)&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        callback();&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;      &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &amp;#125; &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    script.onload = callback;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  head.appendChild(script);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
</content>
    
    <summary type="html">
    
      js-load
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>node 版本管理-nvm</title>
    <link href="https://laoona.com/post/a15455ed.html"/>
    <id>https://laoona.com/post/a15455ed.html</id>
    <published>2018-05-18T16:05:33.000Z</published>
    <updated>2024-07-21T05:42:21.228Z</updated>
    
    <content type="html">&lt;p&gt;node.js 一个奇葩的版本帝，曾经也为了跟上 &lt;strong&gt;node 版本管理&lt;/strong&gt; 发布的步伐。每一次 node 版本的发布，都重新源码编译安装一次。而且每次编译安装 &lt;strong&gt;node 版本管理&lt;/strong&gt; 之后全局安装的 npm 包命令，会全部失效。&lt;/p&gt;
&lt;a id=&quot;more&quot;&gt;&lt;/a&gt;
&lt;p&gt;原因：源码安装包的路径是相同的位置，新安装的 node.js 重写覆盖了 lib/node_modules 目录。&lt;/p&gt;
&lt;p&gt;如果切换之前的 node 版本环境，该怎么办？第一想到的是：每次安装 node.js 到不同的路径。这样虽然保留了 node 版本，但系统存在 node 命令，应该指向哪个版本呢？&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;ln -s /usr/bin/node /usr/&lt;span class=&quot;built_in&quot;&gt;local&lt;/span&gt;/node-4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# or&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;ln -s /usr/bin/node /usr/&lt;span class=&quot;built_in&quot;&gt;local&lt;/span&gt;/node-6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# or&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;ln -s /usr/bin/node /usr/&lt;span class=&quot;built_in&quot;&gt;local&lt;/span&gt;/node-8&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;这样切换环境，非常不方便。&lt;/p&gt;
&lt;p&gt;直到有一天，遇到 nvm-&lt;strong&gt;node 版本管理&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;nvm 是一个独立软件包，在类 unix 的操作系统下，安装命令：&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;curl -o- &lt;a href=&quot;https://raw.githubusercontent.com/creationix/nvm/v0.29.0/install.sh&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;https://raw.githubusercontent.com/creationix/nvm/v0.29.0/install.sh&lt;/a&gt; | bash&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;mac os 还可以使用 Homebrew 来安装&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在安装的时候，nvm 将不同的 node 版本存储到 ~/.nvm// 下，然后修改 $PATH，将指定版本的 node 路径加入，这样我们调用的 node 命令即是使用指定版本的 node。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;nvm 显然比 n 要复杂一些，但是另一方面，由于它是一个独立软件包，因此它和 node 之间的关系看上去更合乎逻辑：nvm 不依赖 node 环境，是 node 依赖 nvm；而不像 n 那样产生类似循环依赖的问题。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;node 版本管理&lt;/strong&gt; 常用操作：&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;nvm list &lt;span class=&quot;comment&quot;&gt;# 显示已经安装的 node 版本&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;nvm install v0.10.32 &lt;span class=&quot;comment&quot;&gt;# 安装 v0.10.32&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;nvm run 0.10.32 app.js &lt;span class=&quot;comment&quot;&gt;# 使用 0.10.32 这个版本的 node，执行 app.js&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;nvm use 0.10.32 &lt;span class=&quot;comment&quot;&gt;# 切换当前 node 版本到 0.10.32，以后在当前窗口使用 node 执行的脚本的版本，都是 0.10.32。&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;nvm &lt;span class=&quot;built_in&quot;&gt;alias&lt;/span&gt; default 0.10.32 &lt;span class=&quot;comment&quot;&gt;# 把 0.10.32 作为 node 的默认版本，开机，新建终端窗口的 node 版本都会是 0.10.32&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;&lt;strong&gt;node 版本管理&lt;/strong&gt; 示例：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://data.laoono.com/blog/date/2018-05/8f91b04a6c7db63ee8fc6c78da7c8fef.png&quot; alt=&quot;node 版本管理&quot;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;-&amp;gt; 代表着当前使用的 node 版本&lt;/p&gt;
&lt;/blockquote&gt;
</content>
    
    <summary type="html">
    
      nvm
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>react 组件间信息传递方式</title>
    <link href="https://laoona.com/post/4144e843.html"/>
    <id>https://laoona.com/post/4144e843.html</id>
    <published>2018-05-15T15:53:05.000Z</published>
    <updated>2024-07-21T05:42:21.228Z</updated>
    
    <content type="html">&lt;p&gt;谈及 React 时，就会想到一个很重要的思想，就是组件化思想。它将可以重用的部分进行组件化开发，形成一个个相对独立的组件，那么组件化后，你也会提出些疑问，组件与组件之间，将怎样进行信息的传递呢? 下面来介绍下组件之间传递信息的方法。&lt;/p&gt;
&lt;p&gt;组件之间传递信息方式，总体可分为以下 5 种：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;1.（父组件）向（子组件）传递信息&lt;br&gt;2.（父组件）向更深层的（子组件） 进行传递信息 &amp;gt;&amp;gt; 利用（context）&lt;br&gt;3.（子组件）向（父组件）传递信息&lt;br&gt;4. 没有任何嵌套关系的组件之间传值（比如：兄弟组件之间传值）&lt;br&gt;5. 利用 react-redux 进行组件之间的状态信息共享&lt;/p&gt;
&lt;/blockquote&gt;
&lt;a id=&quot;more&quot;&gt;&lt;/a&gt;
&lt;p&gt;下面结合实例详细说明种传递信息的方式。&lt;/p&gt;
&lt;p&gt;以下的例子都是比较经典的例子，看过后加入了我的个人见解，希望对你们有所帮助。&lt;/p&gt;
&lt;h2 id=&quot;一-（父组件）向（子组件）传递信息-gt-gt-gt-主要是通过-prop-进行传值&quot;&gt;&lt;a href=&quot;#一-（父组件）向（子组件）传递信息-gt-gt-gt-主要是通过-prop-进行传值&quot; class=&quot;headerlink&quot; title=&quot;一.（父组件）向（子组件）传递信息 &amp;gt;&amp;gt;&amp;gt; 主要是通过 prop 进行传值&quot;&gt;&lt;/a&gt;&lt;a href=&quot;# 一 -（父组件）向（子组件）传递信息 -gt-gt-gt- 主要是通过 -prop 进行传值&quot; title=&quot;一.（父组件）向（子组件）传递信息 &amp;gt;&amp;gt;&amp;gt; 主要是通过 prop 进行传值&quot;&gt;&lt;/a&gt;一.（父组件）向（子组件）传递信息 &amp;gt;&amp;gt;&amp;gt; 主要是通过 prop 进行传值&lt;/h2&gt;&lt;figure class=&quot;highlight jsx&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;26&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;comment&quot;&gt;// 父组件  &lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; MyContainer = React.createClass(&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;attr&quot;&gt;getInitialState&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;      &lt;span class=&quot;attr&quot;&gt;checked&lt;/span&gt;: &lt;span class=&quot;literal&quot;&gt;false&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;#125;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &amp;#125;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;attr&quot;&gt;render&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; (&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;      &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;ToggleButton&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;text&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;Toggle me&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;checked&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&amp;#123;this.state.checked&amp;#125;&lt;/span&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    );&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;// 子组件  &lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; ToggleButton = React.createClass(&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;attr&quot;&gt;render&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;comment&quot;&gt;// 从（父组件）获取的值  &lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; checked = &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.props.checked,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;      text = &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.props.text;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; (&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;      &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;label&lt;/span&gt;&amp;gt;&lt;/span&gt;&amp;#123;text&amp;#125;: &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;checkbox&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;checked&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&amp;#123;checked&amp;#125;&lt;/span&gt; /&amp;gt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;label&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    );&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;)&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;以上这个例子，子组件通过 prop 拿到了 text 值以及 checked 的属性值；那么当子组件要拿到祖父级组件的信息，也是可以通过 prop 进行逐层的获取。来看下下面的例子。&lt;/p&gt;
&lt;p&gt;官方文档的示例代码如下:&lt;br&gt;&lt;figure class=&quot;highlight jsx&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;27&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;28&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;29&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;30&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; Button = React.createClass(&amp;#123;  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attr&quot;&gt;render&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;&amp;#123;  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; (&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;utton&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;style&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&amp;#123;&amp;#123;background:&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;this.props.color&lt;/span&gt;&amp;#125;&amp;#125;&amp;gt;&lt;/span&gt;  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &amp;#123;this.props.children&amp;#125;  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;utton&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        );  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;#125;  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;);  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; Message = React.createClass(&amp;#123;  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attr&quot;&gt;render&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;&amp;#123;  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; (&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &amp;#123;this.props.text&amp;#125; &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Button&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;color&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&amp;#123;this.props.color&amp;#125;&lt;/span&gt;&amp;gt;&lt;/span&gt;Delete&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;Button&lt;/span&gt;&amp;gt;&lt;/span&gt;  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    );  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &amp;#125;  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;);  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; MessageList = React.createClass(&amp;#123;  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attr&quot;&gt;render&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;&amp;#123;  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; color = &lt;span class=&quot;string&quot;&gt;&quot;purple&quot;&lt;/span&gt;;  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; children = &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.props.messages.map(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;message&lt;/span&gt;) &lt;/span&gt;&amp;#123;  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Message&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;text&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&amp;#123;message.text&amp;#125;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;color&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&amp;#123;color&amp;#125;&lt;/span&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;;  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &amp;#125;);  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&amp;#123;children&amp;#125;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;;  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;#125;  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;);&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;以上的例子中第一层组件（MessageList）想要将 color 值传递到第三层组件（Button），通过第二层组件（Message）进行了传递。进而实现了。但是这种方式，并不是很优雅，如果传递的层级更多时，中间的层级都需要来传递，数据的传递变的更加繁琐。所以我们就会想到，是否可以”越级”获取数据。这时候就需要使用 context。能帮你 “越级” 传递数据到组件中你想传递到的深层次组件中。&lt;/p&gt;
&lt;h2 id=&quot;二-（父组件）向更深层的（子组件）-进行传递信息&quot;&gt;&lt;a href=&quot;#二-（父组件）向更深层的（子组件）-进行传递信息&quot; class=&quot;headerlink&quot; title=&quot;二.（父组件）向更深层的（子组件） 进行传递信息&quot;&gt;&lt;/a&gt;&lt;a href=&quot;# 二 -（父组件）向更深层的（子组件）- 进行传递信息&quot; title=&quot;二.（父组件）向更深层的（子组件） 进行传递信息&quot;&gt;&lt;/a&gt;二.（父组件）向更深层的（子组件） 进行传递信息&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;利用（context）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure class=&quot;highlight jsx&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;27&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;28&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;29&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;30&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;31&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;32&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;33&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;34&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;35&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;36&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;37&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;38&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;39&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;40&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; Button = React.createClass(&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;comment&quot;&gt;// 必须指定 context 的数据类型  &lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attr&quot;&gt;contextTypes&lt;/span&gt;: &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;attr&quot;&gt;color&lt;/span&gt;: React.PropTypes.string&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;#125;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attr&quot;&gt;render&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; (&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;button&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;style&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&amp;#123;&amp;#123;background:&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;this.context.color&lt;/span&gt;&amp;#125;&amp;#125;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                &amp;#123;this.props.children&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;button&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        );&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; Message = React.createClass(&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attr&quot;&gt;render&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; (&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                &amp;#123;this.props.text&amp;#125; &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Button&lt;/span&gt;&amp;gt;&lt;/span&gt;Delete&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;Button&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        );&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; MessageList = React.createClass(&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;comment&quot;&gt;// 父组件要定义 childContextTypes 和 getChildContext()   &lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attr&quot;&gt;childContextTypes&lt;/span&gt;: &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;attr&quot;&gt;color&lt;/span&gt;: React.PropTypes.string&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;#125;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attr&quot;&gt;getChildContext&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &amp;#123;&lt;span class=&quot;attr&quot;&gt;color&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;purple&quot;&lt;/span&gt;&amp;#125;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;#125;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attr&quot;&gt;render&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; children = &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.props.messages.map(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;message&lt;/span&gt;) &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Message&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;text&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&amp;#123;message.text&amp;#125;/&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &amp;#125;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&amp;#123;children&amp;#125;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;);&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;以上代码中通过添加 childContextTypes 和 getChildContext() 到 第一层组件 MessageList （ context 的提供者），React 自动向下传递数据然后在组件中的任意组件（也就是说任意子组件，在此示例代码中也就是 Button ）都能通过定义 contextTypes（必须指定 context 的数据类型） 访问 context 中的数据。这样就不需要通过第二层组件进行传递了。&lt;/p&gt;
&lt;p&gt;指定数据并要将数据传递下去的父组件要定义 childContextTypes 和 getChildContext() ；想要接收到数据的子组件 必须定义 contextTypes 来使用传递过来的 context&lt;/p&gt;
&lt;h2 id=&quot;三-（子组件）向（父组件）传递信息&quot;&gt;&lt;a href=&quot;#三-（子组件）向（父组件）传递信息&quot; class=&quot;headerlink&quot; title=&quot;三.（子组件）向（父组件）传递信息&quot;&gt;&lt;/a&gt;&lt;a href=&quot;# 三 -（子组件）向（父组件）传递信息&quot; title=&quot;三.（子组件）向（父组件）传递信息&quot;&gt;&lt;/a&gt;三.（子组件）向（父组件）传递信息&lt;/h2&gt;&lt;figure class=&quot;highlight jsx&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;27&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;28&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;29&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;30&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;31&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;32&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;33&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;34&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;35&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;36&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;37&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;38&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;39&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;40&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;41&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;42&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;43&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;44&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;45&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;46&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;47&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;48&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;49&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;50&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;51&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;52&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;53&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;// 父组件  &lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; MyContainer = React.createClass(&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attr&quot;&gt;getInitialState&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;attr&quot;&gt;checked&lt;/span&gt;: &lt;span class=&quot;literal&quot;&gt;false&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &amp;#125;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;#125;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attr&quot;&gt;onChildChanged&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;newState&lt;/span&gt;) &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.setState(&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;attr&quot;&gt;checked&lt;/span&gt;: newState&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &amp;#125;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;#125;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attr&quot;&gt;render&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; isChecked = &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.state.checked ? &lt;span class=&quot;string&quot;&gt;&#39;yes&#39;&lt;/span&gt; : &lt;span class=&quot;string&quot;&gt;&#39;no&#39;&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; (&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;Are you checked: &amp;#123;isChecked&amp;#125;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;ToggleButton&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;text&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;Toggle me&quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                              &lt;span class=&quot;attr&quot;&gt;initialChecked&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&amp;#123;this.state.checked&amp;#125;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                              &lt;span class=&quot;attr&quot;&gt;callbackParent&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&amp;#123;this.onChildChanged&amp;#125;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        );&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;// 子组件  &lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; ToggleButton = React.createClass(&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attr&quot;&gt;getInitialState&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;attr&quot;&gt;checked&lt;/span&gt;: &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.props.initialChecked&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &amp;#125;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;#125;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attr&quot;&gt;onTextChange&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; newState = !&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.state.checked;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.setState(&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;attr&quot;&gt;checked&lt;/span&gt;: newState&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &amp;#125;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;comment&quot;&gt;// 这里将子组件的信息传递给了父组件  &lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.props.callbackParent(newState);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;#125;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attr&quot;&gt;render&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;comment&quot;&gt;// 从（父组件）获取的值  &lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; text = &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.props.text;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;comment&quot;&gt;// 组件自身的状态数据  &lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; checked = &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.state.checked;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;comment&quot;&gt;//onchange 事件用于单选框与复选框改变后触发的事件。  &lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; (&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;label&lt;/span&gt;&amp;gt;&lt;/span&gt;&amp;#123;text&amp;#125;: &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;checkbox&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;checked&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&amp;#123;checked&amp;#125;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;onChange&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&amp;#123;this.onTextChange&amp;#125;/&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;label&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        );&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;);&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;以上例子中，在父组件绑定 callbackParent={this.onChildChanged}，在子组件利用 this.props.callbackParent(newState), 触发了父级的的 this.onChildChanged 方法，进而将子组件的数据（newState）传递到了父组件。&lt;br&gt;这样做其实是依赖 props 来传递事件的引用，并通过回调的方式来实现的。&lt;/p&gt;
&lt;h2 id=&quot;四-没有任何嵌套关系的组件之间传值（比如：兄弟组件之间传值）&quot;&gt;&lt;a href=&quot;#四-没有任何嵌套关系的组件之间传值（比如：兄弟组件之间传值）&quot; class=&quot;headerlink&quot; title=&quot;四. 没有任何嵌套关系的组件之间传值（比如：兄弟组件之间传值）&quot;&gt;&lt;/a&gt;&lt;a href=&quot;# 四 - 没有任何嵌套关系的组件之间传值（比如：兄弟组件之间传值）&quot; title=&quot;四. 没有任何嵌套关系的组件之间传值（比如：兄弟组件之间传值）&quot;&gt;&lt;/a&gt;四. 没有任何嵌套关系的组件之间传值（比如：兄弟组件之间传值）&lt;/h2&gt;&lt;p&gt;如果组件之间没有任何嵌套关系，组件嵌套层次比较深，我们该怎样去传递信息呢？&lt;/p&gt;
&lt;p&gt;下面来看一个例子&lt;/p&gt;
&lt;p&gt;这个例子需要引入一个 PubSubJS 库，通过这个库你可以订阅的信息，发布消息以及消息退订。&lt;br&gt;PubSubJS 具体可参考下面的内容&lt;br&gt;&lt;a href=&quot;http://blog.csdn.net/u011439689/article/details/5195599&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;http://blog.csdn.net/u011439689/article/details/5195599&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ProductSelection 和 Product 本身是没有嵌套关系的，而是兄弟层级的关系。但通过在 ProductSelection 组件中订阅一个消息，在 Product 组件中又发布了这个消息，使得两个组件又产生了联系，进行传递的信息。&lt;/p&gt;
&lt;p&gt;所以根据我个人的理解，当两个组件没有嵌套关系的时候，也要通过全局的一些事件等，让他们联系到一起，进而达到传递信息的目的。&lt;/p&gt;
&lt;h2 id=&quot;五-利用-react-redux-进行组件之间的状态信息共享&quot;&gt;&lt;a href=&quot;#五-利用-react-redux-进行组件之间的状态信息共享&quot; class=&quot;headerlink&quot; title=&quot;五. 利用 react-redux 进行组件之间的状态信息共享&quot;&gt;&lt;/a&gt;&lt;a href=&quot;# 五 - 利用 react-redux 进行组件之间的状态信息共享&quot; title=&quot;五. 利用 react-redux 进行组件之间的状态信息共享&quot;&gt;&lt;/a&gt;五. 利用 react-redux 进行组件之间的状态信息共享&lt;/h2&gt;&lt;p&gt;如果是比较大型的项目，可以使用 react-redux，这方面的资料可以参考阮一峰的网络日志。地址：&lt;br&gt;&lt;a href=&quot;http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_three_react-redux&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_three_react-redux&lt;/a&gt;&lt;/p&gt;
</content>
    
    <summary type="html">
    
      react-component-transform
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>markdown 代码高亮，支持标记语言的列表</title>
    <link href="https://laoona.com/post/cad5071f.html"/>
    <id>https://laoona.com/post/cad5071f.html</id>
    <published>2018-05-13T15:46:38.000Z</published>
    <updated>2024-07-21T05:42:21.228Z</updated>
    
    <content type="html">&lt;p&gt;在 markdown 编辑时，我们经常需要引入一段代码，此时若果代码能高亮显示，&lt;strong&gt;markdown 代码高亮&lt;/strong&gt; 界面就会非常友好。&lt;/p&gt;
&lt;p&gt;使用前：&lt;/p&gt;
&lt;p&gt;public static void main(String[] args){&lt;br&gt;System.out.println(“Hello”);&lt;br&gt;}&lt;/p&gt;
&lt;a id=&quot;more&quot;&gt;&lt;/a&gt;
&lt;p&gt;使用后：&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(String[] args)&lt;/span&gt;&lt;/span&gt;{ &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    System.out.println(“Hello”); &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;支持 &lt;strong&gt;markdown 代码高亮&lt;/strong&gt; 的标记语言列表&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;language&lt;/th&gt;
&lt;th&gt;key&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1C&lt;/td&gt;
&lt;td&gt;1c&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ActionScript&lt;/td&gt;
&lt;td&gt;actionscript&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apache&lt;/td&gt;
&lt;td&gt;apache&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AppleScript&lt;/td&gt;
&lt;td&gt;applescript&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AsciiDoc&lt;/td&gt;
&lt;td&gt;asciidoc&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AspectJ&lt;/td&gt;
&lt;td&gt;asciidoc&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AutoHotkey&lt;/td&gt;
&lt;td&gt;autohotkey&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AVR Assembler&lt;/td&gt;
&lt;td&gt;avrasm&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Axapta&lt;/td&gt;
&lt;td&gt;axapta&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bash&lt;/td&gt;
&lt;td&gt;bash&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BrainFuck&lt;/td&gt;
&lt;td&gt;brainfuck&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cap’n Proto&lt;/td&gt;
&lt;td&gt;capnproto&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Clojure REPL&lt;/td&gt;
&lt;td&gt;clojure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Clojure&lt;/td&gt;
&lt;td&gt;clojure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CMake&lt;/td&gt;
&lt;td&gt;cmake&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CoffeeScript&lt;/td&gt;
&lt;td&gt;coffeescript&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C++&lt;/td&gt;
&lt;td&gt;cpp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C#&lt;/td&gt;
&lt;td&gt;cs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CSS&lt;/td&gt;
&lt;td&gt;css&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;td&gt;d&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dart&lt;/td&gt;
&lt;td&gt;d&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delphi&lt;/td&gt;
&lt;td&gt;delphi&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Diff&lt;/td&gt;
&lt;td&gt;diff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Django&lt;/td&gt;
&lt;td&gt;django&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DOS.bat&lt;/td&gt;
&lt;td&gt;dos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dust&lt;/td&gt;
&lt;td&gt;dust&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Elixir&lt;/td&gt;
&lt;td&gt;elixir&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ERB(Embedded Ruby)&lt;/td&gt;
&lt;td&gt;erb&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Erlang REPL&lt;/td&gt;
&lt;td&gt;erlang-repl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Erlang&lt;/td&gt;
&lt;td&gt;erlang&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FIX&lt;/td&gt;
&lt;td&gt;fix&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F#&lt;/td&gt;
&lt;td&gt;fsharp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;G-code(ISO 6983)&lt;/td&gt;
&lt;td&gt;gcode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gherkin&lt;/td&gt;
&lt;td&gt;gherkin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GLSL&lt;/td&gt;
&lt;td&gt;glsl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Go&lt;/td&gt;
&lt;td&gt;go&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gradle&lt;/td&gt;
&lt;td&gt;gradle&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Groovy&lt;/td&gt;
&lt;td&gt;groovy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Haml&lt;/td&gt;
&lt;td&gt;haml&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Handlebars&lt;/td&gt;
&lt;td&gt;handlebars&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Haskell&lt;/td&gt;
&lt;td&gt;haskell&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Haxe&lt;/td&gt;
&lt;td&gt;haxe&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTML&lt;/td&gt;
&lt;td&gt;html&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP&lt;/td&gt;
&lt;td&gt;http&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ini file&lt;/td&gt;
&lt;td&gt;ini&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Java&lt;/td&gt;
&lt;td&gt;java&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JavaScript&lt;/td&gt;
&lt;td&gt;javascript&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JSON&lt;/td&gt;
&lt;td&gt;json&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lasso&lt;/td&gt;
&lt;td&gt;lasso&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Less&lt;/td&gt;
&lt;td&gt;less&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lisp&lt;/td&gt;
&lt;td&gt;lisp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LiveCode&lt;/td&gt;
&lt;td&gt;livecodeserver&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LiveScript&lt;/td&gt;
&lt;td&gt;livescript&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lua&lt;/td&gt;
&lt;td&gt;lua&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Makefile&lt;/td&gt;
&lt;td&gt;makefile&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Markdown&lt;/td&gt;
&lt;td&gt;markdown&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mathematica&lt;/td&gt;
&lt;td&gt;mathematica&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Matlab&lt;/td&gt;
&lt;td&gt;matlab&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MEL (Maya Embedded Language)&lt;/td&gt;
&lt;td&gt;mel&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mercury&lt;/td&gt;
&lt;td&gt;mercury&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mizar&lt;/td&gt;
&lt;td&gt;mizar&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monkey&lt;/td&gt;
&lt;td&gt;monkey&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nginx&lt;/td&gt;
&lt;td&gt;nginx&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nimrod&lt;/td&gt;
&lt;td&gt;nimrod&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nix&lt;/td&gt;
&lt;td&gt;nix&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NSIS&lt;/td&gt;
&lt;td&gt;nsis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Objective C&lt;/td&gt;
&lt;td&gt;objectivec&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OCaml&lt;/td&gt;
&lt;td&gt;ocaml&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Oxygene&lt;/td&gt;
&lt;td&gt;oxygene&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Parser 3&lt;/td&gt;
&lt;td&gt;parser3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Perl&lt;/td&gt;
&lt;td&gt;perl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PHP&lt;/td&gt;
&lt;td&gt;php&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PowerShell&lt;/td&gt;
&lt;td&gt;powershell&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Processing&lt;/td&gt;
&lt;td&gt;processing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python’s profiler output&lt;/td&gt;
&lt;td&gt;profile&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Protocol Buffers&lt;/td&gt;
&lt;td&gt;protobuf&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Puppet&lt;/td&gt;
&lt;td&gt;puppet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python&lt;/td&gt;
&lt;td&gt;python&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Q&lt;/td&gt;
&lt;td&gt;q&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;R&lt;/td&gt;
&lt;td&gt;r&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RenderMan RIB&lt;/td&gt;
&lt;td&gt;rib&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Roboconf&lt;/td&gt;
&lt;td&gt;roboconf&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RenderMan RSL&lt;/td&gt;
&lt;td&gt;rsl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ruby&lt;/td&gt;
&lt;td&gt;ruby&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Oracle Rules Language&lt;/td&gt;
&lt;td&gt;ruleslanguage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rust&lt;/td&gt;
&lt;td&gt;rust&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scala&lt;/td&gt;
&lt;td&gt;scala&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scheme&lt;/td&gt;
&lt;td&gt;scheme&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scilab&lt;/td&gt;
&lt;td&gt;scilab&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SCSS&lt;/td&gt;
&lt;td&gt;scss&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Smali&lt;/td&gt;
&lt;td&gt;smali&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SmallTalk&lt;/td&gt;
&lt;td&gt;smalltalk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SML&lt;/td&gt;
&lt;td&gt;sml&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SQL&lt;/td&gt;
&lt;td&gt;sql&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stata&lt;/td&gt;
&lt;td&gt;stata&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;STEP Part21(ISO 10303-21)&lt;/td&gt;
&lt;td&gt;step21&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stylus&lt;/td&gt;
&lt;td&gt;stylus&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Swift&lt;/td&gt;
&lt;td&gt;swift&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tcl&lt;/td&gt;
&lt;td&gt;tcl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tex&lt;/td&gt;
&lt;td&gt;tex&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;text&lt;/td&gt;
&lt;td&gt;text/plain&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Thrift&lt;/td&gt;
&lt;td&gt;thrift&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Twig&lt;/td&gt;
&lt;td&gt;twig&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TypeScript&lt;/td&gt;
&lt;td&gt;typescript&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vala&lt;/td&gt;
&lt;td&gt;vala&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VB.NET&lt;/td&gt;
&lt;td&gt;vbnet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VBScript in HTML&lt;/td&gt;
&lt;td&gt;vbscript-html&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VBScript&lt;/td&gt;
&lt;td&gt;vbscript&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Verilog&lt;/td&gt;
&lt;td&gt;verilog&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VHDL&lt;/td&gt;
&lt;td&gt;vhdl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vim Script&lt;/td&gt;
&lt;td&gt;vim&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Intel x86 Assembly&lt;/td&gt;
&lt;td&gt;x86asm&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;XL&lt;/td&gt;
&lt;td&gt;xl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;XML&lt;/td&gt;
&lt;td&gt;xml&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;YAML&lt;/td&gt;
&lt;td&gt;yml&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
</content>
    
    <summary type="html">
    
      markdown-highlight
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>nginx 静态资源缓存设置</title>
    <link href="https://laoona.com/post/caa0ed0.html"/>
    <id>https://laoona.com/post/caa0ed0.html</id>
    <published>2018-05-13T15:30:08.000Z</published>
    <updated>2024-07-21T05:42:21.228Z</updated>
    
    <content type="html">&lt;p&gt;&lt;strong&gt;nginx 静态资源缓存&lt;/strong&gt; 常用配置示例:&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;attribute&quot;&gt;location&lt;/span&gt; ~.*.(js|css|html|png|jpg)$ {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attribute&quot;&gt;expires&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;3d&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;下面是 &lt;strong&gt;nginx 静态资源缓存&lt;/strong&gt; 说明:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;expires 3d; // 表示缓存 3 天&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;expires 3h; // 表示缓存 3 小时&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;expires max; // 表示缓存 10 年&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;expires -1; // 表示永远过期。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;a id=&quot;more&quot;&gt;&lt;/a&gt;
&lt;blockquote&gt;
&lt;p&gt;如果设置为 -1 在 js、css 等静态文件在没有修改的情况下返回的是 http 304.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;如果修改返回 http 200&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;http 304：自从上次请求后，请求的网页未修改过。服务器返回此响应时，不会返回网页内容。&lt;/p&gt;
&lt;p&gt;http 200：服务器已成功处理了请求，这表示服务器提供了请求的内容。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如果不想让代理或浏览器缓存，加 no-cache 参数&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;attribute&quot;&gt;location&lt;/span&gt; ~.*.(js|css|html|png|jpg)$ {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attribute&quot;&gt;add_header&lt;/span&gt; Cache-Control &lt;span class=&quot;literal&quot;&gt;no&lt;/span&gt;-cache;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;这样浏览器 F5 刷新时，&lt;strong&gt;nginx 静态资源缓存&lt;/strong&gt; 设置返回的状态码就是 http 200，而不是 http 304&lt;/p&gt;
</content>
    
    <summary type="html">
    
      nginx-static-expire
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>如何在非空目录下 git clone 项目</title>
    <link href="https://laoona.com/post/ed3b06d.html"/>
    <id>https://laoona.com/post/ed3b06d.html</id>
    <published>2018-05-13T15:23:34.000Z</published>
    <updated>2024-07-21T05:42:21.224Z</updated>
    
    <content type="html">&lt;p&gt;有时我们需要在 &lt;strong&gt;非空目录&lt;/strong&gt; 下, clone 一个 git 仓库。当执行 git clone 项目时会提示下面的错误信息：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;fatal: destination path ‘.’ already exists and is not an empty directory.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;解决办法：&quot;&gt;&lt;a href=&quot;#解决办法：&quot; class=&quot;headerlink&quot; title=&quot;解决办法：&quot;&gt;&lt;/a&gt;&lt;a href=&quot;# 解决办法：&quot; title=&quot;解决办法：&quot;&gt;&lt;/a&gt;解决办法：&lt;/h2&gt;&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;进入非空目录，假设是 /dir/test&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;cd&lt;/span&gt; /dir/&lt;span class=&quot;built_in&quot;&gt;test&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;blockquote&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;执行命令&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;git &lt;span class=&quot;built_in&quot;&gt;clone&lt;/span&gt; –no-checkout https://git.com/test.git tmp&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;blockquote&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;执行命令&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;mv tmp/.git .&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;blockquote&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;执行命令&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;rmdir tmp&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;blockquote&gt;
&lt;ol start=&quot;5&quot;&gt;
&lt;li&gt;执行命令&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;git reset –hard HEAD&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
</content>
    
    <summary type="html">
    
      git-clone-empty-directory
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>webpack4- 用之初体验（下）</title>
    <link href="https://laoona.com/post/7d2dece.html"/>
    <id>https://laoona.com/post/7d2dece.html</id>
    <published>2018-05-12T15:23:07.000Z</published>
    <updated>2024-07-21T05:42:21.228Z</updated>
    
    <content type="html">&lt;h2 id=&quot;引用字体图片和-svg-图片&quot;&gt;&lt;a href=&quot;#引用字体图片和-svg-图片&quot; class=&quot;headerlink&quot; title=&quot;引用字体图片和 svg 图片&quot;&gt;&lt;/a&gt;&lt;a href=&quot;# 引用字体图片和 svg 图片&quot; title=&quot;引用字体图片和 svg 图片&quot;&gt;&lt;/a&gt;引用字体图片和 svg 图片&lt;/h2&gt;&lt;p&gt;字体图标和 svg 图片都可以通过 file-loader 来解析&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;.exports = {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;: {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        rules: [&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                test: &lt;span class=&quot;regexp&quot;&gt;/.(eot|ttf|woff|svg)$/&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                use: &lt;span class=&quot;string&quot;&gt;‘file-loader’&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            }&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        ]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    }&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;a id=&quot;more&quot;&gt;&lt;/a&gt;
&lt;p&gt;这样即使样式中引入了这类格式的图标或者图片都没有问题了，img 如果也引用 svg 格式的话，配合上面写好的 html-withimg-loader 就都没有问题了&lt;/p&gt;
&lt;h2 id=&quot;添加-CSS3-前缀&quot;&gt;&lt;a href=&quot;#添加-CSS3-前缀&quot; class=&quot;headerlink&quot; title=&quot;添加 CSS3 前缀&quot;&gt;&lt;/a&gt;&lt;a href=&quot;# 添加 CSS3 前缀&quot; title=&quot;添加 CSS3 前缀&quot;&gt;&lt;/a&gt;添加 CSS3 前缀&lt;/h2&gt;&lt;p&gt;通过 postcss 中的 autoprefixer 可以实现将 CSS3 中的一些需要兼容写法的属性添加响应的前缀，这样省去我们不少的时间&lt;/p&gt;
&lt;p&gt;由于也是一个 loader 加载器，我们也需要先安装一下&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;npm i postcss-loader autoprefixer -D&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;安装后，我们还需要像 webpack 一样写一个 config 的配置文件，在项目根目录下创建一个 postcss.config.js 文件，配置如下：&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;.exports = {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    plugins: [&lt;span class=&quot;built_in&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;‘autoprefixer’&lt;/span&gt;)]  &lt;span class=&quot;comment&quot;&gt;// 引用该插件即可了&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;然后在 webpack 里配置 postcss-loader&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;.exports = {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;: {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        rules: [&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                test: &lt;span class=&quot;regexp&quot;&gt;/.css$/&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                use: [&lt;span class=&quot;string&quot;&gt;‘style-loader’&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;‘css-loader’&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;‘postcss-loader’&lt;/span&gt;]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            }&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        ]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    }&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;h2 id=&quot;转义-ES6&quot;&gt;&lt;a href=&quot;#转义-ES6&quot; class=&quot;headerlink&quot; title=&quot;转义 ES6&quot;&gt;&lt;/a&gt;&lt;a href=&quot;# 转义 ES6&quot; title=&quot;转义 ES6&quot;&gt;&lt;/a&gt;转义 ES6&lt;/h2&gt;&lt;p&gt;在实际开发中，我们在大量的使用着 ES6 及之后的 api 去写代码，这样会提高我们写代码的速度，不过由于低版本浏览器的存在，不得不需要转换成兼容的代码，于是就有了常用的 Babel 了&lt;/p&gt;
&lt;p&gt;Babel 会将 ES6 的代码转成 ES5 的代码&lt;/p&gt;
&lt;p&gt;那么不再多说，既然要使用它，就先来安一下&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;npm i babel-core babel-loader babel-preset-env babel-preset-stage-0 -D&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;当把这些都安好后，我们就开始配置，由于要兼容的代码不仅仅包含 ES6 还有之后的版本和那些仅仅是草案的内容，所以我们可以通过一个.babelrc 文件来配置一下，对这些版本的支持&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;.babelrc&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;{&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attr&quot;&gt;“presets”&lt;/span&gt;: [&lt;span class=&quot;string&quot;&gt;“env”&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;“stage-0”&lt;/span&gt;]   // 从右向左解析&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/blockquote&gt;
&lt;p&gt;我们再在 webpack 里配置一下 babel-loader 既可以做到代码转成 ES5 了&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;.exports = {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;: {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        rules: [&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                test:&lt;span class=&quot;regexp&quot;&gt;/.js$/&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                use: &lt;span class=&quot;string&quot;&gt;‘babel-loader’&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                include: &lt;span class=&quot;regexp&quot;&gt;/src/&lt;/span&gt;,          &lt;span class=&quot;comment&quot;&gt;// 只转化 src 目录下的 js&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                exclude: &lt;span class=&quot;regexp&quot;&gt;/node_modules/&lt;/span&gt;  &lt;span class=&quot;comment&quot;&gt;// 排除掉 node_modules，优化打包速度&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            }&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        ]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    }&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;在我们每次 npm run build 的时候都会在 dist 目录下创建很多打好的包，如果积累过多可能也会混乱, 所以应该在每次打包之前将 dist 目录下的文件都清空，然后再把打好包的文件放进去&lt;/p&gt;
&lt;p&gt;这里提供一个 clean-webpack-plugin 插件&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;npm i clean-webpack-plugin -D&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; CleanWebpackPlugin = &lt;span class=&quot;built_in&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;‘clean-webpack-plugin’&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;.exports = {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    plugins: [&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;comment&quot;&gt;// 打包前先清空&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; CleanWebpackPlugin(&lt;span class=&quot;string&quot;&gt;‘dist’&lt;/span&gt;)  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    ]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;h2 id=&quot;启动静态服务器&quot;&gt;&lt;a href=&quot;#启动静态服务器&quot; class=&quot;headerlink&quot; title=&quot;启动静态服务器&quot;&gt;&lt;/a&gt;&lt;a href=&quot;# 启动静态服务器&quot; title=&quot;启动静态服务器&quot;&gt;&lt;/a&gt;启动静态服务器&lt;/h2&gt;&lt;p&gt;启动一个静态服务器，默认会自动刷新，就是说你对 html,css,js 文件做了修改并保存后，浏览器会默认刷新一次展现修改后的效果&lt;/p&gt;
&lt;p&gt;正常情况下我们都是在开发环境中开发项目，所以之前配置的脚本”dev”可以派上用场了，在执行 npm run dev 命令后，会启动静态服务器，我们访问 localhost:3000 端口就可以看到开发的页面内容了&lt;/p&gt;
&lt;p&gt;如果 devServer 里 open 设为 true 后，会自动打开浏览器&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;.exports = {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    devServer: {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        contentBase: &lt;span class=&quot;string&quot;&gt;‘./dist’&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        host: &lt;span class=&quot;string&quot;&gt;‘localhost’&lt;/span&gt;,      &lt;span class=&quot;comment&quot;&gt;// 默认是 localhost&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        port: &lt;span class=&quot;number&quot;&gt;3000&lt;/span&gt;,             &lt;span class=&quot;comment&quot;&gt;// 端口&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        open: &lt;span class=&quot;literal&quot;&gt;true&lt;/span&gt;,             &lt;span class=&quot;comment&quot;&gt;// 自动打开浏览器&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        hot: &lt;span class=&quot;literal&quot;&gt;true&lt;/span&gt;               &lt;span class=&quot;comment&quot;&gt;// 开启热更新&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    }&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;当然在 npm run dev 命令下，打包的文件存在于内存中，并不会产生在 dist 目录下&lt;br&gt;热更新和自动刷新的区别&lt;/p&gt;
&lt;p&gt;在配置 devServer 的时候，如果 hot 为 true，就代表开启了热更新,&lt;br&gt;But 这并没那么简单，因为热更新还需要配置一个 webpack 自带的插件并且还要在主要 js 文件里检查是否有 module.hot&lt;/p&gt;
&lt;p&gt;下面就让我们直接看下代码是如何实现的&lt;/p&gt;
&lt;p&gt;// webpack.config.js&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; webpack = &lt;span class=&quot;built_in&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;‘webpack’&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;.exports = {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    plugins: [&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;comment&quot;&gt;// 热更新，热更新不是刷新&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; webpack.HotModuleReplacementPlugin()&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    ],&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    devServer: {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        contentBase: &lt;span class=&quot;string&quot;&gt;‘./dist’&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        hot: &lt;span class=&quot;literal&quot;&gt;true&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        port: &lt;span class=&quot;number&quot;&gt;3000&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    }&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;blockquote&gt;
&lt;p&gt;此时还没完虽然配置了插件和开启了热更新，但实际上并不会生效&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;// index.js&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; a = &lt;span class=&quot;string&quot;&gt;‘hello world’&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;document&lt;/span&gt;.body.innerHTML = a;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log(&lt;span class=&quot;string&quot;&gt;‘这是 webpack 打包的入口文件’&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;// 还需要在主要的 js 文件里写入下面这段代码&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;.hot) {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;comment&quot;&gt;// 实现热更新&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;.hot.accept();&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;以上 index.js 中的内容，如果将变量 a 的值进行修改保存后，会在不刷新页面的情况下直接修改掉，这样就实现了热更新&lt;/p&gt;
&lt;p&gt;那么热更新从现在看来和自动刷新浏览器的区别也不是太大嘛！自动刷新也是可以接受的啊&lt;/p&gt;
&lt;p&gt;其实不然，热更新的好处可能在 vue 或者 react 中有更大的发挥，其中某一个组件被修改的时候就会针对这个组件进行热更新了，这里用到 vue 或 react 的同学去实际体验一下吧&lt;/p&gt;
&lt;p&gt;resolve 解析&lt;/p&gt;
&lt;p&gt;在 webpack 的配置中，resolve 我们常用来配置别名和省略后缀名&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;.exports = {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    resolve: {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;comment&quot;&gt;// 别名&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        alias: {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            $: &lt;span class=&quot;string&quot;&gt;‘./src/jquery.js’&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        },&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;comment&quot;&gt;// 省略后缀&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        extensions: [&lt;span class=&quot;string&quot;&gt;‘.js’&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;‘.json’&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;‘.css’&lt;/span&gt;]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    },&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;这个配置在 webpack 中比较简单，我们也就不再叙述了，下面来看点干货&lt;/p&gt;
&lt;h2 id=&quot;提取公共代码&quot;&gt;&lt;a href=&quot;#提取公共代码&quot; class=&quot;headerlink&quot; title=&quot;提取公共代码&quot;&gt;&lt;/a&gt;&lt;a href=&quot;# 提取公共代码&quot; title=&quot;提取公共代码&quot;&gt;&lt;/a&gt;提取公共代码&lt;/h2&gt;&lt;p&gt;在 webpack4 之前，提取公共代码都是通过一个叫 CommonsChunkPlugin 的插件来办到的。到了 4 以后，内置了一个一模一样的功能，而且起了一个好听的名字叫“优化”&lt;/p&gt;
&lt;p&gt;下面我们就来看看如何提取公共代码&lt;br&gt;// 假设 a.js 和 b.js 都同时引入了 jquery.js 和一个写好的 utils.js&lt;br&gt;// a.js 和 b.js&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; $ &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;‘jquery’&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; {sum} &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;‘utils’&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;那么他们两个 js 中其中公共部分的代码就是 jquery 和 utils 里的代码了&lt;br&gt;可以针对第三方插件和写好的公共文件&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;27&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;28&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;29&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;30&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;31&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;32&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;33&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;34&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;35&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;36&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;37&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;38&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;39&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;40&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;.exports = {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    entry: {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        a: &lt;span class=&quot;string&quot;&gt;‘./src/a.js’&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        b: &lt;span class=&quot;string&quot;&gt;‘./src/b.js’&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    },&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    output: {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        filename: &lt;span class=&quot;string&quot;&gt;‘[name].js’&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        path: path.resolve(&lt;span class=&quot;string&quot;&gt;‘dust’&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    },&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;comment&quot;&gt;// 提取公共代码&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;   optimization: {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        splitChunks: {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            cacheGroups: {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                vendor: {   &lt;span class=&quot;comment&quot;&gt;// 抽离第三方插件&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                    test: &lt;span class=&quot;regexp&quot;&gt;/node_modules/&lt;/span&gt;,   &lt;span class=&quot;comment&quot;&gt;// 指定是 node_modules 下的第三方包&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                    chunks: &lt;span class=&quot;string&quot;&gt;‘initial’&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                    name: &lt;span class=&quot;string&quot;&gt;‘vendor’&lt;/span&gt;,  &lt;span class=&quot;comment&quot;&gt;// 打包后的文件名，任意命名    &lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                    &lt;span class=&quot;comment&quot;&gt;// 设置优先级，防止和自定义的公共代码提取时被覆盖，不进行打包&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                    priority: &lt;span class=&quot;number&quot;&gt;10&lt;/span&gt;    &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                },&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                utils: { &lt;span class=&quot;comment&quot;&gt;// 抽离自己写的公共代码，utils 这个名字可以随意起&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                    chunks: &lt;span class=&quot;string&quot;&gt;‘initial’&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                    name: &lt;span class=&quot;string&quot;&gt;‘utils’&lt;/span&gt;,  &lt;span class=&quot;comment&quot;&gt;// 任意命名&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                    minSize: &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;    &lt;span class=&quot;comment&quot;&gt;// 只要超出 0 字节就生成一个新包&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                }&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            }&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        }&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    },&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    plugins: [&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; HtmlWebpackPlugin({&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        filename: &lt;span class=&quot;string&quot;&gt;‘a.html’&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        template: &lt;span class=&quot;string&quot;&gt;‘./src/index.html’&lt;/span&gt;,  &lt;span class=&quot;comment&quot;&gt;// 以 index.html 为模板&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        chunks: [&lt;span class=&quot;string&quot;&gt;‘vendor’&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;‘a’&lt;/span&gt;]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    }),&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; HtmlWebpackPlugin({&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        filename: &lt;span class=&quot;string&quot;&gt;‘b.html’&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        template: &lt;span class=&quot;string&quot;&gt;‘./src/index.html’&lt;/span&gt;,  &lt;span class=&quot;comment&quot;&gt;// 以 index.html 为模板&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        chunks: [&lt;span class=&quot;string&quot;&gt;‘vendor’&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;‘b’&lt;/span&gt;]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    })]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;通过以上配置，可以把引入到 a.js 和 b.js 中的这部分公共代码提取出来&lt;/p&gt;
</content>
    
    <summary type="html">
    
      webpack4-0-1
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>webpack4- 用之初体验（上）</title>
    <link href="https://laoona.com/post/bf6eb9ab.html"/>
    <id>https://laoona.com/post/bf6eb9ab.html</id>
    <published>2018-05-12T15:18:30.000Z</published>
    <updated>2024-07-21T05:42:21.228Z</updated>
    
    <content type="html">&lt;p&gt;众所周知，webpack 进入第 4 个大版本已经有 2 个月的时间了，而且 webpack 团队升级更新的速度也是非常的惊人&lt;/p&gt;
&lt;p&gt;在写下如下内容的时候 webpack 已经出到了 4.6 的版本了，剑指 5.0 应该是指日可待了，当然这些都是个人的臆想，并不代表任何意见&lt;/p&gt;
&lt;a id=&quot;more&quot;&gt;&lt;/a&gt;
&lt;p&gt;既然我们已经迎接了 webpack4 的到来了，那么就一起来使用一下，即使你没用过之前的版本，没关系，我们重新出发，将工作中常用到的配置写给大家来看&lt;/p&gt;
&lt;p&gt;非友情提示：由于 webpack 使用起来并不能仅看代码就方便理解，所以有图有真相的才是正解，于是乎本文配图很多，真的是很多&lt;/p&gt;
&lt;p&gt;首先，既来之，则安之&lt;/p&gt;
&lt;h2 id=&quot;安装-webpack&quot;&gt;&lt;a href=&quot;#安装-webpack&quot; class=&quot;headerlink&quot; title=&quot;安装 webpack&quot;&gt;&lt;/a&gt;&lt;a href=&quot;# 安装 webpack&quot; title=&quot;安装 webpack&quot;&gt;&lt;/a&gt;安装 webpack&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;需要先在项目中 npm init 初始化一下，生成 package.json&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;建议 node 版本安装到 8.2 以上&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;webpack4 中除了正常安装 webpack 之外，需要再单独安一个 webpack-cli&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;npm i webpack webpack-cli -D&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;★ npm i -D 是 npm install –save-dev 的简写，是指安装模块并保存到 package.json 的 devDependencies 中，主要在开发环境中的依赖包&lt;/p&gt;
&lt;h2 id=&quot;0-配置了什么&quot;&gt;&lt;a href=&quot;#0-配置了什么&quot; class=&quot;headerlink&quot; title=&quot;0 配置了什么&quot;&gt;&lt;/a&gt;&lt;a href=&quot;#0 配置了什么&quot; title=&quot;0 配置了什么&quot;&gt;&lt;/a&gt;0 配置了什么&lt;/h2&gt;&lt;p&gt;webpack4 可以支持 0 配置打包，这里所说的 0 配置又是什么呢？当然在开发者眼中 0 配置的东西，那根本是无法用的，因为不够智能，那么我们就来看看做到了哪些 0 配置&lt;/p&gt;
&lt;p&gt;在使用 webpack 进行打包的时候，默认情况下会将 src 下的入口文件 (index.js) 进行打包&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;node v8.2 版本以后都会有一个 npx&lt;br&gt;npx 会执行 bin 里的文件&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;npx webpack     // 不设置 mode 的情况下 打包出来的文件自动压缩&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;npx webpack –mode development  // 设置 mode 为开发模式，打包后的文件不被压缩&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;当执行 npx webpack 命令的时候，webpack 会自动查找项目中 src 目录下的 index.js 文件，然后进行打包，生成一个 dist 目录并存在一个打包好的 main.js 文件&lt;br&gt;这些算是 0 配置的操作了，名字都是定义好的，不能变，想想也很鸡肋&lt;/p&gt;
&lt;p&gt;webpack 的使用还是在我们的配置方面，下面就进入我们的常规操作环节&lt;/p&gt;
&lt;p&gt;&lt;em&gt;webpack 是基于 Node 的&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;在项目下创建一个-webpack-config-js-默认，可修改-文件来配置-webpack&quot;&gt;&lt;a href=&quot;#在项目下创建一个-webpack-config-js-默认，可修改-文件来配置-webpack&quot; class=&quot;headerlink&quot; title=&quot;在项目下创建一个 webpack.config.js(默认，可修改)文件来配置 webpack&quot;&gt;&lt;/a&gt;&lt;a href=&quot;# 在项目下创建一个 webpack-config-js- 默认，可修改 - 文件来配置 webpack&quot; title=&quot;在项目下创建一个 webpack.config.js(默认，可修改)文件来配置 webpack&quot;&gt;&lt;/a&gt;在项目下创建一个 webpack.config.js(默认，可修改)文件来配置 webpack&lt;/h2&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;.exports = {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    entry: &lt;span class=&quot;string&quot;&gt;‘’&lt;/span&gt;,               &lt;span class=&quot;comment&quot;&gt;// 入口文件&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    output: {},              &lt;span class=&quot;comment&quot;&gt;// 出口文件&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;: {},              &lt;span class=&quot;comment&quot;&gt;// 处理对应模块&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    plugins: [],             &lt;span class=&quot;comment&quot;&gt;// 对应的插件&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    devServer: {},           &lt;span class=&quot;comment&quot;&gt;// 开发服务器配置&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    mode: &lt;span class=&quot;string&quot;&gt;‘development’&lt;/span&gt;      &lt;span class=&quot;comment&quot;&gt;// 模式配置&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;blockquote&gt;
&lt;p&gt;以上就是 webpack 的正常配置模块&lt;br&gt;★ 启动 devServer 需要安装一下 webpack-dev-server&lt;br&gt;npm i webpack-dev-server -D&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;按照项目的结构，我们就从 0 开始去写一下配置吧&lt;/p&gt;
&lt;p&gt;// webpack.config.js&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; path = &lt;span class=&quot;built_in&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;‘path’&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;.exports = {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    entry: &lt;span class=&quot;string&quot;&gt;‘./src/index.js’&lt;/span&gt;,    &lt;span class=&quot;comment&quot;&gt;// 入口文件&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    output: {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        filename: &lt;span class=&quot;string&quot;&gt;‘bundle.js’&lt;/span&gt;,      &lt;span class=&quot;comment&quot;&gt;// 打包后的文件名称&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        path: path.resolve(&lt;span class=&quot;string&quot;&gt;‘dist’&lt;/span&gt;)  &lt;span class=&quot;comment&quot;&gt;// 打包后的目录，必须是绝对路径&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    }&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;上面就可以说是实现了最简单的 webpack 配置了，那接下来就打包一下看看&lt;/p&gt;
&lt;h2 id=&quot;配置执行文件&quot;&gt;&lt;a href=&quot;#配置执行文件&quot; class=&quot;headerlink&quot; title=&quot;配置执行文件&quot;&gt;&lt;/a&gt;&lt;a href=&quot;# 配置执行文件&quot; title=&quot;配置执行文件&quot;&gt;&lt;/a&gt;配置执行文件&lt;/h2&gt;&lt;p&gt;工作当中我们打包编译的时候一般都执行 npm run dev 这样的命令，既然是通过 npm 执行的命令，我们就应该找到 package.json 里的执行脚本去配置一下命令，这里如下图所示&lt;/p&gt;
&lt;p&gt;npm run build 就是我们打包后的文件，这是生产环境下，上线需要的文件&lt;/p&gt;
&lt;p&gt;npm run dev 是我们开发环境下打包的文件，当然由于 devServer 帮我们把文件放到内存中了，所以并不会输出打包后的 dist 文件夹&lt;/p&gt;
&lt;p&gt;通过 npm run build 之后会生成一个 dist 目录文件夹，就和上面打包后的样子一样了&lt;br&gt;多入口文件&lt;br&gt;多个入口可以有两种实现方式进行打包&lt;/p&gt;
&lt;p&gt;一种是没有关系的但是要打包到一起去的，可以写一个数组，实现多个文件打包&lt;br&gt;另一种就是每一个文件都单独打包成一个文件的&lt;br&gt;下面就来看看这两种方式的写法&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; path = &lt;span class=&quot;built_in&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;‘path’&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;.exports = {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;comment&quot;&gt;// 1. 写成数组的方式就可以打出多入口文件，不过这里打包后的文件都合成了一个 &lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;comment&quot;&gt;// entry: [‘./src/index.js’, ‘./src/login.js’],&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;comment&quot;&gt;// 2. 真正实现多入口和多出口需要写成对象的方式&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    entry: {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        index: &lt;span class=&quot;string&quot;&gt;‘./src/index.js’&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        login: &lt;span class=&quot;string&quot;&gt;‘./src/login.js’&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    },&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    output: {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;comment&quot;&gt;// 1. filename: ‘bundle.js’,&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;comment&quot;&gt;// 2. [name] 就可以将出口文件名和入口文件名一一对应&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        filename: &lt;span class=&quot;string&quot;&gt;‘[name].js’&lt;/span&gt;,      &lt;span class=&quot;comment&quot;&gt;// 打包后会生成 index.js 和 login.js 文件&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        path: path.resolve(&lt;span class=&quot;string&quot;&gt;‘dist’&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    }&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;这时候执行 npm run build 后，会生成打包好的两个 js 文件，如图所示&lt;/p&gt;
&lt;h2 id=&quot;配置-Html-模板&quot;&gt;&lt;a href=&quot;#配置-Html-模板&quot; class=&quot;headerlink&quot; title=&quot;配置 Html 模板&quot;&gt;&lt;/a&gt;&lt;a href=&quot;# 配置 Html 模板&quot; title=&quot;配置 Html 模板&quot;&gt;&lt;/a&gt;配置 Html 模板&lt;/h2&gt;&lt;p&gt;文件都打包好了，但是我们在使用的时候不能在 dist 目录下去创建一个 html 文件，然后去引用打包后的 js 吧，这不合理，实际开发中也不会这样&lt;/p&gt;
&lt;p&gt;我们需要实现 html 打包功能，可以通过一个模板实现打包出引用好路径的 html 来, 这就需要用到一个常用的插件了，html-webpack-plugin，用之前我们来安一下它&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;npm i html-webpack-plugin -D&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;因为是个插件，所以需要在 config.js 里引用一下的&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;21&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; path = &lt;span class=&quot;built_in&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;‘path’&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;// 插件都是一个类，所以我们命名的时候尽量用大写开头&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; HtmlWebpackPlugin = &lt;span class=&quot;built_in&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;‘html-webpack-plugin’&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;.exports = {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    entry: &lt;span class=&quot;string&quot;&gt;‘./src/index.js’&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    output: {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;comment&quot;&gt;// 添加 hash 可以防止文件缓存，每次都会生成 4 位的 hash 串&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        filename: &lt;span class=&quot;string&quot;&gt;‘bundle.[hash:4].js’&lt;/span&gt;,   &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        path: path.resolve(&lt;span class=&quot;string&quot;&gt;‘dist’&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    },&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    plugins: [&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;comment&quot;&gt;// 通过 new 一下这个类来使用插件&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; HtmlWebpackPlugin({&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;comment&quot;&gt;// 用哪个 html 作为模板&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;comment&quot;&gt;// 在 src 目录下创建一个 index.html 页面当做模板来用&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            template: &lt;span class=&quot;string&quot;&gt;‘./src/index.html’&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            hash: &lt;span class=&quot;literal&quot;&gt;true&lt;/span&gt;, &lt;span class=&quot;comment&quot;&gt;// 会在打包好的 bundle.js 后面加上 hash 串&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        })&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    ]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;通过上面的配置后，我们再 npm run build 打包看一下现在是个什么样子了&lt;/p&gt;
&lt;h2 id=&quot;多页面开发，怎么配置多页面&quot;&gt;&lt;a href=&quot;#多页面开发，怎么配置多页面&quot; class=&quot;headerlink&quot; title=&quot;多页面开发，怎么配置多页面&quot;&gt;&lt;/a&gt;&lt;a href=&quot;# 多页面开发，怎么配置多页面&quot; title=&quot;多页面开发，怎么配置多页面&quot;&gt;&lt;/a&gt;多页面开发，怎么配置多页面&lt;/h2&gt;&lt;p&gt;如果开发的时候不只一个页面，我们需要配置多页面，那么需要怎么来搞呢？不用担心，html-webpack-plugin 插件自有办法，我们来观望一下&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;27&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; path = &lt;span class=&quot;built_in&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;‘path’&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; HtmlWebpackPlugin = &lt;span class=&quot;built_in&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;‘html-webpack-plugin’&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;.exports = {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;comment&quot;&gt;// 多页面开发，怎么配置多页面&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    entry: {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        index: &lt;span class=&quot;string&quot;&gt;‘./src/index.js’&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        login: &lt;span class=&quot;string&quot;&gt;‘./src/login.js’&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    },&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;comment&quot;&gt;// 出口文件  &lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    output: {                       &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        filename: &lt;span class=&quot;string&quot;&gt;‘[name].js’&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        path: path.resolve(&lt;span class=&quot;string&quot;&gt;‘dist’&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    },&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    plugins: [&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; HtmlWebpackPlugin({&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            template: &lt;span class=&quot;string&quot;&gt;‘./src/index.html’&lt;/span&gt;,   &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            filename: &lt;span class=&quot;string&quot;&gt;‘index.html’&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            chunks: [&lt;span class=&quot;string&quot;&gt;‘index’&lt;/span&gt;]   &lt;span class=&quot;comment&quot;&gt;// 对应关系,index.js 对应的是 index.html&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        }),&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; HtmlWebpackPlugin({&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            template: &lt;span class=&quot;string&quot;&gt;‘./src/login.html’&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            filename: &lt;span class=&quot;string&quot;&gt;‘login.html’&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            chunks: [&lt;span class=&quot;string&quot;&gt;‘login’&lt;/span&gt;]   &lt;span class=&quot;comment&quot;&gt;// 对应关系,login.js 对应的是 login.html&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        })&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    ]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;h2 id=&quot;继续-npm-run-build-看打包后的样子&quot;&gt;&lt;a href=&quot;#继续-npm-run-build-看打包后的样子&quot; class=&quot;headerlink&quot; title=&quot;继续 npm run build 看打包后的样子&quot;&gt;&lt;/a&gt;&lt;a href=&quot;# 继续 npm-run-build 看打包后的样子&quot; title=&quot;继续 npm run build 看打包后的样子&quot;&gt;&lt;/a&gt;继续 npm run build 看打包后的样子&lt;/h2&gt;&lt;p&gt;上面基本介绍完了 html 和 js 的打包配置了，现在我们还缺一个好兄弟 css，webpack 对 css 的解析需要用到 loader，所以我们先提前安装好，待会好方便使用&lt;/p&gt;
&lt;p&gt;&lt;em&gt;引用 CSS 文件&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;可以在 src/index.js 里引入 css 文件，到时候直接打包到生产目录下&lt;br&gt;需要下载一些解析 css 样式的 loader&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;npm i style-loader css-loader -D&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;blockquote&gt;
&lt;p&gt;引入 less 文件的话，也需要安装对应的 loader&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;npm i less less-loader -D&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/blockquote&gt;
&lt;p&gt;下面我们来看一下如何配置 css 文件的解析&lt;br&gt;// index.js&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;27&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;28&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;29&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;30&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;‘./css/style.css’&lt;/span&gt;;   &lt;span class=&quot;comment&quot;&gt;// 引入 css&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;‘./less/style.less’&lt;/span&gt;; &lt;span class=&quot;comment&quot;&gt;// 引入 less&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log(&lt;span class=&quot;string&quot;&gt;‘这里是打包文件入口 -index.js’&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;// webpack.config.js&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;.exports = {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    entry: {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        index: &lt;span class=&quot;string&quot;&gt;‘./src/index.js’&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    },&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    output: {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        filename: &lt;span class=&quot;string&quot;&gt;‘bundle.js’&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        path: path.resolve(&lt;span class=&quot;string&quot;&gt;‘dist’&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    },&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;: {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        rules: [&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                test: &lt;span class=&quot;regexp&quot;&gt;/.css$/&lt;/span&gt;,     &lt;span class=&quot;comment&quot;&gt;// 解析 css&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                use: [&lt;span class=&quot;string&quot;&gt;‘style-loader’&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;‘css-loader’&lt;/span&gt;] &lt;span class=&quot;comment&quot;&gt;// 从右向左解析&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                &lt;span class=&quot;comment&quot;&gt;/&lt;em&gt; &lt;/em&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;                    也可以这样写，这种方式方便写一些配置参数&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;                    use: [&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;                        {loader: ‘style-loader’},&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;                        {loader: ‘css-loader’}&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;                    ]&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;                /&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            }&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        ]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    }&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;此时打包后的 css 文件是以行内样式 style 的标签写进打包后的 html 页面中，如果样式很多的话，我们更希望直接用 link 的方式引入进去，这时候需要把 css 拆分出来&lt;br&gt;extract-text-webpack-plugin 插件相信用过的人都知道它是干什么的，它的功效就在于会将打包到 js 里的 css 文件进行一个拆分&lt;/p&gt;
&lt;h2 id=&quot;拆分-CSS&quot;&gt;&lt;a href=&quot;#拆分-CSS&quot; class=&quot;headerlink&quot; title=&quot;拆分 CSS&quot;&gt;&lt;/a&gt;&lt;a href=&quot;# 拆分 CSS&quot; title=&quot;拆分 CSS&quot;&gt;&lt;/a&gt;拆分 CSS&lt;/h2&gt;&lt;p&gt;// @next 表示可以支持 webpack4 版本的插件&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;npm i extract-text-webpack-plugin@next -D&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;27&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;28&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;29&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;30&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; path = &lt;span class=&quot;built_in&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;‘path’&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; HtmlWebpackPlugin = &lt;span class=&quot;built_in&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;‘html-webpack-plugin’&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;// 拆分 css 样式的插件&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; ExtractTextWebpackPlugin = &lt;span class=&quot;built_in&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;‘extract-text-webpack-plugin’&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;.exports = {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    entry: &lt;span class=&quot;string&quot;&gt;‘./src/index.js’&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    output: {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        filaneme: &lt;span class=&quot;string&quot;&gt;‘bundle.js’&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        path: path.resolve(&lt;span class=&quot;string&quot;&gt;‘dist’&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    },&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;: {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        rules: [&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                test: &lt;span class=&quot;regexp&quot;&gt;/.css$/&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                use: ExtractTextWebpackPlugin.extract({&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                    &lt;span class=&quot;comment&quot;&gt;// 将 css 用 link 的方式引入就不再需要 style-loader 了&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                    use: &lt;span class=&quot;string&quot;&gt;‘css-loader’&lt;/span&gt;       &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                })&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            }&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        ]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    },&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    plugins: [&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; HtmlWebpackPlugin({&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            template: &lt;span class=&quot;string&quot;&gt;‘./src/index.html’&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        }),&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;comment&quot;&gt;// 拆分后会把 css 文件放到 dist 目录下的 css/style.css&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; ExtractTextWebpackPlugin(&lt;span class=&quot;string&quot;&gt;‘css/style.css’&lt;/span&gt;)  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    ]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;此时拆分完 css 后，打包的 html 页面就以 link 的方式去引入 css 了，这样很好&lt;/p&gt;
&lt;p&gt;当然大家很多都说另外一个插件也是可以办到的，那就是 mini-css-extract-plugin，是的可以说它是为 webpack4 而生的，而之所以上来就没有介绍是因为还不成熟，还有很多 bug 需要去解决的&lt;br&gt;不过既然大家都知道它，那就顺便也提一下吧&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;npm i mini-css-extract-plugin -D&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;使用起来和上面的插件是差不多的&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; MiniCssExtractPlugin = &lt;span class=&quot;built_in&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;‘mini-css-extract-plugin’&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;.exports = {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;: {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        rules: [&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                test: &lt;span class=&quot;regexp&quot;&gt;/.css$/&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                use: [MiniCssExtractPlugin.loader, &lt;span class=&quot;string&quot;&gt;‘css-loader’&lt;/span&gt;]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            }&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        ]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    },&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    plugins: [&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; MiniCssExtractPlugin({&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            filename: &lt;span class=&quot;string&quot;&gt;‘css/a.css’&lt;/span&gt;   &lt;span class=&quot;comment&quot;&gt;// 指定打包后的 css&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        })&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    ]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;h2 id=&quot;拆分成多个-css&quot;&gt;&lt;a href=&quot;#拆分成多个-css&quot; class=&quot;headerlink&quot; title=&quot;拆分成多个 css&quot;&gt;&lt;/a&gt;&lt;a href=&quot;# 拆分成多个 css&quot; title=&quot;拆分成多个 css&quot;&gt;&lt;/a&gt;拆分成多个 css&lt;/h2&gt;&lt;p&gt;这里要着重说一下上面两个插件的区别了，我个人还是建议用 extract-text-webpack-plugin 的，毕竟从之前的版本承接下来的，虽然在安包的时候需要 @next，但是还是值得信赖的&lt;/p&gt;
&lt;p&gt;而且现在的 extract-text-webpack-plugin 也支持了拆分成多个 css，而目前 mini-css-extract-plugin 还不支持此功能&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;27&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;// 正常写入的 less&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; styleLess = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; ExtractTextWebpackPlugin(&lt;span class=&quot;string&quot;&gt;‘css/style.css’&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;// reset&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; resetCss = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; ExtractTextWebpackPlugin(&lt;span class=&quot;string&quot;&gt;‘css/reset.css’&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;.exports = {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;: {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        rules: [&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                test: &lt;span class=&quot;regexp&quot;&gt;/.css$/&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                use: resetCss.extract({&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                    use: &lt;span class=&quot;string&quot;&gt;‘css-loader’&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                })&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            },&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                test: &lt;span class=&quot;regexp&quot;&gt;/.less$/&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                use: styleLess.extract({&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                    use: &lt;span class=&quot;string&quot;&gt;‘css-loader’&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                })&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            }&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        ]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    },&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    plugins: [&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        styleLess,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        resetCss&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    ]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;通过这样操作后可以打包成两个不同的 css 文件，如下图&lt;/p&gt;
&lt;h2 id=&quot;引用图片&quot;&gt;&lt;a href=&quot;#引用图片&quot; class=&quot;headerlink&quot; title=&quot;引用图片&quot;&gt;&lt;/a&gt;&lt;a href=&quot;# 引用图片&quot; title=&quot;引用图片&quot;&gt;&lt;/a&gt;引用图片&lt;/h2&gt;&lt;p&gt;处理图片方面，也需要 loader&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;npm i file-loader url-loader -D&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;如果是在 css 文件里引入的如背景图之类的图片，就需要指定一下相对路径&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;25&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;.exports = {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;: {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        rules: [&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                test: &lt;span class=&quot;regexp&quot;&gt;/.css$/&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                use: ExtractTextWebpackPlugin.extract({&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                    use: &lt;span class=&quot;string&quot;&gt;‘css-loader’&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                    publicPath: &lt;span class=&quot;string&quot;&gt;‘../‘&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                })&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            },&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                test: &lt;span class=&quot;regexp&quot;&gt;/.(jpe?g|png|gif)$/&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                use: [&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                    {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                        loader: &lt;span class=&quot;string&quot;&gt;‘url-loader’&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                        options: {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                            limit: &lt;span class=&quot;number&quot;&gt;8192&lt;/span&gt;,    &lt;span class=&quot;comment&quot;&gt;// 小于 8k 的图片自动转成 base64 格式，并且不会存在实体图片&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                            outputPath: &lt;span class=&quot;string&quot;&gt;‘images/‘&lt;/span&gt;   &lt;span class=&quot;comment&quot;&gt;// 图片打包后存放的目录&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                        }&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                    }&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                ]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            }&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        ]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    }&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;在 css 中指定了 publicPath 路径这样就可以根据相对路径引用到图片资源了.&lt;/p&gt;
&lt;h2 id=&quot;页面-img-引用图片&quot;&gt;&lt;a href=&quot;#页面-img-引用图片&quot; class=&quot;headerlink&quot; title=&quot;页面 img 引用图片&quot;&gt;&lt;/a&gt;&lt;a href=&quot;# 页面 img 引用图片&quot; title=&quot;页面 img 引用图片&quot;&gt;&lt;/a&gt;页面 img 引用图片&lt;/h2&gt;&lt;p&gt;页面中经常会用到 img 标签，img 引用的图片地址也需要一个 loader 来帮我们处理好&lt;/p&gt;
&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;npm i html-withimg-loader -D&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;.exports = {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;built_in&quot;&gt;module&lt;/span&gt;: {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        rules: [&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            {&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                test: &lt;span class=&quot;regexp&quot;&gt;/.(htm|html)$/&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                use: &lt;span class=&quot;string&quot;&gt;‘html-withimg-loader’&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            }&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        ]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    }&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;}&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;这样再打包后的 html 文件下 img 就可以正常引用图片路径了&lt;/p&gt;
&lt;p&gt;本文地址 &lt;a href=&quot;//haozigan.com/2018-05/webpack4-0.html&quot;&gt;//haozigan.com/2018-05/webpack4-0.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/tags/webpack/&quot;&gt;#webpack&lt;/a&gt;&lt;/p&gt;
</content>
    
    <summary type="html">
    
      webpack4-0
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>解决 nginx 添加 openssl 模块编译时报错问题</title>
    <link href="https://laoona.com/post/21a1b07b.html"/>
    <id>https://laoona.com/post/21a1b07b.html</id>
    <published>2018-05-09T15:05:30.000Z</published>
    <updated>2024-07-21T05:42:21.228Z</updated>
    
    <content type="html">&lt;p&gt;如题所示，报错信息如下：&lt;/p&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;/bin/sh: line 2: ./config: No such file or directory&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;make[1]: *** [/usr/&lt;span class=&quot;built_in&quot;&gt;local&lt;/span&gt;/ssl/.openssl/include/openssl/ssl.h] Error 127&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;make[1]: Leaving directory `/usr/&lt;span class=&quot;built_in&quot;&gt;local&lt;/span&gt;/src/nginx-1.9.9‘&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;make: *** [build] Error 2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;需要说明的是，我这里编译所使用的 Nginx 源码是 1.9.9 的。根据报错信息我们知道，出错是因为 Nginx 在编译时并不能在 /usr/local/ssl/.openssl/ 这个目录找到对应的文件，其实我们打开 /usr/local/ssl/ 这个目录可以发现这个目录下是没有.openssl 目录的，因此我们修改 Nginx 编译时对 openssl 的路径选择就可以解决这个问题了&lt;br&gt;&lt;a id=&quot;more&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;解决方案&quot;&gt;&lt;a href=&quot;#解决方案&quot; class=&quot;headerlink&quot; title=&quot;解决方案&quot;&gt;&lt;/a&gt;&lt;a href=&quot;# 解决方案&quot; title=&quot;解决方案&quot;&gt;&lt;/a&gt;解决方案&lt;/h2&gt;&lt;p&gt;打开 nginx 源文件下的 /usr/local/src/nginx-1.9.9/auto/lib/openssl/conf 文件：&lt;/p&gt;
&lt;p&gt;找到这么一段代码：&lt;/p&gt;
&lt;figure class=&quot;highlight plain&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;CORE_INCS=&amp;quot;$CORE_INCS $OPENSSL/.openssl/include&amp;quot;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;CORE_DEPS=&amp;quot;$CORE_DEPS $OPENSSL/.openssl/include/openssl/ssl.h&amp;quot;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;CORE_LIBS=&amp;quot;$CORE_LIBS $OPENSSL/.openssl/lib/libssl.a&amp;quot;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;CORE_LIBS=&amp;quot;$CORE_LIBS $OPENSSL/.openssl/lib/libcrypto.a&amp;quot;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;CORE_LIBS=&amp;quot;$CORE_LIBS $NGX_LIBDL&amp;quot;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;修改成以下代码：&lt;/p&gt;
&lt;figure class=&quot;highlight plain&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;CORE_INCS=&amp;quot;$CORE_INCS $OPENSSL/.openssl/include&amp;quot;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;CORE_DEPS=&amp;quot;$CORE_DEPS $OPENSSL/include/openssl/ssl.h&amp;quot;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;CORE_LIBS=&amp;quot;$CORE_LIBS $OPENSSL/lib/libssl.a&amp;quot;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;CORE_LIBS=&amp;quot;$CORE_LIBS $OPENSSL/lib/libcrypto.a&amp;quot;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;CORE_LIBS=&amp;quot;$CORE_LIBS $NGX_LIBDL&amp;quot;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;然后再进行 Nginx 的编译安装即可&lt;/p&gt;
</content>
    
    <summary type="html">
    
      nginx-openssl
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>form 表单标签的 enctype 属性的作用及应用示例介绍</title>
    <link href="https://laoona.com/post/adbaaab0.html"/>
    <id>https://laoona.com/post/adbaaab0.html</id>
    <published>2016-08-17T14:06:43.000Z</published>
    <updated>2024-07-21T05:42:21.224Z</updated>
    
    <content type="html">&lt;p&gt;enctype 是指定将数据回发到服务器时浏览器使用的编码类型，其编码类型有以下三种，下面通过示例为大家详细介绍下其具体的使用&lt;/p&gt;
&lt;h2 id=&quot;编码类型有以下三种：&quot;&gt;&lt;a href=&quot;#编码类型有以下三种：&quot; class=&quot;headerlink&quot; title=&quot;编码类型有以下三种：&quot;&gt;&lt;/a&gt;&lt;a href=&quot;# 编码类型有以下三种：&quot; title=&quot;编码类型有以下三种：&quot;&gt;&lt;/a&gt;编码类型有以下三种：&lt;/h2&gt;&lt;p&gt;application/x-www-form-urlencoded： 在发送前编码所有字符（默认）。这是标准的编码格式。&lt;br&gt;multipart/form-data： 不对字符编码，在使用包含文件上传控件的表单时，必须使用该值。&lt;br&gt;text/plain： 窗体数据以纯文本形式进行编码，其中不含任何控件或格式字符。&lt;br&gt;&lt;a id=&quot;more&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;enctype=”multipart/form-data”是上传二进制数据过去。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;为什么上传文件要设置-enctype-”multipart-form-data”&quot;&gt;&lt;a href=&quot;#为什么上传文件要设置-enctype-”multipart-form-data”&quot; class=&quot;headerlink&quot; title=&quot;为什么上传文件要设置 enctype=”multipart/form-data”&quot;&gt;&lt;/a&gt;&lt;a href=&quot;# 为什么上传文件要设置 enctype-”multipart-form-data”&quot; title=&quot;为什么上传文件要设置 enctype=”multipart/form-data”&quot;&gt;&lt;/a&gt;为什么上传文件要设置 enctype=”multipart/form-data”&lt;/h2&gt;&lt;p&gt;因为设置 enctype 为 multipart/form-data 值后，不对字符编码，则数据通过二进制的形式传送到服务器端，这时如果用 request 是无法直接获取到相应表单的值的，而应该通过 stream 流对象，将传到服务器端的二进制数据解码，从而读取数据。&lt;/p&gt;
&lt;p&gt;如果要上传文件的话，是一定要将 encotype 设置为 multipart/form-data 的。&lt;/p&gt;
</content>
    
    <summary type="html">
    
      form-enctype
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>meta标签</title>
    <link href="https://laoona.com/post/8fd588e7.html"/>
    <id>https://laoona.com/post/8fd588e7.html</id>
    <published>2016-06-06T14:03:46.000Z</published>
    <updated>2024-07-21T05:42:21.224Z</updated>
    
    <content type="html">&lt;p&gt;&lt;strong&gt;meta标签&lt;/strong&gt; 是HTML语言head区的一个辅助性标签，它位于HTML文档头部的head标记和title标记之间，它提供用户不可见的信息。它可用于浏览器（如何显示内容或重新加载页面），搜索引擎（关键词），或其他web服务。&lt;/p&gt;
&lt;h2 id=&quot;申明文档使用的字符编码&quot;&gt;&lt;a href=&quot;#申明文档使用的字符编码&quot; class=&quot;headerlink&quot; title=&quot;申明文档使用的字符编码&quot;&gt;&lt;/a&gt;申明文档使用的字符编码&lt;/h2&gt;&lt;figure class=&quot;highlight html&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;charset&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&#39;utf-8&#39;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;或者&lt;/p&gt;
&lt;figure class=&quot;highlight html&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;http-equiv&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;Content-Type&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;content&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;text/html; charset=utf-8&quot;&lt;/span&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;该 meta 标签定义了 HTML 页面所使用的字符集为 utf-8 ，就是万国码。它可以在同一页面显示中文简体、繁体及其它语言（如日文，韩文）等。当然，你也可以使用gb2312（简体中文），big5（繁体中文）等等其他字符集。&lt;/p&gt;
&lt;a id=&quot;more&quot;&gt;&lt;/a&gt;
&lt;p&gt;而目前我们一般推荐使用第一种写法，也是HTML5使用的写法。&lt;/p&gt;
&lt;h2 id=&quot;声明使用的浏览器及版本&quot;&gt;&lt;a href=&quot;#声明使用的浏览器及版本&quot; class=&quot;headerlink&quot; title=&quot;声明使用的浏览器及版本&quot;&gt;&lt;/a&gt;声明使用的浏览器及版本&lt;/h2&gt;&lt;figure class=&quot;highlight html&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;http-equiv&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;X-UA-Compatible&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;content&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;IE=edge,chrome=1&quot;&lt;/span&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;当指定的content值为IE=edge,chrome=1时，优先使用 IE 最新版本和 Chrome。假定客户端安装了Google Chrome Frame，则在IE中使用chrome的渲染引擎来渲染页面，否则，将会使用客户端IE最高的标准模式对页面进行渲染。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;还有以下几种设置方式：&lt;/em&gt;&lt;/p&gt;
&lt;figure class=&quot;highlight html&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;http-equiv&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;X-UA-Compatible&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;content&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;IE=6&quot;&lt;/span&gt; /&amp;gt;&lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;&amp;lt;!-- 使用IE6 --&amp;gt;&lt;/span&gt; &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;http-equiv&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;X-UA-Compatible&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;content&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;IE=EmulateIE7&quot;&lt;/span&gt; /&amp;gt;&lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;&amp;lt;!-- 使用IE7 --&amp;gt;&lt;/span&gt; &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;http-equiv&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;X-UA-Compatible&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;content&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;IE=8&quot;&lt;/span&gt; /&amp;gt;&lt;/span&gt;&lt;span class=&quot;comment&quot;&gt;&amp;lt;!-- 使用IE8 --&amp;gt;&lt;/span&gt; &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;http-equiv&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;X-UA-Compatible&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;content&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;IE=edge&quot;&lt;/span&gt; /&amp;gt;&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;&amp;lt;!--指示IE以目前可用的最高模式显示内容--&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h2 id=&quot;SEO优化相关&quot;&gt;&lt;a href=&quot;#SEO优化相关&quot; class=&quot;headerlink&quot; title=&quot;SEO优化相关&quot;&gt;&lt;/a&gt;SEO优化相关&lt;/h2&gt;&lt;figure class=&quot;highlight html&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;keywords&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;content&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;html5, css3, 关键字&quot;&lt;/span&gt;/&amp;gt;&lt;/span&gt;  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;description&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;content&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;不超过150个字符&quot;&lt;/span&gt; /&amp;gt;&lt;/span&gt; &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;author&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;content&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;laoona&quot;&lt;/span&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h2 id=&quot;页面重定向和刷新：content内的数字代表时间（秒），既多少时间后刷新。如果加url-则会重定向到指定网页。&quot;&gt;&lt;a href=&quot;#页面重定向和刷新：content内的数字代表时间（秒），既多少时间后刷新。如果加url-则会重定向到指定网页。&quot; class=&quot;headerlink&quot; title=&quot;页面重定向和刷新：content内的数字代表时间（秒），既多少时间后刷新。如果加url,则会重定向到指定网页。&quot;&gt;&lt;/a&gt;页面重定向和刷新：content内的数字代表时间（秒），既多少时间后刷新。如果加url,则会重定向到指定网页。&lt;/h2&gt;&lt;figure class=&quot;highlight html&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;http-equiv&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;Refresh&quot;&lt;/span&gt;  &lt;span class=&quot;attr&quot;&gt;contect&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;5;url=http://www.laoona.com&quot;&lt;/span&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;上述代码表示停留5秒钟后自动刷新跳转到URL网址&lt;a href=&quot;http://www.laoona.com。&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;http://www.laoona.com。&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;Expires网页过期时间&quot;&gt;&lt;a href=&quot;#Expires网页过期时间&quot; class=&quot;headerlink&quot; title=&quot;Expires网页过期时间&quot;&gt;&lt;/a&gt;Expires网页过期时间&lt;/h2&gt;&lt;figure class=&quot;highlight html&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;http-equiv&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;Expires&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;contect&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;Mon,12 May 2016 00:20:00 GMT&quot;&lt;/span&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;设定网页的到期时间，一旦过期则必须到服务器上重新调用，需要注意的是必须使用GMT时间格式，或直接设为0(不缓存),最好还是服务器端配置页面的缓存控制。&lt;/p&gt;
&lt;h2 id=&quot;Pragma禁止本地缓存&quot;&gt;&lt;a href=&quot;#Pragma禁止本地缓存&quot; class=&quot;headerlink&quot; title=&quot;Pragma禁止本地缓存&quot;&gt;&lt;/a&gt;Pragma禁止本地缓存&lt;/h2&gt;&lt;figure class=&quot;highlight html&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;http-equiv&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;Pragma&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;contect&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;no-cache&quot;&lt;/span&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;设定网页不保存在缓存中，每次访问都刷新页面。这样设定，访问者将无法脱机浏览。&lt;/p&gt;
&lt;h2 id=&quot;viewport移动设备屏幕可视区域&quot;&gt;&lt;a href=&quot;#viewport移动设备屏幕可视区域&quot; class=&quot;headerlink&quot; title=&quot;viewport移动设备屏幕可视区域&quot;&gt;&lt;/a&gt;viewport移动设备屏幕可视区域&lt;/h2&gt;&lt;p&gt;由于移动设备屏幕宽度不同于传统 web，因此我们需要改变 viewport 值。&lt;br&gt;大部分4.7-5寸设备的viewport宽设为360px；5.5寸设备设为400px；iphone6设为375px；ipone6 plus设为414px。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;width – viewport 的宽度 （范围从 200 到 10,000，默认为 980 像素）&lt;/li&gt;
&lt;li&gt;height – viewport 的高度 （范围从 223 到 10,000 ）&lt;/li&gt;
&lt;li&gt;initial-scale – 初始的缩放比例 （范围从 &amp;gt; 0 到 10）&lt;/li&gt;
&lt;li&gt;minimum-scale – 允许用户缩放到的最小比例&lt;/li&gt;
&lt;li&gt;maximum-scale – 允许用户缩放到的最大比例&lt;/li&gt;
&lt;li&gt;user-scalable – 用户是否可以手动缩放 (no，yes)&lt;/li&gt;
&lt;/ul&gt;
&lt;figure class=&quot;highlight html&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;viewport&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;content&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no&quot;&lt;/span&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;blockquote&gt;
&lt;p&gt;强制让文档与设备的宽度保持 1:1 ；&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;文档最大的宽度比列是1.0（ initial-scale 初始刻度值和 maximum-scale 最大刻度值）；&lt;br&gt;user-scalable 定义用户是否可以手动缩放（ no 为不缩放），使页面固定设备上面的大小；&lt;br&gt;注意：实际测试中发现，有些安卓系统自带的浏览器并不支持这一条规则，能够对页面进行放大，一旦放大响应的 box 也随之放大，导致页面出现错乱问题，解决方法：定义页面的最小宽度。&lt;/p&gt;
&lt;figure class=&quot;highlight css&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;selector-tag&quot;&gt;body&lt;/span&gt; &amp;#123; &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attribute&quot;&gt;min-width&lt;/span&gt;: &lt;span class=&quot;number&quot;&gt;320px&lt;/span&gt;; &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;注意，很多人使用initial-scale=1到非响应式网站上，这会让网站以100%宽度渲染，用户需要手动移动页面或者缩放。如果和initial-scale=1同时使用user-scalable=no或maximum-scale=1，则用户将不能放大/缩小网页来看到全部的内容。&lt;/p&gt;
&lt;p&gt;对于移动设备上的meta还有以下一些设置。&lt;/p&gt;
&lt;h2 id=&quot;WebApp全屏模式：伪装app，离线应用。&quot;&gt;&lt;a href=&quot;#WebApp全屏模式：伪装app，离线应用。&quot; class=&quot;headerlink&quot; title=&quot;WebApp全屏模式：伪装app，离线应用。&quot;&gt;&lt;/a&gt;WebApp全屏模式：伪装app，离线应用。&lt;/h2&gt;&lt;figure class=&quot;highlight html&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;apple-mobile-web-app-capable&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;content&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;yes&quot;&lt;/span&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h2 id=&quot;隐藏状态栏-设置状态栏颜色：只有在开启WebApp全屏模式时才生效。content的值为default-black-black-translucent&quot;&gt;&lt;a href=&quot;#隐藏状态栏-设置状态栏颜色：只有在开启WebApp全屏模式时才生效。content的值为default-black-black-translucent&quot; class=&quot;headerlink&quot; title=&quot;隐藏状态栏/设置状态栏颜色：只有在开启WebApp全屏模式时才生效。content的值为default | black | black-translucent&quot;&gt;&lt;/a&gt;隐藏状态栏/设置状态栏颜色：只有在开启WebApp全屏模式时才生效。content的值为default | black | black-translucent&lt;/h2&gt;&lt;figure class=&quot;highlight html&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;apple-mobile-web-app-status-bar-style&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;content&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;black-translucent&quot;&lt;/span&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h2 id=&quot;添加到主屏后的标题&quot;&gt;&lt;a href=&quot;#添加到主屏后的标题&quot; class=&quot;headerlink&quot; title=&quot;添加到主屏后的标题&quot;&gt;&lt;/a&gt;添加到主屏后的标题&lt;/h2&gt;&lt;figure class=&quot;highlight html&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;apple-mobile-web-app-title&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;content&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;标题&quot;&lt;/span&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h2 id=&quot;忽略数字自动识别为电话号码-忽略识别邮箱&quot;&gt;&lt;a href=&quot;#忽略数字自动识别为电话号码-忽略识别邮箱&quot; class=&quot;headerlink&quot; title=&quot;忽略数字自动识别为电话号码/忽略识别邮箱&quot;&gt;&lt;/a&gt;忽略数字自动识别为电话号码/忽略识别邮箱&lt;/h2&gt;&lt;figure class=&quot;highlight html&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;content&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;telephone=no&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;format-detection&quot;&lt;/span&gt; /&amp;gt;&lt;/span&gt;  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;content&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;email=no&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;format-detection&quot;&lt;/span&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
</content>
    
    <summary type="html">
    
      html-meta, meta标签
    
    </summary>
    
    
      <category term="html" scheme="https://laoona.com/tags/html/"/>
    
  </entry>
  
  <entry>
    <title>nginx alias root 和 location 指向</title>
    <link href="https://laoona.com/post/23157895.html"/>
    <id>https://laoona.com/post/23157895.html</id>
    <published>2016-06-01T09:37:38.000Z</published>
    <updated>2024-07-21T05:42:21.228Z</updated>
    
    <content type="html">&lt;p&gt;虚拟服务器可拥有一个宿主目录和任意数量的其它目录，这些其它目录通常被称为虚拟目录。&lt;/p&gt;
&lt;p&gt;nginx没有虚拟目录的说法，因为nginx本来就根据目录设计并工作的。如果要把虚拟目录强硬插上一个&lt;em&gt;虚拟目录&lt;/em&gt;的说法，那只有&lt;code&gt;alias&lt;/code&gt;标签比较像。还有一个和&lt;code&gt;alias&lt;/code&gt;相似的标签&lt;code&gt;root&lt;/code&gt;，它们之间有何区别？&lt;/p&gt;
&lt;a id=&quot;more&quot;&gt;&lt;/a&gt;
&lt;h2 id=&quot;最基本的区别&quot;&gt;&lt;a href=&quot;#最基本的区别&quot; class=&quot;headerlink&quot; title=&quot;最基本的区别&quot;&gt;&lt;/a&gt;最基本的区别&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;alias 指定的目录是准确的, 作用可以理解为linux的 &lt;code&gt;ln&lt;/code&gt;，给location指定一个目录。 &lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;root 指定目录的上级目录，并且该上级目录要含有locatoin指定名称的同名目录。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;alias使用注意&quot;&gt;&lt;a href=&quot;#alias使用注意&quot; class=&quot;headerlink&quot; title=&quot;alias使用注意&quot;&gt;&lt;/a&gt;alias使用注意&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;p&gt;使用alias时，目录名后面一定要加”/“。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;使用alias标签的目录块中不能使用rewrite的break。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;alias在使用正则匹配时，必须捕捉要匹配的内容并在指定的内容处使用。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;alias只能位于location块中&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;例子&quot;&gt;&lt;a href=&quot;#例子&quot; class=&quot;headerlink&quot; title=&quot;例子&quot;&gt;&lt;/a&gt;例子&lt;/h2&gt;&lt;figure class=&quot;highlight nginx&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;attribute&quot;&gt;location&lt;/span&gt; /abc/ &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attribute&quot;&gt;alias&lt;/span&gt; /home/html/abc/;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;在这段配置下，&lt;code&gt;http://test/abc/a.html&lt;/code&gt; &lt;em&gt;就指定的是&lt;/em&gt; &lt;code&gt;/home/html/abc/a.html&lt;/code&gt;。这段配置亦可改成使用root标签：&lt;/p&gt;
&lt;figure class=&quot;highlight nginx&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;attribute&quot;&gt;location&lt;/span&gt; /abc/ &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attribute&quot;&gt;root&lt;/span&gt; /home/html/;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;这样，nginx就会去找&lt;code&gt;/home/html/&lt;/code&gt;目录下的abc目录了，得到的结果是相同的。但是，如果我把alias的配置改成&lt;/p&gt;
&lt;figure class=&quot;highlight nginx&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;attribute&quot;&gt;location&lt;/span&gt; /abc/ &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attribute&quot;&gt;alias&lt;/span&gt; /home/html/def/;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;那么nginx将会直接从&lt;code&gt;/home/html/def/&lt;/code&gt;取数据，例如访问&lt;code&gt;http://test/abc/a.html&lt;/code&gt;指向的是 &lt;code&gt;/home/html/def/a.html&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;这段配置还不能直接使用root配置，如果非要配置，只有在&lt;code&gt;/home/html/&lt;/code&gt;下建立一个 &lt;code&gt;def-&amp;gt;abc&lt;/code&gt;的软link（快捷方式）了。&lt;/p&gt;
&lt;p&gt;一般情况下，在location /中配置root，在location /other中配置alias是一个好习惯。&lt;/p&gt;
&lt;h2 id=&quot;alias-fast-cgi&quot;&gt;&lt;a href=&quot;#alias-fast-cgi&quot; class=&quot;headerlink&quot; title=&quot;alias fast-cgi&quot;&gt;&lt;/a&gt;alias fast-cgi&lt;/h2&gt;&lt;p&gt;nginx在处理php脚本时，需要传递给fastcgi才能处理，&lt;em&gt;下面是fast-cgi无法工作的配置&lt;/em&gt;&lt;/p&gt;
&lt;figure class=&quot;highlight nginx&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;section&quot;&gt;server&lt;/span&gt; &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attribute&quot;&gt;listen&lt;/span&gt;      &lt;span class=&quot;number&quot;&gt;80&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attribute&quot;&gt;server_name&lt;/span&gt;  pwta; &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attribute&quot;&gt;root&lt;/span&gt; html;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attribute&quot;&gt;location&lt;/span&gt; /test/&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;attribute&quot;&gt;alias&lt;/span&gt; html/test/;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;attribute&quot;&gt;autoindex&lt;/span&gt; &lt;span class=&quot;literal&quot;&gt;on&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attribute&quot;&gt;location&lt;/span&gt; &lt;span class=&quot;regexp&quot;&gt;~ \.php$&lt;/span&gt; &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;attribute&quot;&gt;fastcgi_pass&lt;/span&gt;   &lt;span class=&quot;number&quot;&gt;127.0.0.1:9000&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;attribute&quot;&gt;fastcgi_index&lt;/span&gt;  index.php;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;attribute&quot;&gt;fastcgi_param&lt;/span&gt;  SCRIPT_FILENAME  &lt;span class=&quot;variable&quot;&gt;$document_root&lt;/span&gt;&lt;span class=&quot;variable&quot;&gt;$fastcgi_script_name&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;attribute&quot;&gt;include&lt;/span&gt;        fastcgi_params;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;通过上面的配置， 我们发现, 访问&lt;code&gt;/test/a.php&lt;/code&gt;, php脚本并没有作用。为什么呢？答案在下面：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Adding alias will effectively overwrite the $document_root to whatever is the alias. Note that it will not affect $fastcgi_script_name or $request_filename. Using the new $document_root together with regex matching the file name, resolves to the script file&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;针对上面的配置我们要改成这样：&lt;br&gt;&lt;figure class=&quot;highlight nginx&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;24&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;section&quot;&gt;server&lt;/span&gt; &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;attribute&quot;&gt;listen&lt;/span&gt;      &lt;span class=&quot;number&quot;&gt;80&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;attribute&quot;&gt;server_name&lt;/span&gt;  pwta;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;attribute&quot;&gt;index&lt;/span&gt; index.html index.php;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;attribute&quot;&gt;root&lt;/span&gt; html;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;attribute&quot;&gt;location&lt;/span&gt; /test/ &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attribute&quot;&gt;alias&lt;/span&gt; html/test/;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;attribute&quot;&gt;location&lt;/span&gt; &lt;span class=&quot;regexp&quot;&gt;~  ^/test/(.+\.php)$&lt;/span&gt; &amp;#123; &lt;span class=&quot;comment&quot;&gt;### This location block was the solution&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attribute&quot;&gt;alias&lt;/span&gt; html/test/;     &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attribute&quot;&gt;fastcgi_pass&lt;/span&gt;   &lt;span class=&quot;number&quot;&gt;127.0.0.1:9000&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attribute&quot;&gt;fastcgi_index&lt;/span&gt;  index.php;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attribute&quot;&gt;fastcgi_param&lt;/span&gt;  SCRIPT_FILENAME  &lt;span class=&quot;variable&quot;&gt;$document_root&lt;/span&gt;&lt;span class=&quot;variable&quot;&gt;$1&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attribute&quot;&gt;include&lt;/span&gt; fastcgi_params;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt; &lt;span class=&quot;attribute&quot;&gt;location&lt;/span&gt; &lt;span class=&quot;regexp&quot;&gt;~ \.php$&lt;/span&gt; &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attribute&quot;&gt;fastcgi_pass&lt;/span&gt;   &lt;span class=&quot;number&quot;&gt;127.0.0.1:9000&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attribute&quot;&gt;fastcgi_index&lt;/span&gt;  index.php;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attribute&quot;&gt;fastcgi_param&lt;/span&gt;  SCRIPT_FILENAME  &lt;span class=&quot;variable&quot;&gt;$document_root&lt;/span&gt;&lt;span class=&quot;variable&quot;&gt;$fastcgi_script_name&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;attribute&quot;&gt;include&lt;/span&gt;        fastcgi_params;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;重启nginx，php文件解析生效&lt;/p&gt;
&lt;p&gt;参考资料&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://down.chinaz.com/server/201111/1382_1.htm&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;http://down.chinaz.com/server/201111/1382_1.htm&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;http://stackoverflow.com/questions/10084137/nginx-aliaslocation-directive&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;http://stackoverflow.com/questions/10084137/nginx-aliaslocation-directive&lt;/a&gt;&lt;/p&gt;
</content>
    
    <summary type="html">
    
      nginx没有虚拟目录的说法，因为nginx本来就根据目录设计并工作的。如果要把虚拟目录强硬插上一个*虚拟目录*的说法，那只有`alias`标签比较像。还有一个和`alias`相似的标签`root`，它们之间有何区别？
    
    </summary>
    
    
      <category term="nginx" scheme="https://laoona.com/tags/nginx/"/>
    
  </entry>
  
  <entry>
    <title>async javascript 下</title>
    <link href="https://laoona.com/post/57e96af.html"/>
    <id>https://laoona.com/post/57e96af.html</id>
    <published>2016-05-31T14:00:11.000Z</published>
    <updated>2024-07-21T05:42:21.224Z</updated>
    
    <content type="html">&lt;p&gt;接着上文：&lt;a href=&quot;/2016-05/async-javaScript.html&quot;&gt;async javaScript 上&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;JavaScript异步编程解决方案&quot;&gt;&lt;a href=&quot;#JavaScript异步编程解决方案&quot; class=&quot;headerlink&quot; title=&quot;JavaScript异步编程解决方案&quot;&gt;&lt;/a&gt;JavaScript异步编程解决方案&lt;/h2&gt;&lt;p&gt;现在主要的异步编程的方案有3种：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;PubSub模式（分布式事件）&lt;/li&gt;
&lt;li&gt;Promise对象&lt;/li&gt;
&lt;li&gt;工作流控制库&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;下面我们将逐个进行分析，在这些异步方案之前，我们经常看到所谓的&lt;em&gt;金字塔厄运&lt;/em&gt;&lt;/p&gt;
&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;asyncFunc1(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;result1&lt;/span&gt;)&lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;comment&quot;&gt;//some codes&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    asyncFunc2(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;result2&lt;/span&gt;)&lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;comment&quot;&gt;//some codes&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        asyncFunc3(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;result3&lt;/span&gt;)&lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;comment&quot;&gt;//other codes&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &amp;#125;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;#125;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;);&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;a id=&quot;more&quot;&gt;&lt;/a&gt;
&lt;p&gt;那么，我们的解决方案就是使我们能更加方便的组织异步代码，规避像上面那样的问题。&lt;/p&gt;
&lt;h2 id=&quot;PubSub模式（分布式事件）&quot;&gt;&lt;a href=&quot;#PubSub模式（分布式事件）&quot; class=&quot;headerlink&quot; title=&quot;PubSub模式（分布式事件）&quot;&gt;&lt;/a&gt;PubSub模式（分布式事件）&lt;/h2&gt;&lt;p&gt;所谓的PubSub模式其实很简单， 比如我们平时使用的&lt;code&gt;dom.addEventListener&lt;/code&gt;就是一个PubSub模式鲜活的例子。在2000年DOM Level 2发布之前， 我们可能 需要使用类似于dom.onclick的方式去绑定事件。这样很容易产生问题，如果没有分布式事件的话，我们不能：&lt;br&gt;&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;dom.onclick = eventHandler1;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;dom.onclick = eventHandler2;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;很明显，onclick只是dom的一个属性，同一个key不能对应多个value，第一个会被第二个覆盖掉，所以我们只能：&lt;/p&gt;
&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;dom.onclick = &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;)&lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    eventHandler1.apply(&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;,&lt;span class=&quot;built_in&quot;&gt;arguments&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    eventHandler1.apply(&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;,&lt;span class=&quot;built_in&quot;&gt;arguments&lt;/span&gt;);  &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;这样的坏处很多，比如不够灵活，代码冗长，不利于维护等等。&lt;/p&gt;
&lt;p&gt;现在开始学习前端，可能已经没有老师或者书籍讲解这样的用法了。&lt;code&gt;dom.addEventListener&lt;/code&gt;标准化之后，我们可以：&lt;/p&gt;
&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;dom.addEventListener(&lt;span class=&quot;string&quot;&gt;&#39;click&#39;&lt;/span&gt;,eventHandler1);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;dom.addEventListener(&lt;span class=&quot;string&quot;&gt;&#39;click&#39;&lt;/span&gt;,eventHandler2);&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;而像jquery这样的类库，也自然磨平了不同浏览器的差异，提供了类似于&lt;code&gt;$dom.on()&lt;/code&gt;的方法。如今，几乎所有的前端dom相关的类库都会提供类似的API。当然，在javascript世界的另一端，nodejs也有核心模块&lt;code&gt;Events&lt;/code&gt;提供的&lt;code&gt;EventEmitter&lt;/code&gt;对象，从而很容易实现分布式事件：&lt;/p&gt;
&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; Emitter = &lt;span class=&quot;built_in&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;&quot;events&quot;&lt;/span&gt;).EevntEmitter;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; emitter = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; Emitter();&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;emitter.on(&lt;span class=&quot;string&quot;&gt;&#39;someEvent&#39;&lt;/span&gt;,&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;stream&lt;/span&gt;)&lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log(stream + &lt;span class=&quot;string&quot;&gt;&#39;from eventHandler1&#39;&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;emitter.on(&lt;span class=&quot;string&quot;&gt;&#39;someEvent&#39;&lt;/span&gt;,&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;stream&lt;/span&gt;)&lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log(stream + &lt;span class=&quot;string&quot;&gt;&#39;from eventHandler2&#39;&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;emitter.emit(&lt;span class=&quot;string&quot;&gt;&#39;someEvent&#39;&lt;/span&gt;,&lt;span class=&quot;string&quot;&gt;&#39;I am a stream!&#39;&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;我们用DOM举例并不说明PubSub模式就是事件监听，而是因为事件监听是一个典型的分布式事件的示例，只是我们的订阅和发布依托的对象不是一个常规的对象，而且是一个浏览器的DOM对象，而在jQuery中这个对象就是jQuery对象了，下面，我们用简单的代码实现一个PubSub模式：&lt;/p&gt;
&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;21&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; PubSub = &amp;#123;&lt;span class=&quot;attr&quot;&gt;handler&lt;/span&gt;: &amp;#123;&amp;#125;&amp;#125;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;PubSub.sub = &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;evnt, handler&lt;/span&gt;) &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;   &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; handlers = &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.handlers; &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;   !(event &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; handlers) &amp;amp;&amp;amp; handlers(event) = [];&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;   handers[event].push(handler);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;PubSub.pub = &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;event&lt;/span&gt;) &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;   &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; handlers = (handlers[event] || []); &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;   &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; handlerArgs = [].slice.call(&lt;span class=&quot;built_in&quot;&gt;arguments&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;   &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt;(&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, item; item = handlers[i]; i++) &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        item.apply(&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;, handlerArgs);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;如同我们看到的，上面的代码只是一个最简单甚至不安全的实现。在生产环境中，有很多成熟的框架，比如PubSubJS这样纯粹的PubSub模式的实现。同时，从上面的实现中，我们能发现，所有的event-handler都是同步执行的，这与我们浏览器中真实点击事件的事件处理时机还是有差异的，真实的点击事件的handler会在后续的event-loop中触发，同样，我们手动的dom.click()或者jQuery的$dom.click()都是同步执行的（大家可以测试一下）。&lt;/p&gt;
&lt;p&gt;PubSub模式是大家最常用的一种方式，相对容易理解。基于这种事件化对象，实现了代码的分层次化，像大名如雷贯耳的Backbone.js也是使用了这样的技术。这是PubSub模式的好处。但是，事件不是万金油，有一些情况不适合用事件来处理，比如一些一次性转化且只有成功或者失败结果的流程，使用PubSub模式就有一些不合适。而这种情景下，Promise就显得更加适合我们。&lt;/p&gt;
&lt;h2 id=&quot;Promise对象&quot;&gt;&lt;a href=&quot;#Promise对象&quot; class=&quot;headerlink&quot; title=&quot;Promise对象&quot;&gt;&lt;/a&gt;Promise对象&lt;/h2&gt;&lt;p&gt;Promise在很多语言中都有各自的实现，而其与javascript的结缘要归功于javascript发展历史上有里程碑意义的Dojo框架。2007年Dojo的开发者Twisted的启发，为Dojo添加了一个dojo.Deferred对象。2009年，Kris Zyp在CommmonJS社区提出了Promiser/A规范。之后，风云变幻，nodejs异军突起（2010年初,nodejs 放弃了对Promise的原生支持），2011年jQuery1.5携带着叛逆的Promise实现以及崭新的ajax风火出世，从此Promise真正被javascript开发者所熟知。&lt;/p&gt;
&lt;p&gt;如今，更多的实现早已关注羽翼更加丰满的Promise/A+规范，jQuery对Promise的实现也对标准有所妥协，同时像Q.js的出现，也使得javascript世界有了通吃客户端和服务端的直观且纯粹的实现。&lt;/p&gt;
&lt;p&gt;就在不远的（2014年12月）将来，javascript发展史上有了一个重大的时刻将会到来，ES6将成为正式标准，在众多夺人眼球的特性中，对Promise的原生支持仍然不乏瞩目，如果再配以Generator将是如虎添翼。&lt;/p&gt;
&lt;p&gt;稍远的将来，ES7会提供一个async关键字引导声明的函数，支持 &lt;code&gt;await&lt;/code&gt;， 而此番花样将会如何让我们拭目以待。 &lt;/p&gt;
&lt;p&gt;CommonJS社区的Promise/A规范相对简洁，而Promise/A+规范规范对其作了一些补充，我们后面将以Promise/A+规范配以实例学习Promise。&lt;/p&gt;
&lt;p&gt;什么是Promise？Promise是一个对象，它代表异步函数的返回结果。用代码表示也就是：&lt;/p&gt;
&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; promise = asyncFunction();&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;如果具象一点，我们常见的一个jQuery的ajax调用就是这样：&lt;/p&gt;
&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; ajaxPromise = $.ajax(&lt;span class=&quot;string&quot;&gt;&#39;mydata&#39;&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;ajaxPromise.done(successFunction);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;ajaxPromise.fail(errorFunction);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;ajaxPromise.always(completeFunction);&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;从上面的代码中，我们看到jQuery返回的Promise对象拥有若干方法，比如done、fail和always分别对应了ajax成功、失败以及无论成功失败都应该执行的回调，这些方法可以看做是规范之上的具体实现带给我们的语法糖。那么，真实的Promise规范是什么样？（其实，规范相对简短，大家可以稍花时间阅读，在此我们做一下主干介绍）&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Promise的状态能且只能是下面三种的某一种：pending, fulfilled, rejected。这三种状态之间的关系：&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;pending:可以转变到fulfilled状态或者rejected状态&lt;/li&gt;
&lt;li&gt;fulfilled:不可以转变到其他任何状态，而且必须有一个不可改变的value&lt;/li&gt;
&lt;li&gt;rejected:不可以转变到其他任何状态，而且必须有一个不可改变的reason&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;关于value和reason，我们可以分别理解为fulfilled的结果和rejected的原因。&lt;/p&gt;
&lt;p&gt;Promise必须要拥有一个&lt;code&gt;then&lt;/code&gt;方法，用以访问当前或者最终的value或reason。then方法拥有两个参数，而且这两个参数都是可选的，用promise.then(onFulfilled, onRejected)。分析如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;onFulfilled: :如果不是函数，将被忽略。&lt;br&gt;如果是函数，只有且必须在promise状态转换为fulfilled之后被触发一次，并且只传递promise的value作为第一个参数。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;onRejected:如果不是函数，将被忽略。&lt;br&gt;如果是函数，只有且必须在promise状态转换为rejected之后被触发一次，并且只传递promise的reason作为第一个参数。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;tip&quot;&gt;&lt;br&gt;   另外：多次调用then绑定的回调函数，在&lt;code&gt;fulfilled&lt;/code&gt;或&lt;code&gt;rejected&lt;/code&gt;的时候，执行顺序与绑定顺序相对应。规范要求，调用需要在&lt;code&gt;then&lt;/code&gt;之后的event loop中执行。&lt;br&gt;&lt;/div&gt;

&lt;p&gt;Promise的then方法必须返回一个promise对象，以供链式调用，如果onFulfilled或者onRejected有throw，那么后生成的Promise对象应该以抛出内容为reason转化为rejected状态。&lt;/p&gt;
&lt;p&gt;在浅析Promise规范之后，我们可以完善一下本章节的第一段代码：&lt;/p&gt;
&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; promise = asyncFunction();&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;promise = promise.then(onFulfilled1, onRejected1)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                 .then(onFulfilled2, onRejected2);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;promise.then(onFulfilled3, onRejected3);&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;Promise/A规范的实现众多，在我们的实际生产中，我们应该选择哪个实现呢？这个只能说因地制宜。 &lt;/p&gt;
&lt;p&gt;当然，现在应该有很多人和我一样，期待着ES6的原生Promise实现。ES标准化的Promise看上去是这样的：&lt;/p&gt;
&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; promise = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;built_in&quot;&gt;Promise&lt;/span&gt;(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;resolve, reject&lt;/span&gt;) &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;comment&quot;&gt;// do a thing, possibly async, then…&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;comment&quot;&gt;/* everything turned out fine */&lt;/span&gt;) &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    resolve(&lt;span class=&quot;string&quot;&gt;&quot;Stuff worked!&quot;&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    reject(&lt;span class=&quot;built_in&quot;&gt;Error&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;&quot;It broke&quot;&lt;/span&gt;));&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;promise.then(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;result&lt;/span&gt;) &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log(result); &lt;span class=&quot;comment&quot;&gt;// &quot;Stuff worked!&quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;, &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;err&lt;/span&gt;) &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log(err); &lt;span class=&quot;comment&quot;&gt;// Error: &quot;It broke&quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;);&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;接下来，我们顺带提及一下Generator吧，如果你还不知道Generator是什么？看这里。简洁一点描述就是Generator函数可以通过特定的yield关键字中断函数执行，并与外界共享执行上下文。Generator函数基于这一特性，可以跟异步函数配合，等待异步函数的执行（结果），然后通过特定的接口（next）将异步结果注入到Generator自己的上下文中，然后继续执行后面的代码。&lt;/p&gt;
&lt;p&gt;这样结合后，我们便能用同步的方式书写异步代码。能与Generator配合的实现有很多，其中就有Promise对象，而express的主人TJ大神给我们提供了一个非常成熟的方案–co。个人感觉，基于Generator优化异步代码的方式会是未来的最受欢迎的方式。在此，推荐几篇比较优秀的文章，我也就不班门弄斧了。&lt;/p&gt;
&lt;p&gt;朴灵大大的还热乎的&lt;a href=&quot;http://www.infoq.com/cn/articles/generator-and-asynchronous-programming&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;Generator与异步编程&lt;/a&gt;,不知道是哪位老师的&lt;a href=&quot;http://bg.biedalian.com/2013/12/21/harmony-generator.html&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;Harmony Generator, yield, ES6, co框架学习&lt;/a&gt;,屈屈大大的&lt;a href=&quot;https://www.imququ.com/post/generator-function-in-es6.html&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;ES6中的生成器函数介绍&lt;/a&gt;。如果想学习这一“不远未来”的技术，请点击进入上述链接吧。&lt;/p&gt;
&lt;p&gt;另外，Google和Mozilla分别给了一些自己的解决方案：&lt;a href=&quot;https://github.com/google/traceur-compiler&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;traceur&lt;/a&gt; 和 &lt;a href=&quot;http://taskjs.org/&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;taskjs&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;基于Promise，我们可以实现各种串行并行的异步操作，但是，这个串行并行的控制，需要我们手动去维护，而flow-control类的方案，恰恰满足了我们这方面的需求，下面我们就从这里说起吧。&lt;/p&gt;
&lt;h2 id=&quot;工作流控制库&quot;&gt;&lt;a href=&quot;#工作流控制库&quot; class=&quot;headerlink&quot; title=&quot;工作流控制库&quot;&gt;&lt;/a&gt;工作流控制库&lt;/h2&gt;&lt;p&gt;所谓的工作流控制库（flow-control），我用自己的语言描述便是通过固有的模式（库提供相关的api）组织任务（代码/函数）的执行，从而轻松实现并行串行等需求。那么，比如我们有一个需求，需要读取三个文件，而三个文件是有顺序依赖关系的，那么我们需要做的就是顺序读取，可能代码原始是这样的：&lt;/p&gt;
&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;fs.readFile(&lt;span class=&quot;string&quot;&gt;&#39;originalFile&#39;&lt;/span&gt;,&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;err,data1&lt;/span&gt;)&lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  fs.readFile(data1,&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;err,data2&lt;/span&gt;)&lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    fs.readFile(data2,&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;err,data3&lt;/span&gt;)&lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;      &lt;span class=&quot;comment&quot;&gt;//operate with data3&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;#125;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &amp;#125;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;);&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;我们看到了一个“美丽的”金字塔。那么，如果用久负盛名的async后，会是怎么样呢？&lt;/p&gt;
&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;async&lt;/span&gt;.waterfall([&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;cb&lt;/span&gt;)&lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    fs.readFile(&lt;span class=&quot;string&quot;&gt;&#39;originalFile&#39;&lt;/span&gt;,cb);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &amp;#125;,&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;data1,cb&lt;/span&gt;)&lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    fs.readFile(data1,cb);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &amp;#125;,&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;data2,cb&lt;/span&gt;)&lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    fs.readFile(data2,cb);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;],&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;err,result&lt;/span&gt;)&lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;comment&quot;&gt;//result now equals data3 &amp;amp; operate with data3&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;);&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;而同样的需求，用极简主义的step实现，代码又是如何呢？&lt;br&gt;&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;step(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;)&lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  fs.readFile(&lt;span class=&quot;string&quot;&gt;&#39;originalFile&#39;&lt;/span&gt;,&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;,&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;err,data1&lt;/span&gt;)&lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  fs.readFile(data1,&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;,&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;err,data2&lt;/span&gt;)&lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  fs.readFile(data2,&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;,&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;err,data3&lt;/span&gt;)&lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;comment&quot;&gt;//operate with data3&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;);&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;关于原始方案异步函数嵌套异步函数，我们可以一目了然就不做解释了。下面，我们对比一下async和step两者：&lt;/p&gt;
&lt;p&gt;最明显的区别便是，async对外暴露一个对象，对象之下有实现若干特定流程的api。比如，我们需求中，由上而下有顺序依赖关系，async会给我们提供一个很文艺的api叫waterfall,而没有依赖关系只有顺序要求，我们就可以使用async.series,并行推进任务可以用async.parallel等等。&lt;/p&gt;
&lt;p&gt;相比async，step就显得简洁很多，step给我们只提供了一个函数，它接受一个系列函数作为参数，并根据函数中对this的调用区分实现不同类型的流程控制。上面的示例中，异步函数在完成之后将结果传入step的回调函数执行时的this（如你所想，这时候this是一个函数）,而正是通过this实现了将异步操作的结果传入到下一个step的回调函数，从而实现流程控制。通过this，我们实现其它的流程控制，比如要求多个任务并行：&lt;/p&gt;
&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;Step(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;loadStuff&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    fs.readFile(&lt;span class=&quot;string&quot;&gt;&#39;file-1&#39;&lt;/span&gt;, &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.parallel());&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    fs.readFile(&lt;span class=&quot;string&quot;&gt;&#39;file-2&#39;&lt;/span&gt;, &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.parallel());&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    fs.readFile(&lt;span class=&quot;string&quot;&gt;&#39;file-3&#39;&lt;/span&gt;, &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.parallel());&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &amp;#125;,&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;showStuff&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;err, f1, f2, f3&lt;/span&gt;) &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;comment&quot;&gt;//operate with f1, f2, f3&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;);&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;另外，async还为我们提供了一些流程控制之外的非常易用集合操作的方法以及一些工具函数。比如，类似于数组的map操作，我们看下面的函数：&lt;/p&gt;
&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;async&lt;/span&gt;.map([&lt;span class=&quot;string&quot;&gt;&#39;file1&#39;&lt;/span&gt;,&lt;span class=&quot;string&quot;&gt;&#39;file2&#39;&lt;/span&gt;,&lt;span class=&quot;string&quot;&gt;&#39;file3&#39;&lt;/span&gt;], fs.stat, &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;err, results&lt;/span&gt;)&lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;comment&quot;&gt;// results is now an array of stats for each file&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;);&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;而当我们需要用step实现类似需求的时候怎么办呢？因为step是极简主义，源码也总共寥寥百余行，但是，我们完全可以借助既有的函数和方法，模拟出一个stepMap:&lt;/p&gt;
&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;stepMap&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;arr, iterator, callback&lt;/span&gt;)&lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  step(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;)&lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; group = &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.group();&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt;(&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; i = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, l = arr.length; i &amp;lt; l; i++)&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;      iterator(arr[i], group());&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &amp;#125;,callback);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;总之，关于这一类型的解决方案，async和step是两个比较大众的实现，哪个更优，我觉得各有利弊，就像我们权衡express和connect一样。如果你喜欢便捷易用，又对api天生敏感，async是不错的选择；如果你像我一样，喜欢简洁，而且喜欢自己折腾，又不想死记api，那不妨尝试一下step。&lt;/p&gt;
</content>
    
    <summary type="html">
    
      async javascript
    
    </summary>
    
    
      <category term="javascript" scheme="https://laoona.com/tags/javascript/"/>
    
  </entry>
  
  <entry>
    <title>async javascript 上</title>
    <link href="https://laoona.com/post/7279a639.html"/>
    <id>https://laoona.com/post/7279a639.html</id>
    <published>2016-05-31T11:19:12.000Z</published>
    <updated>2024-07-21T05:42:21.224Z</updated>
    
    <content type="html">&lt;p&gt;最近看了一些javascript异步编程方面文章， 也反复读了几遍薄薄的 &lt;a href=&quot;http://book.douban.com/subject/24319975/&quot; title=&quot;书名&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;&amp;lt;&amp;lt; Async JavaScript &amp;gt;&amp;gt;&lt;/a&gt;。总结一下， 供自己后续学习使用， 并分享给大家。&lt;/p&gt;
&lt;p&gt;首先， 有几个问题:&lt;/p&gt;
&lt;p&gt;什么是异步编程/异步函数？&lt;br&gt;异步函数和回调函数有什么关系？&lt;br&gt;为什么异步编程经常与javascript同时出现？&lt;br&gt;javascript中的异步函数的机制是怎样的？&lt;br&gt;那么现在异步编程有什么解决文案？&lt;br&gt;未来的javascript异步编程是什么样子？&lt;/p&gt;
&lt;a id=&quot;more&quot;&gt;&lt;/a&gt;
&lt;h2 id=&quot;什么是异步函数？&quot;&gt;&lt;a href=&quot;#什么是异步函数？&quot; class=&quot;headerlink&quot; title=&quot;什么是异步函数？&quot;&gt;&lt;/a&gt;什么是异步函数？&lt;/h2&gt;&lt;p&gt;对一个jser而言，学习和使用javascrtip的过程中, &lt;em&gt;异步编程&lt;/em&gt;出现频率应该是极高的，或许仅次于&lt;em&gt;事件驱动&lt;/em&gt;/&lt;em&gt;单线程&lt;/em&gt;。那么什么是异步编程呢？什么是异步函数呢？&lt;/p&gt;
&lt;p&gt;言简意赅的说：异步函数就是会导致将来运行 &lt;strong&gt;一个取自事件队列的函数&lt;/strong&gt; 的函数。这是的重点是&lt;strong&gt;取自事件队列&lt;/strong&gt;，关于这个概念，暂且按下不表，将在后面进行分析，我们现在只需要知道异步函数是会导致将来某个时刻运行另外一个函数的函数。&lt;/p&gt;
&lt;h2 id=&quot;异步函数-VS-回调函数&quot;&gt;&lt;a href=&quot;#异步函数-VS-回调函数&quot; class=&quot;headerlink&quot; title=&quot;异步函数 VS 回调函数&quot;&gt;&lt;/a&gt;异步函数 VS 回调函数&lt;/h2&gt;&lt;p&gt;又是一个高频词汇，&lt;em&gt;回调函数&lt;/em&gt; 。再次，我觉得有必要区分一下回调函数和异步函数的概念，虽然在很多人看来，在这一点上的区分不必太过纠结，可是借用老罗的话，&lt;em&gt;我不是为了输赢，我就是认真&lt;/em&gt;，对概念的精确理解和把握，往往是我们深入学习的第一个台阶。&lt;/p&gt;
&lt;p&gt;所谓回函函数：&lt;/p&gt;
&lt;p&gt;In computer programming, a callback is a piece of executable code that is passed as an argument to other code, which is expected to call back (execute) the argument at some convenient time. The invocation may be immediate as in a synchronous callback or it might happen at later time, as in an asynchronous callback. In all cases, the intention is to specify a function or subroutine as an entity that is, depending on the language, more or less similar to a variable.(from &lt;a href=&quot;http://en.wikipedia.org/wiki/Callback_(computer_programming&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;wikipedia&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;从wikipedia的说法中我们可以清晰的看到：&lt;/p&gt;
&lt;p&gt;首先，回调函数作为参数传入到另外一段代码中的一段可执行代码，也就是它所强调的是回调函数是需要被当作参数传入到其它代码中的；&lt;/p&gt;
&lt;p&gt;其次，回调函数可以是同步的，也可以是异步的，这取决于使用者。&lt;/p&gt;
&lt;p&gt;如果我们进入到wikipedia的页面，我们能额外发现一些其它的知识，比如回调函数会出现在拥有某些特性的语言中，那么函数是一等会民的javascript当然也就完美支持回调函数了。&lt;/p&gt;
&lt;p&gt;那么，现在这两个概念应该比较清晰了，我们举个例子比较一下。比如：&lt;br&gt;&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;callbackFunc&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;     &lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log(&lt;span class=&quot;string&quot;&gt;&quot;callback executed!&quot;&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;setTimeout(callbackFunc, &lt;span class=&quot;number&quot;&gt;10000&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;syncFunc&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;callbackFunc&lt;/span&gt;) &lt;/span&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    callbackFunc();&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;在上面的代码片段中，setTimeou是一个异步函数， 因为它导致 了大约1秒后callbackFunc的运行。而callbackFunc对于setTimeout来说，它是一个回调函数。同时，callbackFunc对于syncFunc来说，它也是一个回调函数，但是被同步执行（在同一个事件循环里被执行）,那么syncFunc不能被称为异步函数&lt;/p&gt;
&lt;p&gt;另外，在网上的一些文章中都能看到，很多人将回调函数作为了异步编程的一个解决文案进行总结，包括阮一峰老师的&lt;a href=&quot;http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;javascript异步编程的4种方法&lt;/a&gt;。对于此，我认为这种分类是不恰当的。如果将回调函数看做异步编程的一种解决文案，那么我们后面讲到的分布式事件、Promise以及强大的工作流程控制库都是借助回调函数的形式来实现，岂不是都能看作是同一种解决？所以，我认为，回调函数并不能简单地被当做异步编程的一种解决文案。&lt;/p&gt;
&lt;h2 id=&quot;javascript中的异步机制&quot;&gt;&lt;a href=&quot;#javascript中的异步机制&quot; class=&quot;headerlink&quot; title=&quot;javascript中的异步机制&quot;&gt;&lt;/a&gt;javascript中的异步机制&lt;/h2&gt;&lt;p&gt;每一个jser都应该了解，javascript是单线程的，所谓&lt;em&gt;单线程&lt;/em&gt;，就是同一时刻只能执行一个任务，或者说只能有一个函数一个代码片段在执行。那么我们就很容易产生疑问，如果是单线程，那异步是如何实现的？&lt;/p&gt;
&lt;p&gt;一句话回答：&lt;strong&gt;事件驱动(event-driven)&lt;/strong&gt;。&lt;/p&gt;
&lt;!-- 不只是javascript，几乎所有的单线程且异步的语言，都是通过event-driven实现的。下面，希望用最易懂的文字描述清楚事件驱动。 --&gt;
&lt;p&gt;首先，javascript是单线程执行的， 但是javscript引擎的平台（浏览器或者nodejs）等是拥有若干线程的。比如，对于一个浏览器而言，有一条线程做渲染，有一条线程记录事件（click)等，有一条线程执行javascript等等，这些线程在浏览器内核的协调控制下执行（javascript线程执行期间，不能进行ui渲染）。这是单线程实现的异步基础。&lt;/p&gt;
&lt;p&gt;其次，每一个异步函数都会对应至少一个event-handler，而上面提到的 &lt;em&gt;事件队列&lt;/em&gt; 便是 event-handler在被处理的时候该放在的地方。javascript引擎的线程会在适当的时机处理一系列的 event-handler，适当的时机需要满足两个条件：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;该事件已经满足触发条件（比如：setTimeout(func, 1000)后大约1000ms）；&lt;/li&gt;
&lt;li&gt;javascript的线程空闲（比如：setTimeout注册的回调延时条件已经满足，但是此时的javascript引擎正在做一个复杂的for循环耗时3秒，那么setTimeout的回调函数也能只能等待for循环执行完成后，再执行）。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这是再提到event-loop的存在，每一次循环都是一个tick，它的作用就是在不断循环检测事件队列中是否有event-handler，如果有便会取出执行。我们可以这样理解event-loop:&lt;/p&gt;
&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;while&lt;/span&gt; (&lt;span class=&quot;literal&quot;&gt;true&lt;/span&gt;) &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (atLeasetOneEventIsQueued) &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        fireNextQueuedEvent();&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;最后，事件满足触发条件（上文中适当的时机条件1）是如何判断的？&lt;/p&gt;
&lt;p&gt;不同的事件的触发条件可能由不同的线程监控。比如，我们发送一个ajax请求，应该是浏览器有一个独立的线程发送http请求并在请求返回的时候通知javascript引擎线程满足触发条件；而click一个button，应该是浏览器的GUI线程通知javascript引擎，然后适时执行相应的event-handler。&lt;/p&gt;
&lt;p&gt;我们举个例子说明，假设：我们处在一个页面，这个页面上有一个&lt;code&gt;setTimeout&lt;/code&gt;正在执行延时1000ms执行的某段代码 ；而在这个200ms的时候，我们点击了一个按钮，因为此时已经满足事件触发条件，且javscript线程空闲，所以按照我们脚本，浏览器会立即执行与这个事件绑定的另外某段代码；点击事件触发的某段代码会做两件事，&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一件是注册一个setinterval要求每隔700ms执行某段代码&lt;/li&gt;
&lt;li&gt;另一件是发送一个ajax请求，并要求请求返回后执行某段代码，这个请求会在1500ms后返回。在这之后可能还会有其它事件被触发。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上文中，每一个某段代码都是一个event-handler,而event-handler被触发的时机可能受前面event-handler的影响。我们按照每个event-handler的执行时间都非常短来处理。可以提到下图（上文标示event-hanlder对应的异步函数，下方标示大致的时间）:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://sxxz.u.qiniudn.com/async-javascript-event-driven.png&quot; alt=&quot;1&quot; title=&quot;event-handler&quot;&gt;&lt;/p&gt;
&lt;p&gt;从图中我们能看到事件的执行顺序，这个很容易理解。现在想一下，如果点事件的event-handler先执行一个while循环耗时了100ms，然后再去setInterval和ajax请求，那么执行的顺序又是怎样的呢？如果理解了javascript的事件驱动机制，这个就很容易了。留下一段代码，大家自己尝试一下。是不是跟大家想的一样？&lt;/p&gt;
&lt;figure class=&quot;highlight js&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; obj = &amp;#123;&lt;span class=&quot;string&quot;&gt;&quot;num&quot;&lt;/span&gt;: &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&amp;#125;, start = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;built_in&quot;&gt;Date&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;setTimeout(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;&amp;#123;obj.num = &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&amp;#125;, &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;);&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;while&lt;/span&gt;(&lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;built_in&quot;&gt;Date&lt;/span&gt; - start &amp;lt; &lt;span class=&quot;number&quot;&gt;1000&lt;/span&gt;) &amp;#123;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;alert(&lt;span class=&quot;built_in&quot;&gt;JSON&lt;/span&gt;.stringify(obj));&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;或许还可以想到我们平时遇到的一些问题背后的原因：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;为什么大多情况下setInterval执行间隔会小于setTimeout?&lt;/li&gt;
&lt;li&gt;为什么setTimeout会有最小间隔？whatwg和w3c的HTML5规范都规定4ms&lt;/li&gt;
&lt;li&gt;为什么建议耗时的函数分多次执行？比如，process.nextTick。&lt;/li&gt;
&lt;/ol&gt;
</content>
    
    <summary type="html">
    
      async javascript
    
    </summary>
    
    
      <category term="javascript" scheme="https://laoona.com/tags/javascript/"/>
    
  </entry>
  
  <entry>
    <title>html头文件设置常用之&lt;meta&gt;设置缓存</title>
    <link href="https://laoona.com/post/2d85b6e5.html"/>
    <id>https://laoona.com/post/2d85b6e5.html</id>
    <published>2016-05-30T13:07:56.000Z</published>
    <updated>2024-07-21T05:42:21.224Z</updated>
    
    <content type="html">&lt;p&gt;&lt;code&gt;&amp;lt;meta http-equiv=&amp;quot;pragma&amp;quot; content=&amp;quot;no-cache&amp;quot;&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;pragma与no-cache用于定义页面缓存,不缓存页面(为了提高速度一些浏览器会缓存浏览者浏览过的页面,通过下面的定义,浏览器一般不会缓存页面,而且浏览器无法脱机浏览.)&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;meta http-equiv=&amp;quot;cache-control&amp;quot; content=&amp;quot;no-cache&amp;quot;&amp;gt;&lt;/code&gt;,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;常见的取值有private、no-cache、max-age、must-revalidate等，默认为private,其作用根据不同的重新浏览方式分为以下几种情况：&lt;/p&gt;
&lt;/blockquote&gt;
&lt;a id=&quot;more&quot;&gt;&lt;/a&gt;
&lt;p&gt;1） &lt;em&gt;打开新窗口&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;值为private、no-cache、must-revalidate，那么打开新窗口访问时都会重新访问服务器。 而如果指定了max-age值，那么在此值内的时间里就不会重新访问服务器，例如： Cache-control: max-age=5(表示当访问此网页后的5秒内再次访问不会去服务器) &lt;/p&gt;
&lt;p&gt;2） &lt;em&gt;在地址栏回车&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;值为private或must-revalidate则只有第一次访问时会访问服务器，以后就不再访问。 值为no-cache，那么每次都会访问。 值为max-age，则在过期之前不会重复访问。&lt;/p&gt;
&lt;p&gt;3） &lt;em&gt;按后退按扭&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;值为private、must-revalidate、max-age，则不会重访问， 值为no-cache，则每次都重复访问 &lt;/p&gt;
&lt;p&gt;4） &lt;em&gt;按刷新按扭&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;无论为何值，都会重复访问 Cache-control值为“no-cache”时，访问此页面不会在Internet临时文件夹留下页面备份。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;meta http-equiv=&amp;quot;expires&amp;quot; content=&amp;quot;0&amp;quot;&amp;gt;&lt;/code&gt; 指定Expires值为一个早已过去的时间，那么访问此网时若重复在地址栏按回车，那么每次都会重复访问： Expires: Fri, 31 Dec 1999 16:00:00 GMT 比如：禁止页面在IE中缓存 http响应消息头部设置： &lt;code&gt;CacheControl = no-cache Pragma=no-cache Expires = -1&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Expires是个好东东，如果服务器上的网页经常变化，就把它设置为0，表示立即过期。  &lt;/p&gt;
&lt;/blockquote&gt;
</content>
    
    <summary type="html">
    
      html meta cache
    
    </summary>
    
    
      <category term="cache" scheme="https://laoona.com/tags/cache/"/>
    
  </entry>
  
  <entry>
    <title>centos安装vsftd</title>
    <link href="https://laoona.com/post/8d91d5e2.html"/>
    <id>https://laoona.com/post/8d91d5e2.html</id>
    <published>2016-05-26T23:27:37.000Z</published>
    <updated>2024-07-21T05:42:21.224Z</updated>
    
    <content type="html">&lt;h2 id=&quot;概述：&quot;&gt;&lt;a href=&quot;#概述：&quot; class=&quot;headerlink&quot; title=&quot;概述：&quot;&gt;&lt;/a&gt;概述：&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;vsftpd&lt;/strong&gt;是Linux下比较著名的FTP服务器，搭建FTP服务器当然首选这个。本文介绍了在CentOS 6.4下安装&lt;strong&gt;vsftpd&lt;/strong&gt;、配置虚拟用户登录FTP的过程。&lt;/p&gt;
&lt;h2 id=&quot;安装vsftpd&quot;&gt;&lt;a href=&quot;#安装vsftpd&quot; class=&quot;headerlink&quot; title=&quot;安装vsftpd&quot;&gt;&lt;/a&gt;安装vsftpd&lt;/h2&gt;&lt;p&gt;查看是否已经安装vsftpd&lt;/p&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;rpm -qa | grep vsftpd&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;如果没有，就安装，并设置开机启动&lt;/p&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;yum -y install vsftpd&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;chkconfig vsftpd on&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;a id=&quot;more&quot;&gt;&lt;/a&gt;
&lt;h2 id=&quot;修改配置文件&quot;&gt;&lt;a href=&quot;#修改配置文件&quot; class=&quot;headerlink&quot; title=&quot;修改配置文件&quot;&gt;&lt;/a&gt;修改配置文件&lt;/h2&gt;&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;vim /etc/vsftpd/vsftpd.conf&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;blockquote&gt;
&lt;p&gt;anonymous_enable=NO //设定不允许匿名访问&lt;br&gt;local_enable=YES //设定本地用户可以访问。注：如使用虚拟宿主用户，在该项目设定为NO的情况下所有虚拟用户将无法访问&lt;br&gt;chroot_list_enable=YES //使用户不能离开主目录&lt;br&gt;ascii_upload_enable=YES&lt;br&gt;ascii_download_enable=YES //设定支持ASCII模式的上传和下载功能&lt;br&gt;pam_service_name=vsftpd //PAM认证文件名。PAM将根据/etc/pam.d/vsftpd进行认证&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;添加ftp用户&quot;&gt;&lt;a href=&quot;#添加ftp用户&quot; class=&quot;headerlink&quot; title=&quot;添加ftp用户&quot;&gt;&lt;/a&gt;添加ftp用户&lt;/h2&gt;&lt;p&gt;下面是添加ftpuser用户，设置根目录为/home/wwwroot/ftpuser,禁止此用户登录SSH的权限，并限制其访问其它目录。&lt;/p&gt;
&lt;p&gt;同样打开vsftpd的配置文件&lt;/p&gt;
&lt;figure class=&quot;highlight nginx&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;#chroot_list_enable=YES&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;#(default follows)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;#chroot_list_file=/etc/vsftpd.chroot_list&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;修改为&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;chroot_list_enable=YES&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;#(default follows)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;chroot_list_file=/etc/vsftpd/chroot_list&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h2 id=&quot;增加用户ftpuser，指向目录-home-wwwroot-ftpuser-禁止登录SSH权限。&quot;&gt;&lt;a href=&quot;#增加用户ftpuser，指向目录-home-wwwroot-ftpuser-禁止登录SSH权限。&quot; class=&quot;headerlink&quot; title=&quot;增加用户ftpuser，指向目录/home/wwwroot/ftpuser,禁止登录SSH权限。&quot;&gt;&lt;/a&gt;增加用户&lt;code&gt;ftpuser&lt;/code&gt;，指向目录/home/wwwroot/ftpuser,禁止登录SSH权限。&lt;/h2&gt;&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;useradd -d /home/wwwroot/ftpuser -g ftp -s /sbin/nologin ftpuser&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h2 id=&quot;设置用户口令&quot;&gt;&lt;a href=&quot;#设置用户口令&quot; class=&quot;headerlink&quot; title=&quot;设置用户口令&quot;&gt;&lt;/a&gt;设置用户口令&lt;/h2&gt;&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;passwd ftpuser&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h2 id=&quot;编辑文件chroot-list&quot;&gt;&lt;a href=&quot;#编辑文件chroot-list&quot; class=&quot;headerlink&quot; title=&quot;编辑文件chroot_list&quot;&gt;&lt;/a&gt;编辑文件chroot_list&lt;/h2&gt;&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;vi /etc/vsftpd/chroot_list&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;`&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;blockquote&gt;
&lt;p&gt;内容为ftp用户名,每个用户占一行,如：&lt;br&gt;peter&lt;br&gt;john&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;重新启动vsftpd&quot;&gt;&lt;a href=&quot;#重新启动vsftpd&quot; class=&quot;headerlink&quot; title=&quot;重新启动vsftpd&quot;&gt;&lt;/a&gt;重新启动vsftpd&lt;/h2&gt;&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;service vsftpd restart&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;div class=&quot;tip&quot;&gt;出现的错误&lt;br&gt;1、500 OOPS: cannot change directory&lt;br&gt;&lt;/div&gt;

&lt;h4 id=&quot;解决方法：&quot;&gt;&lt;a href=&quot;#解决方法：&quot; class=&quot;headerlink&quot; title=&quot;解决方法：&quot;&gt;&lt;/a&gt;解决方法：&lt;/h4&gt;&lt;p&gt;在终端输入命令：&lt;br&gt;&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;setsebool -P ftpd_disable_trans 1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;service vsftpd restart&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;原因：这是因为服务器开启了selinux，这限制了FTP的登录。&lt;/p&gt;
&lt;/blockquote&gt;
</content>
    
    <summary type="html">
    
      centos安装vsftd
    
    </summary>
    
    
      <category term="centos" scheme="https://laoona.com/tags/centos/"/>
    
      <category term="vsftd" scheme="https://laoona.com/tags/vsftd/"/>
    
  </entry>
  
  <entry>
    <title>mac 终端 使用ftp命令</title>
    <link href="https://laoona.com/post/2e6545bc.html"/>
    <id>https://laoona.com/post/2e6545bc.html</id>
    <published>2016-05-25T22:36:05.000Z</published>
    <updated>2024-07-21T05:42:21.228Z</updated>
    
    <content type="html">&lt;h2 id=&quot;使用-mac终端-连接ftp服务器&quot;&gt;&lt;a href=&quot;#使用-mac终端-连接ftp服务器&quot; class=&quot;headerlink&quot; title=&quot;使用 mac终端 连接ftp服务器&quot;&gt;&lt;/a&gt;使用 mac终端 连接ftp服务器&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;格式：ftp [hostname| ip-address]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;ftp 127.0.0.1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;#服务器询问你用户名和口令，输入后即可&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h2 id=&quot;下载文件&quot;&gt;&lt;a href=&quot;#下载文件&quot; class=&quot;headerlink&quot; title=&quot;下载文件&quot;&gt;&lt;/a&gt;下载文件&lt;/h2&gt;&lt;p&gt;下载文件通常用get和mget这两条命令。&lt;br&gt;&lt;em&gt;get&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;格式：get [remote-file] [local-file]&lt;br&gt;将单个文件从远端主机中传送至本地主机中.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;a id=&quot;more&quot;&gt;&lt;/a&gt;
&lt;p&gt;&lt;em&gt;mget&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;格式：mget [remote-files]&lt;br&gt;将多个文件从远端主机中传送至本地主机中.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如要获取服务器上Cahce目录下的所有文件,则:&lt;/p&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;ftp&amp;gt; &lt;span class=&quot;built_in&quot;&gt;cd&lt;/span&gt; /rCache&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;ftp&amp;gt; mget *.*&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h2 id=&quot;上传文件&quot;&gt;&lt;a href=&quot;#上传文件&quot; class=&quot;headerlink&quot; title=&quot;上传文件&quot;&gt;&lt;/a&gt;上传文件&lt;/h2&gt;&lt;p&gt;&lt;em&gt;put&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;格式：put local-file [remote-file]&lt;br&gt;将本地主机中一个文件传送至远端主机.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;mput&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;将本地主机中一批文件传送至远端主机.&lt;br&gt;如要把本地当前目录下所有odt文件上传到服务器Doc目录下&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;ftp&amp;gt; &lt;span class=&quot;built_in&quot;&gt;cd&lt;/span&gt; /Doc &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;ftp&amp;gt; mput *.odt&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h2 id=&quot;断开连接&quot;&gt;&lt;a href=&quot;#断开连接&quot; class=&quot;headerlink&quot; title=&quot;断开连接&quot;&gt;&lt;/a&gt;断开连接&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;bye：中断与服务器的连接。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;ftp&amp;gt; &lt;span class=&quot;built_in&quot;&gt;bye&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;div class=&quot;tip&quot;&gt;&lt;br&gt;另：默认的本地目录是home。&lt;br&gt;&lt;/div&gt;

&lt;p&gt;输入&lt;code&gt;help&lt;/code&gt;即可获得所有命令的帮助。&lt;/p&gt;
</content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;使用-mac终端-连接ftp服务器&quot;&gt;&lt;a href=&quot;#使用-mac终端-连接ftp服务器&quot; class=&quot;headerlink&quot; title=&quot;使用 mac终端 连接ftp服务器&quot;&gt;&lt;/a&gt;使用 mac终端 连接ftp服务器&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;格式：ftp [hostname| ip-address]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;ftp 127.0.0.1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;#服务器询问你用户名和口令，输入后即可&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h2 id=&quot;下载文件&quot;&gt;&lt;a href=&quot;#下载文件&quot; class=&quot;headerlink&quot; title=&quot;下载文件&quot;&gt;&lt;/a&gt;下载文件&lt;/h2&gt;&lt;p&gt;下载文件通常用get和mget这两条命令。&lt;br&gt;&lt;em&gt;get&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;格式：get [remote-file] [local-file]&lt;br&gt;将单个文件从远端主机中传送至本地主机中.&lt;/p&gt;
&lt;/blockquote&gt;
    
    </summary>
    
    
      <category term="mac终端" scheme="https://laoona.com/tags/mac%E7%BB%88%E7%AB%AF/"/>
    
      <category term="mac" scheme="https://laoona.com/tags/mac/"/>
    
      <category term="ftp" scheme="https://laoona.com/tags/ftp/"/>
    
  </entry>
  
</feed>
