<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[前端开发笔记]]></title><description><![CDATA[前端技术笔记，摄影分享]]></description><link>http://hanhan.pro/</link><image><url>http://hanhan.pro/favicon.png</url><title>前端开发笔记</title><link>http://hanhan.pro/</link></image><generator>Ghost 5.75</generator><lastBuildDate>Tue, 11 Aug 2026 15:02:45 GMT</lastBuildDate><atom:link href="http://hanhan.pro/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[在 HarmonyOS 上做"看 Git 仓库"的 App：HTTP 请求、懒加载树、平板分栏四个工程点]]></title><description><![CDATA[上一篇文章介绍了我的第一个鸿蒙 App「MarkBook」——一个在手机上随手看 Git 仓库代码的轻量工具：加仓库、看文件、翻 Markdown，免登录、随开随看。今天这篇，拆一拆它背后几个「只有鸿蒙开发者才懂」的坑。]]></description><link>http://hanhan.pro/harmonyos-markbook-read-github-code-self-built-deflate-unzip/</link><guid isPermaLink="false">6a7b30628875400001ae53a3</guid><category><![CDATA[arkTS]]></category><category><![CDATA[arkUI]]></category><category><![CDATA[HarmonyOS]]></category><category><![CDATA[鸿蒙开发]]></category><category><![CDATA[AppGallery]]></category><category><![CDATA[端云一体化]]></category><category><![CDATA[应用开发]]></category><category><![CDATA[frontend]]></category><category><![CDATA[前端]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[性能优化]]></category><dc:creator><![CDATA[reno]]></dc:creator><pubDate>Mon, 10 Aug 2026 14:24:00 GMT</pubDate><media:content url="http://hanhan.pro/content/images/2026/08/IMG_2981.png" medium="image"/><content:encoded><![CDATA[<img src="http://hanhan.pro/content/images/2026/08/IMG_2981.png" alt="&#x5728; HarmonyOS &#x4E0A;&#x505A;&quot;&#x770B; Git &#x4ED3;&#x5E93;&quot;&#x7684; App&#xFF1A;HTTP &#x8BF7;&#x6C42;&#x3001;&#x61D2;&#x52A0;&#x8F7D;&#x6811;&#x3001;&#x5E73;&#x677F;&#x5206;&#x680F;&#x56DB;&#x4E2A;&#x5DE5;&#x7A0B;&#x70B9;"><p>&#x5148;&#x8BF4;&#x7ED3;&#x8BBA;&#xFF1A;&#x4E00;&#x4E2A;&quot;&#x770B; Git &#x4ED3;&#x5E93;&quot;&#x7684; App&#xFF0C;&#x6280;&#x672F;&#x5E95;&#x5EA7;&#x5176;&#x5B9E;&#x53EA;&#x6709;&#x56DB;&#x4EF6;&#x4E8B;&#x2014;&#x2014;<strong>HTTP &#x8BF7;&#x6C42;&#x3001;&#x89E3;&#x538B;&#x3001;&#x6587;&#x4EF6;&#x6811;&#x3001;Markdown &#x6E32;&#x67D3;</strong>&#x3002;&#x542C;&#x8D77;&#x6765;&#x90FD;&#x4E0D;&#x96BE;&#xFF0C;&#x4F46;&#x6BCF;&#x4E00;&#x6B65;&#x8E29;&#x8FDB;&#x53BB;&#xFF0C;&#x90FD;&#x80FD;&#x9047;&#x5230;&#x70B9;&#x9E3F;&#x8499;&#x7279;&#x6709;&#x7684;&quot;&#x60CA;&#x559C;&quot;&#x3002;</p>
<h4 id="%E2%91%A0-%E8%AE%BF%E9%97%AE-git-%E5%B9%B3%E5%8F%B0-api%EF%BC%9A%E8%BF%9E-patch-%E9%83%BD%E6%B2%A1%E6%9C%89%E7%9A%84-http-%E6%A8%A1%E5%9D%97">&#x2460; &#x8BBF;&#x95EE; Git &#x5E73;&#x53F0; API&#xFF1A;&#x8FDE; <code>PATCH</code> &#x90FD;&#x6CA1;&#x6709;&#x7684; http &#x6A21;&#x5757;</h4>
<p>MarkBook &#x652F;&#x6301; GitHub / Gitee / GitLab / &#x4E91;&#x6548;&#x591A;&#x4E2A;&#x5E73;&#x53F0;&#x3002;&#x516C;&#x5F00;&#x4ED3;&#x5E93;&#x7684;&#x6D4F;&#x89C8;&#x57FA;&#x672C;&#x4E0D;&#x9700;&#x8981;&#x767B;&#x5F55;&#xFF0C;&#x8D70;&#x7684;&#x5C31;&#x662F;&#x5404;&#x5E73;&#x53F0;&#x7684; REST API&#x3002;&#x9E3F;&#x8499;&#x8FD9;&#x8FB9;&#x7528; <code>@ohos.net.http</code>&#xFF1A;</p>
<pre><code class="language-typescript">import { http } from &apos;@kit.NetworkKit&apos;;

async function getJson(url: string): Promise&lt;Record&lt;string, Object&gt;&gt; {
  const req = http.createHttp();
  try {
    const res = await req.request(url, {
      method: http.RequestMethod.GET,
      header: { &apos;Accept&apos;: &apos;application/json&apos;, &apos;User-Agent&apos;: &apos;MarkBook&apos; },
      readTimeout: 30000
    });
    const text = res.result as string;
    return JSON.parse(text) as Record&lt;string, Object&gt;;
  } finally {
    req.destroy(); // &#x590D;&#x7528;&#x5B9E;&#x4F8B;&#x5FC5;&#x987B;&#x624B;&#x52A8;&#x9500;&#x6BC1;&#xFF0C;&#x5426;&#x5219;&#x8FDE;&#x63A5;&#x6CC4;&#x6F0F;
  }
}
</code></pre>
<p>&#x5751;&#x6709;&#x4E24;&#x4E2A;&#x3002;&#x7B2C;&#x4E00;&#x4E2A;&#x662F;<strong>&#x5E73;&#x53F0;&#x5DEE;&#x5F02;</strong>&#xFF1A;GitHub&#x3001;Gitee&#x3001;GitLab&#x3001;&#x4E91;&#x6548;&#x7684;&#x63A5;&#x53E3;&#x5F62;&#x72B6;&#x5404;&#x4E0D;&#x76F8;&#x540C;&#xFF08;&#x6811;&#x63A5;&#x53E3;&#x3001;&#x63D0;&#x4EA4;&#x63A5;&#x53E3;&#x3001;&#x6587;&#x4EF6; URL &#x89C4;&#x5219;&#x90FD;&#x4E0D;&#x4E00;&#x6837;&#xFF09;&#xFF0C;&#x5F97;&#x5728; Service &#x5C42;&#x505A;&#x4E00;&#x5C42;&#x5F52;&#x4E00;&#x5316;&#x9002;&#x914D;&#x5668;&#xFF0C;&#x4E0A;&#x5C42;&#x53EA;&#x7BA1;&quot;&#x7ED9;&#x6211; owner / repo / &#x8DEF;&#x5F84;&quot;&#x3002;&#x7B2C;&#x4E8C;&#x4E2A;&#x662F; <strong>ArkTS &#x4E25;&#x683C;&#x6A21;&#x5F0F;</strong>&#xFF1A;<code>res.result</code> &#x4E0D;&#x80FD;&#x5F53; <code>any</code> &#x76F4;&#x63A5;&#x7528;&#xFF0C;&#x8981; <code>as string</code> &#x5355;&#x6B21;&#x8F6C;&#x578B;&#xFF1B;&#x63A5;&#x53E3;&#x5FC5;&#x987B;&#x663E;&#x5F0F;&#x5B9A;&#x4E49;&#xFF0C;&#x4E0D;&#x80FD;&#x5199;&#x672A;&#x7C7B;&#x578B;&#x5316;&#x7684;&#x5BF9;&#x8C61;&#x5B57;&#x9762;&#x91CF;&#x3002;</p>
<p>&#x987A;&#x5E26;&#x4E00;&#x63D0; API 24 &#x7684;&#x4E00;&#x4E2A;&#x9650;&#x5236;&#xFF1A;<code>http.RequestMethod</code> &#x91CC;&#x6CA1;&#x6709; <code>PATCH</code>&#xFF0C;GitLab &#x67D0;&#x4E9B;&#x63A5;&#x53E3;&#x8981;&#x7528; PATCH &#x65F6;&#xFF0C;&#x53EA;&#x80FD;&#x62FF; <code>PUT</code> &#x66FF;&#x4EE3;&#x6216;&#x6362;&#x63A5;&#x53E3;&#x3002;</p>
<h4 id="%E2%91%A1-%E8%87%AA%E7%A0%94-deflate-%E8%A7%A3%E5%8E%8B%EF%BC%9A%E6%9C%80%E7%A1%AC%E6%A0%B8%E7%9A%84%E4%B8%80%E6%AE%B5">&#x2461; &#x81EA;&#x7814; DEFLATE &#x89E3;&#x538B;&#xFF1A;&#x6700;&#x786C;&#x6838;&#x7684;&#x4E00;&#x6BB5;</h4>
<p>Git &#x5E73;&#x53F0;&#x7684;&#x54CD;&#x5E94;&#x9ED8;&#x8BA4; gzip &#x538B;&#x7F29;&#xFF0C;&#x5C24;&#x5176;&#x662F;&#x4ED3;&#x5E93;&#x6587;&#x4EF6;&#x5185;&#x5BB9;&#xFF0C;&#x4F53;&#x79EF;&#x80FD;&#x5DEE;&#x4E00;&#x4E2A;&#x6570;&#x91CF;&#x7EA7;&#x3002;&#x6309;&#x8BF4;&#x89E3;&#x538B;&#x662F;&#x73B0;&#x6210;&#x7684;&#x4E8B;&#x2014;&#x2014;<strong>&#x4F46;&#x9E3F;&#x8499; <code>util</code> &#x6A21;&#x5757;&#x5728;&#x8FD9;&#x4E2A; API &#x7EA7;&#x522B;&#x6CA1;&#x6709; <code>Inflater</code> &#x7C7B;&#xFF0C;DEFLATE &#x89E3;&#x538B;&#x5F97;&#x81EA;&#x5DF1;&#x5B9E;&#x73B0;&#x3002;</strong></p>
<p>DEFLATE &#x662F;&#x4EC0;&#x4E48;&#xFF1F;&#x4E00;&#x53E5;&#x8BDD;&#xFF1A;<strong>LZ77 &#x957F;&#x5EA6;-&#x8DDD;&#x79BB;&#x5339;&#x914D; + Huffman &#x7F16;&#x7801;</strong>&#x3002;&#x538B;&#x7F29;&#x6D41;&#x91CC;&#x5206;&#x4E09;&#x79CD;&#x5757;&#xFF1A;&#x4E0D;&#x538B;&#x7F29;&#x5757;&#x3001;&#x56FA;&#x5B9A; Huffman &#x5757;&#x3001;&#x52A8;&#x6001; Huffman &#x5757;&#x3002;&#x52A8;&#x6001;&#x5757;&#x8981;&#x5148;&#x89E3;&#x51FA;&quot;&#x7801;&#x957F;&#x5E8F;&#x5217;&quot;&#x518D;&#x91CD;&#x5EFA; Huffman &#x8868;&#x3002;&#x4F4D;&#x6D41;&#x662F; <strong>LSB-first</strong>&#xFF08;&#x4F4E;&#x5B57;&#x8282;&#x5728;&#x524D;&#xFF09;&#xFF0C;&#x8FD9;&#x662F;&#x6700;&#x5BB9;&#x6613;&#x5199;&#x9519;&#x7684;&#x5730;&#x65B9;&#x3002;</p>
<p>&#x6838;&#x5FC3;&#x9AA8;&#x67B6;&#x957F;&#x8FD9;&#x6837;&#xFF08;&#x5B8C;&#x6574;&#x5B9E;&#x73B0;&#x7EA6;&#x4E24;&#x767E;&#x884C;&#xFF0C;&#x8FD9;&#x91CC;&#x662F;&#x5173;&#x952E;&#x601D;&#x8DEF;&#xFF09;&#xFF1A;</p>
<pre><code class="language-typescript">// &#x9010;&#x4F4D;&#x8BFB;&#x53D6;&#xFF1A;DEFLATE &#x4F4D;&#x6D41;&#x4ECE;&#x6700;&#x4F4E;&#x4F4D;&#x5F00;&#x59CB;
class BitReader {
  private pos: number = 0;
  private bit: number = 0;

  constructor(private buf: Uint8Array) {}

  readBits(n: number): number {
    let val = 0;
    for (let i = 0; i &lt; n; i++) {
      const b = this.buf[this.pos];
      val |= ((b &gt;&gt; this.bit) &amp; 1) &lt;&lt; i;
      if (++this.bit === 8) { this.bit = 0; this.pos++; }
    }
    return val;
  }
}

// &#x52A8;&#x6001; Huffman &#x5757;&#xFF1A;&#x5148;&#x8BFB;&#x7801;&#x957F; &#x2192; &#x91CD;&#x5EFA;&#x5B57;&#x9762;/&#x957F;&#x5EA6;&#x3001;&#x8DDD;&#x79BB;&#x4E24;&#x5F20; Huffman &#x8868;
// &#x7136;&#x540E;&#x4E3B;&#x5FAA;&#x73AF;&#xFF1A;&#x8BFB;&#x7B26;&#x53F7; &#x2192; 256 &#x7ED3;&#x675F; / &#x5B57;&#x9762;&#x91CF;&#x76F4;&#x51FA; / &#x957F;&#x5EA6;+&#x8DDD;&#x79BB; &#x2192; &#x4ECE;&#x6ED1;&#x52A8;&#x7A97;&#x53E3;&#x56DE;&#x62F7;
</code></pre>
<p>&#x4E3B;&#x5FAA;&#x73AF;&#x5C31;&#x4E00;&#x53E5;&#x8BDD;&#xFF1A;&#x8BFB;&#x5230; 0~255 &#x76F4;&#x63A5;&#x8F93;&#x51FA;&#xFF1B;&#x8BFB;&#x5230; 256 &#x7ED3;&#x675F;&#x5F53;&#x524D;&#x5757;&#xFF1B;&#x8BFB;&#x5230; 257~285&#xFF0C;&#x518D;&#x8DDF;&#x4E00;&#x4E2A;&#x8DDD;&#x79BB;&#xFF0C;&#x4ECE;&quot;&#x6ED1;&#x52A8;&#x7A97;&#x53E3;&quot;&#x91CC;&#x56DE;&#x62F7;&#x4E00;&#x6BB5;&#x5386;&#x53F2;&#x5B57;&#x8282;&#x62FC;&#x51FA;&#x6765;&#x3002;gzip &#x683C;&#x5F0F;&#x989D;&#x5916;&#x5E26;&#x4E00;&#x4E2A; <code>1f 8b</code> &#x5934;&#x548C;&#x4E00;&#x4E2A; CRC32 &#x5C3E;&#x5DF4;&#xFF0C;zlib &#x53C8;&#x662F;&#x53E6;&#x4E00;&#x5957;&#x5934;&#xFF08;<code>78</code> &#x5F00;&#x5934; + ADLER32&#xFF09;&#x3002;<strong>Git &#x5E73;&#x53F0;&#x7ED9;&#x7684;&#x662F; gzip&#xFF0C;&#x6240;&#x4EE5; <code>1f 8b</code> &#x5934;&#x3001;CRC32 &#x6821;&#x9A8C;&#x90FD;&#x8981;&#x81EA;&#x5DF1;&#x5904;&#x7406;&#x3002;</strong></p>
<p>&#x8FD9;&#x6BB5;&#x5199;&#x5B8C;&#xFF0C;&#x6700;&#x6709;&#x6210;&#x5C31;&#x611F;&#x7684;&#x4E00;&#x523B;&#x662F;&#xFF1A;&#x4E00;&#x4E2A;&#x51E0;&#x5341; MB &#x7684;&#x4ED3;&#x5E93;&#x6587;&#x4EF6;&#x5217;&#x8868;&#xFF0C;&#x624B;&#x673A;&#x4E0A;&#x4ECE;&quot;&#x8F6C;&#x5708;&quot;&#x53D8;&#x6210;&quot;&#x79D2;&#x5F00;&quot;&#x3002;&#x90A3;&#x4E00;&#x523B;&#x4F60;&#x624D;&#x771F;&#x6B63;&#x7406;&#x89E3;&#x4EC0;&#x4E48;&#x53EB;&quot;&#x628A;&#x539F;&#x7406;&#x5403;&#x900F;&#x4E86;&quot;&#x3002;</p>
<h4 id="%E2%91%A2-%E6%96%87%E4%BB%B6%E6%A0%91%EF%BC%9A%E5%B1%95%E5%BC%80%E5%93%AA%E5%B1%82%EF%BC%8C%E6%89%8D%E5%8A%A0%E8%BD%BD%E5%93%AA%E5%B1%82">&#x2462; &#x6587;&#x4EF6;&#x6811;&#xFF1A;&#x5C55;&#x5F00;&#x54EA;&#x5C42;&#xFF0C;&#x624D;&#x52A0;&#x8F7D;&#x54EA;&#x5C42;</h4>
<p>&#x4ED3;&#x5E93;&#x76EE;&#x5F55;&#x662F;&#x68F5;&#x6811;&#x3002;&#x6700;&#x6734;&#x7D20;&#x7684;&#x5199;&#x6CD5;&#x662F;&#x8C03;&#x4E00;&#x6B21;&quot;&#x9012;&#x5F52;&#x6811;&quot;&#x63A5;&#x53E3;&#xFF0C;&#x628A;&#x6574;&#x68F5;&#x76EE;&#x5F55;&#x62C9;&#x4E0B;&#x6765;&#x2014;&#x2014;&#x5C0F;&#x4ED3;&#x5E93;&#x6CA1;&#x95EE;&#x9898;&#xFF0C;&#x5927;&#x4ED3;&#x5E93;&#x76F4;&#x63A5;&#x5361;&#x6B7B;&#x3002;</p>
<p>MarkBook &#x7684;&#x505A;&#x6CD5;&#x662F;<strong>&#x61D2;&#x52A0;&#x8F7D;</strong>&#xFF1A;&#x5217;&#x8868;&#x5C55;&#x5F00;&#x4E00;&#x4E2A;&#x76EE;&#x5F55;&#xFF0C;&#x624D;&#x53BB;&#x8BF7;&#x6C42;&#x5B83;&#x7684;&#x5B50;&#x9879;&#xFF0C;&#x5E76;&#x4E14;&#x7528; V2 &#x72B6;&#x6001;&#x7BA1;&#x7406;&#x88C5;&#x9970;&#x5668;&#x7BA1;&#x4F4F;&#x6BCF;&#x4E00;&#x5C42;&#x8282;&#x70B9;&#x7684;&#x52A0;&#x8F7D;&#x72B6;&#x6001;&#xFF1A;</p>
<pre><code class="language-typescript">@ObservedV2
class RepoNode {
  @Trace path: string = &apos;&apos;;
  @Trace type: string = &apos;blob&apos;;      // &apos;tree&apos; | &apos;blob&apos;
  @Trace children: RepoNode[] = [];  // &#x5DF2;&#x52A0;&#x8F7D;&#x7684;&#x5B50;&#x8282;&#x70B9;
  @Trace loaded: boolean = false;    // &#x662F;&#x5426;&#x5DF2;&#x8BF7;&#x6C42;&#x8FC7;

  get isDir(): boolean { return this.type === &apos;tree&apos;; }
}
</code></pre>
<p>&#x7528;&#x6237;&#x70B9;&#x5F00; <code>src/</code>&#xFF0C;&#x624D;&#x53BB;&#x8BF7;&#x6C42; <code>src/</code> &#x7684;&#x5B50;&#x9879;&#xFF1B;&#x70B9;&#x5F00; <code>docs/</code>&#xFF0C;&#x624D;&#x52A0;&#x8F7D; <code>docs/</code>&#x3002;&#x6811;&#x7684;&#x6BCF;&#x4E00;&#x5C42;&#x4E92;&#x4E0D;&#x6253;&#x6270;&#xFF0C;&#x6EDA;&#x52A8;&#x4E5F;&#x987A;&#x3002;</p>
<h4 id="%E2%91%A3-markdown-%E6%B8%B2%E6%9F%93-%E4%BB%A3%E7%A0%81%E5%9D%97%E5%A4%8D%E5%88%B6">&#x2463; Markdown &#x6E32;&#x67D3; + &#x4EE3;&#x7801;&#x5757;&#x590D;&#x5236;</h4>
<p>README&#x3001;&#x6587;&#x6863;&#x5728;&#x624B;&#x673A;&#x4E0A;&#x76F4;&#x63A5;&#x6E32;&#x67D3;&#x6210;&#x6392;&#x7248;&#x597D;&#x7684;&#x9875;&#x9762;&#x3002;&#x8FD9;&#x91CC;&#x6709;&#x4E24;&#x4E2A;&#x79FB;&#x52A8;&#x7AEF;&#x7279;&#x6709;&#x7684;&#x8BB2;&#x7A76;&#xFF1A;&#x4E00;&#x662F;<strong>&#x4EE3;&#x7801;&#x5757;</strong>&#x8981;&#x80FD;&#x4E00;&#x952E;&#x590D;&#x5236;&#xFF08;&#x957F;&#x6309;&#x5F39;&#x51FA;&#x590D;&#x5236;&#x83DC;&#x5355;&#xFF0C;ArkUI &#x91CC;&#x7528;&#x81EA;&#x5B9A;&#x4E49;&#x4E0A;&#x4E0B;&#x6587;&#x83DC;&#x5355;&#x5B9E;&#x73B0;&#xFF09;&#xFF1B;&#x4E8C;&#x662F;<strong>&#x957F;&#x6587;&#x6863;</strong>&#x522B;&#x4E00;&#x4E0A;&#x6765;&#x5C31;&#x5168;&#x91CF;&#x89E3;&#x6790;&#xFF0C;&#x5148;&#x6E32;&#x67D3;&#x9996;&#x5C4F;&#x3001;&#x6EDA;&#x52A8;&#x518D;&#x8865;&#x5145;&#xFF0C;&#x907F;&#x514D;&#x5927; Markdown &#x5361; UI&#x3002;</p>
<h4 id="%E2%91%A4-%E5%B9%B3%E6%9D%BF%E5%88%86%E6%A0%8F%EF%BC%9A%E4%B8%80%E5%A5%97%E5%B8%83%E5%B1%80%EF%BC%8C%E4%B8%A4%E7%A7%8D%E5%BD%A2%E6%80%81">&#x2464; &#x5E73;&#x677F;&#x5206;&#x680F;&#xFF1A;&#x4E00;&#x5957;&#x5E03;&#x5C40;&#xFF0C;&#x4E24;&#x79CD;&#x5F62;&#x6001;</h4>
<p>&#x6700;&#x65B0;&#x7248;&#x7ED9;&#x5E73;&#x677F;&#x505A;&#x4E86;&#x4E13;&#x95E8;&#x9002;&#x914D;&#xFF1A;&#x5E73;&#x677F;&#x6A2A;&#x5C4F;&#x65F6; <code>Navigation</code> &#x8D70; <code>Split</code> &#x5206;&#x680F;&#x6A21;&#x5F0F;&#x2014;&#x2014;&#x5DE6;&#x680F;&#x4ED3;&#x5E93;/&#x6587;&#x4EF6;&#x5217;&#x8868;&#xFF0C;&#x53F3;&#x680F;&#x6587;&#x4EF6;&#x8BE6;&#x60C5;&#xFF0C;&#x50CF;&#x684C;&#x9762; IDE &#x4E00;&#x6837;&#x5BF9;&#x7167;&#x7740;&#x770B;&#xFF1B;&#x624B;&#x673A;&#x4E0A;&#x9000;&#x56DE;&#x5E95;&#x90E8;&#x5BFC;&#x822A;&#x7684; <code>Stack</code> &#x6A21;&#x5F0F;&#x3002;ArkUI &#x7684; <code>Navigation</code> + <code>NavPathStack</code> &#x5929;&#x7136;&#x652F;&#x6301;&#x8FD9;&#x4E24;&#x79CD;&#x6A21;&#x5F0F;&#x5207;&#x6362;&#xFF1A;</p>
<pre><code class="language-typescript">Navigation(this.pathStack) {
  // &#x5DE6;&#x680F;&#x5217;&#x8868; + &#x53F3;&#x680F;&#x8BE6;&#x60C5;
}
.mode(isWide() ? NavigationMode.Split : NavigationMode.Stack)
</code></pre>
<p>&#x5224;&#x65AD;&#x5BBD;&#x5C4F;&#x7528;&#x7684;&#x662F; <code>display.getDefaultDisplaySync()</code>&#xFF0C;&#x5BBD;&#x5EA6;&#x591F;&#x5C31;&#x5206;&#x680F;&#x3001;&#x4E0D;&#x591F;&#x5C31;&#x5806;&#x53E0;&#xFF0C;&#x4E00;&#x5957;&#x4EE3;&#x7801;&#x4E24;&#x79CD;&#x5F62;&#x6001;&#xFF1B;&#x6298;&#x53E0;&#x5C4F;&#x5408;&#x4E0A;&#x3001;&#x5C55;&#x5F00;&#x65F6;&#x8FD8;&#x8981;&#x76D1;&#x542C;&#x5C3A;&#x5BF8;&#x53D8;&#x5316;&#x52A8;&#x6001;&#x5207;&#x6362;&#x3002;</p>
<h4 id="arkts-%E4%B8%A5%E6%A0%BC%E6%A8%A1%E5%BC%8F%EF%BC%9A%E7%BC%96%E8%AF%91%E6%9C%9F%E5%B0%B1%E6%8A%8A%E4%BD%A0%E6%95%99%E5%81%9A%E4%BA%BA">ArkTS &#x4E25;&#x683C;&#x6A21;&#x5F0F;&#xFF1A;&#x7F16;&#x8BD1;&#x671F;&#x5C31;&#x628A;&#x4F60;&#x6559;&#x505A;&#x4EBA;</h4>
<p>&#x5199; MarkBook &#x662F;&#x7B2C;&#x4E00;&#x6B21;&#x5168;&#x91CF;&#x5403; ArkTS &#x4E25;&#x683C;&#x6A21;&#x5F0F;&#xFF0C;&#x51E0;&#x4E2A;&quot;&#x540D;&#x573A;&#x9762;&quot;&#xFF1A;</p>
<ul>
<li><code>catch (e: Error)</code> <strong>&#x4E0D;&#x80FD;&#x5199;&#x7C7B;&#x578B;&#x6CE8;&#x89E3;</strong>&#xFF0C;&#x5F97;&#x53BB;&#x6389;&#xFF0C;&#x51FD;&#x6570;&#x4F53;&#x91CC;&#x518D;&#x624B;&#x52A8;&#x5224;&#x65AD;&#xFF1B;</li>
<li><strong>&#x4E0D;&#x8BB8;&#x89E3;&#x6784;</strong>&#xFF0C;<code>const { a } = obj</code> &#x76F4;&#x63A5;&#x7F16;&#x8BD1;&#x5931;&#x8D25;&#xFF0C;&#x6539;&#x6210; <code>obj.a</code>&#xFF1B;</li>
<li>&#x4E0D;&#x8BB8; <code>any</code>&#x3001;&#x4E0D;&#x8BB8;&#x672A;&#x7C7B;&#x578B;&#x5316;&#x5BF9;&#x8C61;&#x5B57;&#x9762;&#x91CF;&#xFF0C;&#x903C;&#x7740;&#x4F60;&#x628A;&#x6570;&#x636E;&#x7ED3;&#x6784;&#x90FD;&#x5B9A;&#x4E49;&#x6210; <code>interface</code>&#xFF1B;</li>
<li><code>Column</code> &#x7EC4;&#x4EF6;<strong>&#x6CA1;&#x6709; <code>.maxWidth()</code></strong>&#xFF0C;&#x53EA;&#x6709; <code>.constraintSize({ maxWidth: ... })</code>&#x3002;</li>
</ul>
<p>&#x4E00;&#x5F00;&#x59CB;&#x5F88;&#x70E6;&#xFF0C;&#x5199;&#x5B8C;&#x53D1;&#x73B0;&#xFF1A;&#x8FD9;&#x4E9B;&#x7EA6;&#x675F;&#x5176;&#x5B9E;&#x5728;&#x903C;&#x4F60;&#x5199;&#x51FA;&#x66F4;&#x53EF;&#x7EF4;&#x62A4;&#x7684;&#x4EE3;&#x7801;&#x2014;&#x2014;&#x63A5;&#x53E3;&#x5148;&#x5B9A;&#x4E49;&#x6E05;&#x695A;&#xFF0C;&#x6570;&#x636E;&#x5F62;&#x72B6;&#x4E0D;&#x4F1A;&#x5199;&#x7740;&#x5199;&#x7740;&#x5C31;&#x98D8;&#x4E86;&#x3002;</p>
<h4 id="%E5%81%9A%E5%BE%97%E5%A5%BD%E7%9A%84-%E8%BF%98%E8%83%BD%E4%BC%98%E5%8C%96%E7%9A%84">&#x505A;&#x5F97;&#x597D;&#x7684; &amp; &#x8FD8;&#x80FD;&#x4F18;&#x5316;&#x7684;</h4>
<p><strong>&#x505A;&#x5F97;&#x597D;&#x7684;</strong>&#xFF1A;&#x514D;&#x767B;&#x5F55;&#x770B;&#x516C;&#x5F00;&#x4ED3;&#x5E93;&#x3001;&#x8DEF;&#x5F84;&#x8BBE;&#x8BA1;&#x5408;&#x7406;&#xFF1B;&#x81EA;&#x7814;&#x89E3;&#x538B;&#x8BA9;&#x5927;&#x4ED3;&#x5E93;&#x4E5F;&#x80FD;&#x79D2;&#x5F00;&#xFF1B;&#x6811;&#x7684;&#x61D2;&#x52A0;&#x8F7D; + &#x5206;&#x680F;&#x9002;&#x914D;&#xFF0C;&#x624B;&#x673A;&#x4E0A;&#x8F7B;&#x5FEB;&#x3001;&#x5E73;&#x677F;&#x4E0A;&#x50CF; IDE&#xFF1B;&#x6536;&#x85CF;&#x79BB;&#x7EBF;&#x770B;&#xFF0C;&#x6CA1;&#x7F51;&#x4E5F;&#x80FD;&#x67E5;&#x3002;</p>
<p><strong>&#x8FD8;&#x80FD;&#x4F18;&#x5316;&#x7684;</strong>&#xFF1A;&#x8D85;&#x5927;&#x4ED3;&#x5E93;&#x7684;&#x6811;&#x6E32;&#x67D3;&#x6027;&#x80FD;&#x8FD8;&#x53EF;&#x4EE5;&#x518D;&#x538B;&#xFF1B;Markdown &#x7684;&#x6E32;&#x67D3;&#x8986;&#x76D6;&#x5EA6;&#xFF08;&#x8868;&#x683C;&#x3001;&#x6D41;&#x7A0B;&#x56FE;&#x7B49;&#xFF09;&#x8FD8;&#x6709;&#x63D0;&#x5347;&#x7A7A;&#x95F4;&#xFF1B;&#x8DE8;&#x5E73;&#x53F0; API &#x7684;&#x5F52;&#x4E00;&#x5316;&#x9002;&#x914D;&#x5668;&#x76EE;&#x524D;&#x662F;&quot;&#x591F;&#x7528;&quot;&#xFF0C;&#x79BB;&quot;&#x4F18;&#x96C5;&quot;&#x8FD8;&#x6709;&#x8DDD;&#x79BB;&#x3002;</p>
<h4 id="%E6%9C%80%E5%90%8E">&#x6700;&#x540E;</h4>
<p>&#x5F88;&#x591A;&#x4EBA;&#x95EE;&quot;&#x9E3F;&#x8499;&#x5F00;&#x53D1;&#x96BE;&#x4E0D;&#x96BE;&quot;&#x3002;&#x6211;&#x7684;&#x7B54;&#x6848;&#x5728; MarkBook &#x91CC;&#xFF1A;<strong>&#x96BE;&#x7684;&#x4E0D;&#x662F;&#x8BED;&#x6CD5;&#xFF0C;&#x662F;&quot;&#x7CFB;&#x7EDF;&#x601D;&#x7EF4;&quot;</strong>&#x2014;&#x2014;<code>util</code> &#x91CC;&#x6CA1;&#x6709; <code>Inflater</code>&#xFF0C;&#x90A3;&#x5C31;&#x81EA;&#x5DF1;&#x5199;&#x4E00;&#x4E2A;&#xFF1B;<code>http</code> &#x6CA1;&#x6709; <code>PATCH</code>&#xFF0C;&#x90A3;&#x5C31;&#x6362;&#x6761;&#x8DEF;&#x8D70;&#x3002;&#x6BCF;&#x89E3;&#x51B3;&#x4E00;&#x4E2A;&#x8FD9;&#x6837;&#x7684;&#x95EE;&#x9898;&#xFF0C;&#x4F60;&#x5C31;&#x6BD4;&quot;&#x4F1A;&#x7528;&#x6846;&#x67B6;&quot;&#x7684;&#x5F00;&#x53D1;&#x8005;&#x591A;&#x61C2;&#x4E00;&#x5C42;&#x3002;</p>
<p>&#x4E0B;&#x4E00;&#x671F;&#xFF0C;&#x6211;&#x7684;&#x7B2C;&#x4E8C;&#x4E2A;&#x9E3F;&#x8499; App&#x300C;&#x901F;&#x5370; QuickMark&#x300D;&#x4E5F;&#x4E0A;&#x67B6;&#x4E86;&#x2014;&#x2014;&#x7ED9;&#x7167;&#x7247;&#x6279;&#x91CF;&#x52A0;&#x6C34;&#x5370;&#xFF0C;&#x50CF;&#x7D20;&#x7EA7;&#x5408;&#x6210;&#x5F15;&#x64CE; + AGC &#x7AEF;&#x4E91;&#x4E00;&#x4F53;&#x5316;&#xFF0C;&#x7EE7;&#x7EED;&#x62C6;&#x5B9E;&#x6218;&#x3002;</p>
<blockquote>
<p>&#x1F4E5; MarkBook&#xFF1A;&#x534E;&#x4E3A;&#x5E94;&#x7528;&#x5E02;&#x573A;&#x641C;&#x7D22;&#x300C;MarkBook&#x300D;&#x5373;&#x53EF;&#x4E0B;&#x8F7D;&#xFF08;&#x514D;&#x8D39;&#x3001;&#x514D;&#x767B;&#x5F55;&#xFF09;&#x3002;<br>
&#x5173;&#x6CE8;&#x300C;APP&#x5F00;&#x53D1;&#x5B9E;&#x6218;&#x6D3E;&#x300D;&#x2014;&#x2014;&#x8FD9;&#x4E2A;&#x53F7;&#x65E2;&#x5206;&#x4EAB;&#x6211;&#x7684;&#x9E3F;&#x8499; App&#xFF0C;&#x4E5F;&#x62C6;&#x9E3F;&#x8499;&#x5F00;&#x53D1;&#x5B9E;&#x6218;&#x3002;&#x4E0B;&#x671F;&#x62C6;&#x300C;&#x901F;&#x5370; QuickMark&#x300D;&#x3002;</p>
</blockquote>
<p>&#x8F6C;&#x8F7D;&#x8BF7;&#x6CE8;&#x660E;&#x6765;&#x6E90;&#xFF1A;<br>
&#x539F;&#x6587;&#x94FE;&#x63A5;&#xFF1A;<a href="http://hanhan.pro/harmonyos-markbook-read-github-code-self-built-deflate-unzip">http://hanhan.pro/harmonyos-markbook-read-github-code-self-built-deflate-unzip</a><br>
&#x4F5C;&#x8005;&#xFF1A;Reno</p>
]]></content:encoded></item><item><title><![CDATA[写了多年前端，我做了第一个鸿蒙 App——MarkBook]]></title><description><![CDATA[一个前端工程师的 HarmonyOS 上手实录，附一个已上架的真实应用。]]></description><link>http://hanhan.pro/first-harmonyos-app-development-by-a-frontend-developer/</link><guid isPermaLink="false">6a6cb0478875400001ae5338</guid><category><![CDATA[前端]]></category><category><![CDATA[鸿蒙]]></category><category><![CDATA[app]]></category><category><![CDATA[应用开发]]></category><category><![CDATA[arkUI]]></category><category><![CDATA[arkTS]]></category><category><![CDATA[HarmonyOS]]></category><category><![CDATA[MarkBook]]></category><category><![CDATA[frontend]]></category><dc:creator><![CDATA[reno]]></dc:creator><pubDate>Fri, 31 Jul 2026 14:44:07 GMT</pubDate><media:content url="http://hanhan.pro/content/images/2026/07/IMG_2885.jpg" medium="image"/><content:encoded><![CDATA[<h2 id="%E5%89%8D%E7%AB%AF%E5%8E%BB%E6%90%9E%E9%B8%BF%E8%92%99%EF%BC%8C%E6%98%AF%E4%B8%8D%E6%98%AF%E6%83%B3%E4%B8%8D%E5%BC%80%EF%BC%9F">&#x524D;&#x7AEF;&#x53BB;&#x641E;&#x9E3F;&#x8499;&#xFF0C;&#x662F;&#x4E0D;&#x662F;&#x60F3;&#x4E0D;&#x5F00;&#xFF1F;</h2>
<img src="http://hanhan.pro/content/images/2026/07/IMG_2885.jpg" alt="&#x5199;&#x4E86;&#x591A;&#x5E74;&#x524D;&#x7AEF;&#xFF0C;&#x6211;&#x505A;&#x4E86;&#x7B2C;&#x4E00;&#x4E2A;&#x9E3F;&#x8499; App&#x2014;&#x2014;MarkBook"><p>&#x4F5C;&#x4E3A;&#x4E00;&#x4E2A;&#x5199;&#x4E86;&#x591A;&#x5E74;&#x524D;&#x7AEF;&#x3001;React / Vue / &#x5C0F;&#x7A0B;&#x5E8F;&#x90FD;&#x6478;&#x8FC7;&#x7684;&#x4EBA;&#xFF0C;&#x7B2C;&#x4E00;&#x6B21;&#x6253;&#x5F00; DevEco Studio&#x3001;&#x9762;&#x5BF9;&#x6EE1;&#x5C4F;&#x7684; <code>.ets</code> &#x6587;&#x4EF6;&#x65F6;&#xFF0C;&#x6211;&#x7684;&#x7B2C;&#x4E00;&#x53CD;&#x5E94;&#x548C;&#x5927;&#x591A;&#x6570;&#x540C;&#x884C;&#x4E00;&#x6837;&#xFF1A;<strong>&#x53C8;&#x4E00;&#x4E2A;&#x8981;&#x91CD;&#x65B0;&#x5B66;&#x7684;&#x8BED;&#x8A00;&#xFF1F;</strong></p>
<p>&#x4F46;&#x771F;&#x6B63;&#x4E0A;&#x624B;&#x4E4B;&#x540E;&#x6211;&#x53D1;&#x73B0;&#xFF0C;&#x4E8B;&#x60C5;&#x6CA1;&#x90A3;&#x4E48;&#x7CDF;&#x2014;&#x2014;ArkTS &#x770B;&#x8D77;&#x6765;&#x548C; TypeScript &#x51E0;&#x4E4E;&#x4E00;&#x6837;&#xFF0C;ArkUI &#x7684;&#x58F0;&#x660E;&#x5F0F;&#x5199;&#x6CD5;&#x4E5F;&#x548C; React/Vue &#x6709;&#x516B;&#x5206;&#x795E;&#x4F3C;&#x3002;&#x771F;&#x6B63;&#x8BA9;&#x6211;&quot;&#x5361;&#x4F4F;&quot;&#x7684;&#xFF0C;&#x662F;&#x90A3;&#x4E9B;&#x5B98;&#x65B9;&#x6587;&#x6863;&#x6CA1;&#x660E;&#x8BF4;&#x7684;&#x4E25;&#x683C;&#x6A21;&#x5F0F;&#x548C;&#x5DE5;&#x5177;&#x94FE;&#x7EC6;&#x8282;&#x3002;</p>
<p>&#x4E8E;&#x662F;&#x5C31;&#x6709;&#x4E86;&#x4ECA;&#x5929;&#x8FD9;&#x7BC7;&#x6587;&#x7AE0;&#x7684;&#x4E3B;&#x89D2;&#xFF1A;<strong>MarkBook</strong>&#x2014;&#x2014;&#x4E00;&#x6B3E;&#x5DF2;&#x7ECF;&#x4E0A;&#x67B6;&#x534E;&#x4E3A;&#x5E94;&#x7528;&#x5E02;&#x573A;&#x7684;&#x9E3F;&#x8499;&#x539F;&#x751F;&#x5E94;&#x7528;&#xFF0C;&#x4E00;&#x4E2A;&#x8FD0;&#x884C;&#x5728;&#x624B;&#x673A;&#x4E0A;&#x7684; Git &#x4ED3;&#x5E93;&#x7BA1;&#x7406;&#x5BA2;&#x6237;&#x7AEF;&#xFF0C;&#x7EAF; ArkTS &#x5B9E;&#x73B0;&#x3002;</p>
<p>&#x8FD9;&#x7BC7;&#x6587;&#x7AE0;&#x60F3;&#x804A;&#x804A;&#xFF0C;&#x4F5C;&#x4E3A;&#x4E00;&#x4E2A;&#x6709;&#x7ECF;&#x9A8C;&#x7684;&#x524D;&#x7AEF;&#x5DE5;&#x7A0B;&#x5E08;&#xFF0C;&#x505A;&#x9E3F;&#x8499;&#x5E94;&#x7528;&#x5230;&#x5E95;&#x80FD;&quot;&#x767D;&#x6361;&quot;&#x54EA;&#x4E9B;&#x4F18;&#x52BF;&#x3001;&#x5FC5;&#x987B;&#x8865;&#x54EA;&#x4E9B;&#x8BFE;&#xFF0C;&#x4EE5;&#x53CA; ArkTS &#x548C; JS/TS&#x3001;ArkUI &#x548C; React/Vue &#x5230;&#x5E95;&#x5DEE;&#x5728;&#x54EA;&#x3002;</p>
<p><strong>&#x6838;&#x5FC3;&#x7ED3;&#x8BBA;&#x653E;&#x524D;&#x9762;&#xFF1A;&#x53EA;&#x8981;&#x4F60;&#x4F1A; TypeScript + &#x4E00;&#x79CD;&#x58F0;&#x660E;&#x5F0F; UI &#x6846;&#x67B6;&#xFF0C;&#x4E0A;&#x624B; ArkTS/ArkUI &#x7684;&#x6210;&#x672C;&#x5927;&#x6982;&#x662F;&#x4E00;&#x5230;&#x4E24;&#x5468;&#x3002;</strong> &#x524D;&#x7AEF;&#x8F6C;&#x9E3F;&#x8499;&#xFF0C;&#x6BD4;&#x60F3;&#x8C61;&#x4E2D;&#x5E73;&#x6ED1;&#x5F97;&#x591A;&#x3002;</p>
<h2 id="%E4%B8%80%E3%80%81%E5%85%88%E6%90%9E%E6%B8%85%E6%A5%9A%EF%BC%9Aarkts-%E5%88%B0%E5%BA%95%E6%98%AF%E4%BB%80%E4%B9%88">&#x4E00;&#x3001;&#x5148;&#x641E;&#x6E05;&#x695A;&#xFF1A;ArkTS &#x5230;&#x5E95;&#x662F;&#x4EC0;&#x4E48;</h2>
<p>&#x4E00;&#x53E5;&#x8BDD;&#xFF1A;<strong>ArkTS &#x662F; TypeScript &#x7684;&#x4E25;&#x683C;&#x9759;&#x6001;&#x5B50;&#x96C6;</strong>&#xFF0C;&#x4E13;&#x95E8;&#x4E3A; ArkCompiler &#x7684; AOT &#x7F16;&#x8BD1;&#x4F18;&#x5316;&#x3002;</p>
<p>&#x5B83;&#x4FDD;&#x7559;&#x4E86; TS &#x7EDD;&#x5927;&#x90E8;&#x5206;&#x597D;&#x7528;&#x7684;&#x4E1C;&#x897F;&#x2014;&#x2014;interface&#x3001;&#x6CDB;&#x578B;&#x3001;async/await&#x2014;&#x2014;&#x4F46;&#x628A; TS &#x91CC;&quot;&#x7075;&#x6D3B;&quot;&#x7684;&#x90E8;&#x5206;&#x780D;&#x6389;&#x4E86;&#xFF0C;&#x6362;&#x53D6;&#x7F16;&#x8BD1;&#x671F;&#x5C31;&#x80FD;&#x786E;&#x5B9A;&#x7C7B;&#x578B;&#x7684;&#x786E;&#x5B9A;&#x6027;&#x3002;</p>
<table>
<thead>
<tr>
<th>&#x5BF9;&#x6BD4;&#x9879;</th>
<th>TypeScript / JavaScript</th>
<th>ArkTS</th>
</tr>
</thead>
<tbody>
<tr>
<td>&#x7C7B;&#x578B;&#x68C0;&#x67E5;</td>
<td>&#x7F16;&#x8BD1;&#x671F;&#x5BBD;&#x677E;&#xFF0C;any &#x6A2A;&#x884C;</td>
<td>&#x4E25;&#x683C;&#x6A21;&#x5F0F;&#xFF0C;<strong>&#x7981;&#x6B62; any/unknown</strong></td>
</tr>
<tr>
<td>&#x5BF9;&#x8C61;&#x5B57;&#x9762;&#x91CF;</td>
<td><code>const a = {}</code> &#x968F;&#x4FBF;&#x5199;</td>
<td>&#x9700;&#x8981;&#x663E;&#x5F0F; interface</td>
</tr>
<tr>
<td>delete</td>
<td>&#x652F;&#x6301;</td>
<td>&#x7981;&#x6B62;&#xFF08;&#x8D4B;&#x9ED8;&#x8BA4;&#x503C;&#x4EE3;&#x66FF;&#xFF09;</td>
</tr>
<tr>
<td>&#x89E3;&#x6784;</td>
<td>&#x5E38;&#x7528;</td>
<td>&#x53C2;&#x6570;/&#x58F0;&#x660E;&#x5C42;&#x7981;&#x6B62;&#x89E3;&#x6784;</td>
</tr>
<tr>
<td>&#x52A8;&#x6001;&#x52A0;&#x5C5E;&#x6027;</td>
<td><code>obj.x = 1</code></td>
<td>&#x9700;&#x8981;&#x663E;&#x5F0F;&#x7D22;&#x5F15;&#x8BBF;&#x95EE;</td>
</tr>
<tr>
<td>&#x72B6;&#x6001;&#x7BA1;&#x7406;</td>
<td>useState / ref / reactive</td>
<td>&#x88C5;&#x9970;&#x5668; @State/@Prop/@Link&#x2026;</td>
</tr>
<tr>
<td>UI</td>
<td>DOM + CSS</td>
<td>ArkUI &#x7EC4;&#x4EF6; + &#x94FE;&#x5F0F;&#x5C5E;&#x6027;</td>
</tr>
</tbody>
</table>
<p>&#x5BF9;&#x4F60;&#x6211;&#x8FD9;&#x79CD; TS &#x8001;&#x624B;&#x6765;&#x8BF4;&#xFF0C;&#x4E0A;&#x9762;&#x8FD9;&#x4E9B;&quot;&#x9650;&#x5236;&quot;&#x5176;&#x5B9E;&#x4E0D;&#x75DB;&#x4E0D;&#x75D2;&#x2014;&#x2014;&#x5199;&#x591A;&#x4E86;&#x53CD;&#x800C;&#x53D1;&#x73B0;&#xFF0C;<strong>&#x4E25;&#x683C;&#x6A21;&#x5F0F;&#x903C;&#x7740;&#x4F60;&#x5199;&#x51FA;&#x66F4;&#x7A33;&#x7684;&#x4EE3;&#x7801;</strong>&#x3002;</p>
<h2 id="%E4%BA%8C%E3%80%81%E5%89%8D%E7%AB%AF%E5%B7%A5%E7%A8%8B%E5%B8%88%E7%99%BD%E6%8D%A1%E7%9A%84%E5%9B%9B%E4%B8%AA%E4%BC%98%E5%8A%BF">&#x4E8C;&#x3001;&#x524D;&#x7AEF;&#x5DE5;&#x7A0B;&#x5E08;&quot;&#x767D;&#x6361;&quot;&#x7684;&#x56DB;&#x4E2A;&#x4F18;&#x52BF;</h2>
<h3 id="1-typescript-%E7%9B%B4%E6%8E%A5%E8%BF%81%E7%A7%BB">1. TypeScript &#x76F4;&#x63A5;&#x8FC1;&#x79FB;</h3>
<p>&#x5982;&#x679C;&#x4F60;&#x5728;&#x9879;&#x76EE;&#x91CC;&#x5DF2;&#x7ECF;&#x7528;&#x4E86; TS&#xFF0C;&#x90A3;&#x4E48; ArkTS &#x7684;&#x8BED;&#x6CD5;&#x4F60;&#x5927;&#x6982;&#x8BA4;&#x8BC6; 90%&#x3002;interface&#x3001;&#x6CDB;&#x578B;&#x3001;async/await&#x3001;&#x7C7B;&#x3001;&#x679A;&#x4E3E;&#x2026;&#x2026;&#x5168;&#x90E8;&#x76F4;&#x63A5;&#x80FD;&#x7528;&#x3002;</p>
<h3 id="2-%E5%A3%B0%E6%98%8E%E5%BC%8F-ui-%E5%93%8D%E5%BA%94%E5%BC%8F%E7%8A%B6%E6%80%81%EF%BC%8C%E5%B0%B1%E6%98%AF-reactvue-%E7%9A%84%E4%BA%B2%E6%88%9A">2. &#x58F0;&#x660E;&#x5F0F; UI + &#x54CD;&#x5E94;&#x5F0F;&#x72B6;&#x6001;&#xFF0C;&#x5C31;&#x662F; React/Vue &#x7684;&quot;&#x4EB2;&#x621A;&quot;</h3>
<p>ArkUI &#x7684;&#x6838;&#x5FC3;&#x5FC3;&#x667A;&#x6A21;&#x578B;&#x548C; React/Vue &#x51E0;&#x4E4E;&#x4E00;&#x6837;&#xFF1A;<strong>UI &#x662F;&#x72B6;&#x6001;&#x7684;&#x51FD;&#x6570;&#xFF0C;&#x72B6;&#x6001;&#x53D8;&#x4E86; UI &#x81EA;&#x52A8;&#x66F4;&#x65B0;</strong>&#x3002;</p>
<pre><code class="language-typescript">// ArkUI &#x7EC4;&#x4EF6;&#xFF1A;&#x58F0;&#x660E;&#x5F0F; + &#x54CD;&#x5E94;&#x5F0F;
@Entry
@Component
struct Counter {
  @State count: number = 0;      // &#x76F8;&#x5F53;&#x4E8E; useState / ref

  build() {
    Column() {                    // &#x76F8;&#x5F53;&#x4E8E; flex-direction: column
      Text(`&#x70B9;&#x51FB;&#x4E86; ${this.count} &#x6B21;`)
        .fontSize(20)
      Button(&apos;+1&apos;)
        .onClick(() =&gt; { this.count++; })   // &#x6539;&#x72B6;&#x6001;&#x81EA;&#x52A8;&#x5237;&#x65B0; UI
    }
  }
}
</code></pre>
<p>React &#x5F00;&#x53D1;&#x8005;&#x770B;&#x5230; <code>@State</code> &#x4F1A;&#x5FC3;&#x4E00;&#x7B11;&#x2014;&#x2014;&#x8FD9;&#x4E0D;&#x5C31;&#x662F; <code>useState</code> &#x5417;&#xFF1F;Vue &#x5F00;&#x53D1;&#x8005;&#x770B;&#x5230; <code>@State</code> &#x4E5F;&#x4F1A;&#x5FC3;&#x4E00;&#x7B11;&#x2014;&#x2014;&#x8FD9;&#x4E0D;&#x5C31;&#x662F; <code>ref</code> &#x5417;&#xFF1F;<strong>&#x58F0;&#x660E;&#x5F0F; + &#x54CD;&#x5E94;&#x5F0F; + &#x72B6;&#x6001;&#x9A71;&#x52A8;&#xFF0C;&#x524D;&#x7AEF;&#x6700;&#x6838;&#x5FC3;&#x7684;&#x601D;&#x7EF4;&#x6A21;&#x578B;&#x5728;&#x8FD9;&#x91CC;&#x5168;&#x90E8;&#x6210;&#x7ACB;&#x3002;</strong></p>
<h3 id="3-flex-%E5%B8%83%E5%B1%80%E6%80%9D%E7%BB%B4%E7%9B%B4%E6%8E%A5%E5%B9%B3%E7%A7%BB">3. Flex &#x5E03;&#x5C40;&#x601D;&#x7EF4;&#x76F4;&#x63A5;&#x5E73;&#x79FB;</h3>
<p>ArkUI &#x6CA1;&#x6709; CSS&#xFF0C;&#x4F46;&#x6709;&#x4F60;&#x719F;&#x6089;&#x7684; flex&#xFF1A;</p>
<ul>
<li><code>Column</code> = <code>display:flex; flex-direction: column</code></li>
<li><code>Row</code> = <code>display:flex; flex-direction: row</code></li>
<li><code>.layoutWeight(1)</code> = <code>flex: 1</code></li>
<li><code>Stack</code> = &#x5B9A;&#x4F4D;&#x53E0;&#x52A0;</li>
</ul>
<p>&#x5199;&#x8FC7;&#x5C0F;&#x7A0B;&#x5E8F;&#x6216; React Native &#x7684;&#x4EBA;&#xFF0C;&#x534A;&#x5C0F;&#x65F6;&#x5C31;&#x80FD;&#x4E0A;&#x624B; ArkUI &#x5E03;&#x5C40;&#x3002;</p>
<h3 id="4-%E8%B7%AF%E7%94%B1%E8%B7%B3%E8%BD%AC%E7%9A%84%E6%80%9D%E8%B7%AF%EF%BC%8C%E5%92%8C%E5%B0%8F%E7%A8%8B%E5%BA%8F-rn-%E6%98%AF%E5%90%8C%E4%B8%80%E5%A5%97">4. &#x8DEF;&#x7531;&#x8DF3;&#x8F6C;&#x7684;&#x601D;&#x8DEF;&#xFF0C;&#x548C;&#x5C0F;&#x7A0B;&#x5E8F; / RN &#x662F;&#x540C;&#x4E00;&#x5957;</h3>
<p>&#x524D;&#x7AEF;&#x6700;&#x719F;&#x7684;&#x8DEF;&#x7531;&#x8DF3;&#x8F6C;&#xFF0C;&#x5728;&#x9E3F;&#x8499;&#x4E0A;&#x4E5F;&#x662F;&#x8001;&#x719F;&#x4EBA;&#xFF0C;&#x4E09;&#x4E2A;&#x5E73;&#x53F0;&#x7684;&#x6838;&#x5FC3;&#x90FD;&#x662F;&#x300C;<strong>&#x8DEF;&#x7531;&#x6808; + push/pop + &#x4F20;&#x53C2;</strong>&#x300D;&#xFF1A;</p>
<table>
<thead>
<tr>
<th>&#x5E73;&#x53F0;</th>
<th>&#x8DF3;&#x8F6C;&#x5199;&#x6CD5;</th>
<th>&#x4F20;&#x53C2;&#x65B9;&#x5F0F;</th>
</tr>
</thead>
<tbody>
<tr>
<td>React Native</td>
<td><code>navigation.navigate(&apos;Detail&apos;, { id: 1 })</code></td>
<td>params &#x5BF9;&#x8C61;</td>
</tr>
<tr>
<td>&#x5FAE;&#x4FE1;&#x5C0F;&#x7A0B;&#x5E8F;</td>
<td><code>wx.navigateTo({ url: &apos;/pages/detail/detail?id=1&apos; })</code></td>
<td>URL query &#x5B57;&#x7B26;&#x4E32;</td>
</tr>
<tr>
<td>&#x9E3F;&#x8499;&#xFF08;Navigation&#xFF09;</td>
<td><code>pathStack.pushPath({ name: &apos;Detail&apos;, param: { id: 1 } })</code></td>
<td>param &#x5BF9;&#x8C61;</td>
</tr>
</tbody>
</table>
<pre><code class="language-typescript">// &#x9E3F;&#x8499;&#xFF1A;Navigation + NavPathStack
pathStack.pushPath({ name: &apos;Detail&apos;, param: { id: 1 } });   // &#x76F8;&#x5F53;&#x4E8E; RN &#x7684; navigate
pathStack.pop();                                             // &#x8FD4;&#x56DE;&#x4E0A;&#x4E00;&#x9875;
</code></pre>
<p>&#x533A;&#x522B;&#x53EA;&#x5728;&#x4E24;&#x70B9;&#xFF1A;</p>
<ul>
<li>&#x5C0F;&#x7A0B;&#x5E8F;&#x53C2;&#x6570;&#x8D70; <strong>URL query</strong>&#xFF0C;&#x5F97;&#x62FC;&#x5B57;&#x7B26;&#x4E32;&#x3001;&#x518D;&#x5E8F;&#x5217;&#x5316;&#xFF1B;RN &#x548C;&#x9E3F;&#x8499;&#x76F4;&#x63A5;&#x4F20; <strong>&#x5BF9;&#x8C61;</strong>&#xFF08;<code>param</code> &#x53EF;&#x4EE5;&#x662F;&#x4EFB;&#x610F;&#x53EF;&#x5E8F;&#x5217;&#x5316;&#x5BF9;&#x8C61;&#xFF09;</li>
<li>&#x5C0F;&#x7A0B;&#x5E8F;&#x8981;&#x628A;&#x9875;&#x9762;&#x6CE8;&#x518C;&#x8FDB; <code>app.json</code>&#xFF1B;&#x9E3F;&#x8499;&#x65B0;&#x7248;&#x7528; <code>Navigation</code> &#x7684; <code>navDestination</code> &#x58F0;&#x660E;&#x5F0F;&#x5206;&#x53D1;&#xFF0C;&#x4E0D;&#x7528;&#x5168;&#x5C40;&#x6CE8;&#x518C;&#x8868;&#xFF0C;&#x8DEF;&#x7531;&#x6808;&#x5BF9;&#x8C61;&#x8FD8;&#x80FD;&#x901A;&#x8FC7; <code>@Provide</code>/<code>@Consume</code> &#x5728;&#x7EC4;&#x4EF6;&#x6811;&#x91CC;&#x8DE8;&#x5C42;&#x4F20;&#x9012;&#xFF08;&#x601D;&#x8DEF;&#x7C7B;&#x4F3C; React Context&#xFF09;</li>
</ul>
<p>&#x5199;&#x8FC7;&#x5C0F;&#x7A0B;&#x5E8F;&#x6216; RN &#x7684;&#x4EBA;&#xFF0C;&#x9E3F;&#x8499;&#x7684;&#x8DEF;&#x7531;&#x51E0;&#x4E4E;&#x96F6;&#x6210;&#x672C;&#x8FC1;&#x79FB;&#x3002;</p>
<h2 id="%E4%B8%89%E3%80%81%E9%9C%80%E8%A6%81%E8%A1%A5%E8%AF%BE%E7%9A%84%E5%9B%9B%E4%B8%AA%E5%9C%B0%E6%96%B9">&#x4E09;&#x3001;&#x9700;&#x8981;&quot;&#x8865;&#x8BFE;&quot;&#x7684;&#x56DB;&#x4E2A;&#x5730;&#x65B9;</h2>
<p>&#x767D;&#x6361;&#x7684;&#x591A;&#xFF0C;&#x4F46;&#x8981;&#x8865;&#x7684;&#x4E5F;&#x4E0D;&#x5C11;&#x3002;&#x522B;&#x6015;&#xFF0C;&#x90FD;&#x662F;&quot;&#x5B66;&#x4E00;&#x6B21;&#x7BA1;&#x7EC8;&#x8EAB;&quot;&#x7684;&#x4E1C;&#x897F;&#x3002;</p>
<h3 id="1-arkts-%E4%B8%A5%E6%A0%BC%E6%A8%A1%E5%BC%8F-%E2%80%94%E2%80%94-%E6%9C%80%E5%AE%B9%E6%98%93%E8%A2%AB%E7%BC%96%E8%AF%91%E9%94%99%E8%AF%AF%E5%8A%9D%E9%80%80">1. ArkTS &#x4E25;&#x683C;&#x6A21;&#x5F0F; &#x2014;&#x2014; &#x6700;&#x5BB9;&#x6613;&#x88AB;&#x7F16;&#x8BD1;&#x9519;&#x8BEF;&#x529D;&#x9000;</h3>
<p>&#x524D;&#x7AEF;&#x7684; TS &#x9879;&#x76EE;&#x91CC; <code>any</code> &#x662F;&#x5E38;&#x6001;&#xFF0C;&#x4F46; ArkTS &#x4E25;&#x683C;&#x6A21;&#x5F0F;<strong>&#x7F16;&#x8BD1;&#x671F;&#x5C31;&#x62D2;&#x7EDD; any</strong>&#xFF0C;&#x62A5;&#x9519;&#x8FD8;&#x4F1A;&#x7ED9;&#x4F60;&#x4E00;&#x4E2A; <code>arkts-no-any-unknown</code> &#x8FD9;&#x6837;&#x7684;&#x4EE3;&#x53F7;&#x3002;&#x4E00;&#x5F00;&#x59CB;&#x5F88;&#x6293;&#x72C2;&#xFF0C;&#x5199;&#x51E0;&#x5468;&#x5C31;&#x4E60;&#x60EF;&#x4E86;&#xFF0C;&#x800C;&#x4E14;&#x4EE3;&#x7801;&#x8D28;&#x91CF;&#x8089;&#x773C;&#x53EF;&#x89C1;&#x5730;&#x53D8;&#x597D;&#x3002;</p>
<h3 id="2-arkui-%E7%BB%84%E4%BB%B6%E4%BD%93%E7%B3%BB-%E2%80%94%E2%80%94-%E4%B8%8D%E6%98%AF-css%EF%BC%8C%E6%98%AF%E9%93%BE%E5%BC%8F-api">2. ArkUI &#x7EC4;&#x4EF6;&#x4F53;&#x7CFB; &#x2014;&#x2014; &#x4E0D;&#x662F; CSS&#xFF0C;&#x662F;&#x94FE;&#x5F0F; API</h3>
<p>&#x6CA1;&#x6709; <code>.class{}</code> &#x9009;&#x62E9;&#x5668;&#xFF0C;&#x4E00;&#x5207;&#x7528;&#x94FE;&#x5F0F;&#x5C5E;&#x6027;&#xFF1A;</p>
<pre><code class="language-typescript">Column()
  .width(&apos;100%&apos;)
  .padding(16)
  .backgroundColor(&apos;#F5F5F5&apos;)
  .borderRadius(12)
</code></pre>
<p>&#x8BB0;&#x5FC6;&#x6210;&#x672C;&#x5728;&#x4E8E;&#x7EC4;&#x4EF6; API &#x5F88;&#x4E30;&#x5BCC;&#xFF08;List&#x3001;Scroll&#x3001;Grid&#x3001;Tabs&#x3001;Navigation&#x3001;Swiper&#x2026;&#x2026;&#xFF09;&#xFF0C;&#x4F46;&#x90FD;&#x9075;&#x5FAA;&#x540C;&#x4E00;&#x5957;&#x94FE;&#x5F0F;&#x98CE;&#x683C;&#xFF0C;&#x67E5;&#x4E00;&#x6B21;&#x6587;&#x6863;&#x5C31;&#x80FD;&#x4E3E;&#x4E00;&#x53CD;&#x4E09;&#x3002;</p>
<h3 id="3-stage-%E6%A8%A1%E5%9E%8B-%E2%80%94%E2%80%94-%E5%85%A8%E6%96%B0%E7%9A%84%E5%BA%94%E7%94%A8%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F">3. Stage &#x6A21;&#x578B; &#x2014;&#x2014; &#x5168;&#x65B0;&#x7684;&#x5E94;&#x7528;&#x751F;&#x547D;&#x5468;&#x671F;</h3>
<p>HarmonyOS &#x7528;&#x7684;&#x662F; Stage &#x6A21;&#x578B;&#xFF1A;<code>UIAbility</code> + <code>module.json5</code>&#xFF0C;&#x5BF9;&#x5E94;&#x524D;&#x7AEF;&#x7684;&quot;&#x5165;&#x53E3; + &#x914D;&#x7F6E;&#x6587;&#x4EF6;&quot;&#x3002;&#x6CA1;&#x6709; Android &#x7684; Activity&#x3001;&#x6CA1;&#x6709; iOS &#x7684; ViewController&#xFF0C;&#x9700;&#x8981;&#x91CD;&#x65B0;&#x7406;&#x89E3;&#x4E00;&#x6B21;&#x5E94;&#x7528;&#x662F;&#x600E;&#x4E48;&#x542F;&#x52A8;&#x3001;&#x600E;&#x4E48;&#x4F20;&#x53C2;&#x3001;&#x600E;&#x4E48;&#x9000;&#x5230;&#x540E;&#x53F0;&#x7684;&#x3002;</p>
<h3 id="4-%E5%B7%A5%E5%85%B7%E9%93%BE-%E2%80%94%E2%80%94-%E4%BB%8E-npm-%E5%88%B0-hvigor">4. &#x5DE5;&#x5177;&#x94FE; &#x2014;&#x2014; &#x4ECE; npm &#x5230; hvigor</h3>
<p>&#x6CA1;&#x6709; <code>npm run dev</code>&#xFF0C;&#x6784;&#x5EFA;&#x7528; <strong>hvigor</strong>&#xFF0C;&#x5305;&#x7BA1;&#x7406;&#x7528; <strong>ohpm</strong>&#xFF0C;&#x8C03;&#x8BD5;&#x9760; <strong>hilog</strong> &#x548C; DevEco Studio&#x3002;&#x7B7E;&#x540D;&#x3001;&#x4E0A;&#x67B6;&#x534E;&#x4E3A;&#x5E94;&#x7528;&#x5E02;&#x573A;&#x53C8;&#x662F;&#x4E00;&#x5957;&#x6D41;&#x7A0B;&#x3002;&#x8FD9;&#x4E9B;&#x6CA1;&#x6709;&#x5B66;&#x4E60;&#x95E8;&#x69DB;&#xFF0C;&#x7EAF;&#x7CB9;&#x662F;&quot;&#x719F;&#x80FD;&#x751F;&#x5DE7;&quot;&#x3002;</p>
<h2 id="%E5%9B%9B%E3%80%81%E6%88%91%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AA%E9%B8%BF%E8%92%99%E5%BA%94%E7%94%A8%EF%BC%9Amarkbook">&#x56DB;&#x3001;&#x6211;&#x7684;&#x7B2C;&#x4E00;&#x4E2A;&#x9E3F;&#x8499;&#x5E94;&#x7528;&#xFF1A;MarkBook</h2>
<p>&#x94FA;&#x57AB;&#x4E86;&#x8FD9;&#x4E48;&#x591A;&#xFF0C;&#x8BE5;&#x4E0A;&#x6B63;&#x83DC;&#x4E86;&#x3002;</p>
<p><strong>MarkBook &#x662F;&#x4EC0;&#x4E48;&#xFF1F;</strong> &#x4E00;&#x4E2A;&#x8FD0;&#x884C;&#x5728;&#x624B;&#x673A;&#x4E0A;&#x7684; Git &#x4ED3;&#x5E93;&#x7BA1;&#x7406;&#x5BA2;&#x6237;&#x7AEF;&#x3002;&#x4F60;&#x53EF;&#x4EE5;&#x6D4F;&#x89C8;&#x4EFB;&#x610F; Git &#x4ED3;&#x5E93;&#x7684;&#x6587;&#x4EF6;&#x6811;&#x3001;&#x67E5;&#x770B;&#x6587;&#x4EF6;&#x5185;&#x5BB9;&#x3001;Markdown &#x9884;&#x89C8;&#x3001;&#x6536;&#x85CF;&#x79BB;&#x7EBF;&#x9605;&#x8BFB;&#x3001;&#x67E5;&#x770B;&#x63D0;&#x4EA4;&#x5386;&#x53F2;&#x3002;&#x6838;&#x5FC3;&#x662F;&#x57FA;&#x4E8E; <strong>Git HTTP Smart Protocol</strong> &#x7684;&#x7EAF; ArkTS &#x5B9E;&#x73B0;&#xFF0C;&#x4E0D;&#x9700;&#x8981;&#x4EFB;&#x4F55;&#x540E;&#x7AEF;&#x3002;</p>
<p>&#x505A;&#x5B83;&#x7684;&#x539F;&#x56E0;&#x5F88;&#x6734;&#x7D20;&#xFF1A;&#x9E3F;&#x8499;&#x751F;&#x6001;&#x91CC;&#x51E0;&#x4E4E;&#x6CA1;&#x6709;&#x8D81;&#x624B;&#x7684; Git &#x5DE5;&#x5177;&#xFF0C;&#x800C;&#x6211;&#x5728; GitHub &#x4E0A;&#x770B;&#x4EE3;&#x7801;&#x7684;&#x4E60;&#x60EF;&#x53C8;&#x505C;&#x4E0D;&#x4E0B;&#x6765;&#x3002;<strong>&#x9700;&#x6C42;&#x6C38;&#x8FDC;&#x662F;&#x6700;&#x597D;&#x7684;&#x8001;&#x5E08;&#x3002;</strong></p>
<p>&#x4E0B;&#x9762;&#x6311;&#x4E24;&#x4E2A;&#x6700;&#x503C;&#x5F97;&#x8BF4;&#x7684;&#x529F;&#x80FD;&#x70B9;&#xFF0C;&#x8BB2;&#x8BB2;&#x5B9E;&#x73B0;&#x601D;&#x8DEF;&#x548C;&#x8E29;&#x8FC7;&#x7684;&#x5751;&#x3002;</p>
<h3 id="%E5%8A%9F%E8%83%BD%E7%82%B9%E4%B8%80%EF%BC%9A%E4%BB%8E%E9%9B%B6%E5%AE%9E%E7%8E%B0-git-http-smart-protocol">&#x529F;&#x80FD;&#x70B9;&#x4E00;&#xFF1A;&#x4ECE;&#x96F6;&#x5B9E;&#x73B0; Git HTTP Smart Protocol</h3>
<p>&#x9E3F;&#x8499;&#x4E0A;&#x6CA1;&#x6709;&#x73B0;&#x6210;&#x7684; Git &#x5BA2;&#x6237;&#x7AEF;&#x5E93;&#xFF0C;&#x6240;&#x4EE5;&#x6700;&#x786C;&#x6838;&#x7684;&#x90E8;&#x5206;&#x2014;&#x2014;<strong>Git &#x534F;&#x8BAE;&#x672C;&#x8EAB;</strong>&#x2014;&#x2014;&#x53EA;&#x80FD;&#x81EA;&#x5DF1;&#x5199;&#x3002;</p>
<p>&#x5B9E;&#x73B0;&#x601D;&#x8DEF;&#x5176;&#x5B9E;&#x662F;&#x4E00;&#x4E2A;&#x6807;&#x51C6;&#x6D41;&#x7A0B;&#xFF1A;</p>
<ol>
<li><strong>refs &#x53D1;&#x73B0;</strong>&#xFF1A;&#x8BF7;&#x6C42; <code>info/refs?service=git-upload-pack</code>&#xFF0C;&#x62FF;&#x5230;&#x5206;&#x652F;/&#x6807;&#x7B7E;&#x548C; HEAD</li>
<li><strong>fetch &#x8BF7;&#x6C42;</strong>&#xFF1A;&#x6309; Git Protocol v2 &#x53D1;&#x9001; <code>command=fetch</code> + <code>want</code> + <code>deepen</code></li>
<li><strong>&#x89E3;&#x6790;&#x54CD;&#x5E94;</strong>&#xFF1A;&#x5904;&#x7406; pkt-line &#x5206;&#x5E27; &#x2192; &#x627E;&#x5230; PACK &#x6BB5; &#x2192; &#x89E3;&#x6790; packfile&#xFF08;&#x53D8;&#x957F;&#x6574;&#x6570;&#x3001;delta &#x89E3;&#x538B;&#xFF09;&#x2192; DEFLATE &#x89E3;&#x538B; &#x2192; &#x8FD8;&#x539F;&#x51FA; commit / tree / blob &#x5BF9;&#x8C61;</li>
</ol>
<p>&#x4E0A;&#x9762;&#x8FD9;&#x5957;&#x6D41;&#x7A0B;&#x843D;&#x5230;&#x4EE3;&#x7801;&#x4E0A;&#xFF0C;&#x7B2C; 2 &#x6B65;&#x300C;&#x6784;&#x9020; fetch &#x8BF7;&#x6C42;&#x4F53;&#x300D;&#x5927;&#x6982;&#x957F;&#x8FD9;&#x6837;&#xFF1A;</p>
<pre><code class="language-typescript">// &#x6784;&#x9020; Git Protocol v2 fetch &#x8BF7;&#x6C42;&#xFF08;ArkTS&#xFF09;
const bodyLines: string[] = [];
bodyLines.push(this.encodePktLine(&apos;command=fetch\n&apos;));    // &#x534F;&#x8BAE;&#x547D;&#x4EE4;
bodyLines.push(&apos;0001&apos;);                                   // &#x80FD;&#x529B;/&#x53C2;&#x6570;&#x5206;&#x9694;&#x7B26;
bodyLines.push(this.encodePktLine(&apos;deepen 8\n&apos;));         // &#x53EA;&#x53D6;&#x6700;&#x8FD1; 8 &#x5C42;&#x5386;&#x53F2;&#xFF08;&#x6309;&#x4ED3;&#x5E93;&#x89C4;&#x6A21;&#x52A8;&#x6001;&#x8C03;&#x6574;&#xFF09;
bodyLines.push(this.encodePktLine(&apos;filter blob:none\n&apos;)); // &#x8DF3;&#x8FC7;&#x6587;&#x4EF6;&#x5185;&#x5BB9;&#xFF0C;&#x53EA;&#x8981; commit/tree
bodyLines.push(this.encodePktLine(&apos;done\n&apos;));
// &#x53D1;&#x8BF7;&#x6C42; &#x2192; &#x62FF;&#x54CD;&#x5E94; &#x2192; pkt-line &#x5206;&#x5E27; &#x2192; &#x627E; PACK &#x6BB5; &#x2192; &#x89E3;&#x6790; packfile &#x2192; DEFLATE &#x89E3;&#x538B;
const response = await this.httpPostBinary(url, bodyLines.join(&apos;&apos;),
  &apos;application/x-git-upload-pack-request&apos;);
</code></pre>
<p><strong>&#x96BE;&#x70B9;&#x4E3B;&#x8981;&#x5728;&#x4E09;&#x4E2A;&#x5730;&#x65B9;&#xFF1A;</strong></p>
<ul>
<li><strong>packfile &#x662F;&#x4E8C;&#x8FDB;&#x5236;&#x683C;&#x5F0F;</strong>&#xFF0C;&#x8FB9;&#x89D2;&#x7EC6;&#x8282;&#x6781;&#x591A;&#xFF08;ofs-delta&#x3001;ref-delta&#x3001;&#x53EF;&#x53D8;&#x957F;&#x7F16;&#x7801;&#x2026;&#x2026;&#xFF09;&#xFF0C;&#x548C;&#x524D;&#x7AEF;&#x719F;&#x6089;&#x7684; JSON &#x5B8C;&#x5168;&#x662F;&#x4E24;&#x4E2A;&#x4E16;&#x754C;</li>
<li><strong>API 24 &#x6CA1;&#x6709;&#x73B0;&#x6210;&#x7684; Inflater</strong>&#xFF0C;DEFLATE &#x89E3;&#x538B;&#x5F97;&#x81EA;&#x5DF1;&#x5B9E;&#x73B0;</li>
<li><strong>&#x5927;&#x4ED3;&#x5E93;&#x54CD;&#x5E94;&#x4F53;&#x79EF;&#x53EF;&#x8FBE;&#x51E0;&#x5341; MB</strong>&#xFF0C;&#x89E3;&#x6790;&#x65F6;&#x7684;&#x5185;&#x5B58;&#x5CF0;&#x503C;&#x63A7;&#x5236;&#x4E0D;&#x597D;&#x5C31; OOM</li>
</ul>
<p>&#x8FD9;&#x90E8;&#x5206;&#x7684;&#x6536;&#x83B7;&#x662F;&quot;&#x8DE8;&#x8BED;&#x8A00;&#x901A;&#x7528;&quot;&#x7684;&#xFF1A;&#x641E;&#x61C2; Git &#x7684;&#x5BF9;&#x8C61;&#x6A21;&#x578B;&#x548C; pack &#x683C;&#x5F0F;&#x4E4B;&#x540E;&#xFF0C;&#x4EFB;&#x4F55;&#x5E73;&#x53F0;&#x4E0A;&#x5199; Git &#x5DE5;&#x5177;&#x90FD;&#x6709;&#x5E95;&#x3002;</p>
<h3 id="%E5%8A%9F%E8%83%BD%E7%82%B9%E4%BA%8C%EF%BC%9A%E5%A4%A7%E4%BB%93%E5%BA%93%E7%9A%84%E6%80%A7%E8%83%BD%E4%B8%8E%E5%86%85%E5%AD%98%E4%BC%98%E5%8C%96">&#x529F;&#x80FD;&#x70B9;&#x4E8C;&#xFF1A;&#x5927;&#x4ED3;&#x5E93;&#x7684;&#x6027;&#x80FD;&#x4E0E;&#x5185;&#x5B58;&#x4F18;&#x5316;</h3>
<p>&#x524D;&#x7AEF;&#x5BF9;&#x6027;&#x80FD;&#x5929;&#x7136;&#x654F;&#x611F;&#xFF0C;&#x8FD9;&#x4E2A;&#x4E60;&#x60EF;&#x5728;&#x9E3F;&#x8499;&#x4E0A;&#x5E2E;&#x4E86;&#x6211;&#x5927;&#x5FD9;&#x3002;</p>
<p>&#x4EE5; tensorflow &#x8FD9;&#x79CD;&#x8D85;&#x5927;&#x4ED3;&#x5E93;&#x4E3A;&#x4F8B;&#xFF1A;&#x5982;&#x679C;&#x6309;&quot;&#x9010;&#x5C42;&#x904D;&#x5386;&#x6587;&#x4EF6;&#x6811;&quot;&#x7684;&#x65B9;&#x5F0F;&#xFF0C;&#x6BCF;&#x4E2A;&#x76EE;&#x5F55;&#x8981; 2~5 &#x6B21; HTTP &#x8BF7;&#x6C42;&#xFF0C;&#x8D70;&#x4E00;&#x904D;&#x4E0B;&#x6765;&#x8BF7;&#x6C42;&#x91CF;&#x7206;&#x70B8;&#xFF0C;&#x8FD8;&#x6781;&#x6613; OOM&#x3002;&#x6211;&#x7684;&#x5E94;&#x5BF9;&#x7B56;&#x7565;&#x662F;&#xFF1A;</p>
<ul>
<li><strong>&#x5927;&#x4ED3;&#x5E93;&#x6A21;&#x5F0F;</strong>&#xFF1A;&#x54CD;&#x5E94;&#x4E0A;&#x9650;&#x4ECE; 2MB &#x653E;&#x5BBD;&#xFF0C;&#x914D;&#x5408;&#x964D;&#x7EA7;&#x786E;&#x8BA4;&#x5F39;&#x7A97;</li>
<li><strong>blob SHA &#x76F4;&#x53D6;</strong>&#xFF1A;&#x6587;&#x4EF6;&#x5217;&#x8868;&#x8FD4;&#x56DE; blob SHA&#xFF0C;&#x8BE6;&#x60C5;&#x9875;&#x76F4;&#x63A5;&#x6309; SHA &#x62C9;&#x5185;&#x5BB9;&#xFF0C;&#x7ED5;&#x8FC7;&#x6574;&#x68F5;&#x6811;&#x7684;&#x904D;&#x5386;</li>
<li><strong>&#x6ED1;&#x52A8;&#x7A97;&#x53E3;</strong>&#xFF1A;&#x5305;&#x6570;&#x636E;&#x5185;&#x5B58;&#x6309;&#x9700;&#x91CA;&#x653E;&#xFF0C;&#x7F13;&#x5B58;&#x8BBE;&#x4E0A;&#x9650;&#xFF0C;&#x9632;&#x6B62;&#x5BF9;&#x8C61;&#x6EDE;&#x7559;&#x5806;&#x5185;&#x5B58;</li>
<li><strong>&#x63D0;&#x4EA4;&#x5386;&#x53F2;&#x6309;&#x4ED3;&#x5E93;&#x89C4;&#x6A21;&#x52A8;&#x6001;&#x964D;&#x7EA7;</strong>&#xFF1A;&#x5206;&#x652F;&#x591A;&#x7684;&#x5927;&#x4ED3;&#x5E93;&#x9010; commit &#x83B7;&#x53D6;&#xFF0C;&#x63A7;&#x5236;&#x5185;&#x5B58;&#x5CF0;&#x503C;</li>
</ul>
<p>&#x5176;&#x4E2D;&#x6700;&#x7ACB;&#x7AFF;&#x89C1;&#x5F71;&#x7684;&#x662F;&#x300C;blob SHA &#x76F4;&#x53D6;&#x300D;&#x2014;&#x2014;&#x6587;&#x4EF6;&#x5217;&#x8868;&#x628A; blob SHA &#x4E00;&#x8D77;&#x8FD4;&#x56DE;&#xFF0C;&#x8BE6;&#x60C5;&#x9875;&#x76F4;&#x63A5;&#x6309; SHA &#x62C9;&#x5185;&#x5BB9;&#xFF0C;&#x5B8C;&#x5168;&#x8DF3;&#x8FC7;&#x6811;&#x904D;&#x5386;&#xFF1A;</p>
<pre><code class="language-typescript">// &#x8BE6;&#x60C5;&#x9875;&#xFF1A;&#x4F18;&#x5148;&#x7528;&#x6587;&#x4EF6;&#x5217;&#x8868;&#x4F20;&#x6765;&#x7684; blob SHA &#x76F4;&#x63A5;&#x83B7;&#x53D6;&#x5185;&#x5BB9;
const blobSha = AppStorage.get&lt;string&gt;(&apos;detail_blob_sha&apos;) ?? &apos;&apos;;
if (blobSha !== &apos;&apos;) {
  content = await this.gitService.getBlob(blobSha);      // &#x4E00;&#x6761;&#x8BF7;&#x6C42;&#x641E;&#x5B9A;
} else {
  content = await this.gitService.getFileContentByPath(  // &#x56DE;&#x9000;&#xFF1A;&#x6CBF;&#x6811;&#x9010;&#x5C42;&#x627E;
    this.filePath, ref || undefined);
}
</code></pre>
<p><strong>&#x505A;&#x5F97;&#x597D;&#x7684;&#x5730;&#x65B9;&#xFF1A;</strong> &#x7EAF; ArkTS &#x96F6;&#x7B2C;&#x4E09;&#x65B9;&#x4F9D;&#x8D56;&#x8DD1;&#x901A;&#x5B8C;&#x6574; Git &#x534F;&#x8BAE;&#xFF1B;&#x5927;&#x4ED3;&#x5E93;&#x4ECE;&quot;&#x76F4;&#x63A5;&#x5D29;&quot;&#x5230;&quot;&#x80FD;&#x6253;&#x5F00;&quot;&#xFF1B;Markdown &#x6E32;&#x67D3;&#x3001;&#x4EE3;&#x7801;&#x9AD8;&#x4EAE;&#x3001;&#x6DF1;&#x6D45;&#x8272;&#x4E3B;&#x9898;&#x8FD9;&#x4E9B;&#x4F53;&#x9A8C;&#x4E5F;&#x505A;&#x5B8C;&#x4E86;&#x3002;</p>
<p><strong>&#x8FD8;&#x80FD;&#x4F18;&#x5316;&#x7684;&#x5730;&#x65B9;&#xFF1A;</strong> &#x6587;&#x4EF6;&#x7EA7;&#x63D0;&#x4EA4;&#x5386;&#x53F2;&#x76EE;&#x524D;&#x5728;&#x4E3B;&#x7EBF;&#x7A0B;&#x89E3;&#x6790; packfile&#xFF0C;&#x8D85;&#x5927;&#x4ED3;&#x5E93;&#x4F1A;&#x89E6;&#x53D1;&#x7CFB;&#x7EDF; <code>THREAD_BLOCK_6S</code> &#x88AB;&#x5F3A;&#x6740;&#xFF0C;&#x540E;&#x7EED;&#x8981;&#x6539;&#x6210; TaskPool &#x540E;&#x53F0;&#x7EBF;&#x7A0B;&#xFF1B;Git &#x64CD;&#x4F5C;&#x76EE;&#x524D;&#x4EE5;&quot;&#x6D4F;&#x89C8;&quot;&#x4E3A;&#x4E3B;&#xFF0C;&#x63D0;&#x4EA4;&#x3001;&#x63A8;&#x9001;&#x3001;&#x5206;&#x652F;&#x7BA1;&#x7406;&#x8FD8;&#x6CA1;&#x505A;&#xFF1B;&#x672C;&#x5730;&#x7F13;&#x5B58;&#x548C;&#x79BB;&#x7EBF;&#x80FD;&#x529B;&#x4E5F;&#x503C;&#x5F97;&#x52A0;&#x5F3A;&#x3002;</p>
<h2 id="%E4%BA%94%E3%80%81%E7%BB%99%E6%83%B3%E5%B0%9D%E8%AF%95%E7%9A%84%E5%89%8D%E7%AB%AF%E5%90%8C%E8%A1%8C%E7%9A%84%E5%BB%BA%E8%AE%AE">&#x4E94;&#x3001;&#x7ED9;&#x60F3;&#x5C1D;&#x8BD5;&#x7684;&#x524D;&#x7AEF;&#x540C;&#x884C;&#x7684;&#x5EFA;&#x8BAE;</h2>
<ol>
<li><strong>&#x522B;&#x88AB;&quot;&#x65B0;&#x8BED;&#x8A00;&quot;&#x5413;&#x4F4F;</strong>&#xFF1A;ArkTS &#x662F; TS &#x7684;&#x4E25;&#x683C;&#x5B50;&#x96C6;&#xFF0C;&#x4E0D;&#x662F;&#x65B0;&#x8BED;&#x8A00;&#x3002;&#x771F;&#x6B63;&#x7684;&#x65B0;&#x4E1C;&#x897F;&#x662F; ArkUI &#x7EC4;&#x4EF6;&#x5E93;&#x548C; Stage &#x6A21;&#x578B;&#xFF0C;&#x4F46;&#x90FD;&#x6709;&#x5B98;&#x65B9;&#x6587;&#x6863;&#x548C;&#x793A;&#x4F8B;&#x5DE5;&#x7A0B;&#x3002;</li>
<li><strong>&#x4ECE; DevEco Studio &#x7684;&#x6A21;&#x677F;&#x5DE5;&#x7A0B;&#x5F00;&#x59CB;</strong>&#xFF1A;&#x4E0D;&#x8981;&#x81EA;&#x5DF1;&#x4ECE;&#x96F6;&#x642D;&#x73AF;&#x5883;&#xFF0C;&#x6A21;&#x677F;&#x4F1A;&#x5E2E;&#x4F60;&#x641E;&#x5B9A; hvigor/ohpm &#x7684;&#x7248;&#x672C;&#x5339;&#x914D;&#xFF0C;&#x80FD;&#x7701;&#x6389;&#x4F60;&#x534A;&#x5929;&#x5230;&#x4E00;&#x5929;&#x7684;&#x8E29;&#x5751;&#x65F6;&#x95F4;&#x3002;</li>
<li><strong>&#x6027;&#x80FD;&#x601D;&#x7EF4;&#x662F;&#x524D;&#x7AEF;&#x7684;&#x4F18;&#x52BF;</strong>&#xFF1A;&#x9E3F;&#x8499;&#x751F;&#x6001;&#x8FD8;&#x5E74;&#x8F7B;&#xFF0C;&#x5F88;&#x591A;&quot;&#x6027;&#x80FD;&#x4F18;&#x5316;&quot;&#x7684;&#x5751;&#xFF08;OOM&#x3001;&#x4E3B;&#x7EBF;&#x7A0B;&#x963B;&#x585E;&#xFF09;&#x8FD8;&#x6CA1;&#x6709;&#x5B8C;&#x6574;&#x7684;&#x793E;&#x533A;&#x7B54;&#x6848;&#xFF0C;&#x800C;&#x524D;&#x7AEF;&#x5DE5;&#x7A0B;&#x5E08;&#x5929;&#x751F;&#x5BF9;&#x6E32;&#x67D3;&#x6027;&#x80FD;&#x3001;&#x5185;&#x5B58;&#x6CC4;&#x6F0F;&#x654F;&#x611F;&#x2014;&#x2014;&#x8FD9;&#x6070;&#x6070;&#x662F;&#x6211;&#x4EEC;&#x7684;&#x5DEE;&#x5F02;&#x5316;&#x4F18;&#x52BF;&#x3002;</li>
<li><strong>&#x5148;&#x628A;&#x4E00;&#x4E2A;&#x529F;&#x80FD;&#x505A;&#x95ED;&#x73AF;</strong>&#xFF1A;&#x4E0D;&#x8981;&#x8D2A;&#x591A;&#xFF0C;&#x628A;&#x4E00;&#x4E2A;&#x6838;&#x5FC3;&#x529F;&#x80FD;&#x4ECE;&quot;&#x80FD;&#x7528;&quot;&#x505A;&#x5230;&quot;&#x597D;&#x7528;&quot;&#xFF0C;&#x6BD4;&#x5806;&#x529F;&#x80FD;&#x5217;&#x8868;&#x6709;&#x4EF7;&#x503C;&#x5F97;&#x591A;&#x3002;</li>
</ol>
<h2 id="%E5%85%AD%E3%80%81%E6%9C%80%E5%90%8E">&#x516D;&#x3001;&#x6700;&#x540E;</h2>
<p>&#x5982;&#x679C;&#x4F60;&#x624B;&#x8FB9;&#x6709;&#x9E3F;&#x8499;&#x8BBE;&#x5907;&#xFF0C;&#x6B22;&#x8FCE;&#x53BB;&#x534E;&#x4E3A;&#x5E94;&#x7528;&#x5E02;&#x573A;&#x641C;&#x7D22; <strong>MarkBook</strong> &#x8BD5;&#x8BD5;&#x2014;&#x2014;&#x4E00;&#x4E2A;&#x524D;&#x7AEF;&#x5DE5;&#x7A0B;&#x5E08;&#x4ECE;&#x96F6;&#x505A;&#x51FA;&#x6765;&#x7684;&#x3001;&#x5DF2;&#x4E0A;&#x67B6;&#x7684;&#x9E3F;&#x8499;&#x5E94;&#x7528;&#x3002;&#x5982;&#x679C;&#x4F60;&#x4E5F;&#x6B63;&#x5728;&#x89C2;&#x671B;&#x9E3F;&#x8499;&#x5F00;&#x53D1;&#xFF0C;&#x5E0C;&#x671B;&#x8FD9;&#x7BC7;&#x6587;&#x7AE0;&#x80FD;&#x8BA9;&#x4F60;&#x5C11;&#x4E00;&#x70B9;&#x72B9;&#x8C6B;&#x3002;</p>
<p><strong>&#x524D;&#x7AEF;&#x5F00;&#x53D1;&#x9E3F;&#x8499;&#xFF0C;&#x96BE;&#x7684;&#x4E0D;&#x662F;&#x8BED;&#x8A00;&#xFF0C;&#x662F;&#x8FC8;&#x51FA;&#x7B2C;&#x4E00;&#x6B65;&#x7684;&#x52C7;&#x6C14;&#x3002;</strong> &#x800C;&#x6211;&#x4EEC;&#x6070;&#x597D;&#x4E0D;&#x7F3A;&#x8FD9;&#x4E2A;&#x3002;</p>
<p>&#x8F6C;&#x8F7D;&#x8BF7;&#x6CE8;&#x660E;&#x6765;&#x6E90;&#xFF1A;</p>
<ul>
<li>&#x539F;&#x6587;&#x94FE;&#x63A5;&#xFF1A;<a href="http://hanhan.pro/first-harmonyos-app-development-by-a-frontend-developer/">https://hanhan.pro/first-harmonyos-app-development-by-a-frontend-developer/</a></li>
<li>&#x4F5C;&#x8005;&#xFF1A;Reno</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[整合qiankun微前端框架心得笔记]]></title><description><![CDATA[由于项目需要，使用qiankun框架整合了三个系统，一个vue3+vite2的项目和两个vue2的项目，主应用是vue3+vite2的项目。
这次整合涉及到vue3、vite以及服务器部署，所以踩了很多坑，最终搞定了本地和测试环境的整合。]]></description><link>http://hanhan.pro/using-qiankun-micro-frontends-solution/</link><guid isPermaLink="false">6596a4b993ef2d0001f41553</guid><category><![CDATA[前端]]></category><category><![CDATA[qiankun]]></category><category><![CDATA[乾坤]]></category><category><![CDATA[微前端框架]]></category><category><![CDATA[micro-frontends]]></category><dc:creator><![CDATA[reno]]></dc:creator><pubDate>Thu, 08 Dec 2022 07:15:10 GMT</pubDate><media:content url="http://hanhan.pro/content/images/2022/12/qiankun-blue.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://hanhan.pro/content/images/2022/12/qiankun-blue.jpg" alt="&#x6574;&#x5408;qiankun&#x5FAE;&#x524D;&#x7AEF;&#x6846;&#x67B6;&#x5FC3;&#x5F97;&#x7B14;&#x8BB0;"><p>&#x672C;&#x6587;&#x4E3B;&#x8981;&#x8BB2;&#x6574;&#x5408;&#x601D;&#x8DEF;&#x548C;&#x4E00;&#x4E9B;&#x5FC3;&#x5F97;&#x5C0F;&#x7ED3;&#xFF0C;&#x800C;&#x4E0D;&#x4EC5;&#x4EC5;&#x662F;&#x7B80;&#x5355;&#x5730;&#x8BB2;&#x64CD;&#x4F5C;&#x6B65;&#x9AA4;&#x3002;&#x7136;&#x540E;&#x5217;&#x51FA;&#x4E00;&#x4E9B;&#x8981;&#x70B9;&#xFF0C;&#x5E2E;&#x5927;&#x5BB6;&#x907F;&#x5751;&#x3002;<br>
&#x5EFA;&#x8BAE;&#x6700;&#x597D;&#x5148;&#x770B;qiankun&#x5B98;&#x7F51;&#x5BF9;qiankun&#x6709;&#x4E00;&#x70B9;&#x4E86;&#x89E3;&#x518D;&#x770B;&#x672C;&#x6587;&#xFF0C;&#x6216;&#x8005;&#x5B98;&#x7F51;&#x6587;&#x6863;&#x7ED3;&#x5408;&#x672C;&#x6587;&#x4E00;&#x8D77;&#x770B;&#x3002;</p>
<h2 id="%E6%8E%A5%E5%85%A5qiankun%E6%A1%86%E6%9E%B6%E5%89%8D%E9%9C%80%E8%A6%81%E5%87%86%E5%A4%87%E7%9A%84%E5%B7%A5%E4%BD%9C">&#x63A5;&#x5165;qiankun&#x6846;&#x67B6;&#x524D;&#x9700;&#x8981;&#x51C6;&#x5907;&#x7684;&#x5DE5;&#x4F5C;</h2>
<p>&#x4F7F;&#x7528;qiankun&#x6846;&#x67B6;&#x4E00;&#x822C;&#x662F;&#x7528;&#x6765;&#x6574;&#x5408;PC&#x7AEF;&#x540E;&#x53F0;&#x7BA1;&#x7406;&#x7CFB;&#x7EDF;&#x3002;&#x5728;&#x6574;&#x5408;&#x8FD9;&#x4E9B;&#x540E;&#x53F0;&#x7CFB;&#x7EDF;&#x4E4B;&#x524D;&#xFF0C;&#x4F60;&#x9700;&#x8981;&#x8003;&#x8651;&#x548C;&#x51C6;&#x5907;&#x4EE5;&#x4E0B;&#x4E8B;&#x60C5;&#xFF1A;</p>
<ol>
<li>&#x65B0;&#x5F00;&#x4E00;&#x4E2A;&#x7B80;&#x5355;&#x7684;&#x9879;&#x76EE;&#x4F5C;&#x4E3A;&#x4E3B;&#x5E94;&#x7528;&#xFF1A;&#x4E3B;&#x5E94;&#x7528;&#x662F;&#x7528;&#x6765;&#x653E;&#x7EDF;&#x4E00;&#x767B;&#x5F55;&#x7684;&#x9875;&#x9762;&#xFF0C;&#x548C;&#x5404;&#x5B50;&#x5E94;&#x7528;&#x5165;&#x53E3;&#x7684;&#x4E00;&#x4E2A;&#x9875;&#x9762;&#x3002;&#x9996;&#x5148;&#x662F;&#x9700;&#x8981;&#x4E00;&#x4E2A;&#x65B0;&#x9879;&#x76EE;&#x505A;&#x4E3A;qiankun&#x6846;&#x67B6;&#x7684;&#x4E3B;&#x5E94;&#x7528;&#xFF0C;&#x5728;&#x5176;&#x6B21;&#x662F;&#x8003;&#x8651;&#x5230;&#x6743;&#x9650;&#x95EE;&#x9898;&#xFF0C;&#x4E0D;&#x80FD;&#x62FF;&#x4EFB;&#x4E00;&#x5B50;&#x5E94;&#x7528;&#x4F5C;&#x4E3A;&#x4E3B;&#x5E94;&#x7528;&#x5165;&#x53E3;&#xFF0C;&#x7136;&#x540E;&#x4E5F;&#x65B9;&#x4FBF;&#x5F00;&#x53D1;&#x548C;&#x7EF4;&#x62A4;&#x3002;</li>
<li>&#x6574;&#x5408;&#x540E;&#x7CFB;&#x7EDF;&#x767B;&#x5F55;&#x65B9;&#x5F0F;&#xFF1A;&#x4F7F;&#x7528;&#x5355;&#x70B9;&#x767B;&#x5F55;&#x8FD8;&#x662F;&#x4EC0;&#x4E48;&#x65B9;&#x5F0F;&#xFF0C;&#x8FD9;&#x4E2A;&#x9700;&#x8981;&#x6839;&#x636E;&#x81EA;&#x5DF1;&#x7684;&#x9879;&#x76EE;&#x60C5;&#x51B5;&#x548C;&#x9879;&#x76EE;&#x9700;&#x6C42;&#x51B3;&#x5B9A;&#x3002;&#x4E0D;&#x505A;&#x7EDF;&#x4E00;&#x767B;&#x5F55;&#x7684;&#x8BDD;&#xFF0C;&#x6574;&#x5408;&#x8D77;&#x6765;&#x540E;&#x5404;&#x4E2A;&#x5B50;&#x7CFB;&#x7EDF;&#x8FD8;&#x9700;&#x8981;&#x5404;&#x81EA;&#x767B;&#x5F55;&#x3002;</li>
<li>&#x6574;&#x5408;&#x540E;&#x670D;&#x52A1;&#x5668;&#x7AEF;&#x90E8;&#x7F72;&#x65B9;&#x6848;&#xFF1A;&#x6574;&#x5408;&#x524D;&#x53EF;&#x80FD;&#x51E0;&#x4E2A;&#x9879;&#x76EE;&#x90E8;&#x7F72;&#x5728;&#x4E0D;&#x540C;&#x670D;&#x52A1;&#x5668;&#xFF0C;&#x6574;&#x5408;&#x540E;&#x9700;&#x8981;&#x8003;&#x8651;&#x662F;&#x4E0D;&#x662F;&#x653E;&#x5728;&#x540C;&#x4E00;&#x53F0;&#x670D;&#x52A1;&#x5668;&#x3002;</li>
<li>&#x8DEF;&#x7531;&#x7684;history&#x6A21;&#x5F0F;&#x6700;&#x597D;&#x7EDF;&#x4E00;&#xFF1A;&#x672C;&#x6587;&#x51E0;&#x4E2A;&#x5B50;&#x7CFB;&#x7EDF;&#x7684;history&#x6A21;&#x5F0F;&#x7EDF;&#x4E00;&#x4F7F;&#x7528;&#x7684;<code>history</code>&#x3002;</li>
</ol>
<p>&#x6574;&#x5408;&#x524D;&#x4E3B;&#x8981;&#x662F;&#x8003;&#x8651;&#x548C;&#x51C6;&#x5907;&#x597D;&#x8FD9;&#x51E0;&#x70B9;&#xFF0C;&#x53EF;&#x4EE5;&#x5728;&#x6574;&#x5408;&#x8FC7;&#x7A0B;&#x4E2D;&#x5C11;&#x8D70;&#x5F2F;&#x8DEF;&#x3002;&#x8FD9;&#x6BCF;&#x4E00;&#x70B9;&#x53C8;&#x6D89;&#x53CA;&#x5230;&#x5F88;&#x591A;&#x7EC6;&#x8282;&#xFF0C;&#x9700;&#x8981;&#x5728;&#x6574;&#x5408;&#x5F00;&#x53D1;&#x7684;&#x8FC7;&#x7A0B;&#x53BB;&#x89E3;&#x51B3;&#xFF0C;&#x6BD4;&#x5982;&#x5B50;&#x5E94;&#x7528;&#x8DDF;&#x4E3B;&#x5E94;&#x7528;&#x7684;&#x901A;&#x4FE1;&#x3001;&#x6784;&#x5EFA;&#x6253;&#x5305;&#x7B49;&#x95EE;&#x9898;&#xFF0C;&#x9700;&#x8981;&#x770B;&#x5B98;&#x65B9;&#x6587;&#x6863;&#xFF0C;&#x7136;&#x540E;&#x6839;&#x636E;&#x81EA;&#x5DF1;&#x9879;&#x76EE;&#x73B0;&#x72B6;&#x53BB;&#x4FEE;&#x6539;&#x8C03;&#x6574;&#x3002;</p>
<h2 id="%E6%95%B4%E5%90%88%E5%89%8D%E5%90%8E%E7%9A%84%E5%8F%98%E5%8C%96">&#x6574;&#x5408;&#x524D;&#x540E;&#x7684;&#x53D8;&#x5316;</h2>
<table>
<thead>
<tr>
<th>&#x4E8B;&#x9879;</th>
<th>&#x6574;&#x5408;&#x524D;</th>
<th>&#x6574;&#x5408;&#x540E;</th>
</tr>
</thead>
<tbody>
<tr>
<td>&#x7528;&#x6237;&#x4FE1;&#x606F;</td>
<td>&#x5404;&#x5B50;&#x7CFB;&#x7EDF;&#x5404;&#x81EA;&#x83B7;&#x53D6;</td>
<td>&#x4E3B;&#x5E94;&#x7528;&#x7EDF;&#x4E00;&#x83B7;&#x53D6;</td>
</tr>
<tr>
<td>&#x767B;&#x5F55;&#x9000;&#x51FA;</td>
<td>&#x5404;&#x5B50;&#x7CFB;&#x7EDF;&#x5355;&#x72EC;&#x767B;&#x5F55;&#x9000;&#x51FA;</td>
<td>&#x4E3B;&#x5E94;&#x7528;&#x7EDF;&#x4E00;&#x767B;&#x5F55;&#x9000;&#x51FA;</td>
</tr>
<tr>
<td>&#x670D;&#x52A1;&#x5668;&#x90E8;&#x7F72;</td>
<td>&#x90E8;&#x7F72;&#x5728;&#x4E0D;&#x540C;&#x670D;&#x52A1;&#x5668;&#xFF0C;&#x7B80;&#x5355;&#x914D;&#x7F6E;nginx</td>
<td>&#x8003;&#x8651;&#x662F;&#x5426;&#x90E8;&#x7F72;&#x5728;&#x4E00;&#x53F0;&#x670D;&#x52A1;&#x5668;&#xFF0C;&#x7EDF;&#x4E00;&#x914D;&#x7F6E;nginx</td>
</tr>
<tr>
<td>&#xFF5C; history&#x6A21;&#x5F0F;</td>
<td>&#x6709;&#x7684;hash&#xFF0C;&#x6709;&#x7684;history</td>
<td>&#x7EDF;&#x4E00;&#x4F7F;&#x7528;history(&#x5EFA;&#x8BAE;)</td>
</tr>
</tbody>
</table>
<h2 id="%E6%95%B4%E5%90%88%E8%BF%87%E7%A8%8B%E9%9C%80%E8%A6%81%E5%A4%84%E7%90%86%E7%9A%84%E7%96%91%E9%9A%BE%E9%97%AE%E9%A2%98">&#x6574;&#x5408;&#x8FC7;&#x7A0B;&#x9700;&#x8981;&#x5904;&#x7406;&#x7684;&#x7591;&#x96BE;&#x95EE;&#x9898;</h2>
<p>&#x628A;&#x7F51;&#x4E0A;qiankun&#x914D;&#x7F6E;&#x597D;&#x7684;demo&#x4E0B;&#x8F7D;&#x4E0B;&#x6765;&#x8FD0;&#x884C;&#x8D77;&#x6765;&#xFF0C;&#x611F;&#x89C9;&#x6BD4;&#x8F83;&#x7B80;&#x5355;&#x6BD4;&#x8F83;&#x597D;&#x914D;&#x7F6E;&#xFF0C;&#x4F46;&#x662F;&#x5728;&#x73B0;&#x6709;&#x9879;&#x76EE;&#x4E0A;&#x4FEE;&#x6539;&#x914D;&#x7F6E;&#x4F1A;&#x53D1;&#x73B0;&#x5B8C;&#x5168;&#x4E0D;&#x4E00;&#x6837;&#x3002;&#x4EE5;&#x4E0B;&#x662F;&#x4E00;&#x4E9B;&#x9700;&#x8981;&#x6CE8;&#x610F;&#x7684;&#x4E8B;&#x9879;&#xFF1A;</p>
<ol>
<li>vite&#x914D;&#x7F6E;&#x4FEE;&#x6539;&#xFF1A;&#x5E94;&#x8BE5;&#x662F;&#x8FD9;&#x4E9B;&#x914D;&#x7F6E;&#x5DE5;&#x4F5C;&#x91CC;&#x6700;&#x9EBB;&#x70E6;&#x6700;&#x9700;&#x8981;&#x4ED4;&#x7EC6;&#x7684;&#xFF0C;vite&#x7684;qiankun&#x5168;&#x5C40;&#x53D8;&#x91CF;&#x540D;&#x8DDF;webpack&#x7684;&#x662F;&#x4E0D;&#x4E00;&#x6837;&#x7684;&#x3002;</li>
<li>&#x8DEF;&#x7531;&#x914D;&#x7F6E;&#x4FEE;&#x6539;&#xFF1A;&#x73B0;&#x6709;&#x9879;&#x76EE;&#x7684;&#x8DEF;&#x7531;&#x5B88;&#x536B;&#x91CC;&#x9762;&#x6D89;&#x53CA;&#x5230;&#x91CD;&#x5B9A;&#x5411;&#x9875;&#x9762;&#x7684;&#xFF0C;&#x5728;&#x8C03;&#x901A;qiankun&#x524D;&#x53EF;&#x4EE5;&#x6682;&#x65F6;&#x6CE8;&#x91CA;&#x6389;&#xFF0C;&#x4E0D;&#x7136;&#x4F1A;&#x9020;&#x6210;&#x4E3B;&#x5E94;&#x7528;&#x9875;&#x9762;&#x767D;&#x5C4F;&#xFF0C;&#x5B50;&#x7CFB;&#x7EDF;&#x9875;&#x9762;&#x52A0;&#x8F7D;&#x4E0D;&#x51FA;&#x6765;&#x3002;</li>
<li>&#x751F;&#x547D;&#x5468;&#x671F;&#xFF1A;&#x6309;&#x7167;qiankun&#x5B98;&#x7F51;&#x7684;&#x6587;&#x6863;&#xFF0C;&#x7ED9;&#x6BCF;&#x4E2A;&#x5B50;&#x5E94;&#x7528;&#x6DFB;&#x52A0;&#x751F;&#x547D;&#x5468;&#x671F;&#xFF0C;&#x8BB0;&#x5F97;&#x8981;&#x9500;&#x6BC1;&#x3002;</li>
<li>&#x5E94;&#x7528;&#x901A;&#x4FE1;&#xFF1A;&#x4E3B;&#x5E94;&#x7528;&#x767B;&#x5F55;&#x5B8C;&#x4E0B;&#x53D1;token&#x7ED9;&#x5B50;&#x5E94;&#x7528;&#xFF0C;&#x5B50;&#x5E94;&#x7528;&#x8D85;&#x65F6;&#x9700;&#x8981;&#x901A;&#x77E5;&#x4E3B;&#x5E94;&#x7528;&#xFF0C;&#x4EE5;&#x53CA;&#x5B50;&#x5E94;&#x7528;&#x52A0;&#x8F7D;&#x5B8C;&#x6210;&#x901A;&#x77E5;&#x4E3B;&#x5E94;&#x7528;&#x7B49;&#x7B49;&#xFF0C;&#x90FD;&#x9700;&#x8981;&#x4E3B;&#x5E94;&#x7528;&#x548C;&#x5B50;&#x5E94;&#x7528;&#x901A;&#x4FE1;&#xFF0C;&#x6309;&#x7167;&#x5B98;&#x7F51;&#x6587;&#x6863;&#x4F7F;&#x7528;&#x3002;</li>
<li>&#x78B0;&#x5230;&#x95EE;&#x9898;&#x53EF;&#x4EE5;&#x591A;&#x770B;&#x770B;&#x5B98;&#x7F51;&#x7684; <a href="https://qiankun.umijs.org/zh/faq?ref=hanhan.pro">&#x5E38;&#x89C1;&#x95EE;&#x9898;</a> &#xFF0C;&#x90E8;&#x7F72;&#x76F8;&#x5173;&#x591A;&#x770B;<a href="https://qiankun.umijs.org/zh/cookbook?ref=hanhan.pro">&#x5165;&#x95E8;&#x6559;&#x7A0B;</a>&#xFF0C;&#x4E0D;&#x5C11;&#x95EE;&#x9898;&#x6700;&#x7EC8;&#x90FD;&#x662F;&#x6839;&#x636E;&#x5B98;&#x7F51;&#x6587;&#x6863;&#x89E3;&#x51B3;&#x7684;&#x3002;</li>
</ol>
<h2 id="vite2vue3%E4%B8%BB%E5%BA%94%E7%94%A8%E9%85%8D%E7%BD%AE%E8%A6%81%E7%82%B9">Vite2+Vue3&#x4E3B;&#x5E94;&#x7528;&#x914D;&#x7F6E;&#x8981;&#x70B9;</h2>
<p><code>main.js</code>&#x91CC;&#x7684;&#x914D;&#x7F6E;&#x57FA;&#x672C;&#x4E0A;&#x6309;&#x7167;&#x5B98;&#x7F51;&#x6587;&#x6863;&#x6765;&#x5C31;&#x597D;&#xFF1A;</p>
<pre><code class="language-js">import { initGlobalState } from &apos;qiankun&apos;
import storage from &apos;store&apos;
import { ACCESS_TOKEN } from &apos;@/store/mutation-types&apos;
import { registerMicroApps, start } from &apos;qiankun&apos;

const initialState = {
    // &#x8FD9;&#x91CC;&#x53EF;&#x4EE5;&#x5199;&#x521D;&#x59CB;&#x5316;&#x6570;&#x636E;
    project_id: &apos;&#x9879;&#x76EE;5&apos;,
    token: storage.get(ACCESS_TOKEN)||&apos;&apos;,
    spinning: false
}
const actions = initGlobalState(initialState) //&#x521D;&#x59CB;&#x5316;state

// &#x76D1;&#x542C;actions&#x5168;&#x5C40;&#x516C;&#x5171;&#x72B6;&#x6001;&#x6570;&#x636E;&#x7684;&#x53D8;&#x5316;
actions.onGlobalStateChange((state, prevState) =&gt; {
    console.log(&quot;&#x4E3B;&#x5E94;&#x7528;&#x53D8;&#x66F4;&#x524D;&#xFF1A;&quot;, prevState);
    console.log(&quot;&#x4E3B;&#x5E94;&#x7528;&#x53D8;&#x66F4;&#x540E;&#xFF1A;&quot;, state);
})

function loader(loading) {
  console.log(&apos;loading&apos;,loading)
  if(loading){
    actions.setGlobalState({ spinning: loading });
  }
}

registerMicroApps([
  {
    name: &apos;app-aaa&apos;, // &#x4E0E;&#x5B50;&#x5E94;&#x7528;&#x6253;&#x5305;&#x914D;&#x7F6E;&#x91CC;&#x7684;&#x4E00;&#x81F4;
    entry: import.meta.env.DEV ? &apos;//localhost:7100&apos; : &apos;/subapp/aaa/&apos;, //&#x672C;&#x5730;&#x5F00;&#x53D1;&#x662F;localhost&#xFF0C;&#x90E8;&#x7F72;&#x5230;&#x6D4B;&#x8BD5;&#x548C;&#x751F;&#x4EA7;&#x73AF;&#x5883;&#x662F;&#x7528;&#x540E;&#x9762;&#x7684;
    container: &apos;#appContainer&apos;,
    activeRule: &apos;/app-aaa&apos;,
    props: { actions },   //&#x5411;&#x5B50;&#x5E94;&#x7528;&#x4F20;&#x9012;&#x521B;&#x5EFA;&#x7684;&#x5168;&#x5C40;&#x72B6;&#x6001;
    loader
  },
  {
    name: &apos;app-bbb&apos;, // &#x4E0E;&#x5B50;&#x5E94;&#x7528;&#x6253;&#x5305;&#x914D;&#x7F6E;&#x91CC;&#x7684;&#x4E00;&#x81F4;
    entry: import.meta.env.DEV ? &apos;//localhost:7200&apos; : &apos;/subapp/bbb/&apos;, //&#x672C;&#x5730;&#x5F00;&#x53D1;&#x662F;localhost&#xFF0C;&#x90E8;&#x7F72;&#x5230;&#x6D4B;&#x8BD5;&#x548C;&#x751F;&#x4EA7;&#x73AF;&#x5883;&#x662F;&#x7528;&#x540E;&#x9762;&#x7684;
    container: &apos;#appContainer&apos;,
    activeRule: &apos;/app-bbb&apos;,
    props: { actions },   //&#x5411;&#x5B50;&#x5E94;&#x7528;&#x4F20;&#x9012;&#x521B;&#x5EFA;&#x7684;&#x5168;&#x5C40;&#x72B6;&#x6001;
    loader
  }
])

start()
</code></pre>
<p>&#x4E3B;&#x5E94;&#x7528;&#x914D;&#x7F6E;&#x8981;&#x70B9;&#xFF1A;</p>
<ol>
<li>&#x5728;&#x4E3B;&#x5E94;&#x7528;&#x91CC;&#x521D;&#x59CB;&#x5316;&#x5E94;&#x7528;&#x548C;&#x521D;&#x59CB;&#x5316;&#x901A;&#x4FE1;&#xFF1B;</li>
<li>&#x6D4B;&#x8BD5;&#x73AF;&#x5883;<code>entry</code>&#x540D;&#x5B57;&#xFF0C;&#x4E0D;&#x80FD;&#x548C;<code>activeRule</code>&#x4E00;&#x6837;&#xFF0C;&#x5426;&#x5219;&#x4E3B;&#x5E94;&#x7528;&#x9875;&#x9762;&#x5237;&#x65B0;&#x5C31;&#x53D8;&#x6210;&#x5FAE;&#x5E94;&#x7528;&#xFF0C;&#x5B98;&#x7F51;&#x6709;&#x5F3A;&#x8C03;&#xFF1B;</li>
<li>&#x6D4B;&#x8BD5;&#x73AF;&#x5883;<code>entry</code>&#x540D;&#x5B57;&#xFF0C;&#x662F;&#x8DDF;&#x5B50;&#x5E94;&#x7528;&#x6784;&#x5EFA;&#x91CC;&#x9762;&#x7684;<code>publicPath</code>&#x6216;&#x8005;<code>assetsPublicPath</code>&#x4E00;&#x81F4;&#x7684;&#xFF0C;&#x8FD9;&#x91CC;&#x5212;&#x91CD;&#x70B9;&#xFF1B;</li>
<li><code>activeRule</code>&#x5C31;&#x662F;&#x6D4F;&#x89C8;&#x5668;&#x5730;&#x5740;&#x680F;&#x91CC;&#x7684;&#x540E;&#x534A;&#x622A;&#x8DEF;&#x5F84;&#xFF1B;</li>
<li>&#x5982;&#x679C;&#x4E3B;&#x5E94;&#x7528;&#x662F;<code>vite2+vue3</code>&#x5E94;&#x7528;&#xFF0C;vite&#x914D;&#x7F6E;&#x6587;&#x4EF6;<code>&#x4E0D;&#x9700;&#x8981;</code>&#x989D;&#x5916;&#x52A0;output&#x90A3;&#x4E9B;&#x6253;&#x5305;&#x6210;umd&#x7684;&#x914D;&#x7F6E;&#xFF0C;<code>&#x4E0D;&#x9700;&#x8981;</code>&#xFF0C;&#x52A0;&#x4E86;&#x6253;&#x5305;&#x4F1A;&#x62A5;&#x9519;&#xFF1B;</li>
<li>&#x8981;&#x628A;&#x6240;&#x6709;&#x5B50;&#x5E94;&#x7528;&#x91CC;&#x7684;<code>proxy</code>&#x63A5;&#x53E3;&#x4EE3;&#x7406;&#xFF0C;&#x62F7;&#x5230;&#x4E3B;&#x5E94;&#x7528;&#x91CC;&#x9762;&#xFF0C;&#x8FD9;&#x6837;&#x624D;&#x80FD;&#x5728;&#x4E3B;&#x5E94;&#x7528;&#x91CC;&#x8BBF;&#x95EE;&#x5230;&#x5B50;&#x5E94;&#x7528;&#x91CC;&#x7684;&#x63A5;&#x53E3;&#x3002;</li>
</ol>
<h2 id="vite2vue3%E5%AD%90%E5%BA%94%E7%94%A8%E9%85%8D%E7%BD%AE%E8%A6%81%E7%82%B9">Vite2+Vue3&#x5B50;&#x5E94;&#x7528;&#x914D;&#x7F6E;&#x8981;&#x70B9;</h2>
<p><code>vite.config.ts</code>&#x6587;&#x4EF6;&#x9700;&#x8981;&#x589E;&#x52A0;&#x7684;&#x5185;&#x5BB9;&#xFF1A;</p>
<pre><code class="language-js">import qiankun from &quot;vite-plugin-qiankun&quot;;

export default defineConfig({
  base: &quot;/subapp/aaa/&quot;, // &#x4E0E;&#x4E3B;&#x5E94;&#x7528;&#x91CC;&#x9762;&#x6D4B;&#x8BD5;&#x73AF;&#x5883;&#x7684;entry&#x4E00;&#x81F4;
  headers: {
    // &#x5141;&#x8BB8;&#x8DE8;&#x57DF;&#x8BBF;&#x95EE;
    &quot;Access-Control-Allow-Origin&quot;: &quot;*&quot;
  },
  port: 7100, // &#x4E0E;&#x4E3B;&#x5E94;&#x7528;&#x91CC;&#x6CE8;&#x518C;&#x7684;&#x5F00;&#x53D1;&#x73AF;&#x5883;entry&#x4E00;&#x81F4;
  output: {
    // &#x628A;&#x5B50;&#x5E94;&#x7528;&#x6253;&#x5305;&#x6210; umd &#x5E93;&#x683C;&#x5F0F;
    library: `${name}-[name]`, // &#x6211;&#x8FD9;&#x91CC;library&#x540D;&#x5B57;&#x8DDF;package.json&#x91CC;&#x7684;name&#x4E0D;&#x4E00;&#x6837;&#xFF0C;&#x4E5F;&#x662F;&#x53EF;&#x4EE5;&#x7684;
    libraryTarget: &quot;umd&quot;, // &#x91CD;&#x70B9;&#xFF0C;&#x5B50;&#x5E94;&#x7528;&#x8981;&#x6253;&#x5305;&#x6210;umd&#x683C;&#x5F0F;
    jsonpFunction: `webpackJsonp_${name}`
  },
  plugins: [
    // &#x589E;&#x52A0;qiankun&#x63D2;&#x4EF6;
    qiankun(&quot;app-aaa&quot;, { // app-aaa&#x662F;&#x4E0E;&#x4E3B;&#x5E94;&#x7528;main.ts&#x91CC;&#x6CE8;&#x518C;&#x5B50;&#x5E94;&#x7528;&#x7684;name&#x4E00;&#x81F4;
      useDevMode: true
    }),
  ]
})
</code></pre>
<p><code>src</code>&#x76EE;&#x5F55;&#x589E;&#x52A0;<code>public-path.ts</code>&#x6587;&#x4EF6;&#xFF1A;</p>
<pre><code class="language-js">import { renderWithQiankun, qiankunWindow } from &apos;vite-plugin-qiankun/dist/helper&apos;;
if (qiankunWindow.__POWERED_BY_QIANKUN__) {
    // eslint-disable-next-line no-undef
    __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
</code></pre>
<p>&#x8DEF;&#x7531;&#x6587;&#x4EF6;&#x9700;&#x8981;&#x4FEE;&#x6539;&#x7684;&#x5185;&#x5BB9;&#xFF1A;</p>
<pre><code class="language-js">import { qiankunWindow } from &apos;vite-plugin-qiankun/dist/helper&apos;;

export default createRouter({
  history: createWebHistory(
    qiankunWindow.__POWERED_BY_QIANKUN__ ? &apos;/app-aaa/&apos; : &apos;/subapp/aaa/&apos;
  ),
});
</code></pre>
<p><code>src</code>&#x76EE;&#x5F55;&#x589E;&#x52A0;<code>action.ts</code>&#x6587;&#x4EF6;&#xFF1A;</p>
<pre><code class="language-js">function emptyAction() {
  // &#x8B66;&#x544A;&#xFF1A;&#x63D0;&#x793A;&#x5F53;&#x524D;&#x4F7F;&#x7528;&#x7684;&#x662F;&#x7A7A; Action
  console.warn(&quot;Current execute action is empty!&quot;);
}

// &#x6211;&#x4EEC;&#x9996;&#x5148;&#x8BBE;&#x7F6E;&#x4E00;&#x4E2A;&#x7528;&#x4E8E;&#x901A;&#x4FE1;&#x7684;Actions&#x7C7B;
class Actions {
  actions = {
    onGlobalStateChange: emptyAction,
    setGlobalState: emptyAction
  }
  
  // &#x9ED8;&#x8BA4;&#x503C;&#x4E3A;&#x7A7A;Action
  constructor() {
  }

  // &#x8BBE;&#x7F6E;actions
  setActions(actions) {
    console.log(actions)
    this.actions = actions
  }

  // &#x6620;&#x5C04;
  onGlobalStateChange(...args) {
    return this.actions.onGlobalStateChange(...args)
  }

  // &#x6620;&#x5C04;
  setGlobalState(...args) {
    return this.actions.setGlobalState(...args)
  }
}

const actions = new Actions()
export default actions
</code></pre>
<p><code>main.ts</code>&#x6587;&#x4EF6;&#x9700;&#x8981;&#x589E;&#x52A0;&#x7684;&#x5185;&#x5BB9;&#xFF1A;</p>
<pre><code class="language-js">import { renderWithQiankun, qiankunWindow } from &apos;vite-plugin-qiankun/dist/helper&apos;;
import actions from &apos;./action&apos;;

let instance: any;
let history: any;

declare global {
  interface Window {
    __POWERED_BY_QIANKUN__?: string;
  }
}

if (!qiankunWindow.__POWERED_BY_QIANKUN__) {
  // &#x72EC;&#x7ACB;&#x8BBF;&#x95EE;&#x65F6;&#x7684;&#x4EE3;&#x7801;
  instance = createApp(App)
  instance
    .use(router)
    .use(store)
  instance.mount(&apos;#subApp&apos;)
  // ... ...
} else {
  // &#x5728;qiankun&#x5185;&#x8BBF;&#x95EE;
  renderWithQiankun({
    mount(props) {
      history = createWebHistory(
        qiankunWindow.__POWERED_BY_QIANKUN__ ? &apos;/app-aaa&apos; : &apos;/subapp/aaa&apos;
      );
      instance = createApp(App)
      instance
        .use(router)
        .use(store)
      instance.mount(
        (props.container
          ? props.container.querySelector(&apos;#subApp&apos;)
          : document.getElementById(&apos;subApp&apos;)) as Element
      )
      if (props) {//&#x5B50;&#x5E94;&#x7528;&#x63A5;&#x6536;&#x4E3B;&#x5E94;&#x7528;&#x503C;
        actions.setActions(props)
        actions.onGlobalStateChange((state) =&gt; {
          console.log(&quot;&#x6211;&#x662F;&#x5B50;&#x5E94;&#x7528;&#xFF0C;&#x6211;&#x68C0;&#x6D4B;&#x5230;&#x6570;&#x636E;&#x4E86;&#xFF1A;&quot;, state);
          if(!state.token){
              console.log(&apos;document.location.hostname&apos;, window.location.origin)
          }
        }, true);
      }
    },
    bootstrap() {
      console.log(&apos;--bootstrap&apos;)
    },
    update() {
      console.log(&apos;--update&apos;)
    },
    unmount() {
      instance.unmount()
      console.log(&apos;--unmount&apos;)
      console.log(&apos;instance&apos;,instance)
      console.log(&apos;history&apos;,history)

      instance._container.innerHTML = &apos;&apos;;
      history.destroy();// &#x4E0D;&#x5378;&#x8F7D;  router &#x4F1A;&#x5BFC;&#x81F4;&#x5176;&#x4ED6;&#x5E94;&#x7528;&#x8DEF;&#x7531;&#x5931;&#x8D25;
      instance = null;
    },
  })
}
</code></pre>
<h4 id="vite2vue3%E5%AD%90%E5%BA%94%E7%94%A8%E9%85%8D%E7%BD%AE%E8%A6%81%E7%82%B9%EF%BC%9A">vite2+vue3&#x5B50;&#x5E94;&#x7528;&#x914D;&#x7F6E;&#x8981;&#x70B9;&#xFF1A;</h4>
<ol>
<li>&#x5B89;&#x88C5;<code>qiankun</code>&#xFF1B;</li>
<li>&#x5B89;&#x88C5;<code>vite-plugin-qiankun</code>&#xFF1B;</li>
<li><code>vite.config.ts</code>&#x6587;&#x4EF6;&#x91CC;&#x9762;&#x589E;&#x52A0;<code>base</code>&#x3001;<code>port</code>&#x3001;<code>headers</code>&#x8DE8;&#x57DF;&#x3001;<code>output</code>&#x548C;<code>qiankun&#x63D2;&#x4EF6;</code>&#x914D;&#x7F6E;&#xFF1B;</li>
<li>&#x6CE8;&#x610F;<code>qiankunWindow.__POWERED_BY_QIANKUN__</code>&#x91CC;&#x7684;&#x53D8;&#x91CF;&#x540D;&#x662F;<code>qiankunWindow</code>&#xFF0C;<code>qiankunWindow</code>&#x76F8;&#x5F53;&#x4E8E;&#x4E00;&#x4E2A;&#x5047;&#x7684;window&#x5BF9;&#x8C61;&#xFF0C;&#x662F;&#x4F5C;&#x4E3A;&#x5B50;&#x5E94;&#x7528;js&#x4EE3;&#x7801;&#x6267;&#x884C;&#x65F6;&#x7684;&#x5168;&#x5C40;&#x53D8;&#x91CF;&#xFF0C;&#x51E0;&#x4E2A;&#x6587;&#x4EF6;&#x90FD;&#x7528;&#x5230;&#x8FD9;&#x4E2A;&#xFF0C;&#x5212;&#x91CD;&#x70B9;&#xFF1B;</li>
<li><code>main.ts</code>&#x6587;&#x4EF6;&#x91CC;&#x589E;&#x52A0;&#x5224;&#x65AD;&#x662F;&#x5426;&#x662F;<code>qiankunWindow.__POWERED_BY_QIANKUN__</code>&#x6765;&#x5206;&#x522B;&#x5199;&#x72EC;&#x7ACB;&#x8BBF;&#x95EE;&#x65F6;&#x548C;qiankun&#x91CC;&#x8BBF;&#x95EE;&#x65F6;&#x7684;&#x4EE3;&#x7801;&#xFF1B;</li>
<li><code>main.ts</code>&#x6587;&#x4EF6;&#x91CC;&#x7684;qiankun&#x8BBF;&#x95EE;&#x7684;&#x4EE3;&#x7801;&#x662F;&#x653E;&#x5728;<code>renderWithQiankun</code>&#x91CC;&#x7684;<code>mount</code>&#x751F;&#x547D;&#x5468;&#x671F;&#x91CC;&#x9762;&#xFF1B;</li>
<li>&#x6709;&#x4E24;&#x5904;&#x8DEF;&#x7531;&#x76F8;&#x5173;&#x7684;&#x4FEE;&#x6539;&#xFF0C;&#x5728;<code>main.ts</code>&#x548C;&#x8DEF;&#x7531;&#x6587;&#x4EF6;&#x91CC;&#x3002;</li>
<li>&#x8DEF;&#x7531;&#x6587;&#x4EF6;&#x548C;<code>vite.config.ts</code>&#x91CC;&#x9762;&#x7684;<code>/subapp/aaa/</code>&#xFF0C;&#x548C;&#x4E3B;&#x5E94;&#x7528;<code>main.ts</code>&#x91CC;&#x6CE8;&#x518C;&#x5B50;&#x5E94;&#x7528;&#x7684;<code>entry</code>&#x662F;&#x4E00;&#x81F4;&#x7684;&#x3002;</li>
</ol>
<h2 id="vue2%E5%AD%90%E5%BA%94%E7%94%A8%E9%85%8D%E7%BD%AE%E8%A6%81%E7%82%B9">Vue2&#x5B50;&#x5E94;&#x7528;&#x914D;&#x7F6E;&#x8981;&#x70B9;</h2>
<p><code>vue.config.js</code>&#x589E;&#x52A0;&#x7684;&#x914D;&#x7F6E;&#xFF1A;</p>
<pre><code class="language-js">  devServer: {
    port: 7200, // &#x4E0E;&#x4E3B;&#x5E94;&#x7528;&#x91CC;&#x6CE8;&#x518C;&#x7684;&#x5F00;&#x53D1;&#x73AF;&#x5883;entry&#x4E00;&#x81F4;
    headers: {
      &apos;Access-Control-Allow-Origin&apos;: &apos;*&apos;
    }
  }
  publicPath: process.env.NODE_ENV === &apos;development&apos; ? &apos;/&apos; : &apos;/subapp/bbb/&apos;, // &#x589E;&#x52A0;&#x4E86;&#x5224;&#x65AD;&#xFF0C;&#x751F;&#x4EA7;&#x73AF;&#x5883;&#x7684;&#x8DEF;&#x5F84;&#x8DDF;&#x4E3B;&#x5E94;&#x7528;&#x91CC;&#x4E00;&#x81F4;
  output: {
    library: `${name}-[name]`,
    libraryTarget: &apos;umd&apos;, // &#x628A;&#x5FAE;&#x5E94;&#x7528;&#x6253;&#x5305;&#x6210; umd &#x5E93;&#x683C;&#x5F0F;
    jsonpFunction: `webpackJsonp_${name}`
  }
</code></pre>
<p><code>src</code>&#x76EE;&#x5F55;&#x589E;&#x52A0;<code>public-path.js</code>&#x6587;&#x4EF6;&#xFF1A;</p>
<pre><code class="language-js">if (window.__POWERED_BY_QIANKUN__) {
    // eslint-disable-next-line no-undef
    __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
}
</code></pre>
<p>&#x8DEF;&#x7531;&#x6587;&#x4EF6;&#x9700;&#x8981;&#x4FEE;&#x6539;&#x7684;&#x5185;&#x5BB9;&#xFF1A;</p>
<pre><code class="language-js">export default new Router({
  mode: &apos;history&apos;,
  base: window.__POWERED_BY_QIANKUN__ ? &apos;/app-bbb&apos; : &apos;/&apos;,
})
</code></pre>
<p><code>src</code>&#x76EE;&#x5F55;&#x589E;&#x52A0;<code>action.js</code>&#x6587;&#x4EF6;&#xFF0C;&#x4E0E;&#x4E0A;&#x9762;&#x5B50;&#x5E94;&#x7528;&#x7684;&#x4E00;&#x6837;&#xFF1A;</p>
<pre><code class="language-js">function emptyAction() {
  // &#x8B66;&#x544A;&#xFF1A;&#x63D0;&#x793A;&#x5F53;&#x524D;&#x4F7F;&#x7528;&#x7684;&#x662F;&#x7A7A; Action
  console.warn(&quot;Current execute action is empty!&quot;);
}

// &#x6211;&#x4EEC;&#x9996;&#x5148;&#x8BBE;&#x7F6E;&#x4E00;&#x4E2A;&#x7528;&#x4E8E;&#x901A;&#x4FE1;&#x7684;Actions&#x7C7B;
class Actions {
  actions = {
    onGlobalStateChange: emptyAction,
    setGlobalState: emptyAction
  }
  
  // &#x9ED8;&#x8BA4;&#x503C;&#x4E3A;&#x7A7A;Action
  constructor() {
  }

  // &#x8BBE;&#x7F6E;actions
  setActions(actions) {
    console.log(actions)
    this.actions = actions
  }

  // &#x6620;&#x5C04;
  onGlobalStateChange(...args) {
    return this.actions.onGlobalStateChange(...args)
  }

  // &#x6620;&#x5C04;
  setGlobalState(...args) {
    return this.actions.setGlobalState(...args)
  }
}

const actions = new Actions()
export default actions
</code></pre>
<p><code>main.js</code>&#x6587;&#x4EF6;&#x9700;&#x8981;&#x589E;&#x52A0;&#x7684;&#x5185;&#x5BB9;&#xFF1A;</p>
<pre><code class="language-js">import router from &apos;./router&apos;
import store from &apos;./store&apos;
import actions from &apos;./action&apos;

let instance = null
function render(props = {}) {
  const { container } = props
  instance = new Vue({
    router,
    store,
    render: h =&gt; h(App)
  }).$mount(container ? container.querySelector(&apos;#subApp&apos;) : &apos;#subApp&apos;)
}

if (!window.__POWERED_BY_QIANKUN__) {
  render()
}

export async function bootstrap () {
  console.log(&apos;[vue] vue app bootstraped&apos;)
}

export async function mount(props) {
  console.log(&apos;receive props&apos;, props)
  // Vue.prototype.$qiankun=props
  if (props) { // &#x5B50;&#x5E94;&#x7528;&#x63A5;&#x6536;&#x4E3B;&#x5E94;&#x7528;&#x503C;
    actions.setActions(props)
    actions.onGlobalStateChange((state) =&gt; {
      console.log(&apos;&#x6211;&#x662F;&#x5B50;&#x5E94;&#x7528;bbb&#xFF0C;&#x6211;&#x68C0;&#x6D4B;&#x5230;&#x6570;&#x636E;&#x4E86;&#xFF1A;&apos;, state)
    }, true)
  }
  render(props)
}

export async function unmount() {
  instance.$destroy()
  instance.$el.innerHTML = &apos;&apos;
  instance = null
}
</code></pre>
<h4 id="vue2%E5%AD%90%E5%BA%94%E7%94%A8%E9%85%8D%E7%BD%AE%E8%A6%81%E7%82%B9%EF%BC%9A">vue2&#x5B50;&#x5E94;&#x7528;&#x914D;&#x7F6E;&#x8981;&#x70B9;&#xFF1A;</h4>
<ol>
<li>&#x4E0D;&#x9700;&#x8981;&#x5B89;&#x88C5;&#x4EC0;&#x4E48;&#xFF0C;&#x6574;&#x4F53;&#x914D;&#x7F6E;&#x76F8;&#x5BF9;&#x6BD4;&#x8F83;&#x7B80;&#x5355;&#xFF1B;</li>
<li><code>vue.config.js</code>&#x6587;&#x4EF6;&#x91CC;&#x9762;&#x4FEE;&#x6539;<code>publicPath</code>&#x914D;&#x7F6E;&#xFF0C;&#x5982;&#x4E0A;&#x9762;&#x4EE3;&#x7801;&#x52A0;&#x4E0A;&#x5F00;&#x53D1;&#x73AF;&#x5883;&#x5224;&#x65AD;&#xFF1B;</li>
<li><code>vue.config.js</code>&#x6587;&#x4EF6;&#x91CC;&#x9762;&#x5728;<code>devServer</code>&#x4E0B;&#x589E;&#x52A0;<code>port</code>&#x548C;<code>headers</code>&#x8DE8;&#x57DF;&#x914D;&#x7F6E;&#xFF1B;</li>
<li><code>vue.config.js</code>&#x6587;&#x4EF6;&#x91CC;&#x9762;&#x5728;<code>configureWebpack</code>&#x4E0B;&#x589E;&#x52A0;<code>output</code>&#x914D;&#x7F6E;&#xFF1B;</li>
<li>&#x6CE8;&#x610F;<code>window.__POWERED_BY_QIANKUN__</code>&#x91CC;&#x7684;&#x53D8;&#x91CF;&#x540D;&#x662F;<code>window</code>&#x3002;</li>
<li><code>main.js</code>&#x6587;&#x4EF6;&#x91CC;&#x57FA;&#x672C;&#x6309;&#x7167;&#x5B98;&#x7F51;&#x6765;&#x4FEE;&#x6539;&#x5C31;&#x53EF;&#x4EE5;&#xFF0C;<code>router</code>&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x4F60;&#x73B0;&#x6709;&#x7684;&#xFF0C;&#x7136;&#x540E;&#x5728;&#x8DEF;&#x7531;&#x6587;&#x4EF6;&#x91CC;&#x4FEE;&#x6539;&#x5C31;&#x597D;&#x3002;</li>
<li><code>vue.config.js</code>&#x91CC;&#x9762;&#x7684;<code>/subapp/bbb/</code>&#xFF0C;&#x548C;&#x4E3B;&#x5E94;&#x7528;<code>main.ts</code>&#x91CC;&#x6CE8;&#x518C;&#x5B50;&#x5E94;&#x7528;&#x7684;<code>entry</code>&#x662F;&#x4E00;&#x81F4;&#x7684;&#x3002;</li>
<li>&#x8DEF;&#x7531;&#x6587;&#x4EF6;&#x91CC;&#x9762;&#x7684;<code>app-bbb</code>&#xFF0C;&#x548C;&#x4E3B;&#x5E94;&#x7528;<code>main.ts</code>&#x91CC;&#x6CE8;&#x518C;&#x5B50;&#x5E94;&#x7528;&#x7684;<code>name</code>&#x662F;&#x4E00;&#x81F4;&#x7684;&#x3002;</li>
</ol>
<h3 id="%E9%83%A8%E7%BD%B2%E7%9A%84nginx%E9%85%8D%E7%BD%AE%EF%BC%9A">&#x90E8;&#x7F72;&#x7684;nginx&#x914D;&#x7F6E;&#xFF1A;</h3>
<p>&#x57FA;&#x672C;&#x4E0A;&#x6309;&#x7167;&#x5B98;&#x7F51;&#x7684;&#x914D;&#x7F6E;&#x6765;&#x7684;&#xFF0C;&#x5B98;&#x7F51;&#x5199;&#x7684;&#x5F88;&#x8BE6;&#x7EC6;&#x4E86;&#xFF0C;&#x6309;&#x5B98;&#x7F51;&#x914D;&#x7F6E;&#x6CA1;&#x9519;&#x3002;&#x8FD9;&#x4E2A;&#x914D;&#x7F6E;&#x662F;&#x4E3B;&#x5E94;&#x7528;&#x8DDF;&#x5B50;&#x5E94;&#x7528;&#x90E8;&#x7F72;&#x5728;&#x540C;&#x4E00;&#x53F0;&#x670D;&#x52A1;&#x5668;&#x7684;&#x914D;&#x7F6E;&#xFF0C;&#x9002;&#x7528;&#x4E8E;&#x6D4B;&#x8BD5;&#x548C;&#x751F;&#x4EA7;&#x73AF;&#x5883;&#x3002;</p>
<pre><code class="language-bash">server{  
  listen 80;  
  server_name yourdomain.com;
  add_header Access-Control-Allow-Origin *;
  add_header Access-Control-Allow-Methods &apos;GET, POST, OPTIONS&apos;;
  add_header Access-Control-Allow-Headers &apos;DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization&apos;;
  
  #lijian
  location / {
    root /www/html/app;
    index index.html;
    try_files $uri $uri/ /index.html;
  }

  location /admin111 {
    proxy_pass http://111.111.111.111:8888;
  }

  location /admin222 {
    proxy_pass http://222.222.222.222:8888;
  }

}
</code></pre>
<pre><code>...
&#x2514;&#x2500;&#x2500; app/                 # &#x4E3B;&#x5E94;&#x7528;&#x7684;&#x76EE;&#x5F55;(/www/html/app)
    &#x251C;&#x2500;&#x2500; css/             # &#x4E3B;&#x5E94;&#x7528;&#x7684;css&#x6587;&#x4EF6;&#x5939;
    &#x251C;&#x2500;&#x2500; js/              # &#x4E3B;&#x5E94;&#x7528;&#x7684;js&#x6587;&#x4EF6;&#x5939;
    &#x251C;&#x2500;&#x2500; index.html       # &#x4E3B;&#x5E94;&#x7528;&#x7684;index.html
    &#x251C;&#x2500;&#x2500; subapp/          # &#x5B58;&#x653E;&#x6240;&#x6709;&#x5B50;&#x5E94;&#x7528;&#x7684;&#x76EE;&#x5F55;
    |     &#x251C;&#x2500;&#x2500; aaa/       # &#x5B58;&#x653E;&#x5B50;&#x5E94;&#x7528; aaa &#x7684;&#x76EE;&#x5F55;
    |     &#x251C;&#x2500;&#x2500; bbb/       # &#x5B58;&#x653E;&#x5B50;&#x5E94;&#x7528; bbb &#x7684;&#x76EE;&#x5F55;
...
</code></pre>
<p>nginx&#x914D;&#x7F6E;&#x8BF4;&#x660E;&#xFF1A;</p>
<ol>
<li>&#x8FD9;&#x662F;&#x4E3B;&#x5E94;&#x7528;&#x548C;&#x5B50;&#x5E94;&#x7528;&#x90FD;&#x90E8;&#x7F72;&#x5728;&#x540C;&#x4E00;&#x53F0;&#x670D;&#x52A1;&#x5668;&#x7684;&#x57FA;&#x672C;&#x914D;&#x7F6E;&#xFF0C;&#x5212;&#x91CD;&#x70B9;&#xFF1B;</li>
<li>&#x6CE8;&#x610F;&#x4E0A;&#x9762;&#x914D;&#x7F6E;&#xFF0C;&#x8FD9;&#x91CC;&#x53EA;&#x9700;&#x8981;&#x914D;&#x7F6E;&#x4E3B;&#x5E94;&#x7528;&#x7684;&#x76EE;&#x5F55;&#x5C31;&#x597D;&#xFF0C;&#x670D;&#x52A1;&#x5668;<code>/www/html/app</code>&#x76EE;&#x5F55;&#x4E0B;&#x653E;&#x4E3B;&#x5E94;&#x7528;&#x7684;&#x9875;&#x9762;&#x6587;&#x4EF6;&#x3002;</li>
<li>&#x9700;&#x8981;&#x5728;&#x670D;&#x52A1;&#x5668;<code>/www/html/app</code>&#x76EE;&#x5F55;&#x4E0B;&#x5EFA;&#x7ACB;<code>subapp</code>&#x76EE;&#x5F55;&#xFF0C;<code>subapp</code>&#x76EE;&#x5F55;&#x662F;&#x4E0E;&#x672C;&#x6587;&#x4E0A;&#x9762;&#x7684;&#x4FDD;&#x6301;&#x4E00;&#x81F4;&#x7684;&#x3002;</li>
<li>&#x5B50;&#x5E94;&#x7528;<code>aaa</code>&#x5728;&#x670D;&#x52A1;&#x5668;<code>/www/html/app/subapp</code>&#x4E0B;&#x9762;&#x5EFA;&#x7ACB;<code>aaa</code>&#x76EE;&#x5F55;&#xFF0C;&#x628A;&#x6784;&#x5EFA;&#x597D;&#x7684;&#x9875;&#x9762;&#x653E;&#x8FDB;&#x53BB;&#x3002;</li>
<li>&#x5B50;&#x5E94;&#x7528;<code>bbb</code>&#x540C;&#x7406;&#xFF0C;&#x5728;&#x670D;&#x52A1;&#x5668;<code>/www/html/app/subapp</code>&#x4E0B;&#x9762;&#x5EFA;&#x7ACB;<code>bbb</code>&#x76EE;&#x5F55;&#xFF0C;&#x628A;&#x6784;&#x5EFA;&#x597D;&#x7684;&#x9875;&#x9762;&#x653E;&#x8FDB;&#x53BB;&#x3002;</li>
<li>&#x8FD9;&#x91CC;&#x7684;<code>subapp</code>&#x76EE;&#x5F55;&#xFF0C;&#x4EE5;&#x53CA;<code>subapp</code>&#x4E0B;&#x9762;&#x5EFA;&#x7ACB;&#x7684;<code>aaa</code>&#x548C;<code>bbb</code>&#x4E24;&#x4E2A;&#x76EE;&#x5F55;&#xFF0C;&#x662F;&#x8DDF;&#x672C;&#x6587;&#x4E0A;&#x9762;&#x4E3B;&#x5E94;&#x7528;&#x548C;&#x5B50;&#x5E94;&#x7528;&#x914D;&#x7F6E;&#x91CC;&#x7684;<code>/subapp/aaa/</code>&#x548C;<code>/subapp/bbb/</code>&#x4E00;&#x81F4;&#x7684;&#xFF0C;&#x91CD;&#x70B9;&#x91CD;&#x70B9;&#x91CD;&#x70B9;&#x3002;</li>
<li>&#x4E4B;&#x524D;&#x672C;&#x5730;&#x5F00;&#x53D1;&#x8981;&#x628A;&#x5404;&#x4E2A;&#x5B50;&#x5E94;&#x7528;&#x91CC;&#x9762;&#x914D;&#x7F6E;&#x7684;&#x4EE3;&#x7406;&#x62F7;&#x8D1D;&#x5230;&#x4E3B;&#x5E94;&#x7528;&#x91CC;&#x9762;&#x53BB;&#xFF0C;&#x4E0A;&#x5230;&#x6D4B;&#x8BD5;&#x6216;&#x8005;&#x751F;&#x4EA7;&#x73AF;&#x5883;&#x5219;&#x9700;&#x8981;nginx&#x91CC;&#x9762;&#x505A;&#x8F6C;&#x53D1;&#xFF0C;&#x5982;&#x4E0A;&#x9762;&#x914D;&#x7F6E;&#xFF0C;ip&#x53EF;&#x4EE5;&#x6362;&#x6210;&#x57DF;&#x540D;&#x3002;</li>
</ol>
<h2 id="%E5%BF%83%E5%BE%97%E5%92%8C%E6%80%BB%E7%BB%93">&#x5FC3;&#x5F97;&#x548C;&#x603B;&#x7ED3;</h2>
<ol>
<li>&#x57FA;&#x4E8E;<code>vite</code>&#x7684;vue3&#x5E94;&#x7528;&#x5728;&#x672C;&#x5730;&#x5F00;&#x53D1;&#x548C;&#x6D4B;&#x8BD5;&#x751F;&#x4EA7;&#x90FD;&#x662F;&#x53EF;&#x4EE5;&#x641E;&#x5B9A;&#x7684;&#xFF0C;&#x4E0D;&#x7528;&#x628A;vite&#x66FF;&#x6362;&#x6362;&#x6210;webpack&#xFF08;&#x7F51;&#x4E0A;&#x89C1;&#x6709;&#x66FF;&#x6362;&#x7684;&#xFF09;&#x3002;</li>
<li>&#x57FA;&#x4E8E;<code>vite</code>&#x7684;&#x5E94;&#x7528;&#x9700;&#x8981;&#x5B89;&#x88C5;qiankun&#x63D2;&#x4EF6;&#xFF0C;&#x53D8;&#x91CF;&#x540D;&#x4E0D;&#x4E00;&#x6837;&#x3002;</li>
<li>&#x57FA;&#x4E8E;<code>vue2</code>&#x7684;&#x5E94;&#x7528;&#x63A5;&#x5165;qiankun&#x76F8;&#x5BF9;&#x7B80;&#x5355;&#x5F97;&#x591A;&#x3002;</li>
<li>&#x672C;&#x5730;&#x5F00;&#x53D1;&#x548C;&#x6D4B;&#x8BD5;&#x751F;&#x4EA7;&#x7684;<code>entry</code>&#x548C;<code>publicPath</code>&#x7B49;&#x914D;&#x7F6E;&#x4E0D;&#x4E00;&#x6837;&#xFF0C;&#x9700;&#x8981;&#x50CF;&#x672C;&#x6587;&#x4E00;&#x6837;&#x505A;&#x662F;&#x4E0D;&#x662F;&#x672C;&#x5730;&#x5F00;&#x53D1;&#x73AF;&#x5883;&#x7684;&#x5224;&#x65AD;&#x3002;</li>
<li><code>Vue2&#x9879;&#x76EE;</code>&#x6709;&#x7684;&#x8D44;&#x6E90;&#x8DEF;&#x5F84;&#x540D;&#x662F;<code>publicPath</code>&#xFF0C;&#x6709;&#x7684;&#x662F;<code>assetsPublicPath</code>&#xFF0C;&#x6839;&#x636E;&#x5B9E;&#x9645;&#x9879;&#x76EE;&#x6765;&#x3002;</li>
<li>&#x6574;&#x5408;qiankun&#x6700;&#x82B1;&#x65F6;&#x95F4;&#x7684;&#x4E0D;&#x662F;qiankun&#x672C;&#x8EAB;&#xFF0C;&#x662F;&#x5404;&#x4E2A;&#x7CFB;&#x7EDF;&#x7684;&#x767B;&#x5F55;&#x6539;&#x9020;&#xFF0C;&#x4EE5;&#x53CA;&#x4E0D;&#x65AD;&#x8BD5;&#x9519;&#x5C1D;&#x8BD5;&#xFF0C;&#x672C;&#x6587;&#x662F;&#x8FD9;&#x6837;&#x3002;</li>
<li>&#x78B0;&#x5230;&#x95EE;&#x9898;&#x591A;&#x770B;&#x5B98;&#x7F51;&#x7684; <a href="https://qiankun.umijs.org/zh/faq?ref=hanhan.pro">&#x5E38;&#x89C1;&#x95EE;&#x9898;</a> &#xFF0C;&#x90E8;&#x7F72;&#x76F8;&#x5173;&#x7684;&#x95EE;&#x9898;&#x591A;&#x770B;<a href="https://qiankun.umijs.org/zh/cookbook?ref=hanhan.pro">&#x5165;&#x95E8;&#x6559;&#x7A0B;</a>&#xFF0C;&#x7279;&#x522B;&#x662F;&#x90E8;&#x7F72;&#x76F8;&#x5173;&#x7684;&#xFF0C;&#x6839;&#x636E;&#x5B98;&#x7F51;&#x6587;&#x6863;&#x6765;&#x6CA1;&#x9519;&#x3002;</li>
<li>&#x4E00;&#x5B9A;&#x8981;&#x4ED4;&#x7EC6;&#x518D;&#x4ED4;&#x7EC6;&#xFF0C;&#x8010;&#x5FC3;&#x518D;&#x8010;&#x5FC3;&#xFF0C;&#x4E0D;&#x65AD;&#x5730;&#x8BD5;&#x9519;&#x3002;</li>
</ol>
<p>&#x4EE5;&#x4E0A;&#x5C31;&#x662F;&#x6574;&#x5408;<code>qiankun</code>&#x7684;&#x5FC3;&#x5F97;&#x603B;&#x7ED3;&#xFF0C;&#x5982;&#x679C;&#x6709;&#x9519;&#x8BEF;&#x548C;&#x4E0D;&#x5B8C;&#x5584;&#x7684;&#x5730;&#x65B9;&#xFF0C;&#x6B22;&#x8FCE;&#x6307;&#x6B63;&#x3002;</p>
<h4 id="%E8%BD%AC%E8%BD%BD%E8%AF%B4%E6%98%8E">&#x8F6C;&#x8F7D;&#x8BF4;&#x660E;</h4>
<p>&#x539F;&#x6587;&#x6807;&#x9898;&#xFF1A;&#x6574;&#x5408;qiankun&#x5FAE;&#x524D;&#x7AEF;&#x6846;&#x67B6;&#x7684;&#x5FC3;&#x5F97;&#x7B14;&#x8BB0;<br>
&#x539F;&#x6587;&#x5730;&#x5740;&#xFF1A;hanhan.pro/using-qiankun-micro-frontends-solution/<br>
&#x539F;&#x6587;&#x4F5C;&#x8005;&#xFF1A;xiaohan<br>
&#x8F6C;&#x8F7D;&#x8BF7;&#x6CE8;&#x660E;&#x51FA;&#x5904;</p>
]]></content:encoded></item><item><title><![CDATA[Mac M1安装arm版homebrew和nvm和nodejs]]></title><description><![CDATA[<p></p><p>Mac M1&#x4EE5;&#x53CA;&#x66F4;&#x65B0;&#x6B3E;ARM&#x67B6;&#x6784;&#x7684;&#x7535;&#x8111;&#xFF0C;&#x5B89;&#x88C5;homebrew&#x3001;nvm&#x3001;nodejs&#x7B80;&#x5355;&#x7684;&#x65B9;&#x6CD5;&#x5C0F;&#x8BB0;&#x3002;</p>
<h3 id="1-%E5%AE%89%E8%A3%85homebrew">1. &#x5B89;&#x88C5;homebrew</h3>
<pre><code class="language-bash">/bin/bash -c &quot;$(curl -fsSL https://gitee.com/ineo6/homebrew-install/raw/master/install.sh)&quot;
</code></pre>
<p>&#x7136;</p>]]></description><link>http://hanhan.pro/install-homebrew-nvm-nodejs-in-mac-m1-arm-system/</link><guid isPermaLink="false">6596a4b993ef2d0001f41551</guid><category><![CDATA[前端]]></category><category><![CDATA[macos]]></category><category><![CDATA[homebrew]]></category><category><![CDATA[nvm]]></category><category><![CDATA[nodejs]]></category><dc:creator><![CDATA[reno]]></dc:creator><pubDate>Sun, 19 Jun 2022 05:30:00 GMT</pubDate><media:content url="http://hanhan.pro/content/images/2022/12/banner-mac-homebrew.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://hanhan.pro/content/images/2022/12/banner-mac-homebrew.jpg" alt="Mac M1&#x5B89;&#x88C5;arm&#x7248;homebrew&#x548C;nvm&#x548C;nodejs"><p></p><p>Mac M1&#x4EE5;&#x53CA;&#x66F4;&#x65B0;&#x6B3E;ARM&#x67B6;&#x6784;&#x7684;&#x7535;&#x8111;&#xFF0C;&#x5B89;&#x88C5;homebrew&#x3001;nvm&#x3001;nodejs&#x7B80;&#x5355;&#x7684;&#x65B9;&#x6CD5;&#x5C0F;&#x8BB0;&#x3002;</p>
<h3 id="1-%E5%AE%89%E8%A3%85homebrew">1. &#x5B89;&#x88C5;homebrew</h3>
<pre><code class="language-bash">/bin/bash -c &quot;$(curl -fsSL https://gitee.com/ineo6/homebrew-install/raw/master/install.sh)&quot;
</code></pre>
<p>&#x7136;&#x540E;&#x4F1A;&#x63D0;&#x793A;&#x4E0B;&#x4E00;&#x6B65;&#xFF0C;&#x8981;&#x5728;&#x7EC8;&#x7AEF;&#x6267;&#x884C;&#x4EE5;&#x4E0B;&#x547D;&#x4EE4;&#xFF1A;</p>
<pre><code class="language-bash"> echo &apos;eval &quot;$(/opt/homebrew/bin/brew shellenv)&quot;&apos; &gt;&gt; /Users/&#x4F60;&#x7684;&#x7528;&#x6237;&#x540D;/.zprofile
    eval &quot;$(/opt/homebrew/bin/brew shellenv)&quot;
</code></pre>
<p>&#x6267;&#x884C;&#x540E;&#xFF0C;&#x5C31;&#x53EF;&#x4EE5;&#x987A;&#x5229;&#x5B89;&#x88C5;&#x6210;&#x529F;&#x3002;</p>
<h3 id="2-%E5%AE%89%E8%A3%85nvm">2. &#x5B89;&#x88C5;nvm</h3>
<pre><code class="language-bash">brew install nvm
</code></pre>
<p>&#x4E0B;&#x8F7D;&#x5B8C;nvm&#x57FA;&#x672C;&#x4E0A;&#x5C31;&#x80FD;&#x987A;&#x5229;&#x5B89;&#x88C5;&#x597D;&#x4E86;&#xFF0C;&#x7136;&#x540E;&#x4F1A;&#x663E;&#x793A;&#x4E00;&#x5927;&#x6BB5;&#x63D0;&#x793A;&#x5185;&#x5BB9;&#xFF1B;</p>
<pre><code class="language-bash"> export NVM_DIR=&quot;$HOME/.nvm&quot;
  [ -s &quot;/opt/homebrew/opt/nvm/nvm.sh&quot; ] &amp;&amp; \. &quot;/opt/homebrew/opt/nvm/nvm.sh&quot;  # This loads nvm
</code></pre>
<p>&#x628A;&#x63D0;&#x793A;&#x4E2D;&#x7684;&#x8FD9;&#x6BB5;&#x914D;&#x7F6E;&#x4EE3;&#x7801;&#xFF0C;&#x7C98;&#x8D34;&#x5230;&#x4F60;&#x7684;&#x7528;&#x6237;&#x76EE;&#x5F55;&#x4E0B;<code>.zshrc</code>&#x6587;&#x4EF6;&#x6216;&#x8005;<code>.zprofile</code>&#x6587;&#x4EF6;&#x91CC;&#x3002;</p>
<pre><code class="language-bash">brew reintall nvm
</code></pre>
<p>&#x5982;&#x679C;&#x6CA1;&#x6709;&#x63D0;&#x793A;&#x5B89;&#x88C5;&#x6210;&#x529F;&#xFF0C;&#x53EF;&#x4EE5;&#x91CD;&#x65B0;&#x5B89;&#x88C5;&#x4E00;&#x904D;&#x3002;</p>
<h3 id="3-%E4%BD%BF%E7%94%A8nvm">3. &#x4F7F;&#x7528;nvm</h3>
<p>&#x5728;&#x7EC8;&#x7AEF;&#x65B0;&#x5F00;&#x4E00;&#x4E2A;&#x7A97;&#x53E3;&#x6216;&#x8005;&#x6807;&#x7B7E;&#x9875;&#xFF0C;&#x7136;&#x540E;&#x8F93;&#x5165;<code>nvm</code>&#xFF0C;&#x7136;&#x540E;&#x51FA;&#x73B0;nvm&#x9009;&#x9879;&#xFF0C;&#x5C31;&#x8BF4;&#x660E;<code>nvm</code>&#x53EF;&#x7528;&#x4E86;&#x3002;</p>
<h3 id="4-%E5%AE%89%E8%A3%85nodejs">4. &#x5B89;&#x88C5;<code>nodejs</code></h3>
<pre><code class="language-bash">nvm i 14.17.0
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Vue3项目中使用Less]]></title><description><![CDATA[Vue3新项目中安装使用less整体跟vue2差不多，需要先安装less相关的依赖，然后添加一些配置。]]></description><link>http://hanhan.pro/vue/</link><guid isPermaLink="false">6596a4b993ef2d0001f41550</guid><category><![CDATA[vue]]></category><category><![CDATA[前端]]></category><category><![CDATA[less]]></category><dc:creator><![CDATA[reno]]></dc:creator><pubDate>Tue, 30 Nov 2021 03:13:35 GMT</pubDate><media:content url="http://hanhan.pro/content/images/2021/11/banner-dark-blue.jpg" medium="image"/><content:encoded><![CDATA[<h3 id="%E5%AE%89%E8%A3%85%E6%AD%A5%E9%AA%A4">&#x5B89;&#x88C5;&#x6B65;&#x9AA4;</h3>
<ol>
<li>&#x5B89;&#x88C5;<code>less</code>&#x6700;&#x65B0;&#x7248;&#x548C;<code>less-loader</code>&#x7684;<code>7.2.0</code>&#xFF08;10.2.0&#x62A5;&#x9519;&#xFF09;&#x7248;&#x672C;&#xFF1A;</li>
</ol>
<pre><code class="language-bash">npm i less -D
npm i less-loader@7.2.0 -D
</code></pre>
<ol start="2">
<li>&#x5B89;&#x88C5;<code>style-resources-loader</code>&#x548C;<code>vue-cli-plugin-style-resources-loader</code>&#x6700;&#x65B0;&#x7248;&#xFF1A;</li>
</ol>
<pre><code class="language-bash">npm i style-resources-loader vue-cli-plugin-style-resources-loader -D
</code></pre>
<ol start="3">
<li>&#x5728;&#x9879;&#x76EE;&#x6839;&#x76EE;&#x5F55;&#x7684;<code>vue.config.js</code>&#x6587;&#x4EF6;&#xFF08;&#x6CA1;&#x6709;&#x5219;&#x65B0;&#x5EFA;&#xFF09;&#x6DFB;&#x52A0;&#x4EE5;&#x4E0B;&#x914D;&#x7F6E;&#xFF1A;</li>
</ol>
<pre><code class="language-js">const path = require(&apos;path&apos;)

module.exports = {
  pluginOptions: {
    &apos;style-resources-loader&apos;: {
      preProcessor: &apos;less&apos;,
      patterns: [
        path.resolve(__dirname, &apos;src/global.less&apos;)
      ]
    }
  }
}
</code></pre>
<ol start="4">
<li>&#x53EF;&#x4EE5;&#x5728;&#x9879;&#x76EE;&#x4E2D;&#x4F7F;&#x7528;<code>less</code>&#x4E86;&#x3002;</li>
</ol>
<pre><code class="language-js">&lt;style lang=&quot;less&quot;&gt;
...
&lt;/style&gt;
</code></pre>
]]></content:encoded></item><item><title><![CDATA[使用Vue Cli4+Electron 13搭建桌面端应用小记]]></title><description><![CDATA[为了选择较新的vue和electron版本，本文使用vue cli4和vue-cli-plugin-electron-builder插件搭建了一个基于vue的桌面端应用，并记录了项目搭建前后的一些技术点和注意事项。]]></description><link>http://hanhan.pro/use-vue-electron-to-build-desktop-app/</link><guid isPermaLink="false">6596a4b993ef2d0001f4154f</guid><category><![CDATA[electron]]></category><category><![CDATA[vue]]></category><dc:creator><![CDATA[reno]]></dc:creator><pubDate>Wed, 24 Nov 2021 02:51:19 GMT</pubDate><media:content url="http://hanhan.pro/content/images/2021/11/vue-electron.jpg" medium="image"/><content:encoded><![CDATA[<h2 id="%E9%A1%B9%E7%9B%AE%E9%85%8D%E7%BD%AE">&#x9879;&#x76EE;&#x914D;&#x7F6E;</h2>
<ul>
<li>Vue: 2</li>
<li>Vue Cli: 4.5.14</li>
<li>Electron: 13.6.0</li>
<li>Nodejs: 14.17.0</li>
</ul>
<h2 id="%E9%A1%B9%E7%9B%AE%E6%90%AD%E5%BB%BA">&#x9879;&#x76EE;&#x642D;&#x5EFA;</h2>
<ol>
<li>&#x521B;&#x5EFA;Vue&#x9879;&#x76EE;&#xFF1B;</li>
</ol>
<pre><code class="language-bash">vue create vue-project
</code></pre>
<img src="http://hanhan.pro/content/images/2021/11/vue-electron.jpg" alt="&#x4F7F;&#x7528;Vue Cli4+Electron 13&#x642D;&#x5EFA;&#x684C;&#x9762;&#x7AEF;&#x5E94;&#x7528;&#x5C0F;&#x8BB0;"><p>&#x672C;&#x6587;&#x4F7F;&#x7528;&#x7684;vue2 default&#xFF0C;&#x76F4;&#x63A5;&#x5B89;&#x88C5;&#x5B8C;&#x6210;&#x3002;&#x5EFA;&#x8BAE;&#x81EA;&#x5B9A;&#x4E49;&#xFF0C;&#x7136;&#x540E;&#x628A;less&#x5B89;&#x88C5;&#x4E0A;&#x53BB;&#xFF0C;&#x4EE5;&#x4FBF;&#x7ED3;&#x5408;antd vue&#x4F7F;&#x7528;&#x3002;</p>
<ol start="2">
<li>&#x8FDB;&#x5165;&#x9879;&#x76EE;&#x76EE;&#x5F55;&#xFF1B;</li>
</ol>
<pre><code class="language-bash">cd vue-project
</code></pre>
<ol start="3">
<li>&#x5B89;&#x88C5;&#x5E76;&#x8C03;&#x7528;vue-cli-plugin-electron-builder&#x7684;&#x751F;&#x6210;&#x5668;&#xFF1B;</li>
</ol>
<pre><code class="language-bash">vue add electron-builder
</code></pre>
<p>&#x8FD9;&#x6B65;&#x9700;&#x8981;&#x7B49;&#x5F85;&#x5DEE;&#x4E0D;&#x591A;1&#x5206;&#x949F;&#x5DE6;&#x53F3;&#xFF0C;&#x5982;&#x679C;&#x7F51;&#x7EDC;&#x4E0D;&#x7A33;&#x5B9A;&#x9020;&#x6210;electron&#x5B89;&#x88C5;&#x5931;&#x8D25;&#xFF0C;&#x9700;&#x8981;&#x91CD;&#x65B0;&#x6267;&#x884C;&#x8FD9;&#x4E00;&#x6B65;&#x3002;</p>
<ol start="4">
<li>&#x5B89;&#x88C5;&#x597D;&#x4F9D;&#x8D56;&#xFF0C;&#x5C31;&#x53EF;&#x4EE5;&#x8FD0;&#x884C;&#x9879;&#x76EE;&#x4E86;&#xFF1B;</li>
</ol>
<pre><code class="language-bash">yarn electron:serve
</code></pre>
<p>&#x6216;</p>
<pre><code class="language-bash">npm run electron:serve
</code></pre>
<ol start="5">
<li>&#x9879;&#x76EE;&#x6253;&#x5305;&#x6210;&#x684C;&#x9762;&#x7AEF;app&#xFF1B;</li>
</ol>
<pre><code class="language-bash">yarn electron:build
</code></pre>
<p>&#x6216;</p>
<pre><code class="language-bash">npm run electron:build
</code></pre>
<h2 id="%E5%BA%94%E7%94%A8%E9%85%8D%E7%BD%AE">&#x5E94;&#x7528;&#x914D;&#x7F6E;</h2>
<p>&#x5F00;&#x53D1;&#x684C;&#x9762;&#x7AEF;&#x5E94;&#x7528;&#xFF0C;&#x5173;&#x4E8E;less&#x3001;&#x5E94;&#x7528;&#x6807;&#x9898;&#x3001;&#x6253;&#x5305;&#x7B49;&#x914D;&#x7F6E;&#x5982;&#x4E0B;&#xFF1A;</p>
<h3 id="%E5%AE%89%E8%A3%85less">&#x5B89;&#x88C5;LESS</h3>
<p>&#x5982;&#x679C;&#x5B89;&#x88C5;&#x7684;vue2&#x9879;&#x76EE;&#x6CA1;&#x6709;&#x5F15;&#x5165;less&#xFF0C;&#x5728;&#x57FA;&#x4E8E;vue cli4&#x7684;&#x9879;&#x76EE;&#x91CC;&#x5B89;&#x88C5;less&#xFF0C;&#x4EE5;&#x53CA;&#x4F7F;&#x7528;antd vue&#x7684;less&#x7248;&#x672C;&#x65B9;&#x6CD5;&#x5982;&#x4E0B;&#xFF1A;</p>
<ol>
<li>&#x5B89;&#x88C5;<code>less</code>&#x548C;<code>less-loader</code>&#xFF1B;</li>
</ol>
<pre><code class="language-bash">npm i less@3.9.0 less-loader@6.1.0
</code></pre>
<p>&#x5728;<code>node</code>14.17.0&#x4E0B;&#x4F7F;&#x7528;<code>less-loader</code>6.1.0&#x7248;&#x672C;&#x6CA1;&#x6709;&#x95EE;&#x9898;&#xFF0C;&#x4F7F;&#x7528;7&#x4EE5;&#x4E0A;&#x7684;&#x7248;&#x672C;&#x5C31;&#x62A5;&#x9519;&#x4E86;&#x3002;</p>
<ol start="2">
<li>&#x5B89;&#x88C5;&#x4EE5;&#x4E0B;&#x4F9D;&#x8D56;&#xFF1A;</li>
</ol>
<pre><code class="language-bash">npm i style-resources-loader vue-cli-plugin-style-resources-loader -D
</code></pre>
<ol start="3">
<li>&#x5728;&#x9879;&#x76EE;&#x6839;&#x76EE;&#x5F55;&#x7684;<code>vue.config.js</code>&#x6587;&#x4EF6;&#x6DFB;&#x52A0;&#x5982;&#x4E0B;&#x914D;&#x7F6E;&#xFF1A;</li>
</ol>
<pre><code class="language-js">const path = require(&apos;path&apos;)

module.exports = {
  pluginOptions: {
    &apos;style-resources-loader&apos;: {
      preProcessor: &apos;less&apos;,
      patterns: [
        path.resolve(__dirname, &apos;src/global.less&apos;)
      ]
    }
  }
}
</code></pre>
<p>&#x8BF4;&#x660E;&#xFF1A;<code>global.less</code>&#x6587;&#x4EF6;&#x9700;&#x8981;&#x65B0;&#x5EFA;&#x6216;&#x6539;&#x4E3A;&#x4F60;&#x81EA;&#x5DF1;&#x7684;&#x5168;&#x5C40;less&#x6587;&#x4EF6;&#x540D;&#xFF1B;</p>
<ol start="4">
<li>
<p>&#x73B0;&#x5728;&#x53EF;&#x4EE5;&#x5728;vue&#x9879;&#x76EE;&#x91CC;&#x6109;&#x5FEB;&#x7684;&#x4F7F;&#x7528;less&#x4E86;&#xFF0C;&#x5982;&#x9700;&#x5F15;&#x7528;antd&#x7684;less&#x7EE7;&#x7EED;&#x5F80;&#x4E0B;&#x64CD;&#x4F5C;&#xFF1B;</p>
</li>
<li>
<p>&#x5728;&#x9879;&#x76EE;&#x6839;&#x76EE;&#x5F55;&#x7684;<code>babel.config.js</code>&#x6587;&#x4EF6;&#x91CC;&#x7684;<code>plugins</code>&#x4E0B;&#x9762;&#x6DFB;&#x52A0;&#x5982;&#x4E0B;&#x914D;&#x7F6E;&#xFF1A;</p>
</li>
</ol>
<pre><code class="language-js">module.exports = {
  plugins: [
    [
      &apos;import&apos;,
      { libraryName: &apos;ant-design-vue&apos;, libraryDirectory: &apos;es&apos;, style: true }
    ]
  ]
}
</code></pre>
<ol start="6">
<li>&#x5728;&#x9879;&#x76EE;&#x7684;<code>main.js</code>&#x91CC;&#x53EF;&#x4EE5;&#x50CF;&#x4E0B;&#x9762;&#x8FD9;&#x6837;&#x6309;&#x9700;&#x5F15;&#x7528;antd&#x7684;&#x7EC4;&#x4EF6;&#x4E86;&#xFF0C;&#x800C;&#x4E0D;&#x662F;&#x5F15;&#x7528;&#x6574;&#x4E2A;css&#x6587;&#x4EF6;&#xFF1B;</li>
</ol>
<pre><code class="language-js">import {
  Badge, Button, Card, Divider, 
} from &apos;ant-design-vue&apos;
</code></pre>
<h3 id="%E5%BA%94%E7%94%A8%E6%A0%87%E9%A2%98%E9%85%8D%E7%BD%AE">&#x5E94;&#x7528;&#x6807;&#x9898;&#x914D;&#x7F6E;</h3>
<p>&#x9ED8;&#x8BA4;electron&#x5F00;&#x542F;&#x4E86;&#x8FB9;&#x6846;&#x663E;&#x793A;&#xFF0C;&#x6807;&#x9898;&#x4F1A;&#x663E;&#x793A;&#x5728;&#x7A97;&#x4F53;&#x5E95;&#x90E8;&#x3002;&#x5982;&#x679C;&#x8BBE;&#x7F6E;&#x4E86;&#x4E0D;&#x663E;&#x793A;&#x8FB9;&#x6846;&#x5219;&#x6807;&#x9898;&#x4E0D;&#x663E;&#x793A;&#x3002;</p>
<pre><code class="language-js">module.exports = {
  chainWebpack: config =&gt; {
    config.plugin(&apos;html&apos;)
      .tap(args =&gt; {
        args[0].title = &quot;&#x5E94;&#x7528;&#x540D;&#x79F0;&quot;
        return args
      })
  }
}
</code></pre>
<p>&#x8FD9;&#x91CC;&#x8BBE;&#x7F6E;&#x597D;&#x5C31;&#x53EF;&#x4EE5;&#x4E86;&#xFF0C;&#x5C31;&#x4E0D;&#x7528;&#x5230;<code>index.html</code>&#x91CC;&#x4FEE;&#x6539;&#x4E86;&#x3002;</p>
<h3 id="vue%E8%AF%BB%E5%86%99%E6%96%87%E4%BB%B6%E9%85%8D%E7%BD%AE">Vue&#x8BFB;&#x5199;&#x6587;&#x4EF6;&#x914D;&#x7F6E;</h3>
<p>&#x9ED8;&#x8BA4;&#x5728;vue&#x91CC;&#x65E0;&#x6CD5;&#x8BFB;&#x53D6;&#x672C;&#x5730;&#x6587;&#x4EF6;&#xFF0C;&#x9700;&#x8981;&#x5728;&#x6839;&#x76EE;&#x5F55;&#x7684;<code>vue.config.js</code>&#x6587;&#x4EF6;&#x6DFB;&#x52A0;&#x5982;&#x4E0B;&#x914D;&#x7F6E;&#xFF1A;</p>
<pre><code class="language-js">module.exports = {
  pluginOptions: {
    electronBuilder: {
      nodeIntegration: true
    }
  }
}
</code></pre>
<h3 id="%E5%AE%8C%E6%95%B4%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6">&#x5B8C;&#x6574;&#x914D;&#x7F6E;&#x6587;&#x4EF6;</h3>
<h4 id="babelconfigjs%E9%85%8D%E7%BD%AE"><code>babel.config.js</code>&#x914D;&#x7F6E;</h4>
<pre><code class="language-js">module.exports = {
  presets: [
    &apos;@vue/cli-plugin-babel/preset&apos;
  ],
  plugins: [
    [
      &apos;import&apos;,
      { libraryName: &apos;ant-design-vue&apos;, libraryDirectory: &apos;es&apos;, style: true }
    ]
  ]
}
</code></pre>
<h4 id="vueconfigjs%E9%85%8D%E7%BD%AE"><code>vue.config.js</code>&#x914D;&#x7F6E;</h4>
<pre><code class="language-js">const path = require(&apos;path&apos;)

module.exports = {
  css: {  
    loaderOptions: {
      less: {
        lessOptions:{
          modifyVars: {},
          javascriptEnabled: true,
        }
      }
    }
  },
  chainWebpack: config =&gt;{
    config.plugin(&apos;html&apos;)
      .tap(args =&gt; {
        args[0].title = &quot;&#x5E94;&#x7528;&#x540D;&#x79F0;&quot;
        return args
      })
  },
  pluginOptions: {
    &apos;style-resources-loader&apos;: {
      preProcessor: &apos;less&apos;,
      patterns: [
        path.resolve(__dirname, &apos;src/global.less&apos;)
      ]
    },
    electronBuilder: {
      builderOptions: {
        extraResources: {
          from: &apos;./public/data&apos;,
          to: &apos;./data&apos;
        },
        mac: {
          icon: &apos;./public/app.png&apos;
        },
        win: {
          icon: &apos;./public/app.ico&apos;
        },
        productName: &apos;build-app-name&apos;,
      },
      nodeIntegration: true
    }
  }
}
</code></pre>
<h3 id="electron%E5%BC%80%E5%8F%91%E6%8A%80%E6%9C%AF%E7%82%B9">Electron&#x5F00;&#x53D1;&#x6280;&#x672F;&#x70B9;</h3>
<h4 id="%E5%8F%91%E9%80%81%E6%B6%88%E6%81%AF">&#x53D1;&#x9001;&#x6D88;&#x606F;</h4>
<ol>
<li>&#x6E32;&#x67D3;&#x8FDB;&#x7A0B;(vue&#x7AEF;)&#x5411;&#x4E3B;&#x7EBF;&#x7A0B;(electron&#x7AEF;)&#x53D1;&#x9001;&#x6570;&#x636E;&#xFF1A;</li>
</ol>
<pre><code class="language-js">import { ipcRenderer } from &apos;electron&apos;

const data = { a: 1 }
ipcRenderer.send(&apos;call&apos;, data)
</code></pre>
<p>&#x53D1;&#x9001;&#x7684;&#x6570;&#x636E;&#x652F;&#x6301;&#x6570;&#x7EC4;&#x6216;&#x5BF9;&#x8C61;&#x683C;&#x5F0F;&#x3002;</p>
<ol start="2">
<li>&#x4E3B;&#x7EBF;&#x7A0B;&#x63A5;&#x6536;&#x6E32;&#x67D3;&#x8FDB;&#x7A0B;&#x53D1;&#x8FC7;&#x6765;&#x7684;&#x6570;&#x636E;&#xFF0C;&#x5E76;&#x8FD4;&#x56DE;&#x6570;&#x636E;&#xFF1B;</li>
</ol>
<pre><code class="language-js">import { ipcMain } from &apos;electron&apos;

ipcMain.on(&apos;call&apos;, (event, data) =&gt; {
  console.log(&apos;data&apos;, data)
  // ...
  const replyData = { success: true, message: &apos;&#x6536;&#x5230;&#x6570;&#x636E;&#x4E86;&apos; }
  event.reply(&apos;reply&apos;, replyData)
})
</code></pre>
<ol start="3">
<li>&#x6E32;&#x67D3;&#x8FDB;&#x7A0B;&#x63A5;&#x6536;&#x4E3B;&#x7EBF;&#x7A0B;&#x53D1;&#x9001;&#x6570;&#x636E;&#xFF1A;</li>
</ol>
<pre><code class="language-js">import { ipcRenderer } from &apos;electron&apos;

ipcRenderer.on(&apos;reply&apos;, function(event, data) {
  console.log(&apos;data&apos;, data)
})
</code></pre>
<p><code>reply</code>&#x4E3A;&#x4E0A;&#x9762;&#x4E3B;&#x7EBF;&#x7A0B;<code>background.js</code>&#x91CC;&#x5B9A;&#x4E49;&#x7684;&#x4E8B;&#x4EF6;&#x540D;&#x3002;&#x81F3;&#x6B64;3&#x6B65;&#xFF0C;&#x5C31;&#x662F;&#x4ECE;&#x6E32;&#x67D3;&#x8FDB;&#x7A0B;&#x53D1;&#x9001;&#x5230;&#x63A5;&#x6536;&#x6570;&#x636E;&#x7684;&#x4E00;&#x4E2A;&#x8FC7;&#x7A0B;&#x4E86;&#x3002;</p>
<ol start="4">
<li>&#x5982;&#x679C;&#x9700;&#x8981;&#x4ECE;&#x4E3B;&#x8FDB;&#x7A0B;&#x4E3B;&#x52A8;&#x5411;&#x6E32;&#x67D3;&#x8FDB;&#x7A0B;&#x53D1;&#x9001;&#x6570;&#x636E;&#xFF0C;&#x65B9;&#x5F0F;&#x5982;&#x4E0B;&#xFF1A;</li>
</ol>
<pre><code class="language-js">win.webContents.send(&apos;fromElectron&apos;, { b: 2 })
</code></pre>
<p>&#x8FD9;&#x91CC;&#x7684;<code>win</code>&#x662F;electron&#x521D;&#x59CB;&#x5316;&#x540E;&#x7684;&#x7A97;&#x4F53;&#x3002;</p>
<h4 id="backgroundjs%E4%BB%A3%E7%A0%81%E5%86%99%E6%B3%95"><code>background.js</code>&#x4EE3;&#x7801;&#x5199;&#x6CD5;</h4>
<p>&#x8FD9;&#x662F;&#x9879;&#x76EE;&#x751F;&#x6210;&#x7684;electron&#x5165;&#x53E3;&#x6587;&#x4EF6;&#xFF0C;&#x9ED8;&#x8BA4;&#x662F;&#x591A;&#x4E2A;function&#x540C;&#x6B65;&#x5199;&#x6CD5;&#xFF0C;&#x5EFA;&#x8BAE;&#x6539;&#x9020;&#x6210;<code>Class</code>&#x7684;&#x5199;&#x6CD5;&#xFF0C;&#x4FBF;&#x4E8E;&#x540E;&#x671F;&#x6269;&#x5C55;&#x3002;</p>
<pre><code class="language-js">&apos;use strict&apos;

import { app, protocol, BrowserWindow, ipcMain, nativeTheme } from &apos;electron&apos;
import { createProtocol } from &apos;vue-cli-plugin-electron-builder/lib&apos;
import installExtension, { VUEJS_DEVTOOLS } from &apos;electron-devtools-installer&apos;
const isDevelopment = process.env.NODE_ENV !== &apos;production&apos;

class ElectronApp {
  constructor() {
    this.mainWindow = null
  }

  init() {
    this.initApp()
    this.bindEvents()
  }
  
  initApp() {
    // Scheme must be registered before the app is ready
    protocol.registerSchemesAsPrivileged([
      { scheme: &apos;app&apos;, privileges: { secure: true, standard: true } }
    ])

    // Quit when all windows are closed.
    app.on(&apos;window-all-closed&apos;, () =&gt; {
      // On macOS it is common for applications and their menu bar
      // to stay active until the user quits explicitly with Cmd + Q
      if (process.platform !== &apos;darwin&apos;) {
        app.quit()
      }
    })

    app.on(&apos;activate&apos;, () =&gt; {
      // On macOS it&apos;s common to re-create a window in the app when the
      // dock icon is clicked and there are no other windows open.
      if (BrowserWindow.getAllWindows().length === 0) this.createWindow()
    })

    // This method will be called when Electron has finished
    // initialization and is ready to create browser windows.
    // Some APIs can only be used after this event occurs.
    app.on(&apos;ready&apos;, async () =&gt; {
      if (isDevelopment &amp;&amp; !process.env.IS_TEST) {
        // Install Vue Devtools
        try {
          await installExtension(VUEJS_DEVTOOLS)
        } catch (e) {
          console.error(&apos;Vue Devtools failed to install:&apos;, e.toString())
        }
      }
      await this.createWindow()
    })

    // Exit cleanly on request from parent process in development mode.
    if (isDevelopment) {
      if (process.platform === &apos;win32&apos;) {
        process.on(&apos;message&apos;, (data) =&gt; {
          if (data === &apos;graceful-exit&apos;) {
            app.quit()
          }
        })
      } else {
        process.on(&apos;SIGTERM&apos;, () =&gt; {
          app.quit()
        })
      }
    }

  }

  bindEvents() {
    // &#x5207;&#x6362;&#x64CD;&#x4F5C;
    ipcMain.on(&apos;call&apos;, async (event, app, project) =&gt; {
      const replyData = { success: true, message: &apos;&#x6536;&#x5230;&#x6570;&#x636E;&#x4E86;&apos; }
      event.reply(&apos;reply&apos;, replyData)
    })
  }

  async createWindow() {
    // Create the browser window.
    const win = new BrowserWindow({
      width: 800,
      height: 600,
      minWidth: 800,
      minHeight: 600,
      webPreferences: {
        // Use pluginOptions.nodeIntegration, leave this alone
        // See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
        nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
        contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION,
      },
    })

    win.setMenu(null)

    if (process.env.WEBPACK_DEV_SERVER_URL) {
      // Load the url of the dev server if in development mode
      await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
      if (!process.env.IS_TEST) win.webContents.openDevTools()
    } else {
      createProtocol(&apos;app&apos;)
      // Load the index.html when not in development
      win.loadURL(&apos;app://./index.html&apos;)
    }

    this.mainWindow = win
  }

}

new ElectronApp().init()
</code></pre>
]]></content:encoded></item><item><title><![CDATA[在Taro 3 React工程使用DVA]]></title><description><![CDATA[在Taro3 React版本的工程中使用Dva，大体上跟Taro 2的版本差不多，只是有一些依赖和引用不一样。]]></description><link>http://hanhan.pro/using-dva-in-taro3-react-project/</link><guid isPermaLink="false">6596a4b993ef2d0001f4154e</guid><category><![CDATA[前端]]></category><category><![CDATA[DVA]]></category><category><![CDATA[Taro]]></category><dc:creator><![CDATA[reno]]></dc:creator><pubDate>Thu, 10 Jun 2021 02:40:18 GMT</pubDate><media:content url="http://hanhan.pro/content/images/2021/06/taro-3-dva.jpg" medium="image"/><content:encoded><![CDATA[<h3 id="%E6%93%8D%E4%BD%9C%E6%AD%A5%E9%AA%A4">&#x64CD;&#x4F5C;&#x6B65;&#x9AA4;</h3>
<ol>
<li>
<img src="http://hanhan.pro/content/images/2021/06/taro-3-dva.jpg" alt="&#x5728;Taro 3 React&#x5DE5;&#x7A0B;&#x4F7F;&#x7528;DVA"><p>&#x4F7F;&#x7528;taro&#x521B;&#x5EFA;&#x811A;&#x624B;&#x67B6;&#x5DE5;&#x7A0B;&#xFF0C;&#x6700;&#x597D;&#x9009;&#x9ED8;&#x8BA4;&#xFF0C;&#x9009;redux&#x7684;&#x8BDD;&#x8FD8;&#x9700;&#x8981;&#x4FEE;&#x6539;&#xFF1B;</p>
</li>
<li>
<p>&#x5B89;&#x88C5;DVA&#x76F8;&#x5173;&#x4F9D;&#x8D56;&#xFF1A;</p>
</li>
</ol>
<pre><code class="language-bash">npm i redux react-redux redux-logger redux-thunk dva-core dva-loading
</code></pre>
<p>&#x4E0D;&#x9700;&#x8981;&#x5B89;&#x88C5;<code>@tarojs/redux</code>&#x548C;<code>@tarojs/redux-h5</code></p>
<ol start="3">
<li>&#x5B89;&#x88C5;&#x5176;&#x4ED6;&#x4F9D;&#x8D56;&#xFF1A;</li>
</ol>
<pre><code class="language-bash">npm i
</code></pre>
<ol start="4">
<li>&#x5728;<code>src/app.tsx</code>&#x540C;&#x7EA7;&#x589E;&#x52A0;<code>dva.ts</code>&#xFF1A;</li>
</ol>
<pre><code class="language-ts">import Taro from &apos;@tarojs/taro&apos;
import { create } from &apos;dva-core&apos;
// import { createLogger } from &apos;redux-logger&apos;
import createLoading from &apos;dva-loading&apos;

let app, store, dispatch, registered

function createApp(options?: any) {
  const { models } = options
  // if (process.env.NODE_ENV === &apos;development&apos;) {
  //   options.onAction = [createLogger()]
  // }
  app = create({
    ...options
  })
  app.use(createLoading({}))

  // &#x9002;&#x914D;&#x652F;&#x4ED8;&#x5B9D;&#x5C0F;&#x7A0B;&#x5E8F;
  if (Taro.getEnv() === Taro.ENV_TYPE.ALIPAY) {
    global = {};
  }

  if (!global.registered) models.forEach((model) =&gt; app.model(model))
  global.registered = true
  app.start()

  store = app._store
  app.getStore = () =&gt; store
  
  dispatch = store.dispatch
  app.dispatch = dispatch

  global.store = store

  return app
}

export default {
  createApp,
  getDispatch() {
    return app.dispatch
  }
}
</code></pre>
<ol start="5">
<li>&#x5728;<code>src/pages/index</code>&#x76EE;&#x5F55;&#x4E0B;&#xFF0C;&#x521B;&#x5EFA;<code>model.ts</code>&#xFF1A;</li>
</ol>
<pre><code class="language-ts">export interface HomeModelState {
}

const HomeModel = {
  namespace: &apos;home&apos;,
  state: {
  },
  effects: {
  },
  reducers: {
    save(state, { payload }) {
      return {
        ...state,
        ...payload,
      }
    }
  },
}

export default HomeModel
</code></pre>
<ol start="6">
<li>&#x5728;<code>src</code>&#x76EE;&#x5F55;&#x4E0B;&#x5EFA;&#x7ACB;<code>models</code>&#x76EE;&#x5F55;&#xFF0C;&#x5E76;&#x521B;&#x5EFA;<code>index.ts</code>&#xFF1A;</li>
</ol>
<pre><code class="language-ts">import home from &apos;../pages/index/model&apos;

export default [
  home,
]
</code></pre>
<p>&#x5EFA;&#x8BAE;&#x5728;<code>src/models</code>&#x4E0B;&#x653E;&#x516C;&#x7528;&#x7684;model&#x6587;&#x4EF6;&#xFF0C;&#x5176;&#x4ED6;&#x5206;&#x522B;&#x653E;&#x5728;&#x9875;&#x9762;&#x76EE;&#x5F55;&#xFF0C;&#x5E76;&#x5728;&#x8FD9;&#x4E2A;&#x5165;&#x53E3;&#x6587;&#x4EF6;<code>index.ts</code>&#x91CC;&#x5BFC;&#x5165;&#x8FDB;&#x6765;&#x3002;</p>
<ol start="7">
<li>&#x4FEE;&#x6539;<code>src</code>&#x76EE;&#x5F55;&#x4E0B;&#x7684;<code>app.tsx</code>&#xFF1A;</li>
</ol>
<pre><code class="language-tsx">import { Provider } from &apos;react-redux&apos;
import dva from &apos;./dva&apos;
import models from &apos;./models/index&apos;


const dvaApp = dva.createApp({
  initialState: {},
  models: models
});
const store = dvaApp.getStore();
</code></pre>
<p>&#x4E0A;&#x9762;&#x662F;&#x8981;&#x589E;&#x52A0;&#x7684;&#x4EE3;&#x7801;&#xFF1B;</p>
<pre><code class="language-tsx">...

  render () {
    return (
      &lt;Provider store={store}&gt;
        &lt;Index /&gt;
      &lt;/Provider&gt;
    )
  }

...

</code></pre>
<p>&#x5982;&#x4E0A;&#xFF0C;&#x5C31;&#x5728;<code>render</code>&#x91CC;&#x7684;<code>&lt;Index /&gt;</code>&#x5916;&#x5305;&#x88F9;<code>Provider</code>&#x5C31;&#x597D;&#x3002;</p>
<p>&#x81EA;&#x6B64;&#xFF0C;Taro 3&#x7684;react&#x5DE5;&#x7A0B;&#x5F15;&#x5165;Dva&#x5B8C;&#x6210;&#x3002;<br>
&#x672C;&#x6587;&#x9002;&#x7528;&#x4E8E;Taro 3.x.x&#xFF0C;&#x4EB2;&#x6D4B;&#x6CA1;&#x95EE;&#x9898;&#x3002;</p>
<h3 id="taro3%E4%B8%8E2%E5%AE%89%E8%A3%85dva%E7%9A%84%E5%8C%BA%E5%88%AB">Taro3&#x4E0E;2&#x5B89;&#x88C5;Dva&#x7684;&#x533A;&#x522B;</h3>
<ol>
<li>Taro 3&#x4E0D;&#x9700;&#x8981;&#x5B89;&#x88C5;<code>@tarojs/redux</code>&#x548C;<code>@tarojs/redux-h5</code>&#xFF1B;</li>
<li>Taro 3&#x8981;&#x4ECE;<code>react-redux</code>&#x91CC;&#x5F15;&#x5165;<code>Provider</code>&#xFF1B;</li>
</ol>
<pre><code class="language-ts">import { Provider } from &apos;react-redux&apos;
</code></pre>
]]></content:encoded></item><item><title><![CDATA[在Taro2工程中使用DVA]]></title><description><![CDATA[本文是关于Ts版的Taro 2工程如何引入Dva 2。整体思路就是先安装默认脚手架工程，然后安装dva相关依赖及其他依赖，然后编写相关代码，引入dva。]]></description><link>http://hanhan.pro/using-dva-in-taro2/</link><guid isPermaLink="false">6596a4b993ef2d0001f4154c</guid><category><![CDATA[前端]]></category><category><![CDATA[DVA]]></category><category><![CDATA[Taro]]></category><dc:creator><![CDATA[reno]]></dc:creator><pubDate>Sun, 17 May 2020 16:13:00 GMT</pubDate><media:content url="http://hanhan.pro/content/images/2021/06/taro-2-dva.jpg" medium="image"/><content:encoded><![CDATA[<h3 id="%E6%93%8D%E4%BD%9C%E6%AD%A5%E9%AA%A4">&#x64CD;&#x4F5C;&#x6B65;&#x9AA4;</h3>
<ol>
<li>
<img src="http://hanhan.pro/content/images/2021/06/taro-2-dva.jpg" alt="&#x5728;Taro2&#x5DE5;&#x7A0B;&#x4E2D;&#x4F7F;&#x7528;DVA"><p>&#x521B;&#x5EFA;&#x5B98;&#x65B9;&#x811A;&#x624B;&#x67B6;&#x5DE5;&#x7A0B;&#xFF0C;&#x672C;&#x6587;&#x9009;&#x7684;&#x9ED8;&#x8BA4;&#xFF0C;&#x6CA1;&#x6709;&#x9009;redux&#xFF1B;</p>
</li>
<li>
<p>&#x5B89;&#x88C5;DVA&#x76F8;&#x5173;&#x4F9D;&#x8D56;&#xFF1A;</p>
</li>
</ol>
<pre><code class="language-bash">npm i redux @tarojs/redux @tarojs/redux-h5 redux-logger redux-thunk dva-core dva-loading
</code></pre>
<ol start="3">
<li>&#x5B89;&#x88C5;&#x5176;&#x4ED6;&#x4F9D;&#x8D56;&#xFF1A;</li>
</ol>
<pre><code class="language-bash">npm i
</code></pre>
<ol start="4">
<li>&#x5728;<code>src/app.tsx</code>&#x540C;&#x7EA7;&#x589E;&#x52A0;<code>dva.ts</code>&#xFF1A;</li>
</ol>
<pre><code class="language-ts">import Taro from &apos;@tarojs/taro&apos;
import { create } from &apos;dva-core&apos;
// import { createLogger } from &apos;redux-logger&apos;
import createLoading from &apos;dva-loading&apos;

let app, store, dispatch, registered

function createApp(options?: any) {
  const { models } = options
  // if (process.env.NODE_ENV === &apos;development&apos;) {
  //   options.onAction = [createLogger()]
  // }
  app = create({
    ...options
  })
  app.use(createLoading({}))

  // &#x9002;&#x914D;&#x652F;&#x4ED8;&#x5B9D;&#x5C0F;&#x7A0B;&#x5E8F;
  if (Taro.getEnv() === Taro.ENV_TYPE.ALIPAY) {
    global = {};
  }

  if (!global.registered) models.forEach((model) =&gt; app.model(model))
  global.registered = true
  app.start()

  store = app._store
  app.getStore = () =&gt; store
  
  dispatch = store.dispatch
  app.dispatch = dispatch

  global.store = store

  return app
}

export default {
  createApp,
  getDispatch() {
    return app.dispatch
  }
}
</code></pre>
<ol start="5">
<li>&#x5728;<code>src/pages/index</code>&#x76EE;&#x5F55;&#x4E0B;&#xFF0C;&#x521B;&#x5EFA;<code>model.ts</code>&#xFF1A;</li>
</ol>
<pre><code class="language-ts">export interface HomeModelState {
}

const HomeModel = {
  namespace: &apos;home&apos;,
  state: {
  },
  effects: {
  },
  reducers: {
    save(state, { payload }) {
      return {
        ...state,
        ...payload,
      }
    }
  },
}

export default HomeModel
</code></pre>
<ol start="6">
<li>&#x5728;<code>src</code>&#x76EE;&#x5F55;&#x4E0B;&#x5EFA;&#x7ACB;<code>models</code>&#x76EE;&#x5F55;&#xFF0C;&#x5E76;&#x521B;&#x5EFA;<code>index.ts</code>&#xFF1A;</li>
</ol>
<pre><code class="language-ts">import home from &apos;../pages/index/model&apos;

export default [
  home,
]
</code></pre>
<p>&#x5EFA;&#x8BAE;&#x5728;<code>src/models</code>&#x4E0B;&#x653E;&#x516C;&#x7528;&#x7684;model&#x6587;&#x4EF6;&#xFF0C;&#x5176;&#x4ED6;&#x5206;&#x522B;&#x653E;&#x5728;&#x9875;&#x9762;&#x76EE;&#x5F55;&#xFF0C;&#x5E76;&#x5728;&#x8FD9;&#x4E2A;&#x5165;&#x53E3;&#x6587;&#x4EF6;<code>index.ts</code>&#x91CC;&#x5BFC;&#x5165;&#x8FDB;&#x6765;&#x3002;</p>
<ol start="7">
<li>&#x4FEE;&#x6539;<code>src</code>&#x76EE;&#x5F55;&#x4E0B;&#x7684;<code>app.tsx</code>&#xFF1A;</li>
</ol>
<pre><code class="language-tsx">import { Provider } from &apos;@tarojs/redux&apos;
import dva from &apos;./dva&apos;
import models from &apos;./models/index&apos;


const dvaApp = dva.createApp({
  initialState: {},
  models: models
});
const store = dvaApp.getStore();
</code></pre>
<p>&#x4E0A;&#x9762;&#x662F;&#x8981;&#x589E;&#x52A0;&#x7684;&#x4EE3;&#x7801;&#xFF1B;</p>
<pre><code class="language-tsx">...

  render () {
    return (
      &lt;Provider store={store}&gt;
        &lt;Index /&gt;
      &lt;/Provider&gt;
    )
  }

...

</code></pre>
<p>&#x5982;&#x4E0A;&#xFF0C;&#x5C31;&#x5728;<code>render</code>&#x91CC;&#x7684;<code>&lt;Index /&gt;</code>&#x5916;&#x5305;&#x88F9;<code>Provider</code>&#x5C31;&#x597D;&#x3002;</p>
<p>&#x81EA;&#x6B64;&#xFF0C;Taro 2&#x7684;&#x5DE5;&#x7A0B;&#x5F15;&#x5165;Dva&#x5B8C;&#x6210;&#x3002;<br>
&#x672C;&#x6587;&#x9002;&#x7528;&#x4E8E;Taro 1.x.x &#x548C; 2.x.x&#xFF0C;&#x4EB2;&#x6D4B;&#x6CA1;&#x95EE;&#x9898;&#x3002;</p>
]]></content:encoded></item><item><title><![CDATA[前端编码规范]]></title><description><![CDATA[本文是在项目开发中总结的一些前端编码规范，以及接口规范等。]]></description><link>http://hanhan.pro/frontend-code-guide/</link><guid isPermaLink="false">6596a4b993ef2d0001f41549</guid><category><![CDATA[前端规范]]></category><category><![CDATA[前端]]></category><dc:creator><![CDATA[reno]]></dc:creator><pubDate>Sun, 22 Sep 2019 00:00:00 GMT</pubDate><media:content url="http://hanhan.pro/content/images/2020/02/16-frontend-guide.jpg" medium="image"/><content:encoded><![CDATA[<h2 id="%E5%B7%A5%E7%A8%8B%E8%A7%84%E8%8C%83%EF%BC%9A">&#x5DE5;&#x7A0B;&#x89C4;&#x8303;&#xFF1A;</h2>
<ul>
<li>&#x7B80;&#x5355;&#x6A21;&#x5757;&#x76EE;&#x5F55;&#xFF1A;&#x5728; views &#x76EE;&#x5F55;&#x4E0B;&#x5EFA;&#x7ACB;&#x76EE;&#x5F55;&#xFF0C;&#x5E76;&#x5728;&#x76EE;&#x5F55;&#x4E0B;&#x5EFA;&#x7ACB;&#x9875;&#x9762;&#x6587;&#x4EF6;&#xFF1B;</li>
<li>&#x590D;&#x6742;&#x6A21;&#x5757;&#x76EE;&#x5F55;&#xFF1A;&#x5728; &#x9875;&#x9762;&#x76EE;&#x5F55;&#x4E0B;&#x589E;&#x52A0; components &#x5B50;&#x76EE;&#x5F55;&#xFF1B;<pre><code class="language-bash">&#x251C;&#x2500;&#x2500; src
    &#x251C;&#x2500;&#x2500; views
          &#x251C;&#x2500;&#x2500; moduleA
                  &#x2514;&#x2500;&#x2500; index.vue
          &#x251C;&#x2500;&#x2500; moduleB
                  &#x251C;&#x2500;&#x2500; components
                        &#x251C;&#x2500;&#x2500; a.vue
                        &#x2514;&#x2500;&#x2500; b.vue
                  &#x2514;&#x2500;&#x2500; index.vue
</code></pre>
</li>
</ul>
<!--more-->
<ul>
<li>
<img src="http://hanhan.pro/content/images/2020/02/16-frontend-guide.jpg" alt="&#x524D;&#x7AEF;&#x7F16;&#x7801;&#x89C4;&#x8303;"><p>&#x8DE8;&#x6A21;&#x5757;&#x7684;&#x7EC4;&#x4EF6;&#x76EE;&#x5F55;&#xFF1A;<br>
&#x65E0;&#x9700;&#x4F7F;&#x7528;&#x516C;&#x5171;&#x7EC4;&#x4EF6;&#x7684;&#x9875;&#x9762;&#xFF1A;&#x5728;&#x9875;&#x9762;&#x7684;&#x540C;&#x7EA7;&#x76EE;&#x5F55;&#x589E;&#x52A0; components &#x76EE;&#x5F55;&#xFF1B;</p>
<pre><code class="language-bash">&#x251C;&#x2500;&#x2500; src
    &#x251C;&#x2500;&#x2500; views
          &#x251C;&#x2500;&#x2500; moduleA
          &#x251C;&#x2500;&#x2500; moduleB
                  &#x2514;&#x2500;&#x2500; components
                        &#x251C;&#x2500;&#x2500; a.vue
                        &#x2514;&#x2500;&#x2500; b.vue
</code></pre>
</li>
<li>
<p>&#x9700;&#x4F7F;&#x7528;&#x516C;&#x5171;&#x7EC4;&#x4EF6;&#x7684;&#x9875;&#x9762;&#xFF1A;&#x5728;&#x9875;&#x9762;&#x4E2D;&#x76F4;&#x63A5;&#x5BFC;&#x5165;npm&#x7EC4;&#x4EF6;&#xFF1B;</p>
</li>
</ul>
<h2 id="%E5%91%BD%E5%90%8D%E8%A7%84%E8%8C%83%EF%BC%9A">&#x547D;&#x540D;&#x89C4;&#x8303;&#xFF1A;</h2>
<ul>
<li>
<p>&#x76EE;&#x5F55;&#x547D;&#x540D;&#xFF1A;&#x9875;&#x9762;/&#x666E;&#x901A;&#x76EE;&#x5F55;&#x547D;&#x540D;&#x4F7F;&#x7528;&#x5C0F;&#x9A7C;&#x5CF0;&#xFF0C;&#x516C;&#x5171;&#x7EC4;&#x4EF6;&#x76EE;&#x5F55;&#x540D;&#x4F7F;&#x7528;&#x5927;&#x9A7C;&#x5CF0;&#xFF1B;</p>
</li>
<li>
<p>&#x6587;&#x4EF6;&#x547D;&#x540D;&#xFF1A;&#x4F7F;&#x7528;&#x82F1;&#x6587;&#x5C0F;&#x5199;&#xFF0C;&#x5C0F;&#x9A7C;&#x5CF0;&#x65B9;&#x5F0F;&#xFF0C;&#x4F8B;: dashboard, errorPage&#xFF1B;</p>
</li>
<li>
<p>&#x7279;&#x5B9A;&#x529F;&#x80FD;&#x7684;&#x6587;&#x4EF6;&#x547D;&#x540D;&#xFF1A;&#x5982;&#x4FEE;&#x6539;&#x9875;&#x9762; xxxUpdate&#xFF1B;</p>
</li>
<li>
<p>&#x539F;&#x5219;&#xFF1A;&#x80FD;&#x63CF;&#x8FF0;&#x6E05;&#x695A;&#x76EE;&#x5F55;/&#x6587;&#x4EF6;&#x7684;&#x4F5C;&#x7528;&#xFF0C;&#x82E5;&#x975E;&#x4E13;&#x4E1A;&#x7B80;&#x5199;&#x8BCD;&#x6C47;&#xFF0C;&#x5C3D;&#x91CF;&#x4E0D;&#x4F7F;&#x7528;&#x7B80;&#x5199;&#x3002;<br>
&#x8BE5;&#x539F;&#x5219;&#x540C;&#x6837;&#x9002;&#x7528;&#x4E8E; CSS&#x3001;JS &#x7684;&#x547D;&#x540D;&#x3002;</p>
</li>
</ul>
<h2 id="html%E8%A7%84%E8%8C%83%EF%BC%9A">HTML&#x89C4;&#x8303;&#xFF1A;</h2>
<ul>
<li>&#x5F15;&#x53F7;&#xFF1A;&#x5728;&#x6807;&#x7B7E;&#x5C5E;&#x6027;&#x4E0A;&#x4F7F;&#x7528;&#x53CC;&#x5F15;&#x53F7;&#xFF1B;</li>
<li>&#x7A7A;&#x683C;&#xFF1A;&#x7F29;&#x8FDB;&#x4F7F;&#x7528;2&#x4E2A;&#x7A7A;&#x683C;&#xFF1B;</li>
<li>&#x6362;&#x884C;&#xFF1A;&#x6807;&#x7B7E;&#x5C5E;&#x6027;&#x8D85;&#x8FC7;3&#x4E2A;&#x987B;&#x6362;&#x884C;&#xFF1B;</li>
</ul>
<h2 id="css%E8%A7%84%E8%8C%83%EF%BC%9A">CSS&#x89C4;&#x8303;&#xFF1A;</h2>
<ul>
<li>&#x7F29;&#x8FDB;&#xFF1A;&#x4F7F;&#x7528;2&#x4E2A;&#x7A7A;&#x683C;&#xFF1B;</li>
<li>&#x6362;&#x884C;&#xFF1A;&#x6BCF;&#x4E2A;&#x5C5E;&#x6027;&#x5360;&#x4E00;&#x884C;&#xFF1B;</li>
<li>&#x5206;&#x53F7;&#xFF1A;&#x6BCF;&#x4E2A;&#x5C5E;&#x6027;&#x58F0;&#x660E;&#x7ED3;&#x5C3E;&#x90FD;&#x8981;&#x52A0;&#x5206;&#x53F7;&#xFF1B;</li>
<li>&#x5A92;&#x4F53;&#x67E5;&#x8BE2;&#xFF1A;&#x5C3D;&#x91CF;&#x9760;&#x8FD1;&#x89C4;&#x5219;&#xFF0C;&#x4E0D;&#x8981;&#x653E;&#x5E95;&#x90E8;&#xFF1B;</li>
<li>&#x547D;&#x540D;&#xFF1A;
<ul>
<li>&#x7C7B;&#x540D;&#x4F7F;&#x7528;&#x5C0F;&#x5199;&#x5B57;&#x6BCD;&#x5E76;&#x4EE5; - &#x5206;&#x9694;&#xFF1B;</li>
<li>id&#x91C7;&#x7528;&#x5C0F;&#x9A7C;&#x5CF0;&#x5F0F;&#x547D;&#x540D;&#xFF1B;</li>
<li>less/scss&#x4E2D;&#x7684;&#x53D8;&#x91CF;&#x3001;&#x51FD;&#x6570;&#x3001;&#x6DF7;&#x5408;&#x3001;placeholder&#x91C7;&#x7528;&#x5C0F;&#x9A7C;&#x5CF0;&#x5F0F;&#x547D;&#x540D;&#xFF1B;</li>
</ul>
</li>
<li>&#x9700;&#x8981;&#x7A7A;&#x683C;&#x7684;&#x60C5;&#x51B5;&#xFF1A;
<ul>
<li>&#x591A;&#x4E2A;&#x7C7B;&#x540D;&#x7684; , &#x540E;&#x53CA;&#x5C5E;&#x6027;&#x540D;&#x7684; : &#x540E;&#xFF1B;</li>
<li>&#x9009;&#x62E9;&#x5668; &gt; , + , ~ &#x524D;&#x540E;&#xFF1B;<pre><code class="language-css">.element &gt; .dialog {
  ...
}

.dialog {
  color: #f00 !important;
  background-color: rgba(0, 0, 0, .5);
}
</code></pre>
</li>
</ul>
</li>
<li>&#x9700;&#x8981;&#x7A7A;&#x884C;&#x7684;&#x60C5;&#x51B5;&#xFF1A;&#x4E0D;&#x540C;&#x7684;&#x9009;&#x62E9;&#x5668;&#x4E4B;&#x95F4;&#x9700;&#x8981;&#x7A7A;&#x4E00;&#x884C;&#xFF1B;<pre><code class="language-css">.dialog {
  color: #f00;
  font-size: 16px;

  &amp;:after {
    ...
  }
}
</code></pre>
</li>
<li>&#x9700;&#x8981;&#x6362;&#x884C;&#x7684;&#x60C5;&#x51B5;&#xFF1A;
<ul>
<li>{ &#x540E;&#x548C; } &#x524D;&#x9700;&#x8981;&#x6362;&#x884C;&#xFF1B;</li>
<li>&#x6BCF;&#x4E2A;&#x5C5E;&#x6027;&#x72EC;&#x5360;&#x4E00;&#x884C;&#xFF1B;</li>
<li>&#x591A;&#x4E2A;&#x89C4;&#x5219;&#x7684;&#x5206;&#x9694;&#x7B26; , &#x540E;&#xFF1B;</li>
</ul>
</li>
<li>&#x6742;&#x9879;&#xFF1A;
<ul>
<li>&#x5C5E;&#x6027;&#x503C; 0 &#x540E;&#x9762;&#x4E0D;&#x8981;&#x52A0;&#x5355;&#x4F4D;&#xFF1B;</li>
<li>&#x5C3D;&#x91CF;&#x5C11;&#x7528;&#x6216;&#x4E0D;&#x4F7F;&#x7528; !important&#xFF1B;</li>
</ul>
</li>
</ul>
<h2 id="js%E8%A7%84%E8%8C%83%EF%BC%9A">JS&#x89C4;&#x8303;&#xFF1A;</h2>
<ul>
<li>&#x5F15;&#x53F7;&#xFF1A;&#x5B57;&#x7B26;&#x4F7F;&#x7528;&#x5355;&#x5F15;&#x53F7;&#xFF1B;</li>
<li>&#x7F29;&#x8FDB;&#xFF1A;&#x4F7F;&#x7528;2&#x4E2A;&#x7A7A;&#x683C;&#xFF1B;</li>
<li>&#x53D8;&#x91CF;&#x547D;&#x540D;&#xFF1A;
<ul>
<li>&#x6807;&#x51C6;&#x53D8;&#x91CF;&#x547D;&#x540D;&#x4F7F;&#x7528;&#x9A7C;&#x5CF0;&#x7ED3;&#x6784;&#xFF1B;</li>
<li>&#x5E38;&#x91CF;&#x5168;&#x5927;&#x5199;&#xFF0C;&#x7528;&#x4E0B;&#x5212;&#x7EBF;&#x8FDE;&#x63A5;&#xFF1B;</li>
<li>&#x6784;&#x9020;&#x51FD;&#x6570;&#xFF0C;&#x5927;&#x5199;&#x7B2C;&#x4E00;&#x4E2A;&#x5B57;&#x6BCD;&#xFF1B;</li>
<li>&#x5C5E;&#x6027;&#x884C;&#x3001;&#x6570;&#x7EC4;&#x7ED3;&#x5C3E;&#x52A0;&#x9017;&#x53F7;&#xFF1B;</li>
</ul>
</li>
<li>&#x51FD;&#x6570;&#xFF1A;
<ul>
<li>&#x65E0;&#x8BBA;&#x662F;&#x51FD;&#x6570;&#x58F0;&#x660E;&#x8FD8;&#x662F;&#x51FD;&#x6570;&#x8868;&#x8FBE;&#x5F0F;&#xFF0C;( &#x524D;&#x4E0D;&#x8981;&#x7A7A;&#x683C;&#xFF0C;&#x4F46; { &#x524D;&#x8981;&#x6709;&#x7A7A;&#x683C;&#xFF1B;</li>
<li>&#x53C2;&#x6570;&#x4E4B;&#x95F4;&#x7528; , &#x5206;&#x9694;&#xFF0C;&#x6CE8;&#x610F;&#x9017;&#x53F7;&#x540E;&#x6709;&#x4E00;&#x4E2A;&#x7A7A;&#x683C;&#xFF1B;</li>
<li>&#x533F;&#x540D;&#x51FD;&#x6570;&#x4E0D;&#x8981;&#x7A7A;&#x683C;&#xFF1B;</li>
</ul>
<pre><code class="language-js">doSomething(item);

const doSomething = (a, b, c) =&gt; {
  // ...
};
</code></pre>
</li>
<li>&#x5BF9;&#x8C61;&#xFF1A;&#x5C5E;&#x6027;&#x540D;&#x4E0D;&#x8981;&#x52A0;&#x5F15;&#x53F7;&#xFF1B;</li>
<li>undefined&#xFF1A;&#x4F7F;&#x7528;typeof&#x548C;&#x5B57;&#x7B26;&#x4E32; <code>undefined</code> &#x5BF9;&#x53D8;&#x91CF;&#x8FDB;&#x884C;&#x5224;&#x65AD;&#xFF1B;</li>
<li>&#x6742;&#x9879;&#xFF1A;
<ul>
<li>&#x5BF9;&#x4E0A;&#x4E0B;&#x6587;this&#x7684;&#x5F15;&#x7528;&#x4F7F;&#x7528; <code>_this</code>, <code>_self</code>, <code>that</code>&#x5176;&#x4E2D;&#x4E00;&#x4E2A;&#x6765;&#x547D;&#x540D;&#xFF1B;</li>
<li>&#x62EC;&#x53F7;&#xFF1A;<code>if</code>, <code>else</code>, <code>for</code>, <code>while</code>, <code>do</code>, <code>switch</code>, <code>try</code>, <code>catch</code>, <code>finally</code>, <code>with</code> &#x8FD9;&#x4E9B;&#x5173;&#x952E;&#x5B57;&#x540E;&#x7684;&#x5C0F;&#x62EC;&#x53F7;&#x524D;&#x540E;&#x90FD;&#x6709;1&#x4E2A;&#x7A7A;&#x683C;&#xFF0C;&#x4E14;&#x5FC5;&#x987B;&#x6709;&#x5927;&#x62EC;&#x53F7;&#xFF08;&#x5373;&#x4F7F;&#x4EE3;&#x7801;&#x5757;&#x7684;&#x5185;&#x5BB9;&#x53EA;&#x6709;&#x4E00;&#x884C;&#xFF09;</li>
<li>&#x8DEF;&#x5F84;&#xFF1A;&#x8D85;&#x8FC7;2&#x5C42;&#x4F7F;&#x7528;&#x522B;&#x540D; <code>@/</code> &#xFF0C;&#x4E0D;&#x8981;&#x4F7F;&#x7528;&#x591A;&#x4E2A; <code>../</code></li>
</ul>
</li>
<li>JSLint:
<ul>
<li>debugger&#x4E0D;&#x8981;&#x51FA;&#x73B0;&#x5728;&#x63D0;&#x4EA4;&#x7684;&#x4EE3;&#x7801;&#x91CC;&#xFF1B;</li>
<li>&#x6A21;&#x677F;&#x5B57;&#x7B26;&#x4E32;&#x4F7F;&#x7528; <code> </code>&#xFF0C;&#x800C;&#x4E0D;&#x662F; &#x2018;&#x2019; &#x548C; + &#x62FC;&#x63A5;&#xFF1B;</li>
<li>&#x4E09;&#x5143;&#x8FD0;&#x7B97;&#x7B26;&#x6709;&#x7A7A;&#x683C;&#xFF0C;&#x4E14;&#x6700;&#x591A;&#x4E24;&#x5C42;&#x7ED3;&#x6784;&#xFF1B;</li>
<li>&#x5355;&#x884C;&#x6CE8;&#x91CA;&#x8BED;&#x53E5;&#x540E;&#x6709;&#x4E14;&#x53EA;&#x6709;&#x4E00;&#x4E2A;&#x7A7A;&#x683C;&#xFF0C;&#x4F8B;&#xFF1A; // something</li>
<li>&#x591A;&#x884C;&#x6CE8;&#x91CA;&#x4F7F;&#x7528; /** */ &#xFF0C;&#x4E14;&#x52A0;&#x4E0A; @description @params @return &#x4FE1;&#x606F;&#xFF1B;<pre><code class="language-js">/**
  * @description &#x63CF;&#x8FF0;&#x4FE1;&#x606F;
  * @params Object item
  * @return Array data
  */
</code></pre>
</li>
</ul>
</li>
<li>IDE&#x76F8;&#x5173;:
<ul>
<li>&#x4F7F;&#x7528;VS Code&#xFF1B;</li>
<li>VS Code &#x987B;&#x5B89;&#x88C5;&#x7684;&#x57FA;&#x7840;&#x63D2;&#x4EF6;&#xFF1A;ESLint&#x3001;Vetur&#x3001;Prettier Code formatter&#x3001;Vue Peek&#xFF1B;</li>
</ul>
</li>
</ul>
<h2 id="%E6%8E%A5%E5%8F%A3%E8%A7%84%E8%8C%83%EF%BC%9A">&#x63A5;&#x53E3;&#x89C4;&#x8303;&#xFF1A;</h2>
<ul>
<li>
<p>&#x4E1A;&#x52A1;&#x63A5;&#x53E3;&#x89C4;&#x8303;&#xFF1A;</p>
<pre><code class="language-json">{
  &quot;code&quot;: 1, //&#x63A5;&#x53E3;&#x72B6;&#x6001; 1:&#x6210;&#x529F; 2:&#x53C2;&#x6570;&#x9519;&#x8BEF;&#x3001;&#x7CFB;&#x7EDF;&#x95EE;&#x9898; -1:&#x672A;&#x767B;&#x5F55;
  &quot;bizCode&quot;: 20001, //&#x4E1A;&#x52A1;&#x72B6;&#x6001; &#x5F53;code&#x4E3A;1&#x65F6;&#xFF0C;&#x987B;&#x6709; bizCode&#x3001;bizMsg
  &quot;bizMsg&quot;: &quot;&#x6210;&#x529F;&quot;,
  &quot;errorCode&quot;: 50001, // &#x9519;&#x8BEF;&#x7F16;&#x7801; &#x5F53;code&#x4E3A;2&#x65F6;&#xFF0C;&#x987B;&#x6709; errorCode&#x3001;errorMsg
  &quot;errorMsg&quot;: &quot;&#x670D;&#x52A1;&#x7AEF;&#x5F02;&#x5E38;, &#x8BF7;&#x7A0D;&#x540E;&#x518D;&#x8BD5;&quot;,
  &quot;data&quot;: {
    &quot;integralAmount&quot;: &quot;11&quot;, 
    &quot;shopCode&quot;: &quot;DDDDD&quot;,
    &quot;wxShopStatus&quot;: 1, 
    &quot;surveyStatus&quot;: 1   
  }
}
</code></pre>
</li>
<li>
<p>code:&#x63A5;&#x53E3;&#x72B6;&#x6001; [Int]</p>
</li>
<li>
<p>&#x72B6;&#x6001;1&#x65F6;&#xFF0C;bizCode: 20000, bizMsg: &apos;&#x6210;&#x529F;&apos; &#x53F7;&#x6BB5;&#x89C4;&#x5219;&#xFF1A;2&#x53F7;&#x6BB5; eg: 20001</p>
</li>
<li>
<p>&#x72B6;&#x6001;2&#x65F6;&#xFF0C;errorCode: 50001, errorMsg: &apos;xxxx&#x9519;&#x8BEF;&apos;    &#x53F7;&#x6BB5;&#x89C4;&#x5219;&#xFF1A;5&#x53F7;&#x6BB5; &#x670D;&#x52A1;&#x7AEF;&#x9519;&#x8BEF; eg:50001&#x3001; 6&#x53F7;&#x6BB5; &#x53C2;&#x6570;&#x9519;&#x8BEF; eg:60001</p>
</li>
<li>
<p>&#x72B6;&#x6001;-1&#x65F6;&#xFF0C;&#x9664;&#x5B57;&#x6BB5;code&#x5916;&#x7686;&#x4E0D;&#x8FD4;&#x56DE;</p>
</li>
<li>
<p>bizCode,bizMsg &#x4E0E; errorCode&#x3001;errorMsg &#x662F;&#x4E92;&#x65A5;&#x7684;</p>
</li>
<li>
<p>code&#x3001;bizCode&#x3001;errorCode &#x5FC5;&#x987B;&#x4E3A;Int&#x578B;</p>
</li>
<li>
<p>&#x3010;&#x7F16;&#x53F7;&#x5168;&#x5C40;&#x7EDF;&#x4E00;&#x3011;</p>
</li>
<li>
<p>&#x4E3E;&#x4F8B;&#xFF1A;</p>
</li>
<li>
<p>20000 &#x6210;&#x529F;</p>
</li>
<li>
<p>20001 &#x4F18;&#x60E0;&#x5238;&#x5DF2;&#x9886;&#x5B8C;</p>
</li>
<li>
<p>20002 &#x79EF;&#x5206;&#x4E0D;&#x8DB3;</p>
</li>
<li>
<p>20003 &#x5DF2;&#x7ECF;&#x9886;&#x53D6;&#x8FC7;&#x4E86;</p>
</li>
<li>
<p>50001 &#x670D;&#x52A1;&#x7AEF;&#x5F02;&#x5E38;, &#x8BF7;&#x7A0D;&#x540E;&#x518D;&#x8BD5;</p>
</li>
<li>
<p>50002 &#x670D;&#x52A1;&#x7AEF;&#x5F02;&#x5E38;&#xFF0C;&#x95EE;&#x9898;xxx</p>
</li>
<li>
<p>60001 &#x53C2;&#x6570;&#x9519;&#x8BEF;</p>
</li>
<li>
<p>&#x65E0;&#x5206;&#x9875;&#x7684;&#x6570;&#x636E;&#x7ED3;&#x6784;&#xFF0C;&#x76F4;&#x63A5;&#x5217;&#x51FA;&#x5C5E;&#x6027;&#x548C;&#x503C;&#xFF1A;</p>
<pre><code class="language-json">&quot;data&quot;: {
  &quot;title&quot;: &quot;&#x6807;&#x9898;&quot;,
  &quot;content&quot;: &quot;&#x5185;&#x5BB9;&quot;,
}
</code></pre>
</li>
<li>
<p>&#x6709;&#x5206;&#x9875;&#x7684;&#x6570;&#x636E;&#x7ED3;&#x6784;&#xFF0C;data&#x91CC;&#x6709;list&#x548C;pagination&#x5C5E;&#x6027;&#xFF0C;&#x5206;&#x522B;&#x662F;&#x5217;&#x8868;&#x548C;&#x5206;&#x9875;&#x6570;&#x636E;&#xFF1A;</p>
<pre><code class="language-json">&quot;data&quot;: {
  &quot;list&quot;: [
      {&quot;id&quot;: 1, &quot;title&quot;: &quot;1&quot;},
      {&quot;id&quot;: 2, &quot;title&quot;: &quot;2&quot;}
 ],
  &quot;pagination&quot;: {
      &quot;total&quot;: 300,
      &quot;current&quot;: 1,
      &quot;pageSize&quot;: 20,
  }
}
</code></pre>
</li>
<li>
<p>YApi&#x76F8;&#x5173;&#xFF1A;</p>
<ul>
<li>&#x6DFB;&#x52A0;&#x7684;&#x5B57;&#x6BB5;&#x8981;&#x6709;&#x5907;&#x6CE8;&#xFF1B;</li>
<li>&#x540E;&#x7AEF;&#x5F00;&#x53D1;&#x5B8C;&#x63A5;&#x53E3;&#x540E;&#xFF0C;&#x9700;&#x5C06;&#x63A5;&#x53E3;&#x72B6;&#x6001;&#x66F4;&#x65B0;&#x4E3A;&#x201C;&#x5DF2;&#x5B8C;&#x6210;&#x201D;&#xFF0C;&#x524D;&#x7AEF;&#x5207;&#x6362;&#x5230;&#x5B8C;&#x6210;&#x7684;&#x63A5;&#x53E3;&#xFF1B;</li>
</ul>
</li>
<li>
<p>&#x63A5;&#x53E3;&#x4E2D;&#x7684;&#x6570;&#x636E;&#x5B57;&#x6BB5;&#xFF1A;</p>
</li>
<li>
<p>&#x540E;&#x7AEF;&#x987B;&#x6309;&#x524D;&#x7AEF;&#x5B9E;&#x9645;&#x9700;&#x8981;&#x7684;&#x5B57;&#x6BB5;&#x7ED9;&#xFF0C;&#x4E0D;&#x8981;&#x7ED9;&#x4E00;&#x4E9B;&#x591A;&#x4F59;&#x7684;&#x5B57;&#x6BB5;&#xFF1B;</p>
</li>
<li>
<p>&#x524D;&#x7AEF;&#x5148;&#x884C;&#x7684;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x524D;&#x7AEF;&#x63D0;&#x4F9B;&#x6C49;&#x5B57;&#x7248;&#x6570;&#x636E;&#x7ED3;&#x6784;&#x5B9A;&#x4E49;&#xFF1B;</p>
</li>
<li>
<p>&#x63A5;&#x53E3;&#x4E2D;&#x7684;&#x6570;&#x636E;&#x683C;&#x5F0F;&#x5316;&#x3001;&#x8BA1;&#x7B97;&#x7B49;&#x64CD;&#x4F5C;&#x9700;&#x540E;&#x7AEF;&#x5904;&#x7406;&#x597D;&#xFF0C;&#x524D;&#x7AEF;&#x4E0D;&#x5904;&#xFF1B;&#x8003;&#x8651;&#x5230;&#x591A;&#x7AEF;&#x7684;&#x60C5;&#x51B5;&#xFF1B;<br>
&#x539F;&#x5219;&#xFF1A;&#x524D;&#x7AEF;&#x53EA;&#x505A;&#x6570;&#x636E;&#x6E32;&#x67D3;&#xFF0C;&#x4E0D;&#x5904;&#x7406;&#x6570;&#x636E;&#xFF1B;</p>
</li>
<li>
<p>&#x6743;&#x9650;&#x548C;&#x4F1A;&#x8BDD;&#x8D85;&#x65F6;&#xFF08;&#x5931;&#x6548;&#xFF09;&#xFF1A;</p>
<ul>
<li>&#x9ED8;&#x8BA4;&#x8D85;&#x65F6;&#x65F6;&#x95F4;30&#x5206;&#x949F;&#xFF1B;</li>
<li>&#x540E;&#x7AEF;&#x8FD4;&#x56DE;&#x7684;&#x63A5;&#x53E3;&#x5E26;&#x6709;&#x8D85;&#x65F6;&#x7684;&#x7F16;&#x7801;&#x548C;&#x4FE1;&#x606F;&#xFF1B;</li>
<li>&#x524D;&#x7AEF;&#x5F39;&#x51FA;&#x8D85;&#x65F6;&#x7684;&#x63D0;&#x793A;&#xFF0C;&#x70B9;&#x51FB;&#x540E;&#x8DF3;&#x8F6C;&#x5230;&#x767B;&#x5F55;&#x9875;&#xFF1B;</li>
</ul>
</li>
<li>
<p>&#x767B;&#x5F55;&#xFF1A;</p>
<ul>
<li>&#x524D;&#x7AEF;&#x5411;&#x540E;&#x7AEF;&#x63D0;&#x4EA4;&#x767B;&#x5F55;&#x9700;&#x8981;&#x7684;&#x6570;&#x636E;&#x5B57;&#x6BB5;&#xFF1B;</li>
<li>&#x540E;&#x7AEF;&#x5C06;&#x7528;&#x6237;&#x540D;&#x7B49;&#x4FE1;&#x606F;&#x5199;&#x5165;&#x5230;session&#x91CC;&#xFF1B;</li>
<li>&#x524D;&#x7AEF;&#x901A;&#x8FC7;cookie&#x83B7;&#x53D6;&#x5230;&#x7528;&#x6237;&#x540D;&#x4FE1;&#x606F;&#xFF1B;</li>
</ul>
</li>
<li>
<p>&#x8DE8;&#x57DF;&#x5904;&#x7406;&#xFF1A;</p>
<ul>
<li>
<p>&#x540E;&#x7AEF;&#x9700;&#x8981;&#x5728;Nginx&#x670D;&#x52A1;&#x5668;&#x914D;&#x7F6E;&#x8DE8;&#x57DF;&#xFF0C;&#x9700;&#x8981;&#x6309;&#x57DF;&#x540D;&#x8BBE;&#x7F6E;&#xFF0C;&#x4E0D;&#x8981;&#x8BBE;&#x7F6E;&#x4E3A;*&#xFF1B;</p>
<pre><code class="language-bash">Access-Control-Allow-Origin: http://dev.yougou.com
Access-Control-Allow-Methods: GET,PUT,POST,DELETE,OPTIONS
</code></pre>
</li>
<li>
<p>&#x5141;&#x8BB8;&#x524D;&#x7AEF;&#x643A;&#x5E26;Cookie&#x8BF7;&#x6C42;&#xFF1A;</p>
<pre><code class="language-bash">Access-Control-Allow-Credentials: true
</code></pre>
</li>
</ul>
</li>
</ul>
<h2 id="%E5%9B%BD%E9%99%85%E5%8C%96%EF%BC%9A">&#x56FD;&#x9645;&#x5316;&#xFF1A;</h2>
<ul>
<li>&#x9879;&#x76EE;&#x5DE5;&#x7A0B;&#x4E2D;&#x7684;&#x591A;&#x8BED;&#x8A00;&#xFF1A;
<ul>
<li>&#x4F7F;&#x7528;i18N&#x7EC4;&#x4EF6;&#xFF1B;</li>
<li>&#x4E0D;&#x540C;&#x7684;&#x8BED;&#x8A00;&#x4F7F;&#x7528;&#x5BF9;&#x5E94;&#x7684;&#x8BED;&#x8A00;&#x6587;&#x4EF6;&#xFF1B;</li>
</ul>
</li>
<li>&#x7EC4;&#x4EF6;&#x4E2D;&#x7684;&#x591A;&#x8BED;&#x8A00;&#xFF1A;
<ul>
<li>&#x8BED;&#x8A00;&#x6807;&#x8BC6;&#x4F7F;&#x7528;&#x7CFB;&#x7EDF;&#x91CC;&#x4F20;&#x8FC7;&#x6765;&#x7684;&#x8BED;&#x8A00;&#xFF1B;</li>
<li>&#x6BCF;&#x4E2A;&#x7EC4;&#x4EF6;&#x4F7F;&#x7528;&#x5230;&#x7684;&#x8BED;&#x8A00;&#xFF0C;&#x6309;&#x8BED;&#x8A00;&#x5EFA;&#x7ACB;&#x6587;&#x4EF6;&#x653E;&#x5728;&#x6BCF;&#x4E2A;&#x7EC4;&#x4EF6;&#x91CC;&#xFF1B;</li>
</ul>
</li>
<li>&#x8BED;&#x8A00;&#x5305;&#x4E2D;&#x7684;&#x6570;&#x636E;&#x7ED3;&#x6784;&#x6309;&#x7167;&#x529F;&#x80FD;&#x6216;&#x9875;&#x9762;&#x540D;&#x79F0;&#x6765;&#x5B9A;&#x4E49;&#xFF1B;</li>
</ul>
<h2 id="%E4%B8%8A%E4%B8%8B%E6%B8%B8%E5%8D%8F%E4%BD%9C%E8%A7%84%E8%8C%83%EF%BC%9A">&#x4E0A;&#x4E0B;&#x6E38;&#x534F;&#x4F5C;&#x89C4;&#x8303;&#xFF1A;</h2>
<ul>
<li>&#x524D;&#x7AEF;&#x4E0E;&#x4EA7;&#x54C1;&#x53CA;UI&#x8BBE;&#x8BA1;&#x5E08;&#x7684;&#x4EA4;&#x4E92;&#xFF1A;
<ul>
<li>&#x524D;&#x7AEF;&#x6309;&#x7167;UI&#x8BBE;&#x8BA1;&#x5E08;&#x63D0;&#x4F9B;&#x7684; sketch &#x6216; ps &#x6587;&#x4EF6;&#x8FDB;&#x884C;&#x5F00;&#x53D1;&#xFF1B;</li>
</ul>
</li>
<li>&#x524D;&#x7AEF;&#x4E0E;&#x540E;&#x7AEF;&#x5F00;&#x53D1;&#x534F;&#x4F5C;&#xFF1A;
<ul>
<li>&#x524D;&#x7AEF;&#x5728;&#x5B8C;&#x6210;&#x754C;&#x9762;&#x5E03;&#x5C40;&#x4EA4;&#x4E92;&#x5F00;&#x53D1;&#x540E;&#xFF0C;&#x518D;&#x7ED9;&#x5230;&#x540E;&#x7AEF;&#x8FDB;&#x884C;&#x5F00;&#x53D1;&#xFF1B;</li>
</ul>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[MacOS下安装Yii2]]></title><description><![CDATA[本文主要是关于在MacOS下Composer和Yii2的安装，以及Yii2的运行。]]></description><link>http://hanhan.pro/install-yii2-in-macos/</link><guid isPermaLink="false">6596a4b993ef2d0001f41548</guid><category><![CDATA[yii2]]></category><category><![CDATA[php]]></category><category><![CDATA[macos]]></category><dc:creator><![CDATA[reno]]></dc:creator><pubDate>Wed, 19 Jun 2019 00:00:00 GMT</pubDate><media:content url="http://hanhan.pro/content/images/2020/02/15-install-yii2.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://hanhan.pro/content/images/2020/02/15-install-yii2.jpg" alt="MacOS&#x4E0B;&#x5B89;&#x88C5;Yii2"><p>&#x5B89;&#x88C5;php&#x73AF;&#x5883;&#x7684;&#x6559;&#x7A0B;&#x7F51;&#x4E0A;&#x6BD4;&#x8F83;&#x591A;&#x5C31;&#x7565;&#x8FC7;&#x4E86;&#xFF0C;&#x4E5F;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;mamp&#x4E4B;&#x7C7B;&#x7684;&#x5957;&#x4EF6;&#x3002;</p>
<h4 id="%E5%AE%89%E8%A3%85composer%EF%BC%9A">&#x5B89;&#x88C5;Composer&#xFF1A;</h4>
<ol>
<li>&#x6309;&#x987A;&#x5E8F;&#x4F9D;&#x6B21;&#x6267;&#x884C;&#x4EE5;&#x4E0B;&#x56DB;&#x4E2A;&#x547D;&#x4EE4;&#xFF1A;</li>
</ol>
<pre><code class="language-bash">php -r &quot;copy(&apos;https://getcomposer.org/installer&apos;, &apos;composer-setup.php&apos;);&quot;
php -r &quot;if (hash_file(&apos;sha384&apos;, &apos;composer-setup.php&apos;) === &apos;48e3236262b34d30969dca3c37281b3b4bbe3221bda826ac6a9a62d6444cdb0dcd0615698a5cbe587c3f0fe57a54d8f5&apos;) { echo &apos;Installer verified&apos;; } else { echo &apos;Installer corrupt&apos;; unlink(&apos;composer-setup.php&apos;); } echo PHP_EOL;&quot;
php composer-setup.php
php -r &quot;unlink(&apos;composer-setup.php&apos;);&quot;
</code></pre>
<ol start="2">
<li>&#x5C06;Composer&#x8BBE;&#x4E3A;&#x5168;&#x5C40;&#xFF1A;</li>
</ol>
<pre><code class="language-bash">mv composer.phar /usr/local/bin/composer
</code></pre>
<h4 id="yii2%E9%AB%98%E7%BA%A7%E7%89%88%E5%AE%89%E8%A3%85%EF%BC%9A">Yii2&#x9AD8;&#x7EA7;&#x7248;&#x5B89;&#x88C5;&#xFF1A;</h4>
<ol>
<li>&#x6267;&#x884C;&#xFF1A;</li>
</ol>
<pre><code class="language-bash">composer create-project --prefer-dist yiisoft/yii2-app-advanced yii2-advanced
</code></pre>
<ol start="2">
<li>&#x521D;&#x59CB;&#x5316;&#xFF1A;</li>
</ol>
<pre><code class="language-bash">php init
</code></pre>
<ol start="3">
<li>&#x5206;&#x522B;&#x6253;&#x5F00;&#x524D;&#x540E;&#x53F0;&#x7F51;&#x5740;&#x8FD0;&#x884C;&#xFF1A;</li>
</ol>
<pre><code class="language-bash">http://localhost:8888/yii2-advanced/frontend/web/
http://localhost:8888/yii2-advanced/backend/web/
</code></pre>
<h4 id="%E6%95%B0%E6%8D%AE%E5%BA%93%E9%85%8D%E7%BD%AE%EF%BC%9A">&#x6570;&#x636E;&#x5E93;&#x914D;&#x7F6E;&#xFF1A;</h4>
<ol>
<li>&#x8FDB;&#x5165;<code>phpmyadmin</code>&#xFF0C;&#x521B;&#x5EFA;&#x6570;&#x636E;&#x8868;<code>yii2advanced</code>&#x3002;</li>
<li>&#x6253;&#x5F00;<code>common/config/main-local.php</code>&#xFF0C;&#x6DFB;&#x52A0;&#x6570;&#x636E;&#x5E93;&#x7AEF;&#x53E3;&#x53CA;&#x4FEE;&#x6539;&#x8D26;&#x53F7;&#x5BC6;&#x7801;&#x3002;</li>
<li>&#x6267;&#x884C;&#x6570;&#x636E;&#x8FC1;&#x79FB;&#x547D;&#x4EE4;&#xFF1A;</li>
</ol>
<pre><code class="language-bash">php yii migrate
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Electron之在Windows下安装grpc]]></title><description><![CDATA[grpc有一些版本是不兼容electron的，本文介绍在Windows系统下安装electron和grpc。]]></description><link>http://hanhan.pro/install-grpc-for-electron-in-windows/</link><guid isPermaLink="false">6596a4b993ef2d0001f41547</guid><category><![CDATA[electron]]></category><category><![CDATA[grpc]]></category><category><![CDATA[windows]]></category><category><![CDATA[前端]]></category><dc:creator><![CDATA[reno]]></dc:creator><pubDate>Fri, 03 May 2019 00:00:00 GMT</pubDate><media:content url="http://hanhan.pro/content/images/2020/02/14-electron-grpc-win-1.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://hanhan.pro/content/images/2020/02/14-electron-grpc-win-1.jpg" alt="Electron&#x4E4B;&#x5728;Windows&#x4E0B;&#x5B89;&#x88C5;grpc"><p>&#x4EE5;&#x4E0B;&#x662F;&#x57FA;&#x4E8E;grpc 1.19.0&#x7248;&#x672C;&#x548C;electron 4.0.3&#x7248;&#x672C;&#xFF0C;&#x4EB2;&#x6D4B;&#x662F;&#x786E;&#x5B9A;&#x597D;&#x7528;&#x7684;&#x3002;</p>
<h3 id="%E5%AE%89%E8%A3%85electron%E7%89%B9%E5%AE%9A%E7%89%88%E6%9C%AC%E5%92%8Cgrpc%E7%9A%84%E6%AD%A5%E9%AA%A4%EF%BC%9A">&#x5B89;&#x88C5;electron&#x7279;&#x5B9A;&#x7248;&#x672C;&#x548C;grpc&#x7684;&#x6B65;&#x9AA4;&#xFF1A;</h3>
<h4 id="1-windows%E4%B8%8B%E7%9A%84nrmpc%E6%96%87%E4%BB%B6%E5%8F%82%E8%80%83%EF%BC%9A">1. windows&#x4E0B;&#x7684;nrmpc&#x6587;&#x4EF6;&#x53C2;&#x8003;&#xFF1A;</h4>
<pre><code class="language-bash">prefix=D:\nodejs\node_modules\npm
sass_binary_site=https://npm.taobao.org/mirrors/node-sass/
phantomjs_cdnurl=http://npm.taobao.org/mirrors/phantomjs
ELECTRON_MIRROR=http://npm.taobao.org/mirrors/electron/
</code></pre>
<p>&#x7B2C;&#x4E00;&#x884C;&#x662F;&#x5C06;&#x76EE;&#x5F55;&#x6307;&#x5411;&#x81EA;&#x5B9A;&#x4E49;&#x7684;nodejs&#x5B89;&#x88C5;&#x76EE;&#x5F55;&#xFF0C;&#x5982;&#x679C;&#x4E0D;&#x662F;&#x5B89;&#x88C5;&#x5728;&#x9ED8;&#x8BA4;&#x7684;C&#x76D8;&#x76EE;&#x5F55;&#x4E0B;&#x3002;</p>
<h4 id="2-%E5%9C%A8electron%E9%A1%B9%E7%9B%AE%E7%9B%AE%E5%BD%95%E4%B8%8B%EF%BC%8C%E5%AE%89%E8%A3%85electron%E7%9A%84403%E7%89%88%E6%9C%AC%E3%80%82">2. &#x5728;electron&#x9879;&#x76EE;&#x76EE;&#x5F55;&#x4E0B;&#xFF0C;&#x5B89;&#x88C5;<code>Electron</code>&#x7684;<code>4.0.3</code>&#x7248;&#x672C;&#x3002;</h4>
<pre><code class="language-bash">npm i electron@4.0.3 -g
</code></pre>
<h4 id="3-%E5%9C%A8electron%E9%A1%B9%E7%9B%AE%E7%9B%AE%E5%BD%95%E4%B8%8B%EF%BC%8C%E5%AE%89%E8%A3%85grpc%E7%9A%841190%E7%89%88%E6%9C%AC%E3%80%82">3. &#x5728;electron&#x9879;&#x76EE;&#x76EE;&#x5F55;&#x4E0B;&#xFF0C;&#x5B89;&#x88C5;<code>grpc</code>&#x7684;<code>1.19.0</code>&#x7248;&#x672C;&#x3002;</h4>
<pre><code class="language-bash">npm install grpc@1.19.0 --runtime=electron --target=4.0.3
</code></pre>
<p>&#x7ECF;&#x8FC7;&#x4EE5;&#x4E0A;&#x51E0;&#x4E2A;&#x6B65;&#x9AA4;&#xFF0C;&#x7136;&#x540E;&#x5728;electron&#x9879;&#x76EE;&#x6267;&#x884C;<code>npm i</code>&#x5B89;&#x88C5;&#x5176;&#x4ED6;&#x4F9D;&#x8D56;&#x540E;&#xFF0C;&#x9879;&#x76EE;&#x5E94;&#x8BE5;&#x5C31;&#x53EF;&#x4EE5;&#x8FD0;&#x884C;&#x3002;</p>
<h3 id="%E5%A6%82%E6%9E%9C%E8%BF%98%E8%BF%90%E8%A1%8C%E4%B8%8D%E8%B5%B7%E6%9D%A5%EF%BC%8C%E5%8F%AF%E4%BB%A5%E5%B0%9D%E8%AF%95%E4%BB%A5%E4%B8%8B2%E4%B8%AA%E6%96%B9%E6%B3%95%EF%BC%9A">&#x5982;&#x679C;&#x8FD8;&#x8FD0;&#x884C;&#x4E0D;&#x8D77;&#x6765;&#xFF0C;&#x53EF;&#x4EE5;&#x5C1D;&#x8BD5;&#x4EE5;&#x4E0B;2&#x4E2A;&#x65B9;&#x6CD5;&#xFF1A;</h3>
<h4 id="1-%E5%A6%82%E6%9E%9C%E7%BC%96%E8%AF%91%E5%A4%B1%E8%B4%A5%E5%8F%AF%E5%B0%9D%E8%AF%95%EF%BC%9A">1. &#x5982;&#x679C;&#x7F16;&#x8BD1;&#x5931;&#x8D25;&#x53EF;&#x5C1D;&#x8BD5;&#xFF1A;</h4>
<pre><code class="language-bash">.\node_modules\.bin\electron-rebuild
</code></pre>
<p>&#x4F7F;&#x7528;electron-rebuild&#x91CD;&#x65B0;&#x7F16;&#x8BD1;&#x3002;</p>
<h4 id="2-windwos%E9%85%8D%E7%BD%AE%EF%BC%9A">2. windwos&#x914D;&#x7F6E;&#xFF1A;</h4>
<pre><code class="language-bash">npm config set prefix &quot;D:\nodejs\node_global&quot;
npm config set cache &quot;D:\nodejs\node_cache&quot;
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Electron之在MacOS下安装grpc]]></title><description><![CDATA[grpc有一些版本是不兼容electron的，本文介绍在MacOS系统下安装electron和grpc。]]></description><link>http://hanhan.pro/install-grpc-for-electron-in-macos/</link><guid isPermaLink="false">6596a4b993ef2d0001f41546</guid><category><![CDATA[electron]]></category><category><![CDATA[grpc]]></category><category><![CDATA[macos]]></category><category><![CDATA[前端]]></category><dc:creator><![CDATA[reno]]></dc:creator><pubDate>Sun, 28 Apr 2019 00:00:00 GMT</pubDate><media:content url="http://hanhan.pro/content/images/2020/02/13-electron-grpc-mac-3.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://hanhan.pro/content/images/2020/02/13-electron-grpc-mac-3.jpg" alt="Electron&#x4E4B;&#x5728;MacOS&#x4E0B;&#x5B89;&#x88C5;grpc"><p>grpc&#x7684;1.19.0&#x7248;&#x672C;&#x5728;electron&#x7684;4.0.3&#x7248;&#x672C;&#x4E0B;&#x662F;&#x786E;&#x5B9A;&#x597D;&#x7528;&#x7684;&#x3002;</p>
<p>&#x65B0;&#x7248;&#x672C;&#x7684;grpc&#x548C;electron&#x7248;&#x672C;&#x8FD8;&#x6CA1;&#x8BD5;&#x8FC7;&#xFF0C;&#x4E0D;&#x8FC7;&#x5927;&#x5BB6;&#x53EF;&#x4EE5;&#x53C2;&#x8003;&#x8FD9;2&#x4E2A;&#x3002;</p>
<pre><code class="language-bash">&gt; Version 1.23.0 is now out with Electron 6 support. Please try that version.
&gt;&gt;I&apos;m sorry, Electron 6 support got broken in grpc 1.24.0. But it is fixed in grpc 1.24.1
</code></pre>
<p>&#x51FA;&#x81EA;<a href="https://github.com/grpc/grpc-node/issues/989?ref=hanhan.pro">Electron v6 and gRPC error #989</a></p>
<h3 id="%E5%AE%89%E8%A3%85electron%E7%89%B9%E5%AE%9A%E7%89%88%E6%9C%AC%E5%92%8Cgrpc%E7%9A%84%E6%AD%A5%E9%AA%A4%EF%BC%9A">&#x5B89;&#x88C5;electron&#x7279;&#x5B9A;&#x7248;&#x672C;&#x548C;grpc&#x7684;&#x6B65;&#x9AA4;&#xFF1A;</h3>
<p>&#x4EE5;&#x4E0B;&#x57FA;&#x4E8E;grpc 1.19.0&#x7248;&#x672C;&#x548C;electron 4.0.3&#x7248;&#x672C;&#xFF0C;&#x8FD9;&#x662F;&#x786E;&#x5B9A;&#x597D;&#x7528;&#x7684;&#x3002;</p>
<h4 id="1-mac%E4%B8%8B%E7%9A%84nrmpc%E6%96%87%E4%BB%B6%E5%8F%82%E8%80%83%EF%BC%9A">1. mac&#x4E0B;&#x7684;.nrmpc&#x6587;&#x4EF6;&#x53C2;&#x8003;&#xFF1A;</h4>
<pre><code class="language-bash">sass_binary_site=https://npm.taobao.org/mirrors/node-sass/
phantomjs_cdnurl=http://npm.taobao.org/mirrors/phantomjs
ELECTRON_MIRROR=http://npm.taobao.org/mirrors/electron/
</code></pre>
<p>&#x5982;&#x679C;&#x5F53;&#x524D;&#x7528;&#x6237;&#x7684;&#x6839;&#x76EE;&#x5F55;&#x4E0B;&#x6CA1;&#x6709;<code>.npmrc</code>&#x6587;&#x4EF6;&#xFF0C;&#x5C31;&#x65B0;&#x5EFA;&#x4E00;&#x4E2A;&#x5E76;&#x5199;&#x5165;&#x8FD9;&#x4E9B;&#x5185;&#x5BB9;&#x3002;</p>
<h4 id="2-%E5%9C%A8electron%E9%A1%B9%E7%9B%AE%E7%9B%AE%E5%BD%95%E4%B8%8B%EF%BC%8C%E5%AE%89%E8%A3%85electron%E7%9A%84403%E7%89%88%E6%9C%AC%E3%80%82">2. &#x5728;electron&#x9879;&#x76EE;&#x76EE;&#x5F55;&#x4E0B;&#xFF0C;&#x5B89;&#x88C5;<code>Electron</code>&#x7684;4.0.3&#x7248;&#x672C;&#x3002;</h4>
<pre><code class="language-bash">npm i electron@4.0.3
</code></pre>
<h4 id="3-%E5%9C%A8electron%E9%A1%B9%E7%9B%AE%E7%9B%AE%E5%BD%95%E4%B8%8B%EF%BC%8C%E5%AE%89%E8%A3%85grpc%E7%9A%841190%E7%89%88%E6%9C%AC%E3%80%82">3. &#x5728;electron&#x9879;&#x76EE;&#x76EE;&#x5F55;&#x4E0B;&#xFF0C;&#x5B89;&#x88C5;<code>grpc</code>&#x7684;1.19.0&#x7248;&#x672C;&#x3002;</h4>
<pre><code class="language-bash">npm install grpc@1.19.0 --runtime=electron --target=4.0.3
</code></pre>
<p>&#x7ECF;&#x8FC7;&#x4EE5;&#x4E0A;&#x51E0;&#x4E2A;&#x6B65;&#x9AA4;&#xFF0C;&#x7136;&#x540E;&#x5728;electron&#x9879;&#x76EE;&#x6267;&#x884C;<code>npm i</code>&#x5B89;&#x88C5;&#x5176;&#x4ED6;&#x4F9D;&#x8D56;&#x540E;&#xFF0C;&#x9879;&#x76EE;&#x5E94;&#x8BE5;&#x5C31;&#x53EF;&#x4EE5;&#x8FD0;&#x884C;&#x3002;</p>
<h3 id="%E5%A6%82%E6%9E%9C%E8%BF%98%E8%BF%90%E8%A1%8C%E4%B8%8D%E8%B5%B7%E6%9D%A5%EF%BC%8C%E5%8F%AF%E4%BB%A5%E5%B0%9D%E8%AF%95%E4%BB%A5%E4%B8%8B2%E4%B8%AA%E6%96%B9%E6%B3%95%EF%BC%9A">&#x5982;&#x679C;&#x8FD8;&#x8FD0;&#x884C;&#x4E0D;&#x8D77;&#x6765;&#xFF0C;&#x53EF;&#x4EE5;&#x5C1D;&#x8BD5;&#x4EE5;&#x4E0B;2&#x4E2A;&#x65B9;&#x6CD5;&#xFF1A;</h3>
<h4 id="1-%E5%A6%82%E6%9E%9C%E7%BC%96%E8%AF%91%E5%A4%B1%E8%B4%A5%E5%8F%AF%E5%B0%9D%E8%AF%95%EF%BC%9A">1. &#x5982;&#x679C;&#x7F16;&#x8BD1;&#x5931;&#x8D25;&#x53EF;&#x5C1D;&#x8BD5;&#xFF1A;</h4>
<pre><code class="language-bash">./node_modules/.bin/electron-rebuild
</code></pre>
<p>&#x4F7F;&#x7528;<code>electron-rebuild</code>&#x91CD;&#x65B0;&#x7F16;&#x8BD1;&#x3002;</p>
<h4 id="2-%E5%A6%82%E6%9E%9C%E6%8F%90%E7%A4%BA%E4%BA%86npm-rebuild%E9%94%99%E8%AF%AF%EF%BC%9A">2. &#x5982;&#x679C;&#x63D0;&#x793A;&#x4E86;<code>npm rebuild</code>&#x9519;&#x8BEF;&#xFF1A;</h4>
<pre><code class="language-bash">npm rebuild
</code></pre>
<p>&#x76F4;&#x63A5;&#x6267;&#x884C;<code>npm rebuild</code>&#x7F16;&#x8BD1;&#x3002;</p>
]]></content:encoded></item><item><title><![CDATA[前后端接口联调小结]]></title><description><![CDATA[在项目开发过程中，前端与后端联调接口会碰到很多问题，比如规范、跨域等问题，因此总结了一些规范和开发中碰到的问题，以及如何设置和获取自定义相应头字段，方便前后端的同学参考和进一步了解。]]></description><link>http://hanhan.pro/debugging-api-between-frontend-and-backend/</link><guid isPermaLink="false">6596a4b993ef2d0001f41545</guid><category><![CDATA[接口联调]]></category><category><![CDATA[前端]]></category><dc:creator><![CDATA[reno]]></dc:creator><pubDate>Mon, 25 Jun 2018 00:00:00 GMT</pubDate><media:content url="http://hanhan.pro/content/images/2020/02/12-frontend-backend.jpg" medium="image"/><content:encoded><![CDATA[<h2 id="%E6%8E%A5%E5%8F%A3%E8%A7%84%E8%8C%83%EF%BC%9A">&#x63A5;&#x53E3;&#x89C4;&#x8303;&#xFF1A;</h2>
<h4 id="1-%E5%90%8E%E7%AB%AF%E9%9C%80%E7%BB%99%E5%87%BA%E5%9B%BA%E5%AE%9A%E7%9A%84%E8%B7%AF%E5%BE%84%EF%BC%8C%E6%AF%94%E5%A6%82xxapi%EF%BC%9B">1. &#x540E;&#x7AEF;&#x9700;&#x7ED9;&#x51FA;&#x56FA;&#x5B9A;&#x7684;&#x8DEF;&#x5F84;&#xFF0C;&#x6BD4;&#x5982;<code>/xxapi</code>&#xFF1B;</h4>
<h4 id="2-%E5%90%8E%E7%AB%AF%E8%BF%94%E5%9B%9E%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%9A">2. &#x540E;&#x7AEF;&#x8FD4;&#x56DE;&#x7684;&#x57FA;&#x672C;&#x6570;&#x636E;&#x7ED3;&#x6784;&#xFF1A;</h4>
<pre><code class="language-json">data: null,
success: true,
message: &quot;&#x8BF7;&#x6C42;&#x6210;&#x529F;&quot;,
</code></pre>
<img src="http://hanhan.pro/content/images/2020/02/12-frontend-backend.jpg" alt="&#x524D;&#x540E;&#x7AEF;&#x63A5;&#x53E3;&#x8054;&#x8C03;&#x5C0F;&#x7ED3;"><p>&#x9ED8;&#x8BA4;&#x7684;&#x6570;&#x636E;&#x7ED3;&#x6784;&#x5E94;&#x8BE5;&#x81F3;&#x5C11;&#x6709;&#x8FD9;3&#x4E2A;&#x5C5E;&#x6027;&#xFF0C;&#x5982;&#x679C;&#x6CA1;&#x6709;&#x6570;&#x636E;&#x5219; <code>data</code> &#x4E3A; <code>null</code> &#xFF1B;<code>success</code>&#x5C5E;&#x6027;&#x662F;&#x65B9;&#x4FBF;&#x524D;&#x7AEF;&#x5224;&#x65AD;&#x54CD;&#x5E94;&#x7ED3;&#x679C;&#x662F;&#x5426;&#x4E3A;&#x6210;&#x529F;&#x7684;&#x72B6;&#x6001;&#xFF0C;&#x6BD4;&#x5982;&#x767B;&#x5F55;&#x9875;&#x9700;&#x8981;&#x54CD;&#x5E94;&#x7ED9;&#x524D;&#x7AEF;&#x7684;&#x9519;&#x8BEF;&#x4FE1;&#x606F;&#x6709;&#x5F88;&#x591A;&#x79CD;&#xFF0C;&#x800C;&#x524D;&#x7AEF;&#x9996;&#x5148;&#x9700;&#x8981;&#x77E5;&#x9053;&#x662F;&#x6210;&#x529F;&#x8FD8;&#x662F;&#x5931;&#x8D25;&#x6765;&#x8FDB;&#x884C;&#x903B;&#x8F91;&#x7F16;&#x7801;&#xFF1B;&#x5982;&#x679C;&#x5931;&#x8D25;&#xFF0C;&#x524D;&#x7AEF;&#x53EF;&#x76F4;&#x63A5;&#x5C06;<code>message</code>&#x663E;&#x793A;&#x7ED9;&#x7528;&#x6237;&#x3002;</p>
<!--more-->
<h4 id="3-%E5%90%8E%E7%AB%AF%E8%BF%94%E5%9B%9E%E7%9A%84%E5%88%97%E8%A1%A8%E9%A1%B5%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%9A">3. &#x540E;&#x7AEF;&#x8FD4;&#x56DE;&#x7684;&#x5217;&#x8868;&#x9875;&#x6570;&#x636E;&#x7ED3;&#x6784;&#xFF1A;</h4>
<pre><code class="language-json">data: {
    list: [
        {id:1, title: &quot;1&quot;},
        {id:2, title: &quot;2&quot;},
        ...
    ],
    pagination: {
        total: 300,
        current: 1,
    }
},
success: true,
message: &quot;&#x8BF7;&#x6C42;&#x6210;&#x529F;&quot;,
</code></pre>
<p><code>total</code>&#x4E3A;&#x8BB0;&#x5F55;&#x603B;&#x6570;&#xFF0C;<code>current</code>&#x4E3A;&#x5F53;&#x524D;&#x7B2C;&#x51E0;&#x9875;&#xFF0C;&#x9ED8;&#x8BA4;&#x663E;&#x793A;&#x6570;&#x524D;&#x540E;&#x7AEF;&#x5E94;&#x5546;&#x5B9A;&#x597D;&#xFF0C;&#x6BD4;&#x5982;20&#x6761;&#xFF0C;&#x5199;&#x5230;&#x5404;&#x81EA;&#x5DE5;&#x7A0B;&#x7684;&#x914D;&#x7F6E;&#x53C2;&#x6570;&#x3002;</p>
<h4 id="4-%E5%90%8E%E7%AB%AF%E8%BF%94%E5%9B%9E%E7%9A%84%E8%AF%A6%E6%83%85%E9%A1%B5%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%9A">4. &#x540E;&#x7AEF;&#x8FD4;&#x56DE;&#x7684;&#x8BE6;&#x60C5;&#x9875;&#x6570;&#x636E;&#x7ED3;&#x6784;&#xFF1A;</h4>
<pre><code class="language-json">data: {
    title: &quot;&#x6807;&#x9898;&quot;,
    content: &quot;&#x5185;&#x5BB9;&quot;,
    ...
},
success: true,
message: &quot;&#x8BF7;&#x6C42;&#x6210;&#x529F;&quot;,
</code></pre>
<h4 id="5-%E5%89%8D%E7%AB%AF%E6%8F%90%E4%BA%A4%E7%9A%84%E6%96%B0%E5%BB%BA%EF%BC%8F%E4%BF%AE%E6%94%B9%E9%A1%B5%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%9A">5. &#x524D;&#x7AEF;&#x63D0;&#x4EA4;&#x7684;&#x65B0;&#x5EFA;&#xFF0F;&#x4FEE;&#x6539;&#x9875;&#x6570;&#x636E;&#x7ED3;&#x6784;&#xFF1A;</h4>
<pre><code class="language-json">title: &quot;&#x6807;&#x9898;&quot;,
content: &quot;&#x5185;&#x5BB9;&quot;,
...
</code></pre>
<h4 id="6-%E5%90%8E%E7%AB%AF%E8%BF%94%E5%9B%9E%E7%9A%84%E5%9F%BA%E7%A1%80%EF%BC%88%E5%8D%95%E4%B8%AA%EF%BC%89%E6%9F%B1%E5%9B%BE%E3%80%81%E9%A5%BC%E5%9B%BE%E3%80%81%E6%8A%98%E7%BA%BF%E5%9B%BE%E7%9A%84%E5%9B%BE%E8%A1%A8%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%9A">6. &#x540E;&#x7AEF;&#x8FD4;&#x56DE;&#x7684;&#x57FA;&#x7840;&#xFF08;&#x5355;&#x4E2A;&#xFF09;&#x67F1;&#x56FE;&#x3001;&#x997C;&#x56FE;&#x3001;&#x6298;&#x7EBF;&#x56FE;&#x7684;&#x56FE;&#x8868;&#x6570;&#x636E;&#x7ED3;&#x6784;&#xFF1A;</h4>
<pre><code class="language-json">data:[
    {&quot;x&quot;:&quot;&#x5E7F;&#x4E1C;&#x7701;&quot;,&quot;y&quot;:76011802.16},
    {&quot;x&quot;:&quot;&#x6C5F;&#x82CF;&#x7701;&quot;,&quot;y&quot;:40717628.60},
    ...
],
success: true,
message: &quot;&#x8BF7;&#x6C42;&#x6210;&#x529F;&quot;,
</code></pre>
<h4 id="7-%E5%90%8E%E7%AB%AF%E8%BF%94%E5%9B%9E%E7%9A%84%E5%A4%9A%E6%9D%A1%E6%8A%98%E7%BA%BF%E5%9B%BE%E7%9A%84%E5%9B%BE%E8%A1%A8%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%9A">7. &#x540E;&#x7AEF;&#x8FD4;&#x56DE;&#x7684;&#x591A;&#x6761;&#x6298;&#x7EBF;&#x56FE;&#x7684;&#x56FE;&#x8868;&#x6570;&#x636E;&#x7ED3;&#x6784;&#xFF1A;</h4>
<pre><code class="language-json">data:[
    {&quot;x&quot;:&quot;&#x5E7F;&#x4E1C;&#x7701;&quot;,&quot;y&quot;:76011802.16, type:&quot;&#x963F;&#x8FEA;&#x8FBE;&#x65AF;&quot;},
    {&quot;x&quot;:&quot;&#x6C5F;&#x82CF;&#x7701;&quot;,&quot;y&quot;:40717628.60, type:&quot;&#x8010;&#x514B;&quot;},
    ...
],
success: true,
message: &quot;&#x8BF7;&#x6C42;&#x6210;&#x529F;&quot;,
</code></pre>
<p>&#x540E;&#x9762;&#x591A;&#x4E00;&#x4E2A;<code>type</code>&#x5C5E;&#x6027;&#xFF0C;&#x5177;&#x4F53;&#x4EE5;&#x5B9E;&#x9645;&#x56FE;&#x8868;&#x7C7B;&#x578B;&#x548C;&#x7ED3;&#x6784;&#x4E3A;&#x51C6;&#x3002;</p>
<h2 id="%E5%B8%B8%E8%A7%81%E6%8E%A5%E5%8F%A3%E6%8A%A5%E9%94%99%E5%8F%8A%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88%EF%BC%9A">&#x5E38;&#x89C1;&#x63A5;&#x53E3;&#x62A5;&#x9519;&#x53CA;&#x89E3;&#x51B3;&#x65B9;&#x6848;&#xFF1A;</h2>
<p>&#x5728;&#x524D;&#x7AEF;&#x9875;&#x9762;&#x8BBF;&#x95EE;&#x540E;&#x7AEF;&#x63A5;&#x53E3;&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x5982;&#x679C;&#x540E;&#x7AEF;&#x6216;&#x670D;&#x52A1;&#x5668;&#x7AEF;&#x672A;&#x505A;&#x4E00;&#x4E9B;&#x8BBE;&#x7F6E;&#xFF0C;&#x4F1A;&#x9020;&#x6210;&#x9875;&#x9762;&#x8BBF;&#x95EE;&#x63A5;&#x53E3;&#x5931;&#x8D25;&#xFF0C;&#x5728;&#x6D4F;&#x89C8;&#x5668;&#x7684;&#x63A7;&#x5236;&#x53F0;&#x4F1A;&#x663E;&#x793A;&#x62A5;&#x9519;&#x4FE1;&#x606F;&#x3002;&#x672C;&#x6587;&#x9488;&#x5BF9;&#x4E00;&#x4E9B;&#x5E38;&#x89C1;&#x7684;&#x9519;&#x8BEF;&#xFF0C;&#x5217;&#x51FA;&#x4E86;&#x89E3;&#x51B3;&#x65B9;&#x6848;&#x3002;</p>
<h4 id="1-%E4%B8%8D%E5%90%8C%E7%AB%AF%E5%8F%A3%E6%88%96%E4%B8%8D%E5%90%8C%E7%9A%84%E5%9F%9F%E5%90%8D%E4%BA%A7%E7%94%9F%E7%9A%84%E8%B7%A8%E5%9F%9F%E9%97%AE%E9%A2%98%EF%BC%8C%E9%94%99%E8%AF%AF%E5%A6%82%E4%B8%8B%EF%BC%9A">1. &#x4E0D;&#x540C;&#x7AEF;&#x53E3;&#x6216;&#x4E0D;&#x540C;&#x7684;&#x57DF;&#x540D;&#x4EA7;&#x751F;&#x7684;&#x8DE8;&#x57DF;&#x95EE;&#x9898;&#xFF0C;&#x9519;&#x8BEF;&#x5982;&#x4E0B;&#xFF1A;</h4>
<pre><code class="language-bash">Failed to load ... : No &apos;Access-Control-Allow-Origin&apos; header is present on the requested resource. Origin &apos;http://...&apos; is therefore not allowed access. If an opaque response serves your needs, set the request&apos;s mode to &apos;no-cors&apos; to fetch the resource with CORS disabled.
</code></pre>
<p>&#x51FA;&#x73B0;&#x8FD9;&#x4E2A;&#x9519;&#x8BEF;&#x662F;&#x56E0;&#x4E3A;&#x524D;&#x7AEF;&#x9875;&#x9762;&#x8DDF;&#x540E;&#x7AEF;&#x63A5;&#x53E3;&#x5728;&#x4E0D;&#x540C;&#x7684;&#x7AEF;&#x53E3;&#x6216;IP&#x6216;&#x57DF;&#x540D;&#x4E0B;&#x9762;&#xFF0C;&#x4E5F;&#x5C31;&#x662F;&#x8DE8;&#x57DF;&#x3002;&#x5173;&#x4E8E;&#x8DE8;&#x57DF;&#x4F60;&#x53EF;&#x80FD;&#x9700;&#x8981;&#x8BE6;&#x7EC6;&#x4E86;&#x89E3; <a href="https://developer.mozilla.org/zh/docs/Web/HTTP/Access_control_CORS?ref=hanhan.pro">&#x8DE8;&#x57DF;&#x8D44;&#x6E90;&#x5171;&#x4EAB; CORS</a>&#x3002;&#x8DE8;&#x57DF;&#x4EA7;&#x751F;&#x7684;&#x539F;&#x56E0;&#x662F;&#x6D4F;&#x89C8;&#x5668;&#x9075;&#x5FAA;&#x7684;&#x57FA;&#x672C;&#x5B89;&#x5168;&#x7B56;&#x7565; - <a href="https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy?ref=hanhan.pro">MDN web docs[&#x6D4F;&#x89C8;&#x5668;&#x7684;&#x540C;&#x6E90;&#x7B56;&#x7565;]</a>&#x3002;</p>
<p>&#x89E3;&#x51B3;&#x65B9;&#x6848;&#xFF1A;</p>
<pre><code class="language-bash">Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET,PUT,POST,DELETE,OPTIONS
</code></pre>
<p>&#x5982;&#x679C;&#x540E;&#x7AEF;&#x662F;Java&#x9879;&#x76EE;&#xFF0C;&#x4E00;&#x822C;&#x662F;&#x5728;&#x5F00;&#x53D1;&#x73AF;&#x5883;&#x670D;&#x52A1;&#x5668;&#x7684;nginx&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x4E2D;&#x6DFB;&#x52A0;&#x4E0A;&#x9762;&#x51E0;&#x9879;&#x6765;&#x7EDF;&#x4E00;&#x914D;&#x7F6E;&#xFF0C;&#x800C;&#x4E0D;&#x662F;&#x5728;&#x540E;&#x7AEF;&#x4EE3;&#x7801;&#x91CC;&#x914D;&#x7F6E;&#x3002;&#x6DFB;&#x52A0;&#x5B8C;&#x540E;&#x91CD;&#x542F;nginx&#xFF0C;&#x7136;&#x540E;&#x5728;&#x6D4F;&#x89C8;&#x5668;&#x7684;&#x54CD;&#x5E94;&#x5934;&#x91CC;&#x5E94;&#x8BE5;&#x53EF;&#x4EE5;&#x770B;&#x5230;&#x521A;&#x624D;&#x914D;&#x7F6E;&#x7684;&#x51E0;&#x9879;&#xFF0C;&#x8BF4;&#x660E;&#x914D;&#x7F6E;&#x6210;&#x529F;&#x3002;&#x8FD9;&#x91CC;<code>Access-Control-Allow-Origin</code>&#x8BBE;&#x7F6E;&#x4E3A;<code>*</code>&#x8868;&#x793A;&#x5141;&#x8BB8;&#x6240;&#x6709;&#x7684;&#x57DF;&#xFF0C;&#x4E5F;&#x53EF;&#x4EE5;&#x6839;&#x636E;&#x5177;&#x4F53;&#x7684;&#x73AF;&#x5883;&#x6765;&#x8BBE;&#x7F6E;&#x5177;&#x4F53;&#x7684;IP&#x6216;&#x57DF;&#x540D;&#x3002;</p>
<h4 id="2-%E8%AF%B7%E6%B1%82%E5%A4%B4%E7%B1%BB%E5%9E%8B%E7%9A%84%E9%94%99%E8%AF%AF%EF%BC%9A">2. &#x8BF7;&#x6C42;&#x5934;&#x7C7B;&#x578B;&#x7684;&#x9519;&#x8BEF;&#xFF1A;</h4>
<pre><code class="language-bash">Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
</code></pre>
<p>&#x8FD9;&#x4E2A;&#x9519;&#x8BEF;&#x5F53;&#x524D;&#x8BF7;&#x6C42;Content-Type&#x7684;&#x503C;&#x4E0D;&#x88AB;&#x652F;&#x6301;&#x3002;&#x53EF;&#x80FD;&#x524D;&#x7AEF;&#x53D1;&#x9001;&#x7684;&#x8BF7;&#x6C42;&#x5934;&#x7C7B;&#x578B;&#x6709;<code>application/json</code>&#xFF0C;&#x8FD9;&#x4E2A;&#x8BF7;&#x6C42;&#x6D89;&#x53CA;&#x5230;&#x9884;&#x68C0;&#x8BF7;&#x6C42;&#xFF0C;&#x53EF;&#x53C2;&#x770B; <a href="https://developer.mozilla.org/zh/docs/Web/HTTP/Access_control_CORS?ref=hanhan.pro">HTTP&#x8BBF;&#x95EE;&#x63A7;&#x5236;&#xFF08;CORS&#xFF09;</a>&#x3002;</p>
<p>&#x89E3;&#x51B3;&#x65B9;&#x6848;&#xFF1A;</p>
<pre><code class="language-bash">Access-Control-Allow-Headers: Content-Type,*
</code></pre>
<p>nginx&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x4E2D;&#x6DFB;&#x52A0;&#x8FD9;&#x9879;&#x914D;&#x7F6E;&#xFF0C;&#x8868;&#x793A;&#x63A5;&#x6536;&#x524D;&#x7AEF;&#x7684;<code>Content-Type</code>&#x3002;</p>
<h4 id="3-%E6%90%BA%E5%B8%A6cookie%E8%AE%BE%E7%BD%AE%E4%BA%A7%E7%94%9F%E7%9A%84%E9%97%AE%E9%A2%98%EF%BC%8C%E9%94%99%E8%AF%AF%E5%A6%82%E4%B8%8B%EF%BC%9A">3. &#x643A;&#x5E26;cookie&#x8BBE;&#x7F6E;&#x4EA7;&#x751F;&#x7684;&#x95EE;&#x9898;&#xFF0C;&#x9519;&#x8BEF;&#x5982;&#x4E0B;&#xFF1A;</h4>
<pre><code class="language-bash">Failed to load ... : Response to preflight request doesn&apos;t pass access control check: The value of the &apos;Access-Control-Allow-Credentials&apos; header in the response is &apos;&apos; which must be &apos;true&apos; when the request&apos;s credentials mode is &apos;include&apos;. Origin &apos;http://...&apos; is therefore not allowed access.
</code></pre>
<p>&#x51FA;&#x73B0;&#x8FD9;&#x4E2A;&#x9519;&#x8BEF;&#x662F;&#x56E0;&#x4E3A;&#x524D;&#x7AEF;&#x8BF7;&#x6C42;&#x63A5;&#x53E3;&#x7684;&#x65F6;&#x5019;&#x5728;&#x8BF7;&#x6C42;&#x5934;&#x91CC;&#x52A0;&#x4E86;<code>credentials: &apos;include&apos;</code>&#x53C2;&#x6570;&#x643A;&#x5E26;cookie&#x4FE1;&#x606F;&#xFF0C;&#x800C;&#x540E;&#x7AEF;&#x672A;&#x505A;&#x63A5;&#x6536;cookie&#x7684;&#x8BBE;&#x7F6E;&#x3002;</p>
<p>&#x89E3;&#x51B3;&#x65B9;&#x6848;&#xFF1A;</p>
<pre><code class="language-bash">Access-Control-Allow-Credentials: true
</code></pre>
<p>nginx&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x4E2D;&#x6DFB;&#x52A0;&#x8FD9;&#x9879;&#x914D;&#x7F6E;&#xFF0C;&#x8868;&#x793A;&#x63A5;&#x6536;&#x524D;&#x7AEF;&#x643A;&#x5E26;&#x7684;cookie&#x4FE1;&#x606F;&#x3002;&#x53EA;&#x6709;&#x524D;&#x540E;&#x7AEF;&#x90FD;&#x8BBE;&#x7F6E;&#xFF0C;&#x8DE8;&#x57DF;&#x643A;&#x5E26;cookie&#x8BF7;&#x6C42;&#x624D;&#x80FD;&#x6210;&#x529F;&#x3002;&#x8BE6;&#x7EC6;&#x7684;&#x4E86;&#x89E3;&#x53EF;&#x53C2;&#x770B; <a href="https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials?ref=hanhan.pro">MDN web docs [Access-Control-Allow-Credentials]</a></p>
<h2 id="%E8%87%AA%E5%AE%9A%E4%B9%89%E5%93%8D%E5%BA%94%E5%A4%B4%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88%EF%BC%9A">&#x81EA;&#x5B9A;&#x4E49;&#x54CD;&#x5E94;&#x5934;&#x89E3;&#x51B3;&#x65B9;&#x6848;&#xFF1A;</h2>
<p>&#x5728;&#x72EC;&#x7ACB;&#x7684;&#x524D;&#x7AEF;&#x5DE5;&#x7A0B;&#x4E2D;&#xFF0C;&#x7528;&#x6237;&#x8BBF;&#x95EE;&#x5230;&#x7684;&#x867D;&#x7136;&#x662F;&#x9759;&#x6001;&#x9875;&#x9762;&#xFF0C;&#x800C;&#x5B9E;&#x9645;&#x4E0A;&#x73B0;&#x5728;&#x7684;&#x524D;&#x7AEF;&#x9875;&#x9762;&#x5DF2;&#x7ECF;&#x6709;&#x4E86;&#x81EA;&#x5DF1;&#x7684;&#x8DEF;&#x7531;&#x3001;&#x6743;&#x9650;&#x63A7;&#x5236;&#x7B49;&#x7B49;&#x3002;</p>
<p>&#x5728;&#x72EC;&#x7ACB;&#x7684;&#x524D;&#x7AEF;&#x5DE5;&#x7A0B;&#x5DE5;&#x7A0B;&#x4E2D;&#x540C;&#x6837;&#x4F1A;&#x78B0;&#x5230;&#x4E00;&#x4E2A;&#x95EE;&#x9898;&#xFF1A;&#x524D;&#x7AEF;&#x9875;&#x9762;&#x5982;&#x4F55;&#x6BD4;&#x8F83;&#x597D;&#x7684;&#x83B7;&#x53D6;&#x7528;&#x6237;&#x8D85;&#x65F6;&#x72B6;&#x6001;&#x6765;&#x9000;&#x51FA;&#x767B;&#x5F55;&#xFF1F;&#x672C;&#x6587;&#x4ECB;&#x7ECD;&#x4F7F;&#x7528;&#x81EA;&#x5B9A;&#x4E49;&#x54CD;&#x5E94;&#x5934;&#x5B57;&#x6BB5;&#x6765;&#x89E3;&#x51B3;&#x8FD9;&#x4E2A;&#x95EE;&#x9898;&#x3002;</p>
<h5 id="1-%E5%90%8E%E7%AB%AF%E5%9C%A8%E5%93%8D%E5%BA%94%E5%A4%B4%E9%87%8C%E5%A2%9E%E5%8A%A0%E5%B1%9E%E6%80%A7%EF%BC%8C%E4%BE%8B%E5%A6%82%EF%BC%9A">1. &#x540E;&#x7AEF;&#x5728;&#x54CD;&#x5E94;&#x5934;&#x91CC;&#x589E;&#x52A0;&#x5C5E;&#x6027;&#xFF0C;&#x4F8B;&#x5982;&#xFF1A;</h5>
<pre><code class="language-bash">x-session-expired: 1
</code></pre>
<p>&#x540E;&#x7AEF;&#x4EE3;&#x7801;&#x901A;&#x8FC7;&#x589E;&#x52A0;<code>x-session-expired</code>&#x4E3A;<code>1</code>&#x6765;&#x544A;&#x8BC9;&#x524D;&#x7AEF;&#x5F53;&#x524D;&#x7528;&#x6237;&#x8D85;&#x65F6;&#x4E86;&#x3002;&#x7136;&#x540E;&#x5728;&#x6D4F;&#x89C8;&#x5668;&#x7684;&#x54CD;&#x5E94;&#x91CC;&#x5E94;&#x8BE5;&#x80FD;&#x770B;&#x5230;&#x4E0A;&#x9762;&#x8FD9;&#x4E2A;&#x914D;&#x7F6E;&#x3002;&#x4F46;&#x662F;&#x524D;&#x7AEF;&#x5728;&#x8DE8;&#x57DF;&#x8BF7;&#x6C42;&#x60C5;&#x51B5;&#x4E0B;&#x9ED8;&#x8BA4;&#x53EA;&#x80FD;&#x83B7;&#x53D6;&#x5230;&#x54CD;&#x5E94;&#x5934;&#x91CC;&#x7684;<code>Cache-Control</code>&#x3001;<code>Content-Language</code>&#x3001;<code>Content-Type</code>&#x3001;<code>Expires</code>&#x3001;<code>Last-Modified</code>&#x3001;<code>Pragma</code>6&#x4E2A;&#x57FA;&#x672C;&#x5B57;&#x6BB5;&#xFF0C;&#x5982;&#x679C;&#x8981;&#x83B7;&#x53D6;&#x5230;&#x521A;&#x589E;&#x52A0;&#x7684;<code>x-session-expired</code>&#x5B57;&#x6BB5;&#xFF0C;&#x9700;&#x8981;&#x8FDB;&#x884C;&#x4E0B;&#x4E00;&#x6B65;&#x3002;</p>
<h4 id="2-%E5%90%8E%E7%AB%AF%E5%A2%9E%E5%8A%A0%E4%BB%A5%E4%B8%8B%E9%85%8D%E7%BD%AE%EF%BC%9A">2. &#x540E;&#x7AEF;&#x589E;&#x52A0;&#x4EE5;&#x4E0B;&#x914D;&#x7F6E;&#xFF1A;</h4>
<pre><code class="language-bash">Access-Control-Expose-Headers: x-session-expired
</code></pre>
<p>&#x8BE5;&#x914D;&#x7F6E;&#x7684;&#x4F5C;&#x7528;&#x662F;&#x6307;&#x5B9A;&#x54EA;&#x4E9B;&#x9996;&#x90E8;&#x53EF;&#x4EE5;&#x4F5C;&#x4E3A;&#x54CD;&#x5E94;&#x7684;&#x4E00;&#x90E8;&#x5206;&#x66B4;&#x9732;&#x7ED9;&#x5916;&#x90E8;&#xFF0C;&#x8FD9;&#x6837;&#x524D;&#x7AEF;&#x624D;&#x80FD;&#x83B7;&#x53D6;&#x5230;&#x4E0A;&#x9762;&#x4E00;&#x6B65;&#x6DFB;&#x52A0;&#x7684;<code>x-session-expired</code>&#x5B57;&#x6BB5;&#x53CA;&#x5176;&#x503C;&#x3002;</p>
<h4 id="3-%E5%89%8D%E7%AB%AF%E5%9C%A8-fetch-%E8%AF%B7%E6%B1%82%E7%9A%84%E6%97%B6%E5%80%99%E8%8E%B7%E5%8F%96%E8%87%AA%E5%AE%9A%E4%B9%89%E5%93%8D%E5%BA%94%E5%A4%B4%E5%AD%97%E6%AE%B5%EF%BC%9A">3. &#x524D;&#x7AEF;&#x5728; <code>fetch</code> &#x8BF7;&#x6C42;&#x7684;&#x65F6;&#x5019;&#x83B7;&#x53D6;&#x81EA;&#x5B9A;&#x4E49;&#x54CD;&#x5E94;&#x5934;&#x5B57;&#x6BB5;&#xFF1A;</h4>
<pre><code class="language-js">return fetch(url, newOptions)
    .then(checkStatus)
    .then(response =&gt; {
      const { dispatch } = store;
      const { headers } = response;
      if (headers &amp;&amp; headers.has(&apos;x-session-expired&apos;)) {
        // &#x5982;&#x679C;&#x6709;&#x54CD;&#x5E94;&#x5934;&#x91CC;&#x6709;x-session-expired&#x5219;&#x9000;&#x51FA;
        dispatch({
          type: &apos;login/logout&apos;,
        });
        return;
      }
      return response.json();
    })
    .catch((e) =&gt; {
        ...
    });
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#x4E0A;&#x9762;&#x4EE3;&#x7801;&#x7684;<code>headers.has(&apos;x-session-expired&apos;)</code>&#xFF0C;&#x524D;&#x7AEF;&#x901A;&#x8FC7;has&#x65B9;&#x6CD5;&#x6765;&#x83B7;&#x53D6;&#x54CD;&#x5E94;&#x5934;&#x91CC;&#x662F;&#x5426;&#x6709;<code>x-session-expired</code>&#x5B57;&#x6BB5;&#xFF0C;&#x6765;&#x5224;&#x65AD;&#x662F;&#x9000;&#x51FA;&#x8FD8;&#x662F;&#x89E3;&#x6790;&#x6570;&#x636E;&#x3002;</p>
<p>&#x81F3;&#x6B64;&#xFF0C;&#x540E;&#x7AEF;&#x8BBE;&#x7F6E;&#x81EA;&#x5B9A;&#x4E49;&#x54CD;&#x5E94;&#x5934;&#x5B57;&#x6BB5;&#x4E14;&#x524D;&#x7AEF;&#x83B7;&#x53D6;&#x8BE5;&#x5B57;&#x6BB5;&#x7684;&#x95EE;&#x9898;&#x89E3;&#x51B3;&#x4E86;&#x3002;&#x8BE5;&#x65B9;&#x6CD5;&#x4E5F;&#x540C;&#x6837;&#x9002;&#x7528;&#x4E8E;&#x6DFB;&#x52A0;&#x5176;&#x4ED6;&#x7684;&#x54CD;&#x5E94;&#x5934;&#x5B57;&#x6BB5;&#xFF0C;&#x89E3;&#x51B3;&#x65E0;&#x6743;&#x9650;&#x6216;&#x5176;&#x4ED6;&#x95EE;&#x9898;&#x3002;</p>
<h4 id="%E7%96%91%E9%97%AE%EF%BC%9A%E5%8F%AF%E8%83%BD%E6%9C%89%E5%90%8C%E5%AD%A6%E4%BC%9A%E6%8F%90%E5%87%BA%EF%BC%9A%E8%B6%85%E6%97%B6%E6%83%85%E5%86%B5%E4%B8%8B%EF%BC%8C%E5%90%8E%E7%AB%AF%E8%BF%94%E5%9B%9E%E4%B8%8D%E5%90%8C%E7%9A%84json%E6%95%B0%E6%8D%AE%E6%9D%A5%E5%91%8A%E8%AF%89%E5%89%8D%E7%AB%AF%E7%94%A8%E6%88%B7%E8%B6%85%E6%97%B6%E4%B8%8D%E8%A1%8C%E5%90%97%EF%BC%9F">&#x7591;&#x95EE;&#xFF1A;&#x53EF;&#x80FD;&#x6709;&#x540C;&#x5B66;&#x4F1A;&#x63D0;&#x51FA;&#xFF1A;&#x8D85;&#x65F6;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x540E;&#x7AEF;&#x8FD4;&#x56DE;&#x4E0D;&#x540C;&#x7684;json&#x6570;&#x636E;&#x6765;&#x544A;&#x8BC9;&#x524D;&#x7AEF;&#x7528;&#x6237;&#x8D85;&#x65F6;&#x4E0D;&#x884C;&#x5417;&#xFF1F;</h4>
<ul>
<li>&#x8D85;&#x65F6;&#x6216;&#x8005;&#x65E0;&#x6743;&#x9650;&#x7684;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x540E;&#x7AEF;&#x5E94;&#x8BE5;&#x662F;&#x7ED9;&#x524D;&#x7AEF;&#x54CD;&#x5E94;&#x4E0D;&#x540C;&#x7684;&#x72B6;&#x6001;&#x7801;&#x7684;&#xFF0C;&#x6BD4;&#x5982;401&#x65E0;&#x6743;&#x9650;&#x3001;403&#x8BBF;&#x95EE;&#x88AB;&#x7981;&#x6B62;&#x3002;&#x4F46;&#x662F;&#x5982;&#x679C;&#x6B64;&#x65F6;&#x8FD8;&#x8981;&#x7ED9;&#x524D;&#x7AEF;&#x54CD;&#x5E94;&#x6570;&#x636E;&#xFF0C;&#x6309;&#x7167;&#x89C4;&#x8303;&#x5C31;&#x662F;&#x8981;&#x8FD4;&#x56DE;200&#x7684;&#x72B6;&#x6001;&#x7801;&#xFF0C;&#x6240;&#x4EE5;&#x8FD9;&#x6837;&#x80AF;&#x5B9A;&#x662F;&#x4E0D;&#x597D;&#x7684;&#x3002;</li>
<li>&#x4ECE;&#x4E0A;&#x9762;&#x7B2C;&#x4E09;&#x6B65;&#x7684;&#x524D;&#x7AEF;&#x4EE3;&#x7801;&#x53EF;&#x4EE5;&#x770B;&#x51FA;&#xFF0C;&#x5982;&#x679C;&#x54CD;&#x5E94;&#x5934;&#x6709;&#x90A3;&#x4E2A;&#x8D85;&#x65F6;&#x7684;&#x5B57;&#x6BB5;<code>x-session-expired</code>&#x5B57;&#x6BB5;&#x5C31;&#x76F4;&#x63A5;&#x9000;&#x51FA;&#x767B;&#x5F55;&#xFF0C;&#x4E0D;&#x8FDB;&#x884C;&#x89E3;&#x6790;&#x54CD;&#x5E94;&#x7684;&#x6570;&#x636E;&#x4E86;&#x3002;&#x5728;&#x54CD;&#x5E94;&#x5934;&#x6CA1;&#x6709;&#x90A3;&#x4E2A;&#x5B57;&#x6BB5;&#x7684;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x624D;&#x53BB;&#x89E3;&#x6790;&#x54CD;&#x5E94;&#x7684;&#x6570;&#x636E;&#x3002;&#x5982;&#x679C;&#x524D;&#x7AEF;&#x8981;&#x5BF9;&#x54CD;&#x5E94;&#x7684;&#x6570;&#x636E;&#x8FDB;&#x884C;&#x5224;&#x65AD;&#xFF0C;&#x8FD8;&#x9700;&#x8981;&#x589E;&#x52A0;&#x989D;&#x5916;&#x7684;&#x4EE3;&#x7801;&#x53BB;&#x89E3;&#x6790;&#x54CD;&#x5E94;&#x7684;&#x6570;&#x636E;&#xFF0C;&#x5E76;&#x989D;&#x5916;&#x589E;&#x52A0;&#x903B;&#x8F91;&#x4EE3;&#x7801;&#x8FDB;&#x884C;&#x72B6;&#x6001;&#x5224;&#x65AD;&#xFF0C;&#x8FD9;&#x6837;&#x6709;&#x7684;&#x9519;&#x8BEF;&#x5728;&#x4EE3;&#x7801;&#x903B;&#x8F91;&#x91CC;&#x5224;&#x65AD;&#xFF0C;&#x6709;&#x7684;&#x9519;&#x8BEF;&#x901A;&#x8FC7;&#x72B6;&#x6001;&#x7801;&#x5224;&#x65AD;&#x663E;&#x7136;&#x662F;&#x4E0D;&#x597D;&#x7684;&#x3002;&#x5E94;&#x8BE5;&#x628A;&#x9519;&#x8BEF;&#x7EDF;&#x4E00;&#x653E;&#x5230;&#x54CD;&#x5E94;&#x7684;&#x72B6;&#x6001;&#x7801;&#x6765;&#x5904;&#x7406;&#x4F1A;&#x66F4;&#x597D;&#x4E00;&#x4E9B;&#x3002;</li>
</ul>
<h2 id="%E7%9F%A5%E8%AF%86%E8%A6%81%E7%82%B9%EF%BC%9A">&#x77E5;&#x8BC6;&#x8981;&#x70B9;&#xFF1A;</h2>
<p>&#x5173;&#x4E8E;&#x7B80;&#x5355;&#x8BF7;&#x6C42;&#x548C;&#x975E;&#x7B80;&#x5355;&#x8BF7;&#x6C42;&#x3001;&#x4EE5;&#x53CA;&#x9884;&#x68C0;&#x8BF7;&#x6C42;&#x7B49;&#x6982;&#x5FF5;&#xFF0C;&#x5EFA;&#x8BAE;&#x770B;&#x4E0B;&#x9762;&#x5217;&#x51FA;&#x7684;&#x524D;2&#x7BC7;&#x8BE6;&#x7EC6;&#x4E86;&#x89E3;&#x4E00;&#x4E0B;&#x3002;&#x5173;&#x4E8E;&#x6D4F;&#x89C8;&#x5668;&#x7684;&#x540C;&#x6E90;&#x7B56;&#x7565;&#x7B49;&#xFF0C;&#x53EF;&#x4EE5;&#x770B;&#x7B2C;3&#x7BC7;&#x8BE6;&#x7EC6;&#x4E86;&#x89E3;&#x3002;</p>
<ul>
<li><a href="https://developer.mozilla.org/zh/docs/Web/HTTP/Access_control_CORS?ref=hanhan.pro">HTTP&#x8BBF;&#x95EE;&#x63A7;&#x5236;&#xFF08;CORS&#xFF09;</a></li>
<li><a href="http://www.ruanyifeng.com/blog/2016/04/cors.html?ref=hanhan.pro">&#x8DE8;&#x57DF;&#x8D44;&#x6E90;&#x5171;&#x4EAB; CORS &#x8BE6;&#x89E3;</a></li>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy?ref=hanhan.pro">&#x6D4F;&#x89C8;&#x5668;&#x7684;&#x540C;&#x6E90;&#x7B56;&#x7565;</a></li>
<li><a href="https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials?ref=hanhan.pro">Access-Control-Allow-Credentials</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Centos linux7安装gogs及自动部署]]></title><description><![CDATA[如果你需要在自己的服务器简单方便地搭建git服务，而且只需使用基本常用的git服务，可以使用gogs。]]></description><link>http://hanhan.pro/install-gogs-in-centos-7/</link><guid isPermaLink="false">6596a4b993ef2d0001f41544</guid><category><![CDATA[gogs]]></category><category><![CDATA[git]]></category><category><![CDATA[前端]]></category><dc:creator><![CDATA[reno]]></dc:creator><pubDate>Sun, 17 Jun 2018 00:00:00 GMT</pubDate><media:content url="http://hanhan.pro/content/images/2020/02/11-linux-gogs.jpg" medium="image"/><content:encoded><![CDATA[<h4 id="%E6%88%91%E4%B8%BA%E4%BB%80%E4%B9%88%E4%BD%BF%E7%94%A8gogs%EF%BC%9F">&#x6211;&#x4E3A;&#x4EC0;&#x4E48;&#x4F7F;&#x7528;gogs&#xFF1F;</h4>
<ul>
<li>&#x9700;&#x8981;&#x5728;&#x81EA;&#x5DF1;&#x7684;&#x670D;&#x52A1;&#x5668;&#x642D;&#x5EFA;git&#x670D;&#x52A1;&#xFF1B;</li>
<li>&#x7B80;&#x5355;&#x65B9;&#x4FBF;&#x5730;&#x5B89;&#x88C5;git&#x670D;&#x52A1;&#xFF1B;</li>
<li>&#x53EA;&#x9700;&#x4F7F;&#x7528;&#x57FA;&#x672C;&#x7684;git&#x670D;&#x52A1;&#xFF1B;</li>
</ul>
<img src="http://hanhan.pro/content/images/2020/02/11-linux-gogs.jpg" alt="Centos linux7&#x5B89;&#x88C5;gogs&#x53CA;&#x81EA;&#x52A8;&#x90E8;&#x7F72;"><p>&#x5173;&#x4E8E;gogs&#x7684;&#x8BE6;&#x7EC6;&#x4ECB;&#x7ECD;&#x53EF;&#x53C2;&#x770B;<a href="https://gogs.io/docs/intro?ref=hanhan.pro">&#x5B98;&#x65B9;&#x7B80;&#x4ECB;</a>&#x3002;</p>
<h3 id="%E5%AE%89%E8%A3%85%E6%AD%A5%E9%AA%A4">&#x5B89;&#x88C5;&#x6B65;&#x9AA4;</h3>
<p>&#x672C;&#x6587;&#x4ECB;&#x7ECD;&#x6700;&#x7B80;&#x5355;&#x7684;&#x4E8C;&#x8FDB;&#x5236;&#x5B89;&#x88C5;&#x65B9;&#x5F0F;&#xFF0C;&#x4E14;&#x524D;&#x63D0;&#x662F;&#x5DF2;&#x7ECF;&#x5B89;&#x88C5;Linux&#x548C;Mysql&#x7684;&#x60C5;&#x51B5;&#x4E0B;&#x3002;&#x7B80;&#x5355;&#x6765;&#x8BF4;&#x5C31;&#x662F;&#x4E0A;&#x4F20;&#x538B;&#x7F29;&#x5305;&#x548C;&#x89E3;&#x538B;&#xFF0C;&#x7136;&#x540E;&#x542F;&#x52A8;gogs&#x670D;&#x52A1;&#x8FDB;&#x884C;&#x4E00;&#x4E9B;&#x914D;&#x7F6E;&#x5C31;&#x53EF;&#x4EE5;&#x4E86;&#xFF0C;&#x5177;&#x4F53;&#x5982;&#x4E0B;&#xFF1A;</p>
<h4 id="1-%E5%9C%A8gogs%E5%AE%98%E7%BD%91%E4%B8%8B%E8%BD%BD-64%E4%BD%8Dtargz%E5%8E%8B%E7%BC%A9%E5%8C%85-%EF%BC%8C%E5%B9%B6%E4%B8%8A%E4%BC%A0%E5%88%B0%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%9A%84-home-%EF%BC%88%E6%88%96%E8%80%85%E5%85%B6%E4%BB%96%EF%BC%89%E7%9B%AE%E5%BD%95%E4%B8%8B%EF%BC%9B">1. &#x5728;gogs&#x5B98;&#x7F51;&#x4E0B;&#x8F7D; <a href="https://dl.gogs.io/0.11.53/gogs_0.11.53_linux_amd64.tar.gz?ref=hanhan.pro">64&#x4F4D;TAR.GZ&#x538B;&#x7F29;&#x5305;</a> &#xFF0C;&#x5E76;&#x4E0A;&#x4F20;&#x5230;&#x670D;&#x52A1;&#x5668;&#x7684; <code>/home</code> &#xFF08;&#x6216;&#x8005;&#x5176;&#x4ED6;&#xFF09;&#x76EE;&#x5F55;&#x4E0B;&#xFF1B;</h4>
<!--more-->
<h4 id="2-%E5%9C%A8%E7%BB%88%E7%AB%AF%E8%BF%9B%E5%85%A5%E5%88%B0%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%9A%84-home-%E7%9B%AE%E5%BD%95%E4%B8%8B%EF%BC%8C%E8%BF%90%E8%A1%8C%E4%BB%A5%E4%B8%8B%E5%91%BD%E4%BB%A4%E8%A7%A3%E5%8E%8B%E5%88%9A%E4%B8%8A%E4%BC%A0%E7%9A%84%E6%96%87%E4%BB%B6%EF%BC%88%E6%88%96ftp%E5%B7%A5%E5%85%B7%E8%A7%A3%E5%8E%8B%E4%B9%9F%E5%8F%AF%E4%BB%A5%EF%BC%89%EF%BC%9B">2. &#x5728;&#x7EC8;&#x7AEF;&#x8FDB;&#x5165;&#x5230;&#x670D;&#x52A1;&#x5668;&#x7684; <code>/home</code> &#x76EE;&#x5F55;&#x4E0B;&#xFF0C;&#x8FD0;&#x884C;&#x4EE5;&#x4E0B;&#x547D;&#x4EE4;&#x89E3;&#x538B;&#x521A;&#x4E0A;&#x4F20;&#x7684;&#x6587;&#x4EF6;&#xFF08;&#x6216;ftp&#x5DE5;&#x5177;&#x89E3;&#x538B;&#x4E5F;&#x53EF;&#x4EE5;&#xFF09;&#xFF1B;</h4>
<pre><code class="language-bash">tar zxf gogs_0.11.53_linux_amd64.tar.gz
</code></pre>
<h4 id="3-%E5%9C%A8%E7%BB%88%E7%AB%AF%E8%BF%9B%E5%85%A5%E8%A7%A3%E5%8E%8B%E5%90%8E%E7%9A%84%E7%9B%AE%E5%BD%95%E4%BE%8B%E5%A6%82homegogs%EF%BC%8C%E5%B9%B6%E6%89%A7%E8%A1%8Cgogs-web%E5%91%BD%E4%BB%A4%E6%9D%A5%E8%BF%90%E8%A1%8Cgogs%E6%9C%8D%E5%8A%A1%EF%BC%9B">3. &#x5728;&#x7EC8;&#x7AEF;&#x8FDB;&#x5165;&#x89E3;&#x538B;&#x540E;&#x7684;&#x76EE;&#x5F55;&#x4F8B;&#x5982;<code>/home/gogs</code>&#xFF0C;&#x5E76;&#x6267;&#x884C;<code>./gogs web</code>&#x547D;&#x4EE4;&#x6765;&#x8FD0;&#x884C;gogs&#x670D;&#x52A1;&#xFF1B;</h4>
<pre><code class="language-bash">cd /home/gogs
./gogs web
</code></pre>
<p>gogs&#x9ED8;&#x8BA4;&#x4F7F;&#x7528;3000&#x7684;&#x7AEF;&#x53E3;&#xFF0C;&#x5982;&#x679C;&#x88AB;&#x5360;&#x7528;&#x5219;&#x6267;&#x884C;<code>./gogs web -port 3001</code>&#x3002;</p>
<h4 id="4-%E6%B5%8F%E8%A7%88%E5%99%A8%E8%BE%93%E5%85%A5httpyourip3000install%E6%9D%A5%E5%AE%89%E8%A3%85gogs%E7%AB%AF%E5%8F%A33000%E4%B8%BA%E5%AE%9E%E9%99%85%E4%BD%BF%E7%94%A8%E7%9A%84%E7%AB%AF%E5%8F%A3%EF%BC%8Cinstall%E4%B8%BA%E9%BB%98%E8%AE%A4%E5%AE%89%E8%A3%85%E9%A1%B5%E9%9D%A2%E7%9A%84%E8%B7%AF%E5%BE%84%EF%BC%8C%E5%9C%A8%E5%AE%89%E8%A3%85%E9%A1%B5%E9%9D%A2%E9%9C%80%E8%A6%81%E5%A1%AB%E5%86%99%E6%95%B0%E6%8D%AE%E5%BA%93%E3%80%81gogs%E7%9B%B8%E5%85%B3%E9%85%8D%E7%BD%AE%EF%BC%8C%E4%BB%A5mysql%E4%B8%BA%E4%BE%8B%EF%BC%9A">4. &#x6D4F;&#x89C8;&#x5668;&#x8F93;&#x5165;<code>http://yourip:3000/install</code>&#x6765;&#x5B89;&#x88C5;gogs(&#x7AEF;&#x53E3;3000&#x4E3A;&#x5B9E;&#x9645;&#x4F7F;&#x7528;&#x7684;&#x7AEF;&#x53E3;&#xFF0C;<code>install</code>&#x4E3A;&#x9ED8;&#x8BA4;&#x5B89;&#x88C5;&#x9875;&#x9762;&#x7684;&#x8DEF;&#x5F84;)&#xFF0C;&#x5728;&#x5B89;&#x88C5;&#x9875;&#x9762;&#x9700;&#x8981;&#x586B;&#x5199;&#x6570;&#x636E;&#x5E93;&#x3001;gogs&#x76F8;&#x5173;&#x914D;&#x7F6E;&#xFF0C;&#x4EE5;mysql&#x4E3A;&#x4F8B;&#xFF1A;</h4>
<ul>
<li>&#x4E3A;gogs&#x6DFB;&#x52A0;mysql&#x6570;&#x636E;&#x5E93;&#xFF1B;</li>
<li>&#x914D;&#x7F6E;mysql&#xFF1B;</li>
<li>&#x914D;&#x7F6E;gogs&#x76F8;&#x5173;&#x4FE1;&#x606F;&#xFF1B;</li>
<li>&#x914D;&#x7F6E;&#x5176;&#x4ED6;&#x4FE1;&#x606F;&#xFF1B;</li>
</ul>
<p>&#x5B8C;&#x6210;&#x4EE5;&#x4E0A;&#x914D;&#x7F6E;&#x5E76;&#x63D0;&#x4EA4;&#x6210;&#x529F;&#x540E;&#xFF0C;gogs&#x5C31;&#x53EF;&#x4EE5;&#x8FD0;&#x884C;&#x8D77;&#x6765;&#x4E86;&#x3002;</p>
<h4 id="5-%E5%9C%A8%E5%88%9A%E5%AE%89%E8%A3%85%E7%9A%84gogs%E8%B7%AF%E5%BE%84%E4%B8%8B%EF%BC%8C%E6%89%BE%E5%88%B0homegogsscriptssystemdgogsservice-%E8%BF%99%E4%B8%AAsystemd%E6%9C%8D%E5%8A%A1%E6%A8%A1%E7%89%88%E6%96%87%E4%BB%B6%E5%A4%8D%E5%88%B6%E4%B8%80%E4%BB%BD%E6%88%96%E4%B8%8B%E5%88%B0%E6%9C%AC%E5%9C%B0%EF%BC%9B">5. &#x5728;&#x521A;&#x5B89;&#x88C5;&#x7684;gogs&#x8DEF;&#x5F84;&#x4E0B;&#xFF0C;&#x627E;&#x5230;<code>/home/gogs/scripts/systemd/gogs.service</code> &#x8FD9;&#x4E2A;systemd&#x670D;&#x52A1;&#x6A21;&#x7248;&#x6587;&#x4EF6;&#x590D;&#x5236;&#x4E00;&#x4EFD;&#x6216;&#x4E0B;&#x5230;&#x672C;&#x5730;&#xFF1B;</h4>
<p>&#x6CE8;&#xFF1A;&#x6B64;&#x6587;&#x4EF6;&#x4E3A;Systemd&#x670D;&#x52A1;&#x6A21;&#x677F;&#x6587;&#x4EF6;&#xFF0C;&#x901A;&#x8FC7;&#x4FEE;&#x6539;&#x8BE5;&#x6587;&#x4EF6;&#x6765;&#x914D;&#x7F6E;&#x5B88;&#x62A4;&#x8FDB;&#x7A0B;&#xFF0C;&#x4EE5;&#x8BA9;gogs&#x540E;&#x53F0;&#x8FD0;&#x884C;&#xFF0C;&#x56E0;&#x4E3A;<code>./gogs web</code>&#x65B9;&#x5F0F;&#x5982;&#x679C;&#x5173;&#x95ED;&#x7EC8;&#x7AEF;&#xFF0C;gogs&#x670D;&#x52A1;&#x5C31;&#x505C;&#x4E86;&#xFF1B;</p>
<h4 id="6-%E4%BF%AE%E6%94%B9gogsservice%E6%96%87%E4%BB%B6%EF%BC%8C%E9%9C%80%E8%A6%81%E4%BF%AE%E6%94%B9%E9%87%8C%E9%9D%A2%E7%9A%84-user%E3%80%81group%E3%80%81workingdirectory%E3%80%81execstart-%E5%92%8C-environment-%E4%B8%BA%E7%9B%B8%E5%AF%B9%E5%BA%94%E7%9A%84%E5%80%BC%E3%80%82%E5%85%B6%E4%B8%AD-workingdirectory-%E4%B8%BA-gogs-%E5%AE%9E%E9%99%85%E5%AE%89%E8%A3%85%E8%B7%AF%E5%BE%84%E6%A0%B9%E7%9B%AE%E5%BD%95%E3%80%82">6. &#x4FEE;&#x6539;<code>gogs.service</code>&#x6587;&#x4EF6;&#xFF0C;&#x9700;&#x8981;&#x4FEE;&#x6539;&#x91CC;&#x9762;&#x7684; <code>User</code>&#x3001;<code>Group</code>&#x3001;<code>WorkingDirectory</code>&#x3001;<code>ExecStart</code> &#x548C; <code>Environment</code> &#x4E3A;&#x76F8;&#x5BF9;&#x5E94;&#x7684;&#x503C;&#x3002;&#x5176;&#x4E2D; <code>WorkingDirectory</code> &#x4E3A; gogs &#x5B9E;&#x9645;&#x5B89;&#x88C5;&#x8DEF;&#x5F84;&#x6839;&#x76EE;&#x5F55;&#x3002;</h4>
<pre><code class="language-bash">User=root
Group=root
Environment=USER=root HOME=/home/git
</code></pre>
<p>&#x6CE8;&#xFF1A;&#x9700;&#x8981;&#x6CE8;&#x610F;&#x914D;&#x7F6E;&#x7528;&#x6237;&#x548C;&#x7FA4;&#x7EC4;&#xFF0C;&#x914D;&#x7F6E;&#x9519;&#x8BEF;&#x4F1A;&#x5BFC;&#x81F4;&#x670D;&#x52A1;&#x542F;&#x52A8;&#x5931;&#x8D25;&#x3002;&#x672C;&#x6587;&#x4F7F;&#x7528;&#x7684;<code>User</code>&#x548C;<code>Group</code>&#x90FD;&#x662F;root&#xFF0C;&#x5EFA;&#x8BAE;&#x5355;&#x72EC;&#x521B;&#x5EFA;&#x4E00;&#x4E2A;<code>git</code>&#x7528;&#x6237;&#x3002;</p>
<h4 id="7-%E5%B0%86%E4%BF%AE%E6%94%B9%E5%A5%BD%E7%9A%84gogsservice%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0%E5%88%B0etcsystemdsystem%E4%B8%8B%EF%BC%8C%E5%B9%B6%E6%89%A7%E8%A1%8C%E4%BB%A5%E4%B8%8B%E5%91%BD%E4%BB%A4%E6%9D%A5%E6%BF%80%E6%B4%BBgogs%E3%80%82">7. &#x5C06;&#x4FEE;&#x6539;&#x597D;&#x7684;<code>gogs.service</code>&#x6587;&#x4EF6;&#x4E0A;&#x4F20;&#x5230;<code>/etc/systemd/system</code>&#x4E0B;&#xFF0C;&#x5E76;&#x6267;&#x884C;&#x4EE5;&#x4E0B;&#x547D;&#x4EE4;&#x6765;&#x6FC0;&#x6D3B;gogs&#x3002;</h4>
<pre><code class="language-bash">sudo systemctl enable gogs
</code></pre>
<h4 id="8-%E6%89%A7%E8%A1%8C%E4%BB%A5%E4%B8%8B%E5%91%BD%E4%BB%A4%E6%9D%A5%E5%90%8E%E5%8F%B0%E5%90%AF%E5%8A%A8gogs%EF%BC%8C%E5%A6%82%E6%9E%9C%E5%90%AF%E5%8A%A8%E6%88%90%E5%8A%9F%E5%88%99gogs%E5%AE%89%E8%A3%85%E5%AE%8C%E6%88%90%E3%80%82">8. &#x6267;&#x884C;&#x4EE5;&#x4E0B;&#x547D;&#x4EE4;&#x6765;&#x540E;&#x53F0;&#x542F;&#x52A8;gogs&#xFF0C;&#x5982;&#x679C;&#x542F;&#x52A8;&#x6210;&#x529F;&#x5219;gogs&#x5B89;&#x88C5;&#x5B8C;&#x6210;&#x3002;</h4>
<pre><code class="language-bash">sudo systemctl start gogs
</code></pre>
<p>&#x5982;&#x679C;&#x521A;&#x624D;&#x5DF2;&#x7ECF;&#x6267;&#x884C;<code>./gogs web</code>&#x542F;&#x52A8;&#x4E86;&#xFF0C;&#x5148;&#x9000;&#x51FA;&#x518D;&#x6267;&#x884C;&#x672C;&#x6B65;&#x9AA4;&#x3002;</p>
<h3 id="gogs%E9%85%8D%E7%BD%AE">gogs&#x914D;&#x7F6E;</h3>
<p>&#x5B89;&#x88C5;&#x5B8C;gogs&#x540E;&#xFF0C;&#x5728;&#x5B89;&#x88C5;&#x76EE;&#x5F55;&#x4E0B;&#x4F1A;&#x591A;&#x51FA;&#x6765;&#x4E00;&#x4E2A;&#x6587;&#x4EF6;&#xFF0C;&#x672C;&#x6587;&#x7684;&#x8DEF;&#x5F84;&#x662F;<code>/home/gogs/custom/conf/app.ini</code>&#xFF0C;&#x901A;&#x8FC7;&#x4FEE;&#x6539;&#x8BE5;&#x6587;&#x4EF6;&#x53EF;&#x4EE5;&#x81EA;&#x5B9A;&#x4E49;&#x914D;&#x7F6E;&#x3002;</p>
<h3 id="%E5%9F%9F%E5%90%8D%E7%BB%91%E5%AE%9A">&#x57DF;&#x540D;&#x7ED1;&#x5B9A;</h3>
<h4 id="1-%E5%8F%82%E7%85%A7%E4%BB%A5%E4%B8%8B%E9%85%8D%E7%BD%AEnginx%E5%B9%B6%E9%87%8D%E5%90%AF%EF%BC%9B">1. &#x53C2;&#x7167;&#x4EE5;&#x4E0B;&#x914D;&#x7F6E;nginx&#x5E76;&#x91CD;&#x542F;&#xFF1B;</h4>
<pre><code class="language-bash">server {
    listen 80;
    server_name git.yourdomain.com;

    location / {
        proxy_pass http://localhost:3000;
    }
}
</code></pre>
<h4 id="2-%E4%BF%AE%E6%94%B9homegogscustomconfappini%E9%87%8Cserver%E4%B8%8B%E9%9D%A2%E7%9A%84rooturl%E4%B8%BA%E4%B8%8A%E9%9D%A2nginx%E9%85%8D%E7%BD%AE%E7%9A%84%E5%9F%9F%E5%90%8D%EF%BC%8C%E5%B9%B6%E9%87%8D%60gogs%E6%9C%8D%E5%8A%A1%E5%B0%B1%E5%8F%AF%E4%BB%A5%E4%BA%86%EF%BC%9B">2. &#x4FEE;&#x6539;<code>/home/gogs/custom/conf/app.ini</code>&#x91CC;<code>[server]</code>&#x4E0B;&#x9762;&#x7684;<code>ROOT_URL</code>&#x4E3A;&#x4E0A;&#x9762;nginx&#x914D;&#x7F6E;&#x7684;&#x57DF;&#x540D;&#xFF0C;&#x5E76;&#x91CD;`gogs&#x670D;&#x52A1;&#x5C31;&#x53EF;&#x4EE5;&#x4E86;&#xFF1B;</h4>
<h3 id="%E8%87%AA%E5%8A%A8%E9%83%A8%E7%BD%B2">&#x81EA;&#x52A8;&#x90E8;&#x7F72;</h3>
<p>&#x901A;&#x8FC7;git&#x7684;&#x94A9;&#x5B50;(hook)&#x6765;&#x5B9E;&#x73B0;&#xFF1A;&#x63D0;&#x4EA4;&#x4EE3;&#x7801;&#x540E;&#xFF0C;&#x76F4;&#x63A5;&#x5C06;&#x4EE3;&#x7801;&#x66F4;&#x65B0;&#x5230;&#x4F60;&#x7684;nginx&#x76EE;&#x5F55;&#xFF0C;&#x4EE5;&#x8FBE;&#x5230;&#x81EA;&#x52A8;&#x90E8;&#x7F72;&#x3002;</p>
<h4 id="1-%E5%9C%A8gogs%E7%BD%91%E7%AB%99%E4%B8%8A%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA%E4%BB%93%E5%BA%93%EF%BC%8C%E4%BE%8B%E5%A6%82%E5%88%9B%E5%BB%BA%E5%A5%BD%E7%9A%84%E5%9C%B0%E5%9D%80%E6%98%AFhttpgityoursitecomuserbloggit%EF%BC%9B">1. &#x5728;gogs&#x7F51;&#x7AD9;&#x4E0A;&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x4ED3;&#x5E93;&#xFF0C;&#x4F8B;&#x5982;&#x521B;&#x5EFA;&#x597D;&#x7684;&#x5730;&#x5740;&#x662F;<code>http://git.yoursite.com/user/blog.git</code>&#xFF1B;</h4>
<h4 id="2-%E6%89%93%E5%BC%80%E7%BB%88%E7%AB%AF%E5%B9%B6%E6%89%A7%E8%A1%8C%E4%BB%A5%E4%B8%8B%E5%91%BD%E4%BB%A4%E6%9D%A5%E8%BF%9B%E5%85%A5%E5%88%9A%E5%88%9B%E5%BB%BA%E7%9A%84%E4%BB%93%E5%BA%93%E7%9A%84hooks%E7%9B%AE%E5%BD%95%E4%B8%8B%EF%BC%8C%E7%84%B6%E5%90%8E%E6%89%BE%E5%88%B0post-updatesample%E6%96%87%E4%BB%B6%EF%BC%8C%E5%B9%B6%E5%A4%8D%E5%88%B6%E4%B8%80%E4%BB%BD%E5%88%B0%E7%9B%B8%E5%90%8C%E7%9B%AE%E5%BD%95%E4%B8%8B%EF%BC%8C%E5%B0%86%E5%85%B6%E6%94%B9%E5%90%8D%E4%B8%BApost-update%E3%80%82">2. &#x6253;&#x5F00;&#x7EC8;&#x7AEF;&#x5E76;&#x6267;&#x884C;&#x4EE5;&#x4E0B;&#x547D;&#x4EE4;&#x6765;&#x8FDB;&#x5165;&#x521A;&#x521B;&#x5EFA;&#x7684;&#x4ED3;&#x5E93;&#x7684;<code>hooks</code>&#x76EE;&#x5F55;&#x4E0B;&#xFF0C;&#x7136;&#x540E;&#x627E;&#x5230;<code>post-update.sample</code>&#x6587;&#x4EF6;&#xFF0C;&#x5E76;&#x590D;&#x5236;&#x4E00;&#x4EFD;&#x5230;&#x76F8;&#x540C;&#x76EE;&#x5F55;&#x4E0B;&#xFF0C;&#x5C06;&#x5176;&#x6539;&#x540D;&#x4E3A;<code>post-update</code>&#x3002;</h4>
<pre><code class="language-bash">cd /home/gogs-repositories/user/blog.git/hooks
</code></pre>
<p><code>/home/gogs-repositories</code>&#x76EE;&#x5F55;&#x4E3A;<code>/home/gogs/custom/conf/app.ini</code>&#x91CC;[repository]&#x7684;<code>ROOT</code>&#x914D;&#x7F6E;&#xFF0C;&#x4E5F;&#x5C31;&#x662F;gogs&#x4ED3;&#x5E93;&#x7684;&#x6839;&#x76EE;&#x5F55;&#x3002;</p>
<h4 id="3-%E4%BF%AE%E6%94%B9post-update%E6%96%87%E4%BB%B6%E4%B8%BA%E5%A6%82%E4%B8%8B%E5%B9%B6%E4%BF%9D%E5%AD%98%EF%BC%9B">3. &#x4FEE;&#x6539;<code>post-update</code>&#x6587;&#x4EF6;&#x4E3A;&#x5982;&#x4E0B;&#x5E76;&#x4FDD;&#x5B58;&#xFF1B;</h4>
<pre><code class="language-bash">#!/bin/sh

unset GIT_DIR
DeployPath=/www/wwwroot/blog/  #&#x6B64;&#x76EE;&#x5F55;&#x4E3A;&#x670D;&#x52A1;&#x5668;&#x9875;&#x9762;&#x76EE;&#x5F55;
cd $DeployPath
git init
git remote add origin /home/gogs-repositories/user/blog.git
git clean -df
git pull origin master
</code></pre>
<p>&#x4EE5;&#x4E0A;&#x7684;&#x51E0;&#x884C;&#x547D;&#x4EE4;&#x7684;&#x610F;&#x601D;&#x662F;&#x5F85;git&#x66F4;&#x65B0;&#x5B8C;&#x6210;&#x540E;&#xFF0C;&#x5C31;&#x8FDB;&#x5165;nginx&#x7684;blog&#x5E94;&#x7528;&#x76EE;&#x5F55;&#x4E0B;&#xFF0C;&#x7136;&#x540E;&#x6E05;&#x7A7A;&#x8BE5;&#x76EE;&#x5F55;&#x5E76;&#x62C9;&#x53D6;&#x6700;&#x65B0;&#x7684;&#x4EE3;&#x7801;&#x3002;</p>
<h4 id="4-%E7%BB%88%E7%AB%AF%E6%89%A7%E8%A1%8C%E4%BB%A5%E4%B8%8B%E5%91%BD%E4%BB%A4%E4%B8%BApost-update%E6%96%87%E4%BB%B6%E8%AE%BE%E7%BD%AE%E6%89%A7%E8%A1%8C%E6%9D%83%E9%99%90%EF%BC%9B">4. &#x7EC8;&#x7AEF;&#x6267;&#x884C;&#x4EE5;&#x4E0B;&#x547D;&#x4EE4;&#x4E3A;<code>post-update</code>&#x6587;&#x4EF6;&#x8BBE;&#x7F6E;&#x6267;&#x884C;&#x6743;&#x9650;&#xFF1B;</h4>
<pre><code class="language-bash">chmod +x post-update
</code></pre>
<h4 id="5-%E4%BF%AE%E6%94%B9bloggit%E4%BB%93%E5%BA%93%E4%B8%8B%E7%9A%84%E4%BB%BB%E6%84%8F%E6%96%87%E4%BB%B6%E5%B9%B6%E6%8F%90%E4%BA%A4%E4%BB%A3%E7%A0%81%EF%BC%8C%E7%84%B6%E5%90%8E%E6%A3%80%E6%9F%A5nginx%E7%9B%AE%E5%BD%95%E4%B8%8B%E7%9A%84%E6%96%87%E4%BB%B6%EF%BC%8C%E5%BA%94%E8%AF%A5%E4%BC%9A%E6%9B%B4%E6%96%B0%E6%88%90%E5%8A%9F%EF%BC%8C%E5%88%99%E8%87%AA%E5%8A%A8%E9%83%A8%E7%BD%B2%E6%88%90%E5%8A%9F%E3%80%82">5. &#x4FEE;&#x6539;<code>blog.git</code>&#x4ED3;&#x5E93;&#x4E0B;&#x7684;&#x4EFB;&#x610F;&#x6587;&#x4EF6;&#x5E76;&#x63D0;&#x4EA4;&#x4EE3;&#x7801;&#xFF0C;&#x7136;&#x540E;&#x68C0;&#x67E5;nginx&#x76EE;&#x5F55;&#x4E0B;&#x7684;&#x6587;&#x4EF6;&#xFF0C;&#x5E94;&#x8BE5;&#x4F1A;&#x66F4;&#x65B0;&#x6210;&#x529F;&#xFF0C;&#x5219;&#x81EA;&#x52A8;&#x90E8;&#x7F72;&#x6210;&#x529F;&#x3002;</h4>
<h4 id="6-hexo%E7%9A%84%E8%87%AA%E5%8A%A8%E9%83%A8%E7%BD%B2%E9%9C%80%E4%BF%AE%E6%94%B9hexo%E6%A0%B9%E7%9B%AE%E5%BD%95%E4%B8%8Bconfigyml%E6%96%87%E4%BB%B6%E9%87%8C%E7%9A%84deploy%E9%83%A8%E5%88%86%EF%BC%9B">6. hexo&#x7684;&#x81EA;&#x52A8;&#x90E8;&#x7F72;&#x9700;&#x4FEE;&#x6539;hexo&#x6839;&#x76EE;&#x5F55;&#x4E0B;<code>_config.yml</code>&#x6587;&#x4EF6;&#x91CC;&#x7684;<code>deploy</code>&#x90E8;&#x5206;&#xFF1B;</h4>
<pre><code class="language-bash">deploy:
  type: git
  repo: http://git.yoursite.com/user/blog.git
  branch: master
</code></pre>
<p>&#x4FEE;&#x6539;<code>repo</code>&#x548C;<code>branch</code>&#x5C31;&#x53EF;&#x4EE5;&#x4E86;&#xFF0C;&#x4E00;&#x5B9A;&#x8981;&#x6CE8;&#x610F;&#x4FEE;&#x6539;<code>branch</code>&#x4E3A;&#x4F60;&#x7684;&#x6B63;&#x786E;&#x7684;branch&#xFF0C;&#x7136;&#x540E;&#x6267;&#x884C;<code>hexo d</code>&#x5E94;&#x8BE5;&#x4F1A;&#x81EA;&#x52A8;&#x90E8;&#x7F72;&#x5230;&#x521A;&#x624D;&#x8BBE;&#x7F6E;&#x7684;nginx&#x76EE;&#x5F55;&#x4E0B;&#x4E86;&#x3002;</p>
<h3 id="%E5%AE%98%E6%96%B9%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98">&#x5B98;&#x65B9;&#x5E38;&#x89C1;&#x95EE;&#x9898;</h3>
<p><a href="https://gogs.io/docs/intro/faqs?ref=hanhan.pro">https://gogs.io/docs/intro/faqs</a></p>
<h3 id="%E5%B8%B8%E7%94%A8gogs%E5%91%BD%E4%BB%A4">&#x5E38;&#x7528;gogs&#x547D;&#x4EE4;</h3>
<p>&#x505C;&#x6B62;gogs:</p>
<pre><code class="language-bash">sudo systemctl stop gogs
</code></pre>
<p>&#x542F;&#x52A8;gogs:</p>
<pre><code class="language-bash">sudo systemctl start gogs
</code></pre>
<p>&#x68C0;&#x67E5;gogs&#x8FD0;&#x884C;&#x72B6;&#x6001;:</p>
<pre><code class="language-bash">sudo systemctl status gogs -l
</code></pre>
]]></content:encoded></item><item><title><![CDATA[使用Docker部署Egg.js应用及Docker常用命令]]></title><description><![CDATA[本文内容包括：linux服务器安装Docker、使用Docker部署node.js应用、更新、Docker里连接主机的mysql数据库，以及可能用到的Docker命令。]]></description><link>http://hanhan.pro/deploy-eggjs-app-with-docker/</link><guid isPermaLink="false">6596a4b993ef2d0001f41543</guid><category><![CDATA[docker]]></category><category><![CDATA[eggjs]]></category><category><![CDATA[nodejs]]></category><category><![CDATA[前端]]></category><dc:creator><![CDATA[reno]]></dc:creator><pubDate>Wed, 06 Jun 2018 00:00:00 GMT</pubDate><media:content url="http://hanhan.pro/content/images/2020/02/10-docker-eggjs-1.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://hanhan.pro/content/images/2020/02/10-docker-eggjs-1.jpg" alt="&#x4F7F;&#x7528;Docker&#x90E8;&#x7F72;Egg.js&#x5E94;&#x7528;&#x53CA;Docker&#x5E38;&#x7528;&#x547D;&#x4EE4;"><p>&#x7F51;&#x4E0A;&#x4E5F;&#x6709;&#x4E0D;&#x5C11;&#x7C7B;&#x4F3C;&#x7684;&#x6587;&#x7AE0;&#xFF0C;&#x4F46;&#x6709;&#x7684;&#x8FC7;&#x4E8E;&#x7B80;&#x5355;&#x751A;&#x81F3;&#x6709;&#x8BEF;&#xFF0C;&#x4E0D;&#x592A;&#x9002;&#x5408;&#x65B0;&#x624B;&#x3002;&#x901A;&#x8FC7;&#x53C2;&#x770B;&#x591A;&#x7BC7;&#x6587;&#x7AE0;&#xFF0C;&#x5E76;&#x57FA;&#x4E8E;&#x4F7F;&#x7528;Docker&#x90E8;&#x7F72;egg.js&#x5E94;&#x7528;&#x7684;&#x5B9E;&#x8DF5;&#x7ECF;&#x9A8C;&#x6574;&#x7406;&#x51FA;&#x4E86;&#x672C;&#x6587;&#x3002;</p>
<h4 id="1%EF%BC%9Adocker%E7%9A%84%E5%89%8D%E7%AB%AF%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F">1&#xFF1A;Docker&#x7684;&#x524D;&#x7AEF;&#x5E94;&#x7528;&#x573A;&#x666F;&#x662F;&#x4EC0;&#x4E48;&#xFF1F;</h4>
<p>&#x6BCF;&#x4E2A;node.js&#x5E94;&#x7528;&#x9700;&#x8981;&#x653E;&#x5728;&#x4E00;&#x4E2A;&#x72EC;&#x7ACB;&#x7684;&#x73AF;&#x5883;Docker&#x5BB9;&#x5668;&#x5185;&#x8FD0;&#x884C;&#xFF0C;&#x76F8;&#x4E92;&#x9694;&#x79BB;&#xFF0C;&#x4E92;&#x4E0D;&#x5F71;&#x54CD;&#x3002;</p>
<h4 id="2%EF%BC%9Adocker%E9%83%A8%E7%BD%B2nodejs%E5%BA%94%E7%94%A8%E7%9A%84%E4%BC%98%E7%82%B9%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F">2&#xFF1A;Docker&#x90E8;&#x7F72;node.js&#x5E94;&#x7528;&#x7684;&#x4F18;&#x70B9;&#x662F;&#x4EC0;&#x4E48;&#xFF1F;</h4>
<p>&#x4F7F;&#x7528;Docker&#x5BB9;&#x5668;&#x90E8;&#x7F72;node.js&#x5FEB;&#x901F;&#x65B9;&#x4FBF;&#xFF0C;&#x7279;&#x522B;&#x662F;&#x5E94;&#x7528;&#x8F83;&#x591A;&#x65F6;&#x90E8;&#x7F72;&#x8FC1;&#x79FB;&#x7B49;&#x4F7F;&#x7528;Docker&#x4F1A;&#x66F4;&#x65B9;&#x4FBF;&#x3002;</p>
<h4 id="3%EF%BC%9A%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E4%BD%BF%E7%94%A8docker%E9%83%A8%E7%BD%B2eggjs%E5%BA%94%E7%94%A8%EF%BC%9F">3&#xFF1A;&#x4E3A;&#x4EC0;&#x4E48;&#x8981;&#x4F7F;&#x7528;Docker&#x90E8;&#x7F72;eggjs&#x5E94;&#x7528;&#xFF1F;</h4>
<p>&#x5728;&#x540C;&#x4E00;&#x53F0;&#x670D;&#x52A1;&#x5668;&#x4E0A;&#x4E0D;&#x80FD;&#x540C;&#x65F6;&#x8FD0;&#x884C;&#x591A;&#x4E2A;eggjs&#x5E94;&#x7528;&#xFF0C;&#x9664;&#x975E;&#x505C;&#x6B62;&#x53E6;&#x5916;&#x4E00;&#x4E2A;eggjs&#x5E94;&#x7528;&#x3002;</p>
<h4 id="4%EF%BC%9A%E4%BD%BF%E7%94%A8docker%E9%83%A8%E7%BD%B2nodejs%E5%BA%94%E7%94%A8%EF%BC%8C%E5%A4%A7%E4%BD%93%E7%9A%84%E6%B5%81%E7%A8%8B%E6%98%AF%E4%BB%80%E4%B9%88%E6%A0%B7%E7%9A%84%EF%BC%9F">4&#xFF1A;&#x4F7F;&#x7528;Docker&#x90E8;&#x7F72;node.js&#x5E94;&#x7528;&#xFF0C;&#x5927;&#x4F53;&#x7684;&#x6D41;&#x7A0B;&#x662F;&#x4EC0;&#x4E48;&#x6837;&#x7684;&#xFF1F;</h4>
<ol>
<li>&#x670D;&#x52A1;&#x5668;&#x5B89;&#x88C5;&#x597D;Docker</li>
<li>&#x672C;&#x5730;&#x5E94;&#x7528;&#x6839;&#x76EE;&#x5F55;&#x7F16;&#x5199;&#x597D;<code>Dockfile</code>&#x6587;&#x4EF6;</li>
<li>&#x5C06;&#x6574;&#x4E2A;&#x5E94;&#x7528;&#x4E00;&#x8D77;&#x4E0A;&#x4F20;&#x5230;&#x670D;&#x52A1;&#x5668;&#x76EE;&#x5F55;&#x4E0B;</li>
<li>&#x4F7F;&#x7528;&#x7EC8;&#x7AEF;&#x8FDE;&#x63A5;&#x670D;&#x52A1;&#x5668;&#x6267;&#x884C;&#x547D;&#x4EE4;&#x5B89;&#x88C5;Docker</li>
<li>&#x90E8;&#x7F72;&#x6210;&#x529F;</li>
</ol>
<p>&#x5177;&#x4F53;&#x7684;&#x64CD;&#x4F5C;&#x8BF7;&#x770B;&#x4E0B;&#x6587;&#x3002;</p>
<h2 id="%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%AE%89%E8%A3%85docker">&#x670D;&#x52A1;&#x5668;&#x5B89;&#x88C5;Docker</h2>
<p>&#x5982;&#x679C;&#x8981;&#x4F7F;&#x7528;Docker&#xFF0C;&#x9700;&#x4F7F;&#x7528;Centos 7.x&#x7248;&#x672C;&#x3002;Docker&#x5BF9;&#x5185;&#x6838;&#x8981;&#x6C42;&#x6BD4;&#x8F83;&#x9AD8;&#xFF0C;&#x8981;&#x5728;Centos6.5&#x53CA;&#x66F4;&#x9AD8;&#x7684;&#x7248;&#x672C;&#x7684;64&#x4F4D;&#x7CFB;&#x7EDF;&#x91CC;&#x5B89;&#x88C5;&#xFF0C;&#x7F51;&#x4E0A;&#x8BF4;6.x&#x4F7F;&#x7528;Docker&#x4F1A;&#x6709;&#x4E0D;&#x7A33;&#x5B9A;&#x60C5;&#x51B5;&#x3002;&#x672C;&#x6587;&#x5B89;&#x88C5;<code>docker ce</code>&#x7248;&#x672C;&#x3002;</p>
<h4 id="1-%E5%AE%89%E8%A3%85%E4%B8%80%E4%BA%9B%E7%B3%BB%E7%BB%9F%E4%BE%9D%E8%B5%96">1. &#x5B89;&#x88C5;&#x4E00;&#x4E9B;&#x7CFB;&#x7EDF;&#x4F9D;&#x8D56;:</h4>
<pre><code class="language-bash">sudo yum install -y yum-utils device-mapper-persistent-data lvm2
</code></pre>
<h4 id="2-%E6%B7%BB%E5%8A%A0%E8%BD%AF%E4%BB%B6%E6%BA%90%EF%BC%8C%E8%BF%99%E9%87%8C%E4%BD%BF%E7%94%A8%E9%98%BF%E9%87%8C%E7%9A%84%E6%BA%90%EF%BC%8C%E6%9B%B4%E5%BF%AB%E6%9B%B4%E7%A8%B3%E5%AE%9A">2. &#x6DFB;&#x52A0;&#x8F6F;&#x4EF6;&#x6E90;&#xFF0C;&#x8FD9;&#x91CC;&#x4F7F;&#x7528;&#x963F;&#x91CC;&#x7684;&#x6E90;&#xFF0C;&#x66F4;&#x5FEB;&#x66F4;&#x7A33;&#x5B9A;:</h4>
<pre><code class="language-bash">sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
</code></pre>
<h4 id="3-%E6%9B%B4%E6%96%B0-yum-%E8%BD%AF%E4%BB%B6%E6%BA%90%E7%BC%93%E5%AD%98%EF%BC%8C%E5%B9%B6%E5%AE%89%E8%A3%85-docker-ce">3. &#x66F4;&#x65B0; <code>yum</code> &#x8F6F;&#x4EF6;&#x6E90;&#x7F13;&#x5B58;&#xFF0C;&#x5E76;&#x5B89;&#x88C5; <code>docker-ce</code>:</h4>
<pre><code class="language-bash">sudo yum makecache fast
sudo yum install docker-ce
</code></pre>
<h4 id="4-%E5%90%AF%E5%8A%A8docker-ce">4. &#x542F;&#x52A8;<code>docker-ce</code>:</h4>
<pre><code class="language-bash">sudo systemctl enable docker
sudo systemctl start docker
</code></pre>
<h4 id="5-%E6%9F%A5%E7%9C%8Bdocker%E7%89%88%E6%9C%AC%EF%BC%9A">5. &#x67E5;&#x770B;Docker&#x7248;&#x672C;&#xFF1A;</h4>
<pre><code class="language-bash">docker -v
</code></pre>
<p>&#x672C;&#x4EBA;&#x5728;Centos 7.2&#x4E0A;&#x5B89;&#x88C5;&#x7684;Docker&#x7248;&#x672C;&#x4E3A;18.05.0-ce&#x3002;</p>
<p>&#x5173;&#x4E8E;<code>docker</code>&#x7684;&#x4F7F;&#x7528;&#x7B49;&#x53EF;&#x67E5;&#x770B; <a href="https://yeasy.gitbooks.io/docker_practice/container/run.html?ref=hanhan.pro">&#x975E;&#x5B98;&#x65B9;docker&#x4E2D;&#x6587;&#x7248;&#x6587;&#x6863;</a>&#x3002;</p>
<h2 id="%E9%83%A8%E7%BD%B2nodejs%E5%BA%94%E7%94%A8%E5%88%B0%E6%9C%8D%E5%8A%A1%E5%99%A8">&#x90E8;&#x7F72;node.js&#x5E94;&#x7528;&#x5230;&#x670D;&#x52A1;&#x5668;</h2>
<h4 id="1-eggjs%E5%BA%94%E7%94%A8%E9%9C%80%E8%A6%81%E4%BF%AE%E6%94%B9%E6%A0%B9%E7%9B%AE%E5%BD%95%E4%B8%8B%E7%9A%84packagejson%EF%BC%88%E6%99%AE%E9%80%9Anodejs%E5%BA%94%E7%94%A8%E5%8F%AF%E5%BF%BD%E7%95%A5%E8%BF%99%E4%B8%80%E6%AD%A5%EF%BC%89%EF%BC%9A%E5%B0%86start%E8%BF%99%E8%A1%8C%E9%87%8C%E5%91%BD%E4%BB%A4%E9%87%8C%E7%9A%84daemon%E5%8E%BB%E6%8E%89%EF%BC%8C%E5%8D%B3%E5%90%AF%E5%8A%A8eggjs%E4%BD%BF%E7%94%A8egg-scripts-start%E5%B0%B1%E5%A5%BD%E4%BA%86%E3%80%82%E5%9C%A8docker%E9%87%8Ceggjs%E5%BA%94%E7%94%A8%E8%A6%81%E5%9C%A8%E5%89%8D%E5%8F%B0%E8%BF%90%E8%A1%8C%E3%80%82">1. egg.js&#x5E94;&#x7528;&#x9700;&#x8981;&#x4FEE;&#x6539;&#x6839;&#x76EE;&#x5F55;&#x4E0B;&#x7684;package.json&#xFF08;&#x666E;&#x901A;node.js&#x5E94;&#x7528;&#x53EF;&#x5FFD;&#x7565;&#x8FD9;&#x4E00;&#x6B65;&#xFF09;&#xFF1A;&#x5C06;<code>start</code>&#x8FD9;&#x884C;&#x91CC;&#x547D;&#x4EE4;&#x91CC;&#x7684;<code> --daemon</code>&#x53BB;&#x6389;&#xFF0C;&#x5373;&#x542F;&#x52A8;eggjs&#x4F7F;&#x7528;<code>egg-scripts start</code>&#x5C31;&#x597D;&#x4E86;&#x3002;&#x5728;Docker&#x91CC;eggjs&#x5E94;&#x7528;&#x8981;&#x5728;&#x524D;&#x53F0;&#x8FD0;&#x884C;&#x3002;</h4>
<h4 id="2-%E5%9C%A8%E6%9C%AC%E5%9C%B0%E5%BA%94%E7%94%A8%E7%9A%84%E6%A0%B9%E7%9B%AE%E5%BD%95%E4%B8%8Bpackagejson%E6%89%80%E5%9C%A8%E7%9B%AE%E5%BD%95%E6%96%B0%E5%BB%BA%E4%B8%80%E4%B8%AA%E5%90%8D%E4%B8%BAdockerfile%E7%9A%84%E6%96%87%E4%BB%B6%EF%BC%88%E6%97%A0%E5%90%8E%E7%BC%80%EF%BC%89%EF%BC%8C%E5%B0%86%E4%BB%A5%E4%B8%8B%E5%86%85%E5%AE%B9%E5%A4%8D%E5%88%B6%E5%88%B0%E6%96%87%E4%BB%B6%E9%87%8C%EF%BC%8C%E5%B9%B6%E5%B0%86usrsrcnode-appkoa-server%E5%85%A8%E9%83%A8%E6%9B%BF%E6%8D%A2%E4%B8%BA%E4%BD%A0%E6%83%B3%E8%AE%BE%E7%BD%AE%E7%9A%84%E8%B7%AF%E5%BE%84%EF%BC%88%E8%AF%A5%E8%B7%AF%E5%BE%84%E4%B8%BAdocker%E5%AE%B9%E5%99%A8%E9%87%8C%E7%9A%84%E8%B7%AF%E5%BE%84%EF%BC%8C%E5%8F%AF%E8%87%AA%E8%A1%8C%E8%AE%BE%E7%BD%AE%EF%BC%89%EF%BC%9A">2. &#x5728;&#x672C;&#x5730;&#x5E94;&#x7528;&#x7684;&#x6839;&#x76EE;&#x5F55;&#x4E0B;(package.json&#x6240;&#x5728;&#x76EE;&#x5F55;)&#x65B0;&#x5EFA;&#x4E00;&#x4E2A;&#x540D;&#x4E3A;<code>Dockerfile</code>&#x7684;&#x6587;&#x4EF6;&#xFF08;&#x65E0;&#x540E;&#x7F00;&#xFF09;&#xFF0C;&#x5C06;&#x4EE5;&#x4E0B;&#x5185;&#x5BB9;&#x590D;&#x5236;&#x5230;&#x6587;&#x4EF6;&#x91CC;&#xFF0C;&#x5E76;&#x5C06;<code>/usr/src/node-app/koa-server</code>&#x5168;&#x90E8;&#x66FF;&#x6362;&#x4E3A;&#x4F60;&#x60F3;&#x8BBE;&#x7F6E;&#x7684;&#x8DEF;&#x5F84;&#xFF08;&#x8BE5;&#x8DEF;&#x5F84;&#x4E3A;docker&#x5BB9;&#x5668;&#x91CC;&#x7684;&#x8DEF;&#x5F84;&#xFF0C;&#x53EF;&#x81EA;&#x884C;&#x8BBE;&#x7F6E;&#xFF09;&#xFF1A;</h4>
<pre><code class="language-bash"># &#x8BBE;&#x7F6E;&#x57FA;&#x7840;&#x955C;&#x50CF;,&#x5982;&#x679C;&#x672C;&#x5730;&#x6CA1;&#x6709;&#x8BE5;&#x955C;&#x50CF;&#xFF0C;&#x4F1A;&#x4ECE;Docker.io&#x670D;&#x52A1;&#x5668;pull&#x955C;&#x50CF;
FROM node:8.6.0-alpine

# &#x8BBE;&#x7F6E;&#x65F6;&#x533A;
RUN apk --update add tzdata \
    &amp;&amp; cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    &amp;&amp; echo &quot;Asia/Shanghai&quot; &gt; /etc/timezone \
    &amp;&amp; apk del tzdata

# &#x521B;&#x5EFA;app&#x76EE;&#x5F55;
RUN mkdir -p /usr/src/node-app/koa-server

# &#x8BBE;&#x7F6E;&#x5DE5;&#x4F5C;&#x76EE;&#x5F55;
WORKDIR /usr/src/node-app/koa-server

# &#x62F7;&#x8D1D;package.json&#x6587;&#x4EF6;&#x5230;&#x5DE5;&#x4F5C;&#x76EE;&#x5F55;
# !!&#x91CD;&#x8981;&#xFF1A;package.json&#x9700;&#x8981;&#x5355;&#x72EC;&#x6DFB;&#x52A0;&#x3002;
# Docker&#x5728;&#x6784;&#x5EFA;&#x955C;&#x50CF;&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x662F;&#x4E00;&#x5C42;&#x4E00;&#x5C42;&#x6784;&#x5EFA;&#x7684;&#xFF0C;&#x4EC5;&#x5F53;&#x8FD9;&#x4E00;&#x5C42;&#x6709;&#x53D8;&#x5316;&#x65F6;&#xFF0C;&#x91CD;&#x65B0;&#x6784;&#x5EFA;&#x5BF9;&#x5E94;&#x7684;&#x5C42;&#x3002;
# &#x5982;&#x679C;package.json&#x548C;&#x6E90;&#x4EE3;&#x7801;&#x4E00;&#x8D77;&#x6DFB;&#x52A0;&#x5230;&#x955C;&#x50CF;&#xFF0C;&#x5219;&#x6BCF;&#x6B21;&#x4FEE;&#x6539;&#x6E90;&#x7801;&#x90FD;&#x9700;&#x8981;&#x91CD;&#x65B0;&#x5B89;&#x88C5;npm&#x6A21;&#x5757;&#xFF0C;&#x8FD9;&#x6837;&#x6728;&#x6709;&#x5FC5;&#x8981;&#x3002;
# &#x6240;&#x4EE5;&#xFF0C;&#x6B63;&#x786E;&#x7684;&#x987A;&#x5E8F;&#x662F;: &#x6DFB;&#x52A0;package.json&#xFF1B;&#x5B89;&#x88C5;npm&#x6A21;&#x5757;&#xFF1B;&#x6DFB;&#x52A0;&#x6E90;&#x4EE3;&#x7801;&#x3002;
COPY package.json /usr/src/node-app/koa-server/package.json

# &#x5B89;&#x88C5;npm&#x4F9D;&#x8D56;(&#x4F7F;&#x7528;&#x6DD8;&#x5B9D;&#x7684;&#x955C;&#x50CF;&#x6E90;)
# &#x5982;&#x679C;&#x4F7F;&#x7528;&#x7684;&#x5883;&#x5916;&#x670D;&#x52A1;&#x5668;&#xFF0C;&#x65E0;&#x9700;&#x4F7F;&#x7528;&#x6DD8;&#x5B9D;&#x7684;&#x955C;&#x50CF;&#x6E90;&#xFF0C;&#x5373;&#x6539;&#x4E3A;`RUN npm i`&#x3002;
RUN npm i --registry=https://registry.npm.taobao.org

# &#x62F7;&#x8D1D;&#x6240;&#x6709;&#x6E90;&#x4EE3;&#x7801;&#x5230;&#x5DE5;&#x4F5C;&#x76EE;&#x5F55;
COPY . /usr/src/node-app/koa-server

# &#x66B4;&#x9732;&#x5BB9;&#x5668;&#x7AEF;&#x53E3;
EXPOSE 9002

# &#x542F;&#x52A8;node&#x5E94;&#x7528;
CMD npm start
</code></pre>
<p>&#x4E0A;&#x9762;&#x7684;&#x6CE8;&#x91CA;&#x4E00;&#x76EE;&#x4E86;&#x7136;&#x3002;&#x6574;&#x4E2A;&#x8FC7;&#x7A0B;&#x7B80;&#x5355;&#x63CF;&#x8FF0;&#x5C31;&#x662F;&#xFF1A;1.&#x62C9;&#x53D6;docker&#x955C;&#x50CF;&#xFF08;&#x5E76;&#x8BBE;&#x7F6E;&#x65F6;&#x533A;&#x7B49;&#xFF09;&#xFF1B;2.&#x521B;&#x5EFA;docker&#x5DE5;&#x4F5C;&#x76EE;&#x5F55;&#xFF0C;&#x5E76;&#x5C06;package.json&#x62F7;&#x8D1D;&#x5230;docker&#x91CC;&#xFF1B;3.&#x5B89;&#x88C5;npm&#x4F9D;&#x8D56;&#xFF1B;4.&#x5C06;&#x670D;&#x52A1;&#x5668;&#x4E0A;&#x7684;&#x5E94;&#x7528;&#x62F7;&#x8D1D;&#x5230;docker&#x91CC;&#xFF1B;5.&#x66B4;&#x9732;docker&#x5BB9;&#x5668;&#x7684;&#x7AEF;&#x53E3;&#xFF0C;&#x7136;&#x540E;&#x542F;&#x52A8;node&#x5E94;&#x7528;&#x3002;</p>
<h4 id="3-%E4%BD%BF%E7%94%A8ftp%E5%B7%A5%E5%85%B7%E6%88%96git%E5%B7%A5%E5%85%B7%E5%B0%86%E6%95%B4%E4%B8%AA%E5%BA%94%E7%94%A8%E4%B8%8A%E4%BC%A0%E5%88%B0%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83%E6%9C%8D%E5%8A%A1%E5%99%A8%EF%BC%8C%E5%B9%B6%E4%BD%BF%E7%94%A8%E7%BB%88%E7%AB%AF%E8%BF%9E%E6%8E%A5%E5%88%B0%E6%9C%8D%E5%8A%A1%E5%99%A8%EF%BC%8C%E8%BF%9B%E5%85%A5%E5%88%B0%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%BA%94%E7%94%A8%E7%9A%84%E7%9B%AE%E5%BD%95%E4%B8%8B%EF%BC%9B%EF%BC%88%E8%BF%87%E7%A8%8B%E7%95%A5%EF%BC%89">3. &#x4F7F;&#x7528;ftp&#x5DE5;&#x5177;&#x6216;git&#x5DE5;&#x5177;&#x5C06;&#x6574;&#x4E2A;&#x5E94;&#x7528;&#x4E0A;&#x4F20;&#x5230;&#x751F;&#x4EA7;&#x73AF;&#x5883;&#x670D;&#x52A1;&#x5668;&#xFF0C;&#x5E76;&#x4F7F;&#x7528;&#x7EC8;&#x7AEF;&#x8FDE;&#x63A5;&#x5230;&#x670D;&#x52A1;&#x5668;&#xFF0C;&#x8FDB;&#x5165;&#x5230;&#x670D;&#x52A1;&#x5668;&#x5E94;&#x7528;&#x7684;&#x76EE;&#x5F55;&#x4E0B;&#xFF1B;&#xFF08;&#x8FC7;&#x7A0B;&#x7565;&#xFF09;</h4>
<h4 id="4-%E6%89%A7%E8%A1%8C%E4%BB%A5%E4%B8%8B%E5%91%BD%E4%BB%A4%EF%BC%8C%E5%AE%89%E8%A3%85docker%E9%95%9C%E5%83%8F%EF%BC%9B">4. &#x6267;&#x884C;&#x4EE5;&#x4E0B;&#x547D;&#x4EE4;&#xFF0C;&#x5B89;&#x88C5;docker&#x955C;&#x50CF;&#xFF1B;</h4>
<pre><code class="language-bash">sudo docker build -t node/koa-server .
</code></pre>
<p><code>-t</code>&#x662F;&#x5BF9;&#x8BE5;&#x955C;&#x50CF;&#x8FDB;&#x884C;tag&#x6807;&#x8BC6;&#xFF0C;&#x6807;&#x8BC6;&#x7684;&#x540D;&#x5B57;&#x4E3A;<code>node/koa-server</code>&#xFF0C;&#x53EF;&#x4EE5;&#x81EA;&#x5B9A;&#x4E49;&#x8FD9;&#x4E2A;&#x540D;&#x5B57;&#x3002;&#x955C;&#x50CF;&#x7684;&#x6784;&#x5EFA;&#x8FC7;&#x7A0B;&#x4F9D;&#x8D56;&#x4E8E;&#x7F51;&#x901F;&#xFF0C;&#x6574;&#x4F53;&#x8FD8;&#x6BD4;&#x8F83;&#x5FEB;&#x3002;npm&#x4F9D;&#x8D56;&#x53EF;&#x80FD;&#x4F1A;&#x4E45;&#x4E00;&#x4E9B;&#xFF0C;&#x56E0;&#x4E3A;egg.js&#x7684;&#x4F9D;&#x8D56;&#x6BD4;&#x8F83;&#x591A;&#x3002;&#x5982;&#x679C;&#x6240;&#x6709;&#x6B65;&#x9AA4;&#x6267;&#x884C;&#x5B8C;&#xFF0C;&#x4F1A;&#x6709;success&#x7684;&#x63D0;&#x793A;&#xFF0C;&#x5B89;&#x88C5;&#x6210;&#x529F;&#x4E86;&#x3002;</p>
<h4 id="5-%E6%89%A7%E8%A1%8C%E4%BB%A5%E4%B8%8B%E5%91%BD%E4%BB%A4%EF%BC%8C%E4%BD%BF%E7%94%A8%E5%88%9A%E5%88%9B%E5%BB%BA%E5%A5%BD%E7%9A%84%E9%95%9C%E5%83%8F%E6%9D%A5%E5%90%AF%E5%8A%A8%E4%B8%80%E4%B8%AA%E5%AE%B9%E5%99%A8%EF%BC%9B">5. &#x6267;&#x884C;&#x4EE5;&#x4E0B;&#x547D;&#x4EE4;&#xFF0C;&#x4F7F;&#x7528;&#x521A;&#x521B;&#x5EFA;&#x597D;&#x7684;&#x955C;&#x50CF;&#x6765;&#x542F;&#x52A8;&#x4E00;&#x4E2A;&#x5BB9;&#x5668;&#xFF1B;</h4>
<pre><code class="language-bash"># &#x666E;&#x901A;node.js&#x5E94;&#x7528;
sudo docker run -d --name koa-server -p 9002:9002 node/koa-server
</code></pre>
<p><code>-d</code>&#x4E3A;&#x540E;&#x53F0;&#x8FD0;&#x884C;&#x5BB9;&#x5668;&#x3002;&#x5982;&#x679C;&#x666E;&#x901A;node.js&#x5E94;&#x7528;&#x4F7F;&#x7528;&#x4EE5;&#x4E0A;&#x547D;&#x4EE4;&#xFF0C;&#x5BB9;&#x5668;&#x4F7F;&#x7528;9002&#x7AEF;&#x53E3;&#xFF0C;&#x4E0E;Dockerfile&#x91CC;&#x9762;&#x7684;&#x4E00;&#x81F4;&#x3002;</p>
<pre><code class="language-bash"># eggjs&#x5E94;&#x7528;
sudo docker run -d --net=host --name koa-server node/koa-server
</code></pre>
<p>eggjs&#x5E94;&#x7528;&#x9700;&#x8981;&#x6267;&#x884C;&#x4EE5;&#x4E0A;&#x547D;&#x4EE4;&#xFF0C;&#x5373;&#x589E;&#x52A0;&#x4E86;<code> --net=host</code>&#xFF0C;&#x8BE5;&#x53C2;&#x6570;&#x8868;&#x793A;&#x4F7F;&#x7528;host&#x7F51;&#x7EDC;&#x6A21;&#x5F0F;&#x4E0E;&#x4E3B;&#x673A;&#x5171;&#x4EAB;&#x7F51;&#x7EDC;&#x6765;&#x8FDE;&#x63A5;mysql&#x6570;&#x636E;&#x5E93;&#xFF1B;(&#x6682;&#x65F6;&#x4F7F;&#x7528;&#x8FD9;&#x79CD;&#x6A21;&#x5F0F;&#x6210;&#x529F;&#x4E86;&#xFF0C;&#x540E;&#x7EED;&#x7814;&#x7A76;&#x5176;&#x4ED6;&#x66F4;&#x597D;&#x65B9;&#x6848;)&#x3002;</p>
<h4 id="6-%E6%89%A7%E8%A1%8C%E4%BB%A5%E4%B8%8B%E5%91%BD%E4%BB%A4%E6%9F%A5%E7%9C%8B%E5%AE%B9%E5%99%A8%E6%98%AF%E5%90%A6%E5%90%AF%E5%8A%A8%E6%88%90%E5%8A%9F%EF%BC%9B">6. &#x6267;&#x884C;&#x4EE5;&#x4E0B;&#x547D;&#x4EE4;&#x67E5;&#x770B;&#x5BB9;&#x5668;&#x662F;&#x5426;&#x542F;&#x52A8;&#x6210;&#x529F;&#xFF1B;</h4>
<pre><code class="language-bash">docker ps
</code></pre>
<p>&#x4EE5;&#x4E0A;&#x547D;&#x4EE4;&#x662F;&#x67E5;&#x770B;&#x8FD0;&#x884C;&#x4E2D;&#x7684;&#x5BB9;&#x5668;&#x3002;&#x5982;&#x679C;&#x521A;&#x624D;&#x542F;&#x52A8;&#x6210;&#x529F;&#xFF0C;&#x5219;&#x4F1A;&#x663E;&#x793A;&#x51FA;&#x6765;&#x3002;</p>
<pre><code class="language-bash">curl -i localhost:9002
</code></pre>
<p>&#x4E5F;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;curl&#x547D;&#x4EE4;&#x6216;&#x8005;&#x5230;&#x6D4F;&#x89C8;&#x5668;&#x91CC;&#x8F93;&#x5165;&#x5E94;&#x7528;&#x7684;&#x8BBF;&#x95EE;&#x5730;&#x5740;&#xFF0C;&#x6765;&#x67E5;&#x770B;&#x80FD;&#x5426;&#x8BBF;&#x95EE;&#x5E94;&#x7528;&#xFF0C;&#x5982;&#x679C;&#x53EF;&#x4EE5;&#x5219;&#x5B89;&#x88C5;&#x6210;&#x529F;&#x3002;</p>
<pre><code class="language-bash">docker logs containerId
</code></pre>
<p>&#x5982;&#x679C;&#x521A;&#x624D;&#x6267;&#x884C;<code>docker ps</code>&#x6CA1;&#x6709;&#x770B;&#x5230;&#x521A;&#x521A;&#x542F;&#x52A8;&#x7684;&#x5BB9;&#x5668;&#xFF0C;&#x8BF4;&#x660E;&#x542F;&#x52A8;&#x5931;&#x8D25;&#xFF0C;&#x4F7F;&#x7528;&#x8BE5;&#x547D;&#x4EE4;&#x6765;&#x67E5;&#x770B;&#x542F;&#x52A8;&#x7684;&#x5177;&#x4F53;&#x60C5;&#x51B5;&#x3002;</p>
<h4 id="7-docker%E5%AE%B9%E5%99%A8%E9%87%8Ceggjs%E8%BF%9E%E6%8E%A5mysql%EF%BC%9A">7. docker&#x5BB9;&#x5668;&#x91CC;eggjs&#x8FDE;&#x63A5;mysql&#xFF1A;</h4>
<p>&#x53EA;&#x9700;&#x8981;&#x6839;&#x636E;&#x60C5;&#x51B5;&#x4FEE;&#x6539;&#x6570;&#x636E;&#x5E93;&#x76F8;&#x5173;&#x4FE1;&#x606F;&#x5373;&#x53EF;&#xFF0C;&#x5728;host&#x7F51;&#x7EDC;&#x6A21;&#x5F0F;&#x4E0B;&#xFF0C;&#x5BB9;&#x5668;&#x91CC;eggjs&#x7684;mysql&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x91CC;&#x7684;host&#x4ECD;&#x53EF;&#x8BBE;&#x7F6E;&#x4E3A;<code>localhost</code>&#x3002;</p>
<h2 id="%E6%9B%B4%E6%96%B0docker%E9%87%8C%E7%9A%84nodejs%E5%BA%94%E7%94%A8">&#x66F4;&#x65B0;docker&#x91CC;&#x7684;node.js&#x5E94;&#x7528;</h2>
<h4 id="1-%E9%80%9A%E8%BF%87%E6%9F%A5%E7%9C%8B%E5%AE%B9%E5%99%A8%E5%88%97%E8%A1%A8%EF%BC%8C%E6%89%BE%E5%88%B0%E9%9C%80%E8%A6%81%E5%81%9C%E6%AD%A2%E7%9A%84%E5%AE%B9%E5%99%A8id%EF%BC%9B">1. &#x901A;&#x8FC7;&#x67E5;&#x770B;&#x5BB9;&#x5668;&#x5217;&#x8868;&#xFF0C;&#x627E;&#x5230;&#x9700;&#x8981;&#x505C;&#x6B62;&#x7684;&#x5BB9;&#x5668;ID&#xFF1B;</h4>
<pre><code class="language-bash">docker ps
</code></pre>
<h4 id="2-%E5%81%9C%E6%AD%A2%E5%AE%B9%E5%99%A8%EF%BC%9B">2. &#x505C;&#x6B62;&#x5BB9;&#x5668;&#xFF1B;</h4>
<pre><code class="language-bash">sudo docker stop containerId
</code></pre>
<h4 id="3-%E5%88%A0%E9%99%A4%E5%AE%B9%E5%99%A8%EF%BC%9B">3. &#x5220;&#x9664;&#x5BB9;&#x5668;&#xFF1B;</h4>
<pre><code class="language-bash">sudo docker rm containerId
</code></pre>
<h4 id="4-%E5%88%A0%E9%99%A4%E9%95%9C%E5%83%8F%EF%BC%9B">4. &#x5220;&#x9664;&#x955C;&#x50CF;&#xFF1B;</h4>
<pre><code class="language-bash"># &#x6B63;&#x5E38;&#x60C5;&#x51B5;&#x53EF;&#x4EE5;&#x5220;&#x9664;
sudo docker rmi imageId
# &#x63D0;&#x793A;&#x65E0;&#x6CD5;&#x5220;&#x9664;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x5F3A;&#x5236;&#x5220;&#x9664;
sudo docker rmi -f imageId
</code></pre>
<h4 id="5-%E5%B0%86%E6%9C%AC%E5%9C%B0%E5%BA%94%E7%94%A8%E4%BB%A3%E7%A0%81%E6%9B%B4%E6%96%B0%E5%88%B0%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%9B%AE%E5%BD%95%E4%B8%8B%E3%80%82">5. &#x5C06;&#x672C;&#x5730;&#x5E94;&#x7528;&#x4EE3;&#x7801;&#x66F4;&#x65B0;&#x5230;&#x670D;&#x52A1;&#x5668;&#x76EE;&#x5F55;&#x4E0B;&#x3002;</h4>
<h4 id="6-%E6%8C%89%E7%85%A7%E4%B8%8A%E9%9D%A2%E7%9A%84%E6%AD%A5%E9%AA%A4%E9%87%8D%E6%96%B0%E6%9E%84%E5%BB%BA%E9%95%9C%E5%83%8F%E5%92%8C%E5%90%AF%E5%8A%A8%E5%AE%B9%E5%99%A8%E3%80%82">6. &#x6309;&#x7167;&#x4E0A;&#x9762;&#x7684;&#x6B65;&#x9AA4;&#x91CD;&#x65B0;&#x6784;&#x5EFA;&#x955C;&#x50CF;&#x548C;&#x542F;&#x52A8;&#x5BB9;&#x5668;&#x3002;</h4>
<h2 id="%E9%87%8D%E7%82%B9%E6%80%BB%E7%BB%93">&#x91CD;&#x70B9;&#x603B;&#x7ED3;</h2>
<ol>
<li>&#x4F7F;&#x7528;Centos 7.x&#x7248;&#x672C;&#x5B89;&#x88C5;docker&#x3002;</li>
<li><code> --daemon</code>&#x8981;&#x53BB;&#x6389;&#xFF0C;&#x8BA9;eggjs&#x5E94;&#x7528;&#x76F4;&#x63A5;&#x524D;&#x53F0;&#x8FD0;&#x884C;&#x3002;</li>
<li>Dockerfile&#x91CC;&#x5148;&#x62F7;&#x8D1D;package.json&#xFF0C;&#x5B89;&#x88C5;npm&#x4F9D;&#x8D56;&#x540E;&#xFF0C;&#x518D;&#x62F7;&#x8D1D;&#x5E94;&#x7528;&#x7684;&#x4EE3;&#x7801;&#x3002;</li>
<li>&#x4F7F;&#x7528;&#x5883;&#x5916;&#x670D;&#x52A1;&#x5668;&#x5219;&#x4E0D;&#x9700;&#x8981;&#x4F7F;&#x7528;&#x6DD8;&#x5B9D;&#x7684;npm&#x955C;&#x50CF;&#x6E90;&#x3002;</li>
</ol>
<h2 id="%E5%8F%AF%E8%83%BD%E5%87%BA%E7%8E%B0%E7%9A%84%E9%97%AE%E9%A2%98">&#x53EF;&#x80FD;&#x51FA;&#x73B0;&#x7684;&#x95EE;&#x9898;</h2>
<ol>
<li>npm&#x5B89;&#x88C5;&#x5931;&#x8D25;&#xFF1A;&#x53EF;&#x80FD;&#x662F;&#x955C;&#x50CF;&#x6E90;&#x7684;&#x95EE;&#x9898;&#xFF0C;&#x9700;&#x8981;&#x5220;&#x9664;&#x955C;&#x50CF;&#x91CD;&#x65B0;&#x6784;&#x5EFA;&#x955C;&#x50CF;&#x3002;</li>
<li>&#x955C;&#x50CF;&#x65E0;&#x6CD5;&#x5220;&#x9664;&#xFF1A;&#x9700;&#x8981;&#x5148;&#x505C;&#x6B62;&#x548C;&#x5220;&#x9664;&#x5BB9;&#x5668;&#x3002;</li>
</ol>
<h2 id="%E5%85%B6%E4%BB%96%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4">&#x5176;&#x4ED6;&#x5E38;&#x7528;&#x547D;&#x4EE4;</h2>
<h4 id="%E9%95%9C%E5%83%8F%E7%9B%B8%E5%85%B3%EF%BC%9A">&#x955C;&#x50CF;&#x76F8;&#x5173;&#xFF1A;</h4>
<p>&#x67E5;&#x770B;&#x955C;&#x50CF;&#x6784;&#x5EFA;&#x5DE5;&#x7A0B;</p>
<pre><code class="language-bash">sudo docker history node/koa-server
</code></pre>
<p>&#x6BD4;&#x5982;&#x4E0A;&#x9762;&#x6211;&#x4EEC;&#x6784;&#x5EFA;<code>node/koa-server</code>&#x8FD9;&#x4E2A;&#x955C;&#x50CF;&#x540E;&#xFF0C;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x8FD9;&#x4E2A;&#x547D;&#x4EE4;&#x6765;&#x67E5;&#x770B;&#x8BE5;&#x955C;&#x50CF;&#x7684;&#x6784;&#x5EFA;&#x8FC7;&#x7A0B;&#xFF0C;&#x6765;&#x53D1;&#x73B0;&#x95EE;&#x9898;&#x3002;</p>
<p>&#x67E5;&#x770B;&#x6240;&#x6709;&#x955C;&#x50CF;&#x5217;&#x8868;</p>
<pre><code class="language-bash">docker images
</code></pre>
<p>&#x5220;&#x9664;&#x955C;&#x50CF;</p>
<pre><code class="language-bash">sudo docker rmi imageId
sudo docker rmi -f imageId
</code></pre>
<p>&#x5148;&#x67E5;&#x770B;&#x955C;&#x50CF;&#x5217;&#x8868;&#xFF0C;&#x627E;&#x5230;&#x8981;&#x5220;&#x9664;&#x7684;&#x955C;&#x50CF;ID&#xFF0C;&#x7136;&#x540E;&#x4F7F;&#x7528;&#x8BE5;&#x547D;&#x4EE4;&#x5220;&#x9664;&#x3002;<code>-f</code>&#x4E3A;&#x5F3A;&#x5236;&#x5220;&#x9664;&#x3002;</p>
<h4 id="%E5%AE%B9%E5%99%A8%E7%9B%B8%E5%85%B3%EF%BC%9A">&#x5BB9;&#x5668;&#x76F8;&#x5173;&#xFF1A;</h4>
<p>&#x67E5;&#x770B;&#x6240;&#x6709;&#x5BB9;&#x5668;&#x5217;&#x8868;</p>
<pre><code class="language-bash">docker ps
</code></pre>
<p>&#x67E5;&#x770B;&#x67D0;&#x4E2A;&#x5BB9;&#x5668;&#x7684;&#x4FE1;&#x606F;</p>
<pre><code class="language-bash">docker logs containerId
</code></pre>
<p>&#x5148;&#x67E5;&#x770B;&#x5BB9;&#x5668;&#x5217;&#x8868;&#xFF0C;&#x627E;&#x5230;&#x8981;&#x67E5;&#x770B;&#x5BB9;&#x5668;&#x7684;ID&#xFF0C;&#x7136;&#x540E;&#x4F7F;&#x7528;&#x8BE5;&#x547D;&#x4EE4;&#x67E5;&#x770B;&#x3002;</p>
<p>&#x62F7;&#x8D1D;&#x4E3B;&#x673A;&#x7684;&#x6587;&#x4EF6;&#x5230;&#x5BB9;&#x5668;&#x7684;&#x76EE;&#x5F55;&#x4E0B;</p>
<pre><code class="language-bash">docker cp src/. mycontainer:/target
</code></pre>
<p><code>src</code>&#x4E3A;&#x8981;&#x62F7;&#x8D1D;&#x7684;&#x76EE;&#x5F55;&#x540D;&#xFF0C;<code>mycontainer</code>&#x4E3A;&#x5BB9;&#x5668;&#x7684;id&#xFF0C;<code>target</code>&#x4E3A;&#x76EE;&#x6807;&#x76EE;&#x5F55;&#x540D;&#x3002;</p>
<p>&#x8FDB;&#x5165;&#x67D0;&#x4E2A;&#x5BB9;&#x5668;&#x7684;&#x73AF;&#x5883;</p>
<pre><code class="language-bash">sudo docker exec -it containerId /bin/sh
</code></pre>
<p>&#x5148;&#x67E5;&#x770B;&#x5BB9;&#x5668;&#x5217;&#x8868;&#xFF0C;&#x627E;&#x5230;&#x8981;&#x67E5;&#x770B;&#x5BB9;&#x5668;&#x7684;ID&#xFF0C;&#x7136;&#x540E;&#x4F7F;&#x7528;&#x8BE5;&#x547D;&#x4EE4;&#x67E5;&#x770B;&#x3002;<code>/bin/sh</code>&#x53EF;&#x5728;&#x6267;&#x884C;<code>docker ps</code>&#x540E;&#x770B;&#x5230;&#x3002;&#x9000;&#x51FA;&#x5BB9;&#x5668;&#x53EF;&#x4EE5;&#x6267;&#x884C;<code>exit;</code>&#x3002;</p>
]]></content:encoded></item></channel></rss>