<?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[vivo 快应用官方博客]]></title><description><![CDATA[快应用── 复杂生活的简单答案，让生活更顺畅。]]></description><link>https://quickapp.vivo.com.cn/</link><image><url>https://quickapp.vivo.com.cn/favicon.png</url><title>vivo 快应用官方博客</title><link>https://quickapp.vivo.com.cn/</link></image><generator>Ghost 5.27</generator><lastBuildDate>Tue, 09 Dec 2025 11:41:22 GMT</lastBuildDate><atom:link href="https://quickapp.vivo.com.cn/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[快应用开发工具 6.6 版本发布]]></title><description><![CDATA[<p>&#x5FEB;&#x5E94;&#x7528;&#x5DE5;&#x5177;&#x5F00;&#x53D1;&#x56E2;&#x961F;&#xFF0C;&#x4E8E; 2023 &#x5E74; 12 &#x6708; 14 &#x65E5;&#xFF0C;&#x53D1;&#x5E03; IDE &#x6700;&#x65B0;&#x7248;&#x672C;&#xFF1A; v6.6.0&#x3002;</p><h2 id="v660-%E6%9B%B4%E6%96%B0%E8%AF%B4%E6%98%8E"><strong>v6.6.0 &#x66F4;&#x65B0;&#x8BF4;&#x660E;</strong></h2><p>&#x6B22;&#x8FCE;&#x60A8;&#x9605;&#x8BFB;&#x5FEB;&#x5E94;&#x7528; IDE 6.6.0 &#x7248;</p>]]></description><link>https://quickapp.vivo.com.cn/quickapp-ide-v6-6-release/</link><guid isPermaLink="false">6571913b764c8700068205e9</guid><category><![CDATA[快应用开发工具]]></category><dc:creator><![CDATA[admin]]></dc:creator><pubDate>Thu, 07 Dec 2023 10:06:23 GMT</pubDate><content:encoded><![CDATA[<p>&#x5FEB;&#x5E94;&#x7528;&#x5DE5;&#x5177;&#x5F00;&#x53D1;&#x56E2;&#x961F;&#xFF0C;&#x4E8E; 2023 &#x5E74; 12 &#x6708; 14 &#x65E5;&#xFF0C;&#x53D1;&#x5E03; IDE &#x6700;&#x65B0;&#x7248;&#x672C;&#xFF1A; v6.6.0&#x3002;</p><h2 id="v660-%E6%9B%B4%E6%96%B0%E8%AF%B4%E6%98%8E"><strong>v6.6.0 &#x66F4;&#x65B0;&#x8BF4;&#x660E;</strong></h2><p>&#x6B22;&#x8FCE;&#x60A8;&#x9605;&#x8BFB;&#x5FEB;&#x5E94;&#x7528; IDE 6.6.0 &#x7248;&#x672C;&#x53D1;&#x884C;&#x8BF4;&#x660E;&#xFF1B;&#x5728;&#x8FD9;&#x4E2A;&#x7248;&#x672C;&#x4E2D;&#xFF0C;&#x6211;&#x4EEC;&#x5BF9;&#x5DF2;&#x77E5;&#x95EE;&#x9898;&#x8FDB;&#x884C;&#x4E86;&#x4F18;&#x5316;&#xFF1A;</p><h2 id="%E4%BF%AE%E6%AD%A3"><strong>&#x4FEE;&#x6B63;</strong></h2><p>&#x5BF9;&#x5DF2;&#x77E5;&#x95EE;&#x9898;&#x3001;&#x4EE5;&#x53CA;&#x7528;&#x6237;&#x53CD;&#x9988;&#x7684;&#x5EFA;&#x8BAE;&#xFF0C;&#x505A;&#x4E86;&#x6539;&#x8FDB;&#x4F18;&#x5316;&#xFF0C;&#x63D0;&#x5347;&#x4E86;&#x5F00;&#x53D1;&#x4F7F;&#x7528;&#x4F53;&#x9A8C;&#x3002;</p><h3 id="%E4%BF%AE%E5%A4%8D%E4%BD%BF%E7%94%A8-less-%E6%B7%B7%E5%85%A5%E6%98%BE%E7%A4%BA%E9%97%AE%E9%A2%98"><strong>&#x4FEE;&#x590D;&#x4F7F;&#x7528; less &#x6DF7;&#x5165;&#x663E;&#x793A;&#x95EE;&#x9898;</strong></h3><figure class="kg-card kg-image-card"><img src="https://quickapp.vivo.com.cn/content/images/2023/12/image-2.png" class="kg-image" alt loading="lazy" width="1150" height="466" srcset="https://quickapp.vivo.com.cn/content/images/size/w600/2023/12/image-2.png 600w, https://quickapp.vivo.com.cn/content/images/size/w1000/2023/12/image-2.png 1000w, https://quickapp.vivo.com.cn/content/images/2023/12/image-2.png 1150w" sizes="(min-width: 720px) 720px"></figure><h3 id="%E4%BF%AE%E5%A4%8D%E6%89%93%E5%8C%85%E4%BD%93%E7%A7%AF%E5%8F%98%E5%A4%A7%E9%97%AE%E9%A2%98">&#x4FEE;&#x590D;&#x6253;&#x5305;&#x4F53;&#x79EF;&#x53D8;&#x5927;&#x95EE;&#x9898;</h3><p>&#x6B64;&#x524D;&#x7248;&#x672C;&#x6253;&#x5305;&#x51FA;&#x73B0;&#x5305;&#x4F53;&#x79EF;&#x53D8;&#x5927;&#x95EE;&#x9898;&#x3002;<br></p><hr><p>2023 &#x5E74; IDE &#x7248;&#x672C;&#x66F4;&#x65B0;&#x65F6;&#x95F4;&#x7EBF;&#xFF1A;</p><ul><li>2023 &#x5E74; 8 &#x6708; 03 &#x65E5;&#xFF1A;<a href="https://quickapp.vivo.com.cn/quickapp-ide-v6-5-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 6.5.0 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li><li>2023 &#x5E74; 7 &#x6708; 03 &#x65E5;&#xFF1A;<a href="https://quickapp.vivo.com.cn/quickapp-ide-v6-4-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 6.4.0 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li><li>2023 &#x5E74; 4 &#x6708; 26 &#x65E5;&#xFF1A;<a href="https://bbs.quickapp.cn/forum.php?mod=viewthread&amp;tid=33217">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 6.3.0 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li></ul><p>2022 &#x5E74; IDE &#x7248;&#x672C;&#x66F4;&#x65B0;&#x65F6;&#x95F4;&#x7EBF;&#xFF1A;</p><ul><li>2022 &#x5E74; 7 &#x6708; 25 &#x65E5;&#xFF1A;<a href="https://forum.lovejade.cn/d/201-62">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 6.2 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li></ul><p>2021 &#x5E74; IDE &#x7248;&#x672C;&#x66F4;&#x65B0;&#x65F6;&#x95F4;&#x7EBF;&#xFF1A;</p><ul><li>10.28 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v5-1-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 5.1 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li><li>9.2 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v5-0-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 5.0 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li><li>7.26 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v4-1-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 4.1 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li><li>6.30 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v4-0-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 4.0 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li><li>5.27 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-10-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.10 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li><li>4.13 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-9-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.9 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li><li>3.11 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-8-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.8 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li><li>2.4 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-7-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.7 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li></ul><p>2020 &#x5E74; IDE &#x7248;&#x672C;&#x66F4;&#x65B0;&#x65F6;&#x95F4;&#x7EBF;&#xFF1A;</p><ul><li>12.29 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-6-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.6 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li><li>12.01 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-5-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.5 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li><li>10.26 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-4-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.4 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li><li>08.18 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-3-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.3 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li><li>07.29 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-2-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.2 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li><li>07.06 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-1-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.1 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li><li>06.01 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.0 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li></ul>]]></content:encoded></item><item><title><![CDATA[快应用开发工具 6.5 版本发布]]></title><description><![CDATA[快应用开发者工具（IDE），专为快应用开发设计，支持快应用、卡片等开发调试、编译预览、打包上传、以及云测、远程预览.....并支持账号登录，应用关联，查看详情等；仍在不断快速迭代中，旨在让开发者能够更高效开发、调试、测试以及发布快应用。]]></description><link>https://quickapp.vivo.com.cn/quickapp-ide-v6-5-release/</link><guid isPermaLink="false">64c72530764c87000682057a</guid><category><![CDATA[快应用开发工具]]></category><dc:creator><![CDATA[admin]]></dc:creator><pubDate>Mon, 31 Jul 2023 03:26:17 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>&#x5FEB;&#x5E94;&#x7528;&#x5DE5;&#x5177;&#x5F00;&#x53D1;&#x56E2;&#x961F;&#xFF0C;&#x4E8E; 2023 &#x5E74; 8 &#x6708; 1 &#x65E5;&#xFF0C;&#x53D1;&#x5E03; IDE &#x6700;&#x65B0;&#x7248;&#x672C;&#xFF1A; v6.5.0&#x3002;</p>
<h2 id="v650-%E6%9B%B4%E6%96%B0%E8%AF%B4%E6%98%8E">v6.5.0 &#x66F4;&#x65B0;&#x8BF4;&#x660E;</h2>
<p>&#x6B22;&#x8FCE;&#x60A8;&#x9605;&#x8BFB;&#x5FEB;&#x5E94;&#x7528; IDE 6.5.0 &#x7248;&#x672C;&#x53D1;&#x884C;&#x8BF4;&#x660E;&#xFF1B;&#x5728;&#x8FD9;&#x4E2A;&#x7248;&#x672C;&#x4E2D;&#xFF0C;&#x6211;&#x4EEC;&#x505A;&#x4E86;&#x4E00;&#x4E9B;&#x66F4;&#x65B0;&#xFF0C;&#x540C;&#x65F6;&#x5BF9;&#x5DF2;&#x77E5;&#x95EE;&#x9898;&#x8FDB;&#x884C;&#x4E86;&#x4F18;&#x5316;&#xFF1A;</p>
<h2 id="%E4%BC%98%E5%8C%96%E6%9B%B4%E6%96%B0">&#x4F18;&#x5316;&#x66F4;&#x65B0;</h2>
<h3 id="%E5%8A%A8%E6%80%81%E6%B8%85%E7%90%86%E9%A1%B9%E7%9B%AE-dist-%E7%9B%AE%E5%BD%95%E4%B8%8B%E6%97%A7%E7%89%88-rpk">&#x52A8;&#x6001;&#x6E05;&#x7406;&#x9879;&#x76EE; dist &#x76EE;&#x5F55;&#x4E0B;&#x65E7;&#x7248; rpk</h3>
<p>rpk &#x4F5C;&#x4E3A;&#x5E94;&#x7528;&#x5B89;&#x88C5;&#x5305;&#xFF0C;&#x662F;&#x5F00;&#x53D1;&#x8005;&#x8FDB;&#x884C;&#x771F;&#x673A;&#x8C03;&#x8BD5;&#x7684;&#x4E3B;&#x8981;&#x5BF9;&#x8C61;&#x3002;&#x65E7;&#x7248; rpk &#x5BF9;&#x4E8E;&#x5F00;&#x53D1;&#x8005;&#x4F5C;&#x7528;&#x751A;&#x5FAE;&#xFF0C;&#x56E0;&#x6B64;&#x672C;&#x7248;&#x672C;&#x5F00;&#x59CB;&#xFF0C;&#x6BCF;&#x6B21;&#x6253;&#x5305;&#x65F6;&#x90FD;&#x4F1A;&#x52A8;&#x6001;&#x6E05;&#x7406;&#x9879;&#x76EE;&#x4E2D;&#x7684;&#x65E7;&#x7248; rpk&#xFF0C;&#x4F7F;&#x5F97; dist &#x76EE;&#x5F55;&#x4E0B;&#x6709;&#x4E14;&#x4EC5;&#x6709;&#x4E24;&#x4E2A;rpk&#xFF08;debug &#x548C; release&#xFF09;&#x3002;</p>
<p><img src="http://image-vivofs.vivo.com.cn/JTC49MqiIeYIy8hS/wukong/image-processing-services/img/compress/c16f8b05-3de8-4820-a789-2c4511c66cb9.png" alt="&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 6.5.0 &#x7248;&#x672C;&#x53D1;&#x5E03;" loading="lazy"></p>
<h3 id="%E6%9B%B4%E6%96%B0-ide-%E5%86%85%E7%BD%AE%E7%9A%84%E8%B0%83%E8%AF%95%E5%99%A8%E5%92%8C%E5%BC%95%E6%93%8E">&#x66F4;&#x65B0; IDE &#x5185;&#x7F6E;&#x7684;&#x8C03;&#x8BD5;&#x5668;&#x548C;&#x5F15;&#x64CE;</h3>
<p>&#x5C06; IDE &#x5185;&#x7F6E;&#x7684;&#x8C03;&#x8BD5;&#x5668;&#x66F4;&#x65B0;&#x81F3; 1.10.0.0 &#x7248;&#x672C;&#xFF0C;&#x5F15;&#x64CE;&#x66F4;&#x65B0;&#x81F3; 1.10.0.1 &#x7248;&#x672C;&#x3002;</p>
<h2 id="%E4%BF%AE%E6%AD%A3">&#x4FEE;&#x6B63;</h2>
<p>&#x5BF9;&#x5DF2;&#x77E5;&#x95EE;&#x9898;&#x3001;&#x4EE5;&#x53CA;&#x7528;&#x6237;&#x53CD;&#x9988;&#x7684;&#x5EFA;&#x8BAE;&#xFF0C;&#x505A;&#x4E86;&#x6539;&#x8FDB;&#x4F18;&#x5316;&#xFF0C;&#x63D0;&#x5347;&#x4E86;&#x5F00;&#x53D1;&#x4F7F;&#x7528;&#x4F53;&#x9A8C;&#x3002;</p>
<h3 id="%E4%BF%AE%E5%A4%8D%E7%BC%96%E8%AF%91%E6%97%B6-less-%E6%8A%A5%E9%94%99%E9%97%AE%E9%A2%98">&#x4FEE;&#x590D;&#x7F16;&#x8BD1;&#x65F6; less &#x62A5;&#x9519;&#x95EE;&#x9898;</h3>
<p><img src="http://image-vivofs.vivo.com.cn/JTC49MqiIeYIy8hS/wukong/image-processing-services/img/compress/3097ecea-1a36-4cc3-8ed0-95225daebdff.png" alt="&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 6.5.0 &#x7248;&#x672C;&#x53D1;&#x5E03;" loading="lazy"></p>
<h3 id="%E4%BF%AE%E5%A4%8D-smart-%E6%A8%A1%E5%BC%8F%E4%B8%8B%E6%89%93%E5%8C%85%E5%BC%82%E5%B8%B8%E9%97%AE%E9%A2%98">&#x4FEE;&#x590D; SMART &#x6A21;&#x5F0F;&#x4E0B;&#x6253;&#x5305;&#x5F02;&#x5E38;&#x95EE;&#x9898;</h3>
<p>6.4.0 &#x7248;&#x672C;&#x6253;&#x5F00; SMART &#x6A21;&#x5F0F;&#xFF0C;&#x8FD0;&#x884C; npm run release &#x6253;&#x5305;&#x9879;&#x76EE;&#x65F6;&#x51FA;&#x73B0;&#x62A5;&#x9519;&#x3002;</p>
<h3 id="%E4%BF%AE%E5%A4%8D-lottie-%E7%BB%84%E4%BB%B6%E9%97%AE%E9%A2%98">&#x4FEE;&#x590D; lottie &#x7EC4;&#x4EF6;&#x95EE;&#x9898;</h3>
<p>6.4.0 &#x7248;&#x672C;&#x4E2D;&#xFF0C;lottie &#x7EC4;&#x4EF6;&#x5728;&#x64AD;&#x653E;&#x52A8;&#x753B;&#x4E4B;&#x540E;&#xFF0C;&#x8BE5;&#x7EC4;&#x4EF6;&#x5728;&#x9884;&#x89C8;&#x6A21;&#x5757;&#x7F3A;&#x5931;&#x3002;</p>
<h3 id="%E4%BF%AE%E5%A4%8D%E9%83%A8%E5%88%86%E5%9C%BA%E6%99%AF%E4%B8%8B%EF%BC%8C%E7%BC%BA%E5%B0%91%E6%96%87%E4%BB%B6%E5%AF%BC%E5%85%A5%E6%8F%90%E7%A4%BA%E7%9A%84%E9%97%AE%E9%A2%98">&#x4FEE;&#x590D;&#x90E8;&#x5206;&#x573A;&#x666F;&#x4E0B;&#xFF0C;&#x7F3A;&#x5C11;&#x6587;&#x4EF6;&#x5BFC;&#x5165;&#x63D0;&#x793A;&#x7684;&#x95EE;&#x9898;</h3>
<p>&#x4E4B;&#x524D;&#x7248;&#x672C;&#xFF0C;&#x5F53;style&#x6807;&#x7B7E;&#x4E2D;&#x5B58;&#x5728;lang&#x7B49;&#x5C5E;&#x6027;&#x65F6;&#xFF0C;&#x4F1A;&#x5BFC;&#x81F4;&#x6587;&#x4EF6;&#x5BFC;&#x5165;&#x63D0;&#x793A;&#x7F3A;&#x5931;&#x3002;</p>
<p><img src="http://image-vivofs.vivo.com.cn/JTC49MqiIeYIy8hS/wukong/image-processing-services/img/compress/9f5a6034-3d43-4de7-ac7f-a966eedf191e.png" alt="&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 6.5.0 &#x7248;&#x672C;&#x53D1;&#x5E03;" loading="lazy"></p>
<hr>
<p>2023 &#x5E74; IDE &#x7248;&#x672C;&#x66F4;&#x65B0;&#x65F6;&#x95F4;&#x7EBF;&#xFF1A;</p>
<ul>
<li>2023 &#x5E74; 7 &#x6708; 03 &#x65E5;&#xFF1A;<a href="https://quickapp.vivo.com.cn/quickapp-ide-v6-4-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 6.4.0 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>2023 &#x5E74; 4 &#x6708; 26 &#x65E5;&#xFF1A;<a href="https://bbs.quickapp.cn/forum.php?mod=viewthread&amp;tid=33217">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 6.3.0 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
</ul>
<p>2022 &#x5E74; IDE &#x7248;&#x672C;&#x66F4;&#x65B0;&#x65F6;&#x95F4;&#x7EBF;&#xFF1A;</p>
<ul>
<li>2022 &#x5E74; 7 &#x6708; 25 &#x65E5;&#xFF1A;<a href="https://forum.lovejade.cn/d/201-62">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 6.2 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
</ul>
<p>2021 &#x5E74; IDE &#x7248;&#x672C;&#x66F4;&#x65B0;&#x65F6;&#x95F4;&#x7EBF;&#xFF1A;</p>
<ul>
<li>10.28 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v5-1-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 5.1 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>9.2 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v5-0-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 5.0 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>7.26 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v4-1-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 4.1 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>6.30 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v4-0-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 4.0 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>5.27 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-10-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.10 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>4.13 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-9-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.9 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>3.11 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-8-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.8 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>2.4 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-7-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.7 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
</ul>
<p>2020 &#x5E74; IDE &#x7248;&#x672C;&#x66F4;&#x65B0;&#x65F6;&#x95F4;&#x7EBF;&#xFF1A;</p>
<ul>
<li>12.29 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-6-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.6 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>12.01 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-5-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.5 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>10.26 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-4-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.4 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>08.18 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-3-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.3 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>07.29 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-2-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.2 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>07.06 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-1-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.1 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>06.01 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.0 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
</ul>
<!--kg-card-end: markdown--><p></p>]]></content:encoded></item><item><title><![CDATA[如何在快应用开发中使用 Tailwind CSS 提升开发效率？]]></title><description><![CDATA[Tailwind CSS 是一种现代的 CSS 框架，它提供了一组预定义的 CSS 类，用于快速开发现代 Web 应用程序。Tailwind 的核心理念是为开发者提供一种灵活的方法来构建自定义的 UI 组件，而不需要编写大量的 CSS 代码。]]></description><link>https://quickapp.vivo.com.cn/how-to-use-tailwind-css-in-quickapp-development/</link><guid isPermaLink="false">64b65d87764c87000682055f</guid><category><![CDATA[快应用]]></category><category><![CDATA[快应用教程]]></category><dc:creator><![CDATA[admin]]></dc:creator><pubDate>Wed, 19 Jul 2023 06:50:18 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Tailwind CSS&#xFF0C;&#x5728; Web &#x5F00;&#x53D1;&#x9886;&#x57DF;&#xFF0C;&#x5DF2;&#x7ECF;&#x6210;&#x4E3A;&#x5404;&#x79CD;&#x6846;&#x67B6;&#x3001;&#x5F00;&#x53D1;&#x4EBA;&#x5458;&#x6807;&#x914D;&#xFF1B;&#x5DF2;&#x7ECF;&#x6709;&#x5927;&#x91CF;&#x5B9E;&#x4F8B;&#x8BC1;&#x660E;&#xFF0C;&#x57FA;&#x4E8E;&#xA0;<code>Tailwind CSS</code>&#xA0;&#x6765;&#x7F16;&#x5199;&#x6837;&#x5F0F;&#xFF0C;&#x53EF;&#x4EE5;&#x4E3A;&#x5F00;&#x53D1;&#x8005;&#x8282;&#x7701;&#x8BF8;&#x591A;&#x65F6;&#x95F4;&#xFF1B;&#x800C;&#x4E14;&#xFF0C;&#x80FD;&#x591F;&#x4F18;&#x5316;&#x51CF;&#x5C0F;&#x4EE3;&#x7801;&#x4F53;&#x79EF;&#x3001;&#x63D0;&#x5347;&#x8FD0;&#x884C;&#x6027;&#x80FD;&#xFF0C;&#x662F;&#x975E;&#x5E38;&#x68D2;&#x7684;&#x6280;&#x672F;&#x5957;&#x4EF6;&#x3002; <a href="https://nicelinks.site/post/5b5fb5bc615bf842b609105f">&#x5FEB;&#x5E94;&#x7528;</a> &#x5F00;&#x53D1;&#xFF0C;&#x540C;&#x6837;&#x57FA;&#x4E8E; Web &#x6280;&#x672F;&#x6808;&#xFF0C;&#x7406;&#x8BBA;&#x4E0A;&#x4E5F;&#x5B8C;&#x5168;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#xA0;<strong>Tailwind CSS</strong>&#xFF1B;&#x5728;&#x5B9E;&#x9645;&#x5F00;&#x53D1;&#x8FC7;&#x7A0B;&#x4E2D;&#xFF0C;&#x8BE5;&#x5982;&#x4F55;&#x4F7F;&#x7528; Tailwind CSS &#x5462;&#xFF1F;&#x8BF7;&#x8BE6;&#x7EC6;&#x8BF4;&#x8BF4;&#x3002;</p>
<hr>
<p><a href="https://nicelinks.site/post/5fd20cb4c06d6302c1907ec7">Tailwind CSS</a> &#x7684;&#x5DE5;&#x4F5C;&#x539F;&#x7406;&#x662F;&#x626B;&#x63CF;&#x6240;&#x6709; <a href="https://nicelinks.site/tags/HTML">HTML</a> &#x6587;&#x4EF6;&#x3001;JavaScript &#x7EC4;&#x4EF6;&#x548C;&#x4EFB;&#x4F55;&#x5176;&#x4ED6;&#x6A21;&#x677F;&#x7684;&#x7C7B;&#x540D;&#xFF0C;&#x751F;&#x6210;&#x76F8;&#x5E94;&#x7684;&#x6837;&#x5F0F;&#xFF0C;&#x7136;&#x540E;&#x5C06;&#x5B83;&#x4EEC;&#x5199;&#x5165;&#x9759;&#x6001; <a href="https://nicelinks.site/tags/CSS">CSS</a> &#x6587;&#x4EF6;&#x3002;&#x5B83;&#x5FEB;&#x901F;&#x3001;&#x7075;&#x6D3B;&#x3001;&#x53EF;&#x9760;&#xFF0C;&#x4E14;&#x8FD0;&#x884C;&#x65F6;&#x95F4;&#x4E3A;&#x96F6;&#x3002;&#x5B98;&#x65B9;&#x63D0;&#x4F9B; <a href="https://tailwindcss.com/docs/installation">Tailwind CLI</a> &#x3001;PostCSS&#x3001;Play CDN &#x7B49;&#x4F7F;&#x7528;&#x65B9;&#x5F0F;&#xFF1B;&#x4E0B;&#x9762;&#x4E3B;&#x8981;&#x8BB2;&#x4E0B;&#x5982;&#x4F55;&#x57FA;&#x4E8E; Tailwind CLI &#x65B9;&#x5F0F;&#xFF0C;&#x5728;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x4E2D;&#x4F7F;&#x7528; Tailwind CSS&#xFF1A;</p>
<h2 id="tailwind-css-%E5%8F%AF%E4%B8%BA%E5%BF%AB%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E5%B8%A6%E6%9D%A5%E5%93%AA%E4%BA%9B%E5%A5%BD%E5%A4%84%EF%BC%9F">Tailwind CSS &#x53EF;&#x4E3A;&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5E26;&#x6765;&#x54EA;&#x4E9B;&#x597D;&#x5904;&#xFF1F;</h2>
<p><a href="https://nicelinks.site/post/5fd20cb4c06d6302c1907ec7">Tailwind CSS</a> &#x662F;&#x4E00;&#x79CD;&#x73B0;&#x4EE3;&#x7684; CSS &#x6846;&#x67B6;&#xFF0C;&#x5B83;&#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x7EC4;&#x9884;&#x5B9A;&#x4E49;&#x7684; CSS &#x7C7B;&#xFF0C;&#x7528;&#x4E8E;&#x5FEB;&#x901F;&#x5F00;&#x53D1;&#x73B0;&#x4EE3; Web &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x3002;Tailwind &#x7684;&#x6838;&#x5FC3;&#x7406;&#x5FF5;&#x662F;&#x4E3A;&#x5F00;&#x53D1;&#x8005;&#x63D0;&#x4F9B;&#x4E00;&#x79CD;&#x7075;&#x6D3B;&#x7684;&#x65B9;&#x6CD5;&#x6765;&#x6784;&#x5EFA;&#x81EA;&#x5B9A;&#x4E49;&#x7684; UI &#x7EC4;&#x4EF6;&#xFF0C;&#x800C;&#x4E0D;&#x9700;&#x8981;&#x7F16;&#x5199;&#x5927;&#x91CF;&#x7684; CSS &#x4EE3;&#x7801;&#x3002;</p>
<p>Tailwind CSS &#x7684;&#x5DE5;&#x4F5C;&#x539F;&#x7406;&#x662F;&#x626B;&#x63CF;&#x6240;&#x6709; HTML &#x6587;&#x4EF6;&#x3001;JavaScript &#x7EC4;&#x4EF6;&#x548C;&#x4EFB;&#x4F55;&#x5176;&#x4ED6;&#x6A21;&#x677F;&#x7684;&#x7C7B;&#x540D;&#xFF0C;&#x751F;&#x6210;&#x76F8;&#x5E94;&#x7684;&#x6837;&#x5F0F;&#xFF0C;&#x7136;&#x540E;&#x5C06;&#x5B83;&#x4EEC;&#x5199;&#x5165;&#x9759;&#x6001; CSS &#x6587;&#x4EF6;&#x3002;&#x5B83;&#x5FEB;&#x901F;&#x3001;&#x7075;&#x6D3B;&#x3001;&#x53EF;&#x9760;&#xFF0C;&#x4E14;&#x8FD0;&#x884C;&#x65F6;&#x95F4;&#x4E3A;&#x96F6;&#x3002;</p>
<p>&#x5728;&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x4E2D;&#x5F15;&#x5165;&#xFF0C;&#x53EF;&#x4EE5;&#x4E3A;&#x9879;&#x76EE;&#x5E26;&#x6765;&#x56DB;&#x65B9;&#x9762;&#x7684;&#x597D;&#x5904;&#xFF1A;<strong>&#x66F4;&#x5FEB;&#x7684;&#x7F16;&#x5199;&#x6548;&#x7387;</strong>&#x3001;<strong>&#x66F4;&#x5C0F;&#x7684;&#x4EE3;&#x7801;&#x603B;&#x4F53;&#x79EF;</strong>&#x3001;<strong>&#x66F4;&#x9AD8;&#x7684;&#x8FD0;&#x884C;&#x6548;&#x7387;</strong>&#x3001;<strong>&#x66F4;&#x6613;&#x4E8E;&#x9879;&#x76EE;&#x7EF4;&#x62A4;</strong>&#x3002;&#x66F4;&#x8BE6;&#x7EC6;&#x8BF4;&#x660E;&#x5982;&#x4E0B;&#xFF1A;</p>
<ul>
<li>&#x9884;&#x5B9A;&#x4E49;&#x7684; CSS &#x7C7B;&#x53EF;&#x4EE5;&#x51CF;&#x5C11;&#x6837;&#x5F0F;&#x7684;&#x5197;&#x4F59;&#xFF0C;&#x4ECE;&#x800C;<strong>&#x51CF;&#x5C0F; CSS &#x6587;&#x4EF6;&#x7684;&#x4F53;&#x79EF;</strong>&#x3002;</li>
<li>&#x5927;&#x91CF;&#x914D;&#x5957;&#x8BBE;&#x65BD;&#xFF0C;&#x53EF;&#x4EE5;<strong>&#x63D0;&#x9AD8;&#x5F00;&#x53D1;&#x6548;&#x7387;</strong>&#xFF0C;&#x4E0D;&#x5FC5;&#x624B;&#x52A8;&#x7F16;&#x5199;&#x5927;&#x91CF;&#x7684; CSS &#x4EE3;&#x7801;&#x3002;</li>
<li>&#x63D0;&#x4F9B;&#x4E86;&#x81EA;&#x52A8;&#x4F18;&#x5316;&#x5DE5;&#x5177;&#xFF0C;&#x53EF;&#x4EE5;<strong>&#x5220;&#x9664;&#x672A;&#x4F7F;&#x7528;&#x7684; CSS &#x4EE3;&#x7801;</strong>&#x3002;</li>
<li>&#x4E0D;&#x7528;&#x8017;&#x65F6;&#x53BB;&#x4E3A; CSS class &#x53D6;&#x8BED;&#x4E49;&#x5316;&#x7C7B;&#x540D;&#xFF0C;&#x4E0D;&#x518D;&#x9700;&#x8981;&#x5173;&#x6CE8; style &#x6807;&#x7B7E;&#xFF1B;</li>
<li>&#x4EE3;&#x7801;&#x4F53;&#x79EF;&#x51CF;&#x5C0F;&#xFF0C;&#x53EF;&#x4EE5;&#x51CF;&#x5C11;&#x4E0B;&#x8F7D;&#x3001;&#x52A0;&#x8F7D;&#x3001;&#x89E3;&#x6790;&#x7B49;&#x6B65;&#x9AA4;&#x8017;&#x65F6;&#x3002;</li>
<li>&#x4F7F; CSS &#x6837;&#x5F0F;&#x66F4;&#x89C4;&#x8303;&#x5316;&#xFF0C;&#x907F;&#x514D;&#x5197;&#x4F59;&#x7684;&#x6837;&#x5F0F;&#x548C;&#x590D;&#x6742;&#x7684;&#x9009;&#x62E9;&#x5668;&#xFF0C;&#x4F18;&#x5316;&#x8FD0;&#x884C;&#x6027;&#x80FD;&#x3002;</li>
<li>Tailwind CSS &#x62E5;&#x6709;&#x6D3B;&#x8DC3;&#x7684;&#x793E;&#x533A;&#x548C;&#x6587;&#x6863;&#xFF0C;&#x53EF;&#x4EE5;&#x5E2E;&#x52A9;&#x5F00;&#x53D1;&#x8005;&#x5FEB;&#x901F;&#x4E0A;&#x624B;&#x548C;&#x89E3;&#x51B3;&#x95EE;&#x9898;&#x3002;</li>
</ul>
<p><img src="https://lovejade.oss-cn-shenzhen.aliyuncs.com/TailwindCSS.gif" alt="Tailwind CSS" loading="lazy"></p>
<h2 id="%E5%A6%82%E4%BD%95%E5%9C%A8%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8-tailwind-css%EF%BC%9F">&#x5982;&#x4F55;&#x5728;&#x9879;&#x76EE;&#x4E2D;&#x4F7F;&#x7528; Tailwind CSS&#xFF1F;</h2>
<h3 id="%E5%AE%89%E8%A3%85-tailwind-css-%E4%BE%9D%E8%B5%96">&#x5B89;&#x88C5; Tailwind CSS &#x4F9D;&#x8D56;</h3>
<p>&#x901A;&#x8FC7; <a href="https://nicelinks.site/post/6216392f2d17f22050cf1a2b">npm</a> &#x5B89;&#x88C5; <code>tailwindcss</code> &#x5E76;&#x521B;&#x5EFA; <code>tailwind.config.js</code>&#xA0;&#x6587;&#x4EF6;&#xFF0C;&#x5177;&#x4F53;&#x547D;&#x4EE4;&#x5982;&#x4E0B;&#xFF1A;</p>
<pre><code class="language-bash">pnpm install -D tailwindcss 
# OR 
# npm install -D tailwindcss 
npx tailwindcss init
</code></pre>
<h3 id="%E9%85%8D%E7%BD%AE%E6%82%A8%E7%9A%84%E6%A8%A1%E6%9D%BF%E8%B7%AF%E5%BE%84">&#x914D;&#x7F6E;&#x60A8;&#x7684;&#x6A21;&#x677F;&#x8DEF;&#x5F84;</h3>
<p>&#x5728;&#x6587;&#x4EF6;&#x4E2D;&#x6DFB;&#x52A0;&#x6240;&#x6709;&#x6A21;&#x677F;&#x6587;&#x4EF6;&#x7684;&#x8DEF;&#x5F84; <code>tailwind.config.js</code>&#xFF0C;&#x53C2;&#x8003;&#x6027;&#x914D;&#x7F6E;&#x5982;&#x4E0B;&#xFF1A;</p>
<pre><code class="language-js">const colors = require(&apos;tailwindcss/colors&apos;)

const selfCustomColors = {
  brand: {
    DEFAULT: &apos;#1e293b&apos;,
  },
  warn: {
    DEFAULT: &apos;#f59e0b&apos;,
  },
  link: {
    DEFAULT: &apos;#0ea5e9&apos;,
  },
  mark: {
    DEFAULT: &apos;#ff4582&apos;,
  },
}

module.exports = {
  mode: &apos;jit&apos;,
  content: [
    &apos;./src/**/*.{ux,html,js,svelte,vue,ts}&apos;,
    &apos;./node_modules/flowbite/**/*.js&apos;,
  ],
  purge: {
    enabled: true,
    content: [
      &apos;./src/**/*.{ux,html,js,svelte,vue,ts}&apos;,
      &apos;./node_modules/flowbite/**/*.js&apos;,
    ],
  },
  // https://tailwindcss.com/docs/configuration#core-plugins
  corePlugins: {
    preflight: false, // disable base/reset styles
    container: false, // disable container component
    content: false, // disable `content` utility
    accentColor: false, // disable `accent-color` utility
    accessibility: false, // disable `appearance` utility
    appearance: false, // disable `appearance` utility 
    aspectRatio: false, // disable `aspect-ratio` utility
    backgroundOpacity: false, // disable `background-opacity` utility
    backdropBlur: false, // disable `backdrop-blur` utility
    backdropBrightness: false, // disable `backdrop-brightness` utility
    backdropContrast: false, // disable `backdrop-contrast` utility
    backdropGrayscale: false, // disable `backdrop-grayscale` utility
    backdropHueRotate: false, // disable `backdrop-hue-rotate` utility
    backdropInvert: false, // disable `backdrop-invert` utility
    backdropOpacity: false, // disable `backdrop-opacity` utility
    backdropSaturate: false, // disable `backdrop-saturate` utility
    backdropSepia: false, // disable `backdrop-sepia` utility
    blur: false, // disable `blur` utility
    borderCollapse: false, // disable `border-collapse` utility
    borderOpacity: false, // disable `border-opacity` utility
    borderSpacing: false, // disable `border-spacing` utility
    boxShadow: false, // disable `box-shadow` utility
    boxShadowColor: false, // disable `box-shadow-color` utility
    boxDecorationBreak: false, // disable `box-decoration-break` utility
    boxSizing: false, // disable `box-sizing` utility
    breakAfter: false, // disable `break-after` utility
    breakBefore: false, // disable `break-before` utility
    breakInside: false, // disable `break-inside` utility
    brightness: false, // disable `brightness` utility
    captionSide: false, // disable `caption-side` utility
    caretColor: false, // disable `caret-color` utility
    clear: false, // disable `clear` utility
    contrast: false, // disable `contrast` utility
    divideColor: false, // disable `divide-color` utility
    divideOpacity: false, // disable `divide-opacity` utility
    divideStyle: false, // disable `divide-style` utility
    divideWidth: false, // disable `divide-width` utility
    float: false, // disable `float` utility
    fontVariantNumeric: false, // disable `font-variant-numeric` utility
    hyphens: false, // disable `hyphens` utility
    isolation: false, // disable `isolation` utility
    lineClamp: false, // disable `line-clamp` utility
    mixBlendMode: false, // diable `mix-blend-mode` utility
    listStyleImage: false, // disable `list-style-image` utility
    listStylePosition: false, // disable `list-style-position` utility
    listStyleType: false, // disable `list-style-type` utility
    objectPosition: false, // disable `object-position` utility
    opacity: false, // disable `opacity` utility
    outlineColor: false, // disable `outline-color` utility
    outlineOffset: false, // disable `outline-offset` utility
    outlineStyle: false, // disable `outline-style` utility
    outlineWidth: false, // disable `outline-width` utility
    overscrollBehavior: false, // disable `overscroll-behavior` utility
    placeContent: false, // disable `place-content` utility
    placeItems: false, // disable `place-items` utility
    placeSelf: false, // disable `place-self` utility
    placeholderOpacity: false, // disable `placeholder-opacity` utility
    resize: false, // disable `resize` utility
    ringColor: false, // disable `ring-color` utility
    ringOffsetColor: false, // disable `ring-offset-color` utility
    ringOffsetWidth: false, // disable `ring-offset-width` utility
    ringOpacity: false, // disable `ring-opacity` utility
    space: false, // disable `space-between` utility
    textDecorationThickness: false, // disable `text-decoration-thickness` utility
    textOpacity: false, // disable `text-opacity` utility
    textTransform: false, // disable `text-transform` utility
    textUnderlineOffset: false, // disable `text-underline-offset` utility
    touchAction: false, // disable `touch-action` utility
    userSelect: false, // disable `user-select` utility
    verticalAlign: false, // disable `vertical-align` utility
    whitespace: false, // disable `whitespace` utility
    wordBreak: false, // disable `word-break` utility
    willChange: false, // disable `will-change` utility
  },
  darkMode: false,
  theme: {
    colors: { ...colors, ...selfCustomColors },
    extend: {
      width: ({ theme }) =&gt; ({
        auto: &apos;auto&apos;,
        ...theme(&apos;spacing&apos;),
      }),
      height: ({ theme }) =&gt; ({
        auto: &apos;auto&apos;,
        ...theme(&apos;spacing&apos;),
      }),
      spacing: {
        &apos;1/2&apos;: &apos;2px&apos;,
        &apos;1&apos;: &apos;4px&apos;,
        &apos;3/2&apos;: &apos;6px&apos;,
        &apos;2&apos;: &apos;8px&apos;,
        &apos;5/2&apos;: &apos;10px&apos;,
        &apos;3&apos;: &apos;12px&apos;,
        &apos;7/2&apos;: &apos;14px&apos;,
        &apos;4&apos;: &apos;16px&apos;,
        &apos;5&apos;: &apos;20px&apos;,
        &apos;6&apos;: &apos;24px&apos;,
        &apos;7&apos;: &apos;28px&apos;,
        &apos;8&apos;: &apos;32px&apos;,
        &apos;9&apos;: &apos;36px&apos;,
        &apos;10&apos;: &apos;40px&apos;,
        &apos;11&apos;: &apos;44px&apos;,
        &apos;12&apos;: &apos;48px&apos;,
        &apos;14&apos;: &apos;56px&apos;,
        &apos;16&apos;: &apos;64px&apos;,
        &apos;20&apos;: &apos;80px&apos;,
        &apos;24&apos;: &apos;96px&apos;,
        &apos;28&apos;: &apos;112px&apos;,
        &apos;32&apos;: &apos;128px&apos;,
        &apos;36&apos;: &apos;144px&apos;,
        &apos;40&apos;: &apos;160px&apos;,
        &apos;44&apos;: &apos;176px&apos;,
        &apos;48&apos;: &apos;192px&apos;,
        &apos;52&apos;: &apos;208px&apos;,
        &apos;56&apos;: &apos;224px&apos;,
        &apos;60&apos;: &apos;240px&apos;,
        &apos;72&apos;: &apos;288px&apos;,
        &apos;80&apos;: &apos;320px&apos;,
        &apos;96&apos;: &apos;384px&apos;,
      },
      borderWidth: {
        &apos;DEFAULT&apos;: &apos;1px&apos;,
        &apos;0&apos;: &apos;0px&apos;,
        &apos;2&apos;: &apos;2px&apos;,
        &apos;4&apos;: &apos;4px&apos;,
        &apos;8&apos;: &apos;8px&apos;,
      },
      borderRadius: {
        &apos;none&apos;: &apos;0&apos;,
        &apos;&apos;: &apos;1px&apos;,
        &apos;sm&apos;: &apos;2px&apos;,
        &apos;DEFAULT&apos;: &apos;4px&apos;,
        &apos;md&apos;: &apos;6px&apos;,
        &apos;lg&apos;: &apos;8px&apos;,
        &apos;xl&apos;: &apos;12px&apos;,
        &apos;2xl&apos;: &apos;16px&apos;,
        &apos;3xl&apos;: &apos;24px&apos;,
      },
      fontSize: {
        &apos;xm&apos;: [&apos;12px&apos;, { lineHeight: &apos;16px&apos; }],
        &apos;sm&apos;: [&apos;14px&apos;, { lineHeight: &apos;20px&apos; }],
        &apos;base&apos;: [&apos;16px&apos;, { lineHeight: &apos;24px&apos; }],
        &apos;lg&apos;: [&apos;18px&apos;, { lineHeight: &apos;28px&apos; }],
        &apos;xl&apos;: [&apos;20px&apos;, { lineHeight: &apos;28px&apos; }],
        &apos;2xl&apos;: [&apos;24px&apos;, { lineHeight: &apos;32px&apos; }],
        &apos;3xl&apos;: [&apos;30px&apos;, { lineHeight: &apos;36px&apos; }],
        &apos;4xl&apos;: [&apos;36px&apos;, { lineHeight: &apos;40px&apos; }],
        &apos;5xl&apos;: [&apos;48px&apos;, { lineHeight: &apos;60px&apos; }],
        &apos;6xl&apos;: [&apos;60px&apos;, { lineHeight: &apos;60px&apos; }],
        &apos;7xl&apos;: [&apos;72px&apos;, { lineHeight: &apos;60px&apos; }],
        &apos;8xl&apos;: [&apos;96px&apos;, { lineHeight: &apos;60px&apos; }],
        &apos;9xl&apos;: [&apos;128px&apos;, { lineHeight: &apos;60px&apos; }],
      }
    },
  },
  variants: {
    extend: {},
  },
  plugins: [],
}
</code></pre>
<h3 id="%E5%B0%86-tailwind-%E6%8C%87%E4%BB%A4%E6%B7%BB%E5%8A%A0%E5%88%B0%E6%82%A8%E7%9A%84-css-%E4%B8%AD">&#x5C06; Tailwind &#x6307;&#x4EE4;&#x6DFB;&#x52A0;&#x5230;&#x60A8;&#x7684; CSS &#x4E2D;</h3>
<p><code>@tailwind</code> &#x5C06; Tailwind &#x6BCF;&#x4E2A;&#x5C42;&#x7684;&#x6307;&#x4EE4;&#x6DFB;&#x52A0;&#x5230;&#x60A8;&#x7684;&#x4E3B; CSS &#x6587;&#x4EF6;&#x4E2D;&#x3002;</p>
<pre><code class="language-css">/* input.css */

/* @tailwind base; */
@tailwind components;
@tailwind utilities;
</code></pre>
<h3 id="%E5%90%AF%E5%8A%A8-tailwind-cli-%E6%9E%84%E5%BB%BA%E8%BF%87%E7%A8%8B">&#x542F;&#x52A8; Tailwind CLI &#x6784;&#x5EFA;&#x8FC7;&#x7A0B;</h3>
<p>&#x8FD0;&#x884C; CLI &#x5DE5;&#x5177;&#x6765;&#x626B;&#x63CF;&#x6A21;&#x677F;&#x6587;&#x4EF6;&#x4E2D;&#x7684;&#x7C7B;&#x5E76;&#x6784;&#x5EFA; CSS&#xFF0C;&#x53C2;&#x8003;&#x6027;&#x547D;&#x4EE4;&#x5982;&#x4E0B;&#xFF1A;</p>
<pre><code class="language-bash">npx tailwindcss -i ./src/input.css -o ./src/output.css --watch
</code></pre>
<p>&#x8FD9;&#x662F;&#x770B;&#x8D77;&#x6765;&#x8DEF;&#x5F84;&#x7B80;&#x77ED;&#x7684;&#x65B9;&#x5F0F;&#xFF0C;&#x5B9E;&#x9645;&#x4E0A;&#x8FD9;&#x4E2A; <code>input.css</code> &#x548C; <code>output.css</code>&#xFF0C;&#x65E0;&#x8BBA;&#x662F;&#x540D;&#x5B57;&#xFF0C;&#x6216;&#x662F;&#x5B83;&#x5B58;&#x5728;&#x7684;&#x8DEF;&#x5F84;&#xFF0C;&#x7686;&#x53EF;&#x4EE5;&#x81EA;&#x884C;&#x6307;&#x5B9A;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x6309;&#x7167;&#x81EA;&#x5DF1;&#x559C;&#x6B22;&#x7684;&#x65B9;&#x5F0F;&#x3001;&#x6216;&#x662F;&#x56E2;&#x961F;&#x7EA6;&#x5B9A;&#x4FD7;&#x6210;&#x7684;&#x5F62;&#x5F0F;&#xFF1B;&#x8B6C;&#x5982;&#x7EDF;&#x4E00;&#x5B58;&#x653E;&#x5728;&#xFF1A;<code>src/assets/styles</code> &#x76EE;&#x5F55;&#x4E0B;&#x3002;</p>
<p>&#x9700;&#x8981;&#x8865;&#x5145;&#x8BF4;&#x660E;&#x7684;&#x662F;&#xFF1A;&#x5728;&#x56E2;&#x961F;&#x5F00;&#x53D1;&#x4E2D;&#xFF0C;&#x8F93;&#x5165;&#x4E0A;&#x8FF0;&#x547D;&#x4EE4;&#xFF0C;&#x7565;&#x663E;&#x7E41;&#x7410;&#xFF0C;&#x53EF;&#x4EE5;&#x5728; <code>package.json</code> &#x6CE8;&#x5165;&#x547D;&#x4EE4;&#xFF08;&#x5982;&#x4E0B;&#x793A;&#x4F8B;&#xFF09;&#xFF1B;&#x5982;&#x6B64;&#x4EE5;&#x4E0B;&#xFF0C;&#x60A8;&#x53EA;&#x9700;&#x5728;&#x300C;<strong>&#x7EC8;&#x7AEF;</strong>&#x300D;&#x8FD0;&#x884C; <code>pnpm tailwindcss</code> &#x6216; <code>npm run tailwindcss</code> &#x547D;&#x4EE4;&#x5373;&#x53EF;&#x3002;</p>
<pre><code class="language-json">&quot;scripts&quot;: {
  &quot;tailwindcss&quot;: &quot;npx tailwindcss -i ./src/input.css -o ./src/output.css --watch&quot;,
}
</code></pre>
<h3 id="%E5%BC%80%E5%A7%8B%E5%9C%A8-ux-%E4%B8%AD%E4%BD%BF%E7%94%A8-tailwind-css">&#x5F00;&#x59CB;&#x5728; UX &#x4E2D;&#x4F7F;&#x7528; Tailwind CSS</h3>
<p>&#x5C06;&#x5DF2;&#x7F16;&#x8BD1;&#x7684; CSS &#x6587;&#x4EF6;&#xFF0C;&#x5728; <code>.ux</code> &#xFF08;&#x975E; <code>app.ux</code>&#xFF09;&#x6587;&#x4EF6;&#x4E2D;&#xFF0C;&#x901A;&#x8FC7; <code>@import</code> &#x65B9;&#x5F0F;&#x5F15;&#x5165;&#xFF1B;</p>
<pre><code class="language-css">&lt;style&gt;
  @import &apos;./../../output.css&apos;;
&lt;/style&gt;
</code></pre>
<p>&#x73B0;&#x5728;&#xFF0C;&#x5373;&#x53EF;&#x5728; <code>.ux</code>  &#x7684; <code>template</code> &#x4E2D;&#xFF0C;&#x5F00;&#x59CB;&#x4F7F;&#x7528; Tailwind &#x7684;&#x5B9E;&#x7528;&#x7A0B;&#x5E8F;&#x7C7B;&#x6765;&#x8BBE;&#x7F6E;&#x5185;&#x5BB9;&#x7684;&#x6837;&#x5F0F;&#xFF0C;&#x5982;&#x4E0B;&#x9762;&#x8FD9;&#x6BB5;&#x4EE3;&#x7801;&#x793A;&#x4F8B;&#xFF1A;</p>
<pre><code class="language-html">&lt;template&gt;
    &lt;div class=&quot;bg-blue-300 w-full flex flex-col justify-center items-center&quot;&gt;
      &lt;text class=&quot;text-red-600&quot;&gt;TailwindCSS Area&lt;/text&gt;
      &lt;text class=&quot;text-red-600&quot;&gt;Awesome TailwindCSS&lt;/text&gt;
    &lt;/div&gt;
&lt;/template&gt;
</code></pre>
<p>&#x5F53;&#x60A8;&#x5199;&#x5B8C;&#x4FDD;&#x5B58;&#x4E4B;&#x540E;&#xFF0C;&#x6253;&#x5F00; <code>output.css</code> &#x5373;&#x53EF;&#x5982;&#x4E0B;&#x7684; CSS &#x4EE3;&#x7801;&#xFF1A;</p>
<pre><code class="language-css">/* @tailwind base; */

.flex {
  display: flex
}

.w-full {
  width: 100%
}

.flex-col {
  flex-direction: column
}

.items-center {
  align-items: center
}

.justify-center {
  justify-content: center
}

.bg-blue-300 {
  background-color: #93c5fd
}

.text-red-600 {
  color: #dc2626
}
</code></pre>
<p>&#x81F3;&#x6B64;&#xFF0C;&#x5728; <a href="https://nicelinks.site/post/5b5fb5bc615bf842b609105f">&#x5FEB;&#x5E94;&#x7528;</a> &#x5F00;&#x53D1;&#x4E2D;&#x5F15;&#x5165; <a href="https://nicelinks.site/post/5fd20cb4c06d6302c1907ec7">Tailwind CSS</a> &#x7684;&#x51C6;&#x5907;&#x5DE5;&#x4F5C;&#xFF0C;&#x5DF2;&#x7ECF;&#x521D;&#x6B65;&#x5B8C;&#x6210;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x4E0E; <code>Tailwind CSS</code> &#x5F00;&#x542F;&#x6109;&#x5FEB;&#x5408;&#x4F5C;&#x4E4B;&#x65C5;&#xFF0C;&#x4ECE;&#x800C;&#x4FC3;&#x4F7F;&#x9AD8;&#x6548;&#x7F16;&#x7801;&#x3001;&#x63D0;&#x524D;&#x5B8C;&#x5DE5;&#x3002;&#x5047;&#x5982;&#xFF0C;&#x60A8;&#x5BF9; <code>Tailwind CSS</code> &#x5C1A;&#x4E0D;&#x719F;&#x6089;&#xFF0C;&#x53EF;&#x901A;&#x8FC7;&#x67E5;&#x9605; <a href="https://tailwindcss.com/docs/flex-basis">Tailwind CSS Doc</a> &#xFF0C;&#x4EA6;&#x53EF;&#x5728;&#x7EBF;&#x4F53;&#x9A8C;&#x2014;&#x2014; <a href="https://play.tailwindcss.com/">Tailwind Playground</a> &#x3002;</p>
<p>&#x9700;&#x8981;&#x8865;&#x5145;&#x8BF4;&#x660E;&#x7684;&#x662F;&#xFF0C;&#x4F7F;&#x7528;  <code>Tailwind CSS</code> &#x5E76;&#x4E0D;&#x7834;&#x574F;&#x60A8;&#x539F;&#x6765;&#x7684; CSS &#x4E66;&#x5199;&#x270D;&#x1F3FB;&#x65B9;&#x5F0F;&#xFF1B;&#x60A8;&#x5B8C;&#x5168;&#x53EF;&#x4EE5;&#x7ED3;&#x5408;&#x559C;&#x6B22;&#x7684;&#x9884;&#x5904;&#x7406;&#x5668;&#xFF08;&#x5982; Sass&#x3001;Less&#x3001;Stylus&#xFF09;&#xFF0C;&#x6765;&#x5171;&#x540C;&#x5DE5;&#x4F5C;&#xFF0C;&#x800C;&#x65E0;&#x9700;&#x505A;&#x66F4;&#x591A;&#x8BBE;&#x7F6E;&#xFF08;&#x5982;&#x4E0B;&#x4EE3;&#x7801;&#x793A;&#x4F8B;&#xFF09;&#xFF1B;&#x4F46;&#x6211;&#x4EE5;&#x4E3A;&#x5F53;&#x60A8;&#x719F;&#x6089; Tailwind CSS &#x4E4B;&#x540E;&#xFF0C;&#x5927;&#x6709;&#x53EF;&#x80FD;&#x4E5F;&#x4F1A;&#x201C;<strong>&#x79FB;&#x60C5;&#x800C;&#x522B;&#x604B;</strong>&#x201D;&#x3002;</p>
<pre><code class="language-css">&lt;style lang=&quot;scss&quot;&gt;
  @import &apos;./../../assets/styles/style.scss&apos;;
  @import &apos;./../../assets/styles/output.css&apos;;

  .primary-btn {
    width: 90 * $size-factor;
    height: 16 * $size-factor;
    background-color: $brand;
    border-radius: 8 * $size-factor;
    color: $white;
  }
&lt;/style&gt;
</code></pre>
<h2 id="%E5%A6%82%E4%BD%95%E5%9F%BA%E4%BA%8E-tailwind-css-%E6%8F%90%E5%8D%87%E5%BC%80%E5%8F%91%E6%95%88%E7%8E%87%EF%BC%9F">&#x5982;&#x4F55;&#x57FA;&#x4E8E; Tailwind CSS &#x63D0;&#x5347;&#x5F00;&#x53D1;&#x6548;&#x7387;&#xFF1F;</h2>
<h3 id="%E5%AE%89%E8%A3%85-tailwind-css-intellisense-%E6%89%A9%E5%B1%95">&#x5B89;&#x88C5; Tailwind CSS IntelliSense &#x6269;&#x5C55;</h3>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x5728;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177;&#x7684;&#x300C;&#x6269;&#x5C55;&#x5E02;&#x573A;&#x300D;&#xFF0C;&#x901A;&#x8FC7;&#x5173;&#x952E;&#x5B57; <code>Tailwind</code> &#x68C0;&#x7D22;&#x201D;Tailwind CSS IntelliSense&#x201C;&#x6269;&#x5C55;&#x2014;&#x2014;&#x9002;&#x7528;&#x4E8E; Visual Studio Code &#x7684;&#x667A;&#x80FD; Tailwind CSS &#x5DE5;&#x5177;&#xFF0C;&#x7528;&#x6237;&#x63D0;&#x4F9B;&#x81EA;&#x52A8;&#x5B8C;&#x6210;&#x3001;&#x8BED;&#x6CD5;&#x7A81;&#x51FA;&#x663E;&#x793A;&#x548C; linting &#x7B49;&#x9AD8;&#x7EA7;&#x529F;&#x80FD;&#x6765;&#x589E;&#x5F3A; Tailwind &#x5F00;&#x53D1;&#x4F53;&#x9A8C;&#xFF1B;&#x7565;&#x4F5C;&#x9002;&#x914D;&#x5373;&#x53EF;&#x652F;&#x6301; <code>*.ux</code>&#xFF1B;&#x8BE6;&#x7EC6;&#x8BBE;&#x7F6E;&#xFF0C;&#x53EF;&#x53C2;&#x89C1;&#xFF1A; <a href="https://github.com/tailwindlabs/tailwindcss-intellisense">Tailwind CSS IntelliSense</a> &#x3002;</p>
<p><img src="https://lovejade.oss-cn-shenzhen.aliyuncs.com/Tailwind-CSS-IntelliSense.png" alt="Tailwind CSS IntelliSense &#x63D0;&#x5347; ux &#x5F00;&#x53D1;&#x6548;&#x7387;" loading="lazy"></p>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x7F16;&#x8F91;&#x201C;&#x5B57;&#x7B26;&#x4E32;&#x201D;&#x5185;&#x5BB9;&#x65F6;&#xFF08;&#x4F8B;&#x5982;&#x5728; JSX &#x5C5E;&#x6027;&#x503C;&#x4E2D;&#xFF09;&#xFF0C;&#x5F00;&#x53D1;&#x5DE5;&#x5177;&#x4E2D;&#x4E0D;&#x4F1A;&#x89E6;&#x53D1;&#x5B8C;&#x6210;&#x3002;&#x66F4;&#x65B0;&#x8BBE;&#x7F6E; <code>editor.quickSuggestions</code> &#x53EF;&#x80FD;&#x4F1A;&#x6539;&#x5584;&#x60A8;&#x7684;&#x4F53;&#x9A8C;&#xFF1A;</p>
<pre><code class="language-json">&quot;editor.quickSuggestions&quot;: {
  &quot;strings&quot;: &quot;on&quot;
}
</code></pre>
<h3 id="%E5%8F%82%E8%80%83%E5%9F%BA%E4%BA%8E-tailwind-css-%E7%BB%84%E4%BB%B6%E7%9A%84%E5%BC%80%E6%BA%90%E5%BA%93">&#x53C2;&#x8003;&#x57FA;&#x4E8E; Tailwind CSS &#x7EC4;&#x4EF6;&#x7684;&#x5F00;&#x6E90;&#x5E93;</h3>
<p>Tailwind CSS &#x751F;&#x6001;&#x53D1;&#x5C55;&#x7E41;&#x8363;&#x8D85;&#x4E4E;&#x60F3;&#x8C61;&#xFF0C;&#x5C31;&#x8FDE;&#x5176;&#x884D;&#x751F;&#x4EA7;&#x54C1;&#x4E5F;&#x4E0D;&#x53EF;&#x80DC;&#x6570;&#xFF1B;&#x5982; <a href="https://flowbite.com/?ref=nicelinks.site">Flowbite</a> &#x2014;&#x2014;&#x5305;&#x542B; 600 &#x591A;&#x4E2A; UI &#x7EC4;&#x4EF6;&#x3001;&#x90E8;&#x5206;&#x548C;&#x9875;&#x9762;&#x7684;&#x5F00;&#x6E90;&#x5E93;&#x8FDB;&#x884C;&#x5F00;&#x53D1;&#xFF0C;&#x8BE5;&#x5E93;&#x4F7F;&#x7528; <a href="https://nicelinks.site/post/5fd20cb4c06d6302c1907ec7">Tailwind CSS</a> &#x7684;&#x5B9E;&#x7528;&#x7A0B;&#x5E8F;&#x7C7B;&#x6784;&#x5EFA;&#x5E76;&#x5728; <a href="https://nicelinks.site/post/605f1c61bffb5e532f3be23c">Figma</a> &#x4E2D;&#x8BBE;&#x8BA1;&#x3002;&#x5B83;&#x4E0D;&#x4EC5;&#x80FD;&#x5145;&#x5F53; Tailwind CSS &#x63D2;&#x4EF6;&#x4F7F;&#x7528;&#xFF0C;&#x4E5F;&#x53EF;&#x4EE5;&#x62F7;&#x8D1D;&#x5230;&#x9879;&#x76EE;&#x76F4;&#x63A5;&#x4F7F;&#x7528;&#xFF0C;&#x8FD8;&#x53EF;&#x4EE5;&#x5728;&#x7EBF;&#x67E5;&#x9605;&#x6548;&#x679C;&#xFF08;&#x652F;&#x6301;&#x591A;&#x79CD;&#x5C4F;&#x5E55;&#x8BBE;&#x5907;&#x7C7B;&#x578B;&#xFF09;&#xFF0C;&#x6311;&#x9009;&#x5339;&#x914D;&#x5B9E;&#x73B0;&#x65B9;&#x6848;&#xFF1B;&#x5728;&#x4ECD;&#x662F;&#x57FA;&#x4E8E;&#x7EC4;&#x4EF6;&#x6811;&#x6784;&#x5EFA;&#x9875;&#x9762;&#x7684;&#x65F6;&#x4EE3;&#xFF0C;&#x6781;&#x5927;&#x63D0;&#x5347;&#x9875;&#x9762;&#x642D;&#x5EFA;&#x6548;&#x7387;&#x3002;&#x5982;&#xFF1A; <a href="https://flowbite.com/docs/components/pagination/">pagination</a> &#x7EC4;&#x4EF6;&#xFF1A;</p>
<p><img src="https://lovejade.oss-cn-shenzhen.aliyuncs.com/TailwindCSS-Flowbite-Pagination.png" alt="Tailwind CSS Flowbite Pagination" loading="lazy"></p>
<hr>
<h2 id="%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E5%8F%8A%E8%AF%B4%E6%98%8E">&#x5E38;&#x89C1;&#x95EE;&#x9898;&#x53CA;&#x8BF4;&#x660E;</h2>
<p>&#x5982;&#x679C;&#x60A8;&#x719F;&#x6089; Web &#x5F00;&#x53D1;&#xFF0C;&#x9488;&#x5BF9;&#x4E0A;&#x8FF0;&#x6559;&#x7A0B;&#xFF0C;&#x60A8;&#x53EF;&#x80FD;&#x4F1A;&#x6709;&#x8BF8;&#x591A;&#x7591;&#x60D1;&#xFF1B;&#x5B9E;&#x9645;&#x4E0A;&#xFF0C;&#x7B14;&#x8005;&#x5728;&#x5B9E;&#x8DF5;&#x4E4B;&#x65F6;&#xFF0C;&#x4E5F;&#x6709;&#x53D1;&#x73B0;&#xFF0C;&#x53EA;&#x4E0D;&#x8FC7;&#x56E0;&#x4E3A;&#x5404;&#x79CD;&#x673A;&#x5236;&#x9650;&#x5236;&#xFF0C;&#x76EE;&#x524D;&#x53EA;&#x80FD;&#x5982;&#x6B64;&#x3002;&#x4E0B;&#x9762;&#x5C31;&#x4E0E;&#x8BF8;&#x541B;&#x5206;&#x4EAB;&#xFF0C;&#x671F;&#x53EF;&#x89E3;&#x60D1;&#xFF1A;</p>
<h3 id="%E4%B8%8D%E8%83%BD%E5%9C%A8-script-%E6%A0%87%E7%AD%BE%E4%B8%AD%EF%BC%8C%E5%BC%95%E5%85%A5%E8%BE%93%E5%87%BA-css-%E6%96%87%E4%BB%B6%E4%B9%88%EF%BC%9F">&#x4E0D;&#x80FD;&#x5728; <code>script</code> &#x6807;&#x7B7E;&#x4E2D;&#xFF0C;&#x5F15;&#x5165;&#x8F93;&#x51FA; CSS &#x6587;&#x4EF6;&#x4E48;**&#xFF1F;</h3>
<p>&#x6309; Web &#x5F00;&#x53D1;&#x4E60;&#x60EF;&#xFF0C;&#x5728; <code>app.ux</code> &#x6587;&#x4EF6;&#x4E2D;&#x53EF;&#x4EE5;&#x76F4;&#x63A5; <code>import</code> &#x8F93;&#x51FA; CSS &#x6587;&#x4EF6;&#xFF08;&#x5982;&#x4E0B;&#x4EE3;&#x7801;&#x6240;&#x793A;&#xFF09;&#xFF0C;&#x90A3;&#x4E3A;&#x4F55;&#x672A;&#x5EFA;&#x8BAE;&#x5982;&#x6B64;&#x5462;&#xFF1F;</p>
<pre><code class="language-js">&lt;script&gt;
import &apos;./output.css&apos;
&lt;/script&gt;
</code></pre>
<p>&#x56E0;&#x4E3A;&#x8FD9;&#x6837;&#x505A;&#x4F1A;&#x62A5;&#x5982;&#x4E0B;&#x9519;&#x8BEF;&#xFF1B;&#x5177;&#x4F53;&#x662F;&#x7F3A;&#x4E4F;&#x4E0E;&#x4E4B;&#x5339;&#x914D;&#x7684; loader&#xFF1B;&#x5F53;&#x7136;&#xFF0C;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#xA0;<code>css-loader</code>&#xA0;&#x548C;&#xA0;<code>style-loader</code>&#xA0;&#x6765;&#x5904;&#x7406; CSS &#x6587;&#x4EF6;&#xFF0C;&#x8BE6;&#x89C1; <a href="https://memo.lovejade.cn/m/271">ChatGPT | You may need an appropriate loader....</a> &#x3002;</p>
<pre><code class="language-bash">You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders

| /* @tailwind base; */
</code></pre>
<p>&#x4F46;&#x5728;<strong>&#x5FEB;&#x5E94;&#x7528;</strong>&#x5F00;&#x53D1;&#x8FC7;&#x7A0B;&#x4E2D;&#xFF0C;&#x5374;&#x4E0D;&#x80FD;&#x751F;&#x6548;&#xFF1B;&#x56E0;&#x4E3A; <a href="https://github.com/webpack-contrib/style-loader">style-loader</a> &#x7684;&#x4F5C;&#x7528;&#x662F;&#x5C06; CSS &#x6CE8;&#x5165; DOM&#xFF0C;&#x5176;&#x4E2D;&#x7528;&#x5230;&#x4E86;&#x8BF8;&#x591A;&#x6D4F;&#x89C8;&#x5668; API&#xFF08;document&#xFF09;&#xFF0C;&#x800C;&#x5FEB;&#x5E94;&#x7528;&#x7684;&#x5F00;&#x53D1;&#x867D;&#x7136;&#x662F;&#x57FA;&#x4E8E;&#x524D;&#x7AEF;&#x6280;&#x672F;&#x6808;&#xFF0C;&#x4F46;&#x5176;&#x8FD0;&#x884C;&#x73AF;&#x5883;&#x6B62;&#x4E8E; <code>v8</code>&#xFF0C;&#x5B9E;&#x9645;&#x7684;&#x6E32;&#x67D3;&#x662F;&#x7531; Android &#x5E95;&#x5C42;&#x5B8C;&#x6210;&#xFF0C;&#x5E76;&#x672A;&#x8D70;&#x6D4F;&#x89C8;&#x5668;&#x8FD9;&#x6761;&#x8DEF;&#xFF0C;&#x56E0;&#x6B64;&#x65E0;&#x6CD5;&#x5DE5;&#x4F5C;&#x3002;&#x5728;&#x6784;&#x5EFA;&#x5DE5;&#x5177;&#x4F18;&#x5316;&#x3001;&#x517C;&#x5BB9;&#x4E4B;&#x524D;&#xFF0C;&#x901A;&#x8FC7; <code>style</code> &#x6807;&#x7B7E;&#x4E2D;&#x5F15;&#x5165; CSS&#xFF0C;&#x6210;&#x4E86;&#x4E3B;&#x8981;&#x9009;&#x62E9;&#x3002;</p>
<h3 id="%E4%B8%BA%E4%BD%95%E5%9C%A8-tailwindconfigjs-%E7%A6%81%E7%94%A8%E5%A6%82%E6%AD%A4%E5%A4%9A%E6%A0%B7%E5%BC%8F%EF%BC%9F">&#x4E3A;&#x4F55;&#x5728; <code>tailwind.config.js</code> &#x7981;&#x7528;&#x5982;&#x6B64;&#x591A;&#x6837;&#x5F0F;&#xFF1F;</h3>
<p>Tailwind <a href="https://tailwindcss.com/docs/configuration#core-plugins">corePlugins</a> &#x90E8;&#x5206;&#x5141;&#x8BB8;&#x60A8;&#x5B8C;&#x5168;&#x7981;&#x7528; Tailwind &#x901A;&#x5E38;&#x9ED8;&#x8BA4;&#x751F;&#x6210;&#x7684;&#x7C7B;&#xFF08;&#x5982;&#x679C;&#x60A8;&#x7684;&#x9879;&#x76EE;&#x4E0D;&#x9700;&#x8981;&#x5B83;&#x4EEC;&#xFF09;&#xFF1B;&#x8FD9;&#x4E2A;&#x8BBE;&#x8BA1;&#x5BF9;&#x4E8E;&#x5FEB;&#x5E94;&#x7528;&#x5B9E;&#x5728;&#x5FC5;&#x8981;&#x7684;&#x7D27;&#xFF0C;&#x5728;&#x4E0A;&#x8FF0;&#x793A;&#x4F8B;&#x4E2D;&#xFF0C;&#x5BF9; <code>text-opacity</code> &#x7B49;&#x6837;&#x5F0F;&#x8FDB;&#x884C;&#x7981;&#x7528;&#xFF0C;&#x4E5F;&#x662F;&#x65E0;&#x5948;&#x4E4B;&#x4E3E;&#x3002;&#x5177;&#x4F53;&#x539F;&#x56E0;&#x5728;&#x4E8E;&#x4EE5;&#x4E0B;&#x4E24;&#x70B9;&#xFF1A;</p>
<p>&#x5176;&#x4E00;&#xFF1A;&#x5FEB;&#x5E94;&#x7528;&#x6807;&#x51C6;&#x867D;&#x7136;&#x57FA;&#x4E8E; Web &#x6280;&#x672F;&#x6808;&#xFF0C;&#x4F46;&#x53EA;&#x662F; Web &#x6807;&#x51C6;&#x5B50;&#x96C6;&#xFF0C;&#x5982;&#x86EE;&#x591A; CSS &#x5C5E;&#x6027;&#x5E76;&#x4E0D;&#x80FD;&#x5F88;&#x597D;&#x7684;&#x652F;&#x6301;&#xFF1B;&#x5176;&#x4E8C;&#xFF1A;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;TailwindCSS &#x4F1A;&#x5C06;&#x6837;&#x5F0F;&#x5C5E;&#x6027;&#x7684;&#x503C;&#x5B58;&#x50A8;&#x4E3A; CSS &#x53D8;&#x91CF;&#xFF08;&#x4F8B;&#x5982;&#xA0;<code>--tw-text-opacity</code>&#xFF09;&#xFF0C;&#x4EE5;&#x4FBF;&#x8FDB;&#x884C;&#x52A8;&#x6001;&#x8BA1;&#x7B97;&#x548C;&#x54CD;&#x5E94;&#x5F0F;&#x8BBE;&#x8BA1;&#x3002;</p>
<p>&#x5982;&#x6B64;&#x4E00;&#x6765;&#xFF0C;&#x5728; template &#x4E2D;&#x4F7F;&#x7528;&#x7C7B; <code>text-red-300</code>&#x3001;<code>border-spacing-1</code>&#xFF0C;&#x8F93;&#x51FA;&#x7684;&#x4FBF;&#x662F;&#x5982;&#x4E0B; CSS&#xFF1B;&#x8FD9;&#x6837;&#x7684;&#x5199;&#x6CD5;&#xFF0C;&#x5728;&#x5FEB;&#x5E94;&#x7528;&#x4E2D;&#x5E76;&#x4E0D;&#x80FD;&#x5F97;&#x5230;&#x6B63;&#x786E;&#x89E3;&#x6790;&#xFF0C;&#x4E5F;&#x5C31;&#x65E0;&#x6CD5;&#x8D77;&#x5230;&#x671F;&#x5F85;&#x6548;&#x679C;&#xFF0C;&#x4E8E;&#x662F;&#x7981;&#x7528;&#x4FBF;&#x6210;&#x4E86;&#x5FC5;&#x987B;&#x8981;&#x505A;&#x4E4B;&#x4E8B;&#x3002;&#x5F53;&#x7136;&#xFF0C;&#x8FD9;&#x6837;&#x7981;&#x7528;&#x4E5F;&#x597D;&#x5904;&#xFF1A;&#x5229;&#x4E8E;&#x8F93;&#x51FA;&#x66F4;&#x5C0F;&#x63D0;&#x53CA;&#x7684; CSS &#x6587;&#x4EF6;&#x3002;&#x5176;&#x4ED6;&#x5C5E;&#x6027;&#x4EA6;&#x590D;&#x5982;&#x662F;&#x3002;</p>
<pre><code class="language-css">.text-red-300 {
  --tw-text-opacity: 1;
  color: rgb(252 165 165 / var(--tw-text-opacity))
}
.border-spacing-1 {
&#xA0; --tw-border-spacing-x: 4px;
&#xA0; --tw-border-spacing-y: 4px;
&#xA0; border-spacing: var(--tw-border-spacing-x) var(--tw-border-spacing-y)
}
</code></pre>
<h3 id="%E4%B8%BA%E4%BD%95%E8%A6%81%E5%9C%A8-inputcss-%E4%B8%AD%E7%A7%BB%E9%99%A4-tailwind-base-%EF%BC%9F">&#x4E3A;&#x4F55;&#x8981;&#x5728; <code>input.css</code> &#x4E2D;&#x79FB;&#x9664; <code>@tailwind base;</code> &#xFF1F;</h3>
<p>&#x8FD9;&#x4E48;&#x505A;&#x4E3B;&#x8981;&#x672A;&#x89E3;&#x51B3;&#x95EE;&#x9898;&#xFF1A; <a href="https://github.com/tailwindlabs/tailwindcss/discussions/8500">How disable default styles for : before and : after</a> &#x3002;</p>
<pre><code class="language-css">/* input.css */

/* @tailwind base; */
@tailwind components;
@tailwind utilities;
</code></pre>
<p>&#x5728;&#x4E00;&#x822C; Web &#x5F00;&#x53D1;&#x8FC7;&#x7A0B;&#x4E2D;&#xFF0C;&#x4F1A;&#x5C06; base&#x3001;components&#x3001;utilities &#x7B49;&#x6307;&#x4EE4;&#xFF0C;&#x90FD;&#x6DFB;&#x52A0;&#x5230; CSS &#x6587;&#x4EF6;&#x9879;&#x76EE;&#x4E2D;&#xFF1B;&#x4F46;&#xFF0C;&#x5728;&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x8FC7;&#x7A0B;&#x4E2D;&#xFF0C;&#x8FD9;&#x65E0;&#x7591;&#x662F;&#x7D2F;&#x8D58;&#xFF1B;&#x56E0;&#x4E3A;&#x5B83;&#x7684;&#x5B58;&#x5728;&#xFF0C;&#x4F1A;&#x4F7F;&#x5F97; <code>output.css</code> &#x8F93;&#x51FA;&#x8F83;&#x591A;&#x5BF9;&#x9879;&#x76EE;&#x6CA1;&#x6709;&#x88E8;&#x76CA;&#x989D;&#x5916;&#x5185;&#x5BB9;&#xFF08;&#x5982;&#x4E0B;&#x4EE3;&#x7801;&#x6240;&#x793A;&#xFF09;&#xFF0C;&#x6545;&#x800C;&#x79FB;&#x9664;&#xFF1B;&#x8FD9;&#x4E0E;&#x901A;&#x8FC7; corePlugins &#x7981;&#x7528;&#x57FA;&#x7840;&#x6837;&#x5F0F;&#xFF08;preflight&#xFF09;&#x3001;&#x7981;&#x7528;&#x5BB9;&#x5668;&#x7EC4;&#x4EF6;&#xFF08;container&#xFF09;&#x4F5C;&#x7528;&#x7C7B;&#x4F3C;&#x3002;</p>
<pre><code class="language-css">*, ::before, ::after {
  --tw-border-spacing-x: 0;
  ......
}
::backdrop {
  --tw-border-spacing-x: 0;
  ......
}
</code></pre>
<h3 id="%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E5%9C%A8%E9%85%8D%E7%BD%AE%E4%B8%AD%E9%80%9A%E8%BF%87-theme-%E8%87%AA%E5%AE%9A%E4%B9%89%E9%95%BF%E5%BA%A6%E5%8D%95%E4%BD%8D%EF%BC%9F">&#x4E3A;&#x4EC0;&#x4E48;&#x8981;&#x5728;&#x914D;&#x7F6E;&#x4E2D;&#x901A;&#x8FC7; <code>theme</code> &#x81EA;&#x5B9A;&#x4E49;&#x957F;&#x5EA6;&#x5355;&#x4F4D;&#xFF1F;</h3>
<p>&#x4FEE;&#x6539;&#x957F;&#x5EA6;&#x5355;&#x4F4D;&#x4ECE; <code>rem</code> &#x5230; <code>px</code>&#xFF0C;&#x8FD9;&#x4E5F;&#x662F;&#x4E0D;&#x5F97;&#x5DF2;&#x800C;&#x4E3A;&#x4E4B;&#x3002; <a href="https://nicelinks.site/post/5b5fb5bc615bf842b609105f">&#x5FEB;&#x5E94;&#x7528;</a> &#x6807;&#x51C6;&#x5BF9; <a href="https://doc.quickapp.cn/tutorial/framework/page-style-and-layout.html?q=#%E9%95%BF%E5%BA%A6%E5%8D%95%E4%BD%8D">&#x957F;&#x5EA6;&#x5355;&#x4F4D;</a> &#x7684;&#x652F;&#x6301;&#xFF0C;&#x5728; 1070 &#x53CA;&#x4EE5;&#x4E0B;&#x7248;&#x672C;&#x4EC5;&#x652F;&#x6301;&#x957F;&#x5EA6;&#x5355;&#x4F4D; <code>px</code> &#x548C; <code>%</code>&#x3002;&#x4ECE; <code>1080</code> &#x7248;&#x672C;&#x5F00;&#x59CB;&#xFF0C;&#x65B0;&#x589E;&#x4E86;&#x957F;&#x5EA6;&#x5355;&#x4F4D; <code>dp</code>&#x3002;&#x5B83;&#x65E0;&#x6CD5;&#x652F;&#x6301; <code>rem</code>&#xFF0C;&#x5C31;&#x53EA;&#x80FD;&#x81EA;&#x5B9A;&#x4E49;&#x8BBE;&#x7F6E;&#x4E3A; <code>px</code>&#xFF1B;&#x5728;&#x901A;&#x8FC7; <code>theme</code> &#x81EA;&#x5B9A;&#x4E49;&#x957F;&#x5EA6;&#x5355;&#x4F4D;&#xFF0C;&#x662F; Tailwind CSS &#x5B98;&#x65B9;&#x63D0;&#x4F9B;&#x7684;&#x529F;&#x80FD;&#xFF0C;&#x4EE5;&#x6B64;&#x80FD;&#x591F;&#x5B9E;&#x73B0;&#x66F4;&#x7CBE;&#x7EC6;&#x7684;&#x6837;&#x5F0F;&#x63A7;&#x5236;&#xFF1B;&#x867D;&#x7136;&#x64CD;&#x4F5C;&#x4E0D;&#x96BE;&#xFF0C;&#x4F46;&#x5C5E;&#x6027;&#x8F83;&#x591A;&#x3001;&#x7EA6;&#x5B9A;&#x7E41;&#x6742;&#x3002;&#x540E;&#x7EED;&#x65F6;&#x95F4;&#x5982;&#x679C;&#x5141;&#x8BB8;&#xFF0C;&#x5C06;&#x63A2;&#x7D22; <code>rem to px</code> &#x6279;&#x91CF;&#x8F6C;&#x6362;&#x63D2;&#x4EF6;&#x6765;&#x5B9E;&#x73B0;&#xFF0C;&#x4EE5;&#x8FBE;&#x5230;&#x5FEB;&#x901F;&#x4FEE;&#x6539;&#x3002;&#x5982;&#x679C;&#x60A8;&#x611F;&#x5174;&#x8DA3;&#xFF0C;&#x53EF;&#x4EE5;&#x67E5;&#x9605; Tailwind CSS &#x5B8C;&#x6574;&#x7248;&#x672C;&#x914D;&#x7F6E;&#x2014;&#x2014; <a href="https://github.com/tailwindlabs/tailwindcss/blob/master/stubs/config.full.js">config.full.js</a> &#x3002;</p>
<h3 id="%E5%85%B6%E4%BB%96%E6%9A%82%E6%9C%AA%E8%A7%A3%E5%86%B3%E9%97%AE%E9%A2%98">&#x5176;&#x4ED6;&#x6682;&#x672A;&#x89E3;&#x51B3;&#x95EE;&#x9898;</h3>
<ul>
<li><strong>&#x5C11;&#x90E8;&#x5206;&#x7C7B;&#x540D;&#x5199;&#x6CD5;&#xFF0C;&#x5FEB;&#x5E94;&#x7528;&#x6784;&#x5EFA;&#x4E0D;&#x652F;&#x6301;</strong></li>
</ul>
<p>&#x5728; Tailwind CSS &#x673A;&#x5236;&#x4E2D;&#xFF0C;&#x652F;&#x6301;&#x4F7F;&#x7528;&#x7C7B;&#x540D;&#x8BF8;&#x5982;  <code>h-[100px] w-1/3</code> &#xFF08;&#x5BF9;&#x5E94;&#x751F;&#x6210; CSS &#x5982;&#x4E0B;&#xFF09;&#xFF0C;&#x7136;&#x800C;&#xFF0C;&#x5728;&#x5FEB;&#x5E94;&#x7528;&#x6784;&#x5EFA;&#x5DE5;&#x5177;&#x6682;&#x4E0D;&#x652F;&#x6301;&#x8FD9;&#x7C7B;&#x540D;&#xFF0C;&#x4E8E;&#x662F;&#x4E4E;&#x8FD9;&#x6837;&#x5199;&#x4FBF;&#x4E0D;&#x4F1A;&#x751F;&#x6548;&#xFF0C;&#x5F53;&#x7136;&#x4E5F;&#x4E0D;&#x4F1A;&#x9020;&#x6210;&#x4EC0;&#x4E48;&#x95EE;&#x9898;&#xFF1B;&#x540E;&#x7EED;&#x4E9F;&#x5F85;&#x6253;&#x5305;&#x5DE5;&#x5177;&#x4F18;&#x5316;&#x3002;</p>
<pre><code class="language-css">.h-\[100px\] {
  height: 100px
}
.w-1\/3 {
  width: 33.333333%
}
</code></pre>
<p>&#x5728;&#x6253;&#x5305;&#xFF08;Toolkit&#xFF09;&#x672A;&#x89E3;&#x51B3;&#x8BE5;&#x95EE;&#x9898;&#x4E4B;&#x524D;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x624B;&#x52A8;&#x5199;&#x4E00;&#x4E2A; <code>class</code>&#xFF0C;&#x6216;&#x8005;&#x4F7F;&#x7528;&#x5185;&#x8054;&#x6837;&#x5F0F;&#xFF08;<code>style</code>&#xFF09;&#x6765;&#x517C;&#x5BB9;&#xFF1B;&#x5728;&#x8FD9;&#x79CD;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x66F4;&#x63A8;&#x8350;&#x540E;&#x8005;&#xFF1B;&#x56E0;&#x4E3A;&#x5F15;&#x5165; Tailwind CSS &#x7684;&#x5F00;&#x53D1;&#x6A21;&#x5F0F;&#x4E2D;&#xFF0C;&#x57FA;&#x672C;&#x4E0D;&#x7528;&#x624B;&#x5199; class&#xFF0C;&#x5373;&#x65E0;&#x9700;&#x6EDA;&#x52A8;&#x5230; <code>style</code> &#x6807;&#x7B7E;&#x6216;&#x8DF3;&#x8F6C; less&#x3001;(s)css&#x3001;&#x6587;&#x4EF6;&#xFF0C;&#x90A3;&#x4E48;&#x76F4;&#x63A5;&#x5728; <code>template</code> &#x4E2D;&#x4F7F;&#x7528;&#x5185;&#x8054;&#x66F4;&#x4E3A;&#x4FBF;&#x6377;&#x3002;</p>
<pre><code class="language-html">&lt;div class=&quot;training-list-width&quot; style=&quot;width: 326px;&quot;&gt;&lt;/div&gt;

&lt;style&gt;
.training-list-width {
  width: 326px;
}
&lt;/style&gt;
</code></pre>
<ul>
<li><strong>&#x5FEB;&#x5E94;&#x7528;&#x6784;&#x5EFA;&#xFF0C;&#x8D44;&#x6E90;&#x5B58;&#x5728;&#x91CD;&#x590D;&#x5F15;&#x7528;&#x95EE;&#x9898;</strong></li>
</ul>
<p>&#x524D;&#x6587;&#x4E2D;&#x63D0;&#x5230;&#xFF0C;&#x5728; <code>script</code> &#x6807;&#x7B7E;&#x4E2D; <code>import</code> CSS &#x8D44;&#x6E90;&#xFF0C;&#x6682;&#x65F6;&#x672A;&#x5F97;&#x5230;&#x652F;&#x6301;&#xFF1B;&#x4F46;&#xFF0C;&#x5728; <code>style</code> &#x6807;&#x7B7E;&#x4E2D; <code>@import</code> &#x7684; CSS &#x6587;&#x4EF6;&#xFF0C;&#x88AB; A&#x3001;B &#x4E24;&#x4E2A;&#x9875;&#x9762;&#xFF08;<code>*.ux</code>&#xFF09;&#x5F15;&#x5165;&#xFF0C;&#x90A3;&#x4E48;&#x5BF9;&#x5E94;&#x7684; css &#x5185;&#x5BB9;&#xFF0C;&#x5C31;&#x4F1A;&#x88AB;&#x6253;&#x5165;&#x5BF9;&#x5E94;&#x9875;&#x9762;&#xFF08;&#x5373;&#x4FBF;&#x6709;&#x7684;&#x5185;&#x5BB9;&#x6CA1;&#x6709;&#x88AB;&#x4F7F;&#x7528;&#xFF09;&#xFF0C;&#x4ECE;&#x800C;&#x5BFC;&#x81F4;&#x4EE3;&#x7801;&#x4F53;&#x79EF;&#x7565;&#x6709;&#x589E;&#x52A0;&#xFF08;&#x5373;&#x4FBF;&#x53C2;&#x8003; <a href="https://forum.lovejade.cn/d/83-rpk">&#x5982;&#x4F55;&#x4F18;&#x5316;&#x300C;&#x5FEB;&#x5E94;&#x7528;&#x300D;rpk &#x5305;&#x4F53;&#x79EF;&#xFF1F;</a> &#x4E00;&#x6587;&#x4E2D;&#x7684;&#x65B9;&#x6CD5;&#xFF0C;&#x4E5F;&#x4E0D;&#x53EF;&#x907F;&#x514D;&#xFF09;&#x3002;&#x8FD9;&#x662F;&#x5FEB;&#x5E94;&#x7528;&#x6784;&#x5EFA;&#x672C;&#x8EAB;&#x5B58;&#x5728;&#x7684;&#x95EE;&#x9898;&#xFF0C;&#x4F7F;&#x7528; Tailwind CSS &#x4E5F;&#x4E0D;&#x4F8B;&#x5916;&#x3002;&#x540E;&#x7EED;&#x9700;&#x8981;&#x6253;&#x5305;&#x5DE5;&#x5177;&#x4F18;&#x5316;&#x3002;</p>
<p>&#x4EE5;&#x4E0A;&#xFF0C;&#x5C31;&#x662F;&#x5728; <code>&#x5FEB;&#x5E94;&#x7528;</code> &#x5F00;&#x53D1;&#x8FC7;&#x7A0B;&#x4E2D;&#xFF0C;&#x5F15;&#x5165; Tailwind CSS &#x6240;&#x9700;&#x7684;&#x64CD;&#x4F5C;&#x3001;&#x4EE5;&#x53CA;&#x5E38;&#x89C1;&#x95EE;&#x9898;&#x8BF4;&#x660E;&#x3002;&#x80AF;&#x5B9A;&#x8FD8;&#x6709;&#x5F02;&#x5E38;&#x66F4;&#x591A;&#x60C5;&#x51B5;&#x6CA1;&#x6709;&#x8003;&#x8651;&#x5230;&#xFF0C;&#x540E;&#x7EED;&#x4F1A;&#x9010;&#x6B65;&#x8865;&#x5145;&#xFF1B;&#x5982;&#x679C;&#x60A8;&#x5728;&#x5B9E;&#x9645;&#x8FD0;&#x7528;&#x8FC7;&#x7A0B;&#x4E2D;&#xFF0C;&#x6B22;&#x8BF7;&#x7559;&#x8A00;&#x4EA4;&#x6D41;&#x3001;&#x53CD;&#x9988;&#x3001;&#x5206;&#x4EAB;&#x3002;</p>
<p>2023 &#x5E74; 07 &#x6708; 05 &#x65E5;&#x5199;&#x4E8E;&#x3014;&#x6DF1;&#x5733;&#x798F;&#x7530;&#x3015;</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[快应用开发工具 6.4 版本发布]]></title><description><![CDATA[快应用开发者工具（IDE），专为快应用开发设计，支持快应用、卡片等开发调试、编译预览、打包上传、以及云测、远程预览.....并支持账号登录，应用关联，查看详情等；仍在不断快速迭代中，旨在让开发者能够更高效开发、调试、测试以及发布快应用。]]></description><link>https://quickapp.vivo.com.cn/quickapp-ide-v6-4-release/</link><guid isPermaLink="false">649beef6764c8700068204cf</guid><category><![CDATA[快应用开发工具]]></category><dc:creator><![CDATA[vivo-developer]]></dc:creator><pubDate>Wed, 28 Jun 2023 09:18:05 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>&#x5FEB;&#x5E94;&#x7528;&#x5DE5;&#x5177;&#x5F00;&#x53D1;&#x56E2;&#x961F;&#xFF0C;&#x4E8E; 2023 &#x5E74; 7 &#x6708; 3 &#x65E5;&#xFF0C;&#x53D1;&#x5E03; IDE &#x6700;&#x65B0;&#x7248;&#x672C;&#xFF1A; <a href="quickapp.vivo.com.cn/ku/">v6.4.0</a>&#x3002;</p>
<h2 id="v640-%E6%9B%B4%E6%96%B0%E8%AF%B4%E6%98%8E">v6.4.0 &#x66F4;&#x65B0;&#x8BF4;&#x660E;</h2>
<p>&#x5728;&#x8FD9;&#x4E2A;&#x7248;&#x672C;&#x4E2D;&#xFF0C;&#x5FEB;&#x5E94;&#x7528;&#x5DE5;&#x5177;&#x5F00;&#x53D1;&#x56E2;&#x961F;&#x505A;&#x4E86;&#x4E00;&#x4E9B;&#x66F4;&#x65B0;&#xFF0C;&#x540C;&#x65F6;&#x5BF9;&#x5DF2;&#x77E5;&#x95EE;&#x9898;&#x8FDB;&#x884C;&#x4E86;&#x4F18;&#x5316;&#xFF1B;&#x4E0B;&#x9762;&#x8DDF;&#x5927;&#x5BB6;&#x5206;&#x4EAB;&#x4E0B;&#xFF0C;&#x5728;&#x6B64;&#x6B21;&#x8FED;&#x4EE3;&#x4E2D;&#xFF0C;&#x6211;&#x4EEC;&#x505A;&#x7684;&#x4E00;&#x4E9B;&#x4E3B;&#x8981;&#x6539;&#x8FDB;&#x3002;</p>
<h3 id="%E4%BC%98%E5%8C%96%E6%9B%B4%E6%96%B0">&#x4F18;&#x5316;&#x66F4;&#x65B0;</h3>
<h4 id="%E5%8D%A1%E7%89%87%E5%B7%A5%E7%A8%8B%E5%A2%9E%E5%8A%A0%E5%88%86%E7%B1%BB">&#x5361;&#x7247;&#x5DE5;&#x7A0B;&#x589E;&#x52A0;&#x5206;&#x7C7B;</h4>
<p>&#x65B0;&#x5EFA;&#x5FEB;&#x5E94;&#x7528;&#x5361;&#x7247;&#xFF0C;&#x9009;&#x62E9;&#x6A21;&#x7248;&#x65F6;&#xFF0C;&#x533A;&#x5206;&#x4E86;&#x4E0D;&#x540C;&#x7684;&#x5382;&#x5546;&#x548C;&#x5361;&#x7247;&#x7C7B;&#x578B;&#x3002;<br>
<img src="https://vassets.vvstc.com/vassets/gob83/i/ee6hdpu3.jpg" width="700px"></p>
<h4 id="rpk-%E5%90%8D%E7%A7%B0%E4%B8%AD%E5%A2%9E%E5%8A%A0%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F%E7%9A%84%E4%BF%A1%E6%81%AF">rpk &#x540D;&#x79F0;&#x4E2D;&#x589E;&#x52A0;&#x73AF;&#x5883;&#x53D8;&#x91CF;&#x7684;&#x4FE1;&#x606F;</h4>
<p>&#x5982;&#x4E0B;&#x56FE;&#xFF0C;&#x70B9;&#x51FB;&#x300C;&#x6253;&#x5305;&#x300D;&#xFF0C;&#x6253;&#x51FA;&#x7684; rpk &#x540D;&#x79F0;&#xFF0C;&#x5E26;&#x6709;&#x73AF;&#x5883;&#x53D8;&#x91CF;&#xFF0C;&#x4FBF;&#x4E8E;&#x5F00;&#x53D1;&#x8005;&#x533A;&#x5206;&#x4E0D;&#x540C;&#x73AF;&#x5883;&#x7684; rpk&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x9009;&#x62E9;&#x6B63;&#x5F0F;&#x5305;&#xFF0C;&#x5219; NODE_ENV&#x4E3A; production&#xFF0C;&#x6253;&#x5305;&#x51FA;&#x6765;&#x7684; rpk &#x540D;&#x79F0;&#x5E26;&#x6709; production&#x3002;<br>
<img src="https://vassets.vvstc.com/vassets/gob83/i/cs497sa5.jpg" width="700px"></p>
<h3 id="%E4%BF%AE%E6%AD%A3">&#x4FEE;&#x6B63;</h3>
<p>&#x5BF9;&#x5DF2;&#x77E5;&#x95EE;&#x9898;&#x3001;&#x4EE5;&#x53CA;&#x7528;&#x6237;&#x53CD;&#x9988;&#x7684;&#x5EFA;&#x8BAE;&#xFF0C;&#x505A;&#x4E86;&#x6539;&#x8FDB;&#x4F18;&#x5316;&#xFF0C;&#x63D0;&#x5347;&#x4E86;&#x5F00;&#x53D1;&#x4F7F;&#x7528;&#x4F53;&#x9A8C;&#x3002;</p>
<h4 id="%E4%BF%AE%E5%A4%8D-git-%E6%8F%92%E4%BB%B6%E5%A4%B1%E6%95%88%E9%97%AE%E9%A2%98">&#x4FEE;&#x590D; git &#x63D2;&#x4EF6;&#x5931;&#x6548;&#x95EE;&#x9898;</h4>
<p>6.3.0 &#x7248;&#x672C;&#xFF0C;&#x6587;&#x4EF6;&#x4FEE;&#x6539;&#x540E;&#xFF0C;&#x5DE6;&#x4FA7;git&#x56FE;&#x6807;&#x663E;&#x793A;&#x51FA;&#x6587;&#x4EF6;&#x4FEE;&#x6539;&#xFF0C;&#x70B9;&#x51FB;&#x5217;&#x8868;&#x4E2D;&#x67D0;&#x4E2A;&#x4FEE;&#x6539;&#x7684;&#x6587;&#x4EF6;&#xFF0C;&#x63D0;&#x793A;&#x627E;&#x4E0D;&#x5230;&#x8BE5;&#x6587;&#x4EF6;&#x3002;<br>
<img src="https://vassets.vvstc.com/vassets/gob83/i/935aa72d.png" width="600px"></p>
<h4 id="%E4%BF%AE%E5%A4%8D-qaui-%E9%A2%84%E8%A7%88%E6%98%BE%E7%A4%BA%E9%97%AE%E9%A2%98">&#x4FEE;&#x590D; qaui &#x9884;&#x89C8;&#x663E;&#x793A;&#x95EE;&#x9898;</h4>
<p>&#x4FEE;&#x590D;&#x4E86; qaui &#x56FE;&#x6807;&#x65E0;&#x6CD5;&#x663E;&#x793A;&#x7684;&#x95EE;&#x9898;<br>
<img src="https://vassets.vvstc.com/vassets/gob83/i/3nso45xg.jpg" width="400px"></p>
<h4 id="%E4%BF%AE%E5%A4%8D%E8%AE%BE%E7%BD%AE-smart-%E5%90%8E%EF%BC%8C%E5%87%BA%E7%8E%B0%E7%99%BD%E5%B1%8F%E7%9A%84%E9%97%AE%E9%A2%98">&#x4FEE;&#x590D;&#x8BBE;&#x7F6E; SMART &#x540E;&#xFF0C;&#x51FA;&#x73B0;&#x767D;&#x5C4F;&#x7684;&#x95EE;&#x9898;</h4>
<img src="https://vassets.vvstc.com/vassets/gob83/i/6bax5947.png" width="700px">
<h4 id="%E4%BF%AE%E5%A4%8D-network-%E9%9D%A2%E6%9D%BF%E6%97%A0%E6%B3%95%E5%B1%95%E7%A4%BA%E7%9A%84%E9%97%AE%E9%A2%98">&#x4FEE;&#x590D; Network &#x9762;&#x677F;&#x65E0;&#x6CD5;&#x5C55;&#x793A;&#x7684;&#x95EE;&#x9898;</h4>
<p>&#x4E4B;&#x524D;&#x7248;&#x672C;&#xFF0C;Network &#x9762;&#x677F;&#x767D;&#x5C4F;&#xFF0C;&#x9700;&#x8981;&#x70B9;&#x51FB;&#x300C;&#x5237;&#x65B0;&#x9884;&#x89C8;&#x548C; Devtools &#x300D;&#x6309;&#x952E;&#x624D;&#x80FD;&#x6062;&#x590D;</p>
<h4 id="%E4%BF%AE%E5%A4%8D%E6%96%B0%E5%BB%BA%E5%B7%A5%E7%A8%8B%E7%89%88%E6%9C%AC%E4%B8%8D%E5%AF%B9%E5%BA%94%E7%9A%84%E9%97%AE%E9%A2%98">&#x4FEE;&#x590D;&#x65B0;&#x5EFA;&#x5DE5;&#x7A0B;&#x7248;&#x672C;&#x4E0D;&#x5BF9;&#x5E94;&#x7684;&#x95EE;&#x9898;</h4>
<p>&#x4E4B;&#x524D;&#x7248;&#x672C;&#xFF0C;&#x65B0;&#x5EFA;&#x5DE5;&#x7A0B;&#x5F39;&#x6846;&#x4E2D;&#x7684;&#x7248;&#x672C;&#x53F7;&#xFF0C;&#x4E0E; IDE &#x771F;&#x5B9E;&#x7248;&#x672C;&#x53F7;&#x4E0D;&#x5BF9;&#x5E94;<br>
<img src="https://vassets.vvstc.com/vassets/gob83/i/obndobe5.png" width="700px"></p>
<hr>
<p>2023 &#x5E74; IDE &#x7248;&#x672C;&#x66F4;&#x65B0;&#x65F6;&#x95F4;&#x7EBF;&#xFF1A;</p>
<ul>
<li>2023 &#x5E74; 7 &#x6708; 03 &#x65E5;&#xFF1A;<a href="https://quickapp.vivo.com.cn/quickapp-ide-v6-4-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 6.4.0 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>2023 &#x5E74; 4 &#x6708; 26 &#x65E5;&#xFF1A;<a href="https://bbs.quickapp.cn/forum.php?mod=viewthread&amp;tid=33217">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 6.3.0 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
</ul>
<p>2022 &#x5E74; IDE &#x7248;&#x672C;&#x66F4;&#x65B0;&#x65F6;&#x95F4;&#x7EBF;&#xFF1A;</p>
<ul>
<li>2022 &#x5E74; 7 &#x6708; 25 &#x65E5;&#xFF1A;<a href="https://forum.lovejade.cn/d/201-62">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 6.2 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
</ul>
<p>2021 &#x5E74; IDE &#x7248;&#x672C;&#x66F4;&#x65B0;&#x65F6;&#x95F4;&#x7EBF;&#xFF1A;</p>
<ul>
<li>10.28 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v5-1-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 5.1 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>9.2 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v5-0-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 5.0 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>7.26 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v4-1-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 4.1 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>6.30 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v4-0-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 4.0 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>5.27 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-10-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.10 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>4.13 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-9-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.9 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>3.11 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-8-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.8 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>2.4 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-7-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.7 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
</ul>
<p>2020 &#x5E74; IDE &#x7248;&#x672C;&#x66F4;&#x65B0;&#x65F6;&#x95F4;&#x7EBF;&#xFF1A;</p>
<ul>
<li>12.29 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-6-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.6 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>12.01 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-5-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.5 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>10.26 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-4-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.4 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>08.18 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-3-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.3 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>07.29 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-2-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.2 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>07.06 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-1-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.1 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>06.01 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.0 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[vivo 发布快应用「小说」组件]]></title><description><![CDATA[快应用是 基于手机硬件平台的新型应用形态，历经多年打磨，已成为主流轻应用平台。小说类应用具备用户规模大(中国网文用户 5 亿+)，用户阅读频率、用户粘度和营收相对高的特点，越来越多开发者，基于快应用平台，发布小说类应用。但，其中也会存在诸多痛点，基于如此背景，vivo 推出快应用「小说组件」，在此与广大快应用开发者分享。]]></description><link>https://quickapp.vivo.com.cn/vivo-release-quickapp-novel-component/</link><guid isPermaLink="false">63c4b94a77e2ca0006a8c8a1</guid><category><![CDATA[快应用]]></category><dc:creator><![CDATA[admin]]></dc:creator><pubDate>Fri, 30 Dec 2022 09:44:10 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p><a href="https://www.quickapp.cn/">&#x5FEB;&#x5E94;&#x7528;</a>&#x662F; &#x57FA;&#x4E8E;&#x624B;&#x673A;&#x786C;&#x4EF6;&#x5E73;&#x53F0;&#x7684;&#x65B0;&#x578B;&#x5E94;&#x7528;&#x5F62;&#x6001;&#xFF0C;&#x5386;&#x7ECF;&#x591A;&#x5E74;&#x6253;&#x78E8;&#xFF0C;&#x5DF2;&#x6210;&#x4E3A;&#x4E3B;&#x6D41;&#x8F7B;&#x5E94;&#x7528;&#x5E73;&#x53F0;&#x3002;&#x5C0F;&#x8BF4;&#x7C7B;&#x5E94;&#x7528;&#x5177;&#x5907;&#x7528;&#x6237;&#x89C4;&#x6A21;&#x5927;(&#x4E2D;&#x56FD;&#x7F51;&#x6587;&#x7528;&#x6237; 5 &#x4EBF;+)&#xFF0C;&#x7528;&#x6237;&#x9605;&#x8BFB;&#x9891;&#x7387;&#x3001;&#x7528;&#x6237;&#x7C98;&#x5EA6;&#x548C;&#x8425;&#x6536;&#x76F8;&#x5BF9;&#x9AD8;&#x7684;&#x7279;&#x70B9;&#xFF0C;&#x8D8A;&#x6765;&#x8D8A;&#x591A;&#x5F00;&#x53D1;&#x8005;&#xFF0C;&#x57FA;&#x4E8E;<strong>&#x5FEB;&#x5E94;&#x7528;</strong>&#x5E73;&#x53F0;&#xFF0C;&#x53D1;&#x5E03;&#x5C0F;&#x8BF4;&#x7C7B;&#x5E94;&#x7528;&#x3002;&#x4F46;&#xFF0C;&#x5176;&#x4E2D;&#x4E5F;&#x4F1A;&#x5B58;&#x5728;&#x8BF8;&#x591A;&#x75DB;&#x70B9;&#xFF0C;&#x57FA;&#x4E8E;&#x5982;&#x6B64;&#x80CC;&#x666F;&#xFF0C;&#x5FEB;&#x5E94;&#x7528;&#x8054;&#x76DF;&#x63A8;&#x51FA;&#x5FEB;&#x5E94;&#x7528;&#x300C;&#x5C0F;&#x8BF4;&#x7EC4;&#x4EF6;&#x300D;&#xFF0C;&#x5728;&#x6B64;&#x4E0E;&#x5E7F;&#x5927;&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x8005;&#x5206;&#x4EAB;&#x3002;</p>
<p><img src="https://zhanstatic.vivo.com.cn/wukong/img/c1a32fc0-6ec4-4eff-b18f-c501e450875d.gif" alt="vivo &#x5FEB;&#x5E94;&#x7528;&#x5C0F;&#x8BF4;&#x7EC4;&#x4EF6;" loading="lazy"></p>
<p><strong>&#x6E29;&#x99A8;&#x63D0;&#x9192;</strong>&#xFF1A;&#x622A;&#x81F3;&#x76EE;&#x524D;&#xFF0C;&#x6B64;&#x5C0F;&#x8BF4;&#x7EC4;&#x4EF6; vivo &#x5DF2;&#x7ECF;&#x652F;&#x6301;&#xFF0C;&#x8054;&#x76DF;&#x5176;&#x4ED6;&#x5382;&#x5546;&#x5C06;&#x4F1A;&#x9646;&#x7EED;&#x5F00;&#x653E;&#x3002;</p>
<h2 id="%E5%BF%AB%E5%BA%94%E7%94%A8%E5%B0%8F%E8%AF%B4%E5%BC%80%E5%8F%91%E7%8E%B0%E7%8A%B6">&#x5FEB;&#x5E94;&#x7528;&#x5C0F;&#x8BF4;&#x5F00;&#x53D1;&#x73B0;&#x72B6;</h2>
<p>&#x76EE;&#x524D;&#xFF0C;&#x57FA;&#x4E8E;&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x300C;&#x5C0F;&#x8BF4;&#x300D;&#x54C1;&#x7C7B;&#x5E94;&#x7528;&#xFF0C;&#x5C1A;&#x6709;&#x8BF8;&#x591A;&#x75DB;&#x70B9;&#xFF0C;&#x5927;&#x81F4;&#x5217;&#x4E3E;&#x5982;&#x4E0B;&#xFF1A;</p>
<h6 id="1%E3%80%81%E5%AE%8C%E6%88%90%E5%A4%9A%E4%B8%AA%E7%BB%84%E4%BB%B6%E7%BB%84%E5%90%88%E8%A3%85%E9%85%8D">1&#x3001;&#x5B8C;&#x6210;&#x591A;&#x4E2A;&#x7EC4;&#x4EF6;&#x7EC4;&#x5408;&#x88C5;&#x914D;</h6>
<p>&#x4F8B;&#x5982;&#x4F7F;&#x7528; swiper &#x7EC4;&#x4EF6;&#x548C; text &#x7EC4;&#x4EF6;&#x7EC4;&#x5408;&#x7684;&#x6A2A;&#x5411;&#x5C0F;&#x8BF4;&#x9605;&#x8BFB;<br>
&#x4F8B;&#x5982;&#x4F7F;&#x7528; list &#x7EC4;&#x4EF6;&#x548C; text &#x7EC4;&#x4EF6;&#x7EC4;&#x5408;&#x7684;&#x7AD6;&#x5411;&#x5C0F;&#x8BF4;&#x9605;&#x8BFB;<br>
&#x4E14;&#x7EC4;&#x5408;&#x65B9;&#x6848;&#x5F88;&#x96BE;&#x505A;&#x5230;&#x4E24;&#x8005;&#x517C;&#x5BB9;&#x7684;&#x52A8;&#x6001;&#x5207;&#x6362;&#xFF0C;&#x5F00;&#x53D1;&#x8005;&#x5F00;&#x53D1;&#x8D77;&#x6765;&#x5DE5;&#x4F5C;&#x91CF;&#x76F8;&#x5BF9;&#x4E5F;&#x6BD4;&#x8F83;&#x5927;&#x3002;</p>
<h6 id="2%E3%80%81%E5%AE%8C%E6%88%90%E5%B0%8F%E8%AF%B4%E6%95%B0%E6%8D%AE%E5%A4%84%E7%90%86">2&#x3001;&#x5B8C;&#x6210;&#x5C0F;&#x8BF4;&#x6570;&#x636E;&#x5904;&#x7406;</h6>
<p>&#x9700;&#x8981;&#x5F00;&#x53D1;&#x8005;&#x83B7;&#x53D6;&#x5230;&#x5C0F;&#x8BF4;&#x5185;&#x5BB9;&#x540E;&#xFF0C;&#x8FDB;&#x884C;&#x5206;&#x6BB5;&#x3001;&#x5206;&#x884C;&#x3001;&#x5206;&#x9875;&#xFF0C;&#x7136;&#x540E;&#x5C06;&#x6570;&#x636E;&#x585E;&#x5165;text&#x7EC4;&#x4EF6;&#x4E2D;&#xFF0C;&#x6570;&#x636E;&#x5904;&#x7406;&#x903B;&#x8F91;&#x662F;&#x6BD4;&#x8F83;&#x591A;&#x7684;&#x3002;</p>
<h6 id="3%E3%80%81%E5%AE%8C%E6%88%90%E5%A4%A7%E5%B1%8F%E9%80%82%E9%85%8D">3&#x3001;&#x5B8C;&#x6210;&#x5927;&#x5C4F;&#x9002;&#x914D;</h6>
<p>&#x9700;&#x8981;&#x5F00;&#x53D1;&#x8005;&#x5BF9;&#x4E8E;&#x6298;&#x53E0;&#x5C4F;&#x624B;&#x673A;&#x5927;&#x5C4F;&#x505A;&#x989D;&#x5916;&#x7684;&#x6587;&#x5B57;&#x9002;&#x914D;&#xFF0C;&#x53C8;&#x591A;&#x4E86;&#x4E00;&#x5C42;&#x9002;&#x914D;&#x7684;&#x5DE5;&#x4F5C;&#x3002;</p>
<h6 id="4%E3%80%81%E5%AE%8C%E6%88%90%E5%B9%BF%E5%91%8A%E5%BC%80%E5%8F%91">4&#x3001;&#x5B8C;&#x6210;&#x5E7F;&#x544A;&#x5F00;&#x53D1;</h6>
<p>&#x9700;&#x8981;&#x989D;&#x5916;&#x5728; list &#x7EC4;&#x4EF6;&#x6216;&#x8005; swiper &#x7EC4;&#x4EF6;&#x4E2D;&#x52A0;&#x5165;&#x5E7F;&#x544A;&#xFF0C;&#x5E7F;&#x544A;&#x9700;&#x8981;&#x989D;&#x5916;&#x5224;&#x65AD;&#xFF0C;&#x672A;&#x6709;&#x9884;&#x7559;&#x5E7F;&#x544A;&#x4F4D;&#x5BB9;&#x5668;&#x3002;</p>
<h6 id="5%E3%80%81%E9%98%85%E8%AF%BB%E4%BD%93%E9%AA%8C%E9%80%89%E6%8B%A9%E5%B0%91">5&#x3001;&#x9605;&#x8BFB;&#x4F53;&#x9A8C;&#x9009;&#x62E9;&#x5C11;</h6>
<p>&#x9605;&#x8BFB;&#x4F53;&#x9A8C;&#x4E0A;&#x65E0;&#x6CD5;&#x52A8;&#x6001;&#x7684;&#x6A2A;&#x7AD6;&#x5C4F;&#x9605;&#x8BFB;&#x9009;&#x62E9;&#xFF0C;&#x9650;&#x5236;&#x4E86;&#x7528;&#x6237;&#x7684;&#x9605;&#x8BFB;&#x559C;&#x597D;&#x9009;&#x62E9;</p>
<h6 id="6%E3%80%81%E5%BC%80%E5%8F%91%E6%88%90%E6%9C%AC%E9%AB%98">6&#x3001;&#x5F00;&#x53D1;&#x6210;&#x672C;&#x9AD8;</h6>
<p>&#x57FA;&#x4E8E;&#x4EE5;&#x4E0A;&#x4E00;&#x7CFB;&#x5217;&#x7684;&#x5F00;&#x53D1;&#xFF0C;&#x5BF9;&#x4E8E;&#x524D;&#x7AEF;&#x5F00;&#x53D1;&#x8005;&#x6765;&#x8BF4;&#x5F00;&#x53D1;&#x6210;&#x672C;&#x662F;&#x6BD4;&#x8F83;&#x9AD8;&#x7684;&#x3002;</p>
<p><img src="https://zhanstatic.vivo.com.cn/wukong/img/4d2e5b51-ad4d-4747-8cee-b58615fe3a4a.gif" alt="vivo &#x5FEB;&#x5E94;&#x7528;&#x5C0F;&#x8BF4;&#x7EC4;&#x4EF6;" loading="lazy"></p>
<h2 id="%E5%B0%8F%E8%AF%B4%E7%BB%84%E4%BB%B6%E6%96%B9%E6%A1%88">&#x5C0F;&#x8BF4;&#x7EC4;&#x4EF6;&#x65B9;&#x6848;</h2>
<p>&#x5C0F;&#x8BF4;&#x7EC4;&#x4EF6;&#x7684;&#x53D1;&#x5E03;&#xFF0C;&#x89E3;&#x51B3;&#x4E86;&#x4E0A;&#x8FF0;&#x4E00;&#x7CFB;&#x5217;&#x96BE;&#x9898;&#x3002;&#x6574;&#x4F53;&#x6548;&#x679C;&#x5982;&#x4E0B;&#xFF08;&#x5176;&#x4E2D;&#x5185;&#x5BB9;&#x5F15;&#x7528;&#x4E8E;&#x7F51;&#x7EDC;&#xFF0C;&#x4EC5;&#x7528;&#x4E8E;&#x6D4B;&#x8BD5;&#x67E5;&#x770B;&#x6548;&#x679C;&#xFF09;&#xFF1A;<br>
&#x57FA;&#x4E8E;&#x5C0F;&#x8BF4;&#x7EC4;&#x4EF6;&#xFF0C;&#x53EF;&#x4EE5;&#x5E2E;&#x60A8;&#x5FEB;&#x901F;&#x5B9E;&#x73B0;&#x4EE5;&#x4E0B;&#x57FA;&#x672C;&#x529F;&#x80FD;&#xFF1A;</p>
<h6 id="1%E3%80%81%E5%85%A8%E5%8A%9F%E8%83%BD%E6%A6%82%E8%A7%88%E3%80%81%E5%B7%A6%E5%8F%B3%E9%98%85%E8%AF%BB%E3%80%81%E4%B8%8A%E4%B8%8B%E9%98%85%E8%AF%BB">1&#x3001;&#x5168;&#x529F;&#x80FD;&#x6982;&#x89C8;&#x3001;&#x5DE6;&#x53F3;&#x9605;&#x8BFB;&#x3001;&#x4E0A;&#x4E0B;&#x9605;&#x8BFB;</h6>
<p><img src="https://zhanstatic.vivo.com.cn/wukong/img/003f0eb6-757d-4c59-98b4-3340e296860e.gif" alt loading="lazy"></p>
<h6 id="2%E3%80%81%E6%96%87%E5%AD%97%E5%8A%A8%E6%80%81%E5%A4%A7%E5%B0%8F%E5%92%8C%E8%83%8C%E6%99%AF%E3%80%81%E8%A1%8C%E9%97%B4%E8%B7%9D%E3%80%81%E5%B9%BF%E5%91%8A%E5%AE%B9%E5%99%A8">2&#x3001;&#x6587;&#x5B57;&#x52A8;&#x6001;&#x5927;&#x5C0F;&#x548C;&#x80CC;&#x666F;&#x3001;&#x884C;&#x95F4;&#x8DDD;&#x3001;&#x5E7F;&#x544A;&#x5BB9;&#x5668;</h6>
<p><img src="https://zhanstatic.vivo.com.cn/wukong/img/953d3b4d-d278-4d7a-aaa5-af680ac33658.gif" alt loading="lazy"></p>
<h6 id="3%E3%80%81%E5%A4%A7%E5%B1%8F%E9%98%85%E8%AF%BB%E6%96%87%E5%AD%97%E9%80%82%E9%85%8D">3&#x3001;&#x5927;&#x5C4F;&#x9605;&#x8BFB;&#x6587;&#x5B57;&#x9002;&#x914D;</h6>
<p><img src="https://zhanstatic.vivo.com.cn/wukong/img/00340c43-32d7-42f2-bc1b-29ffe34cb8b1.gif" alt loading="lazy"></p>
<h6 id="4%E3%80%81%E4%BC%98%E5%8C%96%E5%8A%9F%E8%83%BD">4&#x3001;&#x4F18;&#x5316;&#x529F;&#x80FD;</h6>
<p>preLoadPage &#x63A5;&#x53E3;(&#x8BE6;&#x89C1;&#x4E0B;&#x6587;&#x6280;&#x672F;&#x6587;&#x6863;) &#x53EF;&#x4EE5;&#x63D0;&#x524D;&#x9884;&#x52A0;&#x8F7D;&#x4E0B;&#x4E00;&#x9875;&#x5E7F;&#x544A;&#xFF0C;&#x63D0;&#x9AD8;&#x5E7F;&#x544A;&#x66DD;&#x5149;&#x7387;&#x3002;</p>
<h2 id="%E5%B0%8F%E8%AF%B4%E7%BB%84%E4%BB%B6%E7%89%B9%E7%82%B9">&#x5C0F;&#x8BF4;&#x7EC4;&#x4EF6;&#x7279;&#x70B9;</h2>
<h6 id="1%E3%80%81%E9%AB%98%E6%95%88%E3%80%81%E5%BF%AB%E6%8D%B7">1&#x3001;&#x9AD8;&#x6548;&#x3001;&#x5FEB;&#x6377;</h6>
<p>&#x53EA;&#x9700;&#x8981;&#x5C06;&#x5206;&#x6BB5;&#x7B26;&#x914D;&#x7F6E;&#x597D;&#xFF0C;&#x7136;&#x540E;&#x4E00;&#x952E;&#x585E;&#x5165;&#x6574;&#x4E2A;&#x7AE0;&#x8282;&#x6570;&#x636E;&#xFF0C;&#x5C06;&#x5E7F;&#x544A;&#x4F4D;&#x653E;&#x5165;&#x9884;&#x7559;&#x5BB9;&#x5668;&#xFF0C;&#x4E4B;&#x540E;&#x5C31;&#x53EF;&#x4EE5;&#x663E;&#x793A;&#x3002;</p>
<h6 id="2%E3%80%81%E5%85%BC%E5%AE%B9%E5%8E%9F%E6%9C%89%E5%B0%8F%E8%AF%B4%E6%96%B9%E6%A1%88">2&#x3001;&#x517C;&#x5BB9;&#x539F;&#x6709;&#x5C0F;&#x8BF4;&#x65B9;&#x6848;</h6>
<p>&#x5BF9;&#x4E8E;&#x5DF2;&#x6709;&#x5C0F;&#x8BF4;&#x65B9;&#x6848;&#xFF0C;&#x60F3;&#x8981;&#x5207;&#x91CF;&#x4F53;&#x9A8C;&#x5C0F;&#x8BF4;&#x7EC4;&#x4EF6;&#x53EF;&#x4EE5;&#x8FD9;&#x4E48;&#x505A;&#xFF1A;&#x5224;&#x65AD; vivo &#x5FEB;&#x5E94;&#x7528;&#x5F15;&#x64CE;&#x7248;&#x672C;&#xFF0C;&#x6839;&#x636E;&#x7248;&#x672C;&#x6765;&#x8DEF;&#x7531;&#x5230;&#x65B0;&#x7684;&#x5C0F;&#x8BF4;&#x7EC4;&#x4EF6;&#x754C;&#x9762;&#xFF0C;&#x7136;&#x540E;&#x663E;&#x793A;&#x5C0F;&#x8BF4;&#x3002;<a href="https://doc.quickapp.cn/features/system/device.html#devicehost1070">&#x7248;&#x672C;&#x5224;&#x65AD;&#x65B9;&#x6CD5;</a> &#xFF08;vivo &#x5E73;&#x53F0;&#x8981;&#x6C42; versionCode &#x5927;&#x4E8E;&#x7B49;&#x4E8E; 11010701&#xFF09;&#x3002;</p>
<pre><code>const device = require(&apos;@system.device&apos;)
const host = device.host
const packagename = host.package
const versionName = host.versionName
const versionCode = host.versionCode
</code></pre>
<h2 id="%E6%96%87%E6%A1%A3%E3%80%81%E6%BA%90%E7%A0%81%E3%80%81sample-%E4%BD%93%E9%AA%8C">&#x6587;&#x6863;&#x3001;&#x6E90;&#x7801;&#x3001;sample &#x4F53;&#x9A8C;</h2>
<ul>
<li>&#x8BE6;&#x7EC6;&#x6307;&#x5BFC;&#x6587;&#x6863;&#xFF1A; <a href="https://zhanstatic.vivo.com.cn/wukong/file/a048f644-a7fd-41dc-82e9-b37a434f2fa1.pdf">&#x5C0F;&#x8BF4;&#x7EC4;&#x4EF6;&#x6587;&#x6863;</a>&#xFF1B;</li>
<li>&#x793A;&#x4F8B;&#x6E90;&#x7801;&#xFF1A;<a href="https://zhanstatic.vivo.com.cn/wukong/file/0e00e49c-7ea6-4cb4-8afb-674ee1f69f1b.txt">Sample &#x793A;&#x4F8B;&#x6E90;&#x7801;</a>&#xFF1B;</li>
<li>&#x5728;&#x7EBF; Sample&#xFF1A;<a href="https://zhanstatic.vivo.com.cn/wukong/file/3729f8eb-c0bf-4407-8a29-d70447a04569.rpk">Sample rpk &#x4F53;&#x9A8C;</a>&#x3002;</li>
</ul>
<h2 id="%E6%8A%80%E6%9C%AF%E6%94%AF%E6%8C%81">&#x6280;&#x672F;&#x652F;&#x6301;</h2>
<p>&#x5982;&#x6709;&#x9002;&#x914D;&#x95EE;&#x9898;&#xFF0C;&#x5FEB;&#x5E94;&#x7528;&#x6280;&#x672F;&#x5F1F;&#x548C;&#x5F00;&#x53D1;&#x8005;&#xFF0C;&#x5C06;&#x5168;&#x529B;&#x7ED9;&#x4E88;&#x652F;&#x6301;&#x3002;</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[今日美句：canvas开发相关方法及流程]]></title><description><![CDATA[今日美句：canvas 开发相关方法及流程。]]></description><link>https://quickapp.vivo.com.cn/how-to-use-quickapp-canvas-to-achieve-beautiful-sentences/</link><guid isPermaLink="false">63c4b94a77e2ca0006a8c897</guid><category><![CDATA[快应用教程]]></category><dc:creator><![CDATA[xrbklmmt]]></dc:creator><pubDate>Mon, 10 Jan 2022 08:49:02 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><h2 id="%E4%B8%80%E3%80%81%E9%A6%96%E9%A1%B5%E6%97%A5%E5%8E%86">&#x4E00;&#x3001;&#x9996;&#x9875;&#x65E5;&#x5386;</h2>
<p><code>&#x7528;&#x4E8E;&#x5C55;&#x793A;&#x81EA;&#x5F53;&#x65E5;&#xFF0C;&#x81F3;&#x5F80;&#x540E;&#x4E00;&#x4E2A;&#x6708;&#x7684;&#x65E5;&#x5386;&#x6570;&#x3002;&#x6BCF;&#x201C;&#x5F20;&#x201D;&#x65E5;&#x5386;&#x5361;&#x7247;&#x7531;&#x56FE;&#x7247;&#x3001;&#x65E5;&#x671F;&#xFF08;&#x9633;&#x5386;&#x3001;&#x9634;&#x5386;&#xFF09;&#x53CA;&#x6BCF;&#x65E5;&#x91D1;&#x53E5;&#x7EC4;&#x6210;&#x3002;</code></p>
<h3 id="1%E5%B7%A6%E5%8F%B3%E5%88%87%E6%8D%A2">1.&#x5DE6;&#x53F3;&#x5207;&#x6362;</h3>
<img src="https://zhanstatic.vivo.com.cn/wukong/file/73a51575-6922-40f2-81e2-ee37d697ded1.gif" alt="&#x9996;&#x9875;&#x65E5;&#x5386;&#x5207;&#x6362;" style="zoom:50%;">
<p>&#x4F7F;&#x7528;<code>swiper</code>&#x7EC4;&#x4EF6;&#x53EF;&#x4EE5;&#x5B9E;&#x73B0;&#x5DE6;&#x53F3;&#x5207;&#x6362;&#x5F53;&#x524D;&#x65E5;&#x671F;&#x7684;&#x9700;&#x6C42;&#x3002;</p>
<p><code>swiper</code>&#x7EC4;&#x4EF6;&#x9700;&#x8981;&#x56FA;&#x5B9A;&#x4E00;&#x4E2A;&#x9AD8;&#x5EA6;&#xFF0C;&#x4E0D;&#x80FD;&#x7531;&#x5B50;&#x7EC4;&#x4EF6;&#x6491;&#x5F00;&#x3002;&#x9996;&#x9875;&#x6BCF;&#x201C;&#x5F20;&#x201D;&#x65E5;&#x5386;&#x5361;&#x7247;&#x9700;&#x5360;&#x4E00;&#x5C4F;&#xFF0C;&#x4F7F;&#x7528;&#x4E0B;&#x9762;&#x65B9;&#x6CD5;&#x83B7;&#x53D6;<code>pageHeight</code></p>
<ul>
<li>
<p>index.ux</p>
<pre><code class="language-js">async onInit() {
    // this.$app.$def.manifest.config.designWidth &#x53EF;&#x83B7;&#x53D6;&#x5DF2;&#x914D;&#x7F6E;designWidth(*&#x53EA;&#x8BFB;),&#x5982;&#x672A;&#x914D;&#x7F6E;&#x5219;&#x4F7F;&#x7528;&#x9ED8;&#x8BA4;designWidth
    const designWidth =
      this.$app.$def.manifest.config.designWidth || this.$app.$def.designWidth // &#x8FD9;&#x91CC;&#x5EFA;&#x8BAE;&#x5C06;&#x9ED8;&#x8BA4;designWidth&#x5373;`750`,&#x4F5C;&#x4E3A;&#x5E38;&#x91CF;&#x4FDD;&#x5B58;&#x5728;`app.ux`
    const { windowHeight, windowWidth } = await $utils.deviceGetInfo() // utils.js&#x4E2D;&#x65B9;&#x6CD5;&#x5DF2;&#x6CE8;&#x518C;&#x5230;&#x5168;&#x5C40;
    this.height = (windowHeight / windowWidth) * designWidth // pageHeight
  }
</code></pre>
</li>
<li>
<p>utils.js</p>
<pre><code class="language-js">/**
 * &#x83B7;&#x53D6;&#x8BBE;&#x5907;&#x4FE1;&#x606F;
 */
function deviceGetInfo() {
  return new Promise((resolve, reject) =&gt; {
    require(&apos;@system.device&apos;).getInfo({
      success: ret =&gt; {
        resolve(ret)
      }
    })
  })
}
</code></pre>
</li>
<li>
<p>app.ux</p>
<pre><code class="language-js">const $utils = require(&apos;[pathName]/utils&apos;).default
/* @desc: &#x6CE8;&#x5165;&#x65B9;&#x6CD5;&#x81F3;&#x5168;&#x5C40; global,&#x4EE5;&#x4FBF;&#x9875;&#x9762;&#x8C03;&#x7528; */
const hook2global = global.__proto__ || global
hook2global.$utils = $utils
</code></pre>
</li>
</ul>
<h3 id="2%E6%97%A5%E5%8E%86%E5%8D%A1%E7%89%87">2.&#x65E5;&#x5386;&#x5361;&#x7247;</h3>
<img src="https://zhanstatic.vivo.com.cn/wukong/img/dcccd2b0-0257-4ad9-b1a0-eb90a02f590b.png" alt="&#x65E5;&#x5386;&#x5361;&#x7247;" style="zoom:75%;">
<h4 id="2-1-span-idcalendar-image%E5%9B%BE%E7%89%87span">2-1. <span id="calendar-image">&#x56FE;&#x7247;</span></h4>
<h5 id="2-1-1-%E5%B1%85%E4%B8%AD">2-1-1. &#x5C45;&#x4E2D;</h5>
<p>&#x7531;&#x4E8E;&#x5C55;&#x793A;&#x5728;&#x5361;&#x7247;&#x7684;&#x80CC;&#x666F;&#x56FE;&#x7247;&#xFF0C;&#x4E0D;&#x4E00;&#x5B9A;&#x5927;&#x5C0F;&#x76F8;&#x540C;&#x3002;&#x6B64;&#x65F6;&#x53EF;&#x4EE5;&#x8BBE;&#x7F6E;&#x4E00;&#x4E2A;&#x56FA;&#x5B9A;&#x7684;&#x201C;box&quot;&#xFF0C;&#x6765;&#x7ED8;&#x5236;&#x56FE;&#x7247;&#x533A;&#x57DF;&#x3002;&#x8BE5;&#x6A21;&#x677F;&#x4E2D;&#x8BBE;&#x7F6E;&#x56FE;&#x7247;&#x5BBD;&#x9AD8;&#x6BD4;<code>(sw:sh)</code>&#x56FA;&#x5B9A;&#x4E3A;3:2&#x3002;</p>
<p>&#x4F7F;&#x7528;<code>ctx.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)</code>&#x8FDB;&#x884C;&#x7ED8;&#x5236;&#x65F6;&#xFF0C;&#x9700;&#x8981;&#x6CE8;&#x610F;&#xFF1A;</p>
<ul>
<li>
<p>&#x5982;&#x679C;&#x56FE;&#x7247;&#x7684;&#x5B9E;&#x9645;&#x9AD8;&#xFF1E;&#xFF1D; &#x201C;box&#x201D;&#x7684;&#x9AD8;&#xFF0C;&#x5219;&#x9700;&#x7ED8;&#x5236;&#x7684;&#x56FE;&#x7247;&#x5BBD;&#x5EA6;<code>dw</code>&#x4E3A;<code>sw</code>&#xFF0C;&#x518D;&#x8BA1;&#x7B97;&#x51FA;<code>dh</code></p>
</li>
<li>
<p>&#x5982;&#x679C;&#x56FE;&#x7247;&#x7684;&#x5B9E;&#x9645;&#x9AD8; &lt; &#x201C;box&#x201D;&#x7684;&#x9AD8;&#xFF0C;&#x5219;&#x9700;&#x7ED8;&#x5236;&#x7684;&#x56FE;&#x7247;&#x9AD8;&#x5EA6;<code>dh</code>&#x4E3A;<code>sh</code>&#xFF0C;&#x518D;&#x8BA1;&#x7B97;&#x51FA;<code>dw</code></p>
</li>
</ul>
<pre><code class="language-js">const sw = this.width
const sh = this.width / (3 / 2)
let dw = sw
let dh = dw / (img.width / img.height)
if (dh &lt; sh) {
   dh = sh
   dw = dh * (img.width / img.height)
 }
</code></pre>
<h5 id="2-1-2-%E6%98%8E%E6%9A%97">2-1-2. &#x660E;&#x6697;</h5>
<p>&#x9996;&#x9875;&#x7684;&#x56FE;&#x7247;&#x660E;&#x6697;&#x8BBE;&#x7F6E;&#x4E00;&#x4E2A;&#x9ED8;&#x8BA4;&#x503C;&#x3002;&#x9700;&#x8981;&#x4ECE;&#x7236;&#x7EC4;&#x4EF6;&#x4F20;&#x9012;&#xFF0C;&#x8BE6;&#x7EC6;&#x5728;<a href="#card-mask">&#x5361;&#x7247;&#x5206;&#x4EAB;-&#x660E;&#x6697;</a>&#x4E2D;&#x8BF4;&#x660E;&#x3002;</p>
<h4 id="2-2-%E6%97%A5%E5%8E%86">2-2. &#x65E5;&#x5386;</h4>
<p><code>&#x65E5;&#x5386;&#x90E8;&#x5206;&#xFF0C;&#x5206;&#x4E3A;&#x9634;&#x5386;&#x3001;&#x9633;&#x5386;&#x3002;</code></p>
<h5 id="2-2-1-%E6%97%A5%E5%8E%86%E6%95%B0%E6%8D%AE">2-2-1. &#x65E5;&#x5386;&#x6570;&#x636E;</h5>
<p>&#x8FD9;&#x91CC;&#x76F4;&#x63A5;&#x627E;&#x4E86;&#x4E00;&#x4E2A;js&#x5E93;&#x53BB;&#x83B7;&#x53D6;&#x5230;&#x65E5;&#x671F;&#x76F8;&#x5173;&#x4FE1;&#x606F;<code>calendar</code>&#xFF1A;<a href="https://github.com/jjonline/calendar.js">GitHub&#x5730;&#x5740;</a></p>
<img src="https://zhanstatic.vivo.com.cn/wukong/img/77cc2a55-2538-4d8e-8a26-fb423b770ccenwebp.png.webp" alt="calendar-info">
<h5 id="2-2-2-%E7%BB%98%E5%88%B6%E9%98%B4%E5%8E%86">2-2-2. &#x7ED8;&#x5236;&#x9634;&#x5386;</h5>
<p>&#x5E74;&#x6708;&#x65E5;&#x4EE5;&#x201C;&#x5217;&#x201D;&#x7684;&#x5F62;&#x5F0F;&#x6392;&#x7248;&#xFF0C;&#x8986;&#x76D6;&#x5728;&#x56FE;&#x7247;&#x4E0A;&#x3002;&#x6839;&#x636E;&#x83B7;&#x53D6;&#x5230;&#x7684;&#x65E5;&#x5386;&#x6570;&#x636E;&#xFF0C;&#x9700;&#x8981;&#x4F7F;&#x7528;&#x7684;&#x4FE1;&#x606F;&#x6709;</p>
<pre><code class="language-js">const { Animal, IDayCn, IMonthCn, gzDay, gzMonth, gzYear } = calendar
</code></pre>
<p>&#x65E5;&#x671F;&#x5185;&#x5BB9;&#x6574;&#x4F53;&#x9760;&#x53F3;&#xFF0C;&#x5148;&#x5B9A;&#x4E49;&#x4E00;&#x4E9B;&#x9700;&#x8981;&#x7684;&#x5E38;&#x91CF;&#x3001;&#x53D8;&#x91CF;&#x3002;&#x5E38;&#x91CF;&#x6570;&#x503C;&#x5E76;&#x65E0;&#x56FA;&#x5B9A;&#xFF0C;&#x4F46;&#x5EFA;&#x8BAE;&#x6839;&#x636E;<strong>&#x5361;&#x7247;&#x5BBD;&#x5EA6;</strong>&#xFF08;&#x9996;&#x9875;&#x65E5;&#x5386;&#x5BBD;&#x5EA6;&#x4E3A;&#x9875;&#x9762;&#x5BBD;&#x5EA6;&#xFF0C;&#x5373;<code>designWidth</code>&#xFF09;&#xFF0C;<strong>&#x6309;&#x6BD4;&#x4F8B;</strong>&#x8BA1;&#x7B97;&#xFF0C;&#x63D0;&#x9AD8;<strong>&#x517C;&#x5BB9;&#x6027;</strong>&#xFF1A;</p>
<pre><code class="language-js">const YTD_SIZE = sw / 28 // &#x5E74;&#x6708;&#x53CA;&#x661F;&#x671F; &#x6587;&#x5B57;&#x5927;&#x5C0F;
const FIRST_WORD_TOP = sh / 6.25, // &#x6BCF;&#x5217;&#x6587;&#x5B57;&#x5185;&#x5BB9;&#xFF0C;&#x9996;&#x5B57;&#x7B26;&#x7684;&#x4E0A;&#x8FB9;&#x8DDD;
      LINE_HEIGHT = YTD_SIZE + 10, // &#x5B57;&#x4F53;&#x5927;&#x5C0F;&#x52A0;&#x4E0A;&#x4E0B;&#x95F4;&#x8DDD;&#x603B;&#x548C;10
      LETTER_SPACING = YTD_SIZE + 10 // &#x5B57;&#x4F53;&#x5927;&#x5C0F;&#x52A0;&#x5DE6;&#x53F3;&#x95F4;&#x8DDD;&#x603B;&#x548C;10
// &#x7B2C;&#x4E00;&#x4E2A;&#x9700;&#x8981;&#x7ED8;&#x5236;&#x7684;&#x65E5;&#x671F;&#x5B57;&#x7B26;&#x7684;&#x521D;&#x59CB;&#x5750;&#x6807; (dx,dy)
    let dx = sw * 0.76, 
      dy = FIRST_WORD_TOP
</code></pre>
<p>&#x7531;&#x4E8E;&#x6587;&#x5B57;&#x5185;&#x5BB9;&#x4EE5;&#x201C;&#x5217;&#x201D;&#x7684;&#x5F62;&#x5F0F;&#x6392;&#x7248;&#xFF0C;&#x5219;&#x6BCF;&#x7ED8;&#x5236;&#x4E00;&#x4E2A;&#x5B57;&#x7B26;&#xFF0C;<code>dy</code>&#x5C31;&#x9700;&#x8981;&#x589E;&#x52A0;&#x4E00;&#x4E2A;&#x6587;&#x5B57;&#x7684;<code>lineHeight</code>&#xFF1A;</p>
<pre><code class="language-js">lunarDateHandler(ctx, str, dx, dy, lineHieght) {
    str.split(&apos;&apos;).forEach(ele =&gt; { // calendar&#x8FD4;&#x56DE;&#x7684;&#x65E5;&#x671F;&#x4FE1;&#x606F;&#xFF0C;&#x4E0D;&#x4E00;&#x5B9A;&#x662F;&#x4E00;&#x4E2A;&#x5B57;&#x7B26;&#xFF0C;&#x6BD4;&#x5982; gzMonth=&#x201C;&#x620A;&#x620C;&#x201D;&#x7B49;
      ctx.fillText(ele, dx, dy)
      dy += lineHieght
    })
    return dy // &#x8FD4;&#x56DE;&#x65B0;&#x7684;dy&#x7528;&#x4E8E;&#x7ED8;&#x5236;&#x5206;&#x5272;&#x7EBF;&#x7684;&#x9AD8;
}
</code></pre>
<p>&#x6BCF;&#x5217;&#x6587;&#x672C;&#x5185;&#x5BB9;&#x7684;&#x5DE6;&#x8FB9;&#xFF0C;&#x6709;&#x4E00;&#x6761;<strong>&#x5206;&#x5272;&#x7EBF;</strong>&#x3002;&#x6709;&#x4E9B;&#x5206;&#x5272;&#x7EBF;&#x4F4D;&#x4E8E;&#x4E24;&#x5217;&#x6587;&#x5B57;&#x4E4B;&#x95F4;&#xFF0C;&#x7ED9;&#x5206;&#x5272;&#x7EBF;&#x5B9A;&#x4E49;&#x4E00;&#x4E9B;&#x5DE6;&#x53F3;&#x7684;<code>&quot;margin&quot;</code>&#xFF1A;</p>
<pre><code class="language-js">const BORDER_LEFT = 10, // margin-left
      BORDER_RIGHT = 10, // margin-right
      BORDER_TOP = FIRST_WORD_TOP - YTD_SIZE, // &#x6BCF;&#x5217;&#x6587;&#x5B57;&#x5185;&#x5BB9;&#x7684;&#x5DE6;&#x8FB9;&#x6846;,&#x5DE6;&#x53F3;&#x8FB9;&#x8DDD;&#x53CA;&#x4E0A;&#x8FB9;&#x8DDD;
</code></pre>
<p>&#x56E0;&#x4E3A;canvas&#x7ED8;&#x5236;&#x6587;&#x5B57;&#x65F6;&#xFF0C;&#x5E76;&#x4E0D;&#x5B58;&#x5728;&#x201C;&#x884C;&#x9AD8;&#x201D;&#x7684;&#x6982;&#x5FF5;&#xFF0C;&#x5728;&#x7ED8;&#x5236;&#x6BCF;&#x5217;&#x6700;&#x540E;&#x4E00;&#x4E2A;&#x5B57;&#x7B26;&#x65F6;&#xFF0C;&#x5B9E;&#x9645;&#x4E0A;&#x53EA;&#x9700;&#x8981;&#x518D;&#x589E;&#x52A0;&#x4E00;&#x4E2A;&#x5B57;&#x7B26;&#x4E0B;&#x8FB9;&#x8DDD;&#x7684;&#x503C;&#xFF08;&#x5373; <code>(lineHieght-YTD_SIZE)/2</code>&#xFF0C;&#x8FD4;&#x56DE;&#x7684;&#x5C31;&#x662F;&#x5B9E;&#x9645;&#x9700;&#x8981;&#x7684;&#x7EBF;&#x6761;&#x9AD8;&#x5EA6;&#xFF0C;&#x4F46;&#x662F;&#x6211;&#x4EEC;&#x5E76;&#x6CA1;&#x6709;&#x5728;<code>lunarDateHandler</code>&#x65B9;&#x6CD5;&#x4E2D;&#x5904;&#x7406;&#xFF0C;&#x800C;&#x662F;&#x76F4;&#x63A5;&#x7ED9;dy&#x589E;&#x52A0;&#x4E86;&#x4E00;&#x4E2A;<code>lineHeight</code></p>
<pre><code class="language-js">this.lunarDateBorderLeft(
      ctx,
      dx - BORDER_RIGHT,
      BORDER_TOP,
      dx - BORDER_RIGHT,
      dy - YTD_SIZE  // &#x8FD9;&#x91CC;&#x9700;&#x8981;&#x51CF;&#x53BB;&#x4E00;&#x4E2A;&#x5B57;&#x7B26;&#x9AD8;&#x5EA6;&#xFF0C;&#x89C6;&#x89C9;&#x4E0A;&#x4F7F;&#x6587;&#x5B57;&#x4E0A;&#x8FB9;&#x8DDD;&#x548C;&#x7EBF;&#x6761;&#x4E0A;&#x8FB9;&#x8DDD;&#x5BF9;&#x9F50;&#xFF0C;&#x8FBE;&#x5230;&#x5B57;&#x7B26;&#x62E5;&#x6709;&#x201C;&#x884C;&#x9AD8;&#x201D;&#x7684;&#x6548;&#x679C;
    )
/**
 * &#x7ED8;&#x5236;&#x7EBF;&#x6761;&#x7684;&#x65B9;&#x6CD5;
 */
lunarDateBorderLeft(ctx, x0, y0, x1, y1) {
    ctx.moveTo(x0, y0)
    ctx.lineTo(x1, y1)
    ctx.stroke()
}
</code></pre>
<h5 id="2-2-3-%E7%BB%98%E5%88%B6%E9%98%B3%E5%8E%86">2-2-3. &#x7ED8;&#x5236;&#x9633;&#x5386;</h5>
<p>&#x5E74;&#x6708;&#x53CA;&#x661F;&#x671F;&#xFF1A;</p>
<p>&#x200B;	&#x7B80;&#x5355;&#x5B9A;&#x4E49;&#x4E00;&#x4E2A;(x,y)&#xFF0C;&#x4F7F;&#x5F97;&#x6587;&#x5B57;&#x5185;&#x5BB9;&#x4F4D;&#x4E8E;<strong>&#x53F3;&#x4E0B;&#x89D2;</strong>&#x5373;&#x53EF;&#xFF0C;&#x5EFA;&#x8BAE;&#x6839;&#x636E;&#x5361;&#x7247;&#x5BBD;&#x5EA6;&#xFF0C;<strong>&#x6309;&#x6BD4;&#x4F8B;</strong>&#x6765;&#x8BA1;&#x7B97;&#x3002;</p>
<p>&#x5F53;&#x65E5;&#x65E5;&#x671F;&#xFF1A;</p>
<p>&#x200B;	&#x7B80;&#x5355;&#x5B9A;&#x4E49;&#x4E00;&#x4E2A;(x,y)&#xFF0C;&#x4F7F;&#x5F97;&#x6587;&#x5B57;&#x5185;&#x5BB9;&#x4F4D;&#x4E8E;<strong>&#x5DE6;&#x4E0B;&#x89D2;</strong>&#x5373;&#x53EF;&#xFF0C;&#x5EFA;&#x8BAE;&#x6839;&#x636E;&#x5361;&#x7247;&#x5BBD;&#x5EA6;&#xFF0C;<strong>&#x6309;&#x6BD4;&#x4F8B;</strong>&#x6765;&#x8BA1;&#x7B97;&#x3002;</p>
<h5 id="2-2-4-%E6%AF%8F%E6%97%A5%E9%87%91%E5%8F%A5">2-2-4. &#x6BCF;&#x65E5;&#x91D1;&#x53E5;</h5>
<p><code>&#x4E0B;&#x65B9;&#x7684;&#x6587;&#x672C;&#x5185;&#x5BB9;&#xFF0C;&#x4E0A;&#x4E0B;&#x5C45;&#x4E2D;&#x4E14;&#x6362;&#x884C;&#x5C55;&#x793A;&#x3002;</code></p>
<p>&#x6839;&#x636E;&#x5361;&#x7247;&#x7684;&#x9AD8;&#x5EA6;&#xFF08;&#x7531;&#x4E8E;&#x9996;&#x9875;&#x5360;&#x4E00;&#x5C4F;&#xFF0C;&#x5373;<code>pageHeight</code>&#xFF09;&#x51CF;&#x53BB;&#x4E0A;&#x65B9;&#x56FE;&#x7247;&#x53CA;&#x65E5;&#x671F;&#x7684;&#x9AD8;&#x5EA6;&#xFF0C;&#x8BA1;&#x7B97;&#x51FA;&#x5269;&#x4F59;&#x7684;&#x3001;&#x53EF;&#x7528;&#x4E8E;&#x5C55;&#x793A;&#x6587;&#x5B57;&#x5185;&#x5BB9;&#x7684;&#x9AD8;&#x5EA6;<code>contentHeight</code></p>
<pre><code class="language-js">const contentHeight = this.height - sh
</code></pre>
<p>&#x5B9A;&#x4E49;<strong>&#x56FA;&#x5B9A;</strong>&#x6587;&#x5B57;&#x5185;&#x5BB9;<strong>&#x5DE6;&#x8FB9;&#x8DDD;</strong>&#x53CA;<strong>&#x6BCF;&#x884C;&#x5BBD;&#x5EA6;</strong></p>
<pre><code class="language-js">const lineWidth = $utils.lineWidthHandler(w) // &#x56FA;&#x5B9A;&#x6BCF;&#x884C;&#x5BBD;&#x5EA6;
const default_drawX = w * 0.06 // &#x56FA;&#x5B9A;&#x4E00;&#x4E2A;&#x5DE6;&#x8FB9;&#x8DDD;
</code></pre>
<h5 id="2-2-5-%E5%BC%80%E5%A7%8B%E7%BB%98%E5%88%B6">2-2-5. &#x5F00;&#x59CB;&#x7ED8;&#x5236;</h5>
<ul>
<li>&#x7ED8;&#x5236;&#x524D;&#xFF1A;</li>
</ul>
<pre><code class="language-js">// &#x83B7;&#x53D6;&#x6587;&#x5B57;&#x5185;&#x5BB9;&#x603B;&#x5BBD;&#x5EA6;
const txtToatalWidth = ctx.measureText(content).width // &#x8FD9;&#x4E2A;&#x5BBD;&#x5EA6;&#x548C;&#x6587;&#x5B57;&#x5927;&#x5C0F;&#x53CA;&#x6587;&#x5B57;&#x5185;&#x5BB9;&#x7684;&#x957F;&#x5EA6;&#x6709;&#x5173;
let drawTxt = &apos;&apos; // &#x5F53;&#x524D;&#x7ED8;&#x5236;&#x7684;&#x5185;&#x5BB9;
let drawLine = 1 // &#x7B2C;&#x51E0;&#x884C;&#x5F00;&#x59CB;&#x7ED8;&#x5236;
let drawIndex = 0 // &#x5F53;&#x524D;&#x7ED8;&#x5236;&#x5185;&#x5BB9;&#x7684;&#x7D22;&#x5F15;
</code></pre>
<ul>
<li>
<p>&#x7ED8;&#x5236;&#x65B9;&#x6CD5;</p>
<p>&#x9700;&#x8981;&#x7ED8;&#x5236;&#x5185;&#x5BB9;&#x7684;&#x5BBD;&#x5EA6;<code>ctx.measureText(drawTxt).width</code>&#xFF1C;&#x6BCF;&#x884C;&#x5BBD;&#x5EA6;<code>lineWidth</code>&#xFF0C;&#x5219;&#x76F4;&#x63A5;&#x7ED8;&#x5236;&#xFF1A;</p>
<pre><code class="language-js"> if (txtToatalWidth &lt;= lineWidth) {
    ctx.fillText(content, drawX, drawY)
} 
</code></pre>
<p>&#x9700;&#x8981;&#x7ED8;&#x5236;&#x5185;&#x5BB9;&#x7684;&#x5BBD;&#x5EA6;<code>ctx.measureText(drawTxt).width</code>&#xFF1E;&#x6BCF;&#x884C;&#x5BBD;&#x5EA6;<code>lineWidth</code>&#xFF1A;</p>
<pre><code class="language-js">for (let i = 0; i &lt; content.length; i++) {
	drawTxt += content[i]
if (ctx.measureText(drawTxt).width &gt;= lineWidth) {
        if (drawLine &gt;= 10) { // &#x7ED8;&#x5236;&#x7684;&#x884C;&#x6570;&#x5927;&#x4E8E;10&#x65F6;&#xFF0C;&#x4E0D;&#x518D;&#x8FDB;&#x884C;&#x7ED8;&#x5236;&#xFF0C;&#x4EE5;&#x7701;&#x7565;&#x53F7;&#x7684;&#x5F62;&#x5F0F;&#x5C55;&#x793A;
          ctx.fillText(content.substring(drawIndex, i) + &apos;..&apos;, drawX, drawY)
          break
        } else {
          ctx.fillText(content.substring(drawIndex, i + 1), drawX, drawY)
          drawIndex = i + 1
          drawLine += 1
          drawY += lineHeight
          drawTxt = &apos;&apos;
        }
      } else {
        //   &#x5185;&#x5BB9;&#x7ED8;&#x5236;&#x5B8C;&#x6BD5;&#xFF0C;&#x4F46;&#x662F;&#x5269;&#x4E0B;&#x7684;&#x5185;&#x5BB9;&#x5BBD;&#x5EA6;&#x4E0D;&#x5230;lineWidth
        if (i === content.length - 1) {
          const lastConten = content.substring(drawIndex)
          ctx.fillText(lastConten, drawX, drawY)
        }
      }
   } 
}
</code></pre>
</li>
<li>
<p>&#x5C01;&#x88C5;&#x65B9;&#x6CD5;</p>
<p>&#x6B64;&#x65F6;&#x53EF;&#x4EE5;&#x5C06;<strong>&#x6587;&#x672C;&#x5185;&#x5BB9;&#x6362;&#x884C;</strong>&#x65B9;&#x6CD5;&#x5C01;&#x88C5;&#xFF0C;&#x547D;&#x540D;&#x4E3A;<code>textWrap</code>&#xFF1A;</p>
<pre><code class="language-js">function textWrap(ctx,content,lineWidth,lineHeight,drawX,drawY){
  if (txtToatalWidth &lt;= lineWidth) {
  // &#x9700;&#x8981;&#x7ED8;&#x5236;&#x5185;&#x5BB9;&#x7684;&#x5BBD;&#x5EA6;`ctx.measureText(drawTxt).width`&#xFF1C;&#x6BCF;&#x884C;&#x5BBD;&#x5EA6;`lineWidth`&#xFF0C;&#x5219;&#x76F4;&#x63A5;&#x7ED8;&#x5236;&#xFF1A;
    ctx.fillText(content, drawX, drawY)
  } else{
      // &#x9700;&#x8981;&#x7ED8;&#x5236;&#x5185;&#x5BB9;&#x7684;&#x5BBD;&#x5EA6;`ctx.measureText(drawTxt).width`&#xFF1E;&#x6BCF;&#x884C;&#x5BBD;&#x5EA6;`lineWidth`&#xFF1A;
    ...
  }
}
</code></pre>
</li>
</ul>
<h2 id="%E4%BA%8C%E3%80%81%E5%8D%A1%E7%89%87%E5%88%86%E4%BA%AB">&#x4E8C;&#x3001;&#x5361;&#x7247;&#x5206;&#x4EAB;</h2>
<p><code>&#x5C06;&#x9700;&#x8981;&#x5206;&#x4EAB;&#x7684;&#x5185;&#x5BB9;&#xFF08;&#x91D1;&#x53E5;&#x3001;&#x8BD7;&#x6B4C;/&#x8BCD;&#xFF09;&#xFF0C;&#x8FDB;&#x884C;&#x76F8;&#x5E94;&#x7F16;&#x8F91;&#x540E;&#xFF0C;&#x751F;&#x6210;&#x56FE;&#x7247;&#x4FDD;&#x5B58;&#x5230;&#x76F8;&#x518C;&#xFF0C;&#x5E76;&#x5206;&#x4EAB;&#x5230;&#x5404;&#x5E73;&#x53F0;&#x3002;</code></p>
<h3 id="1-span-idcalendar-text%E5%88%86%E4%BA%AB%E5%86%85%E5%AE%B9span">1. <span id="calendar-text">&#x5206;&#x4EAB;&#x5185;&#x5BB9;</span></h3>
<h4 id="1-1-%E9%87%91%E5%8F%A5%E6%A8%A1%E6%9D%BF-%E6%97%A5%E5%8E%86%E5%BD%A2%E5%BC%8F">1-1. &#x91D1;&#x53E5;&#x6A21;&#x677F; (&#x65E5;&#x5386;&#x5F62;&#x5F0F;)</h4>
<img src="https://zhanstatic.vivo.com.cn/wukong/img/19d4525d-d9be-4bcd-9968-8e9179eb0bc1.jpg" alt="&#x65E5;&#x5386;&#x5361;&#x7247;" style="zoom:30%">
<h5 id="1-1-1-%E5%9B%BA%E5%AE%9A%E5%8D%A1%E7%89%87%E5%AE%BD%E5%BA%A6">1-1-1. &#x56FA;&#x5B9A;&#x5361;&#x7247;&#x5BBD;&#x5EA6;</h5>
<p>&#x5B9A;&#x4E49;&#x4E00;&#x4E2A;&#x56FA;&#x5B9A;&#x7684;&#x5BBD;&#x5EA6;&#xFF0C;&#x5EFA;&#x8BAE;&#x6839;&#x636E;<code>designWidth</code>&#xFF0C;&#x6309;&#x6BD4;&#x4F8B;&#x8BA1;&#x7B97;</p>
<pre><code class="language-js">let designWidth = this.$app.$def.manifest.config.designWidth || this.$app.$def.designWidth
this.width = designWidth * 0.9
</code></pre>
<h5 id="1-1-2-%E8%AE%A1%E7%AE%97%E5%8D%A1%E7%89%87%E9%AB%98%E5%BA%A6">1-1-2. &#x8BA1;&#x7B97;&#x5361;&#x7247;&#x9AD8;&#x5EA6;</h5>
<pre><code class="language-js">this.fontSize = this.width/21 // &#x968F;&#x610F;&#x5B9A;&#x4E49;&#x4E00;&#x4E2A;&#x5B57;&#x4F53;&#x5927;&#x5C0F;
this.lineHeight = this.width/21 + 20 // &#x6839;&#x636E;&#x5B57;&#x4F53;&#x5927;&#x5C0F;&#x589E;&#x52A0;&#x201C;&#x4E0A;&#x4E0B;&#x95F4;&#x8DDD;&#x201D;&#xFF0C;&#x5B9A;&#x4E49;&#x201C;&#x884C;&#x9AD8;&#x201D;
const lineWidth = $utils.lineWidthHandler(this.width) // &#x56FA;&#x5B9A;&#x6BCF;&#x884C;&#x5BBD;&#x5EA6;
this.lines = (this.info.content.length * this.fontSize) / lineWidth // &#x8BA1;&#x7B97;&#x603B;&#x884C;&#x6570;
const otherLines = this.lineHeight * 5 // slogan&#x53CA;source&#x9884;&#x7559;&#x9AD8;&#x5EA6;
const padding = this.width / 7.5 // &#x6587;&#x672C;&#x5185;&#x5BB9;&#x4E0A;&#x4E0B;padding
// &#x56FE;&#x7247;&#x5BBD;&#x9AD8;&#x6BD4;3:2
const imgHeight = this.width / 1.5
// &#x5361;&#x7247;&#x6700;&#x5C0F;&#x9AD8;&#x5EA6;
const minHeight = imgHeight * 2
const padding = this.lineHeight * 4
this.height = this.lines * this.lineHeight + padding + imgHeight + otherLines
this.height = this.height &lt; minHeight ? minHeight : this.height
</code></pre>
<p>&#x7ED8;&#x5236;&#x6B65;&#x9AA4;&#x53CA;&#x65B9;&#x6CD5;&#x540C;&#x65E5;&#x5386;&#x5361;&#x7247;&#x3002;&#x6B64;&#x65F6;&#xFF0C;&#x53EF;&#x4EE5;&#x5C06;&#x65E5;&#x5386;&#x201C;&#x5361;&#x7247;&#x201D;<strong>&#x4E0B;&#x65B9;&#x5185;&#x5BB9;</strong>&#x7684;&#x7ED8;&#x5236;&#x65B9;&#x6CD5;<strong>&#x5C01;&#x88C5;</strong>&#xFF0C;&#x53EA;&#x9700;&#x8981;&#x4F20;&#x9012;&#x5361;&#x7247;&#x7684;&#x5BBD;&#x3001;&#x9AD8;&#xFF0C;&#x6587;&#x5B57;&#x5927;&#x5C0F;&#x3001;&#x884C;&#x9AD8;&#x548C;&#x6240;&#x9700;&#x7ED8;&#x5236;&#x5185;&#x5BB9;&#x7B49;&#x5173;&#x952E;&#x4FE1;&#x606F;&#xFF0C;&#x5373;&#x53EF;&#x7ED8;&#x5236;<strong>&#x4E0D;&#x540C;size</strong>&#x7684;&#x201C;&#x5361;&#x7247;&#x201D;&#xFF1A;</p>
<pre><code class="language-js">function drawContent(
  ctx,
  info,
  w,
  h,
  fontSize,
  lineHeight,
  marginTop,
  slogan
) {
  ctx.fillStyle = &apos;#000000&apos;
  const lineWidth = $utils.lineWidthHandler(w) // &#x56FA;&#x5B9A;&#x6BCF;&#x884C;&#x5BBD;&#x5EA6;
  const default_drawX = w * 0.06 // &#x56FA;&#x5B9A;&#x4E00;&#x4E2A;&#x5DE6;&#x8FB9;&#x8DDD;
  const content = info.content
  let title = info.title || &apos;&apos;
  let author = info.author || &apos;&apos;
  const source = `${author} ${title}`

  ctx.fillStyle = color
  ctx.font = `${fontSize}px`

  const lineNum = Math.ceil(lineWidth / fontSize)
  const lines = Math.ceil(content.length / lineNum)
  let drawX = default_drawX
  let sourceLeft = w - ctx.measureText(source).width - drawX
  let drawY = (h - lines * lineHeight) / 2 + marginTop
	// &#x7ED8;&#x5236;&#x5F15;&#x7528;&#x51FA;&#x5904;&#xFF08;&#x4F5C;&#x8005;&#x3001;&#x6807;&#x9898;&#xFF09;
  if (!!title || !!author) {
    drawY = (h - lines * lineHeight + lineHeight) / 2 + marginTop - lineHeight
    let sourceTop = lines * lineHeight + drawY + lineHeight / 2
    ctx.fillText(source, sourceLeft, sourceTop)
  }
    // &#x7ED8;&#x5236;&#x53E5;&#x5B50;
  textWrap(
    ctx,
    content,
    lineWidth,
    lineHeight,
    drawX,
    drawY
  )
   	// &#x7ED8;&#x5236;&#x5206;&#x4EAB;&#x6765;&#x6E90;
  if (slogan !== &apos;&apos;) {
    slogan = `&#x5206;&#x4EAB;&#x81EA;${slogan}&#x5FEB;&#x5E94;&#x7528;`
    const sloganSize = $utils.minFontSize(w) // &#x5B9A;&#x4E49;&#x4EFB;&#x610F;&#x5408;&#x9002;&#x7684;&#x5B57;&#x4F53;&#x5927;&#x5C0F;&#xFF0C;&#x5EFA;&#x8BAE;&#x6839;&#x636E;designWidth&#x6309;&#x6BD4;&#x4F8B;&#x8BA1;&#x7B97;
    ctx.fillStyle = &apos;#cccccc&apos;
    ctx.globalAlpha = 0.6
    ctx.font = `${sloganSize}px`
    let sloganMarginLeft = (w - ctx.measureText(slogan).width) / 2 // &#x5C45;&#x4E2D;
    const sloganMarginBottom = 50
    let sloganMarginTop = h - sloganMarginBottom + marginTop
    ctx.fillText(slogan, sloganMarginLeft, sloganMarginTop)
    ctx.globalAlpha = 1
  }
  return lines
}
</code></pre>
<h4 id="1-2-%E9%87%91%E5%8F%A5%E6%A8%A1%E6%9D%BF%E5%9B%BE%E6%96%87%E5%BD%A2%E5%BC%8F">1-2. &#x91D1;&#x53E5;&#x6A21;&#x677F;(&#x56FE;&#x6587;&#x5F62;&#x5F0F;)</h4>
<p><code>&#x56FA;&#x5B9A;&#x4E3A;&#x6B63;&#x65B9;&#x5F62;&#xFF0C;&#x80CC;&#x666F;&#x586B;&#x5145;&#x4E3A;&#x7EAF;&#x56FE;&#x7247;&#xFF0C;&#x6587;&#x672C;&#x5185;&#x5BB9;&#x4E0A;&#x4E0B;&#x5DE6;&#x53F3;&#x5C45;&#x4E2D;&#x4E8E;&#x56FE;&#x7247;&#x4E0A;&#x65B9;</code></p>
<img src="https://zhanstatic.vivo.com.cn/wukong/img/33b38583-0b01-48a6-b468-ab99ce5ecf57.jpg" alt="&#x56FE;&#x6587;&#x5361;&#x7247;" style="zoom:30%">
<h5 id="1-2-1-%E7%BB%98%E5%88%B6%E5%9B%BE%E7%89%87">1-2-1. &#x7ED8;&#x5236;&#x56FE;&#x7247;</h5>
<p>&#x56FE;&#x7247;&#x4E5F;&#x9700;&#x8981;&#x6839;&#x636E;&#x5B9E;&#x9645;&#x5BBD;&#x9AD8;&#x8FDB;&#x884C;&#x5C45;&#x4E2D;&#x5C55;&#x793A;&#xFF0C;&#x53C2;&#x8003;<a href="#calendar-image">&#x65E5;&#x5386;&#x5361;&#x7247;-&#x56FE;&#x7247;</a>&#x7684;&#x7ED8;&#x5236;&#x65B9;&#x6CD5;</p>
<h5 id="1-2-2-%E7%BB%98%E5%88%B6%E5%86%85%E5%AE%B9">1-2-2. &#x7ED8;&#x5236;&#x5185;&#x5BB9;</h5>
<p>&#x7531;&#x4E8E;&#x662F;&#x76F4;&#x63A5;&#x7ED8;&#x5236;&#x5728;&#x56FE;&#x7247;&#x4E0A;&#x65B9;&#xFF0C;&#x6B64;&#x65F6;marginTop&#x4E3A;0&#xFF0C;&#x76F4;&#x63A5;&#x8C03;&#x7528;<code>drawContent</code>&#x65B9;&#x6CD5;&#xFF1A;</p>
<pre><code class="language-js">drawContent(
  ctx,
  info,
  w,
  h, // h = w
  fontSize,
  lineHeight,
  marginTop=0
)
</code></pre>
<h4 id="span-idcard-mask1-3-%E7%BB%98%E5%88%B6%E9%87%91%E5%8F%A5%E5%8D%A1%E7%89%87span"><span id="card-mask">1-3. &#x7ED8;&#x5236;&#x91D1;&#x53E5;&#x5361;&#x7247;</span></h4>
<p><code>&#x5173;&#x4E8E;&#x660E;&#x6697;&#x5EA6;&#x7684;&#x7ED8;&#x5236;&#xFF0C;&#x5B9E;&#x9645;&#x4E0A;&#x662F;&#x6DFB;&#x52A0;&#x4E86;&#x4E00;&#x5C42;&#x9ED1;&#x8272;&#x7684;&quot;&#x8499;&#x7248;&quot;&#xFF0C;&#x901A;&#x8FC7;&#x7236;&#x5B50;&#x7EC4;&#x4EF6;&#x4E4B;&#x95F4;&#x4F20;&#x503C;&#xFF0C;$watch&#x76D1;&#x542C;&#x8499;&#x7248;&#x900F;&#x660E;&#x5EA6;&#x7684;&#x53D8;&#x5316;&#xFF0C;&#x5B9E;&#x73B0;&#x6548;&#x679C;</code></p>
<pre><code class="language-js">drawCard(
    idx,
    info,
    font = this.font,
    fontSize = this.fontSize,
    hasTitle = this.hasTitle,
    hasAuthor = this.hasAuthor,
    lineHeight = this.lineHeight,
    alignType = this.alignType
  ) {
    const canvas = this.$element(`canvas${idx}`) //&#x83B7;&#x53D6; canvas &#x7EC4;&#x4EF6;
    const ctx = canvas.getContext(&apos;2d&apos;) //&#x83B7;&#x53D6; canvas &#x7ED8;&#x56FE;&#x4E0A;&#x4E0B;&#x6587;
    ctx.clearRect(0, 0, this.width, this.height)
    ctx.fillStyle = &apos;#ffffff&apos;
    ctx.fillRect(0, 0, this.width, this.height)
    // &#x7ED8;&#x5236;&#x80CC;&#x666F;&#x56FE;
    const img = new Image()
    img.src = info.data.image
    img.onload = () =&gt; {
      // &#x56FA;&#x5B9A;&#x80CC;&#x666F;&#x56FE;&#x5927;&#x5C0F; w: h = 3: 2
      const sw = this.width
      const sh = this.width / (3 / 2)
      let dw = sw
      let dh = dw / (img.width / img.height)
      if (dh &lt; sh) {
        dh = sh
        dw = dh * (img.width / img.height)
      }
      ctx.drawImage(
        img,
        0,
        -(dh - sh) / 2,
        img.width,
        img.height,
        0,
        -(dh - sh),
        dw,
        dh
      )
      // &#x660E;&#x6697;&#x5EA6;
      ctx.globalAlpha = this.alpha
      ctx.fillStyle = &apos;#000000&apos;
      ctx.fillRect(0, 0, sw, sh)
      // &#x6587;&#x5B57;&#x90E8;&#x5206;
      ctx.globalAlpha = 1 // &#x8FD8;&#x539F;&#x9ED8;&#x8BA4;&#x900F;&#x660E;&#x5EA6; 1
      // &#x65E5;&#x671F;&#x90E8;&#x5206; &#x9634;&#x5386;
      this.drawLunarDate(ctx, info.calendar, sw, sh)
      // &#x65E5;&#x671F;&#x90E8;&#x5206; &#x9633;&#x5386;
      const DATE_SIZE = sw / 3.5 // &#x5F53;&#x65E5; &#x6587;&#x5B57;&#x5927;&#x5C0F;
      const marginTop = sh + DATE_SIZE * 0.2
      this.drawNewDate(ctx, info.calendar, sw, sh, DATE_SIZE, marginTop)
      // &#x5185;&#x5BB9;
      const contentHeight = this.height - sh
      this.lines = drawContent(
        ctx,
        info.data,
        sw,
        contentHeight,
        fontSize,
        &apos;#000000&apos;,
        this.slogan,
        marginTop,
        hasTitle,
        hasAuthor,
        font,
        lineHeight
      )
    }
    img.onerror = () =&gt; {
      console.log(&apos;&#x56FE;&#x7247;&#x52A0;&#x8F7D;&#x5931;&#x8D25;&apos;)
    }
  }
</code></pre>
<h4 id="1-4-%E8%AF%97%E8%AF%8D%E8%AF%97%E6%AD%8C%E6%A8%A1%E6%9D%BF">1-4. &#x8BD7;&#x8BCD;/&#x8BD7;&#x6B4C;&#x6A21;&#x677F;</h4>
<p>&#x8BD7;&#x8BCD;/&#x8BD7;&#x6B4C;&#x7684;&#x6362;&#x884C;&#x6BD4;&#x8F83;&#x7279;&#x6B8A;&#xFF0C;&#x4F8B;&#x5982;&#xFF1A;</p>
<p><img src="https://zhanstatic.vivo.com.cn/wukong/img/b0b59bde-c782-4edc-ad94-3951905ddfe6.png" alt="&#x8BD7;&#x8BCD;" style="zoom:50%;"><img src="https://zhanstatic.vivo.com.cn/wukong/img/2c5a9212-cc88-4710-8666-401dfcbefe8d.jpg" alt="&#x8BD7;&#x6B4C;" style="zoom:50%;"></p>
<p>&#x8FD9;&#x6837;&#x7684;&#x6587;&#x672C;&#x5185;&#x5BB9;&#xFF0C;&#x4E0D;&#x80FD;&#x5355;&#x7EAF;&#x7528;&#x201C;&#x3002;&#x201D;&#x6216;&#x8005;&#x201C; &#x201D;&#xFF08;&#x7A7A;&#x683C;&#xFF09;&#x533A;&#x5206;&#x3002;</p>
<h5 id="1-4-1-%E6%95%B0%E6%8D%AE%E5%A4%84%E7%90%86">1-4-1. &#x6570;&#x636E;&#x5904;&#x7406;</h5>
<p>&#x56E0;&#x6B64;&#x4ECE;<strong>&#x6570;&#x636E;</strong>&#x7740;&#x624B;&#xFF0C;&#x5C06;&#x9700;&#x8981;&#x6362;&#x884C;&#x7684;&#x53E5;&#x5B50;&#xFF0C;&#x7528;&#x201C;/&#x201D;&#x9694;&#x5F00;&#xFF1A;</p>
<pre><code>`&#x201C;&#x884C;&#x5C3D;&#x6F47;&#x6E58;&#x5230;&#x6D1E;&#x5EAD;&#x3002;&#x695A;&#x5929;&#x9614;&#x5904;&#x6570;&#x5CF0;&#x9752;&#x3002;&#x65D7;&#x68A2;&#x4E0D;&#x52A8;&#x665A;&#x6CE2;&#x5E73;&#x3002;/&#x7EA2;&#x84FC;&#x4E00;&#x6E7E;&#x7EB9;&#x7F2C;&#x4E71;&#xFF0C;&#x767D;&#x9C7C;&#x53CC;&#x5C3E;&#x7389;&#x5200;&#x660E;&#x3002;&#x591C;&#x51C9;&#x8239;&#x5F71;&#x6D78;&#x758F;&#x661F;&#x3002;&#x201D;`

`&#x201C;&#x7B49;&#x5F85;&#x4E5F;&#x8BB8;&#x7EC8;&#x4E8E;&#x6709;&#x4EBA;&#x8BB0;&#x5F97;&#x7AEF;&#x6765;/&#x5979;&#x90A3;&#x751C;&#x751C;&#x7684; &#x751C;&#x751C;&#x7684; &#x751C;&#x70B9;&#x201D;`
</code></pre>
<p>&#x518D;&#x5C06;&#x5176;&#x5904;&#x7406;&#x4E3A;<strong>&#x6570;&#x7EC4;</strong>&#xFF1A;</p>
<pre><code class="language-js">let arr = this.info.content.split(&apos;/&apos;)
</code></pre>
<p>&#x8FD9;&#x6837;&#xFF0C;&#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x5F97;&#x5230;&#x4E00;&#x4E2A;&#x6570;&#x7EC4;&#xFF1A;</p>
<img src="https://zhanstatic.vivo.com.cn/wukong/img/aa22baef-8182-408a-a8dd-1d2d773569d0nwebp.png" alt="&#x8BD7;&#x8BCD;-&#x6570;&#x7EC4;" style="zoom:100%;">	
<h5 id="1-4-2-%E6%96%B0%E7%9A%84%E6%95%B0%E7%BB%84">1-4-2. &#x65B0;&#x7684;&#x6570;&#x7EC4;</h5>
<p>&#x53EF;&#x4EE5;&#x53D1;&#x73B0;&#xFF0C;&#x4E0A;&#x56FE;&#x4E2D;&#xFF0C;&#x8BD7;&#x8BCD;&#xFF08;&#x5DE6;&#x56FE;&#xFF09;&#x7684;&#x6BCF;&#x884C;&#xFF0C;&#x5E76;&#x4E0D;&#x662F;&#x6309;&#x7167;&#x6570;&#x7EC4;&#x4E2D;&#x6BCF;&#x4E2A;&#x5143;&#x7D20;&#x53BB;&#x7ED8;&#x5236;&#x7684;&#xFF0C;&#x800C;&#x662F;&#x5C06;&#x6BCF;&#x4E2A;&#x6570;&#x7EC4;&#x5143;&#x7D20;&#x4E2D;&#x7684;&#x5185;&#x5BB9;&#x7ED8;&#x5236;&#x4E86;&#x4E24;&#x884C;&#x3002;</p>
<ul>
<li>
<p>&#x968F;&#x610F;&#x8BBE;&#x7F6E;&#x4E00;&#x4E2A;&#x5408;&#x9002;&#x7684;&#x5B57;&#x4F53;&#x5927;&#x5C0F;&#x53CA;&#x884C;&#x9AD8;&#xFF1A;</p>
<pre><code class="language-js">this.fontSize = $utils.setFontSize(this.width)
this.lineHeight = $utils.setLineHeight(this.fontSize)
</code></pre>
</li>
<li>
<p>&#x5904;&#x7406;&#x6570;&#x7EC4;&#x7684;&#x65B9;&#x6CD5;&#xFF1A;</p>
<pre><code class="language-js">getContentArr(){
    const lineWidth = $utils.lineWidthHandler(this.width) // &#x56FA;&#x5B9A;&#x6BCF;&#x884C;&#x5BBD;&#x5EA6;
    let arr = this.info.content.split(&apos;/&apos;)
    let newArr = []
    for (let i = 0; i &lt; arr.length; i++) {
      let totalWords = arr[i].length // &#x9700;&#x8981;&#x7ED8;&#x5236;&#x7684;&#x6587;&#x672C;&#x603B;&#x5B57;&#x6570;
      let countWordOfALine = Math.floor(lineWidth / this.fontSize) // &#x9650;&#x5236;&#x4E00;&#x884C;&#x7ED8;&#x5236;&#x7684;&#x5B57;&#x6570;
      if (totalWords &gt; countWordOfALine) {  // &#x8D85;&#x51FA;&#x4E00;&#x884C;&#x6240;&#x9650;&#x7684;&#x6587;&#x672C;&#x5185;&#x5BB9;
        const aliquot = Math.floor(totalWords / countWordOfALine)
        const remainder = arr[i].substring(aliquot * countWordOfALine) 
        let start = 0
        let end = countWordOfALine
        arr.splice(i, 0)
        for (let j = 0; j &lt; aliquot; j++) {
          start = countWordOfALine * j
          end = start + countWordOfALine
          let str = arr[i].substring(start, end) // &#x7ED8;&#x5236;aliquot&#x6B21;countWordOfALine&#x957F;&#x5EA6;&#x7684;&#x6587;&#x672C;&#x5185;&#x5BB9;
          newArr.push(str)
        }
        newArr.push(remainder) // &#x5269;&#x4F59;&#x4E0D;&#x591F;&#x7ED8;&#x5236;&#x4E00;&#x6B21;countWordOfALine&#x957F;&#x5EA6;&#x7684;&#x6587;&#x672C;&#x5185;&#x5BB9;
      } else {
        newArr.push(arr[i]) // &#x672A;&#x8D85;&#x51FA;&#x4E00;&#x884C;&#x6240;&#x9650;&#x7684;&#x6587;&#x672C;&#x5185;&#x5BB9;
      }
    }
    return newArr
  }
</code></pre>
</li>
<li>
<p>&#x7136;&#x540E;&#xFF0C;&#x53EF;&#x4EE5;&#x5F97;&#x5230;&#x4E00;&#x4E2A;&#x65B0;&#x7684;&#x6570;&#x7EC4;&#xFF1A;</p>
</li>
</ul>
<img src="https://zhanstatic.vivo.com.cn/wukong/img/95e292e7-fbe2-4bd1-b051-9a068884cebcnwebp.png" alt="&#x8BD7;&#x8BCD;-&#x65B0;&#x6570;&#x7EC4;" style="zoom:100%;">	
<h5 id="1-4-3-%E7%BB%98%E5%88%B6%E5%86%85%E5%AE%B9%E7%9A%84%E6%80%BB%E8%A1%8C%E6%95%B0">1-4-3. &#x7ED8;&#x5236;&#x5185;&#x5BB9;&#x7684;&#x603B;&#x884C;&#x6570;</h5>
<p>&#x6839;&#x636E;&#x65B0;&#x6570;&#x7EC4;&#xFF0C;&#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x5F97;&#x5230;&#x7ED8;&#x5236;&#x7684;&#x603B;&#x884C;&#x6570;&#xFF1A;</p>
<pre><code class="language-js">let contentArr = this.getContentArr()
this.lines = contentArr.length
</code></pre>
<h5 id="1-4-4-%E7%BB%98%E5%88%B6%E5%86%85%E5%AE%B9%E4%B8%AD%E7%9A%84%E5%9B%BA%E5%AE%9A%E9%AB%98%E5%BA%A6">1-4-4. &#x7ED8;&#x5236;&#x5185;&#x5BB9;&#x4E2D;&#x7684;&#x56FA;&#x5B9A;&#x9AD8;&#x5EA6;</h5>
<p>&#x6211;&#x4EEC;&#x8FD8;&#x9700;&#x8981;&#x56FA;&#x5B9A;&#x51FA;&#x5F15;&#x7528;&#x6765;&#x6E90;&#xFF08;&#x6807;&#x9898;&#x3001;&#x4F5C;&#x8005;&#x548C;&#x65F6;&#x4EE3;&#xFF09;&#x3001;slogan&#x7684;&#x9AD8;&#x5EA6;&#xFF0C;&#x4EE5;&#x53CA;&#x7ED9;&#x5361;&#x7247;&#x4E00;&#x4E2A;&#x4E0A;&#x4E0B;&#x7684;<code>padding</code>&#xFF1A;</p>
<pre><code class="language-js">const titleSize = $utils.setFontSize(this.width, 16)
const sourceSize = $utils.minFontSize(this.width)
const cardTop = $utils.setFontSize(this.width, 5)
const cardBottom = cardTop
const sourceTop = $utils.setFontSize(this.width, 44)
const sourceBottom = $utils.setFontSize(this.width, 18)
</code></pre>
<h5 id="1-4-5-%E8%AE%A1%E7%AE%97%E5%8D%A1%E7%89%87%E9%AB%98%E5%BA%A6">1-4-5. &#x8BA1;&#x7B97;&#x5361;&#x7247;&#x9AD8;&#x5EA6;</h5>
<p>&#x6709;&#x4E86;&#x4E0A;&#x8FF0;&#x4FE1;&#x606F;&#xFF0C;&#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x83B7;&#x5F97;&#x5361;&#x7247;&#x7684;&#x9AD8;&#x5EA6;&#xFF1A;</p>
<pre><code class="language-js">this.height = 
  titleSize + sourceSize + this.lines * this.lineHeight + cardTop + cardBottom + sourceTop + sourceBottom + sloganSize
</code></pre>
<h5 id="1-4-6-%E7%BB%98%E5%88%B6%E5%86%85%E5%AE%B9%E5%AF%B9%E9%BD%90%E6%96%B9%E5%BC%8F">1-4-6. &#x7ED8;&#x5236;&#x5185;&#x5BB9;&#x5BF9;&#x9F50;&#x65B9;&#x5F0F;</h5>
<ul>
<li>
<p>&#x8BD7;&#x6B4C;&#xFF1A;</p>
<p><code>&#x6587;&#x672C;&#x5185;&#x5BB9;&#x5DE6;&#x5BF9;&#x9F50;</code></p>
<p>&#x7ED8;&#x5236;&#x201C;&#x65E5;&#x5386;&#x5361;&#x7247;&#x201D;&#x7684;<strong>&#x56FA;&#x5B9A;&#x5DE6;&#x8FB9;&#x8DDD;</strong>&#x7684;&#x65B9;&#x6CD5;&#xFF0C;&#x540C;&#x6837;&#x9002;&#x7528;&#x201C;&#x8BD7;&#x6B4C;&#x5361;&#x7247;&#x201D;</p>
<pre><code class="language-js">const default_drawX = w * 0.06 // &#x56FA;&#x5B9A;&#x4E00;&#x4E2A;&#x5DE6;&#x8FB9;&#x8DDD;
let dx = default_drawX
</code></pre>
</li>
<li>
<p>&#x8BD7;&#x8BCD;&#xFF1A;</p>
<p><code>&#x6587;&#x672C;&#x5185;&#x5BB9;&#x4E0A;&#x4E0B;&#x5DE6;&#x53F3;&#x5C45;&#x4E2D;&#x5BF9;&#x9F50;</code></p>
<p>&#x4E0D;&#x9002;&#x7528;&#x4E8E;&#x4E0A;&#x8FF0;<strong>&#x56FA;&#x5B9A;&#x5DE6;&#x8FB9;&#x8DDD;</strong>&#x7684;&#x65B9;&#x6CD5;&#xFF0C;&#x9700;&#x8981;&#x5BF9;<code>drawX</code>&#x518D;&#x6B21;&#x8FDB;&#x884C;&#x8BA1;&#x7B97;</p>
<pre><code class="language-js">if (info.dynasty !== &apos;&#x73B0;&#x4EE3;&apos;) { // &#x53EF;&#x4EE5;&#x6839;&#x636E;&#x671D;&#x4EE3;&#x53BB;&#x533A;&#x5206;
      let lenArr = []
      arr.forEach(ele =&gt; lenArr.push(ele.length))
      let maxCount = Math.max(...lenArr) // &#x53D6;&#x6570;&#x7EC4;&#x5143;&#x7D20;&#x4E2D;&#x6700;&#x957F;&#x7684;&#x5185;&#x5BB9;&#xFF0C;&#x8BA1;&#x7B97;&#x51FA;&#x5176;&#x5BBD;&#x5EA6;
      let temp = arr.filter(ele =&gt; ele.length === maxCount)
      dx = (w - ctx.measureText(temp[0]).width) / 2 // &#x5F97;&#x5230;&#x53EF;&#x4EE5;&#x4F7F;&#x6587;&#x672C;&#x5185;&#x5BB9;&#x6574;&#x4F53;&#x5C45;&#x4E2D;&#x7684;&#x5DE6;&#x8FB9;&#x8DDD;
}
</code></pre>
</li>
</ul>
<h5 id="1-4-7-%E5%B0%81%E8%A3%85%E6%96%B9%E6%B3%95">1-4-7. &#x5C01;&#x88C5;&#x65B9;&#x6CD5;</h5>
<p>&#x63A5;&#x4E0B;&#x6765;&#x53EF;&#x4EE5;&#x5C01;&#x88C5;&#x7ED8;&#x5236;&#x8BD7;&#x8BCD;/&#x8BD7;&#x6B4C;&#x5361;&#x7247;&#xFF0C;&#x4E3B;&#x4F53;&#x6587;&#x672C;&#x5185;&#x5BB9;&#x7684;&#x65B9;&#x6CD5;&#xFF1A;</p>
<pre><code class="language-js">drawContent(
    ctx,
    info,
    w,
    h,
    dy,
    arr,
    font,
    fontSize,
    lineHeight
  ) {
    const lineWidth = $utils.lineWidthHandler(w) // &#x56FA;&#x5B9A;&#x6BCF;&#x884C;&#x5BBD;&#x5EA6;
    const default_drawX = w * 0.06 // &#x56FA;&#x5B9A;&#x4E00;&#x4E2A;&#x5DE6;&#x8FB9;&#x8DDD;
    let dx = default_drawX
    dy += lineHeight
    ctx.fillStyle = color
    ctx.globalAlpha = 1
    ctx.font = `${fontSize}px normal ${font}`
    if (info.dynasty !== &apos;&#x73B0;&#x4EE3;&apos;) {
      let lenArr = []
      arr.forEach(ele =&gt; lenArr.push(ele.length))
      let maxCount = Math.max(...lenArr)
      let temp = arr.filter(ele =&gt; ele.length === maxCount)
      dx = (w - ctx.measureText(temp[0]).width) / 2
    }
    for (let i = 0; i &lt; arr.length; i++) {
      const element = arr[i]
      ctx.fillText(arr[i], dx, dy)
      if (i !== arr.length - 1) dy += lineHeight
    }
    return dy
  }
</code></pre>
<h4 id="1-5-%E7%BB%98%E5%88%B6%E8%AF%97%E8%AF%8D%E8%AF%97%E6%AD%8C%E5%8D%A1%E7%89%87">1-5. &#x7ED8;&#x5236;&#x8BD7;&#x8BCD;/&#x8BD7;&#x6B4C;&#x5361;&#x7247;</h4>
<pre><code class="language-js">drawCard(
    info,
    font,
    fontSize,
    lineHeight
  ) {
    const canvas = this.$element(&apos;canvas&apos;) //&#x83B7;&#x53D6; canvas &#x7EC4;&#x4EF6;
    const ctx = canvas.getContext(&apos;2d&apos;) //&#x83B7;&#x53D6; canvas &#x7ED8;&#x56FE;&#x4E0A;&#x4E0B;&#x6587;
    let w = this.width,
      h = this.height
    ctx.clearRect(0, 0, w, h)
    ctx.fillStyle = &apos;#ffffff&apos;
    ctx.fillRect(0, 0, w, h)
    // &#x6807;&#x9898;
    let {
      contentArr,
      titleSize,
      sourceSize,
      cardTop,
      cardBottom,
      sourceTop,
      sourceBottom
    } = this.$parent().cardSizeHandler()
    const source = `${info.dynasty} &#x2022; ${info.author}`
    ctx.globalAlpha = 1
    ctx.fillStyle = &apos;#ffffff&apos;
    ctx.fillRect(0, 0, w, h)
    ctx.fillStyle = &apos;#000000&apos;
    // &#x6807;&#x9898;
    ctx.font = `${titleSize}px bold sans-serif`
    let dx = (w - ctx.measureText(info.title).width) / 2
    let dy = cardTop
    ctx.fillText(info.title, dx, dy)
    // &#x6765;&#x6E90;&#xFF08;&#x4F5C;&#x8005;&#xFF09;
    ctx.font = `${sourceSize}px normal sans-serif`
    dx = (w - ctx.measureText(source).width) / 2
    dy = dy + sourceTop + titleSize
    ctx.fillText(source, dx, dy)
    // &#x5185;&#x5BB9;
    dy = dy + sourceSize + sourceBottom
    dy = this.drawContent(
      ctx,
      info,
      w,
      h,
      dy,
      contentArr,
      font,
      fontSize,
      lineHeight
    )
    // slogan
    const txt = `&#x5206;&#x4EAB;&#x81EA;${this.slogan}&#x5FEB;&#x5E94;&#x7528;`
    const sloganSize = $utils.minFontSize(w)
    ctx.fillStyle = &apos;#000000&apos;
    ctx.globalAlpha = 0.3
    ctx.font = `${sloganSize}px normal sans-serif`
    dx = (w - ctx.measureText(txt).width) / 2
    ctx.fillText(txt, dx, this.height - cardBottom / 2)
  }
</code></pre>
<h3 id="2-%E5%B7%A5%E5%85%B7%E6%A0%8F">2. &#x5DE5;&#x5177;&#x680F;</h3>
  <img src="https://zhanstatic.vivo.com.cn/wukong/file/f1ba8140-f4dc-4b41-82ee-acf1c03f622d.gif" alt="&#x5DE5;&#x5177;&#x680F;" style="zoom:67%;">
<h4 id="2-1-%E6%A8%A1%E6%9D%BF">2-1. &#x6A21;&#x677F;</h4>
<p>&#x5361;&#x7247;&#x6A21;&#x677F;&#xFF0C;&#x5373;<a href="#calendar-text">&#x5206;&#x4EAB;&#x5185;&#x5BB9;</a></p>
<h4 id="2-2-%E5%9B%BE%E7%89%87%EF%BC%88%E4%BB%85%E9%87%91%E5%8F%A5%E5%8D%A1%E7%89%87%E6%94%AF%E6%8C%81%EF%BC%89">2-2. &#x56FE;&#x7247;&#xFF08;&#x4EC5;&#x91D1;&#x53E5;&#x5361;&#x7247;&#x652F;&#x6301;&#xFF09;</h4>
<p><code>&#x5E03;&#x5C40;&#x4E0D;&#x518D;&#x8D58;&#x8FF0;</code></p>
<p>&#x5B9E;&#x73B0;&#x5207;&#x6362;&#x56FE;&#x7247;&#xFF0C;&#x5C31;&#x8981;&#x4ECE;&#x5361;&#x7247;&#x7ED8;&#x5236;&#x65B9;&#x6CD5;&#x5165;&#x624B;&#xFF0C;&#x5C06;&#x56FE;&#x7247;&#x5730;&#x5740;&#xFF0C;&#x4F5C;&#x4E3A;&#x53D8;&#x91CF;&#x66B4;&#x9732;&#x51FA;&#x6765;&#xFF0C;&#x7ED8;&#x5236;&#x65B9;&#x6CD5;&#x5728;<a href="#calendar-text">&#x5206;&#x4EAB;&#x5185;&#x5BB9;</a>&#x4E2D;<code>drawCard</code>&#xFF0C;&#x7531;&#x7236;&#x7EC4;&#x4EF6;&#x4F20;&#x9012;&#x7ED9;&#x5361;&#x7247;&#x7EC4;&#x4EF6;&#xFF1A;</p>
<pre><code>// &#x5B50;&#x7EC4;&#x4EF6; options
  choosePicHandler(item, idx) {
      this.localImage = false
      this.subCurrentItem.index = idx
      this.subCurrentItem.type = this.tabBarActive
      this.recentlyList = this.recentlyList.filter(ele =&gt; ele !== item)
      this.recentlyList.unshift(item)
      if (this.recentlyList.length &gt; 10) this.recentlyList.pop()
      $utils.setStorage(&apos;recentlyPics&apos;, JSON.stringify(this.recentlyList)) // &#x901A;&#x8FC7;storage&#x8FDB;&#x884C;&#x5B58;&#x50A8;
      this.$emit(&apos;draw&apos;, {
        currentImg: item,
        subCurrentItem: this.subCurrentItem
      })
  }
// &#x7236;&#x7EC4;&#x4EF6; shareCard
  getNewCurrentImage(e) {
      if (!!e.detail.currentImg) {
        this.cardInfo.data.image = e.detail.currentImg
        switch (this.cardType) {
          case 0:
            this.$child(&apos;card&apos;).drawCard(this.idx, this.cardInfo)
            break
          case 1:
            this.$child(&apos;square&apos;).drawCard(this.cardInfo.data)
            break
          default:
            break
        }
        $utils.setStorage(
          &apos;subCurrentItem&apos;,
          JSON.stringify(e.detail.subCurrentItem)
        )  // &#x901A;&#x8FC7;storage&#x8FDB;&#x884C;&#x5B58;&#x50A8;
      }
   }
</code></pre>
<h4 id="2-3-%E6%8E%92%E7%89%88">2-3. &#x6392;&#x7248;</h4>
<p>&#x540C;&#x6837;&#x662F;&#x9700;&#x8981;&#x4EC0;&#x4E48;&#x5C31;&#x5728;<code>drawCard</code>&#x4E2D;&#x8FDB;&#x884C;&#x58F0;&#x660E;&#xFF0C;&#x5C06;&#x5176;&#x66B4;&#x9732;&#x51FA;&#x6765;</p>
<pre><code class="language-js">// &#x884C;&#x8DDD;&#x3001;&#x5B57;&#x4F53;&#x5927;&#x5C0F;&#x7684;&#x589E;&#x51CF;
  plusAndMinusHandler(e) {
    let { type, num } = e.detail
    if (type === &apos;lineHeight&apos;) {
      const minLineHeight = $utils.setLineHeight(this.fontSize)
      const maxLineHeight = $utils.maxLineHeight(this.fontSize)
      if (this.lineHeight &lt;= minLineHeight &amp;&amp; num &lt; 0) {
        this.lineHeight = minLineHeight
        return
      }
      if (this.lineHeight &gt;= maxLineHeight &amp;&amp; num &gt; 0) {
        this.lineHeight = maxLineHeight
        return
      }
      this.lineHeight += num
    }
    if (type === &apos;fontSize&apos;) {
      const minFontSize = $utils.minFontSize(this.width)
      const maxFontSize = $utils.maxFontSize(this.width)
      if (this.fontSize &lt;= minFontSize &amp;&amp; num &lt; 0) {
        this.fontSize = minFontSize
        return
      }
      if (this.fontSize &gt;= maxFontSize &amp;&amp; num &gt; 0) {
        this.fontSize = maxFontSize
        return
      }
      let temp = this.lineHeight - this.fontSize
      this.fontSize += num
      this.lineHeight = temp + this.fontSize
    }
    if (this.cardType === 0) this.cardSizeHandler()
    this.drawNewCard()
  },
    // &#x6587;&#x672C;&#x5BF9;&#x9F50; 
  textAlignHandler(e) {
    if (this.cardType === 0) {
      this.alignTypeNormal = e.detail.type
    }
    if (this.cardType === 1) {
      this.alignTypeSquare = e.detail.type
    }
    this.drawNewCard()
  },
  //&#x6765;&#x6E90;&#x663E;&#x9690;    
  sourceHandler(e) {
    let { title, author } = e.detail.data
    this.drawNewCard({ hasTitle: title, hasAuthor: author })
  },
    // &#x8BD7;&#x6B4C;/&#x8BD7;&#x8BCD; &#x914D;&#x8272;&#x65B9;&#x6848;
  schemeHandler(e) {
    let { color, bgcolor } = e.detail.scheme
    this.color = color
this.bgcolor = bgcolor
    this.drawNewCard()
  }
</code></pre>
<h2 id="%E4%B8%89%E3%80%81%E9%81%87%E5%88%B0%E7%9A%84%E9%97%AE%E9%A2%98">&#x4E09;&#x3001;&#x9047;&#x5230;&#x7684;&#x95EE;&#x9898;</h2>
<h3 id="1%E6%97%A5%E6%9C%9F%E7%BB%98%E5%88%B6">1.&#x65E5;&#x671F;&#x7ED8;&#x5236;</h3>
<p>&#x9996;&#x9875;&#x5361;&#x7247;&#x539F;&#x9700;&#x6C42;&#x7684;&#x6837;&#x5F0F;&#x5E03;&#x5C40;&#x5982;&#x4E0B;&#xFF1A;</p>
<img src="https://zhanstatic.vivo.com.cn/wukong/img/ede8d7d4-de25-4866-8e4b-9b1513479ef1.jpg" alt="calendar-card" style="zoom:30%">
<p>&#x7531;&#x4E8E;&#x5FEB;&#x5E94;&#x7528;canvas&#x7EC4;&#x4EF6;&#xFF0C;&#x56FE;&#x5F62;&#x548C;&#x6587;&#x5B57;&#x5728;&#x4F7F;&#x7528;<code>canvas.globalCompositeOperation</code> &#x5C5E;&#x6027;&#x65F6;&#xFF0C;&#x4F1A;&#x6709;&#x663E;&#x793A;&#x95EE;&#x9898;&#x3002;&#x56E0;&#x6B64;&#x5C06;<strong>10</strong>&#xFF08;&#x5373;&#x5F53;&#x65E5;&#x65E5;&#x671F;&#xFF09; &#x8FD9;&#x90E8;&#x5206;&#x7ED8;&#x5236;&#x7684;&#x5185;&#x5BB9;&#xFF0C;</p>
<p>&#x76F4;&#x63A5;&#x6587;&#x672C;&#x586B;&#x5145;&#xFF1A;</p>
<pre><code class="language-js">let marginLeft = sw / 15
    ctx.font = `${fontSize}px bold sans-serif`
    ctx.fillStyle = &apos;black&apos;
</code></pre>
<p>&#x540E;&#x7EED;&#x5F15;&#x64CE;&#x7248;&#x672C;&#x89E3;&#x51B3;&#x8BE5;bug&#xFF0C;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x4E0B;&#x9762;&#x4EE3;&#x7801;&#x5B9E;&#x73B0;&#x539F;&#x9700;&#x6C42;&#x6837;&#x5F0F;&#xFF1A;</p>
<pre><code class="language-js">ctx.fillText(`${date}`, marginLeft, marginTop)
ctx.fillStyle = &quot;white&quot;;
ctx.fillRect(0, sh - DATE_SIZE / 2, sw, DATE_SIZE / 2);
ctx.fillStyle = &quot;black&quot;
ctx.globalCompositeOperation = &quot;destination-in&quot;
</code></pre>
<h3 id="2-%E5%B7%A5%E5%85%B7%E6%A0%8F-%E5%AD%97%E4%BD%93">2. &#x5DE5;&#x5177;&#x680F;-&#x5B57;&#x4F53;</h3>
<p>&#x539F;&#x9700;&#x6C42;&#x5982;&#x4E0B;&#xFF1A;</p>
<p><img src="https://zhanstatic.vivo.com.cn/wukong/img/d664590a-768a-41fb-8209-c227904d416c.jpg" alt="&#x5DE5;&#x5177;&#x680F;-&#x6587;&#x5B57;" style="zoom:30%"><img src="https://zhanstatic.vivo.com.cn/wukong/img/fc156d73-a15b-42f2-beaa-d71132b18b3e.jpg" alt="&#x5DE5;&#x5177;&#x680F;-&#x6587;&#x5B57;" style="zoom:30%"></p>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&#x5FEB;&#x5E94;&#x7528;&#x7684;text&#x7EC4;&#x4EF6;&#x652F;&#x6301;&#x7684;&#x4E00;&#x4E9B;&#x5B57;&#x4F53;&#x6837;&#x5F0F;&#xFF0C;&#x7531;&#x4E8E;canvas&#x7EC4;&#x4EF6;&#x5F00;&#x53D1;&#x65F6;&#xFF0C;&#x672A;&#x8003;&#x8651;&#x5230; ctx.font = <code>50px normal serif</code> &#x8FD9;&#x79CD;&#x5199;&#x6CD5;&#xFF0C;&#x5B98;&#x7F51;&#x4E2D;&#x7ED9;&#x7684;&#x5199;&#x6CD5;&#x9ED8;&#x8BA4;&#x662F;  ctx.font = <code>10px sans-serif</code>&#xFF0C;&#x5BFC;&#x81F4;<code> 50px normal serif</code> &#x8FD9;&#x79CD;<strong>&#x4E09;&#x4E2A;&#x6837;&#x5F0F;</strong>&#x7684;&#x5199;&#x6CD5;&#x4E2D;<strong>&#x6700;&#x540E;&#x4E00;&#x4E2A;</strong>&#x6837;&#x5F0F; <strong>&#x90FD;&#x4E0D;&#x751F;&#x6548;</strong>&#x3002;</p>
<p>&#x6682;&#x65F6;&#x53EA;&#x80FD;<strong>&#x6CE8;&#x91CA;</strong>&#x8BE5;&#x5DE5;&#x5177;&#x680F;&#x529F;&#x80FD;&#xFF0C;&#x5F85;&#x540E;&#x7EED;&#x5F15;&#x64CE;&#x7248;&#x672C;&#x4FEE;&#x590D;&#x540E;&#xFF0C;&#x53EF;&#x4EE5;&#x5C06;&#x8BE5;&#x90E8;&#x5206;&#x4EE3;&#x7801;&#x5F00;&#x653E;&#x4F7F;&#x7528;&#x3002;</p>
<pre><code class="language-js">const sentenceOpt = [
  {
    image: &apos;../../assets/images/icon/template.png&apos;,
    type: &apos;&#x6A21;&#x677F;&apos;
  },
  {
    image: &apos;../../assets/images/icon/image.png&apos;,
    type: &apos;&#x56FE;&#x7247;&apos;
  },
  // {
  //   image: &apos;../../assets/images/icon/font.png&apos;,
  //   type: &apos;&#x5B57;&#x4F53;&apos;
  // },
  {
    image: &apos;../../assets/images/icon/layout.png&apos;,
    type: &apos;&#x6392;&#x7248;&apos;
  }
]
</code></pre>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[vscode-loader 解析（node 环境）]]></title><description><![CDATA[VsCode 源码使用 vscode-loader 加载模块（异步模块定义 (AMD) 加载器的一种实现）；vscode-loader 支持在浏览器以及 node 中使用，在两种环境的使用方式基本一致。 本文是对其在浏览器环境运行进行分析。前面，我们已经分析过浏览器环境的模块加载，接下来看 node 环境的模块加载。]]></description><link>https://quickapp.vivo.com.cn/vscode-loader-source-code-analysis-node-env/</link><guid isPermaLink="false">63c4b94a77e2ca0006a8c89c</guid><category><![CDATA[快应用开发工具]]></category><dc:creator><![CDATA[minxuan]]></dc:creator><pubDate>Tue, 21 Dec 2021 07:52:47 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>VsCode &#x6E90;&#x7801;&#x4F7F;&#x7528; vscode-loader &#x52A0;&#x8F7D;&#x6A21;&#x5757;&#xFF08;&#x5F02;&#x6B65;&#x6A21;&#x5757;&#x5B9A;&#x4E49; (AMD) &#x52A0;&#x8F7D;&#x5668;&#x7684;&#x4E00;&#x79CD;&#x5B9E;&#x73B0;&#xFF09;&#xFF1B;vscode-loader &#x652F;&#x6301;&#x5728;&#x6D4F;&#x89C8;&#x5668;&#x4EE5;&#x53CA; node &#x4E2D;&#x4F7F;&#x7528;&#xFF0C;&#x5728;&#x4E24;&#x79CD;&#x73AF;&#x5883;&#x7684;&#x4F7F;&#x7528;&#x65B9;&#x5F0F;&#x57FA;&#x672C;&#x4E00;&#x81F4;&#x3002; &#x672C;&#x6587;&#x662F;&#x5BF9;&#x5176;&#x5728;&#x6D4F;&#x89C8;&#x5668;&#x73AF;&#x5883;&#x8FD0;&#x884C;&#x8FDB;&#x884C;&#x5206;&#x6790;&#x3002;&#x524D;&#x9762;&#xFF0C;&#x6211;&#x4EEC;&#x5DF2;&#x7ECF;&#x5206;&#x6790;&#x8FC7;<a href="https://forum.lovejade.cn/d/115-vscode-loader">&#x6D4F;&#x89C8;&#x5668;&#x73AF;&#x5883;&#x7684;&#x6A21;&#x5757;&#x52A0;&#x8F7D;</a>&#xFF0C;&#x63A5;&#x4E0B;&#x6765;&#x770B; node &#x73AF;&#x5883;&#x7684;&#x6A21;&#x5757;&#x52A0;&#x8F7D;&#x3002;</p>
<h2 id="%E7%A4%BA%E4%BE%8B">&#x793A;&#x4F8B;</h2>
<p>vscode-loader &#x5728; node &#x73AF;&#x5883;&#x4E0B;&#x52A0;&#x8F7D;&#x6A21;&#x5757;&#xFF0C;&#x548C;&#x6D4F;&#x89C8;&#x5668;&#x73AF;&#x5883;&#x57FA;&#x672C;&#x4E00;&#x81F4;&#x3002;&#x4E0D;&#x540C;&#x70B9;&#x662F;&#xFF0C;&#x4E0D;&#x662F;&#x901A;&#x8FC7; script &#x6807;&#x7B7E;&#x52A0;&#x8F7D; loader.js&#xFF0C;&#x800C;&#x662F;&#x901A;&#x8FC7; require &#x52A0;&#x8F7D;&#x3002;</p>
<p>&#x5177;&#x4F53;&#x793A;&#x4F8B;&#x5982;&#x4E0B;&#xFF1A;</p>
<p>&#x52A0;&#x8F7D; loader.js&#xFF0C;&#x518D;&#x8C03;&#x7528; loader &#x6A21;&#x5757;&#x7684;&#x65B9;&#x6CD5;&#xFF0C;&#x52A0;&#x8F7D; test &#x4F9D;&#x8D56;&#xFF1A;</p>
<pre><code class="language-js">loader = require(&quot;./src/loader&quot;);
// &#x8BBE;&#x7F6E;&#x7F13;&#x5B58;
loader.config({
  nodeCachedData: {
    path: &quot;./cache-data&quot;,
  },
});
loader([&quot;test&quot;], function (test) {
  console.log(test.compare(7, 5));
});
</code></pre>
<p>&#x5B9A;&#x4E49;&#x6A21;&#x5757;&#xFF1A;</p>
<pre><code class="language-js">// test.js

define(&quot;test&quot;, function () {
  return {
    compare: function (a, b) {
      return a &gt; b;
    },
  };
});
</code></pre>
<h2 id="loader-%E5%8A%A0%E8%BD%BD%E6%A8%A1%E5%9D%97">loader &#x52A0;&#x8F7D;&#x6A21;&#x5757;</h2>
<p>&#x4E0A;&#x4E00;&#x7BC7;&#x6587;&#x7AE0;&#x4E2D;&#xFF0C;&#x6211;&#x4EEC;&#x63D0;&#x5230;&#xFF0C;&#x6D4F;&#x89C8;&#x5668;&#x73AF;&#x5883;&#x901A;&#x8FC7; require &#x51FD;&#x6570;&#x52A0;&#x8F7D;&#x6A21;&#x5757;&#x3002;&#x800C; node &#x73AF;&#x5883;&#xFF0C;&#x662F;&#x901A;&#x8FC7; loader.js &#x7684;&#x6A21;&#x5757;&#x5BFC;&#x51FA;&#x503C;&#xFF0C;&#x52A0;&#x8F7D;&#x5176;&#x4ED6;&#x6A21;&#x5757;&#x3002;</p>
<p>&#x67E5;&#x770B;&#x5165;&#x53E3;&#x6587;&#x4EF6;&#x4E2D;&#x7684;&#x903B;&#x8F91;&#xFF0C;&#x53EF;&#x4EE5;&#x770B;&#x51FA; loader &#x5C31;&#x662F; require &#x51FD;&#x6570;&#xFF1A;</p>
<pre><code class="language-ts">// &#x521D;&#x59CB;&#x5316;
	export function init(): void {
		...

		if (env.isNode &amp;&amp; !env.isElectronRenderer) {
			// &#x8BBE;&#x7F6E; module.expots
			module.exports = RequireFunc;
			require = &lt;any&gt;RequireFunc;
		} else {
			...
		}
	}
</code></pre>
<p>&#x6240;&#x4EE5;&#xFF0C;node &#x73AF;&#x5883;&#x52A0;&#x8F7D;&#x6A21;&#x5757;&#x7684;&#x903B;&#x8F91;&#xFF0C;&#x548C;&#x6D4F;&#x89C8;&#x5668;&#x57FA;&#x672C;&#x662F;&#x4E00;&#x81F4;&#x7684;&#x3002;&#x4E0D;&#x540C;&#x70B9;&#x5728;&#x4E8E;&#xFF0C;&#x4E4B;&#x524D;&#x63D0;&#x5230;&#x7684;&#xFF0C;&#x4E0D;&#x540C;&#x73AF;&#x5883;&#x4E0B;&#x7684; <code>scriptLoader</code> (&#x811A;&#x672C;&#x52A0;&#x8F7D;&#x5668;)&#x3002;</p>
<h2 id="nodescriptloader">NodeScriptLoader</h2>
<p>&#x4E0B;&#x9762;&#xFF0C;&#x6211;&#x4EEC;&#x5177;&#x4F53;&#x6765;&#x770B; node &#x7684;&#x811A;&#x672C;&#x52A0;&#x8F7D;&#x5668;&#x3002;</p>
<pre><code class="language-ts">class OnlyOnceScriptLoader implements IScriptLoader {

	...

	public load(moduleManager: IModuleManager, scriptSrc: string, callback: () =&gt; void, errorback: (err: any) =&gt; void): void {
		if (!this._scriptLoader) {
			if (this._env.isWebWorker) {
				this._scriptLoader = new WorkerScriptLoader();
			} else if (this._env.isElectronRenderer) {
				// electron &#x6E32;&#x67D3;&#x8FDB;&#x7A0B;&#xFF0C;preferScriptTags &#x6307;&#x5B9A;&#x662F;&#x5426;&#x7528; &lt;script&gt; &#x6807;&#x7B7E;&#x52A0;&#x8F7D;&#xFF0C;&#x9ED8;&#x8BA4;&#x4E3A; false
				const { preferScriptTags } = moduleManager.getConfig().getOptionsLiteral();
				if (preferScriptTags) {
					this._scriptLoader = new BrowserScriptLoader();
				} else {
					this._scriptLoader = new NodeScriptLoader(this._env);
				}
			} else if (this._env.isNode) {
				// node &#x73AF;&#x5883;&#xFF0C;&#x65B0;&#x5EFA; node &#x7684;&#x811A;&#x672C;&#x52A0;&#x8F7D;&#x5668;
				this._scriptLoader = new NodeScriptLoader(this._env);
			} else {
				this._scriptLoader = new BrowserScriptLoader();
			}
		}
		...
	}
}

class NodeScriptLoader implements IScriptLoader {

	private static _BOM = 0xFEFF;
	private static _PREFIX = &apos;(function (require, define, __filename, __dirname) { &apos;;
	private static _SUFFIX = &apos;\n});&apos;;

	...

	public load(moduleManager: IModuleManager, scriptSrc: string, callback: () =&gt; void, errorback: (err: any) =&gt; void): void {
		// load-1: &#x83B7;&#x53D6;&#x914D;&#x7F6E;
		const opts = moduleManager.getConfig().getOptionsLiteral();
		const nodeRequire = ensureRecordedNodeRequire(moduleManager.getRecorder(), (opts.nodeRequire || global.nodeRequire)); // nodeRequire &#x589E;&#x52A0;&#x4E8B;&#x4EF6;&#x8BB0;&#x5F55;
		const nodeInstrumenter = (opts.nodeInstrumenter || function (c) { return c; });	// &#x5982;&#x679C;&#x8BBE;&#x7F6E;&#x4E86; nodeInstrumenter&#xFF0C;&#x5728;&#x811A;&#x672C;&#x52A0;&#x8F7D;&#x4E4B;&#x524D;&#xFF0C;&#x4F1A;&#x5148;&#x5BF9;&#x811A;&#x672C;&#x6267;&#x884C;&#x8BE5;&#x8F6C;&#x6362;&#x51FD;&#x6570;
		// load-2: &#x521D;&#x59CB;&#x5316;
		this._init(nodeRequire);
		this._initNodeRequire(nodeRequire, moduleManager);
		let recorder = moduleManager.getRecorder();

		// load-3: &#x52A0;&#x8F7D;&#x6A21;&#x5757;
		if (/^node\|/.test(scriptSrc)) {
			// &apos;node|&apos; &#x5F00;&#x5934;&#x7684;&#xFF0C;&#x7528; nodeRequire &#x52A0;&#x8F7D;&#xFF08;&#x540C;&#x6B65;&#x52A0;&#x8F7D;&#xFF09;&#xFF0C;&#x76F4;&#x63A5;&#x8C03;&#x7528; callback

			let pieces = scriptSrc.split(&apos;|&apos;);

			let moduleExports = null;
			try {
				moduleExports = nodeRequire(pieces[1]);
			} catch (err) {
				errorback(err);
				return;
			}

			moduleManager.enqueueDefineAnonymousModule([], () =&gt; moduleExports);
			callback();

		} else {

			// load-3-1: &#x8DEF;&#x5F84;&#x5904;&#x7406;
			scriptSrc = Utilities.fileUriToFilePath(this._env.isWindows, scriptSrc);
			const normalizedScriptSrc = this._path.normalize(scriptSrc);
			const vmScriptPathOrUri = this._getElectronRendererScriptPathOrUri(normalizedScriptSrc);
			const wantsCachedData = Boolean(opts.nodeCachedData);
			const cachedDataPath = wantsCachedData ? this._getCachedDataPath(opts.nodeCachedData!, scriptSrc) : undefined;

			// load-3-2: &#x83B7;&#x53D6;&#x6A21;&#x5757;&#x4EE3;&#x7801;&#x548C;&#x7F13;&#x5B58;&#xFF0C;&#x6267;&#x884C;&#x4EE3;&#x7801;
			this._readSourceAndCachedData(normalizedScriptSrc, cachedDataPath, recorder, (err: any, data: string, cachedData: Buffer, hashData: Buffer) =&gt; {
				if (err) {
					errorback(err);
					return;
				}

				// &#x5904;&#x7406;&#x6A21;&#x5757;&#x4EE3;&#x7801;
				let scriptSource: string;
				if (data.charCodeAt(0) === NodeScriptLoader._BOM) {
					scriptSource = NodeScriptLoader._PREFIX + data.substring(1) + NodeScriptLoader._SUFFIX;
				} else {
					scriptSource = NodeScriptLoader._PREFIX + data + NodeScriptLoader._SUFFIX;
				}

				scriptSource = nodeInstrumenter(scriptSource, normalizedScriptSrc);

				// &#x751F;&#x6210;&#x5E76;&#x6267;&#x884C;&#x811A;&#x672C;
				const scriptOpts: INodeVMScriptOptions = { filename: vmScriptPathOrUri, cachedData };
				const script = this._createAndEvalScript(moduleManager, scriptSource, scriptOpts, callback, errorback);

				// &#x5904;&#x7406;&#x3001;&#x9A8C;&#x8BC1;&#x7F13;&#x5B58;
				this._handleCachedData(script, scriptSource, cachedDataPath!, wantsCachedData &amp;&amp; !cachedData, moduleManager);
				this._verifyCachedData(script, scriptSource, cachedDataPath!, hashData, moduleManager);
			});
		}
	}
</code></pre>
<h3 id="%E5%88%9D%E5%A7%8B%E5%8C%96">&#x521D;&#x59CB;&#x5316;</h3>
<p>&#x8FD9;&#x91CC;&#xFF0C;&#x6211;&#x4EEC;&#x5148;&#x770B; load-2 &#x521D;&#x59CB;&#x5316;&#x7684;&#x5904;&#x7406;&#xFF1A;</p>
<pre><code class="language-ts">class NodeScriptLoader implements IScriptLoader {
	private _init(nodeRequire: (nodeModule: string) =&gt; any): void {
		if (this._didInitialize) {
			return;
		}
		this._didInitialize = true;

		// &#x83B7;&#x53D6; node &#x539F;&#x751F;&#x6A21;&#x5757;
		this._fs = nodeRequire(&apos;fs&apos;);
		this._vm = nodeRequire(&apos;vm&apos;);
		this._path = nodeRequire(&apos;path&apos;);
		this._crypto = nodeRequire(&apos;crypto&apos;);
	}

	// &#x4FEE;&#x8865; nodejs &#x7684; require &#x51FD;&#x6570;&#xFF0C;&#x4EE5;&#x4FBF;&#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x4ECE;&#x7F13;&#x5B58;&#x6570;&#x636E;&#x624B;&#x52A8;&#x521B;&#x5EFA;&#x811A;&#x672C;&#x3002;&#x8FD9;&#x662F;&#x901A;&#x8FC7;&#x8986;&#x76D6; `Module._compile` &#x51FD;&#x6570;&#x6765;&#x5B8C;&#x6210;&#x7684;&#x3002;
	private _initNodeRequire(nodeRequire: (nodeModule: string) =&gt; any, moduleManager: IModuleManager): void {
		// require-1: &#x5982;&#x679C;&#x5DF2;&#x7ECF;&#x6253;&#x8FC7;&#x8865;&#x4E01;&#xFF0C;&#x76F4;&#x63A5;&#x8FD4;&#x56DE;
		const { nodeCachedData } = moduleManager.getConfig().getOptionsLiteral();
		if (!nodeCachedData) {
			return;
		}
		if (this._didPatchNodeRequire) {
			return;
		}
		this._didPatchNodeRequire = true;

		// require-2: &#x4FEE;&#x6539; Module.compile
		const that = this
		const Module = nodeRequire(&apos;module&apos;);

		function makeRequireFunction(mod: any) {
			...
		}

		Module.prototype._compile = function (content: string, filename: string) {
			...
		}
	}
}
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;_initNodeRequire &#x4FEE;&#x6539;&#x4E86; node &#x7684; <code>require</code> &#x51FD;&#x6570;&#xFF0C;&#x4E3B;&#x8981;&#x662F;&#x6539;&#x5199;&#x4E86; <code>Module.prototype._compile</code>&#x3002;</p>
<h4 id="node-%E7%9A%84-compile">node &#x7684; _compile</h4>
<p>&#x6211;&#x4EEC;&#x5148;&#x4E86;&#x89E3;&#x4E00;&#x4E0B; node &#x7684; <code>require</code> &#x51FD;&#x6570;&#xFF0C;&#x53CA; <code>Module.prototype._compile</code>&#xFF0C;&#x4EE5;&#x4FBF;&#x540E;&#x7EED;&#x5BF9;&#x6BD4;&#x3002;&#x8FD9;&#x91CC;&#x7684; node &#x4EE3;&#x7801;&#x4E3A; <a href="https://github.com/nodejs/node/blob/v14.0.0/lib/internal/modules/cjs/loader.js">14.0.0 &#x7248;&#x672C;</a>&#x3002;</p>
<p>&#x5148;&#x770B; <code>require</code> &#x51FD;&#x6570;&#xFF1A;</p>
<pre><code class="language-js">// require: &#x6839;&#x636E;&#x8DEF;&#x5F84;&#x52A0;&#x8F7D;&#x6A21;&#x5757;&#xFF0C;&#x8FD4;&#x56DE;&#x6A21;&#x5757;&#x7684; exports &#x5C5E;&#x6027;&#x3002;
Module.prototype.require = function(id) {
	...
	// &#x7B2C;&#x4E00;&#x6B65;&#xFF1A;&#x8C03;&#x7528; Module._load
	return Module._load(id, this, /* isMain */ false);
};

// Module._load&#xFF1A;&#x52A0;&#x8F7D;&#x6A21;&#x5757;&#x3001;&#x7BA1;&#x7406;&#x7F13;&#x5B58;
Module._load = function(request, parent, isMain) {
	...

	// 1. &#x5982;&#x679C;&#x7F13;&#x5B58;&#x4E2D;&#x5DF2;&#x5B58;&#x5728;&#x6A21;&#x5757;&#xFF0C;&#x8FD4;&#x56DE;&#x6A21;&#x5757;&#x7684; exports
	const cachedModule = Module._cache[filename];
    if (cachedModule !== undefined) {
        updateChildren(parent, cachedModule, true);
        if (!cachedModule.loaded)
            return getExportsForCircularRequire(cachedModule);
        return cachedModule.exports;
    }

	...

	// 2. &#x5982;&#x679C;&#x662F;&#x539F;&#x751F;&#x6A21;&#x5757;&#xFF0C;&#x8C03;&#x7528; `NativeModule.prototype.compileForPublicLoader()` &#x5E76;&#x8FD4;&#x56DE; exports
    const mod = loadNativeModule(filename, request);
    if (mod &amp;&amp; mod.canBeRequiredByUsers) return mod.exports;

	...

	// 3. &#x5426;&#x5219;&#xFF0C;&#x65B0;&#x5EFA;&#x4E00;&#x4E2A;&#x6A21;&#x5757;&#x5E76;&#x4FDD;&#x5B58;&#x5230;&#x7F13;&#x5B58;&#xFF0C;&#x52A0;&#x8F7D;&#x6587;&#x4EF6;&#xFF0C;&#x8FD4;&#x56DE; exports
	const module = new Module(filename, parent);
	...
	Module._cache[filename] = module;
	try {
		...
		// &#x7B2C;&#x4E8C;&#x6B65;&#xFF1A;&#x8C03;&#x7528; Module.prototype.load
        module.load(filename);
        ...
    } finally {
        ...
    }

    return module.exports;
}

// Module.prototype.load: &#x6839;&#x636E;&#x6587;&#x4EF6;&#x540D;&#xFF0C;&#x8C03;&#x7528;&#x5408;&#x9002;&#x7684;&#x6269;&#x5C55;&#x5904;&#x7406;&#x5668;&#x3002;
Module.prototype.load = function (filename) {
    ...

	// &#x7B2C;&#x4E09;&#x6B65;&#xFF1A;&#x8C03;&#x7528;&#x5BF9;&#x5E94;&#x7684;&#x5904;&#x7406;&#x5668;&#xFF0C;&#x6BD4;&#x5982; Module._extensions[&apos;.js&apos;]
    Module._extensions[extension](this, filename);
    this.loaded = true;

    ...
};

Module._extensions[&apos;.js&apos;] = function (module, filename) {
    ...
    content = fs.readFileSync(filename, &apos;utf8&apos;);
	// &#x7B2C;&#x56DB;&#x6B65;&#xFF1A;&#x8C03;&#x7528; Module.prototype._compile
    module._compile(content, filename);
};
</code></pre>
<p>&#x4ECE;&#x4E0A;&#x9762;&#x4EE3;&#x7801;&#xFF0C;&#x53EF;&#x4EE5;&#x770B;&#x51FA; node &#x7684; <code>require</code> &#x51FD;&#x6570;&#xFF0C;&#x6267;&#x884C;&#x8FC7;&#x7A0B;&#x662F; <code>require</code> -&gt; <code>Module._load</code> -&gt; <code>Module.prototype.load</code> -&gt; <code>Module._extensions[&apos;.js&apos;]</code> -&gt; <code>Module.prototype._compile</code>&#x3002;</p>
<p>&#x7EE7;&#x7EED;&#x770B; node &#x7684; <code>Module.prototype._compile</code>&#xFF1A;</p>
<pre><code class="language-js">// node

// Module.prototype._compile: &#x5728;&#x6307;&#x5B9A;&#x7684;&#x4E0A;&#x4E0B;&#x6587;&#x4E2D;&#xFF0C;&#x7F16;&#x8BD1;&#x3001;&#x8FD0;&#x884C;&#x6587;&#x4EF6;&#x5185;&#x5BB9;&#x3002;
Module.prototype._compile = function (content, filename) {
    ...

	// node-compile-1&#xFF1A;compiledWrapper: &#x5C06;&#x6587;&#x4EF6;&#x5185;&#x5BB9;&#x8FDB;&#x884C;&#x5C01;&#x88C5;
    const compiledWrapper = wrapSafe(filename, content, this);

    ...
	// node-compile-2&#xFF1A;&#x751F;&#x6210; require, exports &#x7B49;&#x53C2;&#x6570;
    const dirname = path.dirname(filename);
    const require = makeRequireFunction(this, redirects);
    let result;
    const exports = this.exports;
    const thisValue = exports;
    const module = this;
    ...
    if (inspectorWrapper) {
		// &#x65AD;&#x70B9;&#x8C03;&#x8BD5;&#xFF0C;&#x4E00;&#x822C;&#x4E0D;&#x8D70;&#x8FD9;&#x4E2A;&#x903B;&#x8F91;
        result = inspectorWrapper(compiledWrapper, thisValue, exports,
            require, module, filename, dirname);
    } else {
		// node-compile-3&#xFF1A;&#x8C03;&#x7528; compiledWrapper
        result = compiledWrapper.call(thisValue, exports, require, module,
            filename, dirname);
    }
    ...
    return result;
};

// &#x5C01;&#x88C5;&#x6587;&#x4EF6;&#x5185;&#x5BB9;
function wrapSafe(filename, content, cjsModuleInstance) {
    if (patched) {
		// node-compile-1-1&#xFF1A;Module.wrap&#xFF0C;&#x5C01;&#x88C5;&#x6587;&#x4EF6;&#x5185;&#x5BB9;&#xFF0C;&#x8FD4;&#x56DE; (function (exports, require, module, __filename, __dirname) { ${content} \n})
        const wrapper = Module.wrap(content);
		// node-compile-1-2&#xFF1A;vm.runInThisContext&#xFF0C;&#x8C03;&#x7528;&#x865A;&#x62DF;&#x673A;&#x63A5;&#x53E3;&#xFF0C;&#x7F16;&#x8BD1;&#x4EE3;&#x7801;&#xFF0C;&#x5E76;&#x5728;&#x5F53;&#x524D;&#x4E0A;&#x4E0B;&#x6587;&#x6267;&#x884C;&#x4EE3;&#x7801;
        return vm.runInThisContext(wrapper, {
            filename,
            lineOffset: 0,
            displayErrors: true,
            importModuleDynamically: async (specifier) =&gt; {
                const loader = asyncESM.ESMLoader;
                return loader.import(specifier, normalizeReferrerURL(filename));
            },
        });
    }
    ...
}
</code></pre>
<p>node &#x7684; <code>Module.prototype._compile</code>&#xFF0C;&#x5C06;&#x6587;&#x4EF6;&#x5185;&#x5BB9;&#x8FDB;&#x884C;&#x5C01;&#x88C5;&#xFF08;compiledWrapper&#xFF09;&#xFF0C;&#x7136;&#x540E;&#x751F;&#x6210; require &#x7B49;&#x53C2;&#x6570;&#xFF0C;&#x518D;&#x8C03;&#x7528;&#x5C01;&#x88C5;&#x7684;&#x51FD;&#x6570;&#xFF08;compiledWrapper&#xFF09;&#x3002;</p>
<p>node-compile-1-2 &#x4F7F;&#x7528;&#x4E86; node &#x7684; <a href="https://nodejs.org/api/vm.html">vm</a> &#x6A21;&#x5757;&#xFF0C;&#x8BE5;&#x6A21;&#x5757;&#x652F;&#x6301;&#x7F16;&#x8BD1;&#x4EE3;&#x7801;&#x3001;&#x8FD0;&#x884C;&#x4EE3;&#x7801;&#x7B49;&#x529F;&#x80FD;&#x3002;</p>
<h4 id="vscode-loader-%E7%9A%84-compile">vscode-loader &#x7684; _compile</h4>
<p>vscode-loader &#x7684; <code>Module.prototype._compile</code>&#xFF0C;&#x903B;&#x8F91;&#x5982;&#x4E0B;&#xFF1A;</p>
<pre><code class="language-ts">class NodeScriptLoader implements IScriptLoader {
	private _initNodeRequire(nodeRequire: (nodeModule: string) =&gt; any, moduleManager: IModuleManager): void {

		...

		Module.prototype._compile = function (content: string, filename: string) {
			// compile-1: &#x66FF;&#x6362; shebang&#xFF0C;&#x5305;&#x88C5;&#x6E90;&#x7801;
			const scriptSource = Module.wrap(content.replace(/^#!.*/, &apos;&apos;));

			// compile-2: &#x83B7;&#x53D6;&#x7F13;&#x5B58;&#x6570;&#x636E;&#xFF0C;&#x5E76;&#x8BB0;&#x5F55;&#x4E8B;&#x4EF6;
			const recorder = moduleManager.getRecorder();
			// &#x5BF9;&#x4E8E;&#x793A;&#x4F8B;&#x800C;&#x8A00;&#xFF0C;&#x7F13;&#x5B58;&#x8DEF;&#x5F84;&#x4E3A; cache-data/test-${hash}.code
			const cachedDataPath = that._getCachedDataPath(nodeCachedData, filename);
			const options: INodeVMScriptOptions = { filename };
			let hashData: Buffer | undefined;
			try {
				// &#x8BFB;&#x53D6;&#x7F13;&#x5B58;&#x6570;&#x636E;
				const data = that._fs.readFileSync(cachedDataPath);
				hashData = data.slice(0, 16);
				// &#x8BBE;&#x7F6E;&#x5230; options.cachedData
				options.cachedData = data.slice(16);
				recorder.record(LoaderEventType.CachedDataFound, cachedDataPath);
			} catch (_e) {
				recorder.record(LoaderEventType.CachedDataMissed, cachedDataPath);
			}
			// compile-3: &#x65B0;&#x5EFA; vm.Script&#xFF0C;&#x7F16;&#x8BD1;&#x4EE3;&#x7801;
			const script = new that._vm.Script(scriptSource, options);
			// compile-4: &#x751F;&#x6210; compileWrapper&#xFF0C;&#x7528;&#x4E8E;&#x5728;&#x5F53;&#x524D;&#x4E0A;&#x4E0B;&#x6587;&#x8FD0;&#x884C;&#x4EE3;&#x7801;
			const compileWrapper = script.runInThisContext(options);

			// compile-5: &#x751F;&#x6210; require &#x7B49;&#x53C2;&#x6570;
			const dirname = that._path.dirname(filename);
			const require = makeRequireFunction(this);
			const args = [this.exports, require, this, filename, dirname, process, _commonjsGlobal, Buffer];
			// compile-6: &#x6267;&#x884C; compileWrapper&#xFF0C;&#x4F20;&#x5165;&#x53C2;&#x6570;
			const result = compileWrapper.apply(this.exports, args);

			// compile-7: &#x7F13;&#x5B58;&#x6570;&#x636E;
			that._handleCachedData(script, scriptSource, cachedDataPath, !options.cachedData, moduleManager);
			that._verifyCachedData(script, scriptSource, cachedDataPath!, hashData, moduleManager);

			return result;
		}
	}
}
</code></pre>
<p>&#x548C; node &#x7684;&#x76F8;&#x4F3C;&#x4E4B;&#x5904;&#xFF1A;</p>
<ul>
<li><code>compile-1</code>&#xFF0C;&#x7B49;&#x540C;&#x4E8E; <code>node-compile-1-1</code>&#xFF0C;&#x901A;&#x8FC7; <code>Module.wrap</code> &#x5C01;&#x88C5;&#x6587;&#x4EF6;&#x5185;&#x5BB9;&#x3002;&#x8FD9;&#x6837;&#x53EF;&#x4EE5;&#x4FDD;&#x8BC1;&#x4EE3;&#x7801;&#x5728;&#x72EC;&#x7ACB;&#x4E0A;&#x4E0B;&#x6587;&#x4E2D;&#x8FD0;&#x884C;&#x3002;</li>
<li><code>compile-3</code>&#x3001;<code>compile-4</code>&#xFF0C;&#x7B49;&#x540C;&#x4E8E; <code>node-compile-1-2</code>&#xFF0C;&#x8C03;&#x7528;&#x865A;&#x62DF;&#x673A;&#x63A5;&#x53E3; <code>runInThisContext</code>&#xFF0C;&#x7528;&#x4E8E;&#x5728;&#x5F53;&#x524D;&#x4E0A;&#x4E0B;&#x6587;&#x6267;&#x884C;&#x4EE3;&#x7801;&#x3002;</li>
<li><code>compile-5</code>&#xFF0C;&#x7B49;&#x540C;&#x4E8E; <code>node-compile-2</code>&#xFF0C;&#x751F;&#x6210; require &#x7B49;&#x53C2;&#x6570;&#x3002;</li>
<li><code>compile-6</code>&#xFF0C;&#x7B49;&#x540C;&#x4E8E; <code>node-compile-3</code>&#xFF0C;&#x6267;&#x884C;&#x5C01;&#x88C5;&#x540E;&#x7684;&#x4EE3;&#x7801;&#x3002;</li>
</ul>
<p>&#x548C; node &#x7684;&#x4E0D;&#x540C;&#x4E4B;&#x5904;&#xFF1A;</p>
<ul>
<li><code>compile-2</code>&#xFF0C;&#x589E;&#x52A0;&#x4E86;&#x83B7;&#x53D6;&#x7F13;&#x5B58;&#xFF0C;&#x5E76;&#x8BB0;&#x5F55;&#x7F13;&#x5B58;&#x4E8B;&#x4EF6;&#x7684;&#x903B;&#x8F91;&#x3002;</li>
<li><code>compile-3</code>&#xFF0C;&#x7F16;&#x8BD1;&#x4EE3;&#x7801;&#x65F6;&#xFF0C;options &#x4E2D;&#x4F20;&#x5165;&#x4E86;&#x7F13;&#x5B58;&#x3002;</li>
<li><code>compile-5</code>&#xFF0C;&#x6539;&#x5199;&#x4E86; <code>makeRequireFunction</code>&#x3002;</li>
<li><code>compile-7</code>&#xFF0C;&#x6267;&#x884C;&#x4EE3;&#x7801;&#x540E;&#xFF0C;&#x7F13;&#x5B58;&#x4E86;&#x6570;&#x636E;&#x3002;</li>
</ul>
<p>&#x53EF;&#x4EE5;&#x770B;&#x51FA;&#xFF0C;vscode-loader &#x7684; <code>Module.prototype._compile</code>&#xFF0C;&#x4E3B;&#x8981;&#x662F;<strong>&#x589E;&#x52A0;&#x4E86;&#x7F13;&#x5B58;&#x7684;&#x903B;&#x8F91;</strong>&#xFF0C;&#x6539;&#x5199;&#x4E86; <code>makeRequireFunction</code>&#x3002;</p>
<p><code>makeRequireFunction</code> &#x7684;&#x5BF9;&#x6BD4;&#x5982;&#x4E0B;&#xFF1A;</p>
<pre><code class="language-ts">// node
function makeRequireFunction(mod, redirects) {
    const Module = mod.constructor;

    let require;
    if (redirects) {
		// &#x5904;&#x7406;&#x91CD;&#x5B9A;&#x5411;
        const { resolve, reaction } = redirects;
        const id = mod.filename || mod.id;
        require = function require(path) {
			// node &#x534F;&#x8BAE;&#xFF0C;&#x52A0;&#x8F7D;&#x539F;&#x751F;&#x6A21;&#x5757;&#xFF0C;&#x8FD4;&#x56DE; exports
			// &#x6587;&#x4EF6;&#x534F;&#x8BAE;&#xFF0C;&#x8C03;&#x7528; mode.require&#xFF0C;&#x52A0;&#x8F7D;&#x6587;&#x4EF6;
			...
            return mod.require(path);
        };
    } else {
		// &#x975E;&#x91CD;&#x5B9A;&#x5411;&#xFF0C;&#x76F4;&#x63A5;&#x8C03;&#x7528; mod.require
        require = function require(path) {
            return mod.require(path);
        };
    }

    function resolve(request, options) {
        validateString(request, &apos;request&apos;);
        return Module._resolveFilename(request, mod, false, options);
    }
    require.resolve = resolve;
    function paths(request) {
        validateString(request, &apos;request&apos;);
        return Module._resolveLookupPaths(request, mod);
    }
    resolve.paths = paths;
    require.main = process.mainModule;
    require.extensions = Module._extensions;
    require.cache = Module._cache;
    return require;
}

// vscode-loader
function makeRequireFunction(mod: any) {
	const Module = mod.constructor;
	// &#x76F4;&#x63A5;&#x8C03;&#x7528; mod.require
	let require = &lt;any&gt;function require(path) {
		try {
			return mod.require(path);
		} finally {
			// nothing
		}
	}
	require.resolve = function resolve(request, options) {
		return Module._resolveFilename(request, mod, false, options);
	};
	require.resolve.paths = function paths(request) {
		return Module._resolveLookupPaths(request, mod);
	};
	require.main = process.mainModule;
	require.extensions = Module._extensions;
	require.cache = Module._cache;
	return require;
}

</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&#x7531;&#x4E8E; vscode-loader &#x7684; <code>Module.prototype._compile</code> &#x6CA1;&#x6709;&#x91CD;&#x5B9A;&#x5411;&#x7684;&#x60C5;&#x51B5;&#xFF0C;&#x6240;&#x4EE5; <code>makeRequireFunction</code> &#x4E2D;&#x7684; require&#xFF0C;&#x5220;&#x9664;&#x4E86;&#x91CD;&#x5B9A;&#x5411;&#x5904;&#x7406;&#x3002;&#x800C; require &#x7684;&#x5176;&#x4ED6;&#x5C5E;&#x6027;&#xFF0C;&#x548C; node &#x4FDD;&#x6301;&#x4E00;&#x81F4;&#xFF0C;&#x6CA1;&#x6709;&#x4FEE;&#x6539;&#x3002;</p>
<h4 id="vscode-loader-%E7%9A%84%E7%BC%93%E5%AD%98%E5%A4%84%E7%90%86">vscode-loader &#x7684;&#x7F13;&#x5B58;&#x5904;&#x7406;</h4>
<p>vscode-loader &#x901A;&#x8FC7; config &#x6765;&#x8BBE;&#x7F6E;&#x7F13;&#x5B58;&#x76EE;&#x5F55;&#xFF1A;</p>
<pre><code class="language-ts">// &#x8BBE;&#x7F6E;&#x7F13;&#x5B58;
loader.config({
  nodeCachedData: {
    path: &quot;./cache-data&quot;,
  },
});
</code></pre>
<p><code>compile-2</code> &#x901A;&#x8FC7; <code>_getCachedDataPath</code> &#x83B7;&#x53D6;&#x7F13;&#x5B58;&#x8DEF;&#x5F84;&#xFF1A;</p>
<pre><code class="language-ts">// compile-2
const cachedDataPath = that._getCachedDataPath(nodeCachedData, filename);

// &#x5BF9;&#x4E8E;&#x793A;&#x4F8B;&#x800C;&#x8A00;&#xFF0C;&#x7F13;&#x5B58;&#x8DEF;&#x5F84;&#x4E3A; cache-data/test-${hash}.code
private _getCachedDataPath(config: INodeCachedDataConfiguration, filename: string): string {
	// &#x6839;&#x636E;&#x6587;&#x4EF6;&#x540D;&#x3001;&#x914D;&#x7F6E;&#x7B49;&#x751F;&#x6210; hash &#x503C;
	const hash = this._crypto.createHash(&apos;md5&apos;).update(filename, &apos;utf8&apos;).update(config.seed!, &apos;utf8&apos;).update(process.arch, &apos;&apos;).digest(&apos;hex&apos;);
	const basename = this._path.basename(filename).replace(/\.js$/, &apos;&apos;);
	return this._path.join(config.path, `${basename}-${hash}.code`);
}
</code></pre>
<p><code>compile-2</code> &#x8BFB;&#x53D6;&#x7F13;&#x5B58;&#x540E;&#xFF0C;&#x5E76;&#x901A;&#x8FC7; options &#x4F20;&#x5165; vm.script&#xFF0C;&#x4EE5;&#x4F7F;&#x7528;&#x7F13;&#x5B58;&#x6570;&#x636E;&#xFF1A;</p>
<pre><code class="language-ts">// compile-2
try {
	const cachedDataPath = that._getCachedDataPath(nodeCachedData, filename);
	// &#x8BFB;&#x53D6;&#x7F13;&#x5B58;&#x6570;&#x636E;
	const data = that._fs.readFileSync(cachedDataPath);
	hashData = data.slice(0, 16);
	// &#x8BBE;&#x7F6E;&#x5230; options.cachedData
	options.cachedData = data.slice(16);
	...
} catch (_e) {
	...
}
// options &#x4E2D;&#x5305;&#x542B; cachedData
const script = new that._vm.Script(scriptSource, options);
</code></pre>
<p>&#x6267;&#x884C;&#x6E90;&#x6587;&#x4EF6;&#x7684;&#x4EE3;&#x7801;&#x540E;&#xFF0C;<code>compile-7</code> &#x66F4;&#x65B0;&#x548C;&#x6821;&#x9A8C;&#x7F13;&#x5B58;&#x6570;&#x636E;&#xFF1A;</p>
<pre><code class="language-ts">// compile-7
that._handleCachedData(script, scriptSource, cachedDataPath, !options.cachedData, moduleManager);
that._verifyCachedData(script, scriptSource, cachedDataPath!, hashData, moduleManager);

// &#x5904;&#x7406;&#x7F13;&#x5B58;&#x6570;&#x636E;&#xFF1A;&#x5982;&#x679C;&#x7F13;&#x5B58;&#x5931;&#x8D25;&#xFF0C;&#x5C31;&#x5220;&#x9664;&#x539F;&#x6765;&#x7684;&#x7F13;&#x5B58;&#xFF0C;&#x91CD;&#x65B0;&#x751F;&#x6210;&#x7F13;&#x5B58;&#xFF1B;&#x5982;&#x679C; options &#x6CA1;&#x6709;&#x7F13;&#x5B58;&#x6570;&#x636E;&#xFF0C;&#x5C31;&#x751F;&#x6210;&#x7F13;&#x5B58;&#x6570;&#x636E;
private _handleCachedData(script: INodeVMScript, scriptSource: string, cachedDataPath: string, createCachedData: boolean, moduleManager: IModuleManager): void {
	if (script.cachedDataRejected) {
		// cached data got rejected -&gt; delete and re-create
		this._fs.unlink(cachedDataPath, err =&gt; {
			moduleManager.getRecorder().record(LoaderEventType.CachedDataRejected, cachedDataPath);
			this._createAndWriteCachedData(script, scriptSource, cachedDataPath, moduleManager);
			if (err) {
				moduleManager.getConfig().onError(err)
			}
		});
	} else if (createCachedData) {
		// no cached data, but wanted
		this._createAndWriteCachedData(script, scriptSource, cachedDataPath, moduleManager);
	}
}

// &#x6821;&#x9A8C;&#x7F13;&#x5B58;&#x6570;&#x636E;&#xFF1A;&#x5982;&#x679C; hash &#x503C;&#x6539;&#x53D8;&#xFF0C;&#x5C31;&#x5220;&#x9664;&#x7F13;&#x5B58;&#x6587;&#x4EF6;
private _verifyCachedData(script: INodeVMScript, scriptSource: string, cachedDataPath: string, hashData: Buffer | undefined, moduleManager: IModuleManager): void {
	if (!hashData) {
		// nothing to do
		return;
	}
	if (script.cachedDataRejected) {
		// invalid anyways
		return;
	}
	setTimeout(() =&gt; {
		// check source hash - the contract is that file paths change when file content
		// change (e.g use the commit or version id as cache path). this check is
		// for violations of this contract.
		const hashDataNow = this._crypto.createHash(&apos;md5&apos;).update(scriptSource, &apos;utf8&apos;).digest();
		if (!hashData.equals(hashDataNow)) {
			moduleManager.getConfig().onError(&lt;any&gt;new Error(`FAILED TO VERIFY CACHED DATA, deleting stale &apos;${cachedDataPath}&apos; now, but a RESTART IS REQUIRED`));
			this._fs.unlink(cachedDataPath!, err =&gt; {
				if (err) {
					moduleManager.getConfig().onError(err);
				}
			});
		}

	}, Math.ceil(5000 * (1 + Math.random())));
}

</code></pre>
<h3 id="%E5%8A%A0%E8%BD%BD%E6%A8%A1%E5%9D%97">&#x52A0;&#x8F7D;&#x6A21;&#x5757;</h3>
<p>&#x521D;&#x59CB;&#x5316;&#x4E4B;&#x540E;&#xFF0C;load-3 &#x8FDB;&#x884C;&#x6A21;&#x5757;&#x52A0;&#x8F7D;&#xFF0C;&#x4E3B;&#x8981;&#x5206;&#x4E3A;&#x8DEF;&#x5F84;&#x5904;&#x7406;&#x3001;&#x83B7;&#x53D6;&#x6A21;&#x5757;&#x4EE3;&#x7801;&#x5E76;&#x6267;&#x884C;&#x3002;</p>
<h4 id="%E8%B7%AF%E5%BE%84%E5%A4%84%E7%90%86">&#x8DEF;&#x5F84;&#x5904;&#x7406;</h4>
<pre><code class="language-ts">class NodeScriptLoader implements IScriptLoader {
	public load(moduleManager: IModuleManager, scriptSrc: string, callback: () =&gt; void, errorback: (err: any) =&gt; void): void {
		...
		// load-3-1: &#x8DEF;&#x5F84;&#x5904;&#x7406;
		// &#x5BF9;&#x4E8E;&#x793A;&#x4F8B;&#x800C;&#x8A00;&#xFF0C;test.js -&gt; test.js
		scriptSrc = Utilities.fileUriToFilePath(this._env.isWindows, scriptSrc);
		const normalizedScriptSrc = this._path.normalize(scriptSrc);
		const vmScriptPathOrUri = this._getElectronRendererScriptPathOrUri(normalizedScriptSrc);
		// &#x914D;&#x7F6E;&#x662F;&#x5426;&#x4F7F;&#x7528;&#x7F13;&#x5B58;&#xFF0C;&#x793A;&#x4F8B;&#x4E3A; true
		const wantsCachedData = Boolean(opts.nodeCachedData);
		// &#x5982;&#x679C;&#x4F7F;&#x7528;&#x7F13;&#x5B58;&#xFF0C;&#x83B7;&#x53D6;&#x7F13;&#x5B58;&#x8DEF;&#x5F84;&#xFF0C;&#x793A;&#x4F8B;&#x4E3A; cache-data/test-${hash}.code
		const cachedDataPath = wantsCachedData ? this._getCachedDataPath(opts.nodeCachedData!, scriptSrc) : undefined;
		...
	}
}
</code></pre>
<h4 id="%E8%8E%B7%E5%8F%96%E6%A8%A1%E5%9D%97%E4%BB%A3%E7%A0%81%E5%B9%B6%E6%89%A7%E8%A1%8C">&#x83B7;&#x53D6;&#x6A21;&#x5757;&#x4EE3;&#x7801;&#x5E76;&#x6267;&#x884C;</h4>
<pre><code class="language-ts">class NodeScriptLoader implements IScriptLoader {

	private static _BOM = 0xFEFF;
	private static _PREFIX = &apos;(function (require, define, __filename, __dirname) { &apos;;
	private static _SUFFIX = &apos;\n});&apos;;

	public load(moduleManager: IModuleManager, scriptSrc: string, callback: () =&gt; void, errorback: (err: any) =&gt; void): void {
		...
		// load-3-2: &#x83B7;&#x53D6;&#x6A21;&#x5757;&#x4EE3;&#x7801;&#x548C;&#x7F13;&#x5B58;&#xFF0C;&#x6267;&#x884C;&#x4EE3;&#x7801;
		// &#x7B2C;&#x4E00;&#x6B65;: &#x83B7;&#x53D6;&#x6A21;&#x5757;&#x4EE3;&#x7801;&#x548C;&#x7F13;&#x5B58;&#xFF0C;&#x5176;&#x4E2D;&#x83B7;&#x53D6;&#x7F13;&#x5B58;&#x540C; compile-2
		this._readSourceAndCachedData(normalizedScriptSrc, cachedDataPath, recorder, (err: any, data: string, cachedData: Buffer, hashData: Buffer) =&gt; {
			if (err) {
				errorback(err);
				return;
			}

			// &#x7B2C;&#x4E8C;&#x6B65;: &#x5904;&#x7406;&#x6A21;&#x5757;&#x4EE3;&#x7801;&#xFF0C;&#x540C; compile-1
			// &#x5982;&#x679C;&#x6709; bom &#x5219;&#x53BB;&#x9664;&#xFF0C;&#x518D;&#x5C01;&#x88C5;&#x6587;&#x4EF6;&#x5185;&#x5BB9;&#xFF0C;&#x5373; &apos;(function (require, define, __filename, __dirname)&apos; + data + &apos;{ \n});&apos;;
			let scriptSource: string;
			if (data.charCodeAt(0) === NodeScriptLoader._BOM) {
				scriptSource = NodeScriptLoader._PREFIX + data.substring(1) + NodeScriptLoader._SUFFIX;
			} else {
				scriptSource = NodeScriptLoader._PREFIX + data + NodeScriptLoader._SUFFIX;
			}
			// &#x5982;&#x679C;&#x914D;&#x7F6E;&#x4E86;&#x8F6C;&#x6362;&#x51FD;&#x6570;&#xFF0C;&#x5219;&#x6267;&#x884C;&#x8F6C;&#x6362;&#x51FD;&#x6570;&#xFF1A;const nodeInstrumenter = (opts.nodeInstrumenter || function (c) { return c; });
			scriptSource = nodeInstrumenter(scriptSource, normalizedScriptSrc);

			// &#x7B2C;&#x4E09;&#x6B65;: &#x751F;&#x6210;&#x5E76;&#x6267;&#x884C;&#x811A;&#x672C;&#xFF0C;cacheData &#x5BF9;&#x5E94;&#x4ECE;&#x7F13;&#x5B58;&#x8DEF;&#x5F84;&#x8BFB;&#x53D6;&#x7684;&#x7F13;&#x5B58;&#x6570;&#x636E;&#xFF0C;&#x540C; compile-3 ~ compile-6
			const scriptOpts: INodeVMScriptOptions = { filename: vmScriptPathOrUri, cachedData };
			const script = this._createAndEvalScript(moduleManager, scriptSource, scriptOpts, callback, errorback);

			// step-4: &#x66F4;&#x65B0;&#x3001;&#x9A8C;&#x8BC1;&#x7F13;&#x5B58;&#xFF0C;&#x540C; compile-7
			this._handleCachedData(script, scriptSource, cachedDataPath!, wantsCachedData &amp;&amp; !cachedData, moduleManager);
			this._verifyCachedData(script, scriptSource, cachedDataPath!, hashData, moduleManager);
		});

		// &#x7B2C;&#x4E00;&#x6B65;. &#x8BFB;&#x53D6;&#x6A21;&#x5757;&#x548C;&#x7F13;&#x5B58;&#x6587;&#x4EF6;
		private _readSourceAndCachedData(sourcePath: string, cachedDataPath: string | undefined, recorder: ILoaderEventRecorder, callback: (err?: any, source?: string, cachedData?: Buffer, hashData?: Buffer) =&gt; any): void {

			if (!cachedDataPath) {
				// &#x4E0D;&#x4F7F;&#x7528;&#x7F13;&#x5B58;&#x65F6;&#xFF0C;&#x76F4;&#x63A5;&#x8BFB;&#x53D6;&#x6A21;&#x5757;&#x6587;&#x4EF6;
				this._fs.readFile(sourcePath, { encoding: &apos;utf8&apos; }, callback);

			} else {
				// &#x4F7F;&#x7528;&#x7F13;&#x5B58;&#x65F6;&#xFF0C;&#x540C;&#x65F6;&#x8BFB;&#x53D6;&#x6A21;&#x5757;&#x6587;&#x4EF6;&#x548C;&#x7F13;&#x5B58;&#x6587;&#x4EF6;
				let source: string | undefined = undefined;
				let cachedData: Buffer | undefined = undefined;
				let hashData: Buffer | undefined = undefined;
				let steps = 2;

				const step = (err?: any) =&gt; {
					if (err) {
						callback(err);

					} else if (--steps === 0) {
						// &#x4E24;&#x4E2A;&#x6587;&#x4EF6;&#x90FD;&#x8BFB;&#x53D6;&#x540E;&#xFF0C;steps &#x53D8;&#x4E3A; 0&#xFF0C;&#x518D;&#x6267;&#x884C; callback
						callback(undefined, source, cachedData, hashData);
					}
				}

				this._fs.readFile(sourcePath, { encoding: &apos;utf8&apos; }, (err: any, data: string) =&gt; {
					source = data;
					step(err);
				});

				this._fs.readFile(cachedDataPath, (err: any, data: Buffer) =&gt; {
					if (!err &amp;&amp; data &amp;&amp; data.length &gt; 0) {
						hashData = data.slice(0, 16);
						cachedData = data.slice(16);
						recorder.record(LoaderEventType.CachedDataFound, cachedDataPath);

					} else {
						recorder.record(LoaderEventType.CachedDataMissed, cachedDataPath);
					}
					step(); // ignored: cached data is optional
				});
			}
		}

		// &#x7B2C;&#x4E09;&#x6B65;. &#x751F;&#x6210;&#x5E76;&#x6267;&#x884C;&#x811A;&#x672C;
		private _createAndEvalScript(moduleManager: IModuleManager, contents: string, options: INodeVMScriptOptions, callback: () =&gt; void, errorback: (err: any) =&gt; void): INodeVMScript {
			const recorder = moduleManager.getRecorder();
			recorder.record(LoaderEventType.NodeBeginEvaluatingScript, options.filename);

			// &#x540C; compile-3: &#x65B0;&#x5EFA; vm.Script&#xFF0C;&#x7F16;&#x8BD1;&#x4EE3;&#x7801;
			const script = new this._vm.Script(contents, options);
			// &#x540C; compile-4: &#x751F;&#x6210; ret&#xFF0C;&#x7528;&#x4E8E;&#x5728;&#x5F53;&#x524D;&#x4E0A;&#x4E0B;&#x6587;&#x8FD0;&#x884C;&#x4EE3;&#x7801;
			const ret = script.runInThisContext(options);

			// &#x83B7;&#x53D6; define &#x51FD;&#x6570;&#xFF0C;&#x5BF9;&#x5E94; main.ts &#x4E2D;&#x7684; DefineFunc
			const globalDefineFunc = moduleManager.getGlobalAMDDefineFunc();
			let receivedDefineCall = false;
			const localDefineFunc: IDefineFunc = &lt;any&gt;function () {
				receivedDefineCall = true;
				return globalDefineFunc.apply(null, arguments);
			};
			localDefineFunc.amd = globalDefineFunc.amd;

			// &#x540C; compile-6: &#x6267;&#x884C; ret
			ret.call(global, moduleManager.getGlobalAMDRequireFunc(), localDefineFunc, options.filename, this._path.dirname(options.filename));

			recorder.record(LoaderEventType.NodeEndEvaluatingScript, options.filename);

			if (receivedDefineCall) {
				callback();
			} else {
				errorback(new Error(`Didn&apos;t receive define call in ${options.filename}!`));
			}

			return script;
		}
	}
}
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;load-3 &#x52A0;&#x8F7D;&#x6A21;&#x5757;&#xFF0C;&#x548C; <code>Module.prototype._compile</code> &#x7684;&#x5904;&#x7406;&#x903B;&#x8F91;&#x57FA;&#x672C;&#x4E00;&#x81F4;&#xFF0C;&#x90FD;&#x662F;&#x8C03;&#x7528; <code>vm.script</code>&#xFF0C;<code>runInThisContext</code> &#x7F16;&#x8BD1;&#x4EE3;&#x7801;&#x3001;&#x6267;&#x884C;&#x4EE3;&#x7801;&#x3002;&#x5BF9;&#x7F13;&#x5B58;&#x7684;&#x5904;&#x7406;&#x4E5F;&#x57FA;&#x672C;&#x4E00;&#x81F4;&#xFF0C;&#x90FD;&#x662F;&#x8BFB;&#x53D6;&#x7F13;&#x5B58;&#x6587;&#x4EF6;&#x5185;&#x5BB9; <code>cachedData</code>&#xFF0C;&#x5728; <code>new vm.script</code> &#x65F6;&#x4F20;&#x5165;&#x7F13;&#x5B58;&#xFF1B;&#x6267;&#x884C;&#x4EE3;&#x7801;&#x540E;&#xFF0C;&#x901A;&#x8FC7; <code>_handleCachedData</code>&#x3001;<code>_verifyCachedData</code> &#x66F4;&#x65B0;&#x3001;&#x9A8C;&#x8BC1;&#x7F13;&#x5B58;&#x3002;</p>
<h2 id="define-%E5%AE%9A%E4%B9%89%E6%A8%A1%E5%9D%97">define &#x5B9A;&#x4E49;&#x6A21;&#x5757;</h2>
<p>node &#x73AF;&#x5883;&#x548C;&#x6D4F;&#x89C8;&#x5668;&#x73AF;&#x5883;&#xFF0C;define &#x5B9A;&#x4E49;&#x6A21;&#x5757;&#x7684;&#x903B;&#x8F91;&#x662F;&#x4E00;&#x81F4;&#x7684;&#xFF0C;&#x672C;&#x6587;&#x4E0D;&#x518D;&#x8D58;&#x8FF0;&#x3002;</p>
<h2 id="%E6%80%BB%E7%BB%93">&#x603B;&#x7ED3;</h2>
<p>&#x672C;&#x6587;&#x4E3B;&#x8981;&#x4ECB;&#x7ECD;&#x4E86; vscode-loader &#x5728; node &#x73AF;&#x5883;&#x548C;&#x6D4F;&#x89C8;&#x5668;&#x73AF;&#x5883;&#x7684;&#x533A;&#x522B;&#xFF0C;&#x5373; <code>scriptLoader</code> &#x52A0;&#x8F7D;&#x6A21;&#x5757;&#x7684;&#x65B9;&#x5F0F;&#x4E0D;&#x540C;&#xFF1A;</p>
<ul>
<li>&#x6D4F;&#x89C8;&#x5668;&#x73AF;&#x5883;&#xFF0C;&#x751F;&#x6210; <code>&lt;script&gt;</code> &#x6807;&#x7B7E;&#xFF0C;&#x5E76;&#x8BBE;&#x7F6E; async&#xFF0C;&#x5F02;&#x6B65;&#x52A0;&#x8F7D;&#x6A21;&#x5757;&#x3002;</li>
<li>node &#x73AF;&#x5883;&#xFF0C;&#x8BFB;&#x53D6;&#x6587;&#x4EF6;&#x5185;&#x5BB9;&#xFF0C;&#x518D;&#x8C03;&#x7528; <code>vm</code> &#x63A5;&#x53E3;&#xFF08;<code>vm.script</code>&#xFF0C;<code>runInThisContext</code>&#xFF09;&#x7F16;&#x8BD1;&#x4EE3;&#x7801;&#x3001;&#x6267;&#x884C;&#x4EE3;&#x7801;&#xFF0C;&#x4E14;&#x652F;&#x6301;&#x7F13;&#x5B58;&#x6570;&#x636E;&#x3002;</li>
</ul>
<h2 id="%E7%8C%9C%E6%82%A8%E5%8F%AF%E8%83%BD%E6%84%9F%E5%85%B4%E8%B6%A3%E7%9A%84%E6%96%87%E7%AB%A0">&#x731C;&#x60A8;&#x53EF;&#x80FD;&#x611F;&#x5174;&#x8DA3;&#x7684;&#x6587;&#x7AE0;</h2>
<ul>
<li><a href="https://forum.lovejade.cn/d/97-ide-babelconfigjs">&#x5FEB;&#x5E94;&#x7528; IDE &#x914D;&#x7F6E; babel.config.js &#x7684;&#x524D;&#x4E16;&#x4ECA;&#x751F;</a></li>
<li><a href="https://quickapp.vivo.com.cn/quickapp-ide-getting-started/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177;&#x5165;&#x95E8;&#x4ECB;&#x7ECD;</a></li>
<li><a href="https://forum.lovejade.cn/d/75-chrome-url">Chrome &#x4E3A;&#x4F55;&#x65E0;&#x6CD5;&#x901A;&#x8FC7; url &#x62C9;&#x8D77;&#x5FEB;&#x5E94;&#x7528;&#xFF1F;</a></li>
<li><a href="https://forum.lovejade.cn/d/72">&#x56E2;&#x961F;&#x5F00;&#x53D1;&#x5FEB;&#x5E94;&#x7528;&#xFF0C;&#x5982;&#x4F55;&#x7EDF;&#x4E00;&#x4EE3;&#x7801;&#x98CE;&#x683C;&#xFF1F;</a></li>
<li><a href="https://forum.lovejade.cn/d/71-prettier">&#x5982;&#x4F55;&#x7528; Prettier &#x7F8E;&#x5316;&#x60A8;&#x7684;&#x5FEB;&#x5E94;&#x7528;&#x4EE3;&#x7801;&#xFF1F;</a></li>
<li><a href="https://quickapp.vivo.com.cn/quickapp-ide-pretest/">&#x5982;&#x4F55;&#x901A;&#x8FC7; IDE &#x7684;&#x9884;&#x68C0;&#x6D4B;&#x529F;&#x80FD;&#x63D0;&#x9AD8;&#x5BA1;&#x6838;&#x901A;&#x8FC7;&#x7387;</a></li>
<li><a href="https://quickapp.vivo.com.cn/how-to-configure-code-snippets-gracefully-in-quickapp-development/">&#x5982;&#x4F55;&#x4F18;&#x96C5;&#x5730;&#x914D;&#x7F6E;&#x5FEB;&#x5E94;&#x7528;&#x7684;&#x4EE3;&#x7801;&#x7247;&#x6BB5;</a></li>
<li><a href="https://quickapp.vivo.com.cn/how-to-develop-quickapp-based-on-typescript/">&#x5982;&#x4F55;&#x57FA;&#x4E8E; Typescript &#x5F00;&#x53D1;&#x5FEB;&#x5E94;&#x7528;</a></li>
<li><a href="https://forum.lovejade.cn/d/59">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x4E2D;&#xFF0C;&#x5982;&#x4F55;&#x533A;&#x5206;&#x5404;&#x79CD;&#x73AF;&#x5883;&#xFF1F;</a></li>
<li><a href="https://forum.lovejade.cn/d/19-qa-spin">&#x5FEB;&#x5E94;&#x7528;&#x5B98;&#x65B9;&#x52A0;&#x8F7D;&#x52A8;&#x753B;&#x5E93;&#xFF1A;qa-spin</a></li>
<li><a href="https://forum.lovejade.cn/d/102-vscode-loader-requirejs">vscode-loader &#x5B9E;&#x73B0;&#x4E4B;&#xFF1A;requirejs &#x6E90;&#x7801;&#x89E3;&#x6790;</a></li>
<li><a href="https://forum.lovejade.cn/d/115-vscode-loader">vscode-loader &#x6E90;&#x7801;&#x89E3;&#x6790;&#x4E4B;&#x300C;&#x6D4F;&#x89C8;&#x5668;&#x73AF;&#x5883;&#x300D;</a></li>
<li><a href="https://forum.lovejade.cn/d/126-vscode-loader-node">vscode-loader &#x89E3;&#x6790;&#x4E4B;&#xFF08;node &#x73AF;&#x5883;&#xFF09;</a></li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[快应用开发工具 6.0 版本发布]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>&#x5FEB;&#x5E94;&#x7528;&#x5DE5;&#x5177;&#x5F00;&#x53D1;&#x56E2;&#x961F;&#xFF0C;&#x4E8E; 2021 &#x5E74; 12 &#x6708; 14 &#x65E5;&#xFF0C;&#x53D1;&#x5E03; IDE &#x6700;&#x65B0;&#x7248;&#x672C;&#xFF1A;<a href="https://www.quickapp.cn/docCenter/post/97">v6.0.0</a>&#x3002;</p>
<h2 id="v60-%E6%9B%B4%E6%96%B0%E8%AF%B4%E6%98%8E"><code>v6.0</code> &#x66F4;&#x65B0;&#x8BF4;&#x660E;</h2>
<p>&#x5728; 12 &#x6708;&#x4E2D;&#x65EC;&#xFF0C;&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x56E2;&#x961F;&#xFF0C;</p>]]></description><link>https://quickapp.vivo.com.cn/quickapp-ide-v6-0-release/</link><guid isPermaLink="false">63c4b94a77e2ca0006a8c8a0</guid><category><![CDATA[快应用开发工具]]></category><dc:creator><![CDATA[vivo-developer]]></dc:creator><pubDate>Fri, 17 Dec 2021 09:14:44 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>&#x5FEB;&#x5E94;&#x7528;&#x5DE5;&#x5177;&#x5F00;&#x53D1;&#x56E2;&#x961F;&#xFF0C;&#x4E8E; 2021 &#x5E74; 12 &#x6708; 14 &#x65E5;&#xFF0C;&#x53D1;&#x5E03; IDE &#x6700;&#x65B0;&#x7248;&#x672C;&#xFF1A;<a href="https://www.quickapp.cn/docCenter/post/97">v6.0.0</a>&#x3002;</p>
<h2 id="v60-%E6%9B%B4%E6%96%B0%E8%AF%B4%E6%98%8E"><code>v6.0</code> &#x66F4;&#x65B0;&#x8BF4;&#x660E;</h2>
<p>&#x5728; 12 &#x6708;&#x4E2D;&#x65EC;&#xFF0C;&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x56E2;&#x961F;&#xFF0C;&#x5C06;&#x4E4B;&#x524D;&#x9057;&#x7559;&#x7684;&#x4E00;&#x4E9B;&#x672A;&#x89E3;&#x51B3;&#x95EE;&#x9898;&#xFF0C;&#x505A;&#x4E86;&#x5904;&#x7406;&#x548C;&#x4F18;&#x5316;&#xFF0C;&#x63A8;&#x51FA;&#x6700;&#x65B0; <a href="https://www.quickapp.cn/docCenter/post/97">v6.0.0</a> &#x7248;&#x672C;&#xFF1B;&#x4E0B;&#x9762;&#x8BF7;&#x5141;&#x8BB8;&#x8DDF;&#x5927;&#x5BB6;&#x5206;&#x4EAB;&#x4E0B;&#xFF0C;&#x5728;&#x6B64;&#x6B21;&#x8FED;&#x4EE3;&#xFF0C;&#x6211;&#x4EEC;&#x505A;&#x4E86;&#x4E00;&#x4E9B;&#x91CD;&#x8981;&#x6539;&#x8FDB;&#x3002;</p>
<h3 id="%E4%BC%98%E5%8C%96%E6%9B%B4%E6%96%B0">&#x4F18;&#x5316;&#x66F4;&#x65B0;</h3>
<h4 id="%E6%89%93%E5%8C%85%E6%94%AF%E6%8C%81%E4%BF%AE%E6%94%B9%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F%E5%92%8C%E5%85%B6%E4%BB%96%E7%9A%84%E5%8F%82%E6%95%B0">&#x6253;&#x5305;&#x652F;&#x6301;&#x4FEE;&#x6539;&#x73AF;&#x5883;&#x53D8;&#x91CF;&#x548C;&#x5176;&#x4ED6;&#x7684;&#x53C2;&#x6570;</h4>
<p>&#x9876;&#x90E8;&#x5DE5;&#x5177;&#x680F;&#x7684;&#x6253;&#x5305;&#x6539;&#x4E3A;&#x4E0B;&#x62C9;&#x6846;&#x5F62;&#x5F0F;&#xFF0C;&#x9ED8;&#x8BA4;&#x6709;&#x4E09;&#x4E2A;&#x914D;&#x7F6E;&#xFF0C;&#x5206;&#x522B;&#x4F20;&#x5165; NODE_ENV &#x7684;&#x503C;&#x4E3A; production&#xFF08;&#x6B63;&#x5F0F;&#x5305;&#xFF09;&#x3001;development&#xFF08;&#x6D4B;&#x8BD5;&#x5305;&#xFF09; &#x548C; pre&#xFF08;&#x9884;&#x53D1;&#x5305;&#xFF09;&#xFF0C;&#x652F;&#x6301;&#x81EA;&#x5B9A;&#x4E49;&#x914D;&#x7F6E;&#x3002;</p>
<img src="https://statres.quickapp.cn/quickapp/show/img/211208/package_1.png" width="360px">
<p>&#x70B9;&#x51FB;&#x87BA;&#x4E1D;&#x5200;&#x6309;&#x94AE;&#x53EF;&#x81EA;&#x884C;&#x4FEE;&#x6539; NODE_ENV &#x7684;&#x503C;&#xFF0C;&#x5982;&#x6709;&#x9700;&#x6C42;&#x53EF;&#x81EA;&#x5B9A;&#x4E49;&#x5176;&#x4ED6;&#x53D8;&#x91CF;</p>
<img src="https://statres.quickapp.cn/quickapp/show/img/211208/package_2.png" width="720px">
<h4 id="%E4%BC%98%E5%8C%96%E7%83%AD%E6%9B%B4%E6%96%B0%E9%80%9F%E5%BA%A6">&#x4F18;&#x5316;&#x70ED;&#x66F4;&#x65B0;&#x901F;&#x5EA6;</h4>
<p>&#x4F18;&#x5316; watch &#x6A21;&#x5F0F;&#x4E0B;&#x7684;&#x771F;&#x673A;&#x70ED;&#x66F4;&#x65B0;&#x901F;&#x5EA6;&#xFF0C;&#x5728; <code>ctrl + s</code> &#x4FDD;&#x5B58;&#x4E4B;&#x540E;&#xFF0C;&#x70ED;&#x66F4;&#x65B0;&#x5E73;&#x5747;&#x901F;&#x5EA6;&#x4F18;&#x5316;&#x53EF;&#x8FBE; 56%&#xFF0C;&#x5927;&#x9879;&#x76EE;&#x4F18;&#x5316;&#x66F4;&#x4E3A;&#x660E;&#x663E;&#x3002;</p>
<h4 id="%E6%B8%85%E7%90%86%E7%B2%BE%E7%AE%80%E6%97%A5%E5%BF%97">&#x6E05;&#x7406;&#x7CBE;&#x7B80;&#x65E5;&#x5FD7;</h4>
<p>&#x6E05;&#x7406;&#x7CBE;&#x7B80;&#x4E86;&#x8F93;&#x51FA;&#x9762;&#x677F;&#x7684; hap-debug &#x65E5;&#x5FD7;&#xFF0C;&#x53EA;&#x4FDD;&#x7559; warn &#x548C; error &#x7684;&#x65E5;&#x5FD7;&#x3002;</p>
<h4 id="%E6%9B%B4%E6%96%B0%E8%B0%83%E8%AF%95%E5%99%A8%E5%92%8C%E5%BC%95%E6%93%8E">&#x66F4;&#x65B0;&#x8C03;&#x8BD5;&#x5668;&#x548C;&#x5F15;&#x64CE;</h4>
<p>&#x66F4;&#x65B0;&#x4E86; IDE &#x5185;&#x7F6E;&#x7684;&#x6700;&#x65B0;&#x7684;&#x5F15;&#x64CE;&#x548C;&#x8C03;&#x8BD5;&#x5668;&#xFF0C;&#x53EF;&#x901A;&#x8FC7;&#x83DC;&#x5355;&#x300C;<strong>&#x5DE5;&#x5177;</strong>&#x300D;&#x300C;<strong>&#x66F4;&#x65B0;&#x624B;&#x673A;&#x73AF;&#x5883;</strong>&#x300D;&#x66F4;&#x65B0;&#x3002;</p>
<h4 id="%E5%A2%9E%E5%8A%A0%E5%8D%A1%E7%89%87%E9%A2%84%E8%A7%88%E7%9A%84%E4%B8%A4%E4%B8%AA%E9%BB%98%E8%AE%A4%E9%85%8D%E7%BD%AE">&#x589E;&#x52A0;&#x5361;&#x7247;&#x9884;&#x89C8;&#x7684;&#x4E24;&#x4E2A;&#x9ED8;&#x8BA4;&#x914D;&#x7F6E;</h4>
<p>&#x9884;&#x89C8;&#x8BBE;&#x7F6E;&#x91CC;&#x589E;&#x52A0;&#x4E24;&#x4E2A;&#x5361;&#x7247;&#x7684;&#x914D;&#x7F6E;&#xFF1A;&#x5361;&#x7247;&#x548C;&#x5361;&#x7247;&#x5E26;&#x5706;&#x89D2;</p>
<img src="https://statres.quickapp.cn/quickapp/show/img/211208/card_1.png" width="360px">
<p>&#x81EA;&#x5B9A;&#x4E49;&#x914D;&#x7F6E;&#x4E2D;&#x589E;&#x52A0;&#x5706;&#x89D2;&#x914D;&#x7F6E;&#xFF0C;&#x53EF;&#x652F;&#x6301;&#x6570;&#x5B57;&#x548C;&#x767E;&#x5206;&#x6BD4;</p>
<img src="https://statres.quickapp.cn/quickapp/show/img/211208/card_2.png" width="720px">
<h4 id="%E4%BE%A7%E8%BE%B9%E6%A0%8F%E5%88%A0%E9%99%A4%E8%B0%83%E8%AF%95%E9%9D%A2%E6%9D%BF">&#x4FA7;&#x8FB9;&#x680F;&#x5220;&#x9664;&#x8C03;&#x8BD5;&#x9762;&#x677F;</h4>
<p>&#x5220;&#x9664;&#x4E86;&#x4FA7;&#x8FB9;&#x680F;&#x7684;&#x8C03;&#x8BD5;&#x9762;&#x677F;</p>
<h4 id="%E5%A2%9E%E5%8A%A0%E6%89%93%E5%8C%85%E5%A4%B1%E8%B4%A5%E9%94%99%E8%AF%AF%E6%8F%90%E7%A4%BA">&#x589E;&#x52A0;&#x6253;&#x5305;&#x5931;&#x8D25;&#x9519;&#x8BEF;&#x63D0;&#x793A;</h4>
<p>&#x589E;&#x52A0;&#x6253;&#x5305;&#x5931;&#x8D25;&#x7684;&#x9519;&#x8BEF;&#x63D0;&#x793A;&#xFF0C;&#x5E76;&#x53EF;&#x8DF3;&#x8F6C;&#x5230;&#x8F93;&#x51FA;&#x9762;&#x677F;&#x7684; hap-debug &#x680F;&#x67E5;&#x770B;&#x65E5;&#x5FD7;</p>
<img src="https://statres.quickapp.cn/quickapp/show/img/211208/package_3.png" width="720px">
<h3 id="%E4%BF%AE%E5%A4%8D">&#x4FEE;&#x590D;</h3>
<h4 id="%E4%BF%AE%E5%A4%8D-js-%E7%8B%AC%E7%AB%8B%E8%B5%84%E6%BA%90%E6%89%93%E5%8C%85-bug">&#x4FEE;&#x590D; js &#x72EC;&#x7ACB;&#x8D44;&#x6E90;&#x6253;&#x5305; bug</h4>
<p>&#x63A8;&#x8350;&#x4F7F;&#x7528; <a href="https://doc.quickapp.cn/framework/js-split.html">js &#x72EC;&#x7ACB;&#x6253;&#x5305;</a>&#xFF0C;&#x5F53;&#x4E0D;&#x540C;&#x9875;&#x9762;&#x540C;&#x65F6;&#x5F15;&#x5165;&#x540C;&#x4E00; JS &#x8D44;&#x6E90;&#x65F6;&#xFF0C;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#x7F16;&#x8BD1;&#x5DE5;&#x5177;&#x4F1A;&#x5C06;&#x8BE5; JS &#x8D44;&#x6E90;&#x4EE3;&#x7801;&#x6253;&#x5305;&#x81F3;&#x8BE5;&#x9875;&#x9762;&#x6587;&#x4EF6;&#x4E2D;&#x3002;&#x7531;&#x4E8E;&#x6253;&#x5305;&#x540E;&#x76F8;&#x5173;&#x9875;&#x9762;&#x6587;&#x4EF6;&#x90FD;&#x5305;&#x542B;&#x4E86;&#x91CD;&#x590D;&#x7684; JS &#x4EE3;&#x7801;&#xFF0C;&#x4F1A;&#x9020;&#x6210;&#x6700;&#x7EC8;&#x6253;&#x5305;&#x751F;&#x6210;&#x7684; rpk &#x5305;&#x4F53;&#x79EF;&#x8F83;&#x5927;&#x3002;</p>
<p>&#x5FEB;&#x5E94;&#x7528;&#x5E73;&#x53F0;&#x81EA; 1080 &#x7248;&#x672C;&#x8D77;&#x652F;&#x6301;&#x5C06; JS &#x8D44;&#x6E90;&#x72EC;&#x7ACB;&#x6253;&#x5305;&#x3002;&#x5F53; app.ux &#x6216;&#x9875;&#x9762;&#x6587;&#x4EF6;&#x4E24;&#x6B21;&#x6216;&#x4EE5;&#x4E0A;&#x5F15;&#x7528;&#x5230;&#x540C;&#x4E00; JS &#x8D44;&#x6E90;&#x65F6;&#xFF0C;&#x4F1A;&#x5C06;&#x8BE5; JS &#x8D44;&#x6E90;&#x62BD;&#x53D6;&#x5230;&#x72EC;&#x7ACB;&#x7684;&#x6587;&#x4EF6;&#x4E2D;&#xFF0C;&#x4F7F;&#x5F97;&#x76F8;&#x5173;&#x6587;&#x4EF6;&#x5171;&#x7528;&#x540C;&#x4E00;&#x4EFD; JS &#x4EE3;&#x7801;&#xFF0C;&#x53EF;&#x6709;&#x6548;&#x51CF;&#x5C11;&#x6574;&#x4E2A; rpk &#x5305;&#x4F53;&#x79EF;&#x3002;</p>
<p>&#x53EA;&#x9700;&#x5728; <code>quickapp.config.js</code> &#x4E2D;&#x7684; cli &#x91CC;&#x914D;&#x7F6E; <code>splitChunksMode: &quot;SMART&quot;</code>&#xFF0C;&#x5373;&#x53EF;&#x4F7F;&#x7528; js &#x72EC;&#x7ACB;&#x8D44;&#x6E90;&#x6253;&#x5305;&#x3002;</p>
<pre><code class="language-js">// quickapp.config.js
module.exports = {
  cli: {
    // &#x8BF7;&#x6CE8;&#x610F;&#xFF0C;&#x8FD9;&#x91CC;&#x7684; SMART&#xFF0C;&#x987B;&#x8981;&#x662F;&#x5927;&#x5199;&#xFF1B;
    splitChunksMode: &apos;SMART&apos;
  }
}
</code></pre>
<h4 id="%E4%BF%AE%E5%A4%8D%E4%BF%AE%E6%94%B9-manifest-%E5%90%8E%E5%AF%BC%E8%87%B4%E7%9A%84%E7%BC%93%E5%AD%98%E9%97%AE%E9%A2%98">&#x4FEE;&#x590D;&#x4FEE;&#x6539; manifest &#x540E;&#x5BFC;&#x81F4;&#x7684;&#x7F13;&#x5B58;&#x95EE;&#x9898;</h4>
<p>&#x4FEE;&#x590D;&#x4FEE;&#x6539; <code>manifest.json</code> &#x6587;&#x4EF6;&#x4E2D;&#x7684; <code>versionName</code> &#x548C; <code>versionCode</code> &#x5B57;&#x6BB5;&#x5BFC;&#x81F4;&#x771F;&#x673A;&#x8C03;&#x8BD5;&#x65F6; rpk &#x5305;&#x627E;&#x4E0D;&#x5230;&#x95EE;&#x9898;</p>
<h2 id="%E5%B1%95%E6%9C%9B%E6%9C%AA%E6%9D%A5">&#x5C55;&#x671B;&#x672A;&#x6765;</h2>
<p>&#x5728;&#x63A5;&#x4E0B;&#x6765;&#x7684;&#x65E5;&#x5B50;&#x91CC;&#xFF0C;&#x6211;&#x4EEC;&#x5C06;&#x518D;&#x63A5;&#x518D;&#x5389;&#xFF0C;&#x4F7F;&#x5F97; IDE &#x4F7F;&#x7528;&#x4F53;&#x9A8C;&#x518D;&#x5347;&#x4E00;&#x4E2A;&#x53F0;&#x9636;&#x3002;&#x672A;&#x6765;&#xFF0C;&#x56E2;&#x961F;&#x4ECD;&#x5C06;&#x6301;&#x7EED;&#x5173;&#x6CE8;<strong>&#x6027;&#x80FD;</strong>&#x3001;<strong>&#x7A33;&#x5B9A;&#x6027;</strong>&#x3001;<strong>&#x517C;&#x5BB9;&#x6027;</strong>&#xFF0C;&#x8FD9;&#x4E9B;&#x5BF9;&#x4E8E;&#x7528;&#x6237;&#x548C;&#x6211;&#x4EEC;&#xFF0C;&#x90FD;&#x81F3;&#x5173;&#x91CD;&#x8981;&#x7684;&#x57FA;&#x672C;&#x9762;&#xFF1B;&#x540C;&#x65F6;&#x5C06;&#x6295;&#x5165;&#x66F4;&#x591A;&#x7CBE;&#x529B;&#x4E8E; IDE <strong>&#x9884;&#x89C8;</strong>&#x3001;&#x9884;&#x68C0;&#x6D4B;&#xFF0C;&#x529B;&#x4E89;&#x505A;&#x5230;&#x9884;&#x89C8;&#x4E4B;&#x5448;&#x73B0;&#xFF0C;&#x5373;&#x771F;&#x673A;&#x6240;&#x663E;&#xFF08;&#x76F8;&#x4FE1;&#x5728;&#x4E0D;&#x4E45;&#x4E4B;&#x540E;&#xFF0C;&#x5C06;&#x6709;&#x5927;&#x7684;&#x6539;&#x5584;&#xFF09;&#xFF1B;&#x5BF9;&#x4E8E;&#x65B0;&#x529F;&#x80FD;&#xFF0C;&#x4F1A;&#x6301;&#x8C28;&#x614E;&#x6001;&#x5EA6;&#xFF0C;&#x8BA4;&#x771F;&#x7814;&#x7A76;&#xFF0C;&#x529B;&#x4E89;&#x6BCF;&#x4E00;&#x70B9;&#x52AA;&#x529B;&#xFF0C;&#x90FD;&#x80FD;&#x4E3A;&#x60A8;&#x5E26;&#x6765;&#x5E94;&#x6709;&#x4EF7;&#x503C;&#xFF1B;&#x6700;&#x540E;&#xFF0C;&#x6211;&#x4EEC;&#x5C06;&#x59CB;&#x7EC8;&#x503E;&#x542C;&#x7528;&#x6237;&#x7684;&#x58F0;&#x97F3;&#xFF0C;&#x5982;&#x679C;&#x60A8;&#x6709;&#x4EFB;&#x4F55;&#x5EFA;&#x8BAE;&#x6216;&#x610F;&#x89C1;&#xFF0C;&#x8BF7;&#x53CA;&#x65F6;&#x544A;&#x77E5;&#xFF0C;&#x5C06;&#x5C3D;&#x53EF;&#x80FD;&#x6EE1;&#x8DB3;&#x60A8;&#x3002;</p>
<p>&#x5982;&#x679C;&#x60A8;&#x8FD8;&#x6CA1;&#x6709;&#x5C1D;&#x8BD5;&#x8FC7;&#x5FEB;&#x5E94;&#x7528; IDE&#xFF0C;&#x8BF7;<a href="https://www.quickapp.cn/docCenter/IDEPublicity">&#x4E0B;&#x8F7D;</a>&#x4EE5;&#x53CA;&#x5C1D;&#x8BD5;&#x4F7F;&#x7528;&#x5B83;&#xFF0C;&#x5982;&#x679C;&#x60A8;&#x6709;&#x4EFB;&#x4F55;&#x60F3;&#x6CD5;&#xFF0C;&#x8BF7;&#x53CA;&#x65F6;&#x8BA9;&#x6211;&#x4EEC;&#x77E5;&#x6653;&#x3002;</p>
<p>&#x518D;&#x6B21;&#x8868;&#x793A;&#x611F;&#x8C22;&#xFF01;&#x6700;&#x540E;&#xFF0C;&#x613F;&#x6240;&#x6709;&#x4EBA;&#xFF0C;&#x90FD;&#x53EF;&#x4EE5;&#xFF1A;<strong>&#x5DE5;&#x4F5C;&#x5F00;&#x5FC3;&#x4E0D;&#x52A0;&#x73ED;&#xFF0C;&#x751F;&#x6D3B;&#x5FEB;&#x4E50;&#x65E0;&#x5FE7;&#x8651;</strong>&#x3002;</p>
<p>&#x2500;&#x2500; &#x6765;&#x81EA;<code>&#x5FEB;&#x5E94;&#x7528;&#x5DE5;&#x5177;&#x5F00;&#x53D1;&#x56E2;&#x961F;</code>&#xFF0C;&#x4E8E; 2021 &#x5E74; 12 &#x6708; 14 &#x65E5;&#x3002;</p>
<hr>
<p>2021 &#x5E74; IDE &#x7248;&#x672C;&#x66F4;&#x65B0;&#x65F6;&#x95F4;&#x7EBF;&#xFF1A;</p>
<ul>
<li>10.28 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v5-1-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 5.1 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>9.2 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v5-0-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 5.0 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>7.26 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v4-1-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 4.1 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>6.30 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v4-0-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 4.0 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>5.27 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-10-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.10 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>4.13 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-9-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.9 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>3.11 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-8-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.8 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>2.4 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-7-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.7 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
</ul>
<p>2020 &#x5E74; IDE &#x7248;&#x672C;&#x66F4;&#x65B0;&#x65F6;&#x95F4;&#x7EBF;&#xFF1A;</p>
<ul>
<li>12.29 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-6-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.6 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>12.01 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-5-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.5 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>10.26 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-4-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.4 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>08.18 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-3-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.3 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>07.29 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-2-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.2 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>07.06 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-1-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.1 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>06.01 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.0 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[vscode-loader 解析（浏览器环境）]]></title><description><![CDATA[<!--kg-card-begin: markdown--><h2 id="vscode-loader-%E7%9A%84%E4%BD%BF%E7%94%A8%E7%A4%BA%E4%BE%8B">vscode-loader &#x7684;&#x4F7F;&#x7528;&#x793A;&#x4F8B;</h2>
<p><a href="https://github.com/microsoft/vscode-loader">vscode-loader</a> &#x652F;&#x6301;&#x5728;&#x6D4F;&#x89C8;&#x5668;&#x548C; node &#x4E2D;&#x4F7F;&#x7528;&#xFF0C;&#x5728;&#x4E24;&#x79CD;&#x73AF;&#x5883;&#x7684;&#x4F7F;&#x7528;&#x65B9;&#x5F0F;&#x57FA;&#x672C;&#x4E00;&#x81F4;&#x3002;&#x8FD9;&#x91CC;&#x5148;&#x7528;&#x6D4F;&#x89C8;&#x5668;&#x73AF;&#x5883;&#x8FDB;&#x884C;&#x5206;&#x6790;&#xFF1A;</p>
<p>html&#xFF1A;</p>]]></description><link>https://quickapp.vivo.com.cn/vscode-loader-source-code-analysis-browser-env/</link><guid isPermaLink="false">63c4b94a77e2ca0006a8c89b</guid><category><![CDATA[快应用开发工具]]></category><dc:creator><![CDATA[minxuan]]></dc:creator><pubDate>Thu, 04 Nov 2021 08:57:24 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><h2 id="vscode-loader-%E7%9A%84%E4%BD%BF%E7%94%A8%E7%A4%BA%E4%BE%8B">vscode-loader &#x7684;&#x4F7F;&#x7528;&#x793A;&#x4F8B;</h2>
<p><a href="https://github.com/microsoft/vscode-loader">vscode-loader</a> &#x652F;&#x6301;&#x5728;&#x6D4F;&#x89C8;&#x5668;&#x548C; node &#x4E2D;&#x4F7F;&#x7528;&#xFF0C;&#x5728;&#x4E24;&#x79CD;&#x73AF;&#x5883;&#x7684;&#x4F7F;&#x7528;&#x65B9;&#x5F0F;&#x57FA;&#x672C;&#x4E00;&#x81F4;&#x3002;&#x8FD9;&#x91CC;&#x5148;&#x7528;&#x6D4F;&#x89C8;&#x5668;&#x73AF;&#x5883;&#x8FDB;&#x884C;&#x5206;&#x6790;&#xFF1A;</p>
<p>html&#xFF1A;&#x52A0;&#x8F7D; loader.js&#xFF0C;&#x518D;&#x8C03;&#x7528; require &#x65B9;&#x6CD5;&#xFF0C;&#x52A0;&#x8F7D; test &#x4F9D;&#x8D56;&#x3002;</p>
<pre><code class="language-html">&lt;script type=&quot;text/javascript&quot; src=&quot;./src/loader.js&quot;&gt;&lt;/script&gt;
&lt;script&gt;
	require([&apos;test&apos;], function (test) {
		console.log(test.compare(7, 5));
	});
&lt;/script&gt;
</code></pre>
<p>&#x5B9A;&#x4E49;&#x6A21;&#x5757;&#xFF1A;</p>
<pre><code class="language-js">// test.js

define(&apos;test&apos;, function() {
    return {
        compare: function(a, b) {
            return a &gt; b;
        }
    }
});

</code></pre>
<p>define &#x65B9;&#x6CD5;&#xFF1A;<code>define(id?, dependencies?, factory);</code>&#xFF0C;&#x7B2C;&#x4E00;&#x4E2A;&#x53C2;&#x6570;&#x662F;&#x6A21;&#x5757;&#x540D;&#xFF0C;&#x7B2C;&#x4E8C;&#x4E2A;&#x53C2;&#x6570;&#x662F;&#x4F9D;&#x8D56;&#xFF0C;&#x7B2C;&#x4E09;&#x4E2A;&#x53C2;&#x6570;&#x662F;&#x6A21;&#x5757;&#x7684;&#x5DE5;&#x5382;&#x51FD;&#x6570;&#xFF0C;&#x8FD4;&#x56DE;&#x5B9A;&#x4E49;&#x7684;&#x6A21;&#x5757;&#x3002;</p>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&#x548C; requirejs &#x4E0D;&#x540C;&#x70B9;&#x5728;&#x4E8E;&#xFF0C;vscode-loader &#x4E0D;&#x901A;&#x8FC7; data-main &#x6307;&#x5B9A;&#x5165;&#x53E3;&#x6587;&#x4EF6;&#xFF0C;&#x800C;&#x662F;&#x76F4;&#x63A5;&#x52A0;&#x8F7D;&#x6A21;&#x5757;&#x3002;</p>
<h2 id="vscode-loader-%E7%9A%84%E4%BB%A3%E7%A0%81%E7%BB%93%E6%9E%84">vscode-loader &#x7684;&#x4EE3;&#x7801;&#x7ED3;&#x6784;</h2>
<p>&#x4E0D;&#x540C;&#x4E8E; requirejs&#xFF0C;vscode-loader &#x7684;&#x6E90;&#x7801;&#x662F;&#x7528; ts &#x7F16;&#x5199;&#x7684;&#xFF0C;&#x518D;&#x901A;&#x8FC7; <code>yarn compile</code> &#x6253;&#x5305;&#x6210; loader.js&#x3002;&#x6240;&#x4EE5;&#xFF0C;&#x6211;&#x4EEC;&#x5148;&#x770B; vscode-loader/src/core &#x7684;&#x4EE3;&#x7801;&#x7ED3;&#x6784;&#x3002;</p>
<pre><code>&lt;!-- todo --&gt;
&#x251C;&#x2500;&#x2500; core                    # &#x6838;&#x5FC3;&#x4EE3;&#x7801;
&#x2502;   &#x251C;&#x2500;&#x2500; main.ts             # &#x5165;&#x53E3;&#x6587;&#x4EF6;
&#x2502;   &#x251C;&#x2500;&#x2500; env.ts              # &#x73AF;&#x5883;&#xFF0C;&#x7528;&#x4E8E;&#x5224;&#x65AD;&#x5F53;&#x524D;&#x73AF;&#x5883;&#xFF1A;_isWindows&#xFF0C;_isNode&#x3001;_isElectronRenderer(&#x6D4F;&#x89C8;&#x5668;&#x73AF;&#x5883;&#xFF1F;)&#x3001;_isWebWorker
&#x2502;   &#x251C;&#x2500;&#x2500; configuration.ts    # &#x914D;&#x7F6E;&#xFF0C;&#x7C7B;&#x4F3C;&#x4E8E; requirejs &#x4E2D;&#x7684; context.configure&#xFF0C;&#x591A;&#x4E86;&#x6A21;&#x5757; id &#x8F6C;&#x4E3A; path &#x7B49;&#x65B9;&#x6CD5;&#x3002;
&#x2502;   &#x251C;&#x2500;&#x2500; moduleManager.ts    # &#x6A21;&#x5757;&#x7BA1;&#x7406;&#x5668;&#xFF0C;&#x7C7B;&#x4F3C;&#x4E8E; requirejs &#x4E2D;&#x7684; context.Module (&#x6A21;&#x5757;&#x52A0;&#x8F7D;&#x5668;)&#xFF0C;&#x8FD9;&#x90E8;&#x5206;&#x662F;&#x6838;&#x5FC3;&#x4EE3;&#x7801;&#xFF0C;&#x5B9E;&#x73B0;&#x4E86; define&#x3001;require &#x7B49;&#x65B9;&#x6CD5;&#x3002;
&#x2502;   &#x251C;&#x2500;&#x2500; scriptLoader.ts     # &#x811A;&#x672C;&#x52A0;&#x8F7D;&#x5668;&#xFF0C;&#x7C7B;&#x4F3C;&#x4E8E; requirejs &#x4E2D;&#x7684; context.load&#xFF0C;&#x5B9E;&#x73B0;&#x4E86;&#x4E0D;&#x540C;&#x73AF;&#x5883;&#x4E0B;&#x52A0;&#x8F7D;&#x811A;&#x672C;&#x7684;&#x65B9;&#x6CD5;&#x3002;
&#x2502;   &#x251C;&#x2500;&#x2500; loaderEvent.ts      # &#x4E8B;&#x4EF6;&#x8BB0;&#x5F55;&#xFF0C;&#x662F; vscode-loader &#x589E;&#x52A0;&#x7684;&#x529F;&#x80FD;&#xFF0C;&#x7528;&#x4E8E;&#x8BB0;&#x5F55; BeginLoadingScript&#x3001;EndLoadingScriptOK &#x7B49;&#x4E8B;&#x4EF6;&#x53CA;&#x5176;&#x65F6;&#x95F4;&#x6233;&#x3002;
&#x2502;   &#x2514;&#x2500;&#x2500; util.ts             # &#x516C;&#x5171;&#x65B9;&#x6CD5;&#xFF0C;&#x6BD4;&#x5982; uri &#x8F6C; path&#x3001;&#x751F;&#x6210;&#x5F02;&#x6B65;&#x6A21;&#x5757;&#x7684; id &#x7B49;&#x3002;
&#x2502;
&#x2514;&#x2500;&#x2500; loader.js               # &#x6253;&#x5305;&#x4EA7;&#x7269;
</code></pre>
<h2 id="maints">main.ts</h2>
<p>&#x6211;&#x4EEC;&#x5148;&#x770B; vscode-loader &#x7684;&#x5165;&#x53E3;&#x6587;&#x4EF6;&#xFF0C;mian.ts</p>
<pre><code class="language-ts">// &#x9650;&#x5236;&#xFF1A;&#x4E3A;&#x4E86;&#x52A0;&#x8F7D; jquery&#xFF0C;&#x59CB;&#x7EC8; require &apos;jquery&apos; &#x5E76;&#x5728;&#x52A0;&#x8F7D;&#x5668;&#x914D;&#x7F6E;&#x4E2D;&#x6DFB;&#x52A0; &apos;jquery&apos; &#x7684;&#x8DEF;&#x5F84;

declare var doNotInitLoader;
var define;

namespace AMDLoader {

	// 1&#xFF1A;&#x65B0;&#x5EFA;&#x73AF;&#x5883;&#x5BF9;&#x8C61;
	const env = new Environment();

    // 2&#xFF1A;&#x58F0;&#x660E;&#x6A21;&#x5757;&#x7BA1;&#x7406;&#x5668;
	let moduleManager: ModuleManager = null!;

    // 3&#xFF1A;define &#x65B9;&#x6CD5;&#xFF0C;&#x6700;&#x7EC8;&#x8C03;&#x7528; moduleManager.defineModule &#x6216; moduleManager.enqueueDefineAnonymousModule
	const DefineFunc: IDefineFunc = &lt;any&gt;function (id: any, dependencies: any, callback: any): void {
		...
	};
	DefineFunc.amd = {
		jQuery: true
	};

	// 4&#xFF1A;config &#x65B9;&#x6CD5;&#xFF0C;&#x8C03;&#x7528; moduleManager.configure
	const _requireFunc_config = function (params: IConfigurationOptions, shouldOverwrite: boolean = false): void {
		moduleManager.configure(params, shouldOverwrite);
	};

	// 5&#xFF1A;require &#x65B9;&#x6CD5;&#xFF0C;&#x8C03;&#x7528; moduleManager.configure &#x6216; moduleManager.synchronousRequire &#x6216; moduleManager.defineModule
	const RequireFunc: IRequireFunc = &lt;any&gt;function () {
		...
	};
    // require &#x589E;&#x52A0;&#x65B9;&#x6CD5;&#xFF0C;config&#x3001;getConfig&#x3001;reset&#x3001;getBuildInfo&#x3001;getStats&#x3001;define&#xFF0C;&#x6700;&#x7EC8;&#x90FD;&#x662F;&#x8C03;&#x7528; moduleManager &#x7684;&#x65B9;&#x6CD5;
	RequireFunc.config = _requireFunc_config;
	RequireFunc.getConfig = function (): IConfigurationOptions {
		return moduleManager.getConfig().getOptionsLiteral();
	};
	RequireFunc.reset = function (): void {
		moduleManager = moduleManager.reset();
	};
	RequireFunc.getBuildInfo = function (): IBuildModuleInfo[] | null {
		return moduleManager.getBuildInfo();
	};
	RequireFunc.getStats = function (): LoaderEvent[] {
		return moduleManager.getLoaderEvents();
	};
	RequireFunc.define = function () {
		return DefineFunc.apply(null, arguments);
	}

	// 6&#xFF1A;(&#x91CD;&#x70B9;)&#x521D;&#x59CB;&#x5316;&#xFF0C;&#x5982;&#x679C;&#x8FD8;&#x672A;&#x521D;&#x59CB;&#x5316;&#xFF0C;&#x65B0;&#x5EFA;&#x6A21;&#x5757;&#x7BA1;&#x7406;&#x5668;&#xFF0C;&#x5E76;&#x521D;&#x59CB;&#x5316;
	export function init(): void {
        // &#x5982;&#x679C;&#x6709; require &#x65B9;&#x6CD5;&#xFF08;&#x5373; node &#x73AF;&#x5883; / electron &#x73AF;&#x5883;&#xFF09;&#xFF0C;&#x4FDD;&#x5B58;&#x5230; nodeRequire &#x548C; __$__nodeRequire &#x4E2D;
        if (typeof global.require !== &apos;undefined&apos; || typeof require !== &apos;undefined&apos;) {
            const _nodeRequire = (global.require || require);
            if (typeof _nodeRequire === &apos;function&apos; &amp;&amp; typeof _nodeRequire.resolve === &apos;function&apos;) {
                // &#x91CD;&#x65B0;&#x66B4;&#x9732; node &#x7684; require &#x51FD;&#x6570;
                const nodeRequire = ensureRecordedNodeRequire(moduleManager.getRecorder(), _nodeRequire);
                global.nodeRequire = nodeRequire;
                (&lt;any&gt;RequireFunc).nodeRequire = nodeRequire;
                (&lt;any&gt;RequireFunc).__$__nodeRequire = nodeRequire;
            }
        }

        // &#x6839;&#x636E;&#x73AF;&#x5883;&#xFF0C;&#x8BBE;&#x7F6E; module.exports&#x3001;require&#x3001;define &#x7B49;&#x65B9;&#x6CD5;
        if (env.isNode &amp;&amp; !env.isElectronRenderer) {
            module.exports = RequireFunc;
            require = &lt;any&gt;RequireFunc;
        } else {
            if (!env.isElectronRenderer) {
                global.define = DefineFunc;
            }
            global.require = RequireFunc;
        }
    }

	if (typeof global.define !== &apos;function&apos; || !global.define.amd) {
		// &#x7B2C;&#x4E00;&#x6B65;&#xFF1A;&#x65B0;&#x5EFA;&#x6A21;&#x5757;&#x7BA1;&#x7406;&#x5668;
		moduleManager = new ModuleManager(env, createScriptLoader(env), DefineFunc, RequireFunc, Utilities.getHighPerformanceTimestamp());

		// &#x7B2C;&#x4E8C;&#x6B65;&#xFF1A;&#x5982;&#x679C;&#x6709; global.require&#xFF0C;&#x4E14;&#x975E;&#x51FD;&#x6570;&#xFF0C;&#x5219;&#x66F4;&#x65B0; config
		if (typeof global.require !== &apos;undefined&apos; &amp;&amp; typeof global.require !== &apos;function&apos;) {
			RequireFunc.config(global.require);
		}

		// &#x7B2C;&#x4E09;&#x6B65;&#xFF1A;&#x5B9A;&#x4E49; define &#x65B9;&#x6CD5;
		define = function () {
			return DefineFunc.apply(null, arguments);
		};
		define.amd = DefineFunc.amd;

		// &#x7B2C;&#x56DB;&#x6B65;&#xFF1A;&#x5982;&#x679C;&#x8FD8;&#x672A;&#x521D;&#x59CB;&#x5316;&#xFF0C;&#x8C03;&#x7528; init
		if (typeof doNotInitLoader === &apos;undefined&apos;) {
			init();
		}
	}

}
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;main.ts &#x4E2D;&#xFF0C;&#x4E3B;&#x8981;&#x662F;&#x5B9A;&#x4E49;&#x4E86; define&#x3001;config&#x3001;require &#x7B49;&#x65B9;&#x6CD5;&#xFF0C;&#x7136;&#x540E;&#x65B0;&#x5EFA; moduleManager&#xFF0C;&#x518D;&#x8C03;&#x7528; init &#x65B9;&#x6CD5;&#x8FDB;&#x884C;&#x521D;&#x59CB;&#x5316;&#x3002;</p>
<p>init &#x65B9;&#x6CD5;&#xFF0C;&#x4E3B;&#x8981;&#x662F;&#x6839;&#x636E;&#x4E0D;&#x540C;&#x7684;&#x73AF;&#x5883;&#x8BBE;&#x7F6E;&#x65B9;&#x6CD5;&#x3002;&#x6BD4;&#x5982; node &#x73AF;&#x5883;&#xFF0C;&#x4FDD;&#x5B58; node &#x539F;&#x672C;&#x7684; require &#x65B9;&#x6CD5;&#x5230; nodeRequire&#xFF0C;&#x518D;&#x8BBE;&#x7F6E; require = RequireFunc&#x3002;&#x6D4F;&#x89C8;&#x5668;&#x73AF;&#x5883;&#xFF0C;&#x8BBE;&#x7F6E; global.require = RequireFunc&#xFF0C;&#x5373; window.require = RequireFunc&#x3002;</p>
<h2 id="require-%E5%8A%A0%E8%BD%BD%E6%A8%A1%E5%9D%97">require &#x52A0;&#x8F7D;&#x6A21;&#x5757;</h2>
<p>&#x6D4F;&#x89C8;&#x5668;&#x73AF;&#x5883;&#xFF0C;&#x901A;&#x8FC7; require &#x65B9;&#x6CD5;&#xFF0C;&#x52A0;&#x8F7D;&#x6A21;&#x5757;&#x3002;</p>
<pre><code class="language-js">&lt;script&gt;
	require([&apos;test&apos;], function (test) {
		console.log(test.compare(7, 5));
	});
&lt;/script&gt;
</code></pre>
<p>&#x524D;&#x9762;&#x5DF2;&#x7ECF;&#x63D0;&#x5230; require &#x5BF9;&#x5E94; RequireFunc&#xFF0C;&#x6211;&#x4EEC;&#x7EE7;&#x7EED;&#x67E5;&#x770B;&#x4EE3;&#x7801;&#x903B;&#x8F91;&#xFF1A;</p>
<pre><code class="language-ts">// main.ts
const RequireFunc: IRequireFunc = &lt;any&gt;function () {
	// &#x53EA;&#x4F20;&#x4E00;&#x4E2A;&#x53C2;&#x6570;&#xFF1A;&#x5982;&#x679C;&#x662F;&#x5BF9;&#x8C61;&#xFF0C;&#x8C03;&#x7528; moduleManager.configure &#x8FDB;&#x884C;&#x914D;&#x7F6E;&#xFF1B;&#x5982;&#x679C;&#x662F;&#x5B57;&#x7B26;&#x4E32;&#xFF0C;&#x8C03;&#x7528; moduleManager.synchronousRequire &#x540C;&#x6B65;&#x52A0;&#x8F7D;&#x6A21;&#x5757;
	if (arguments.length === 1) {
		if ((arguments[0] instanceof Object) &amp;&amp; !Array.isArray(arguments[0])) {
			_requireFunc_config(arguments[0]);
			return;
		}
		if (typeof arguments[0] === &apos;string&apos;) {
			return moduleManager.synchronousRequire(arguments[0]);
		}
	}
	// &#x4F20; 2-3 &#x4E2A;&#x53C2;&#x6570;&#xFF1A;&#x8C03;&#x7528; moduleManager.defineModule &#x751F;&#x6210;&#x5F02;&#x6B65;&#x6A21;&#x5757;
	// &#x8FD9;&#x91CC;&#x4F20;&#x5165; 2 &#x4E2A;&#x53C2;&#x6570;&#xFF0C;[&apos;test&apos;], f(test)
	if (arguments.length === 2 || arguments.length === 3) {
		if (Array.isArray(arguments[0])) {
			moduleManager.defineModule(Utilities.generateAnonymousModule(), arguments[0], arguments[1], arguments[2], null);
			return;
		}
	}
	throw new Error(&apos;Unrecognized require call&apos;);
};

// utils.ts
export class Utilities {
	private static NEXT_ANONYMOUS_ID = 1;

	// &#x751F;&#x6210;&#x5F02;&#x6B65;&#x6A21;&#x5757;&#x7684;&#x5B57;&#x7B26;&#x4E32;id
	// &#x8FD4;&#x56DE; &apos;===anonymous1===&apos;
	public static generateAnonymousModule(): string {
		return &apos;===anonymous&apos; + (Utilities.NEXT_ANONYMOUS_ID++) + &apos;===&apos;;
	}
}

// moduleManager.ts
export class ModuleManager {
	/**
	 * &#x521B;&#x5EFA;&#x6A21;&#x5757;&#x5E76;&#x5C06;&#x5176;&#x5B58;&#x50A8;&#x5728; _modules &#x4E2D;&#x3002;&#x7BA1;&#x7406;&#x5668;&#x5C06;&#x7ACB;&#x5373;&#x5F00;&#x59CB;&#x89E3;&#x6790;&#x5176;&#x4F9D;&#x8D56;&#x5173;&#x7CFB;&#x3002;
	 * @param strModuleId &#x6A21;&#x5757;&#x7684;&#x552F;&#x4E00;&#x4E14;&#x7EDD;&#x5BF9;&#x7684; id&#x3002;&#x8FD9;&#x4E0D;&#x80FD;&#x4E0E;&#x53E6;&#x4E00;&#x4E2A;&#x6A21;&#x5757;&#x7684; id &#x51B2;&#x7A81;
	 * @param dependencies &#x5177;&#x6709;&#x6A21;&#x5757;&#x4F9D;&#x8D56;&#x9879;&#x7684;&#x6570;&#x7EC4;&#x3002;&#x7279;&#x6B8A;&#x952E;&#x662F;&#xFF1A;&#x201C;require&#x201D;&#x3001;&#x201C;exports&#x201D;&#x548C;&#x201C;module&#x201D;
	 * @param callback &#x5982;&#x679C; callback &#x662F;&#x4E00;&#x4E2A;&#x51FD;&#x6570;&#xFF0C;&#x5B83;&#x5C06;&#x4F7F;&#x7528;&#x89E3;&#x6790;&#x7684;&#x4F9D;&#x8D56;&#x9879;&#x8C03;&#x7528;&#x3002;&#x5982;&#x679C; callback &#x662F;&#x4E00;&#x4E2A;&#x5BF9;&#x8C61;&#xFF0C;&#x5B83;&#x5C06;&#x88AB;&#x89C6;&#x4E3A;&#x6A21;&#x5757;&#x7684;&#x5BFC;&#x51FA;&#x3002;
	 */
	// &#x53C2;&#x6570;&#xFF1A;&apos;===anonymous1===&apos;, [&apos;test&apos;], f(test)
	public defineModule(strModuleId: string, dependencies: string[], callback: any, errorback: ((err: AnnotatedError) =&gt; void) | null | undefined, stack: string | null, moduleIdResolver: ModuleIdResolver = new ModuleIdResolver(strModuleId)): void {
		// define-1&#xFF1A;strModuleId -&gt; moduleId
		let moduleId = this._moduleIdProvider.getModuleId(strModuleId);
		// &#x5982;&#x679C;&#x5DF2;&#x52A0;&#x8F7D;&#xFF0C;&#x63D0;&#x793A;&#x91CD;&#x590D;&#x5B9A;&#x4E49;&#x6A21;&#x5757;
		if (this._modules2[moduleId]) {
			if (!this._config.isDuplicateMessageIgnoredFor(strModuleId)) {
				console.warn(&apos;Duplicate definition of module \&apos;&apos; + strModuleId + &apos;\&apos;&apos;);
			}
			return;
		}

		// define-2&#xFF1A;&#x65B0;&#x5EFA;&#x6A21;&#x5757;&#x5E76;&#x4FDD;&#x5B58;&#x5230; this._modules2
		let m = new Module(moduleId, strModuleId, this._normalizeDependencies(dependencies, moduleIdResolver), callback, errorback, moduleIdResolver);
		this._modules2[moduleId] = m;

		// &#x5982;&#x679C;&#x5DF2;&#x7ECF;&#x6784;&#x5EFA;&#xFF0C;&#x6536;&#x96C6;&#x6784;&#x5EFA;&#x4FE1;&#x606F;
		if (this._config.isBuild()) {
			this._buildInfoDefineStack[moduleId] = stack;
			this._buildInfoDependencies[moduleId] = (m.dependencies || []).map(dep =&gt; this._moduleIdProvider.getStrModuleId(dep.id));
		}

		// define-3&#xFF1A;&#x7ACB;&#x5373;&#x89E3;&#x6790;&#x4F9D;&#x8D56;&#x9879;&#xFF08;&#x4E0D;&#x662F; timeout &#x4E2D;&#x6267;&#x884C;&#xFF09;&#x3002;&#x5982;&#x679C;&#x9700;&#x8981;&#x652F;&#x6301;&#x65E0;&#x5E8F;&#x7684;&#x6A21;&#x5757;&#xFF0C;&#x4E3A;&#x4E86;&#x5B8C;&#x6210;&#x6587;&#x4EF6;&#x7684;&#x5904;&#x7406;&#xFF0C;&#x5219;&#x5728; timeout &#x4E2D;&#x6267;&#x884C;&#x3002;
		this._resolve(m);
	}
}
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&#x8FD9;&#x91CC;&#x662F;&#x8C03;&#x7528;&#x4E86; <code>moduleManager.defineModule</code> &#x751F;&#x6210;&#x5F02;&#x6B65;&#x6A21;&#x5757;&#x3002;<code>defineModule</code> &#x6BCF;&#x4E00;&#x6B65;&#x7684;&#x5177;&#x4F53;&#x903B;&#x8F91;&#x5982;&#x4E0B;&#x3002;</p>
<p>&#x7B2C;&#x4E00;&#x6B65;(define-1)&#xFF0C;strModuleId &#x8F6C;&#x4E3A; moduleId&#xFF1A;</p>
<pre><code class="language-ts">...
// define-1&#xFF1A;strModuleId -&gt; moduleId&#xFF08;&#x9012;&#x589E;&#x7684;&#x6570;&#x5B57;&#xFF09;&#xFF0C;&#x8FD4;&#x56DE; 3
let moduleId = this._moduleIdProvider.getModuleId(strModuleId);
...

class ModuleIdProvider {
	private _nextId: number;
	private _strModuleIdToIntModuleId: Map&lt;string, ModuleId&gt;;
	private _intModuleIdToStrModuleId: string[];

	constructor() {
		this._nextId = 0;
		this._strModuleIdToIntModuleId = new Map&lt;string, ModuleId&gt;();
		this._intModuleIdToStrModuleId = [];

		// &apos;exports&apos;, &apos;modules&apos;, &apos;require&apos; &#x5BF9;&#x5E94; 0&#xFF0C;1&#xFF0C;2&#xFF0C;&#x5176;&#x4ED6;&#x6A21;&#x5757;&#x4ECE; 3 &#x5F00;&#x59CB;&#x3002;
		this.getModuleId(&apos;exports&apos;);
		this.getModuleId(&apos;module&apos;);
		this.getModuleId(&apos;require&apos;);
	}

	public getMaxModuleId(): number {
		return this._nextId;
	}

	// &#x83B7;&#x53D6;&#x6A21;&#x5757; id&#xFF08;&#x9012;&#x589E;&#x7684;&#x6570;&#x5B57;&#xFF09;&#xFF0C;&#x5E76;&#x4FDD;&#x5B58; strModuleId &#x548C; id &#x7684;&#x5173;&#x7CFB;&#x3002;
	public getModuleId(strModuleId: string): ModuleId {
		let id = this._strModuleIdToIntModuleId.get(strModuleId);
		if (typeof id === &apos;undefined&apos;) {
			id = this._nextId++;
			this._strModuleIdToIntModuleId.set(strModuleId, id);
			this._intModuleIdToStrModuleId[id] = strModuleId;
		}
		return id;
	}

	public getStrModuleId(moduleId: ModuleId): string {
		return this._intModuleIdToStrModuleId[moduleId];
	}
}
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x51FA;&#xFF0C;getModuleId &#x662F;&#x751F;&#x6210;&#x9012;&#x589E;&#x7684;&#x6570;&#x5B57;&#xFF0C; 0-2 &#x662F;&#x9ED8;&#x8BA4;&#x7684;&#x6A21;&#x5757;&#xFF0C;&#x7528;&#x6237;&#x5B9A;&#x4E49;&#x7684;&#x6A21;&#x5757;&#x4ECE; 3 &#x5F00;&#x59CB;&#x8BA1;&#x7B97;&#x3002;</p>
<p>&#x7B2C;&#x4E8C;&#x6B65;(define-2)&#xFF0C;&#x89C4;&#x5212;&#x5316;&#x4F9D;&#x8D56;&#xFF0C;&#x5E76;&#x65B0;&#x5EFA;&#x6A21;&#x5757;&#xFF1A;</p>
<pre><code class="language-ts">
...
// define-2&#xFF1A;&#x65B0;&#x5EFA;&#x6A21;&#x5757;
let m = new Module(moduleId, strModuleId, this._normalizeDependencies(dependencies, moduleIdResolver), callback, errorback, moduleIdResolver);
...

// define-2.1&#xFF1A;&#x89C4;&#x8303;&#x5316;&#x4F9D;&#x8D56;
// &#x53C2;&#x6570;&#xFF1A;[&apos;test&apos;], moduleIdResolver
// &#x8FD4;&#x56DE;&#xFF1A;&#x4F9D;&#x8D56; [{id: 4}]
export class ModuleManager {
	private _normalizeDependencies(dependencies: string[], moduleIdResolver: ModuleIdResolver): Dependency[] {
		let result: Dependency[] = [], resultLen = 0;
		for (let i = 0, len = dependencies.length; i &lt; len; i++) {
			result[resultLen++] = this._normalizeDependency(dependencies[i], moduleIdResolver);
		}
		return result;
	}

	// &#x751F;&#x6210; dependency &#x5BF9;&#x8C61;&#xFF0C;{id: number}
	private _normalizeDependency(dependency: string, moduleIdResolver: ModuleIdResolver): Dependency {
		// &#x9ED8;&#x8BA4;&#x4F9D;&#x8D56;
		if (dependency === &apos;exports&apos;) {
			return RegularDependency.EXPORTS;
		}
		if (dependency === &apos;module&apos;) {
			return RegularDependency.MODULE;
		}
		if (dependency === &apos;require&apos;) {
			return RegularDependency.REQUIRE;
		}
		let bangIndex = dependency.indexOf(&apos;!&apos;);

		// &#x63D2;&#x4EF6;&#x4F9D;&#x8D56;
		if (bangIndex &gt;= 0) {
			...
			return new PluginDependency(dependencyId, pluginId, pluginParam);
		}

		// &#x5E38;&#x89C4;&#x4F9D;&#x8D56;
		// getModuleId&#xFF08;&#x524D;&#x9762;&#x5DF2;&#x77E5;&#xFF0C;&#x6A21;&#x5757; id &#x662F;&#x9012;&#x589E;&#x7684;&#x6570;&#x5B57;&#xFF09;&#xFF0C;&#x8FD4;&#x56DE; 4
		return new RegularDependency(this._moduleIdProvider.getModuleId(moduleIdResolver.resolveModule(dependency)));
	}
}

// &#x5E38;&#x89C4;&#x4F9D;&#x8D56;&#xFF0C;&#x5305;&#x542B; exports&#xFF0C;module, require
export class RegularDependency {
	public static EXPORTS = new RegularDependency(ModuleId.EXPORTS);
	public static MODULE = new RegularDependency(ModuleId.MODULE);
	public static REQUIRE = new RegularDependency(ModuleId.REQUIRE);

	public readonly id: ModuleId;

	constructor(id: ModuleId) {
		this.id = id;
	}
}

// define-2.2&#xFF1A;&#x65B0;&#x5EFA;&#x6A21;&#x5757;
// &#x53C2;&#x6570;&#xFF1A;id: 3&#xFF0C;strId: &apos;===anonymous1===&apos;, dependencies: [{id: 4}], callback: f(test)&#xFF0C;errorback: undefined&#xFF0C;moduleIdResolver
export class Module {
	...

	constructor(
		id: ModuleId,
		strId: string,
		dependencies: Dependency[],
		callback: any,
		errorback: ((err: AnnotatedError) =&gt; void) | null | undefined,
		moduleIdResolver: ModuleIdResolver | null,
	) {
		this.id = id;
		this.strId = strId;
		this.dependencies = dependencies;
		this._callback = callback;
		this._errorback = errorback;
		this.moduleIdResolver = moduleIdResolver;
		this.exports = {};
		this.error = null;
		this.exportsPassedIn = false;
		this.unresolvedDependenciesCount = this.dependencies.length;
		this._isComplete = false;
	}
}
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230; <code>require([&apos;test&apos;], function(test){...})</code>&#xFF0C;&#x5BF9;&#x5E94;&#x7684;&#x6A21;&#x5757; id &#x4E3A; 3&#x3002;&#x4F9D;&#x8D56;&#x9879;&#x662F; &apos;test&apos;&#xFF0C;&apos;test&apos; &#x5BF9;&#x5E94;&#x7684;&#x6A21;&#x5757; id &#x4E3A; 4&#x3002;</p>
<p>&#x7B2C;&#x4E09;&#x6B65;(define-3)&#xFF0C;&#x89E3;&#x6790;&#x4F9D;&#x8D56;&#x9879;&#xFF1A;</p>
<pre><code class="language-ts">...
// define-3&#xFF1A;&#x7ACB;&#x5373;&#x89E3;&#x6790;&#x4F9D;&#x8D56;&#x9879;&#xFF0C;&#x53C2;&#x6570; m &#x662F;&#x4E0A;&#x4E00;&#x6B65;&#x65B0;&#x5EFA;&#x7684;&#x6A21;&#x5757; 3
this._resolve(m);
...

export class ModuleManager{
	private _resolve(module: Module): void {
		// &#x904D;&#x5386;&#x4F9D;&#x8D56;&#x6570;&#x7EC4;&#xFF0C;&#x6839;&#x636E;&#x4E0D;&#x540C;&#x7C7B;&#x578B;&#x8FDB;&#x884C;&#x5904;&#x7406;
		// &apos;test&apos; &#x6A21;&#x5757;&#x662F;&#x666E;&#x901A;&#x4F9D;&#x8D56;&#xFF0C;&#x5728;&#x8FD9;&#x91CC;&#x6267;&#x884C;&#x7684;&#x662F; resolve-6 &#x548C; resolve-8 &#x7684;&#x903B;&#x8F91;
		let dependencies = module.dependencies;
		if (dependencies) {
			for (let i = 0, len = dependencies.length; i &lt; len; i++) {
				let dependency = dependencies[i];

				// resolve-1&#xFF1A;exports
				if (dependency === RegularDependency.EXPORTS) {
					module.exportsPassedIn = true;
					module.unresolvedDependenciesCount--;
					continue;
				}

				// resolve-2&#xFF1A;module
				if (dependency === RegularDependency.MODULE) {
					module.unresolvedDependenciesCount--;
					continue;
				}

				// resolve-3&#xFF1A;require
				if (dependency === RegularDependency.REQUIRE) {
					module.unresolvedDependenciesCount--;
					continue;
				}

				// resolve-4&#xFF1A;&#x5982;&#x679C;&#x5DF2;&#x7ECF;&#x52A0;&#x8F7D;&#xFF0C;&#x8DF3;&#x8FC7;
				let dependencyModule = this._modules2[dependency.id];
				if (dependencyModule &amp;&amp; dependencyModule.isComplete()) {
					if (dependencyModule.error) {
						module.onDependencyError(dependencyModule.error);
						return;
					}
					module.unresolvedDependenciesCount--;
					continue;
				}

				// resolve-5&#xFF1A;&#x5982;&#x679C;&#x6709;&#x5FAA;&#x73AF;&#x5F15;&#x7528;&#xFF0C;&#x8DF3;&#x8FC7;
				if (this._hasDependencyPath(dependency.id, module.id)) {
					this._hasDependencyCycle = true;
					console.warn(&apos;There is a dependency cycle between \&apos;&apos; + this._moduleIdProvider.getStrModuleId(dependency.id) + &apos;\&apos; and \&apos;&apos; + this._moduleIdProvider.getStrModuleId(module.id) + &apos;\&apos;. The cyclic path follows:&apos;);
					let cyclePath = this._findCyclePath(dependency.id, module.id, 0) || [];
					cyclePath.reverse();
					cyclePath.push(dependency.id);
					console.warn(cyclePath.map(id =&gt; this._moduleIdProvider.getStrModuleId(id)).join(&apos; =&gt; \n&apos;));

					module.unresolvedDependenciesCount--;
					continue;
				}

				// resolve-6&#xFF1A;&#x8BB0;&#x5F55;&#x53CD;&#x5411;&#x4F9D;&#x8D56;&#x5173;&#x7CFB;
				// &#x6BD4;&#x5982;&#x6A21;&#x5757; 3 &#x4F9D;&#x8D56;&#x6A21;&#x5757; 4&#xFF0C;&#x5373; this._inverseDependencies2[4] = [3]
				this._inverseDependencies2[dependency.id] = this._inverseDependencies2[dependency.id] || [];
				this._inverseDependencies2[dependency.id]!.push(module.id);

				// resolve-7&#xFF1A;&#x63D2;&#x4EF6;&#x4F9D;&#x8D56;
				if (dependency instanceof PluginDependency) {
					...

					this._loadModule(dependency.pluginId);
					continue;
				}

				// resolve-8&#xFF1A;&#x666E;&#x901A;&#x4F9D;&#x8D56;
				// &#x53C2;&#x6570;: 4
				this._loadModule(dependency.id);
			}
		}

		// &#x5982;&#x679C;&#x4F9D;&#x8D56;&#x90FD;&#x5DF2;&#x7ECF;&#x89E3;&#x6790;&#xFF0C;&#x8C03;&#x7528; _onModuleComplete
		// &#x8FD9;&#x91CC; module.unresolvedDependenciesCount: 1&#xFF0C;&#x4E0D;&#x8C03;&#x7528; _onModuleComplete
		if (module.unresolvedDependenciesCount === 0) {
			this._onModuleComplete(module);
		}
	}
	
	// &#x52A0;&#x8F7D;&#x6A21;&#x5757;&#xFF0C;&#x91CD;&#x70B9;&#xFF1A;this._scriptLoader.load&#x3001;this._onLoad
	private _loadModule(moduleId: ModuleId): void {
		if (this._modules2[moduleId] || this._knownModules2[moduleId]) {
			return;
		}
		this._knownModules2[moduleId] = true;

		// loadModule-1&#xFF1A;&#x83B7;&#x53D6;&#x6A21;&#x5757;&#x8DEF;&#x5F84;&#xFF0C;moduleId -&gt; strModuleId -&gt; paths
		// 4 -&gt; &apos;test&apos; -&gt; [&apos;test.js&apos;]
		let strModuleId = this._moduleIdProvider.getStrModuleId(moduleId);
		let paths = this._config.moduleIdToPaths(strModuleId);
		let scopedPackageRegex = /^@[^\/]+\/[^\/]+$/ // matches @scope/package-name
		if (this._env.isNode &amp;&amp; (strModuleId.indexOf(&apos;/&apos;) === -1 || scopedPackageRegex.test(strModuleId))) {
			paths.push(&apos;node|&apos; + strModuleId);
		}

		let lastPathIndex = -1;
		let loadNextPath = (err: any) =&gt; {
			lastPathIndex++;

			if (lastPathIndex &gt;= paths.length) { // lastPathIndex: 0, paths.length: 1, &#x8D70; else &#x7684;&#x903B;&#x8F91;
				this._onLoadError(moduleId, err);
			} else {
				let currentPath = paths[lastPathIndex]; // &quot;test.js&quot;
				let recorder = this.getRecorder();		// &#x4E8B;&#x4EF6;&#x8BB0;&#x5F55;&#x5668;&#xFF0C;&#x7528;&#x4E8E;&#x8BB0;&#x5F55; BeginLoadingScript&#x3001;EndLoadingScriptOK &#x7B49;&#x4E8B;&#x4EF6;&#x53CA;&#x5176;&#x65F6;&#x95F4;&#x6233;&#x3002;

				if (this._config.isBuild() &amp;&amp; currentPath === &apos;empty:&apos;) { // &#x5982;&#x679C;&#x6EE1;&#x8DB3;&#x6761;&#x4EF6;&#xFF0C;&#x76F4;&#x63A5;&#x8C03;&#x7528; this._onLoad&#xFF0C;&#x8FD9;&#x91CC;&#x4E0D;&#x6EE1;&#x8DB3;&#x6761;&#x4EF6;&#xFF0C;&#x8DF3;&#x8FC7;
					this._buildInfoPath[moduleId] = currentPath;
					this.defineModule(this._moduleIdProvider.getStrModuleId(moduleId), [], null, null, null);
					this._onLoad(moduleId);
					return;
				}

				recorder.record(LoaderEventType.BeginLoadingScript, currentPath); // &#x8BB0;&#x5F55;&#x4E8B;&#x4EF6; BeginLoadingScript
				// loadModule-2.1&#xFF1A;&#x8C03;&#x7528; this._scriptLoader.load &#x52A0;&#x8F7D;&#x6A21;&#x5757;
				this._scriptLoader.load(this, currentPath, () =&gt; {
					if (this._config.isBuild()) {
						this._buildInfoPath[moduleId] = currentPath;
					}
					recorder.record(LoaderEventType.EndLoadingScriptOK, currentPath); // &#x8BB0;&#x5F55;&#x4E8B;&#x4EF6; EndLoadingScriptOK
					// loadModule-2.2&#xFF1A;&#x5728;&#x811A;&#x672C;&#x52A0;&#x8F7D;&#x56DE;&#x8C03;&#x4E2D;&#xFF0C;&#x8C03;&#x7528; this._onLoad
					// moduleId: 4&#xFF0C;&#x5BF9;&#x5E94; test &#x6A21;&#x5757;
					this._onLoad(moduleId);
				}, (err) =&gt; {
					recorder.record(LoaderEventType.EndLoadingScriptError, currentPath);
					loadNextPath(err);
				});
			}
		};

		// loadModule-2: &#x8C03;&#x7528; loadNextPath
		loadNextPath(null);
	}
}

</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&#x5728;&#x7B2C;&#x4E09;&#x6B65;(define-3)&#x89E3;&#x6790;&#x4F9D;&#x8D56;&#xFF0C;&#x6700;&#x7EC8;&#x901A;&#x8FC7; <code>this._scriptLoader.load</code> &#x52A0;&#x8F7D; test &#x6A21;&#x5757;&#x3002;&#x6211;&#x4EEC;&#x7EE7;&#x7EED;&#x770B;&#x8FD9;&#x90E8;&#x5206;&#x4EE3;&#x7801;&#xFF1A;</p>
<pre><code class="language-ts">// main.ts
// &#x5728;&#x5165;&#x53E3;&#x6587;&#x4EF6;&#xFF0C;&#x65B0;&#x5EFA;&#x6A21;&#x5757;&#x7BA1;&#x7406;&#x5668;&#x65F6;&#xFF0C;&#x65B0;&#x5EFA;&#x4E86;&#x811A;&#x672C;&#x52A0;&#x8F7D;&#x5668;
moduleManager = new ModuleManager(env, createScriptLoader(env), DefineFunc, RequireFunc, Utilities.getHighPerformanceTimestamp());

// scriptLoader.ts
export function createScriptLoader(env: Environment): IScriptLoader {
	return new OnlyOnceScriptLoader(env);
}

class OnlyOnceScriptLoader implements IScriptLoader {

	...

	constructor(env: Environment) {
		this._env = env;
		this._scriptLoader = null;
		this._callbackMap = {};
	}

	public load(moduleManager: IModuleManager, scriptSrc: string, callback: () =&gt; void, errorback: (err: any) =&gt; void): void {
		// load-1: &#x6839;&#x636E;&#x73AF;&#x5883;&#xFF0C;&#x65B0;&#x5EFA;&#x811A;&#x672C;&#x52A0;&#x8F7D;&#x5668;
		if (!this._scriptLoader) {
			if (this._env.isWebWorker) {
				this._scriptLoader = new WorkerScriptLoader();
			} else if (this._env.isElectronRenderer) {
				const { preferScriptTags } = moduleManager.getConfig().getOptionsLiteral();
				if (preferScriptTags) {
					this._scriptLoader = new BrowserScriptLoader();
				} else {
					this._scriptLoader = new NodeScriptLoader(this._env);
				}
			} else if (this._env.isNode) {
				this._scriptLoader = new NodeScriptLoader(this._env);
			} else {
				// &#x4EE5;&#x6D4F;&#x89C8;&#x5668;&#x73AF;&#x5883;&#x4E3A;&#x4F8B;&#xFF0C;&#x65B0;&#x5EFA;&#x6D4F;&#x89C8;&#x5668;&#x7684;&#x811A;&#x672C;&#x52A0;&#x8F7D;&#x5668;
				this._scriptLoader = new BrowserScriptLoader();
			}
		}
		let scriptCallbacks: IScriptCallbacks = {
			callback: callback,
			errorback: errorback
		};
		// load-2: &#x5C06;&#x811A;&#x672C;&#x7684;&#x56DE;&#x8C03;&#x51FD;&#x6570;&#xFF0C;&#x4FDD;&#x5B58;&#x5230; _callbackMap &#x4E2D;
		if (this._callbackMap.hasOwnProperty(scriptSrc)) {
			this._callbackMap[scriptSrc].push(scriptCallbacks);
			return;
		}
		this._callbackMap[scriptSrc] = [scriptCallbacks];
		// load-3: &#x52A0;&#x8F7D;&#x811A;&#x672C;&#xFF0C;&#x53C2;&#x6570; callback: () =&gt; this.triggerCallback(scriptSrc)
		this._scriptLoader.load(moduleManager, scriptSrc, () =&gt; this.triggerCallback(scriptSrc), (err: any) =&gt; this.triggerErrorback(scriptSrc, err));
	}
}

// &#x6D4F;&#x89C8;&#x5668;&#x73AF;&#x5883;&#x7684;&#x811A;&#x672C;&#x52A0;&#x8F7D;&#x5668;
class BrowserScriptLoader implements IScriptLoader {

	public load(moduleManager: IModuleManager, scriptSrc: string, callback: () =&gt; void, errorback: (err: any) =&gt; void): void {
		if (/^node\|/.test(scriptSrc)) {
			// &apos;node|&apos; &#x5F00;&#x5934;&#x7684;&#xFF0C;&#x662F; node &#x6A21;&#x5757;&#xFF0C;&#x7528; nodeRequire &#x52A0;&#x8F7D;&#xFF0C;&#x76F4;&#x63A5;&#x8C03;&#x7528; callback
			let opts = moduleManager.getConfig().getOptionsLiteral();
			let nodeRequire = ensureRecordedNodeRequire(moduleManager.getRecorder(), (opts.nodeRequire || AMDLoader.global.nodeRequire));
			let pieces = scriptSrc.split(&apos;|&apos;);

			let moduleExports = null;
			try {
				moduleExports = nodeRequire(pieces[1]);
			} catch (err) {
				errorback(err);
				return;
			}

			moduleManager.enqueueDefineAnonymousModule([], () =&gt; moduleExports);
			callback();
		} else {
			// &#x6D4F;&#x89C8;&#x5668;&#x73AF;&#x5883;&#xFF0C;&#x65B0;&#x5EFA; &lt;script&gt; &#x6807;&#x7B7E;&#xFF0C;&#x8BBE;&#x7F6E;&#x4E3A;&#x5F02;&#x6B65;&#x52A0;&#x8F7D;
			let script = document.createElement(&apos;script&apos;);
			script.setAttribute(&apos;async&apos;, &apos;async&apos;);
			script.setAttribute(&apos;type&apos;, &apos;text/javascript&apos;);

			// browser-1: &#x6DFB;&#x52A0; load &#x548C; error &#x7684;&#x4E8B;&#x4EF6;&#x76D1;&#x542C;&#x5668;
			this.attachListeners(script, callback, errorback);

			// &#x8BBE;&#x7F6E; src
			// &#x6BD4;&#x5982;&#x5BF9;&#x4E8E; test &#x6A21;&#x5757;&#xFF0C;&#x5C31;&#x662F; test.js
			const { trustedTypesPolicy } = moduleManager.getConfig().getOptionsLiteral();
			if (trustedTypesPolicy) {
				scriptSrc = trustedTypesPolicy.createScriptURL(scriptSrc);
			}
			script.setAttribute(&apos;src&apos;, scriptSrc);

			// &#x5B89;&#x5168;&#x7B56;&#x7565;&#xFF0C;&#x5C06; CSP nonce &#x4F20;&#x7ED9; &lt;script&gt; &#x6807;&#x7B7E;
			const { cspNonce } = moduleManager.getConfig().getOptionsLiteral();
			if (cspNonce) {
				script.setAttribute(&apos;nonce&apos;, cspNonce);
			}

			// &lt;script&gt; &#x6807;&#x7B7E;&#x6DFB;&#x52A0;&#x5230; head&#xFF0C;&#x52A0;&#x8F7D;&#x811A;&#x672C;
			document.getElementsByTagName(&apos;head&apos;)[0].appendChild(script);
		}
	}

	/**
	 * &#x6DFB;&#x52A0; load &#x548C; error &#x7684;&#x4E8B;&#x4EF6;&#x76D1;&#x542C;&#x5668;&#xFF0C;&#x5E76;&#x5728;&#x5176;&#x4E2D;&#x4E00;&#x4E2A;&#x4E8B;&#x4EF6;&#x89E6;&#x53D1;&#x65F6;&#x79FB;&#x9664;&#x8FD9;&#x4E24;&#x4E2A;&#x76D1;&#x542C;&#x5668;
	 */
	private attachListeners(script: HTMLScriptElement, callback: () =&gt; void, errorback: (err: any) =&gt; void): void {
		let unbind = () =&gt; {
			script.removeEventListener(&apos;load&apos;, loadEventListener);
			script.removeEventListener(&apos;error&apos;, errorEventListener);
		};

		let loadEventListener = (e: any) =&gt; {
			unbind();
			// browser-2: &#x5728;&#x811A;&#x672C;&#x52A0;&#x8F7D;&#x540E;&#xFF0C;&#x6267;&#x884C; callback
			callback();
		};

		let errorEventListener = (e: any) =&gt; {
			unbind();
			errorback(e);
		};

		script.addEventListener(&apos;load&apos;, loadEventListener);
		script.addEventListener(&apos;error&apos;, errorEventListener);
	}

}
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&#x8FD9;&#x91CC;&#x548C; requirejs &#x6D4F;&#x89C8;&#x5668;&#x73AF;&#x5883;&#x52A0;&#x8F7D;&#x6A21;&#x5757;&#x7684;&#x903B;&#x8F91;&#x57FA;&#x672C;&#x4E00;&#x81F4;&#xFF0C;&#x90FD;&#x662F;&#x65B0;&#x5EFA;&#x4E00;&#x4E2A; <code>&lt;script&gt;</code> &#x6807;&#x7B7E;&#xFF0C;&#x8BBE;&#x7F6E;&#x5F02;&#x6B65;&#x52A0;&#x8F7D;&#x3002;&#x5728;&#x811A;&#x672C;&#x52A0;&#x8F7D;&#x540E;&#xFF08;&#x5373; test.js &#x8FD0;&#x884C;&#x7ED3;&#x675F;&#x540E;&#xFF09;&#xFF0C;&#x6267;&#x884C;&#x56DE;&#x8C03;&#x51FD;&#x6570;&#x3002;</p>
<p>&#x56DE;&#x8C03;&#x51FD;&#x6570;&#x7684;&#x4F20;&#x5165;&#x8FC7;&#x7A0B;&#x6BD4;&#x8F83;&#x7ED5;&#xFF0C;&#x6574;&#x7406;&#x5982;&#x4E0B;&#xFF1A;</p>
<pre><code class="language-ts">export class ModuleManager{
	private _loadModule(moduleId: ModuleId): void {
		...
		// &#x7B2C;&#x4E00;&#x6B65;&#xFF1A;&#x52A0;&#x8F7D;&#x811A;&#x672C;&#xFF0C;&#x53C2;&#x6570; callback: `() =&gt; { ... this._onLoad(moduleId); }`
		this._scriptLoader.load(this, currentPath, () =&gt; { ... this._onLoad(moduleId); }, (err) =&gt; {...});
	}
}

class OnlyOnceScriptLoader implements IScriptLoader {
	public load(moduleManager: IModuleManager, scriptSrc: string, callback: () =&gt; void, errorback: (err: any) =&gt; void): void {
		...
		let scriptCallbacks: IScriptCallbacks = {
			// callback: &#x5BF9;&#x5E94;&#x7B2C;&#x4E00;&#x6B65;&#x4F20;&#x5165;&#x7684; () =&gt; { ... this._onLoad(moduleId); }
			callback: callback,
			errorback: errorback
		};
		if (this._callbackMap.hasOwnProperty(scriptSrc)) {
			this._callbackMap[scriptSrc].push(scriptCallbacks);
			return;
		}
		// &#x7B2C;&#x4E8C;&#x6B65;&#xFF1A;&#x6D4F;&#x89C8;&#x5668;&#x73AF;&#x5883;&#x52A0;&#x8F7D;&#x811A;&#x672C;&#xFF0C;&#x53C2;&#x6570; callback: () =&gt; this.triggerCallback(scriptSrc)
		this._scriptLoader.load(moduleManager, scriptSrc, () =&gt; this.triggerCallback(scriptSrc), (err: any) =&gt; this.triggerErrorback(scriptSrc, err));
	}

	private triggerCallback(scriptSrc: string): void {
		let scriptCallbacks = this._callbackMap[scriptSrc];
		delete this._callbackMap[scriptSrc];

		for (let i = 0; i &lt; scriptCallbacks.length; i++) {
			// triggerCallback: &#x89E6;&#x53D1;&#x56DE;&#x8C03;&#xFF0C;scriptCallbacks[i].callback &#x5BF9;&#x5E94;&#x7B2C;&#x4E00;&#x6B65;&#x4F20;&#x5165;&#x7684; () =&gt; { ... this._onLoad(moduleId); }
			scriptCallbacks[i].callback();
		}
	}
}

class BrowserScriptLoader implements IScriptLoader {
	public load(moduleManager: IModuleManager, scriptSrc: string, callback: () =&gt; void, errorback: (err: any) =&gt; void): void {
		...
		// &#x7B2C;&#x4E09;&#x6B65;&#xFF1A;&#x6DFB;&#x52A0;&#x811A;&#x672C;&#x4E8B;&#x4EF6;&#x76D1;&#x542C;&#x5668;&#xFF0C;&#x53C2;&#x6570; callback: () =&gt; this.triggerCallback(scriptSrc)
		this.attachListeners(script, callback, errorback);
		...
	}

	private attachListeners(script: HTMLScriptElement, callback: () =&gt; void, errorback: (err: any) =&gt; void): void {
		...
		let loadEventListener = (e: any) =&gt; {
			unbind();
			// &#x7B2C;&#x56DB;&#x6B65;&#xFF1A;&#x76D1;&#x542C;&#x811A;&#x672C;&#x52A0;&#x8F7D;&#x65F6;&#x95F4;&#xFF0C;&#x6267;&#x884C; callback: () =&gt; this.triggerCallback(scriptSrc)
			callback();
		};
		...
	}

}
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x51FA;&#xFF0C;&#x811A;&#x672C;&#x52A0;&#x8F7D;&#x540E;&#xFF0C;&#x8C03;&#x7528; <code>() =&gt; this.triggerCallback(scriptSrc)</code>&#xFF0C;<code>triggerCallback</code> &#x4E2D;&#x53C8;&#x8C03;&#x7528;<code>() =&gt; { ... this._onLoad(moduleId); }</code>&#x3002;</p>
<p>&#x903B;&#x8F91;&#x5982;&#x4E0B;&#xFF0C;&#x5BF9;&#x4E8E; test &#x6A21;&#x5757;&#xFF0C;&#x6CA1;&#x6709;&#x8FDB;&#x884C;&#x4EC0;&#x4E48;&#x64CD;&#x4F5C;&#x3002;</p>
<pre><code class="language-ts">export class ModuleManager{
	// &#x53C2;&#x6570; moduleId: 4
	private _onLoad(moduleId: ModuleId): void {
		// &#x53EA;&#x5BF9;&#x533F;&#x540D;&#x6A21;&#x5757;&#xFF0C;&#x8FDB;&#x884C; defineModule
		// test &#x6A21;&#x5757;&#x4E0D;&#x662F;&#x533F;&#x540D;&#x6A21;&#x5757;&#xFF0C;&#x6240;&#x4EE5;&#x4EC0;&#x4E48;&#x90FD;&#x6CA1;&#x6709;&#x505A;
		if (this._currentAnnonymousDefineCall !== null) {
			let defineCall = this._currentAnnonymousDefineCall;
			this._currentAnnonymousDefineCall = null;

			this.defineModule(this._moduleIdProvider.getStrModuleId(moduleId), defineCall.dependencies, defineCall.callback, null, defineCall.stack);
		}
	}
}
</code></pre>
<h2 id="define-%E5%AE%9A%E4%B9%89%E6%A8%A1%E5%9D%97">define &#x5B9A;&#x4E49;&#x6A21;&#x5757;</h2>
<p>&#x524D;&#x9762; <code>require</code> &#x901A;&#x8FC7;&#x6DFB;&#x52A0; <code>&lt;script src=&quot;test.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;</code> &#x6807;&#x7B7E;&#x52A0;&#x8F7D; test.js&#xFF0C;&#x800C; test.js &#x4E2D;&#x53C8;&#x8C03;&#x7528; <code>define</code> &#x51FD;&#x6570;&#xFF0C;&#x5B9A;&#x4E49;&#x4E86; test &#x6A21;&#x5757;&#x3002;</p>
<pre><code class="language-js">// test.js
define(&apos;test&apos;, function() {
    return {
        compare: function(a, b) {
            return a &gt; b;
        }
    }
});
</code></pre>
<p>&#x4E0B;&#x9762;&#x770B;&#x4E00;&#x4E0B; <code>define</code> &#x51FD;&#x6570;&#x7684;&#x5B9E;&#x73B0;&#xFF1A;</p>
<pre><code class="language-ts">// main.ts
...
define = function () {
	return DefineFunc.apply(null, arguments);
};

const DefineFunc: IDefineFunc = &lt;any&gt;function (id: any, dependencies: any, callback: any): void {
	// &#x7B2C;&#x4E00;&#x6B65;&#xFF1A;&#x6CA1;&#x6709;&#x4F20;&#x5165; id&#xFF0C;&#x8C03;&#x6574;&#x53C2;&#x6570;
	if (typeof id !== &apos;string&apos;) {
		callback = dependencies;
		dependencies = id;
		id = null;
	}
	// &#x7B2C;&#x4E8C;&#x6B65;&#xFF1A;&#x6CA1;&#x6709;&#x4F20;&#x5165; dependencies&#xFF0C;&#x8C03;&#x6574;&#x53C2;&#x6570;
	// &#x5BF9;&#x4E8E; test &#x6A21;&#x5757;&#xFF0C;&#x8C03;&#x6574;&#x540E;&#xFF0C;id = &apos;test&apos;, callback = f (), dependencies = [&apos;require&apos;, &apos;exports&apos;, &apos;module&apos;]
	if (typeof dependencies !== &apos;object&apos; || !Array.isArray(dependencies)) {
		callback = dependencies;
		dependencies = null;
	}
	if (!dependencies) {
		dependencies = [&apos;require&apos;, &apos;exports&apos;, &apos;module&apos;];
	}

	// &#x7B2C;&#x4E09;&#x6B65;&#xFF1A;&#x5B9A;&#x4E49;&#x6A21;&#x5757;&#xFF08;&#x53EF;&#x4EE5;&#x4E3A;&#x533F;&#x540D;&#x6A21;&#x5757;&#xFF09;&#xFF0C;&#x6700;&#x7EC8;&#x662F;&#x8C03;&#x7528; moduleManager &#x4E2D;&#x7684;&#x65B9;&#x6CD5;
	// &#x5BF9;&#x4E8E; test &#x6A21;&#x5757;&#xFF0C;&#x8C03;&#x7528; moduleManager.defineModule
	if (id) {
		moduleManager.defineModule(id, dependencies, callback, null, null);
	} else {
		moduleManager.enqueueDefineAnonymousModule(dependencies, callback);
	}
};

</code></pre>
<p>&#x524D;&#x9762; <code>require([test], f(test))</code> &#x8C03;&#x7528; <code>moduleManager.defineModule</code> &#x751F;&#x6210;&#x6A21;&#x5757; 3&#xFF0C;&#x8FD9;&#x91CC; <code>define(&apos;test&apos;, f())</code> &#x4E5F;&#x662F;&#x8C03;&#x7528; <code>moduleManager.defineModule</code> &#x751F;&#x6210; test &#x6A21;&#x5757;&#x3002;</p>
<pre><code class="language-ts">// moduleManager.ts
export class ModuleManager {
	// &#x53C2;&#x6570;&#xFF1A;&apos;test&apos;, [&apos;require&apos;, &apos;exports&apos;, &apos;module&apos;], f()
	public defineModule(strModuleId: string, dependencies: string[], callback: any, errorback: ((err: AnnotatedError) =&gt; void) | null | undefined, stack: string | null, moduleIdResolver: ModuleIdResolver = new ModuleIdResolver(strModuleId)): void {
		// define-1&#xFF1A;strModuleId -&gt; moduleId
		// &apos;test&apos; -&gt; 4&#x3002;&#x5728;&#x6A21;&#x5757; 3 &#x89E3;&#x6790;&#x4F9D;&#x8D56;&#x65F6;&#xFF0C;&apos;test&apos; &#x6A21;&#x5757;&#x5DF2;&#x7ECF;&#x751F;&#x6210; moduleId 4&#x3002;
		let moduleId = this._moduleIdProvider.getModuleId(strModuleId);
		...

		// define-2&#xFF1A;&#x65B0;&#x5EFA;&#x6A21;&#x5757;&#x5E76;&#x4FDD;&#x5B58;&#x5230; this._modules2
		// &#x65B0;&#x5EFA; test &#x6A21;&#x5757;
		let m = new Module(moduleId, strModuleId, this._normalizeDependencies(dependencies, moduleIdResolver), callback, errorback, moduleIdResolver);
		this._modules2[moduleId] = m;

		...

		// define-3&#xFF1A;&#x7ACB;&#x5373;&#x89E3;&#x6790;&#x4F9D;&#x8D56;&#x9879;
		// m&#xFF1A;&#x5BF9;&#x5E94; test &#x6A21;&#x5757;
		this._resolve(m);
	}
}
</code></pre>
<p>&#x8FD9;&#x91CC;&#x548C;&#x6A21;&#x5757; 3 &#x7684;&#x751F;&#x6210;&#x903B;&#x8F91;&#x57FA;&#x672C;&#x4E00;&#x81F4;&#xFF0C;&#x4E0D;&#x540C;&#x70B9;&#x5982;&#x4E0B;&#xFF1A;</p>
<ol>
<li>&#x4F9D;&#x8D56;&#x4E0D;&#x540C;&#xFF1A;&#x6A21;&#x5757; 3 &#x4F9D;&#x8D56;&#x4E8E; test &#x6A21;&#x5757;&#xFF0C;&#x800C; test &#x6A21;&#x5757;&#x7531;&#x4E8E;&#x6CA1;&#x6709;&#x4F9D;&#x8D56;&#x9879;&#xFF0C;<code>define</code> &#x51FD;&#x6570;&#x8BBE;&#x7F6E;&#x4E86;&#x9ED8;&#x8BA4;&#x4F9D;&#x8D56;&#x6A21;&#x5757; [&apos;require&apos;, &apos;exports&apos;, &apos;module&apos;]&#x3002;</li>
</ol>
<!-- 在 define-2 中，通过 `_normalizeDependencies` 生成 3 个 dependency 对象，export: `{id: 0}`, module: `{id: 1}`, require: `{id: 2}`。前面已经分析过，dependency 对象就是带唯一 id 的对象，比如 test 模块是 `{id: 4}`。 -->
<ol start="2">
<li>&#x89E3;&#x6790;&#x4F9D;&#x8D56;&#x9879;&#x7684;&#x903B;&#x8F91;&#x4E0D;&#x540C;&#xFF1A;&#x6A21;&#x5757; 3 &#x89E3;&#x6790;&#x4F9D;&#x8D56; test &#x6A21;&#x5757;&#xFF0C;&#x800C; test &#x6A21;&#x5757;&#x89E3;&#x6790;&#x9ED8;&#x8BA4;&#x6A21;&#x5757; [&apos;require&apos;, &apos;exports&apos;, &apos;module&apos;]&#x3002;</li>
</ol>
<p>&#x89E3;&#x6790;&#x9ED8;&#x8BA4;&#x6A21;&#x5757;&#x7684;&#x903B;&#x8F91;&#x5982;&#x4E0B;&#xFF1A;</p>
<pre><code class="language-ts">export class ModuleManager{
	// &#x53C2;&#x6570;&#xFF1A;test &#x6A21;&#x5757;
	private _resolve(module: Module): void {
		// [&apos;require&apos;, &apos;exports&apos;, &apos;module&apos;] &#x662F;&#x9ED8;&#x8BA4;&#x4F9D;&#x8D56;&#x6A21;&#x5757;&#xFF0C;&#x5728;&#x8FD9;&#x91CC;&#x6267;&#x884C;&#x7684;&#x662F; resolve-1&#x3001;resolve-2&#x3001;resolve-3 &#x7684;&#x903B;&#x8F91;
		let dependencies = module.dependencies;
		if (dependencies) {
			for (let i = 0, len = dependencies.length; i &lt; len; i++) {
				let dependency = dependencies[i];

				// resolve-1&#xFF1A;exports
				if (dependency === RegularDependency.EXPORTS) {
					module.exportsPassedIn = true;
					module.unresolvedDependenciesCount--;
					continue;
				}

				// resolve-2&#xFF1A;module
				if (dependency === RegularDependency.MODULE) {
					module.unresolvedDependenciesCount--;
					continue;
				}

				// resolve-3&#xFF1A;require
				if (dependency === RegularDependency.REQUIRE) {
					module.unresolvedDependenciesCount--;
					continue;
				}

				...
			}
		}

		// &#x524D;&#x9762;&#x904D;&#x5386;&#x4F9D;&#x8D56;&#x6570;&#x7EC4;&#xFF0C;&#x6BCF;&#x6B21;&#x90FD; module.unresolvedDependenciesCount--&#xFF0C;&#x6240;&#x4EE5;&#x8FD9;&#x91CC; module.unresolvedDependenciesCount: 0&#xFF0C;&#x8C03;&#x7528; _onModuleComplete
		if (module.unresolvedDependenciesCount === 0) {
			this._onModuleComplete(module);
		}
	}
</code></pre>
<p>&#x524D;&#x9762;&#x6A21;&#x5757; 3 &#x89E3;&#x6790;&#x4F9D;&#x8D56;&#xFF0C;&#x6700;&#x7EC8;&#x8C03;&#x7528; _loadModule(4) &#x52A0;&#x8F7D;&#x6A21;&#x5757; 4&#x3002;&#x800C;&#x8FD9;&#x91CC;&#x89E3;&#x6790;&#x4F9D;&#x8D56;&#x540E;&#xFF0C;&#x8C03;&#x7528; _onModuleComplete &#x5B8C;&#x6210;&#x6A21;&#x5757; 4 &#x7684;&#x89E3;&#x6790;&#x3002;&#x5177;&#x4F53;&#x5982;&#x4E0B;&#xFF1A;</p>
<pre><code class="language-ts">export class ModuleManager{
	private _onModuleComplete(module: Module): void {
		let recorder = this.getRecorder(); // &#x4E8B;&#x4EF6;&#x8BB0;&#x5F55;&#x5668;&#xFF0C;&#x7528;&#x4E8E;&#x8BB0;&#x5F55; BeginLoadingScript&#x3001;EndLoadingScriptOK &#x7B49;&#x4E8B;&#x4EF6;&#x53CA;&#x5176;&#x65F6;&#x95F4;&#x6233;&#x3002;

		if (module.isComplete()) {
			return;
		}

		// &#x7B2C;&#x4E00;&#x6B65;&#xFF1A;&#x904D;&#x5386;&#x4F9D;&#x8D56;&#x6570;&#x7EC4;&#xFF0C;[&apos;require&apos;, &apos;exports&apos;, &apos;module&apos;]&#xFF0C;&#x751F;&#x6210; dependenciesValues
		let dependencies = module.dependencies;
		let dependenciesValues: any[] = [];
		if (dependencies) {
			for (let i = 0, len = dependencies.length; i &lt; len; i++) {
				let dependency = dependencies[i];

				// &apos;exports&apos;: module.exports
				if (dependency === RegularDependency.EXPORTS) {
					dependenciesValues[i] = module.exports;
					continue;
				}

				// &apos;module&apos;: {id: &apos;test&apos;, config: () =&gt; { return this._config.getConfigForModule(&apos;test&apos;) }}
				if (dependency === RegularDependency.MODULE) {
					dependenciesValues[i] = {
						id: module.strId,
						config: () =&gt; {
							return this._config.getConfigForModule(module.strId);
						}
					};
					continue;
				}

				// &apos;require&apos;: require &#x51FD;&#x6570;&#xFF0C;&#x5305;&#x542B; node &#x539F;&#x751F;&#x7684; require&#xFF0C;require.__$__nodeRequire
				if (dependency === RegularDependency.REQUIRE) {
					dependenciesValues[i] = this._createRequire(module.moduleIdResolver!);
					continue;
				}

				...
			}
		}

		// &#x7B2C;&#x4E8C;&#x6B65;&#xFF1A;&#x8C03;&#x7528;&#x6A21;&#x5757;&#x7684; complete &#x65B9;&#x6CD5;&#xFF0C;&#x6267;&#x884C;&#x6A21;&#x5757;&#x7684;&#x5DE5;&#x5382;&#x51FD;&#x6570;
		module.complete(recorder, this._config, dependenciesValues);

		// &#x7B2C;&#x4E09;&#x6B65;&#xFF1A;&#x904D;&#x5386;&#x6A21;&#x5757;&#x7684;&#x53CD;&#x5411;&#x4F9D;&#x8D56;&#x6A21;&#x5757;&#xFF0C;&#x5982;&#x679C;&#x53CD;&#x5411;&#x6A21;&#x5757;&#x7684;&#x4F9D;&#x8D56;&#x90FD;&#x5DF2;&#x7ECF;&#x89E3;&#x6790;&#x5B8C;&#x6210;&#xFF0C;&#x5C31;&#x5BF9;&#x53CD;&#x5411;&#x6A21;&#x5757;&#x6267;&#x884C; _onModuleComplete
		// &#x6A21;&#x5757; 4 &#x7684;&#x53CD;&#x5411;&#x4F9D;&#x8D56;&#x6A21;&#x5757;&#x662F; [3]
		let inverseDeps = this._inverseDependencies2[module.id];
		this._inverseDependencies2[module.id] = null;

		if (inverseDeps) {
			for (let i = 0, len = inverseDeps.length; i &lt; len; i++) {
				let inverseDependencyId = inverseDeps[i];
				let inverseDependency = this._modules2[inverseDependencyId];
				// &#x6BD4;&#x5982;&#x6A21;&#x5757; 3 &#x4F9D;&#x8D56;&#x4E8E;&#x6A21;&#x5757; 4&#xFF0C;&#x73B0;&#x5728;&#x6A21;&#x5757; 4 &#x5DF2;&#x7ECF;&#x89E3;&#x6790;&#x5B8C;&#x6210;&#xFF0C;&#x6240;&#x4EE5;&#x6A21;&#x5757; 3 &#x7684;&#x672A;&#x89E3;&#x6790;&#x4F9D;&#x8D56;&#x6570;&#x91CF; - 1
				inverseDependency.unresolvedDependenciesCount--;
				// &#x5BF9;&#x6A21;&#x5757; 3 &#x6267;&#x884C; _onModuleComplete
				if (inverseDependency.unresolvedDependenciesCount === 0) {
					this._onModuleComplete(inverseDependency);
				}
			}
		}

		// &#x7B2C;&#x56DB;&#x6B65;&#xFF1A;&#x89E3;&#x6790;&#x53CD;&#x5411;&#x63D2;&#x4EF6;&#x4F9D;&#x8D56;
		let inversePluginDeps = this._inversePluginDependencies2.get(module.id);
		if (inversePluginDeps) {
			this._inversePluginDependencies2.delete(module.id);

			for (let i = 0, len = inversePluginDeps.length; i &lt; len; i++) {
				this._loadPluginDependency(module.exports, inversePluginDeps[i]);
			}
		}
	}

}
</code></pre>
<p>&#x7B2C;&#x4E8C;&#x6B65;&#xFF0C;&#x8C03;&#x7528; <code>module.complete</code> &#x65B9;&#x6CD5;&#xFF0C;&#x5B8C;&#x6210;&#x6A21;&#x5757; 4 &#x7684;&#x89E3;&#x6790;&#xFF1A;</p>
<pre><code class="language-ts">// &#x5B8C;&#x6210;&#x6A21;&#x5757;&#x89E3;&#x6790;
export class Module {
	public complete(recorder: ILoaderEventRecorder, config: Configuration, dependenciesValues: any[]): void {
		// &#x6807;&#x8BB0;&#x6A21;&#x5757;&#x5DF2;&#x89E3;&#x6790;&#x5B8C;&#x6210;
		this._isComplete = true;

		let producedError: any = null;
		// &#x8C03;&#x7528;&#x5DE5;&#x5382;&#x51FD;&#x6570;&#xFF0C;&#x8BBE;&#x7F6E; this.exports
		if (this._callback) {
			if (typeof this._callback === &apos;function&apos;) {

				recorder.record(LoaderEventType.BeginInvokeFactory, this.strId); // &#x8BB0;&#x5F55; BeginInvokeFactory &#x4E8B;&#x4EF6;
				// complete-1&#xFF1A;&#x8C03;&#x7528; _invokeFactory
				let r = Module._invokeFactory(config, this.strId, this._callback, dependenciesValues);
				producedError = r.producedError;
				recorder.record(LoaderEventType.EndInvokeFactory, this.strId); // &#x8BB0;&#x5F55; EndInvokeFactory &#x4E8B;&#x4EF6;

				if (!producedError &amp;&amp; typeof r.returnedValue !== &apos;undefined&apos; &amp;&amp; (!this.exportsPassedIn || Utilities.isEmpty(this.exports))) {
					this.exports = r.returnedValue; // &#x5982;&#x679C;&#x5DE5;&#x5382;&#x51FD;&#x6570;&#x6709;&#x8FD4;&#x56DE;&#x503C;&#xFF0C;&#x8BBE;&#x7F6E; this.exports = r.returnedValue
				}

			} else {
				this.exports = this._callback; // &#x5982;&#x679C;&#x6CA1;&#x6709;&#x5DE5;&#x5382;&#x51FD;&#x6570;&#xFF0C;&#x8BBE;&#x7F6E; this.exports = this._callback
			}
		}

		// &#x9519;&#x8BEF;&#x5904;&#x7406;&#x548C;&#x91CD;&#x7F6E;
		...
	}

	private static _invokeFactory(config: Configuration, strModuleId: string, callback: Function, dependenciesValues: any[]): { returnedValue: any; producedError: any; } {
		if (config.isBuild() &amp;&amp; !Utilities.isAnonymousModule(strModuleId)) {
			return {
				returnedValue: null,
				producedError: null
			};
		}

		if (config.shouldCatchError()) {
			return this._safeInvokeFunction(callback, dependenciesValues); // &#x548C; complete-2 &#x7C7B;&#x4F3C;&#xFF0C;&#x53EA;&#x662F;&#x589E;&#x52A0;&#x4E86; try-catch
		}

		// complete-2: &#x8C03;&#x7528; callback&#xFF0C;&#x5E76;&#x5C06;&#x7ED3;&#x679C;&#x8FD4;&#x56DE;&#x3002;
		// &#x5BF9;&#x4E8E;&#x6A21;&#x5757; 4&#xFF0C;&#x662F;&#x8C03;&#x7528; define(&apos;test&apos;, f()) &#x4E2D;&#x7684;&#x51FD;&#x6570;&#xFF0C;&#x5E76;&#x8FD4;&#x56DE; compare: function(a, b)
		return {
			returnedValue: callback.apply(global, dependenciesValues),
			producedError: null
		};
	}

}
</code></pre>
<p>&#x7B2C;&#x4E8C;&#x6B65;&#x89E3;&#x6790;&#x5B8C;&#x6A21;&#x5757; 4&#xFF0C;&#x8C03;&#x7528; <code>define(&apos;test&apos;, f())</code> &#x4E2D;&#x7684;&#x51FD;&#x6570;&#xFF0C;&#x8FD4;&#x56DE;&#x51FD;&#x6570;&#x6267;&#x884C;&#x7ED3;&#x679C; <code>compare: function(a, b)</code>&#xFF0C;&#x5E76;&#x8D4B;&#x503C;&#x7ED9;&#x6A21;&#x5757; 4 &#x7684; <code>exports</code>&#x3002;</p>
<p>&#x7B2C;&#x4E09;&#x6B65;&#xFF0C;&#x7531;&#x4E8E;&#x6A21;&#x5757; 4 &#x5DF2;&#x7ECF;&#x5B8C;&#x6210;&#x89E3;&#x6790;&#xFF0C;&#x6A21;&#x5757; 3 &#x4E5F;&#x53EF;&#x4EE5;&#x5B8C;&#x6210;&#x89E3;&#x6790;&#xFF08;&#x6A21;&#x5757; 3 &#x53EA;&#x4F9D;&#x8D56;&#x6A21;&#x5757; 4&#xFF09;&#xFF0C;&#x6240;&#x4EE5;&#x4E5F;&#x5BF9;&#x6A21;&#x5757; 3 &#x6267;&#x884C; <code>_onModuleComplete</code>&#x3002;</p>
<pre><code class="language-ts">export class ModuleManager{
	private _onModuleComplete(module: Module): void {
		let recorder = this.getRecorder(); // &#x4E8B;&#x4EF6;&#x8BB0;&#x5F55;&#x5668;&#xFF0C;&#x7528;&#x4E8E;&#x8BB0;&#x5F55; BeginLoadingScript&#x3001;EndLoadingScriptOK &#x7B49;&#x4E8B;&#x4EF6;&#x53CA;&#x5176;&#x65F6;&#x95F4;&#x6233;&#x3002;

		if (module.isComplete()) {
			return;
		}

		// &#x7B2C;&#x4E00;&#x6B65;&#xFF1A;&#x904D;&#x5386;&#x4F9D;&#x8D56;&#x6570;&#x7EC4;&#xFF0C;[{id: 4}]&#xFF0C;&#x751F;&#x6210; dependenciesValues: [{ compare: &#x192; (a, b) }]
		let dependencies = module.dependencies;
		let dependenciesValues: any[] = [];
		if (dependencies) {
			for (let i = 0, len = dependencies.length; i &lt; len; i++) {
				let dependency = dependencies[i];
				...

				let dependencyModule = this._modules2[dependency.id];
				if (dependencyModule) {
					// &#x4FDD;&#x5B58;&#x6A21;&#x5757; 4 &#x7684; exports&#xFF0C;&#x5373; test &#x6A21;&#x5757;&#x7684;&#x5DE5;&#x5382;&#x51FD;&#x6570;&#x8FD4;&#x56DE;&#x503C;&#xFF1A;compare: function(a, b)
					dependenciesValues[i] = dependencyModule.exports;
					continue;
				}

				dependenciesValues[i] = null;
			}
		}

		// &#x7B2C;&#x4E8C;&#x6B65;&#xFF1A;&#x8C03;&#x7528;&#x6A21;&#x5757;&#x7684; complete &#x65B9;&#x6CD5;&#xFF0C;&#x6267;&#x884C;&#x6A21;&#x5757;&#x7684;&#x5DE5;&#x5382;&#x51FD;&#x6570;
		module.complete(recorder, this._config, dependenciesValues);

		// &#x6A21;&#x5757; 3 &#x6CA1;&#x6709;&#x53CD;&#x5411;&#x4F9D;&#x8D56;&#xFF0C;&#x7B2C;&#x4E09;&#x6B65;&#x3001;&#x7B2C;&#x56DB;&#x6B65;&#x7565;
		...
	}

}

export class Module {
	public complete(recorder: ILoaderEventRecorder, config: Configuration, dependenciesValues: any[]): void {
		...

		// &#x8C03;&#x7528; _invokeFactory&#xFF0C;dependenciesValues &#x5BF9;&#x5E94; test &#x6A21;&#x5757;&#x7684;&#x8FD4;&#x56DE;&#x503C;
		let r = Module._invokeFactory(config, this.strId, this._callback, dependenciesValues);

		...

		// &#x6A21;&#x5757; 3 &#x7684;&#x5DE5;&#x5382;&#x51FD;&#x6570;&#x6CA1;&#x6709;&#x8FD4;&#x56DE;&#x503C;&#xFF0C;&#x4E0D;&#x8BBE;&#x7F6E;
		if (!producedError &amp;&amp; typeof r.returnedValue !== &apos;undefined&apos; &amp;&amp; (!this.exportsPassedIn || Utilities.isEmpty(this.exports))) {
			this.exports = r.returnedValue;
		}

		...
	}

	private static _invokeFactory(config: Configuration, strModuleId: string, callback: Function, dependenciesValues: any[]): { returnedValue: any; producedError: any; } {
		...

		// &#x5BF9;&#x4E8E;&#x6A21;&#x5757; 3&#xFF0C;&#x662F;&#x8C03;&#x7528; require([&apos;test&apos;], f(test)) &#x4E2D;&#x7684;&#x51FD;&#x6570;&#xFF0C;&#x4F20;&#x5165;&#x53C2;&#x6570; dependenciesValues &#x662F; test &#x6A21;&#x5757;&#x7684;&#x8FD4;&#x56DE;&#x503C;
		// &#x8FD4;&#x56DE; {returnValue: null, producedError: null}
		return {
			returnedValue: callback.apply(global, dependenciesValues),
			producedError: null
		};
	}

}
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;<code>_onModuleComplete</code> &#x6267;&#x884C;&#x4E86;&#x6A21;&#x5757; 3 &#x7684;&#x5DE5;&#x5382;&#x51FD;&#x6570;&#xFF0C;&#x81F3;&#x6B64;&#x6240;&#x6709;&#x6A21;&#x5757;&#x52A0;&#x8F7D;&#x5B8C;&#x6210;&#xFF0C;&#x6A21;&#x5757;&#x7684;&#x5DE5;&#x5382;&#x51FD;&#x6570;&#x4E5F;&#x90FD;&#x6267;&#x884C;&#x5B8C;&#x6BD5;&#x3002;</p>
<h2 id="%E6%80%BB%E7%BB%93">&#x603B;&#x7ED3;</h2>
<p>&#x672C;&#x6587;&#x4EE5;&#x6D4F;&#x89C8;&#x5668;&#x73AF;&#x5883;&#x4E3A;&#x4F8B;&#xFF0C;&#x5206;&#x6790;&#x4E86; vscode-loader &#x7684;&#x6A21;&#x5757;&#x52A0;&#x8F7D;&#xFF1A;</p>
<ol>
<li>&#x5728; vscode-loader &#x4E2D;&#xFF0C;<code>require</code> &#x6216; <code>define</code> &#x51FD;&#x6570;&#xFF0C;&#x4E00;&#x822C;&#x4F1A;&#x8C03;&#x7528; <code>moduleManager.defineModule</code> &#x5B9A;&#x4E49;&#x5F02;&#x6B65;&#x6A21;&#x5757;&#x3002;</li>
<li>&#x5728; <code>defineModule</code> &#x4E2D;&#xFF0C;&#x901A;&#x8FC7; <code>new Module()</code> &#x751F;&#x6210;&#x5F02;&#x6B65;&#x6A21;&#x5757;&#xFF0C;&#x901A;&#x8FC7; <code>this._resolve(m)</code> &#x89E3;&#x6790;&#x6A21;&#x5757;&#x3002;</li>
<li>&#x5728; <code>_resolve</code> &#x4E2D;&#xFF0C;
<ul>
<li>&#x5982;&#x679C;&#x6A21;&#x5757;&#x4F9D;&#x8D56;&#x4E8E;&#x5176;&#x4ED6;&#x6A21;&#x5757;&#xFF0C;&#x4F1A;&#x901A;&#x8FC7; <code>_loadModule</code> &#x52A0;&#x8F7D;&#x4F9D;&#x8D56;&#x6A21;&#x5757;&#x3002;
<ul>
<li>&#x5728; <code>_loadModule</code> &#x4E2D;&#xFF0C;&#x4F1A;&#x8C03;&#x7528; <code>this._scriptLoader.load</code> &#x52A0;&#x8F7D;&#x6A21;&#x5757;&#x3002;&#x5BF9;&#x4E8E;&#x6D4F;&#x89C8;&#x5668;&#x73AF;&#x5883;&#xFF0C;&#x5C31;&#x662F;&#x751F;&#x6210; <code>&lt;script&gt;</code> &#x6807;&#x7B7E;&#xFF0C;&#x5E76;&#x8BBE;&#x7F6E; async&#xFF0C;&#x5F02;&#x6B65;&#x52A0;&#x8F7D;&#x6A21;&#x5757;&#xFF08;&#x5176;&#x4ED6;&#x73AF;&#x5883;&#x7684;&#x52A0;&#x8F7D;&#x65B9;&#x5F0F;&#x6709;&#x5F02;&#xFF09;&#x3002;</li>
<li>&#x5728;&#x52A0;&#x8F7D;&#x6A21;&#x5757;&#x540E;&#xFF0C;&#x4F1A;&#x8C03;&#x7528; <code>this._onload</code> &#x7684;&#x56DE;&#x8C03;&#xFF0C;&#x4E3B;&#x8981;&#x662F;&#x5904;&#x7406;&#x533F;&#x540D;&#x6A21;&#x5757;&#x3002;</li>
</ul>
</li>
<li>&#x5982;&#x679C;&#x6A21;&#x5757;&#x4E0D;&#x4F9D;&#x8D56;&#x4E8E;&#x5176;&#x4ED6;&#x6A21;&#x5757;&#xFF0C;&#x4F1A;&#x6DFB;&#x52A0;&#x9ED8;&#x8BA4;&#x7684;&#x4F9D;&#x8D56; [&apos;require&apos;, &apos;exports&apos;, &apos;module&apos;]&#xFF0C;&#x5E76;&#x901A;&#x8FC7; <code>_onModuleComplete</code> &#x5B8C;&#x6210;&#x6A21;&#x5757;&#x89E3;&#x6790;&#x3002;
<ul>
<li>&#x5728; <code>_onModuleComplete</code> &#x4E2D;&#xFF0C;&#x4F1A;&#x901A;&#x8FC7; <code>module.complete</code> &#x6267;&#x884C;&#x6A21;&#x5757;&#x7684;&#x5DE5;&#x5382;&#x51FD;&#x6570;&#xFF0C;&#x5E76;&#x4F20;&#x5165; <code>dependenciesValues</code> &#x4F5C;&#x4E3A;&#x53C2;&#x6570;&#x3002;</li>
<li>&#x5B8C;&#x6210;&#x5F53;&#x524D;&#x6A21;&#x5757;&#x89E3;&#x6790;&#x540E;&#xFF0C;&#x4F1A;&#x904D;&#x5386;&#x53CD;&#x5411;&#x4F9D;&#x8D56;&#x6A21;&#x5757;&#x6570;&#x7EC4;&#xFF1B;&#x5982;&#x679C;&#x53CD;&#x5411;&#x6A21;&#x5757;&#x7684;&#x4F9D;&#x8D56;&#x5DF2;&#x7ECF;&#x90FD;&#x89E3;&#x6790;&#x5B8C;&#x6210;&#xFF0C;&#x5219;&#x5BF9;&#x53CD;&#x5411;&#x6A21;&#x5757;&#x4E5F;&#x8C03;&#x7528; <code>_onModuleComplete</code>&#xFF0C;&#x6267;&#x884C;&#x53CD;&#x5411;&#x6A21;&#x5757;&#x7684;&#x5DE5;&#x5382;&#x51FD;&#x6570;&#xFF0C;&#x5E76;&#x4F20;&#x5165; <code>dependenciesValues</code> &#x4F5C;&#x4E3A;&#x53C2;&#x6570;&#x3002;</li>
<li><code>dependenciesValues</code>, &#x5BF9;&#x5E94;&#x7684;&#x662F;&#x9ED8;&#x8BA4;&#x4F9D;&#x8D56;&#x7684;&#x5904;&#x7406;&#x503C;&#xFF0C;&#x6216;&#x8005;&#x4F9D;&#x8D56;&#x6A21;&#x5757;&#x7684;&#x5DE5;&#x5382;&#x51FD;&#x6570;&#x8FD4;&#x56DE;&#x503C;&#x3002;</li>
</ul>
</li>
</ul>
</li>
</ol>
<p>&#x901A;&#x8FC7;&#x4E0A;&#x9762;&#x5206;&#x6790;&#xFF0C;&#x53EF;&#x4EE5;&#x77E5;&#x9053;&#xFF0C;&#x5728; <code>_loadModule</code> &#x4E2D;&#x4F1A;&#x9010;&#x7EA7;&#x52A0;&#x8F7D;&#x4F9D;&#x8D56;&#x6A21;&#x5757;&#xFF1B;&#x800C;&#x5728; <code>_onModuleComplete</code> &#x4E2D;&#xFF0C;&#x662F;&#x5148;&#x6267;&#x884C;&#x6700;&#x5E95;&#x5C42;&#x7684;&#x4F9D;&#x8D56;&#x6A21;&#x5757;&#x7684;&#x89E3;&#x6790;&#xFF0C;&#x518D;&#x6267;&#x884C;&#x5176;&#x53CD;&#x5411;&#x6A21;&#x5757;&#x7684;&#x89E3;&#x6790;&#xFF0C;&#x76F4;&#x5230;&#x6240;&#x6709;&#x6A21;&#x5757;&#x89E3;&#x6790;&#x5B8C;&#x6210;&#x3002;</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[快应用开发工具 5.1 版本发布]]></title><description><![CDATA[快应用开发者工具（IDE），专为快应用开发设计，支持快应用、卡片等开发调试、编译预览、打包上传、以及云测、远程预览.....并支持账号登录，应用关联，查看详情等；仍在不断快速迭代中，旨在让开发者能够更高效开发、调试、测试以及发布快应用。]]></description><link>https://quickapp.vivo.com.cn/quickapp-ide-v5-1-release/</link><guid isPermaLink="false">63c4b94a77e2ca0006a8c89f</guid><category><![CDATA[快应用开发工具]]></category><dc:creator><![CDATA[vivo-developer]]></dc:creator><pubDate>Mon, 01 Nov 2021 02:54:24 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>&#x5FEB;&#x5E94;&#x7528;&#x5DE5;&#x5177;&#x5F00;&#x53D1;&#x56E2;&#x961F;&#xFF0C;&#x4E8E; 2021 &#x5E74; 10 &#x6708; 28 &#x65E5;&#xFF0C;&#x53D1;&#x5E03; IDE &#x6700;&#x65B0;&#x7248;&#x672C;&#xFF1A;<a href="https://www.quickapp.cn/docCenter/post/97">v5.1.0</a>&#x3002;</p>
<h2 id="v51-%E6%9B%B4%E6%96%B0%E8%AF%B4%E6%98%8E"><code>v5.1</code> &#x66F4;&#x65B0;&#x8BF4;&#x660E;</h2>
<p>&#x5728; 10 &#x6708;&#x5373;&#x5C06;&#x7ED3;&#x675F;&#x4E4B;&#x9645;&#xFF0C;&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x56E2;&#x961F;&#xFF0C;&#x5C06;&#x4E4B;&#x524D;&#x9057;&#x7559;&#x7684;&#x4E00;&#x4E9B;&#x672A;&#x89E3;&#x51B3;&#x95EE;&#x9898;&#xFF0C;&#x505A;&#x4E86;&#x5904;&#x7406;&#x548C;&#x4F18;&#x5316;&#xFF0C;&#x63A8;&#x51FA;&#x6700;&#x65B0; <a href="https://www.quickapp.cn/docCenter/post/97">v5.1.0</a> &#x7248;&#x672C;&#xFF1B;&#x4E0B;&#x9762;&#x8BF7;&#x5141;&#x8BB8;&#x8DDF;&#x5927;&#x5BB6;&#x5206;&#x4EAB;&#x4E0B;&#xFF0C;&#x5728;&#x6B64;&#x6B21;&#x8FED;&#x4EE3;&#xFF0C;&#x6211;&#x4EEC;&#x505A;&#x4E86;&#x4E00;&#x4E9B;&#x91CD;&#x8981;&#x6539;&#x8FDB;&#x3002;</p>
<h3 id="%E4%BC%98%E5%8C%96%E6%9B%B4%E6%96%B0">&#x4F18;&#x5316;&#x66F4;&#x65B0;</h3>
<h4 id="%E6%96%B0%E5%A2%9E-1100-%E7%89%88%E6%9C%AC%E6%94%AF%E6%8C%81">&#x65B0;&#x589E; 1100 &#x7248;&#x672C;&#x652F;&#x6301;</h4>
<p>&#x5728;&#x672C;&#x7248;&#x672C;&#x7684; IDE &#x91CC;&#xFF0C;&#x65B0;&#x589E;&#x5BF9; 1100 &#x8BED;&#x6CD5;&#x652F;&#x6301;&#xFF0C;&#x5305;&#x62EC;&#x6846;&#x67B6;&#x3001;&#x7EC4;&#x4EF6;&#x3001;&#x63A5;&#x53E3;&#xFF0C;&#x5177;&#x4F53;&#x53EF;&#x67E5; <a href="https://doc.quickapp.cn/changelog/1100.html">&#x6587;&#x6863;</a>&#x3002;</p>
<h4 id="scss%E3%80%81less%E3%80%81css-%E8%AF%AD%E6%B3%95%E6%8F%90%E7%A4%BA%E4%BC%98%E5%8C%96">scss&#x3001;less&#x3001;css &#x8BED;&#x6CD5;&#x63D0;&#x793A;&#x4F18;&#x5316;</h4>
<ol>
<li>scss &#x8BED;&#x6CD5;&#x63D0;&#x793A;&#x4F18;&#x5316;:</li>
</ol>
<p>&#x9996;&#x5148;&#x9700;&#x8981;&#x5B89;&#x88C5;&#x63D2;&#x4EF6;&#xFF1A;<code>SCSS IntelliSense</code>&#x3002;<br>
&#x4F18;&#x5316;&#x5185;&#x5BB9;&#xFF1A;</p>
<ul>
<li>&#x5728; scss &#x6587;&#x4EF6;&#x4E2D;&#xFF0C;&#x53EF;&#x4EE5;&#x63D0;&#x793A;&#x53D8;&#x91CF;/&#x6DF7;&#x5408;/&#x51FD;&#x6570;&#x3002;
<ul>
<li>
<p>&#x8F93;&#x5165;<code>&#x5C5E;&#x6027;&#x540D;: $</code>&#xFF08;&#x4F8B;&#x5982; color: $&#xFF09;&#xFF0C;&#x53EF;&#x4EE5;&#x63D0;&#x793A;&#x53D8;&#x91CF;&#xFF1A;</p>
  <img src="https://statres.quickapp.cn/quickapp/show/img/211022/scss-1.png" width="720px">
</li>
<li>
<p>&#x8F93;&#x5165;<code>@include </code>(&#x8F93;&#x5165;&#x7A7A;&#x683C;&#x540E;&#x624D;&#x663E;&#x793A;&#x63D0;&#x793A;)&#xFF0C;&#x53EF;&#x4EE5;&#x63D0;&#x793A; mixins&#xFF1A;</p>
 <img src="https://statres.quickapp.cn/quickapp/show/img/211022/scss-2.png" width="720px">
</li>
<li>
<p>&#x8F93;&#x5165; <code>&#x5C5E;&#x6027;&#x540D;: </code>(&#x8F93;&#x5165;&#x7A7A;&#x683C;&#x540E;&#x624D;&#x63D0;&#x793A;)&#xFF0C;&#x4F1A;&#x63D0;&#x793A;&#x51FD;&#x6570;&#xFF1A;</p>
  <img src="https://statres.quickapp.cn/quickapp/show/img/211022/scss-3.png" width="720px">
</li>
<li>
<p>hover &#x63D0;&#x793A;&#x548C;&#x5B9A;&#x4E49;&#x8DF3;&#x8F6C;&#xFF1A;&#x5982;&#x4E0B;&#x56FE;&#xFF0C;&#x652F;&#x6301;&#x53D8;&#x91CF;&#x3001;mixin&#x3001;&#x51FD;&#x6570;&#x7684; hover &#x63D0;&#x793A;&#xFF0C;&#x70B9;&#x51FB;&#x53EF;&#x4EE5;&#x8DF3;&#x8F6C;&#x5230;&#x5B9A;&#x4E49;&#x5904;</p>
  <img src="https://statres.quickapp.cn/quickapp/show/img/211022/scss-4.png" width="720px">
</li>
</ul>
</li>
</ul>
<ol start="2">
<li>less &#x8BED;&#x6CD5;&#x63D0;&#x793A;&#x4F18;&#x5316;:</li>
</ol>
<p>&#x9996;&#x5148;&#x9700;&#x8981;&#x5B89;&#x88C5;&#x63D2;&#x4EF6;: <code>Less IntelliSense</code>&#x3002;<br>
&#x4F18;&#x5316;&#x5185;&#x5BB9;&#xFF1A;</p>
<ul>
<li>&#x5728; scss &#x6587;&#x4EF6;&#x4E2D;&#xFF0C;&#x53EF;&#x4EE5;&#x63D0;&#x793A;&#x53D8;&#x91CF;/&#x6DF7;&#x5408;/&#x51FD;&#x6570;&#x3002;
<ul>
<li>
<p>&#x8F93;&#x5165;<code>&#x5C5E;&#x6027;&#x540D;: @</code>&#xFF08;&#x4F8B;&#x5982; color: @&#xFF09;&#xFF0C;&#x53EF;&#x4EE5;&#x63D0;&#x793A;&#x53D8;&#x91CF;&#xFF1A;</p>
  <img src="https://statres.quickapp.cn/quickapp/show/img/211022/less-1.png" width="720px">
</li>
<li>
<p>&#x8F93;&#x5165; <code>.</code> &#xFF0C;&#x53EF;&#x4EE5;&#x63D0;&#x793A; mixin &#x548C;&#x7C7B;&#xFF1A;<br>
<img src="https://statres.quickapp.cn/quickapp/show/img/211022/less-2.png" width="720px"></p>
</li>
<li>
<p>hover &#x63D0;&#x793A;&#x548C;&#x5B9A;&#x4E49;&#x8DF3;&#x8F6C;&#xFF1A;&#x5982;&#x4E0B;&#x56FE;&#xFF0C;&#x652F;&#x6301;&#x53D8;&#x91CF;&#x3001;mixin&#x7684; hover &#x63D0;&#x793A;&#xFF0C;&#x70B9;&#x51FB;&#x53EF;&#x4EE5;&#x8DF3;&#x8F6C;&#x5230;&#x5B9A;&#x4E49;&#x5904;<br>
<img src="https://statres.quickapp.cn/quickapp/show/img/211022/less-3.png" width="720px"></p>
</li>
</ul>
</li>
</ul>
<h4 id="%E7%89%88%E6%9C%AC%E5%8D%87%E7%BA%A7">&#x7248;&#x672C;&#x5347;&#x7EA7;</h4>
<p>&#x5347;&#x7EA7; Electron&#x3001;Node&#x3001;Chrome &#x7248;&#x672C;&#xFF0C;&#x63D0;&#x9AD8;&#x4E86;&#x7A33;&#x5B9A;&#x6027;&#x3002;</p>
<h3 id="%E4%BF%AE%E5%A4%8D">&#x4FEE;&#x590D;</h3>
<h4 id="%E6%A8%A1%E6%8B%9F%E5%99%A8-touch-%E6%A8%A1%E5%BC%8F%E5%88%87%E6%8D%A2%E9%97%AE%E9%A2%98">&#x6A21;&#x62DF;&#x5668; touch &#x6A21;&#x5F0F;&#x5207;&#x6362;&#x95EE;&#x9898;</h4>
<p>&#x4FEE;&#x590D;&#x6A21;&#x62DF;&#x5668;&#x79FB;&#x5165;&#x79FB;&#x51FA;&#x65F6; touch &#x6A21;&#x5F0F;&#x5207;&#x6362;&#x95EE;&#x9898;&#xFF0C;&#x73B0;&#x79FB;&#x51FA;&#x65F6;&#x65E0;&#x9700;&#x591A;&#x70B9;&#x4E00;&#x4E0B;&#x5373;&#x53EF;&#x5207;&#x6362;&#x6A21;&#x5F0F;&#x3002;</p>
<h4 id="%E5%A2%9E%E5%8A%A0%E8%87%AA%E5%AE%9A%E4%B9%89%E7%BB%84%E4%BB%B6%E5%92%8C%E5%BF%AB%E5%BA%94%E7%94%A8%E7%BB%84%E4%BB%B6%E5%86%B2%E7%AA%81%E7%9A%84%E6%A0%A1%E9%AA%8C">&#x589E;&#x52A0;&#x81EA;&#x5B9A;&#x4E49;&#x7EC4;&#x4EF6;&#x548C;&#x5FEB;&#x5E94;&#x7528;&#x7EC4;&#x4EF6;&#x51B2;&#x7A81;&#x7684;&#x6821;&#x9A8C;</h4>
<p>&#x589E;&#x52A0;&#x81EA;&#x5B9A;&#x4E49;&#x7EC4;&#x4EF6;&#x548C;&#x5FEB;&#x5E94;&#x7528;&#x7EC4;&#x4EF6;&#x51B2;&#x7A81;&#x7684;&#x6821;&#x9A8C;&#xFF1A;&#x5B9A;&#x4E49;&#x76F8;&#x540C;&#x540D;&#x5B57;&#x7684;&#x7EC4;&#x4EF6;&#x4F1A;&#x62A5;&#x9519;&#x3002;&#x5FEB;&#x5E94;&#x7528;&#x7EC4;&#x4EF6;&#x53EF;&#x67E5; <a href="https://doc.quickapp.cn/widgets/div.html">&#x6587;&#x6863;</a></p>
<img src="https://statres.quickapp.cn/quickapp/show/img/211022/custom-component.png" width="720px">
<h4 id="mac-%E6%96%B0%E5%BB%BA%E7%AA%97%E5%8F%A3%E9%97%AE%E9%A2%98">mac &#x65B0;&#x5EFA;&#x7A97;&#x53E3;&#x95EE;&#x9898;</h4>
<ol>
<li>&#x65B0;&#x5EFA;&#x9879;&#x76EE;&#x7A97;&#x53E3;&#x65E0;&#x6CD5;&#x4F7F;&#x7528;&#x590D;&#x5236;&#x3001;&#x7C98;&#x8D34;&#x3001;&#x526A;&#x5207;&#x3001;&#x5168;&#x9009;&#x5FEB;&#x6377;&#x952E;&#x95EE;&#x9898;</li>
<li>&#x65B0;&#x5EFA;&#x9879;&#x76EE;&#x8F93;&#x5165;&#x6846;&#x65E0;&#x6CD5;&#x9009;&#x4E2D;&#x95EE;&#x9898;</li>
</ol>
<h4 id="%E5%85%B6%E4%BB%96%E4%BF%AE%E5%A4%8D">&#x5176;&#x4ED6;&#x4FEE;&#x590D;</h4>
<ol>
<li>&#x767B;&#x5F55;&#x53EF;&#x56DE;&#x8F66;&#x786E;&#x5B9A;&#x3002;</li>
<li>&#x652F;&#x6301;&#x6837;&#x5F0F; alt-object-fit&#x3002;</li>
<li>&#x4FEE;&#x590D;&#x6837;&#x5F0F;&#x5C5E;&#x6027; hover &#x63D0;&#x793A;&#x5931;&#x6548;&#x95EE;&#x9898;&#x3002;</li>
</ol>
<h2 id="%E5%B1%95%E6%9C%9B%E6%9C%AA%E6%9D%A5">&#x5C55;&#x671B;&#x672A;&#x6765;</h2>
<p>&#x5728;&#x63A5;&#x4E0B;&#x6765;&#x7684;&#x65E5;&#x5B50;&#x91CC;&#xFF0C;&#x6211;&#x4EEC;&#x5C06;&#x518D;&#x63A5;&#x518D;&#x5389;&#xFF0C;&#x4F7F;&#x5F97; IDE &#x4F7F;&#x7528;&#x4F53;&#x9A8C;&#x518D;&#x5347;&#x4E00;&#x4E2A;&#x53F0;&#x9636;&#x3002;&#x672A;&#x6765;&#xFF0C;&#x56E2;&#x961F;&#x4ECD;&#x5C06;&#x6301;&#x7EED;&#x5173;&#x6CE8;<strong>&#x6027;&#x80FD;</strong>&#x3001;<strong>&#x7A33;&#x5B9A;&#x6027;</strong>&#x3001;<strong>&#x517C;&#x5BB9;&#x6027;</strong>&#xFF0C;&#x8FD9;&#x4E9B;&#x5BF9;&#x4E8E;&#x7528;&#x6237;&#x548C;&#x6211;&#x4EEC;&#xFF0C;&#x90FD;&#x81F3;&#x5173;&#x91CD;&#x8981;&#x7684;&#x57FA;&#x672C;&#x9762;&#xFF1B;&#x540C;&#x65F6;&#x5C06;&#x6295;&#x5165;&#x66F4;&#x591A;&#x7CBE;&#x529B;&#x4E8E; IDE <strong>&#x9884;&#x89C8;</strong>&#x3001;&#x9884;&#x68C0;&#x6D4B;&#xFF0C;&#x529B;&#x4E89;&#x505A;&#x5230;&#x9884;&#x89C8;&#x4E4B;&#x5448;&#x73B0;&#xFF0C;&#x5373;&#x771F;&#x673A;&#x6240;&#x663E;&#xFF08;&#x76F8;&#x4FE1;&#x5728;&#x4E0D;&#x4E45;&#x4E4B;&#x540E;&#xFF0C;&#x5C06;&#x6709;&#x5927;&#x7684;&#x6539;&#x5584;&#xFF09;&#xFF1B;&#x5BF9;&#x4E8E;&#x65B0;&#x529F;&#x80FD;&#xFF0C;&#x4F1A;&#x6301;&#x8C28;&#x614E;&#x6001;&#x5EA6;&#xFF0C;&#x8BA4;&#x771F;&#x7814;&#x7A76;&#xFF0C;&#x529B;&#x4E89;&#x6BCF;&#x4E00;&#x70B9;&#x52AA;&#x529B;&#xFF0C;&#x90FD;&#x80FD;&#x4E3A;&#x60A8;&#x5E26;&#x6765;&#x5E94;&#x6709;&#x4EF7;&#x503C;&#xFF1B;&#x6700;&#x540E;&#xFF0C;&#x6211;&#x4EEC;&#x5C06;&#x59CB;&#x7EC8;&#x503E;&#x542C;&#x7528;&#x6237;&#x7684;&#x58F0;&#x97F3;&#xFF0C;&#x5982;&#x679C;&#x60A8;&#x6709;&#x4EFB;&#x4F55;&#x5EFA;&#x8BAE;&#x6216;&#x610F;&#x89C1;&#xFF0C;&#x8BF7;&#x53CA;&#x65F6;&#x544A;&#x77E5;&#xFF0C;&#x5C06;&#x5C3D;&#x53EF;&#x80FD;&#x6EE1;&#x8DB3;&#x60A8;&#x3002;</p>
<p>&#x5982;&#x679C;&#x60A8;&#x8FD8;&#x6CA1;&#x6709;&#x5C1D;&#x8BD5;&#x8FC7;&#x5FEB;&#x5E94;&#x7528; IDE&#xFF0C;&#x8BF7;<a href="https://www.quickapp.cn/docCenter/IDEPublicity">&#x4E0B;&#x8F7D;</a>&#x4EE5;&#x53CA;&#x5C1D;&#x8BD5;&#x4F7F;&#x7528;&#x5B83;&#xFF0C;&#x5982;&#x679C;&#x60A8;&#x6709;&#x4EFB;&#x4F55;&#x60F3;&#x6CD5;&#xFF0C;&#x8BF7;&#x53CA;&#x65F6;&#x8BA9;&#x6211;&#x4EEC;&#x77E5;&#x6653;&#x3002;</p>
<p>&#x518D;&#x6B21;&#x8868;&#x793A;&#x611F;&#x8C22;&#xFF01;&#x6700;&#x540E;&#xFF0C;&#x613F;&#x6240;&#x6709;&#x4EBA;&#xFF0C;&#x90FD;&#x53EF;&#x4EE5;&#xFF1A;<strong>&#x5DE5;&#x4F5C;&#x5F00;&#x5FC3;&#x4E0D;&#x52A0;&#x73ED;&#xFF0C;&#x751F;&#x6D3B;&#x5FEB;&#x4E50;&#x65E0;&#x5FE7;&#x8651;</strong>&#x3002;</p>
<p>&#x2500;&#x2500; &#x6765;&#x81EA;<code>&#x5FEB;&#x5E94;&#x7528;&#x5DE5;&#x5177;&#x5F00;&#x53D1;&#x56E2;&#x961F;</code>&#xFF0C;&#x4E8E; 2021 &#x5E74; 10 &#x6708; 28 &#x65E5;&#x3002;</p>
<hr>
<p>2021 &#x5E74; IDE &#x7248;&#x672C;&#x66F4;&#x65B0;&#x65F6;&#x95F4;&#x7EBF;&#xFF1A;</p>
<ul>
<li>10.28 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v5-1-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 5.1 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>9.2 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v5-0-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 5.0 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>7.26 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v4-1-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 4.1 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>6.30 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v4-0-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 4.0 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>5.27 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-10-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.10 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>4.13 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-9-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.9 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>3.11 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-8-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.8 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>2.4 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-7-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.7 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
</ul>
<p>2020 &#x5E74; IDE &#x7248;&#x672C;&#x66F4;&#x65B0;&#x65F6;&#x95F4;&#x7EBF;&#xFF1A;</p>
<ul>
<li>12.29 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-6-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.6 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>12.01 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-5-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.5 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>10.26 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-4-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.4 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>08.18 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-3-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.3 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>07.29 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-2-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.2 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>07.06 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-1-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.1 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>06.01 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.0 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[快应用 v1100 产品核心能力介绍]]></title><description><![CDATA[快应用是基于手机硬件平台的新型应用形态，标准是由主流手机厂商组成的快应用联盟联合制定。其标准的诞生将在研发接口、能力接入、开发者服务等层面建设标准平台，以平台化的生态模式对个人开发者和企业开发者全品类开放。]]></description><link>https://quickapp.vivo.com.cn/quickapp-v1100-core-function-introduction/</link><guid isPermaLink="false">63c4b94a77e2ca0006a8c89e</guid><category><![CDATA[快应用]]></category><dc:creator><![CDATA[vivo-developer]]></dc:creator><pubDate>Thu, 21 Oct 2021 02:10:21 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>&#x7ECF;&#x8FC7;&#x534A;&#x5E74;&#x591A;&#x7684;&#x8270;&#x82E6;&#x5F00;&#x53D1;&#xFF0C;<a href="https://nicelinks.site/post/5b5fb5bc615bf842b609105f">&#x5FEB;&#x5E94;&#x7528;</a> 1100 &#x9884;&#x89C8;&#x7248;&#x7EC8;&#x4E8E;&#x8981;&#x548C;&#x5927;&#x5BB6;&#x89C1;&#x9762;&#x4E86;&#x3002;&#x4E3A;&#x4E86;&#x5E2E;&#x52A9;&#x5E7F;&#x5927;&#x5F00;&#x53D1;&#x8005;&#x5F00;&#x53D1;&#x51FA;&#x8FD0;&#x884C;&#x9AD8;&#x6548;&#x3001;&#x529F;&#x80FD;&#x4E30;&#x5BCC;&#x7684;<a href="https://nicelinks.site/post/5b5fb5bc615bf842b609105f">&#x5FEB;&#x5E94;&#x7528;</a>&#xFF0C;&#x5FEB;&#x5E94;&#x7528;&#x6846;&#x67B6;&#x56E2;&#x961F;&#x53EF;&#x8C13;&#x5FEB;&#x9A6C;&#x52A0;&#x97AD;&#x3001;&#x65E5;&#x591C;&#x517C;&#x7A0B;&#x3002;&#x8BA9;&#x6211;&#x4EEC;&#x4E00;&#x8D77;&#x6765;&#x770B;&#x770B;&#x5728; 1100 &#x7248;&#x672C;&#xFF0C;&#x5FEB;&#x5E94;&#x7528;&#x5F15;&#x64CE;&#x65B0;&#x589E;&#x54EA;&#x4E9B;&#x65B0;&#x529F;&#x80FD;&#x5427;&#x3002;</p>
<h2 id="1-lottie-%E7%BB%84%E4%BB%B6"><strong>1. lottie &#x7EC4;&#x4EF6;</strong></h2>
<p>lottie &#x662F; Airbnb &#x63A8;&#x51FA;&#x7684;&#x4E00;&#x6B3E;&#x9AD8;&#x8D28;&#x91CF;&#x52A8;&#x753B;&#x5E93;&#xFF0C;&#x901A;&#x8FC7;&#x5F15;&#x7528; Adobe After Effects &#x7684; Bodymovin &#x63D2;&#x4EF6;&#x5BFC;&#x51FA;&#x7684; .json &#x52A8;&#x753B;&#x6587;&#x4EF6;&#x7ED8;&#x5236;&#x52A8;&#x753B;&#xFF0C;&#x5177;&#x6709;&#x4F7F;&#x7528;&#x65B9;&#x4FBF;&#x3001;&#x6D41;&#x7545;&#x5EA6;&#x9AD8;&#x3001;&#x5185;&#x5B58;&#x5360;&#x7528;&#x5C11;&#x3001;&#x7ED8;&#x5236;&#x9AD8;&#x6548;&#x7684;&#x4F18;&#x70B9;&#x3002;&#x53EF;&#x5728; lottie &#x5B98;&#x7F51;&#x4E86;&#x89E3;&#x66F4;&#x591A;&#x5177;&#x4F53;&#x5185;&#x5BB9;&#x3002;</p>
<p>&#x5FEB;&#x5E94;&#x7528;&#x5F15;&#x64CE;&#x4ECE; 1100 &#x7248;&#x672C;&#x5F00;&#x59CB;&#x63D0;&#x4F9B; lottie &#x52A8;&#x753B;&#x7EC4;&#x4EF6;&#x652F;&#x6301;&#x3002;&#x5F00;&#x53D1;&#x8005;&#x53EF;&#x914D;&#x7F6E; lottie &#x52A8;&#x753B;&#x7684; .json &#x6E90;&#x6587;&#x4EF6;&#xFF0C;&#x5E76;&#x901A;&#x8FC7;&#x5F15;&#x64CE;&#x63D0;&#x4F9B;&#x7684; API &#x5B9E;&#x73B0;&#x52A8;&#x753B;&#x7684;&#x64AD;&#x653E;&#x3001;&#x6682;&#x505C;&#x7B49;&#x64CD;&#x4F5C;&#x3002;</p>
<p><img src="https://zhanstatic.vivo.com.cn/wukong/img/809864b5-703d-400a-b2b7-96aa7cd9bdee.gif" alt="&#x5FEB;&#x5E94;&#x7528; - lottie &#x7EC4;&#x4EF6;" loading="lazy"></p>
<p><strong>&#x2192;&#x2192;</strong><a href="https://doc.quickapp.cn/widgets/lottie.html"><strong>&#x70B9;&#x51FB;&#x67E5;&#x770B;&#x8BE6;&#x7EC6;&#x914D;&#x7F6E;</strong></a> &#x2190;&#x2190;</p>
<h2 id="2-richtext-%E7%BB%84%E4%BB%B6%E6%94%AF%E6%8C%81%E5%9B%BE%E4%B9%A6%E7%BF%BB%E9%A1%B5%E8%83%BD%E5%8A%9B"><strong>2. richtext &#x7EC4;&#x4EF6;&#x652F;&#x6301;&#x56FE;&#x4E66;&#x7FFB;&#x9875;&#x80FD;&#x529B;</strong></h2>
<p>rechtext &#x7EC4;&#x4EF6;&#x65B0;&#x589E; scene &#x5C5E;&#x6027;&#xFF0C;scene &#x53D6;&#x503C;&#x201C;book&#x201D;&#x65F6;&#xFF0C;&#x53EF;&#x5B9E;&#x73B0;&#x56FE;&#x6587;&#x7FFB;&#x9875;&#x6548;&#x679C;&#x3002;&#x901A;&#x8FC7; addContent &#x65B9;&#x6CD5;&#x6DFB;&#x52A0;&#x9875;&#x9762;&#x8981;&#x52A0;&#x8F7D;&#x7684;&#x5185;&#x5BB9;&#xFF0C;&#x9875;&#x9762;&#x7FFB;&#x9875;&#x540E;&#x901A;&#x8FC7; pagechanged &#x65B9;&#x6CD5;&#x8FD4;&#x56DE;&#x5F53;&#x524D;&#x9875;&#x6570;&#x548C;&#x603B;&#x9875;&#x6570;&#xFF0C;&#x52A0;&#x8F7D;&#x5185;&#x5BB9;&#x5B8C;&#x6210;&#x540E;&#x901A;&#x8FC7; splitpage &#x65B9;&#x6CD5;&#x8FD4;&#x56DE;&#x603B;&#x9875;&#x6570;&#x3002;&#x901A;&#x8FC7;&#x65B0;&#x589E;&#x7684;&#x5C5E;&#x6027;&#x548C;&#x65B9;&#x6CD5;&#xFF0C;&#x53EF;&#x4EE5;&#x5B9E;&#x73B0;&#x56FE;&#x6587;&#x5DE6;&#x53F3;&#x7FFB;&#x9875;&#x7684;&#x80FD;&#x529B;&#x3002;</p>
<p><img src="https://bbs.quickapp.cn/data/ueditor/image/20211013/1634114877247685.png" alt="&#x5FEB;&#x5E94;&#x7528; - richtext &#x7EC4;&#x4EF6;&#x652F;&#x6301;&#x56FE;&#x4E66;&#x7FFB;&#x9875;&#x80FD;&#x529B;" title="1634114877247685.png" loading="lazy"></p>
<p><strong>&#x2192;&#x2192; <strong><a href="https://doc.quickapp.cn/widgets/richtext.html?h=%E5%9B%BE%E6%96%87"><strong>&#x70B9;&#x51FB;&#x67E5;&#x770B;&#x8BE6;&#x7EC6;&#x914D;&#x7F6E;</strong></a></strong> &#x2190;&#x2190;</strong></p>
<h2 id="3-text-%E6%94%AF%E6%8C%81-image-%E5%AD%90%E7%BB%84%E4%BB%B6%EF%BC%8C%E4%BB%A5%E6%94%AF%E6%8C%81%E5%9B%BE%E6%96%87%E6%B7%B7%E6%8E%92"><strong>3. text &#x652F;&#x6301; image &#x5B50;&#x7EC4;&#x4EF6;&#xFF0C;&#x4EE5;&#x652F;&#x6301;&#x56FE;&#x6587;&#x6DF7;&#x6392;</strong></h2>
<p>&#x6587;&#x672C;&#x663E;&#x793A;&#x7EC4;&#x4EF6;&#x589E;&#x52A0;&#x652F;&#x6301; image &#x4F5C;&#x4E3A;&#x5B50;&#x7EC4;&#x4EF6;&#xFF0C;&#x65B9;&#x4FBF;&#x5F00;&#x53D1;&#x8005;&#x5B9E;&#x73B0;&#x6587;&#x5B57;&#x4E0E;&#x8868;&#x60C5;&#x56FE;&#x7247;&#x6DF7;&#x6392;&#x7684;&#x663E;&#x793A;&#x6548;&#x679C;&#xFF0C;&#x589E;&#x5F3A;&#x6587;&#x672C;&#x7EC4;&#x4EF6;&#x7684;&#x8868;&#x73B0;&#x80FD;&#x529B;&#x3002;</p>
<p><img src="https://bbs.quickapp.cn/data/ueditor/image/20211013/1634114892877113.png" alt="&#x5FEB;&#x5E94;&#x7528; - text &#x652F;&#x6301; image &#x5B50;&#x7EC4;&#x4EF6;&#xFF0C;&#x4EE5;&#x652F;&#x6301;&#x56FE;&#x6587;&#x6DF7;&#x6392;" title="1634114892877113.png" loading="lazy"></p>
<p><strong>&#x2192;&#x2192; <strong><a href="https://doc.quickapp.cn/widgets/image.html#%E4%BD%9C%E4%B8%BAtext%E3%80%81span%E3%80%81a%E7%9A%84%E5%AD%90%E7%BB%84%E4%BB%B6%E4%BD%BF%E7%94%A8-1100">&#x70B9;&#x51FB;&#x67E5;&#x770B;&#x8BE6;&#x7EC6;&#x914D;&#x7F6E;</a></strong> &#x2190;&#x2190;</strong></p>
<h2 id="4-%E7%81%B0%E8%89%B2%E6%A8%A1%E5%BC%8F"><strong>4. &#x7070;&#x8272;&#x6A21;&#x5F0F;</strong></h2>
<p>&#x589E;&#x52A0;&#x5F15;&#x64CE;&#x7EA7;&#x522B;&#x5C06;&#x9875;&#x9762;&#x7F6E;&#x7070;&#x7684;&#x80FD;&#x529B;&#xFF0C;&#x652F;&#x6301;&#x52A8;&#x6001;&#x548C;&#x9759;&#x6001;&#x4E24;&#x79CD;&#x914D;&#x7F6E;&#x65B9;&#x5F0F;&#xFF0C;&#x63D0;&#x5347;&#x5E94;&#x7528;&#x54CD;&#x5E94;&#x7D27;&#x6025;&#x4E8B;&#x4EF6;&#x7684;&#x901F;&#x5EA6;&#x3002;</p>
<p><img src="https://bbs.quickapp.cn/data/ueditor/image/20211013/1634114902567094.png" alt="&#x5FEB;&#x5E94;&#x7528; - &#x7070;&#x8272;&#x6A21;&#x5F0F;" title="1634114902567094.png" loading="lazy"></p>
<p><strong>&#x2192;&#x2192; <strong><a href="https://doc.quickapp.cn/framework/manifest.html#config">&#x70B9;&#x51FB;&#x67E5;&#x770B;&#x8BE6;&#x7EC6;&#x914D;&#x7F6E;</a></strong> &#x2190;&#x2190;</strong></p>
<h2 id="5-%E6%96%B0%E5%A2%9E-sharebutton-%E5%88%86%E4%BA%AB%E6%8C%89%E9%92%AE%E7%BB%84%E4%BB%B6"><strong>5. &#x65B0;&#x589E; sharebutton &#x5206;&#x4EAB;&#x6309;&#x94AE;&#x7EC4;&#x4EF6;</strong></h2>
<p>&#x65B0;&#x589E;&#x52A0; share-button &#x7EC4;&#x4EF6;&#xFF0C;&#x63D0;&#x4F9B;&#x4E86;&#x7EC4;&#x4EF6;&#x5316;&#x7684;&#x5E94;&#x7528;&#x5206;&#x4EAB;&#x80FD;&#x529B;&#xFF0C;&#x4E30;&#x5BCC;&#x4E86;&#x5F00;&#x53D1;&#x8005;&#x7684;&#x8FD0;&#x8425;&#x624B;&#x6BB5;&#x3002;</p>
<p><img src="https://bbs.quickapp.cn/data/ueditor/image/20211013/1634114909889797.png" alt="&#x5FEB;&#x5E94;&#x7528; - &#x65B0;&#x589E; sharebutton &#x5206;&#x4EAB;&#x6309;&#x94AE;&#x7EC4;&#x4EF6;" title="1634114909889797.png" loading="lazy"></p>
<p><strong>&#x2192;&#x2192; <strong><a href="https://doc.quickapp.cn/widgets/share-button.html">&#x70B9;&#x51FB;&#x67E5;&#x770B;&#x8BE6;&#x7EC6;&#x914D;&#x7F6E;</a></strong> &#x2190;&#x2190;</strong></p>
<h2 id="6-%E7%BB%84%E4%BB%B6%E6%96%B0%E5%A2%9E-overflow-%E5%85%AC%E5%85%B1%E5%B1%9E%E6%80%A7"><strong>6. &#x7EC4;&#x4EF6;&#x65B0;&#x589E; overflow &#x516C;&#x5171;&#x5C5E;&#x6027;</strong></h2>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x5B50;&#x7EC4;&#x4EF6;&#x7684;&#x663E;&#x793A;&#x533A;&#x57DF;&#x4E0D;&#x80FD;&#x8D85;&#x8FC7;&#x7236;&#x7EC4;&#x4EF6;&#x3002;&#x5982;&#x679C;&#x5B50;&#x7EC4;&#x4EF6;&#x7684;&#x5927;&#x5C0F;&#x8D85;&#x8FC7;&#x7236;&#x7EC4;&#x4EF6;&#xFF0C;&#x8D85;&#x51FA;&#x90E8;&#x5206;&#x5C06;&#x4F1A;&#x88AB;&#x7236;&#x7EC4;&#x4EF6;&#x88C1;&#x51CF;&#x6389;&#x3002;&#x901A;&#x8FC7;&#x5C06;&#x5B50;&#x7EC4;&#x4EF6;&#x7684; overflow &#x5C5E;&#x6027;&#x8BBE;&#x7F6E;&#x6210; visible&#xFF0C;&#x5B50;&#x7EC4;&#x4EF6;&#x5C06;&#x53EF;&#x4EE5;&#x8D8A;&#x8FC7;&#x7236;&#x7EC4;&#x4EF6;&#xFF0C;&#x5728;&#x7236;&#x7EC4;&#x4EF6;&#x8FB9;&#x754C;&#x5916;&#x7ED8;&#x5236;&#x3002;</p>
<p><img src="https://bbs.quickapp.cn/data/ueditor/image/20211013/1634114920768812.png" alt="&#x5FEB;&#x5E94;&#x7528; - &#x7EC4;&#x4EF6;&#x65B0;&#x589E; overflow &#x516C;&#x5171;&#x5C5E;&#x6027;" title="1634114920768812.png" loading="lazy"></p>
<p><strong>&#x2192;&#x2192; <strong><a href="https://doc.quickapp.cn/widgets/common-attributes.html?h=overflow">&#x70B9;&#x51FB;&#x67E5;&#x770B;&#x8BE6;&#x7EC6;&#x914D;&#x7F6E;</a></strong> &#x2190;&#x2190;</strong></p>
<h2 id="7-%E6%9B%B4%E5%8F%AF%E6%8E%A7%E7%9A%84%E8%AF%B7%E6%B1%82%E7%B1%BB%E6%8E%A5%E5%8F%A3"><strong>7. &#x66F4;&#x53EF;&#x63A7;&#x7684;&#x8BF7;&#x6C42;&#x7C7B;&#x63A5;&#x53E3;</strong></h2>
<p>&#x65B0;&#x589E;&#xFF1A;</p>
<p>&#x2022; downloadtask &#x63A5;&#x53E3;&#xFF0C;&#x652F;&#x6301; header &#x76D1;&#x542C;&#x3001;&#x8FDB;&#x5EA6;&#x901A;&#x77E5;&#x53CA; abort &#x80FD;&#x529B; <strong>&#x2192;&#x2192;</strong><a href="https://doc.quickapp.cn/features/system/downloadtask.html"><strong>&#x70B9;&#x51FB;&#x67E5;&#x770B;&#x8BE6;&#x7EC6;&#x914D;&#x7F6E;</strong></a></p>
<p>&#x2022; uploadtask &#x63A5;&#x53E3;&#xFF0C;&#x652F;&#x6301; header &#x76D1;&#x542C;&#x3001;&#x8FDB;&#x5EA6;&#x901A;&#x77E5;&#x53CA; abort &#x80FD;&#x529B; <strong>&#x2192;&#x2192;</strong><a href="https://doc.quickapp.cn/features/system/uploadtask.html"><strong>&#x70B9;&#x51FB;&#x67E5;&#x770B;&#x8BE6;&#x7EC6;&#x914D;&#x7F6E;</strong></a></p>
<p>&#x2022; requesttask &#x63A5;&#x53E3;&#xFF0C;&#x652F;&#x6301; header &#x76D1;&#x542C;&#x53CA; abort &#x80FD;&#x529B; <strong>&#x2192;&#x2192;</strong><a href="https://doc.quickapp.cn/features/system/requesttask.html"><strong>&#x70B9;&#x51FB;&#x67E5;&#x770B;&#x8BE6;&#x7EC6;&#x914D;&#x7F6E;</strong></a></p>
<h2 id="8-%E6%94%AF%E6%8C%81%E4%BD%BF%E7%94%A8%E7%B3%BB%E7%BB%9F-nfc-%E5%8A%9F%E8%83%BD%E8%AF%BB%E5%86%99-nfc-%E6%A0%87%E7%AD%BE"><strong>8. &#x652F;&#x6301;&#x4F7F;&#x7528;&#x7CFB;&#x7EDF; NFC &#x529F;&#x80FD;&#x8BFB;&#x5199; NFC &#x6807;&#x7B7E;</strong></h2>
<p>&#x5B9E;&#x73B0; NFC &#x7684;&#x76F8;&#x5173;&#x529F;&#x80FD;&#xFF0C;&#x5373;&#x624B;&#x673A;&#x4F5C;&#x4E3A;&#x8BFB;&#x5361;&#x5668;&#x4F7F;&#x7528;&#xFF0C;&#x7528;&#x4E8E;&#x8BFB;&#x5199; Ndef&#x3001;NfcA &#x7B49;&#x5404;&#x7C7B;&#x578B;&#x7684; NFC &#x5361;&#x3002;</p>
<p><strong>&#x2192;&#x2192; <a href="https://doc.quickapp.cn/features/system/nfc.html">&#x70B9;&#x51FB;&#x67E5;&#x770B;&#x8BE6;&#x7EC6;&#x914D;&#x7F6E;</a>&#x2190;&#x2190;</strong></p>
<h2 id="9-%E7%9C%9F%E6%9C%BA%E6%94%AF%E6%8C%81%E6%80%A7%E8%83%BD%E9%9D%A2%E6%9D%BF%E6%9F%A5%E7%9C%8B"><strong>9. &#x771F;&#x673A;&#x652F;&#x6301;&#x6027;&#x80FD;&#x9762;&#x677F;&#x67E5;&#x770B;</strong></h2>
<p>&#x6027;&#x80FD;&#x9762;&#x677F;&#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x4E9B;&#x5DE5;&#x5177;&#xFF0C;&#x8BA9;&#x5F00;&#x53D1;&#x8005;&#x80FD;&#x591F;&#x66F4;&#x597D;&#x5730;&#x4E86;&#x89E3;&#x5FEB;&#x5E94;&#x7528;&#x7684;&#x6027;&#x80FD;&#xFF0C;&#x52A9;&#x529B;&#x5F00;&#x53D1;&#x51FA;&#x66F4;&#x9AD8;&#x8D28;&#x91CF;&#x7684;&#x5FEB;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x3002;&#x8FD9;&#x4E9B;&#x5DE5;&#x5177;&#x5305;&#x62EC;&#xFF1A;&#x5B9E;&#x65F6;&#x6027;&#x80FD;&#x6307;&#x6807;&#x5C55;&#x793A;&#x3001;&#x544A;&#x8B66;&#x63D0;&#x793A;&#x3001;3D &#x89C6;&#x56FE;&#x3001;&#x5143;&#x7D20;&#x5BA1;&#x67E5;&#x3001;&#x65E5;&#x5FD7;&#x548C;&#x7F51;&#x7EDC;&#x9762;&#x677F;&#x7B49;&#x3002;</p>
<p><img src="https://bbs.quickapp.cn/data/ueditor/image/20211013/1634114947851148.png" alt="&#x5FEB;&#x5E94;&#x7528; - &#x771F;&#x673A;&#x652F;&#x6301;&#x6027;&#x80FD;&#x9762;&#x677F;&#x67E5;&#x770B;" title="1634114947851148.png" loading="lazy"></p>
<p><strong>&#x2192;&#x2192;<a href="https://doc.quickapp.cn/tutorial/framework/analyzer-panel.html?h=%E6%80%A7%E8%83%BD%E9%9D%A2%E6%9D%BF">&#x70B9;&#x51FB;&#x67E5;&#x770B;&#x8BE6;&#x7EC6;&#x914D;&#x7F6E;</a>&#x2190;&#x2190;</strong></p>
<h2 id="10-%E8%B0%83%E8%AF%95%E5%99%A8%E6%94%B9%E7%89%88"><strong>10. &#x8C03;&#x8BD5;&#x5668;&#x6539;&#x7248;</strong></h2>
<p>1100 &#x8C03;&#x8BD5;&#x5668;&#x8FDB;&#x884C;&#x4E86;&#x5168;&#x65B0;&#x6539;&#x7248;&#xFF0C;&#x754C;&#x9762;&#x66F4;&#x52A0;&#x7F8E;&#x89C2;&#x5927;&#x65B9;&#x3002;&#x9664;&#x4E86; UI &#x548C;&#x4EA4;&#x4E92;&#x7684;&#x8C03;&#x6574;&#xFF0C;&#x8FD8;&#x589E;&#x52A0;&#x4E86;&#x5FEB;&#x5E94;&#x7528;&#x5361;&#x7247;&#x6A21;&#x5F0F;&#x7684;&#x8C03;&#x8BD5;&#x652F;&#x6301;&#xFF0C;&#x5E76;&#x4E14;&#x96C6;&#x6210;&#x6027;&#x80FD;&#x9762;&#x677F;&#x3001;&#x95EE;&#x9898;&#x53CD;&#x9988;&#x3001;&#x4F7F;&#x7528;&#x8BF4;&#x660E;&#x7B49;&#x7248;&#x5757;&#xFF0C;&#x529F;&#x80FD;&#x66F4;&#x52A0;&#x4E30;&#x5BCC;&#x5B8C;&#x5584;&#xFF0C;&#x52A9;&#x529B;&#x5F00;&#x53D1;&#x8005;&#x66F4;&#x4FBF;&#x6377;&#x9AD8;&#x6548;&#x5730;&#x5F00;&#x53D1;&#x3002;</p>
<p><img src="https://bbs.quickapp.cn/data/ueditor/image/20211013/1634116521802793.png" alt="&#x5FEB;&#x5E94;&#x7528; - &#x8C03;&#x8BD5;&#x5668;&#x6539;&#x7248;" title="1634116521802793.png" loading="lazy"></p>
<p><strong>&#x2192;&#x2192;<a href="https://www.quickapp.cn/docCenter/post/69">&#x70B9;&#x51FB;&#x4E0B;&#x8F7D;&#x5C1D;&#x9C9C;</a> &#x2190;&#x2190;</strong></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[快应用如何增强语法检查能力]]></title><description><![CDATA[虽然在快应用开发工具里，已经集成了语法提示、自动补全等能力，但如果您想对项目的代码进行进一步校验，给代码定义一个规范，必须按照这个规范进行代码的编写，可以通过使用 eslint，并结合 husky、lint-staged 插件来增强语法检查。]]></description><link>https://quickapp.vivo.com.cn/how-to-use-eslint-in-quickapp-development/</link><guid isPermaLink="false">63c4b94a77e2ca0006a8c89a</guid><category><![CDATA[快应用开发工具]]></category><dc:creator><![CDATA[chenjiangfeng]]></dc:creator><pubDate>Fri, 15 Oct 2021 11:16:40 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><h2 id="%E5%89%8D%E8%A8%80">&#x524D;&#x8A00;</h2>
<p>&#x867D;&#x7136;&#x5728;<a href="https://www.quickapp.cn/docCenter/IDEPublicity">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177;</a>&#x91CC;&#xFF0C;&#x5DF2;&#x7ECF;&#x96C6;&#x6210;&#x4E86;&#x8BED;&#x6CD5;&#x63D0;&#x793A;&#x3001;&#x81EA;&#x52A8;&#x8865;&#x5168;&#x7B49;&#x80FD;&#x529B;&#xFF0C;&#x4F46;&#x5982;&#x679C;&#x60A8;&#x60F3;&#x5BF9;&#x9879;&#x76EE;&#x7684;&#x4EE3;&#x7801;&#x8FDB;&#x884C;&#x8FDB;&#x4E00;&#x6B65;&#x6821;&#x9A8C;&#xFF0C;&#x7ED9;&#x4EE3;&#x7801;&#x5B9A;&#x4E49;&#x4E00;&#x4E2A;&#x89C4;&#x8303;&#xFF0C;&#x5FC5;&#x987B;&#x6309;&#x7167;&#x8FD9;&#x4E2A;&#x89C4;&#x8303;&#x8FDB;&#x884C;&#x4EE3;&#x7801;&#x7684;&#x7F16;&#x5199;&#xFF0C;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x4F7F;&#x7528; eslint&#xFF0C;&#x5E76;&#x7ED3;&#x5408; husky&#x3001;lint-staged &#x63D2;&#x4EF6;&#x6765;&#x589E;&#x5F3A;&#x8BED;&#x6CD5;&#x68C0;&#x67E5;&#x3002;</p>
<h2 id="%E4%BD%BF%E7%94%A8-eslint">&#x4F7F;&#x7528; eslint</h2>
<h3 id="%E5%AE%89%E8%A3%85%E4%BE%9D%E8%B5%96">&#x5B89;&#x88C5;&#x4F9D;&#x8D56;</h3>
<p>&#x9700;&#x8981;&#x5168;&#x5C40;&#x5B89;&#x88C5; eslint &#x6216;&#x8005;&#x53EA;&#x5728;&#x5F53;&#x524D;&#x9879;&#x76EE;&#x4E0B;&#x5B89;&#x88C5; eslint</p>
<pre><code class="language-shell">npm i eslint -g
</code></pre>
<p>&#x6216;</p>
<pre><code class="language-shell">npm i eslint --save-dev
</code></pre>
<p>&#x7531;&#x4E8E;&#x4F1A;&#x7528;&#x5230; <code>eslint-plugin-vue</code> &#x7684;&#x80FD;&#x529B;&#xFF0C;&#x6240;&#x4EE5;&#x6211;&#x4EEC;&#x4E5F;&#x8981;&#x5728;&#x9879;&#x76EE;&#x4E0B;&#x5B89;&#x88C5; <code>eslint-plugin-vue</code> &#x4F9D;&#x8D56;&#xFF1A;</p>
<pre><code class="language-shell">npm i eslint-plugin-vue --save-dev
</code></pre>
<h3 id="%E6%96%B0%E5%BB%BA-eslint-%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6">&#x65B0;&#x5EFA; eslint &#x914D;&#x7F6E;&#x6587;&#x4EF6;</h3>
<p>&#x5728;&#x9879;&#x76EE;&#x6839;&#x76EE;&#x5F55;&#x4E0B;&#xFF0C;&#x65B0;&#x5EFA; .eslintrc &#x6587;&#x4EF6;&#xFF0C;&#x5E76;&#x7F16;&#x5199;&#x914D;&#x7F6E;&#xFF0C;&#x4E0B;&#x9762;&#x4E3A;&#x7B80;&#x5355;&#x7684;&#x914D;&#x7F6E;&#x9879;&#xFF0C;&#x82E5;&#x9879;&#x76EE;&#x4E2D;&#x6709;&#x989D;&#x5916;&#x7684;&#x8981;&#x6C42;&#xFF0C;&#x53EF;&#x6839;&#x636E; vue &#x7684;<a href="https://eslint.vuejs.org/user-guide/#usage">&#x89C4;&#x5219;</a>&#x81EA;&#x5DF1;&#x989D;&#x5916;&#x914D;&#x7F6E;&#x3002;</p>
<pre><code class="language-json">{
  &quot;env&quot;: {
    &quot;commonjs&quot;: true,
    &quot;node&quot;: true,
    &quot;es6&quot;: true
  },
  &quot;extends&quot;: [
    &quot;eslint:recommended&quot;,
    &quot;plugin:vue/base&quot;
  ],
  &quot;globals&quot;: {
    &quot;loadData&quot;: false,
    &quot;saveData&quot;: false,
    &quot;history&quot;: false,
    &quot;console&quot;: true,
    &quot;setTimeout&quot;: false,
    &quot;clearTimeout&quot;: false,
    &quot;setInterval&quot;: false,
    &quot;clearInterval&quot;: false,
    &quot;TextDecoder&quot;: true,
    &quot;$utils&quot;: true
  },
  &quot;rules&quot;: {
    &quot;vue/html-end-tags&quot;: &quot;warn&quot;,
    &quot;vue/html-quotes&quot;: &quot;warn&quot;,
    &quot;vue/comment-directive&quot;: &quot;off&quot;,
    &quot;no-unused-vars&quot;: [
      &quot;warn&quot;,
      {
        &quot;varsIgnorePattern&quot;: &quot;prompt&quot;
      }
    ],
    &quot;quotes&quot;: [
      &quot;warn&quot;,
      &quot;single&quot;,
      {
        &quot;avoidEscape&quot;: true,
        &quot;allowTemplateLiterals&quot;: true
      }
    ],
    &quot;linebreak-style&quot;: [&quot;warn&quot;, &quot;unix&quot;],
    &quot;semi&quot;: [1, &quot;never&quot;]
  }
}
</code></pre>
<p><strong>&#x6CE8;&#x610F;&#xFF1A;</strong> &#x914D;&#x7F6E;&#x4E2D;&#x9700;&#x8981;&#x5173;&#x95ED; <code>vue/commet/directive</code>&#x3002;</p>
<h3 id="%E5%A2%9E%E5%8A%A0-script-%E8%84%9A%E6%9C%AC%E5%91%BD%E4%BB%A4">&#x589E;&#x52A0; script &#x811A;&#x672C;&#x547D;&#x4EE4;</h3>
<pre><code class="language-json">&quot;scripts&quot;: {
    &quot;lint&quot;: &quot;eslint &apos;src/**/*.ux&apos;&quot;
}
</code></pre>
<p>&#x5728;&#x7EC8;&#x7AEF;&#x8FD0;&#x884C; <code>npm run lint</code>&#xFF0C;&#x5373;&#x53EF;&#x7528; eslint &#x5BF9; src &#x4E0B;&#x6240;&#x6709;&#x7684; ux &#x6587;&#x4EF6;&#x8FDB;&#x884C;&#x8BED;&#x6CD5;&#x68C0;&#x67E5;&#x3002;</p>
<h2 id="%E4%BD%BF%E7%94%A8-husky%E3%80%81lint-staged-%E6%8F%92%E4%BB%B6">&#x4F7F;&#x7528; husky&#x3001;lint-staged &#x63D2;&#x4EF6;</h2>
<h3 id="%E5%AE%89%E8%A3%85">&#x5B89;&#x88C5;</h3>
<p>&#x6267;&#x884C;&#x4E0B;&#x9762;&#x547D;&#x4EE4;</p>
<pre><code class="language-shell">npm i husky lint-staged --save-dev
</code></pre>
<h3 id="husky">husky</h3>
<p>&#x5728;&#x6210;&#x529F;&#x5B89;&#x88C5;&#x4E4B;&#x540E;&#xFF0C;&#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x5728; <code>git commit</code> &#x7684;&#x65F6;&#x5019;&#x89E6;&#x53D1; <code>pre-commit</code> &#x94A9;&#x5B50;&#x4ECE;&#x800C;&#x89E6;&#x53D1;&#x5230; husky&#xFF0C;&#x6211;&#x4EEC;&#x5728; <code>package.json</code> &#x6587;&#x4EF6;&#x4E2D;&#x914D;&#x7F6E; husky &#x7684;&#x94A9;&#x5B50;&#x9700;&#x8981;&#x6267;&#x884C;&#x7684;&#x547D;&#x4EE4;&#x6216;&#x64CD;&#x4F5C;&#x3002;</p>
<pre><code class="language-json">&quot;husky&quot;: {
    &quot;hooks&quot;: {
      &quot;pre-commit&quot;: &quot;yarn run precommit-msg &amp;&amp; lint-staged&quot;
    }
}
</code></pre>
<p>&#x8FD9;&#x6837;&#xFF0C;&#x6211;&#x4EEC;&#x5728; <code>git commit</code> &#x7684;&#x65F6;&#x5019;&#x5C31;&#x4F1A;&#x770B;&#x5230; <code>pre-commit</code> &#x6267;&#x884C;&#x4E86;&#x3002;</p>
<p><img src="https://zhanstatic.vivo.com.cn/wukong/img/23945cdb-8c01-46d6-a14d-956eeebf1747.jpg" alt="husky" loading="lazy"></p>
<p>&#x6CE8;&#x610F;&#xFF1A;&#x65B0;&#x7248;&#x672C;&#x7684; husky &#x53EF;&#x80FD;&#x65E0;&#x6CD5;&#x751F;&#x6548;&#xFF0C;&#x964D;&#x4F4E; husky &#x7248;&#x672C;&#x5373;&#x53EF;&#xFF0C;&#x672C;&#x6587;&#x91C7;&#x7528;&#x7684;&#x662F; <code>husky@4.3.8</code> &#x7248;&#x672C;</p>
<h3 id="lint-staged">lint-staged</h3>
<p>lint-staged &#x662F;&#x4E00;&#x4E2A;&#x5728; git &#x6682;&#x5B58;&#x6587;&#x4EF6;&#x4E0A;&#xFF08;&#x4E5F;&#x5C31;&#x662F;&#x88AB; git add &#x7684;&#x6587;&#x4EF6;&#xFF09;&#x8FD0;&#x884C;&#x5DF2;&#x914D;&#x7F6E;&#x7684; linter&#xFF08;&#x6216;&#x5176;&#x4ED6;&#xFF09;&#x4EFB;&#x52A1;&#x3002;lint-staged &#x603B;&#x662F;&#x5C06;&#x6240;&#x6709;&#x6682;&#x5B58;&#x6587;&#x4EF6;&#x7684;&#x5217;&#x8868;&#x4F20;&#x9012;&#x7ED9;&#x4EFB;&#x52A1;&#x3002;</p>
<p>&#x6211;&#x4EEC;&#x5728; <code>package.json</code> &#x6587;&#x4EF6;&#x4E2D;&#x914D;&#x7F6E;</p>
<pre><code class="language-json">&quot;lint-staged&quot;: {
    &quot;**/**.{ux,js,json,less,scss,css,pcss,md,vue}&quot;: [
      &quot;prettier --write&quot;,
      &quot;eslint &apos;src/**/*.ux&apos;&quot;,
      &quot;git add&quot;
    ]
}
</code></pre>
<p>&#x8FD9;&#x91CC; lint-staged &#x7684;&#x914D;&#x7F6E;&#x662F;&#xFF1A;&#x5728; git &#x7684;&#x5F85;&#x63D0;&#x4EA4;&#x7684;&#x6587;&#x4EF6;&#x4E2D;&#xFF0C;&#x6240;&#x6709; <code>ux,js,json,less,scss,css,pcss,md,vue</code> &#x6587;&#x4EF6;&#x90FD;&#x8981;&#x6267;&#x884C;&#x4E24;&#x6761;&#x547D;&#x4EE4;&#x5728; commit &#x4E4B;&#x524D;&#xFF0C;&#x5C06;&#x6682;&#x5B58;&#x533A;&#x7684;&#x5185;&#x5BB9;&#x505A;&#x4E00;&#x6B21;&#x4EE3;&#x7801;&#x7F8E;&#x5316;&#x548C; eslint &#x683C;&#x5F0F;&#x68C0;&#x67E5;&#xFF0C;&#x7136;&#x540E;&#x518D;&#x6DFB;&#x52A0;&#x5230;&#x6682;&#x5B58;&#x533A;&#x3002;</p>
<p>&#x7ED3;&#x5408;&#x6211;&#x4EEC;&#x524D;&#x9762;&#x4ECB;&#x7ECD;&#x7684; husky&#xFF0C;&#x914D;&#x5408; <code>husky</code> &#x7684; <code>pre-commit</code> &#x94A9;&#x5B50;&#xFF0C;&#x5C06;&#x4F1A;&#x5F62;&#x6210;&#x4E00;&#x4E2A;&#x81EA;&#x52A8;&#x5316;&#x5DE5;&#x5177;&#x94FE;&#x3002;</p>
<h2 id="%E4%BD%BF%E7%94%A8-hap-eslint-%E6%8F%92%E4%BB%B6">&#x4F7F;&#x7528; hap-eslint &#x63D2;&#x4EF6;</h2>
<h3 id="%E5%AE%89%E8%A3%85%E6%8F%92%E4%BB%B6">&#x5B89;&#x88C5;&#x63D2;&#x4EF6;</h3>
<p>&#x5728;&#x5546;&#x5E97;&#x641C;&#x7D22; <code>hap-eslint</code>&#xFF0C;&#x70B9;&#x51FB;&#x300C;<strong>&#x5B89;&#x88C5;</strong>&#x300D;&#xFF0C;&#x5373;&#x53EF;&#x5B89;&#x88C5;&#x5FEB;&#x5E94;&#x7528;&#x7684; eslint &#x63D2;&#x4EF6;&#xFF0C;&#x8BE5;&#x63D2;&#x4EF6;&#x4F1A;&#x68C0;&#x6D4B;&#x9879;&#x76EE;&#x4E0B;&#x662F;&#x5426;&#x914D;&#x7F6E;&#x4E86; eslint&#xFF0C;&#x4ECE;&#x800C;&#x6765;&#x5BF9; ux &#x6587;&#x4EF6;&#x4EE5;&#x53CA; js &#x6587;&#x4EF6;&#x8FDB;&#x884C;&#x9759;&#x6001;&#x8BED;&#x6CD5;&#x68C0;&#x67E5;&#x3002;</p>
<p>&#x6CE8;&#x610F;&#xFF1A;&#x5EFA;&#x8BAE;&#x5B89;&#x88C5; <code>7.x</code> &#x7248;&#x672C;&#x7684; eslint&#x3002;</p>
<h3 id="%E5%90%AF%E7%94%A8-eslint">&#x542F;&#x7528; eslint</h3>
<p>&#x70B9;&#x51FB;&#x5E95;&#x90E8;&#x72B6;&#x6001;&#x680F;&#x7684; eslint &#x72B6;&#x6001;&#xFF0C;&#x6839;&#x636E;&#x63D0;&#x793A;&#x9009;&#x62E9; eslint &#x7684;&#x4F5C;&#x7528;&#x8303;&#x56F4;&#x3002;&#x81F3;&#x6B64;&#xFF0C;&#x60A8;&#x5DF2;&#x7ECF;&#x53EF;&#x4EE5;&#x5728;&#x9879;&#x76EE;&#x4E2D;&#x4F7F;&#x7528; eslint &#x4E86;&#x3002;</p>
<p><img src="https://zhanstatic.vivo.com.cn/wukong/img/34e85452-792a-4663-ab4e-cc87bfa568a0.jpg" alt="eslint" loading="lazy"></p>
<h3 id="%E5%90%AF%E7%94%A8%E4%BF%9D%E5%AD%98%E6%97%B6%E8%87%AA%E5%8A%A8-fix">&#x542F;&#x7528;&#x4FDD;&#x5B58;&#x65F6;&#x81EA;&#x52A8; Fix</h3>
<p>&#x5728;&#x8BBE;&#x7F6E;&#x4E2D;&#x641C;&#x7D22;: <code>eslint: auto fix on save</code>&#xFF0C;&#x52FE;&#x9009;&#x8FD9;&#x4E2A;&#x9009;&#x9879;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x5728;&#x4FDD;&#x5B58;&#x6587;&#x4EF6;&#x65F6;&#xFF0C;&#x81EA;&#x52A8;&#x6839;&#x636E;&#x914D;&#x7F6E;&#x683C;&#x5F0F;&#x5316;&#x4EE3;&#x7801;&#x3002;</p>
<p><img src="https://zhanstatic.vivo.com.cn/wukong/img/49a7ed12-1949-4ead-8546-341016074272.jpg" alt="auto fix" loading="lazy"></p>
<h3 id="%E6%95%88%E6%9E%9C">&#x6548;&#x679C;</h3>
<p><img src="https://zhanstatic.vivo.com.cn/wukong/img/c58e0341-255b-47a6-9285-1bfa09b2cdda.gif" alt="eslint" loading="lazy"></p>
<h2 id="%E6%80%BB%E7%BB%93">&#x603B;&#x7ED3;</h2>
<p>&#x672C;&#x6587;&#x4ECB;&#x7ECD;&#x4E86;&#x5728;&#x5FEB;&#x5E94;&#x7528;&#x4E2D;&#x5982;&#x4F55;&#x8FD0;&#x7528; eslint &#x7ED3;&#x5408; husky &#x548C; lint-staged &#x6765;&#x5BF9;&#x4EE3;&#x7801;&#x8FDB;&#x884C;&#x52A0;&#x5F3A;&#x8BED;&#x6CD5;&#x68C0;&#x67E5;&#x5E76;&#x89C4;&#x5B9A;&#x6574;&#x4E2A;&#x9879;&#x76EE;&#x7684;&#x4EE3;&#x7801;&#x98CE;&#x683C;&#xFF0C;&#x5341;&#x5206;&#x65B9;&#x4FBF;&#xFF0C;&#x800C;&#x4E14;&#x80FD;&#x4F7F;&#x9879;&#x76EE;&#x7684;&#x4EE3;&#x7801;&#x66F4;&#x52A0;&#x89C4;&#x8303;&#x3002;</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[requirejs 源码解析]]></title><description><![CDATA[vscode 源码使用 vscode-loader 加载模块，vscode-loader 是异步模块定义 (AMD) 加载器的一种实现。而 AMD 规范的实现典范是 requirejs，可在浏览器、node 等环境中，异步加载 js 或模块。]]></description><link>https://quickapp.vivo.com.cn/requirejs-source-code-analysis/</link><guid isPermaLink="false">63c4b94a77e2ca0006a8c898</guid><category><![CDATA[javascript]]></category><dc:creator><![CDATA[minxuan]]></dc:creator><pubDate>Tue, 12 Oct 2021 01:47:12 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>vscode &#x6E90;&#x7801;&#x4F7F;&#x7528; vscode-loader &#x52A0;&#x8F7D;&#x6A21;&#x5757;&#xFF0C;vscode-loader &#x662F;&#x5F02;&#x6B65;&#x6A21;&#x5757;&#x5B9A;&#x4E49; (AMD) &#x52A0;&#x8F7D;&#x5668;&#x7684;&#x4E00;&#x79CD;&#x5B9E;&#x73B0;&#x3002;&#x800C; AMD &#x89C4;&#x8303;&#x7684;&#x5B9E;&#x73B0;&#x5178;&#x8303;&#x662F; requirejs&#xFF0C;&#x53EF;&#x5728;&#x6D4F;&#x89C8;&#x5668;&#x3001;node &#x7B49;&#x73AF;&#x5883;&#x4E2D;&#xFF0C;&#x5F02;&#x6B65;&#x52A0;&#x8F7D; js &#x6216;&#x6A21;&#x5757;&#x3002;</p>
<p>&#x672C;&#x6587;&#x5148;&#x5B66;&#x4E60;&#x68B3;&#x7406; requirejs &#x7684;&#x6E90;&#x7801;&#xFF0C;&#x4E86;&#x89E3; AMD &#x4E00;&#x822C;&#x662F;&#x5982;&#x4F55;&#x5B9E;&#x73B0;&#x7684;&#x3002;&#x5728;&#x540E;&#x9762;&#x7684;&#x6587;&#x7AE0;&#x4E2D;&#xFF0C;&#x518D;&#x8FDB;&#x4E00;&#x6B65;&#x5B66;&#x4E60; vscode-loader &#x7684;&#x5B9E;&#x73B0;&#x3002;</p>
<h2 id="requirejs-%E7%9A%84%E4%BD%BF%E7%94%A8%E7%A4%BA%E4%BE%8B">requirejs &#x7684;&#x4F7F;&#x7528;&#x793A;&#x4F8B;</h2>
<p>require.js &#x5728; &#x6D4F;&#x89C8;&#x5668;&#x4E2D;&#x7684;&#x4F7F;&#x7528;&#x65B9;&#x6CD5;&#x5982;&#x4E0B;&#xFF1A;</p>
<p>html&#xFF1A;<srcipt> &#x6807;&#x7B7E;&#x7684; src &#x6307;&#x5B9A;&#x4E3A; require.js&#xFF0C;data-main &#x6307;&#x5B9A;&#x4E3A;&#x5165;&#x53E3; js&#x3002;</srcipt></p>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;title&gt;Document&lt;/title&gt;
    &lt;!-- &#x6307;&#x5B9A;&#x5165;&#x53E3;&#x811A;&#x672C; a/b.js --&gt;
    &lt;script src=&quot;require.js&quot; data-main=&quot;a/b.js&quot; &gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>&#x5165;&#x53E3; js&#xFF1A;&#x8C03;&#x7528; requirejs &#x65B9;&#x6CD5;&#xFF0C;&#x52A0;&#x8F7D;&#x6A21;&#x5757;&#x3002;</p>
<pre><code class="language-js">// a/b.js

// &#x914D;&#x7F6E;&#x6A21;&#x5757;&#x8DEF;&#x5F84;
require.config({
    paths: {
        test: &apos;test&apos;
    }
});

// &#x52A0;&#x8F7D;&#x6A21;&#x5757;
requirejs([&apos;test&apos;], function(test) {
    test.compare(2, 5)
});
</code></pre>
<p>&#x5B9A;&#x4E49;&#x6A21;&#x5757;&#xFF1A;</p>
<pre><code class="language-js">// test.js

define(&apos;test&apos;, function() {
    return {
        compare: function(a, b) {
            return a &gt; b;
        }
    }
});

</code></pre>
<p>define &#x65B9;&#x6CD5;&#xFF1A;<code>define(id?, dependencies?, factory);</code>&#xFF0C;&#x7B2C;&#x4E00;&#x4E2A;&#x53C2;&#x6570;&#x662F;&#x6A21;&#x5757;&#x540D;&#xFF0C;&#x7B2C;&#x4E8C;&#x4E2A;&#x53C2;&#x6570;&#x662F;&#x4F9D;&#x8D56;&#xFF0C;&#x7B2C;&#x4E09;&#x4E2A;&#x53C2;&#x6570;&#x662F;&#x6A21;&#x5757;&#x7684;&#x5DE5;&#x5382;&#x51FD;&#x6570;&#xFF0C;&#x8FD4;&#x56DE;&#x5B9A;&#x4E49;&#x7684;&#x6A21;&#x5757;&#x3002;</p>
<h2 id="requirejs-%E7%9A%84%E4%BB%A3%E7%A0%81%E8%A7%A3%E6%9E%90">requirejs &#x7684;&#x4EE3;&#x7801;&#x89E3;&#x6790;</h2>
<p>requirejs &#x7684;&#x4E3B;&#x4F53;&#x662F;&#x4E00;&#x4E2A;&#x81EA;&#x6267;&#x884C;&#x51FD;&#x6570;&#x3002;&#x4E0B;&#x9762;&#x4EE3;&#x7801;&#x7701;&#x7565;&#x4E86;&#x8BB8;&#x591A;&#x7EC6;&#x8282;&#xFF0C;&#x5148;&#x770B;&#x4E00;&#x4E0B;&#x57FA;&#x672C;&#x7684;&#x7ED3;&#x6784;&#x3002;</p>
<pre><code class="language-js">var requirejs, require, define;
(function (global, setTimeout) {
    // &#x5B9A;&#x4E49;&#x4E00;&#x7CFB;&#x5217;&#x7684;&#x53D8;&#x91CF;&#x548C;&#x51FD;&#x6570;&#xFF0C;&#x6700;&#x4E3B;&#x8981;&#x662F; newContext&#x3001;req&#x3001;define
    function newContext(contextName) {}
    req = requirejs = function (deps, callback, errback, optional) {}
    define = function (name, deps, callback) {}
	
    // &#x7B2C;&#x4E00;&#x6B65;&#xFF1A;&#x521B;&#x5EFA;&#x9ED8;&#x8BA4;&#x4E0A;&#x4E0B;&#x6587;
    req({});

    // &#x7B2C;&#x4E8C;&#x6B65;&#xFF1A;&#x6D4F;&#x89C8;&#x5668;&#x73AF;&#x5883;&#xFF0C;&#x67E5;&#x627E;&#x5165;&#x53E3; js&#xFF0C;&#x653E;&#x5230;&#x914D;&#x7F6E;&#x4E2D;
    if (isBrowser &amp;&amp; !cfg.skipDataMain) {
        ...

        cfg.deps = cfg.deps ? cfg.deps.concat(mainScript) : [mainScript];

        ...
    }

    // &#x7B2C;&#x4E09;&#x6B65;&#xFF1A;&#x6839;&#x636E;&#x914D;&#x7F6E;&#xFF0C;&#x52A0;&#x8F7D;&#x5165;&#x53E3; js
    req(cfg);
    
}(this, (typeof setTimeout === &apos;undefined&apos; ? undefined : setTimeout)));
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;requirejs &#x53EF;&#x4EE5;&#x5206;&#x4E3A;&#x4E09;&#x6B65;&#xFF1A;&#x521B;&#x5EFA;&#x9ED8;&#x8BA4;&#x4E0A;&#x4E0B;&#x6587;&#x3001;&#x67E5;&#x627E;&#x5165;&#x53E3; js&#x3001;&#x52A0;&#x8F7D;&#x5165;&#x53E3; js&#x3002;</p>
<p>&#x7B2C;&#x4E00;&#x6B65;&#x548C;&#x7B2C;&#x4E09;&#x6B65;&#x90FD;&#x662F;&#x8C03;&#x7528; req &#x51FD;&#x6570;&#xFF0C;&#x6D89;&#x53CA;&#x4EE3;&#x7801;&#x8F83;&#x591A;&#x3002;&#x6211;&#x4EEC;&#x5148;&#x770B;&#x770B;&#x76F8;&#x5BF9;&#x7B80;&#x5355;&#x7684;&#x7B2C;&#x4E8C;&#x6B65;&#xFF0C;&#x67E5;&#x627E;&#x5165;&#x53E3; js &#x7684;&#x5177;&#x4F53;&#x5B9E;&#x73B0;&#x3002;</p>
<h3 id="%E6%9F%A5%E6%89%BE%E5%85%A5%E5%8F%A3-js">&#x67E5;&#x627E;&#x5165;&#x53E3; js</h3>
<p>&#x4ECE;&#x524D;&#x9762;&#x7684;&#x793A;&#x4F8B; <code>&lt;script src=&quot;require.js&quot; data-main=&quot;a/b.js&quot; &gt;&lt;/script&gt;</code>&#xFF0C;&#x6211;&#x4EEC;&#x77E5;&#x9053;&#xFF0C;&#x5165;&#x53E3; js &#x5728; script &#x6807;&#x7B7E;&#x7684; data-main &#x5C5E;&#x6027;&#x4E2D;&#x6307;&#x5B9A;&#x3002;&#x6240;&#x4EE5;&#x67E5;&#x627E;&#x5165;&#x53E3; js&#xFF0C;&#x4E5F;&#x5C31;&#x662F;&#x5148;&#x627E;&#x5230; data-main&#xFF0C;&#x518D;&#x8FDB;&#x884C;&#x89E3;&#x6790;&#x3002;&#x5177;&#x4F53;&#x5982;&#x4E0B;&#xFF1A;</p>
<pre><code class="language-js">
    if (isBrowser &amp;&amp; !cfg.skipDataMain) {
        // &#x7B2C;&#x4E00;&#x6B65;&#xFF1A;&#x904D;&#x5386; script &#x6807;&#x7B7E;
        // &#x6CE8;&#xFF1A;eachReverse&#xFF0C;&#x5BF9; scripts &#x6570;&#x7EC4;&#xFF0C;&#x904D;&#x5386;&#x6267;&#x884C;&#x4F20;&#x5165;&#x7684;&#x51FD;&#x6570;&#xFF0C;&#x51FD;&#x6570;&#x8FD4;&#x56DE;&#x503C;&#x4E3A; true &#x65F6;&#x4E2D;&#x6B62;&#x904D;&#x5386;
        eachReverse(scripts(), function (script) {
            // &#x7B2C;&#x4E8C;&#x6B65;&#xFF1A;&#x4FDD;&#x5B58; script &#x6807;&#x7B7E;&#x7684;&#x7236;&#x5143;&#x7D20;
            if (!head) {
                head = script.parentNode;
            }

            // &#x7B2C;&#x4E09;&#x6B65;&#xFF1A;&#x83B7;&#x53D6; data-main &#x5C5E;&#x6027;
            dataMain = script.getAttribute(&apos;data-main&apos;);

            // &#x7B2C;&#x56DB;&#x6B65;&#xFF1A;&#x89E3;&#x6790; data-main&#xFF0C;&#x83B7;&#x53D6;&#x5165;&#x53E3; js&#xFF0C;&#x653E;&#x5230;&#x914D;&#x7F6E;&#x4E2D;
            if (dataMain) {
                // &#x7565;&#xFF0C;&#x5728;&#x4E0B;&#x9762;&#x5C55;&#x5F00;&#x8BA8;&#x8BBA;
                ...
            }
        });
    }

    // &#x76F8;&#x5173;&#x51FD;&#x6570;&#x5982;&#x4E0B;&#xFF1A;
    /**
     * &#x904D;&#x5386;&#x6570;&#x7EC4;&#xFF0C;&#x6267;&#x884C;&#x51FD;&#x6570;&#xFF0C;&#x51FD;&#x6570;&#x8FD4;&#x56DE; true &#x65F6;&#xFF0C;break
     */
    function eachReverse(ary, func) {
        if (ary) {
            var i;
            for (i = ary.length - 1; i &gt; -1; i -= 1) {
                if (ary[i] &amp;&amp; func(ary[i], i, ary)) {
                    break;
                }
            }
        }
    }

    function scripts() {
        return document.getElementsByTagName(&apos;script&apos;);
    }

</code></pre>
<p>&#x89E3;&#x6790; data-main &#x7684;&#x5177;&#x4F53;&#x903B;&#x8F91;&#x5982;&#x4E0B;&#xFF1A;</p>
<pre><code class="language-js">
if (dataMain) {
    mainScript = dataMain;

    // &#x7B2C;&#x4E00;&#x6B65;&#xFF1A;&#x5982;&#x679C;&#x6CA1;&#x6709; baseUrl&#xFF0C;&#x5219;&#x89E3;&#x6790;&#x83B7;&#x53D6; baseUrl
    // &#x6CE8;&#xFF1A;mainScript.indexOf(&apos;!&apos;) === -1&#xFF0C;&#x8BE5;&#x5224;&#x65AD;&#x662F;&#x6307; data-main &#x503C;&#x4E0D;&#x662F;&#x52A0;&#x8F7D;&#x5668;&#x63D2;&#x4EF6;&#x6A21;&#x5757;&#x7684; ID&#x3002;
    if (!cfg.baseUrl &amp;&amp; mainScript.indexOf(&apos;!&apos;) === -1) {

        // 1. data-main &#x89E3;&#x6790;&#x4E3A; mainScript &#x548C; subPath
        /**
         * &#x4F8B;&#x5B50;&#xFF1A;
         * dataMain = &apos;a&apos;, &#x89E3;&#x6790;&#x51FA; mainScirpt = &apos;a&apos;, subPath = &apos;./&apos;
         * dataMain = &apos;a/b&apos;, &#x89E3;&#x6790;&#x51FA; mainScript = &apos;b&apos;, subpath = &apos;a/&apos;
         */
        src = mainScript.split(&apos;/&apos;);
        mainScript = src.pop();
        subPath = src.length ? src.join(&apos;/&apos;)  + &apos;/&apos; : &apos;./&apos;;

        // 2. &#x8BBE;&#x7F6E; cfg &#x7684; baseUrl
        cfg.baseUrl = subPath;
    }


    // &#x7B2C;&#x4E8C;&#x6B65;&#xFF1A;mainScript &#x53BB;&#x6389;&#x7ED3;&#x5C3E;&#x7684; .js
    mainScript = mainScript.replace(jsSuffixRegExp, &apos;&apos;);

    // &#x7B2C;&#x4E09;&#x6B65;&#xFF1A;&#x5982;&#x679C; mainScript &#x4ECD;&#x7136;&#x662F;&#x8DEF;&#x5F84;&#xFF0C;&#x5219;&#x56DE;&#x9000;&#x5230; dataMain
    if (req.jsExtRegExp.test(mainScript)) {
        mainScript = dataMain;
    }

    // &#x7B2C;&#x56DB;&#x6B65;&#xFF1A;&#x5C06; data-main &#x811A;&#x672C;&#x653E;&#x5165; cfg.deps &#x4E2D;&#xFF0C;&#x7B49;&#x5F85;&#x540E;&#x7EED;&#x52A0;&#x8F7D;
    cfg.deps = cfg.deps ? cfg.deps.concat(mainScript) : [mainScript];
    
    return true;
}
</code></pre>
<p>&#x7ECF;&#x8FC7;&#x89E3;&#x6790;&#xFF0C;&#x5F97;&#x5230;&#x914D;&#x7F6E;&#x5BF9;&#x8C61; cfg&#x3002;&#x6BD4;&#x5982;&#x5BF9;&#x4E8E; <code>data-main=&quot;./a/b.js&quot;</code>&#xFF0C;&#x5F97;&#x5230;&#x7684; cfg &#x5982;&#x4E0B;&#xFF1A;</p>
<pre><code class="language-js">cfg = {
    baseUrl: &apos;./a/&apos;,
    deps: [&apos;b&apos;],
}
</code></pre>
<h3 id="req-%E5%8A%A0%E8%BD%BD%E5%85%A5%E5%8F%A3-js">req &#x52A0;&#x8F7D;&#x5165;&#x53E3; js</h3>
<!-- 接下来，我们继续看第一步、第三步操作：调用 req 函数，创建默认上下文、加载入口 js -->
<p>&#x914D;&#x7F6E;&#x597D;&#x5165;&#x53E3;&#x6587;&#x4EF6;&#x540E;&#xFF0C;&#x4E0B;&#x4E00;&#x6B65;&#x5C31;&#x662F;&#x8C03;&#x7528; req &#x51FD;&#x6570;&#xFF0C;&#x52A0;&#x8F7D;&#x5165;&#x53E3; js&#x3002;&#x7B2C;&#x4E00;&#x6B65;&#x64CD;&#x4F5C;&#xFF0C;&#x521B;&#x5EFA;&#x9ED8;&#x8BA4;&#x4E0A;&#x4E0B;&#x6587;&#x4E5F;&#x662F;&#x8C03;&#x7528; req &#x51FD;&#x6570;&#xFF0C;&#x6211;&#x4EEC;&#x653E;&#x5728;&#x4E00;&#x8D77;&#x770B;&#x3002;</p>
<pre><code class="language-js">defContextName = &apos;_&apos;

req = requirejs = function (deps, callback, errback, optional) {

    // &#x7B2C;&#x4E00;&#x6B65;&#xFF1A;contextName &#x8BBE;&#x7F6E;&#x4E3A;&#x9ED8;&#x8BA4;&#x503C;
    var context, config,
        contextName = defContextName;

    // &#x7B2C;&#x4E8C;&#x6B65;&#xFF1A;&#x786E;&#x5B9A;&#x7B2C;&#x4E00;&#x4E2A;&#x53C2;&#x6570;&#xFF0C;&#x662F;&#x5426;&#x4E3A; config &#x5BF9;&#x8C61;&#x3002;&#x5982;&#x679C;&#x662F;&#xFF0C;&#x91CD;&#x65B0;&#x4FEE;&#x6539;&#x5176;&#x4ED6;&#x53C2;&#x6570;&#x3002;
    if (!isArray(deps) &amp;&amp; typeof deps !== &apos;string&apos;) {
        // deps is a config object
        config = deps;
        if (isArray(callback)) {
            // Adjust args if there are dependencies
            deps = callback;
            callback = errback;
            errback = optional;
        } else {
            deps = [];
        }
    }

    // &#x7B2C;&#x4E09;&#x6B65;&#xFF1A;&#x6839;&#x636E; config &#x5BF9;&#x8C61;&#xFF0C;&#x66F4;&#x65B0; contextName
    if (config &amp;&amp; config.context) {
        contextName = config.context;
    }

    // &#x7B2C;&#x56DB;&#x6B65;&#xFF1A;&#x6839;&#x636E; contextName &#x83B7;&#x53D6;&#x6216;&#x65B0;&#x5EFA;&#x4E0A;&#x4E0B;&#x6587;
    context = getOwn(contexts, contextName);
    if (!context) {
        context = contexts[contextName] = req.s.newContext(contextName);
    }

    // &#x7B2C;&#x4E94;&#x6B65;&#xFF1A;&#x5982;&#x679C;&#x6709; config &#x5BF9;&#x8C61;&#xFF0C;&#x5C31;&#x66F4;&#x65B0;&#x4E0A;&#x4E0B;&#x6587;&#x7684;&#x914D;&#x7F6E;
    if (config) {
        context.configure(config);
    }

    // &#x7B2C;&#x516D;&#x6B65;&#xFF1A;&#x8C03;&#x7528;&#x4E0A;&#x4E0B;&#x6587;&#x7684; require &#x65B9;&#x6CD5;
    return context.require(deps, callback, errback);
};

s = req.s = {
    contexts: contexts,
    newContext: newContext
};
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230; <code>req</code> &#x51FD;&#x6570;&#x5C31;&#x662F; <code>requirejs</code> &#x51FD;&#x6570;&#x3002;&#x5B83;&#x6709;&#x4E24;&#x79CD;&#x8C03;&#x7528;&#x65B9;&#x5F0F;&#xFF0C;&#x4E00;&#x79CD;&#x662F;&#x4E0D;&#x4F20;&#x5165; config &#x5BF9;&#x8C61;&#xFF0C;&#x4E00;&#x79CD;&#x662F;&#x4F20;&#x5165;&#x3002;</p>
<ul>
<li>&#x4E0D;&#x4F20;&#x5165; config &#x5BF9;&#x8C61;&#xFF1A;
<ul>
<li>&#x76F4;&#x63A5;&#x4F7F;&#x7528;&#x9ED8;&#x8BA4;&#x4E0A;&#x4E0B;&#x6587;&#xFF08;&#x83B7;&#x53D6;&#x6216;&#x65B0;&#x5EFA;&#x9ED8;&#x8BA4;&#x4E0A;&#x4E0B;&#x6587;&#xFF09;&#xFF0C;&#x8C03;&#x7528;&#x9ED8;&#x8BA4;&#x4E0A;&#x4E0B;&#x6587;&#x7684; <code>require</code> &#x65B9;&#x6CD5;&#x3002;</li>
</ul>
</li>
<li>&#x4F20;&#x5165; config &#x5BF9;&#x8C61;&#xFF1A;
<ul>
<li>&#x6839;&#x636E; config &#x66F4;&#x65B0; contextName&#xFF0C;&#x6839;&#x636E; contextName &#x83B7;&#x53D6;&#x6216;&#x65B0;&#x5EFA;&#x4E0A;&#x4E0B;&#x6587;&#xFF08;&#x6CE8;&#x610F;&#xFF1A;&#x5982;&#x679C;&#x5B83;&#x6CA1;&#x6709;&#x66F4;&#x65B0;&#xFF0C;&#x4E5F;&#x8FD8;&#x662F;&#x9ED8;&#x8BA4;&#x4E0A;&#x4E0B;&#x6587;&#xFF09;&#x3002;</li>
<li>&#x7528; config &#x66F4;&#x65B0;&#x4E0A;&#x4E0B;&#x6587;&#x7684;&#x914D;&#x7F6E;&#xFF0C;&#x518D;&#x8C03;&#x7528;&#x4E0A;&#x4E0B;&#x6587;&#x7684; <code>require</code> &#x65B9;&#x6CD5;&#x3002;</li>
</ul>
</li>
</ul>
<!-- todo -->
<!-- 另外，如果只传入 config 对象，不传入 deps, callback, errback 等参数，那么只会设置上下文配置，而第六步的 require 其实是不生效的。 -->
<h4 id="req-%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B">req &#x6267;&#x884C;&#x8FC7;&#x7A0B;</h4>
<p><code>req({})</code>&#xFF0C;&#x4F20;&#x4E86;&#x4E00;&#x4E2A;&#x6CA1;&#x6709;&#x5C5E;&#x6027;&#x7684;&#x5BF9;&#x8C61;&#x8FDB;&#x53BB;&#xFF0C;&#x521B;&#x5EFA;&#x4E86;&#x9ED8;&#x8BA4;&#x4E0A;&#x4E0B;&#x6587;&#x3002;<br>
<code>req(cfg)</code>&#xFF0C;&#x8FD8;&#x662F;&#x4EE5;&#x524D;&#x9762; <code>data-main=&quot;./a/b.js&quot;</code> &#x4E3A;&#x4F8B;&#xFF0C;&#x4F20;&#x5165;&#x53C2;&#x6570;&#x4E3A; { baseUrl: &apos;./a/&apos;, deps: [&apos;b&apos;] }&#xFF0C;&#x52A0;&#x8F7D;&#x4E86;&#x5165;&#x53E3;&#x6587;&#x4EF6;&#x3002;<br>
req &#x524D;&#x4E09;&#x6B65;&#x7684;&#x6267;&#x884C;&#x903B;&#x8F91;&#x5982;&#x4E0B;&#xFF1A;</p>
<pre><code class="language-js">req = requirejs = function (deps, callback, errback, optional) {

    // &#x7B2C;&#x4E00;&#x6B65;&#xFF1A;contextName = &apos;_&apos;
    var context, config,
        contextName = defContextName;

    // &#x7B2C;&#x4E8C;&#x6B65;&#xFF1A;
    // req({})&#xFF0C;&#x7B2C;&#x4E00;&#x4E2A;&#x53C2;&#x6570;&#x662F; {}&#xFF0C;&#x7ED3;&#x679C;&#xFF1A; config = {}, deps = []&#x3002;
    // req(cfg)&#xFF0C;&#x7B2C;&#x4E00;&#x4E2A;&#x53C2;&#x6570;&#x662F; { baseUrl: &apos;./a/&apos;, deps: [&apos;b&apos;] }&#xFF0C;&#x7ED3;&#x679C;&#xFF1A;config = { baseUrl: &apos;./a/&apos;, deps: [&apos;b&apos;] }, deps = []
    if (!isArray(deps) &amp;&amp; typeof deps !== &apos;string&apos;) {
        // config = &#x7B2C;&#x4E00;&#x4E2A;&#x53C2;&#x6570;
        config = deps;
        // &#x672A;&#x4F20;&#x5165;&#x7B2C;&#x4E8C;&#x4E2A;&#x53C2;&#x6570;&#xFF0C;deps = []
        if (isArray(callback)) {
            deps = callback;
            callback = errback;
            errback = optional;
        } else {
            deps = [];
        }
    }

    // &#x7B2C;&#x4E09;&#x6B65;&#xFF1A;
    // req({})&#xFF0C;config &#x4E3A; {}&#xFF0C;&#x6240;&#x4EE5; contextName &#x4F9D;&#x7136;&#x4E3A;&#x9ED8;&#x8BA4;&#x503C; &apos;_&apos;
    // req(cfg)&#xFF0C;config &#x4E3A; { baseUrl: &apos;./a/&apos;, deps: [&apos;b&apos;] }, &#x6240;&#x4EE5; contextName &#x4F9D;&#x7136;&#x4E3A;&#x9ED8;&#x8BA4;&#x503C; &apos;_&apos;
    if (config &amp;&amp; config.context) {
        contextName = config.context;
    }

    ...
};
</code></pre>
<p>&#x6211;&#x4EEC;&#x7EE7;&#x7EED;&#x770B; req &#x51FD;&#x6570;&#x7684;&#x7B2C;&#x56DB;&#x6B65;&#x3002;<br>
<code>req({})</code>&#xFF0C;&#x4E00;&#x5F00;&#x59CB;&#x8FD8;&#x6CA1;&#x6709;&#x9ED8;&#x8BA4;&#x4E0A;&#x4E0B;&#x6587;&#xFF0C;&#x6240;&#x4EE5;&#x4F1A;&#x65B0;&#x5EFA;&#x9ED8;&#x8BA4;&#x4E0A;&#x4E0B;&#x6587;&#x3002;<br>
<code>req(cfg)</code> &#x7684; contextName &#x4E5F;&#x662F;&#x9ED8;&#x8BA4;&#x503C; &apos;_&apos;&#xFF0C;&#x800C;&#x9ED8;&#x8BA4;&#x4E0A;&#x4E0B;&#x6587;&#x5DF2;&#x7ECF;&#x65B0;&#x5EFA;&#xFF0C;&#x6240;&#x4EE5;&#x4F1A;&#x76F4;&#x63A5;&#x83B7;&#x53D6;&#x9ED8;&#x8BA4;&#x4E0A;&#x4E0B;&#x6587;&#x3002;</p>
<pre><code class="language-js">    // req &#x51FD;&#x6570;&#x7684;&#x7B2C;&#x56DB;&#x6B65;&#xFF1A;
    // req({})&#xFF0C;contextName &#x4E3A;&#x9ED8;&#x8BA4;&#x503C; &apos;_&apos;&#xFF0C;&#x4E00;&#x5F00;&#x59CB;&#x6CA1;&#x6709;&#x9ED8;&#x8BA4;&#x4E0A;&#x4E0B;&#x6587;&#xFF0C;&#x6240;&#x4EE5;&#x8D70; req-4.2&#xFF0C;&#x65B0;&#x5EFA;&#x9ED8;&#x8BA4;&#x4E0A;&#x4E0B;&#x6587;&#x3002;
    // req(cfg)&#xFF0C;contextName &#x4E3A;&#x9ED8;&#x8BA4;&#x503C; &apos;_&apos;&#xFF0C;&#x5DF2;&#x7ECF;&#x6709;&#x9ED8;&#x8BA4;&#x4E0A;&#x4E0B;&#x6587;&#xFF0C;&#x6240;&#x4EE5;&#x8D70; req-4.1&#xFF0C;&#x83B7;&#x53D6;&#x9ED8;&#x8BA4;&#x4E0A;&#x4E0B;&#x6587;&#x3002;
    req = requirejs = function (deps, callback, errback, optional) {
        ...
        // req-4.1. &#x6839;&#x636E; contextName &#x83B7;&#x53D6; context&#x3002;
        context = getOwn(contexts, contextName);
        // req-4.2. &#x5982;&#x679C;&#x6CA1;&#x6709; context&#xFF0C;&#x6839;&#x636E; contextName &#x65B0;&#x5EFA;&#x4E00;&#x4E2A;&#x4E0A;&#x4E0B;&#x6587;&#x3002;
        if (!context) {
            context = contexts[contextName] = req.s.newContext(contextName);
        }
        ...
    }

    /* req-4.1 &#x83B7;&#x53D6;&#x4E0A;&#x4E0B;&#x6587; */
    // getOwn &#x7684;&#x7B2C;&#x4E00;&#x4E2A;&#x53C2;&#x6570; contexts&#xFF0C;&#x521D;&#x59CB;&#x5316;&#x65F6;&#x662F; {}
    contexts = {},

    // getOwn&#xFF1A;&#x5224;&#x65AD;&#x5BF9;&#x8C61;&#x4E2D;&#xFF0C;&#x662F;&#x5426;&#x6709;&#x67D0;&#x4E2A;&#x5C5E;&#x6027;&#xFF0C;&#x5982;&#x679C;&#x6709;&#x5C31;&#x8FD4;&#x56DE;&#x5C5E;&#x6027;&#x503C;
    function getOwn(obj, prop) {
        return hasProp(obj, prop) &amp;&amp; obj[prop];
    }
    
    // hasProp&#xFF1A;&#x5224;&#x65AD;&#x5BF9;&#x8C61;&#x4E2D;&#xFF0C;&#x662F;&#x5426;&#x6709;&#x67D0;&#x4E2A;&#x5C5E;&#x6027;
    function hasProp(obj, prop) {
        return hasOwn.call(obj, prop);
    }

    // hasOwn
    op = Object.prototype,
    hasOwn = op.hasOwnProperty,
</code></pre>
<p>&#x7EE7;&#x7EED;&#x770B; req-4.2 &#x65B0;&#x5EFA;&#x4E0A;&#x4E0B;&#x6587;&#x7684;&#x903B;&#x8F91;&#xFF0C;&#x7531;&#x4E8E;&#x4EE3;&#x7801;&#x91CF;&#x5927;&#xFF0C;&#x8FD9;&#x91CC;&#x8FDB;&#x884C;&#x7701;&#x7565;&#x7B80;&#x5316;&#x3002;</p>
<pre><code class="language-js">    /* req-4.2 &#x65B0;&#x5EFA;&#x4E0A;&#x4E0B;&#x6587; */
    function newContext(contextName) {
        // &#x5B9A;&#x4E49;&#x4E00;&#x5806;&#x53D8;&#x91CF;&#x548C;&#x51FD;&#x6570;&#xFF0C;&#x8FD9;&#x91CC;&#x53EA;&#x770B; context
        var context
        ...

        // req-4.2.1&#xFF1A;context &#x8D4B;&#x503C;
        context = {
            config: config,
            contextName: contextName,
            ...
            // &#x4E3A;&#x4E0A;&#x4E0B;&#x6587;&#x8BBE;&#x7F6E;&#x914D;&#x7F6E;
            configure: function (cfg) {
                // &#x786E;&#x4FDD; baseUrl &#x4EE5; / &#x7ED3;&#x675F;
                if (cfg.baseUrl) {
                    if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== &apos;/&apos;) {
                        cfg.baseUrl += &apos;/&apos;;
                    }
                }
                ...
                // configure &#x7684;&#x6700;&#x540E;&#x4E00;&#x6B65;&#xFF1A;&#x5982;&#x679C;&#x6307;&#x5B9A;&#x4E86; deps &#x6216; callback&#xFF0C;&#x5219;&#x4F7F;&#x7528;&#x8FD9;&#x4E9B;&#x53C2;&#x6570;&#x8C03;&#x7528; require&#x3002;
                if (cfg.deps || cfg.callback) {
                    context.require(cfg.deps || [], cfg.callback);
                }
            },
            // &#x52A0;&#x8F7D;&#x6A21;&#x5757;
            makeRequire: function (relMap, options) { ... },
            ...
        }

        // req-4.2.2&#xFF1A;&#x8BBE;&#x7F6E; context.require&#xFF0C;&#x5E76;&#x8FD4;&#x56DE; context
        context.require = context.makeRequire();
        return context;
    }
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#x65B0;&#x5EFA;&#x4E0A;&#x4E0B;&#x6587;&#xFF0C;&#x4E3B;&#x8981;&#x662F;&#x5BF9; context &#x8FDB;&#x884C;&#x8D4B;&#x503C;&#xFF0C;&#x5B9A;&#x4E49;&#x4E00;&#x7CFB;&#x5217;&#x7684;&#x5C5E;&#x6027;&#x548C;&#x65B9;&#x6CD5;&#xFF0C;&#x5E76;&#x8FD4;&#x56DE; context&#x3002;</p>
<p>&#x56DE;&#x5230; req &#x51FD;&#x6570;&#xFF0C;&#x7B2C;&#x4E94;&#x6B65;&#x662F;&#x8BBE;&#x7F6E; config&#xFF0C;&#x5982;&#x679C;&#x6307;&#x5B9A;&#x4E86; deps&#xFF0C;&#x5219;&#x8C03;&#x7528; require &#x52A0;&#x8F7D;&#x6A21;&#x5757;&#x3002;</p>
<p>&#x7B2C;&#x516D;&#x6B65;&#x662F;&#x8FD4;&#x56DE; context.require&#xFF0C;&#x52A0;&#x8F7D;&#x6A21;&#x5757;&#x3002;</p>
<pre><code class="language-js">req = requirejs = function (deps, callback, errback, optional) {
    ...

    // &#x7B2C;&#x4E94;&#x6B65;&#xFF1A;&#x8C03;&#x7528; context.configure &#x66F4;&#x65B0;&#x914D;&#x7F6E;
    /**
     * req({})&#xFF0C;config &#x4E3A; {}&#xFF0C;&#x7ED3;&#x679C;&#xFF1A;context.config = {config: baseUrl: &quot;./&quot;, bundles: {}, config: {}, paths: {}, pkgs: {}, shim: {}, waitSeconds: 7}
     * req(cfg)&#xFF0C;config &#x4E3A; { baseUrl: &apos;./a/&apos;, deps: [&apos;b&apos;] }&#xFF0C;&#x7ED3;&#x679C;&#xFF1A;context.config = {config: baseUrl: &quot;./a/&quot;, deps: [&quot;b&quot;], bundles: {}, config: {}, paths: {}, pkgs: {}, shim: {}, waitSeconds: 7}, &#x7531;&#x4E8E; cfg.deps &#x4E3A; [&apos;b&apos;]&#xFF0C;&#x5728; configure &#x7684;&#x6700;&#x540E;&#x4E00;&#x6B65;&#x4F1A;&#x8C03;&#x7528; context.require(cfg.deps)&#xFF0C;&#x52A0;&#x8F7D;&#x5165;&#x53E3; js
     */
    if (config) {
        context.configure(config);
    }

    // &#x7B2C;&#x516D;&#x6B65;&#xFF1A;context.require&#xFF0C;&#x4ECE;&#x7B2C;&#x4E8C;&#x6B65;&#x53EF;&#x77E5;&#xFF0C;deps &#x5747;&#x4E3A; []&#xFF0C;&#x6240;&#x4EE5;&#x8FD9;&#x91CC;&#x6CA1;&#x6709;&#x4F9D;&#x8D56;&#x6A21;&#x5757;&#x52A0;&#x8F7D;&#x3002;
    return context.require(deps, callback, errback);
};
</code></pre>
<h4 id="%E5%8A%A0%E8%BD%BD%E6%A8%A1%E5%9D%97">&#x52A0;&#x8F7D;&#x6A21;&#x5757;</h4>
<p>&#x68B3;&#x7406;&#x5B8C; req &#x51FD;&#x6570;&#x7684;&#x6267;&#x884C;&#x8FC7;&#x7A0B;&#xFF0C;&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;<code>req(cfg)</code> &#x5728;&#x7B2C;&#x4E94;&#x6B65;&#x4F1A;&#x901A;&#x8FC7; <code>context.require(cfg.deps)</code>&#xFF0C;&#x52A0;&#x8F7D;&#x5165;&#x53E3; js&#xFF0C;&#x5176;&#x4E2D; <code>cfg.deps</code> &#x4E3A; [&apos;b&apos;]&#x3002;</p>
<p>&#x63A5;&#x4E0B;&#x6765;&#xFF0C;&#x5C31;&#x7EE7;&#x7EED;&#x67E5;&#x770B;&#x52A0;&#x8F7D;&#x6A21;&#x5757;&#x7684;&#x5B9E;&#x73B0;&#x903B;&#x8F91;&#x3002;&#x5728;&#x524D;&#x9762;(req-4.2.2)&#xFF0C;&#x53EF;&#x4EE5;&#x770B;&#x5230; <code>context.require = context.makeRequire()</code>&#x3002;</p>
<pre><code class="language-js">context = {
    ...
    makeRequire: function (relMap, options) {
        options = options || {};

        // &#x7B2C;&#x4E00;&#x6B65;&#xFF1A;&#x5B9A;&#x4E49; localRequire&#xFF08;require &#x7684;&#x5B9E;&#x73B0;&#xFF09;
        function localRequire(deps, callback, errback) {
            var id, map, requireMod;

            if (options.enableBuildCallback &amp;&amp; callback &amp;&amp; isFunction(callback)) {
                callback.__requireJsBuild = true;
            }

            // require-1. &#x5982;&#x679C; deps &#x662F;&#x5B57;&#x7B26;&#x4E32;&#x7C7B;&#x578B;&#xFF0C;&#x6839;&#x636E;&#x6A21;&#x5757;&#x540D;&#x79F0;&#x83B7;&#x53D6;&#x6A21;&#x5757;id ,&#x518D;&#x8FD4;&#x56DE; defined[id]
            if (typeof deps === &apos;string&apos;) {
                ...
                return defined[id];
            }

            // require-2. &#x6293;&#x53D6;&#x5168;&#x5C40;&#x961F;&#x5217;&#x4E2D;&#x7B49;&#x5F85;&#x7684; defines
            intakeDefines();

            // require-3. &#x5728; nextTick &#x4E2D;&#xFF0C;&#x52A0;&#x8F7D;&#x6240;&#x6709;&#x4F9D;&#x8D56;
            context.nextTick(function () {
                intakeDefines();

                // &#x83B7;&#x53D6;&#x6A21;&#x5757;&#x52A0;&#x8F7D;&#x5668;&#xFF08;&#x91CD;&#x70B9;&#xFF09;
                requireMod = getModule(makeModuleMap(null, relMap));

                requireMod.skipMap = options.skipMap;

                // &#x521D;&#x59CB;&#x5316;&#x6A21;&#x5757;&#xFF08;&#x91CD;&#x70B9;&#xFF09;
                requireMod.init(deps, callback, errback, {
                    enabled: true
                });

                checkLoaded();
            });

            return localRequire;
        }

        // &#x7B2C;&#x4E8C;&#x6B65;&#xFF1A;localReuire &#x589E;&#x52A0; isBrowser, toUrl, defined, specified &#x56DB;&#x4E2A;&#x65B9;&#x6CD5;
        mixin(localRequire, {
            isBrowser: isBrowser,
            toUrl: function (moduleNamePlusExt) { ... }, // module name + .extension &#x8F6C;&#x4E3A; url &#x8DEF;&#x5F84;
            defined: function (id) { ... },
            specified: function (id) { ... }
        });

        // &#x7B2C;&#x4E09;&#x6B65;&#xFF1A;localRequire &#x589E;&#x52A0; undef &#x65B9;&#x6CD5;&#xFF0C;&#x6CE8;&#x610F;&#xFF1A;&#x53EA;&#x5141;&#x8BB8;&#x5728;&#x9876;&#x7EA7; require &#x8C03;&#x7528; undef
        if (!relMap) {
            localRequire.undef = function (id) {
                ...
            };
        }

        // &#x7B2C;&#x56DB;&#x6B65;&#xFF1A;&#x8FD4;&#x56DE; localRequire
        return localRequire;
    }
}

context.require = context.makeRequire()
</code></pre>
<p><code>context.makeRequire()</code> &#x8FD4;&#x56DE;&#x7684;&#x662F; <code>localRequire</code>&#xFF0C;&#x800C; <code>localRequire</code> &#x4F7F;&#x7528; <code>context.nextTick</code>&#xFF0C;&#x5728;&#x672A;&#x6765;&#x7684;&#x4E8B;&#x4EF6;&#x5FAA;&#x73AF;&#x4E2D;&#x52A0;&#x8F7D;&#x4F9D;&#x8D56;&#x3002;</p>
<p><code>nextTick</code> &#x7684;&#x5B9E;&#x73B0;&#x5982;&#x4E0B;&#xFF1A;</p>
<pre><code class="language-js">context = {
    nextTick: req.nextTick,
};
/**
 * &#x5728;&#x5F53;&#x524D;&#x4EFB;&#x52A1;&#x7ED3;&#x675F;&#x4E4B;&#x540E;&#x6267;&#x884C;&#x67D0;&#x4E9B;&#x64CD;&#x4F5C;&#xFF0C;&#x5177;&#x4F53;&#x6765;&#x8BF4;&#x662F;&#x901A;&#x8FC7; setTimeout &#x5C06;&#x64CD;&#x4F5C;&#x653E;&#x5230;&#x4E8B;&#x4EF6;&#x5FAA;&#x73AF;&#x7684;&#x6D88;&#x606F;&#x961F;&#x5217;&#x4E2D;&#xFF0C;&#x6392;&#x961F;&#x7B49;&#x5F85;&#x6267;&#x884C;&#x3002;
 * &#x5176;&#x4ED6;&#x73AF;&#x5883;&#x4E0B;&#xFF0C;&#x5982;&#x679C;&#x6709;&#x6BD4; setTimeout &#x66F4;&#x597D;&#x7684;&#x89E3;&#x51B3;&#x65B9;&#x6848;&#xFF0C;&#x5C31;&#x4F1A;&#x6539;&#x5199;&#x8BE5;&#x65B9;&#x6CD5;&#x3002;
 * &#x6CE8;&#xFF1A;&#x5EF6;&#x65F6; 4ms&#xFF0C;&#x662F;&#x56E0;&#x4E3A; setTimeout &#x7684;&#x6700;&#x5C0F;&#x5EF6;&#x65F6;&#x65F6;&#x95F4;&#x4E3A; 4ms&#x3002;
*/
req.nextTick = typeof setTimeout !== &apos;undefined&apos; ? function (fn) {
    setTimeout(fn, 4);
} : function (fn) { fn(); };
</code></pre>
<p>&#x7EE7;&#x7EED;&#x770B;&#xFF0C;<code>nextTick</code> &#x4E2D;&#x52A0;&#x8F7D;&#x6A21;&#x5757;&#x7684;&#x903B;&#x8F91;&#xFF1A;</p>
<pre><code class="language-js">context.nextTick(function () {
    ...
    // module-1. &#x83B7;&#x53D6;&#x6A21;&#x5757;&#x52A0;&#x8F7D;&#x5668;
    requireMod = getModule(makeModuleMap(null, relMap));
    
    // module-2. &#x521D;&#x59CB;&#x5316;&#x6A21;&#x5757;&#xFF08;&#x91CD;&#x70B9;&#xFF09;
    requireMod.init(deps, callback, errback, {
        enabled: true
    });
    ...
});

// module-1. &#x83B7;&#x53D6;&#x6216;&#x65B0;&#x5EFA;&#x6A21;&#x5757;&#x52A0;&#x8F7D;&#x5668;&#xFF1A;new context.Module(depMap)
function getModule(depMap) {
    var id = depMap.id,
        mod = getOwn(registry, id);

    if (!mod) {
        // &#x65B0;&#x5EFA;&#x4E00;&#x4E2A;&#x6A21;&#x5757;&#x52A0;&#x8F7D;&#x5668;
        mod = registry[id] = new context.Module(depMap);
    }

    return mod;
}

// &#x6A21;&#x5757;&#x52A0;&#x8F7D;&#x5668;&#xFF1A;&#x5305;&#x542B;&#x5C5E;&#x6027;&#x548C;&#x539F;&#x578B;&#x65B9;&#x6CD5;
Module = function (map) {
    this.map = map;
    ...
};
Module.prototype = {
    ...
};
context = {
    ...
    Module: Module
}
</code></pre>
<p>&#x8FD9;&#x91CC;&#x901A;&#x8FC7; <code>getModule</code> &#x8FD4;&#x56DE; <code>Module</code> &#x7684;&#x5B9E;&#x4F8B;&#xFF0C;<code>Module</code> &#x5305;&#x542B;&#x6A21;&#x5757;&#x76F8;&#x5173;&#x7684;&#x5C5E;&#x6027;&#x548C;&#x65B9;&#x6CD5;&#x3002;</p>
<p>&#x63A5;&#x4E0B;&#x6765;&#xFF0C;&#x8C03;&#x7528; <code>Module</code> &#x7684; <code>init</code> &#x65B9;&#x6CD5;&#x521D;&#x59CB;&#x5316;&#x6A21;&#x5757;&#xFF1A;</p>
<pre><code class="language-js">// module-2. &#x521D;&#x59CB;&#x5316;&#x6A21;&#x5757;
Module.prototype = {
    init: function (depMaps, factory, errback, options) {
        ...

        // &#x5982;&#x679C;&#x672A;&#x542F;&#x52A8;&#xFF0C;&#x5C31;&#x542F;&#x52A8;&#x8BE5;&#x6A21;&#x5757;&#x3002;&#x5982;&#x679C;&#x5DF2;&#x542F;&#x52A8;&#xFF0C;&#x68C0;&#x67E5;&#x5E76;&#x542F;&#x52A8;&#x5176;&#x4F9D;&#x8D56;&#x9879;&#x3002;
        if (options.enabled || this.enabled) {
            this.enable();
        } else {
            this.check();
        }
    },
    enable: function () {
        ... 
        // module-2.1. &#x904D;&#x5386;&#x542F;&#x52A8;&#x4F9D;&#x8D56;
        each(this.depMaps, bind(this, function (depMap, i) {
            ...
            if (!hasProp(handlers, id) &amp;&amp; mod &amp;&amp; !mod.enabled) {
                // &#x8C03;&#x7528; context.enable &#x542F;&#x52A8;
                context.enable(depMap, this);
            }
        }));

        // module-2.2. &#x52A0;&#x8F7D;&#x5F53;&#x524D;&#x6A21;&#x5757;
        this.check();
    }
}

context = {
    ...
    enable: function (depMap) {
        // &#x5982;&#x679C;&#x6A21;&#x5757;&#x4ECD;&#x5728;&#x6CE8;&#x518C;&#x8868;&#x4E2D;&#x7B49;&#x5F85;&#x542F;&#x52A8;&#xFF0C;&#x5219;&#x542F;&#x52A8;&#x8BE5;&#x6A21;&#x5757;&#x3002;
        var mod = getOwn(registry, depMap.id);
        if (mod) {
            // &#x9012;&#x5F52;&#x52A0;&#x8F7D;&#x4F9D;&#x8D56;&#x9879;&#xFF0C;getModule&#xFF0C;&#x5E76; enable
            getModule(depMap).enable();
        }
    },
}
</code></pre>
<p>module-2.1 &#x7684;&#x6267;&#x884C;&#x6D41;&#x7A0B;&#xFF1A;<code>this.init()</code> -&gt; <code>this.enale()</code> -&gt; <code>context.enable(depMap, this)</code> -&gt; <code>getModule(depMap).enable()</code> -&gt; ...<br>
&#x5728;&#x5F53;&#x524D;&#x6A21;&#x5757;&#x6267;&#x884C; <code>enable()</code> &#x65F6;&#xFF0C;&#x904D;&#x5386;&#x542F;&#x52A8;&#x4F9D;&#x8D56;&#x6A21;&#x5757;&#xFF1B;&#x4F9D;&#x8D56;&#x6A21;&#x5757;&#x6267;&#x884C; <code>enable()</code> &#x65F6;&#xFF0C;&#x53C8;&#x4F1A;&#x904D;&#x5386;&#x542F;&#x52A8;&#x5B83;&#x91CC;&#x9762;&#x7684;&#x4F9D;&#x8D56;&#x3002;&#x5C31;&#x8FD9;&#x6837;&#xFF0C;&#x901A;&#x8FC7;&#x9012;&#x5F52;&#xFF0C;&#x542F;&#x52A8;&#x6240;&#x6709;&#x4F9D;&#x8D56;&#x6A21;&#x5757;&#x3002;</p>
<p>&#x7EE7;&#x7EED;&#x770B; module-2.2 <code>this.check()</code> &#x52A0;&#x8F7D;&#x5F53;&#x524D;&#x6A21;&#x5757;&#x3002;</p>
<pre><code class="language-js">Module.prototype = {
    check: function () {
        ...

        if (!this.inited) {
            // &#x8C03;&#x7528; this.fetch
            if (!hasProp(context.defQueueMap, id)) {
                this.fetch();
            }
        }
        ...
    },
    fetch: function () {
        ...
        // &#x8C03;&#x7528; this.load&#x3002;this.callPlugin &#x662F;&#x52A0;&#x8F7D;&#x63D2;&#x4EF6;&#x7684;&#xFF0C;&#x6700;&#x7EC8;&#x4E5F;&#x4F1A;&#x8C03;&#x7528; this.load()&#x3002;
        return map.prefix ? this.callPlugin() : this.load();
    },
    load: function () {
        var url = this.map.url;

        if (!urlFetched[url]) {
            urlFetched[url] = true;
            // &#x8C03;&#x7528; context.load
            context.load(this.map.id, url);
        }
    }
}

context = {
    ...
    // &#x6267;&#x884C; req.load
    load: function (id, url) {
        req.load(context, id, url);
    }
}

req.load = function (context, moduleName, url) {
    var config = (context &amp;&amp; context.config) || {},
        node;
    if (isBrowser) {
        // &#x6D4F;&#x89C8;&#x5668;&#x73AF;&#x5883;&#xFF0C;&#x65B0;&#x5EFA; script &#x6807;&#x7B7E;
        node = req.createNode(config, moduleName, url);

        // &#x8BB0;&#x5F55;&#x4E0A;&#x4E0B;&#x6587;&#x540D;&#x548C;&#x6A21;&#x5757;&#x540D;
        node.setAttribute(&apos;data-requirecontext&apos;, context.contextName);
        node.setAttribute(&apos;data-requiremodule&apos;, moduleName);

        // &#x76D1;&#x542C;&#x4E8B;&#x4EF6;
        if (node.attachEvent &amp;&amp;
                !(node.attachEvent.toString &amp;&amp; node.attachEvent.toString().indexOf(&apos;[native code&apos;) &lt; 0) &amp;&amp;
                !isOpera) {
            // &#x517C;&#x5BB9; IE
            useInteractive = true;

            node.attachEvent(&apos;onreadystatechange&apos;, context.onScriptLoad);
        } else {
            node.addEventListener(&apos;load&apos;, context.onScriptLoad, false);
            node.addEventListener(&apos;error&apos;, context.onScriptError, false);
        }
        // &#x8BBE;&#x7F6E; src
        node.src = url;

        if (config.onNodeCreated) {
            config.onNodeCreated(node, config, moduleName, url);
        }

        // &#x63D2;&#x5165; scirpt &#x6807;&#x7B7E;
        currentlyAddingScript = node;
        if (baseElement) {
            head.insertBefore(node, baseElement);
        } else {
            head.appendChild(node);
        }
        currentlyAddingScript = null;

        return node;
    } else if (isWebWorker) {
        ...
    }
};

// &#x65B0;&#x5EFA; script &#x8282;&#x70B9;
req.createNode = function (config, moduleName, url) {
    var node = config.xhtml ?
            document.createElementNS(&apos;http://www.w3.org/1999/xhtml&apos;, &apos;html:script&apos;) :
            document.createElement(&apos;script&apos;);
    node.type = config.scriptType || &apos;text/javascript&apos;;
    node.charset = &apos;utf-8&apos;;
    node.async = true;
    return node;
};
</code></pre>
<p>module-2.2 &#x52A0;&#x8F7D;&#x6A21;&#x5757;&#x7684;&#x6267;&#x884C;&#x6D41;&#x7A0B;&#xFF1A;<code>this.check()</code> -&gt; <code>this.fetch()</code> -&gt; <code>this.load()</code> -&gt; <code>context.load()</code> -&gt; <code>req.load()</code> -&gt; <code>req.createNode()</code>&#x3002;<br>
&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&#x5728;&#x6D4F;&#x89C8;&#x5668;&#x73AF;&#x5883;&#xFF0C;&#x662F;&#x901A;&#x8FC7;&#x63D2;&#x5165; <code>&lt;script&gt;</code> &#x6807;&#x7B7E;&#xFF0C;&#x8BBE;&#x7F6E; <code>node.src = url</code> &#x6765;&#x52A0;&#x8F7D;&#x6A21;&#x5757;&#x7684;&#x3002;</p>
<h3 id="define-%E5%AE%9A%E4%B9%89%E6%A8%A1%E5%9D%97">define &#x5B9A;&#x4E49;&#x6A21;&#x5757;</h3>
<p>&#x5728; requirejs &#x7684;&#x4F7F;&#x7528;&#x793A;&#x4F8B;&#x4E2D;&#xFF0C;&#x6709;&#x4E00;&#x4E2A; test &#x6A21;&#x5757;&#x3002;&#x5728;&#x8C03;&#x7528; <code>require</code> &#x51FD;&#x6570;&#x65F6;&#xFF0C;&#x4F1A;&#x901A;&#x8FC7; <code>context.require(deps, callback, errback)</code>&#xFF0C;&#x52A0;&#x8F7D; test.js&#x3002;</p>
<pre><code class="language-js">// a/b.js

// &#x52A0;&#x8F7D;&#x6A21;&#x5757;
requirejs([&apos;test&apos;], function(test) {
    test.compare(2, 5)
});
</code></pre>
<p>&#x800C; test.js &#x4E2D;&#xFF0C;&#x901A;&#x8FC7; <code>define</code> &#x51FD;&#x6570;&#x5B9A;&#x4E49;&#x4E86; test &#x6A21;&#x5757;&#x3002;</p>
<pre><code class="language-js">// test.js

define(&apos;test&apos;, function() {
    return {
        compare: function(a, b) {
            return a &gt; b;
        }
    }
});
</code></pre>
<p>&#x4E0B;&#x9762;&#x770B;&#x4E00;&#x4E0B; <code>define</code> &#x51FD;&#x6570;&#x7684;&#x5B9E;&#x73B0;&#xFF1A;</p>
<pre><code class="language-js">commentRegExp = /\/\*[\s\S]*?\*\/|([^:&quot;&apos;=]|^)\/\/.*$/mg,
cjsRequireRegExp = /[^.]\s*require\s*\(\s*[&quot;&apos;]([^&apos;&quot;\s]+)[&quot;&apos;]\s*\)/g,

define = function (name, deps, callback) {
    var node, context;

    // &#x7B2C;&#x4E00;&#x6B65;&#xFF1A;&#x6CA1;&#x6709;&#x4F20;&#x5165; name&#xFF0C;&#x8C03;&#x6574;&#x53C2;&#x6570;
    // &#x793A;&#x4F8B;&#x4E2D;&#x7684; test &#x6A21;&#x5757;&#xFF0C;name &#x4E3A; &apos;test&apos;
    if (typeof name !== &apos;string&apos;) {
        callback = deps;
        deps = name;
        name = null;
    }

    // &#x7B2C;&#x4E8C;&#x6B65;&#xFF1A;&#x6CA1;&#x6709;&#x4F20;&#x5165; deps&#xFF0C;&#x8C03;&#x6574;&#x53C2;&#x6570;
    // test &#x6A21;&#x5757;&#xFF0C;&#x6CA1;&#x6709;&#x4F20;&#x5165; deps&#xFF0C;callback = fn&#xFF0C;deps = null
    if (!isArray(deps)) {
        callback = deps;
        deps = null;
    }

    // &#x7B2C;&#x4E09;&#x6B65;&#xFF1A;&#x6CA1;&#x6709;&#x4F20;&#x5165; deps, callback &#x4E3A;&#x51FD;&#x6570;&#xFF0C;&#x4ECE; callback &#x4E2D;&#x83B7;&#x53D6;&#x4F9D;&#x8D56;
    // test &#x6A21;&#x5757;&#xFF0C;&#x6267;&#x884C;&#x8FD9;&#x90E8;&#x5206;&#x4EE3;&#x7801;&#xFF0C;&#x7531;&#x4E8E; callback &#x6CA1;&#x6709;&#x5F62;&#x5F0F;&#x53C2;&#x6570;&#xFF0C;&#x7ED3;&#x679C;&#xFF1A;deps = []
    if (!deps &amp;&amp; isFunction(callback)) {
        deps = [];
        if (callback.length) {
            callback
                .toString()
                .replace(commentRegExp, commentReplace) // &#x5220;&#x9664;&#x6CE8;&#x91CA;
                .replace(cjsRequireRegExp, function (match, dep) { // &#x83B7;&#x53D6;&#x4F9D;&#x8D56;&#x6A21;&#x5757;
                    deps.push(dep);
                });

            // Function.length &#x5BF9;&#x5E94;&#x51FD;&#x6570;&#x5F62;&#x53C2;&#x7684;&#x4E2A;&#x6570;&#xFF0C;&#x53EA;&#x6709;&#x4E00;&#x4E2A;&#x53C2;&#x6570;&#x65F6;&#xFF0C;deps = [&apos;require&apos;]&#xFF1B;&#x5426;&#x5219; deps = [&apos;require&apos;, &apos;exports&apos;, &apos;module&apos;, ...deps]
            deps = (callback.length === 1 ? [&apos;require&apos;] : [&apos;require&apos;, &apos;exports&apos;, &apos;module&apos;]).concat(deps);
        }
    }

    // &#x7B2C;&#x56DB;&#x6B65;&#xFF1A;&#x517C;&#x5BB9; IE 6-8
    // test &#x6A21;&#x5757;&#xFF0C;&#x975E; IE&#xFF0C;&#x4E0D;&#x6267;&#x884C;&#x8FD9;&#x90E8;&#x5206;&#x4EE3;&#x7801;
    if (useInteractive) {
        node = currentlyAddingScript || getInteractiveScript();
        if (node) {
            if (!name) {
                name = node.getAttribute(&apos;data-requiremodule&apos;);
            }
            context = contexts[node.getAttribute(&apos;data-requirecontext&apos;)];
        }
    }

    /**
     * &#x7B2C;&#x4E94;&#x6B65;&#xFF1A;&#x5982;&#x679C;&#x6709;&#x4E0A;&#x4E0B;&#x6587;&#xFF0C;&#x5219;&#x5C06;&#x4F9D;&#x8D56;&#x52A0;&#x5165; context.defQueue&#x3002;&#x5982;&#x679C;&#x6CA1;&#x6709;&#x4E0A;&#x4E0B;&#x6587;&#xFF0C;&#x5219;&#x5C06;&#x4F9D;&#x8D56;&#x52A0;&#x5165;&#x5168;&#x5C40;&#x961F;&#x5217;&#x3002;
     * &#x811A;&#x672C; onload &#x65F6;&#xFF0C;&#x518D;&#x8C03;&#x7528; def&#x3002;&#x8FD9;&#x5141;&#x8BB8;&#x4E00;&#x4E2A;&#x6587;&#x4EF6;&#x6709;&#x591A;&#x4E2A;&#x6A21;&#x5757;&#xFF0C;&#x800C;&#x4E0D;&#x4F1A;&#x8FC7;&#x65E9;&#x5730;&#x8DDF;&#x8E2A;&#x4F9D;&#x8D56;&#xFF0C;&#x5E76;&#x652F;&#x6301;&#x533F;&#x540D;&#x6A21;&#x5757;&#xFF0C;&#x5176;&#x4E2D;&#x6A21;&#x5757;&#x540D;&#x79F0;&#x5728;&#x811A;&#x672C; onload &#x4E8B;&#x4EF6;&#x53D1;&#x751F;&#x4E4B;&#x524D;&#x662F;&#x672A;&#x77E5;&#x7684;&#x3002;
    */
    // test &#x6A21;&#x5757;&#xFF0C;&#x7531;&#x4E8E;&#x6CA1;&#x6709;&#x6267;&#x884C;&#x7B2C;&#x56DB;&#x6B65;&#xFF0C;&#x6CA1;&#x6709;&#x83B7;&#x53D6; context&#xFF0C;&#x6240;&#x4EE5;&#x52A0;&#x5165; globalDefQueue&#x3002;
    if (context) {
        context.defQueue.push([name, deps, callback]);
        context.defQueueMap[name] = true;
    } else {
        globalDefQueue.push([name, deps, callback]);
    }
};
</code></pre>
<p>&#x901A;&#x8FC7; <code>define(&apos;test&apos;, function() {...})</code>&#xFF0C;&#x4F9D;&#x8D56;&#x6A21;&#x5757;&#x52A0;&#x5165; <code>context.defQueue</code> &#x6216; <code>globalDefQueue</code> &#x4E2D;&#xFF0C;&#x5728;&#x811A;&#x672C; <code>onload</code> &#x4E4B;&#x540E;&#x52A0;&#x8F7D;&#x4F9D;&#x8D56;&#x6A21;&#x5757;&#x3002;</p>
<p>&#x56DE;&#x987E;&#x524D;&#x9762;&#x52A0;&#x8F7D;&#x6A21;&#x5757;&#x7684;&#x6D41;&#x7A0B;&#xFF0C;module-2.2 <code>this.check()</code> -&gt; <code>this.fetch()</code> -&gt; <code>this.load()</code> -&gt; <code>context.load()</code> -&gt; <code>req.load()</code>&#x3002;&#x5728; <code>req.load</code> &#x4E2D;&#xFF0C;&#x4F1A;&#x76D1;&#x542C; test &#x811A;&#x672C;&#x7684; <code>load</code> &#x4E8B;&#x4EF6;&#xFF0C;&#x5E76;&#x5728;&#x8FD9;&#x91CC;&#x518D;&#x6B21;&#x521D;&#x59CB;&#x5316; test &#x6A21;&#x5757;&#x3002;&#x5177;&#x4F53;&#x5982;&#x4E0B;&#xFF1A;</p>
<pre><code class="language-js">req.load = function (context, moduleName, url) {
    ...
    // &#x7B2C;&#x4E00;&#x6B65;&#xFF1A;&#x76D1;&#x542C; script &#x7684; load &#x4E8B;&#x4EF6;&#xFF0C;&#x8C03;&#x7528; context.onScriptLoad
    node.addEventListener(&apos;load&apos;, context.onScriptLoad, false);
    ...
};

function newContext(contextName) {
    var defQueue = []

    context = {
        ...
        defQueue: defQueue,
        onScriptLoad: function (evt) {
            if (evt.type === &apos;load&apos; ||
                    (readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) {
                interactiveScript = null;

                // &#x7B2C;&#x4E8C;&#x6B65;&#xFF1A;&#x83B7;&#x53D6;&#x6A21;&#x5757;&#x540D;&#xFF0C;&#x8C03;&#x7528; completeLoad
                var data = getScriptData(evt);
                context.completeLoad(data.id);
            }
        },
        completeLoad: function (moduleName) {
            var found, args, mod,
                shim = getOwn(config.shim, moduleName) || {},
                shExports = shim.exports;

            // &#x7B2C;&#x4E09;&#x6B65;&#xFF1A;&#x83B7;&#x53D6;&#x5168;&#x5C40;&#x4F9D;&#x8D56;&#x6A21;&#x5757;
            takeGlobalQueue();

            while (defQueue.length) {
                args = defQueue.shift();
                if (args[0] === null) {
                    args[0] = moduleName;
                    if (found) {
                        break;
                    }
                    found = true;
                } else if (args[0] === moduleName) {
                    found = true;
                }

                // &#x7B2C;&#x56DB;&#x6B65;&#xFF1A;&#x83B7;&#x53D6;&#x6A21;&#x5757;&#x5E76;&#x521D;&#x59CB;&#x5316;
                callGetModule(args);
            }
            context.defQueueMap = {};

            ...
        },
    }

    function takeGlobalQueue() {
        // &#x5C06; globalDefQueue &#x4E2D;&#x7684;&#x4F9D;&#x8D56;&#x653E;&#x5165; context &#x7684; defQueue
        if (globalDefQueue.length) {
            each(globalDefQueue, function(queueItem) {
                var id = queueItem[0];
                if (typeof id === &apos;string&apos;) {
                    context.defQueueMap[id] = true;
                }
                defQueue.push(queueItem);
            });
            globalDefQueue = [];
        }
    }

    function callGetModule(args) {
        // &#x8DF3;&#x8FC7;&#x5DF2;&#x5B9A;&#x4E49;&#x7684;&#x6A21;&#x5757;
        if (!hasProp(defined, args[0])) {
            // &#x83B7;&#x53D6;&#x6A21;&#x5757;&#xFF0C;&#x521D;&#x59CB;&#x5316;
            getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]);
        }
    }
}
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&#x4F9D;&#x7136;&#x662F;&#x901A;&#x8FC7; <code>getModule</code> &#x83B7;&#x53D6;&#x6A21;&#x5757;&#xFF0C;&#x518D;&#x901A;&#x8FC7; <code>init</code> &#x521D;&#x59CB;&#x5316;&#x3002;&#x521D;&#x59CB;&#x5316;&#x6D41;&#x7A0B;&#x548C;&#x524D;&#x9762; req &#x51FD;&#x6570;&#x4E00;&#x6837;&#xFF1A;<code>this.init()</code> -&gt; <code>this.enale()</code> -&gt; &#x904D;&#x5386;&#x542F;&#x52A8;&#x4F9D;&#x8D56;&#x6A21;&#x5757;&#xFF08;test &#x6A21;&#x5757;&#x6CA1;&#x6709;&#x4F9D;&#x8D56;&#xFF0C;&#x8DF3;&#x8FC7;&#xFF09; -&gt; <code>this.check()</code>&#xFF0C;&#x4E0D;&#x518D;&#x8D58;&#x8FF0;&#x3002;&#x4E0D;&#x540C;&#x7684;&#x662F;&#xFF0C;<code>this.check()</code> &#x4E2D;&#x7684;&#x6D41;&#x7A0B;&#xFF08;&#x6267;&#x884C; test &#x6A21;&#x5757;&#x7684;&#x5DE5;&#x5382;&#x51FD;&#x6570;&#xFF0C;&#x5E76;&#x8D4B;&#x503C;&#x7ED9; <code>this.exports</code> &#x548C; <code>defined[&apos;test&apos;]</code>&#xFF09;&#xFF1A;</p>
<pre><code class="language-js">Module.prototype = {
    check: function () {
        ...
        // &#x5DF2;&#x7ECF;&#x521D;&#x59CB;&#x5316;&#x8FC7;&#xFF0C;&#x8FD9;&#x6B21;&#x4E0D;&#x8D70; this.fetch()
        if (!this.inited) {
            if (!hasProp(context.defQueueMap, id)) {
                this.fetch();
            }
        } else if (this.error) {
            this.emit(&apos;error&apos;, this.error);
        } else if (!this.defining) {
            // &#x8D70;&#x8FD9;&#x4E2A;&#x6D41;&#x7A0B;
            this.defining = true;

            if (this.depCount &lt; 1 &amp;&amp; !this.defined) {
                if (isFunction(factory)) {
                    // &#x7B2C;&#x4E00;&#x6B65;&#xFF1A;&#x8C03;&#x7528; context.execCb&#xFF0C;&#x6267;&#x884C; factory &#x51FD;&#x6570;&#xFF0C;&#x6267;&#x884C;&#x7ED3;&#x679C;&#x8D4B;&#x503C;&#x7ED9; exports
                    // &#x5BF9;&#x4E8E; test &#x6A21;&#x5757;&#xFF0C;&#x5165;&#x53C2; id = &quot;test&quot;, factory = test &#x6A21;&#x5757;&#x7684;&#x5DE5;&#x5382;&#x51FD;&#x6570;, depExports = [], exports = undefined, &#x7ED3;&#x679C;&#xFF1A;exports = { compare: fn }
                    if ((this.events.error &amp;&amp; this.map.isDefine) ||
                        req.onError !== defaultOnError) {
                        try {
                            exports = context.execCb(id, factory, depExports, exports);
                        } catch (e) {
                            err = e;
                        }
                    } else {
                        exports = context.execCb(id, factory, depExports, exports);
                    }
                    ...
                } else {
                    exports = factory;
                }

                this.exports = exports;

                if (this.map.isDefine &amp;&amp; !this.ignore) {
                    // &#x7B2C;&#x4E8C;&#x6B65;&#xFF1A;&#x8BBE;&#x7F6E; defined[id]
                    // &#x5BF9;&#x4E8E; test &#x6A21;&#x5757;&#xFF0C;id = &apos;test&apos;, exports = { compare: fn }&#xFF0C;&#x7ED3;&#x679C;: defined[&apos;test&apos;] = { compare: fn }
                    defined[id] = exports;
                    
                    if (req.onResourceLoad) {
                        var resLoadMaps = [];
                        each(this.depMaps, function (depMap) {
                            resLoadMaps.push(depMap.normalizedMap || depMap);
                        });
                        req.onResourceLoad(context, this.map, resLoadMaps);
                    }
                }

                cleanRegistry(id);

                this.defined = true;
            }
            
            this.defining = false;

            if (this.defined &amp;&amp; !this.defineEmitted) {
                this.defineEmitted = true;
                // &#x7B2C;&#x4E09;&#x6B65;&#xFF1A;&#x89E6;&#x53D1; defined &#x4E8B;&#x4EF6;
                this.emit(&apos;defined&apos;, this.exports);
                this.defineEmitComplete = true;
            }

        }
    },
    // &#x6CE8;&#x610F;&#xFF1A;&#x8FD9;&#x91CC; enable &#x7684;&#x6A21;&#x5757;&#x5BF9;&#x5E94; require([&apos;test&apos;], f(test))&#xFF0C;&#x5728;&#x8BE5;&#x6A21;&#x5757; enable &#x65F6;&#x904D;&#x5386;&#x5176;&#x4F9D;&#x8D56; [&apos;test&apos;]&#xFF0C;&#x5E76;&#x76D1;&#x542C;&#x4F9D;&#x8D56;&#x7684; defined &#x4E8B;&#x4EF6;
    enable: function () {
        ...
        each(this.depMaps, bind(this, function (depMap, i) {
            var id, mod, handler;

            if (typeof depMap === &apos;string&apos;) {
                ...
                this.depCount += 1;

                // &#x7B2C;&#x56DB;&#x6B65;&#xFF1A;&#x76D1;&#x542C; defined &#x4E8B;&#x4EF6;
                // test &#x6A21;&#x5757;&#xFF0C;depExports = { compare: fn }
                on(depMap, &apos;defined&apos;, bind(this, function (depExports) {
                    if (this.undefed) {
                        return;
                    }
                    // &#x7B2C;&#x4E94;&#x6B65;&#xFF1A;&#x5C06; exports &#x5B58;&#x653E;&#x5230; this.depExports &#x6570;&#x7EC4;&#x4E2D;
                    this.defineDep(i, depExports);
                    // &#x7B2C;&#x516D;&#x6B65;&#xFF1A;&#x518D;&#x6B21;&#x6267;&#x884C; this.check()
                    this.check();
                }));
                ...
            }
            ...
        }
        ...
    },
    defineDep: function (i, depExports) {
        if (!this.depMatched[i]) {
            this.depMatched[i] = true;
            this.depCount -= 1;
            // &#x5C06; exports &#x5B58;&#x653E;&#x5230; this.depExports &#x6570;&#x7EC4;&#x4E2D;
            this.depExports[i] = depExports;
        }
    },
}

function newContext(contextName) {
    context = {
        execCb: function (name, callback, args, exports) {
            return callback.apply(exports, args);
        },
        ...
    }
}
</code></pre>
<p>&#x8FD9;&#x91CC;&#xFF0C;&#x6267;&#x884C; <code>define(&apos;test&apos;, function() {...})</code> &#x4E2D;&#x5DE5;&#x5382;&#x51FD;&#x6570;&#xFF0C;&#x5F97;&#x5230; test &#x6A21;&#x5757;&#x7684;&#x5BF9;&#x8C61; <code>{ compare: fn }</code>&#x3002;&#x518D;&#x5C06;&#x6A21;&#x5757;&#x5BF9;&#x8C61;&#x8D4B;&#x503C;&#x7ED9; <code>this.exports</code>&#xFF0C;&#x7528;&#x4E8E;&#x8F93;&#x51FA;&#x6A21;&#x5757;&#x5BF9;&#x8C61;&#x3002;&#x540C;&#x65F6;&#x4FDD;&#x5B58;&#x5230;&#x4E0A;&#x4E0B;&#x6587;&#x7684; <code>defined</code> &#x5BF9;&#x8C61;&#x4E2D;&#xFF0C;&#x7F13;&#x5B58;&#x8D77;&#x6765;&#x3002;&#xFF08;&#x7B2C;&#x4E00;&#x6B65; - &#x7B2C;&#x4E8C;&#x6B65;&#xFF09;</p>
<p>&#x63A5;&#x7740;&#xFF0C;&#x89E6;&#x53D1; <code>defined</code> &#x4E8B;&#x4EF6;&#xFF0C;&#x5C06; <code>exports</code> &#x5B58;&#x653E;&#x5230; <code>this.depExports</code> &#x6570;&#x7EC4;&#x4E2D;&#xFF0C;&#x5E76;&#x6267;&#x884C; <code>require([&apos;test&apos;], f(test))</code> &#x6A21;&#x5757;&#x7684; <code>this.check()</code>&#x3002;&#xFF08;&#x7B2C;&#x4E09;&#x6B65; - &#x7B2C;&#x516D;&#x6B65;&#xFF09;</p>
<p>&#x7EE7;&#x7EED;&#x770B;&#x8FD9;&#x4E00;&#x6B21;&#x7684; <code>this.check()</code> &#x6D41;&#x7A0B;&#xFF1A;</p>
<pre><code class="language-js">Module.prototype = {
    check: function () {
        ...
        // factory = require &#x4E2D;&#x7684;&#x51FD;&#x6570; f(test), depExports = [compare], exports = undefined
        // &#x8C03;&#x7528; context.execCb&#xFF0C;&#x6267;&#x884C; require([&apos;test&apos;], function (test) {}) &#x4E2D;&#x7684;&#x51FD;&#x6570;&#xFF0C;&#x5E76;&#x5C06; depExports&#xFF08;&#x5373; test &#x6A21;&#x5757;&#x7684;&#x8FD4;&#x56DE;&#x503C;&#xFF0C;compare &#x51FD;&#x6570;&#xFF09; &#x4F5C;&#x4E3A;&#x53C2;&#x6570;&#x4F20;&#x5165;&#x3002;
        exports = context.execCb(id, factory, depExports, exports);
        ...
        }
    }
}
</code></pre>
<p>&#x8FD9;&#x6B21;&#x8C03;&#x7528; <code>check</code>&#xFF0C;&#x6267;&#x884C;&#x7684;&#x662F; <code>require</code> &#x4E2D;&#x4F20;&#x5165;&#x7684;&#x51FD;&#x6570;&#xFF0C;&#x5E76;&#x5C06; <code>this.depExports</code> &#x4F5C;&#x4E3A;&#x53C2;&#x6570;&#x4F20;&#x5165;&#xFF0C;&#x4E5F;&#x5C31;&#x662F;&#x524D;&#x9762; test &#x6A21;&#x5757;&#x7684;&#x8FD4;&#x56DE;&#x503C; <code>{ compare: fn }</code>&#x3002;&#x81F3;&#x6B64;&#xFF0C;test &#x6A21;&#x5757;&#x52A0;&#x8F7D;&#x5B8C;&#x6210;&#x3002;</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[快应用开发工具 5.0 版本发布]]></title><description><![CDATA[快应用开发者工具（IDE），专为快应用开发设计，支持快应用、卡片等开发调试、编译预览、打包上传、以及云测、远程预览.....并支持账号登录，应用关联，查看详情等；仍在不断快速迭代中，旨在让开发者能够更高效开发、调试、测试以及发布快应用。]]></description><link>https://quickapp.vivo.com.cn/quickapp-ide-v5-0-release/</link><guid isPermaLink="false">63c4b94a77e2ca0006a8c899</guid><category><![CDATA[快应用开发工具]]></category><dc:creator><![CDATA[vivo-developer]]></dc:creator><pubDate>Thu, 23 Sep 2021 07:25:48 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>&#x5FEB;&#x5E94;&#x7528;&#x5DE5;&#x5177;&#x5F00;&#x53D1;&#x56E2;&#x961F;&#xFF0C;&#x4E8E; 2021 &#x5E74; 9 &#x6708; 22 &#x65E5;&#xFF0C;&#x53D1;&#x5E03; IDE &#x6700;&#x65B0;&#x7248;&#x672C;&#xFF1A;<a href="https://www.quickapp.cn/docCenter/post/97">v5.0.0</a>&#x3002;</p>
<h2 id="v50-%E6%9B%B4%E6%96%B0%E8%AF%B4%E6%98%8E"><code>v5.0</code> &#x66F4;&#x65B0;&#x8BF4;&#x660E;</h2>
<p>&#x5728; 9 &#x6708;&#x5373;&#x5C06;&#x7ED3;&#x675F;&#x4E4B;&#x9645;&#xFF0C;&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x56E2;&#x961F;&#xFF0C;&#x5C06;&#x4E4B;&#x524D;&#x9057;&#x7559;&#x7684;&#x4E00;&#x4E9B;&#x672A;&#x89E3;&#x51B3;&#x95EE;&#x9898;&#xFF0C;&#x505A;&#x4E86;&#x5904;&#x7406;&#x548C;&#x4F18;&#x5316;&#xFF0C;&#x63A8;&#x51FA;&#x6700;&#x65B0; <a href="https://www.quickapp.cn/docCenter/post/97">v5.0.0</a> &#x7248;&#x672C;&#xFF1B;&#x4E0B;&#x9762;&#x8BF7;&#x5141;&#x8BB8;&#x8DDF;&#x5927;&#x5BB6;&#x5206;&#x4EAB;&#x4E0B;&#xFF0C;&#x5728;&#x6B64;&#x6B21;&#x8FED;&#x4EE3;&#xFF0C;&#x6211;&#x4EEC;&#x505A;&#x4E86;&#x4E00;&#x4E9B;&#x91CD;&#x8981;&#x6539;&#x8FDB;&#x3002;</p>
<h3 id="%E4%BC%98%E5%8C%96%E6%9B%B4%E6%96%B0">&#x4F18;&#x5316;&#x66F4;&#x65B0;</h3>
<h4 id="%E4%BE%9D%E8%B5%96%E5%88%86%E6%9E%90%E6%8F%92%E4%BB%B6">&#x4F9D;&#x8D56;&#x5206;&#x6790;&#x63D2;&#x4EF6;</h4>
<p>&#x5FEB;&#x5E94;&#x7528; IDE &#x63D0;&#x4F9B;&#x4EE3;&#x7801;&#x9759;&#x6001;&#x4F9D;&#x8D56;&#x5206;&#x6790;&#x63D2;&#x4EF6;&#xFF0C;&#x65E8;&#x5728;&#x65B9;&#x4FBF;&#x5F00;&#x53D1;&#x8005;&#x67E5;&#x770B;&#x4EE3;&#x7801;&#x6587;&#x4EF6;&#x6784;&#x6210;&#x548C;&#x4F9D;&#x8D56;&#x5173;&#x7CFB;&#xFF0C;&#x4EE5;&#x4F18;&#x5316;&#x4EE3;&#x7801;&#x5305;&#x5927;&#x5C0F;&#x548C;&#x5185;&#x5BB9;&#xFF08;&#x4F18;&#x5316;&#x8D44;&#x6E90;&#x5C3A;&#x5BF8;&#x3001;&#x5254;&#x9664;&#x91CD;&#x590D;&#x6784;&#x5EFA;&#x7B49;&#xFF0C;&#x5177;&#x4F53;&#x64CD;&#x4F5C;&#x53EF;&#x53C2;&#x89C1;&#x6587;&#x7AE0; &#x2500;&#x2500; <a href="https://forum.lovejade.cn/d/83-rpk">&#x5982;&#x4F55;&#x4F18;&#x5316;&#x300C;&#x5FEB;&#x5E94;&#x7528;&#x300D;rpk &#x5305;&#x4F53;&#x79EF;&#xFF1F;</a>&#xFF09;&#xFF0C;&#x4ECE;&#x800C;&#x4FC3;&#x8FDB;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x8FD0;&#x884C;&#x66F4;&#x8FC5;&#x901F;&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;&#xFF1A;</strong> &#x9700;&#x8981;&#x5148;&#x5B89;&#x88C5;&#x63D2;&#x4EF6; <code>hap-bundle-analyzer</code>&#xFF0C;&#x8BF7;&#x5728;&#x63D2;&#x4EF6;&#x5E02;&#x573A;&#x5B89;&#x88C5;&#x3002;</p>
<p>&#x5B89;&#x88C5;&#x5B8C;&#x6210;&#x4E4B;&#x540E;&#xFF0C;&#x53EF;&#x901A;&#x8FC7;&#x4FA7;&#x8FB9;&#x680F;&#x300C;<strong>&#x5FEB;&#x6377;&#x5165;&#x53E3;</strong>&#x300D;&#x300C;<strong>&#x4F9D;&#x8D56;&#x5206;&#x6790;</strong>&#x300D;&#x6216;&#x8005; <code>ctrl + shift + p</code> &#x8F93;&#x5165; <code>quickapp analyzer</code> &#x4F7F;&#x7528;&#x8BE5;&#x529F;&#x80FD;&#x3002;</p>
<ul>
<li>
<p>&#x8D44;&#x6E90;&#x4F9D;&#x8D56;&#x5206;&#x6790;</p>
<p>&#x7ED9;&#x4E88;&#x7528;&#x6237;&#x76F4;&#x89C2;&#x7684;&#x663E;&#x793A;&#x6253;&#x5305;&#x540E;&#x7684;&#x8D44;&#x6E90;&#x6587;&#x4EF6;&#x7684;&#x8DEF;&#x5F84;&#x5217;&#x8868;&#x53CA;&#x5176;&#x5927;&#x5C0F;&#xFF0C;&#x65B9;&#x4FBF;&#x7528;&#x6237;&#x4F18;&#x5316;&#x8D44;&#x6E90;&#x6587;&#x4EF6;&#x7684;&#x4F53;&#x79EF;&#xFF1A;</p>
<ul>
<li>
<p>&#x8D44;&#x6E90;&#x6587;&#x4EF6;&#x5927;&#x5C0F;&#x8D85;&#x8FC7; <strong>120 KB</strong>&#xFF0C;&#x53EF;&#x80FD;&#x5BFC;&#x81F4;&#x5305;&#x7684;&#x4F53;&#x79EF;&#x8FC7;&#x5927;&#xFF0C;&#x53EF;&#x4F18;&#x5316;&#x3002;</p>
</li>
<li>
<p>&#x8D44;&#x6E90;&#x6587;&#x4EF6;&#x5927;&#x5C0F;&#x5728; <strong>50 KB</strong> &#x5230; <strong>120 KB</strong>&#x4E4B;&#x95F4;&#x3002;</p>
</li>
<li>
<p>&#x8D44;&#x6E90;&#x6587;&#x4EF6;&#x5927;&#x5C0F;&#x5C0F;&#x4E8E; <strong>50 KB</strong>&#x3002;</p>
</li>
</ul>
<p><img src="https://statres.quickapp.cn/quickapp/show/img/210914/v5.0_1.png" alt="&#x5FEB;&#x5E94;&#x7528; IDE &#x4F9D;&#x8D56;&#x5206;&#x6790;&#x63D2;&#x4EF6;" loading="lazy"></p>
</li>
<li>
<p>&#x91CD;&#x590D;&#x5F15;&#x7528;&#x5206;&#x6790;</p>
<p>&#x8BE5;&#x529F;&#x80FD;&#x7528;&#x4E8E;&#x7EDF;&#x8BA1;&#x5728;&#x6253;&#x5305;&#x4E4B;&#x540E;&#xFF0C;&#x5404;&#x4E2A;&#x6587;&#x4EF6;&#x7684;&#x88AB;&#x5F15;&#x7528;&#x6B21;&#x6570;&#x3002;&#x53EA;&#x5C55;&#x793A;&#x5927;&#x4E8E;&#x7B49;&#x4E8E;&#x4E24;&#x6B21;&#x7684;&#x5F15;&#x7528;&#xFF0C;&#x60A8;&#x53EF;&#x6839;&#x636E;&#x88AB;&#x5F15;&#x7528;&#x7684;&#x6B21;&#x6570;&#x548C;&#x5927;&#x5C0F;&#xFF0C;&#x6765;&#x4F18;&#x5316;&#x4EE3;&#x7801;&#xFF0C;&#x4EE5;&#x51CF;&#x5C0F; rpk &#x4F53;&#x79EF;&#xFF0C;&#x60A8;&#x53EF;&#x70B9;&#x51FB;&#x300C;<strong>&#x9875;&#x9762;&#x5F15;&#x7528;&#x8BE6;&#x60C5;</strong>&#x300D;&#x4E0B;&#x7684;&#x300C;<strong>&#x67E5;&#x770B;&#x5F15;&#x7528;&#x8DEF;&#x5F84;</strong>&#x300D;&#x6765;&#x67E5;&#x770B;&#x8BE5;&#x6587;&#x4EF6;&#x88AB;&#x9875;&#x9762;&#x5F15;&#x7528;&#x7684;&#x8BE6;&#x7EC6;&#x8DEF;&#x5F84;&#x3002;</p>
<p><img src="https://statres.quickapp.cn/quickapp/show/img/210914/v5.0_2.png" alt="&#x5FEB;&#x5E94;&#x7528; IDE &#x4F9D;&#x8D56;&#x5206;&#x6790;&#x63D2;&#x4EF6;" loading="lazy"></p>
</li>
<li>
<p>&#x4F9D;&#x8D56;&#x5206;&#x6790;</p>
<p>&#x8BE5;&#x529F;&#x80FD;&#x7528;&#x4E8E;&#x7EDF;&#x8BA1;&#x5728;&#x6253;&#x5305;&#x4E4B;&#x540E;&#xFF0C;&#x5404;&#x4E2A;&#x6587;&#x4EF6;&#x7684;&#x4F9D;&#x8D56;&#x5173;&#x7CFB;&#x3002;&#x6839;&#x8282;&#x70B9;&#x4E3A;&#x5404;&#x4E2A;&#x9875;&#x9762;&#x7684;&#x8DEF;&#x5F84;&#xFF0C;&#x5B50;&#x8282;&#x70B9;&#x4E3A;&#x9875;&#x9762;&#x5BFC;&#x5165;&#x7684;&#x7EC4;&#x4EF6;&#x6216;&#x8005;&#x662F;&#x6587;&#x4EF6;&#x8DEF;&#x5F84;&#xFF0C;&#x663E;&#x793A;&#x7684;&#x6587;&#x4EF6;&#x5927;&#x5C0F;&#x4E3A;&#x539F;&#x59CB;&#x6CA1;&#x6709;&#x7ECF;&#x8FC7; minify &#x5904;&#x7406;&#x7684;&#x6587;&#x4EF6;&#x5927;&#x5C0F;&#x3002;</p>
<p><img src="https://statres.quickapp.cn/quickapp/show/img/210914/v5.0_3.png" alt="&#x5FEB;&#x5E94;&#x7528; IDE &#x4F9D;&#x8D56;&#x5206;&#x6790;&#x63D2;&#x4EF6;" loading="lazy"></p>
</li>
</ul>
<h4 id="web-%E6%8B%89%E8%B5%B7%E5%BF%AB%E5%BA%94%E7%94%A8%E6%8F%92%E4%BB%B6">Web &#x62C9;&#x8D77;&#x5FEB;&#x5E94;&#x7528;&#x63D2;&#x4EF6;</h4>
<p>&#x5FEB;&#x5E94;&#x7528; IDE &#x63D0;&#x4F9B;&#x6B64;&#x63D2;&#x4EF6;&#xFF0C;&#x65E8;&#x5728;&#x65B9;&#x4FBF;&#x5F00;&#x53D1;&#x8005;&#x300C;&#x6D4B;&#x8BD5;&#x57FA;&#x4E8E;&#x7F51;&#x9875;&#x62C9;&#x8D77;&#x5FEB;&#x5E94;&#x7528;&#x300D;&#xFF08;deeplink &#x65B9;&#x5F0F;&#xFF09;&#x3002;&#x6B64;&#x63D2;&#x4EF6;&#x4F1A;&#x5F00;&#x542F;&#x4E00;&#x4E2A;&#x672C;&#x5730;&#x670D;&#x52A1;&#xFF0C;&#x60A8;&#x53EF;&#x7528;&#x624B;&#x673A;&#xFF0C;&#x626B;&#x63CF;&#x5982;&#x4E0B;&#x4E8C;&#x7EF4;&#x7801;&#xFF0C;&#x5373;&#x53EF;&#x5728;&#x624B;&#x673A;&#x7AEF;&#x6253;&#x5F00;&#x8BE5;&#x670D;&#x52A1;&#x9875;&#x9762;&#xFF1B;&#x6839;&#x636E;&#x63D0;&#x793A;&#x64CD;&#x4F5C;&#xFF0C;&#x60A8;&#x5373;&#x53EF;&#x6D4B;&#x8BD5;&#xFF0C;&#x7F51;&#x9875;&#x80FD;&#x5426;&#x62C9;&#x8D77;&#x60A8;&#x6B63;&#x5728;&#x5F00;&#x53D1;&#x7684;&#x5FEB;&#x5E94;&#x7528;&#xFF08;&#x5982;&#x679C;&#x60A8;&#x7684;&#x5FEB;&#x5E94;&#x7528;&#xFF0C;&#x8FD8;&#x672A;&#x4E0A;&#x7EBF;&#xFF0C;&#x8BF7;&#x63D0;&#x524D;&#x5728;&#x624B;&#x673A;&#x7AEF;&#x5B89;&#x88C5;&#x8BE5;&#x5FEB;&#x5E94;&#x7528;&#xFF09;&#x3002;</p>
<p><img src="https://statres.quickapp.cn/quickapp/show/img/210914/v5.0_4.png" alt="&#x5FEB;&#x5E94;&#x7528; IDE - Web &#x62C9;&#x8D77;&#x5FEB;&#x5E94;&#x7528;&#x63D2;&#x4EF6;" loading="lazy"></p>
<h4 id="%E6%A8%A1%E7%89%88%E6%96%B0%E5%BB%BA%E5%BC%B9%E6%A1%86%E5%A1%AB%E5%85%A5%E9%A1%B9%EF%BC%8C%E7%BB%99%E5%87%BA%E9%BB%98%E8%AE%A4">&#x6A21;&#x7248;&#x65B0;&#x5EFA;&#x5F39;&#x6846;&#x586B;&#x5165;&#x9879;&#xFF0C;&#x7ED9;&#x51FA;&#x9ED8;&#x8BA4;</h4>
<p>&#x589E;&#x52A0;&#x5728;&#x65B0;&#x5EFA;&#x6A21;&#x677F;&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x81EA;&#x52A8;&#x586B;&#x5165;&#x4FE1;&#x606F;&#xFF1A;&#x5176;&#x4E2D;&#x9879;&#x76EE;&#x540D;&#x79F0; <code>quickapp-code-${ num + 1 }</code></p>
<p><img src="https://statres.quickapp.cn/quickapp/show/img/210914/v5.0_6.png" alt="&#x5FEB;&#x5E94;&#x7528; IDE" loading="lazy"></p>
<h4 id="%E5%86%85%E5%AD%98%E5%BF%AB%E7%85%A7%E5%91%BD%E4%BB%A4">&#x5185;&#x5B58;&#x5FEB;&#x7167;&#x547D;&#x4EE4;</h4>
<p>&#x4E3A;&#x65B9;&#x4FBF;&#x6392;&#x67E5;&#x5185;&#x5B58;&#x95EE;&#x9898;&#xFF0C;&#x589E;&#x52A0;&#x5185;&#x5B58;&#x5FEB;&#x7167;&#x547D;&#x4EE4;&#x3002;</p>
<ul>
<li>&#x8C03;&#x8D77;&#x547D;&#x4EE4;&#x8F93;&#x5165;&#x6846;&#xFF1A;<code>cmd + shift + p</code> (Mac)&#xFF0C;<code>ctrl + shift + p</code> (Windows);</li>
<li>&#x547D;&#x4EE4;&#xFF1A;
<ul>
<li><code>hap: take all heap snapshot</code> &#x751F;&#x6210;&#x6240;&#x6709; heap snapshot&#xFF1B;</li>
<li><code>hap: take extension heap snapshot</code> &#x751F;&#x6210;&#x63D2;&#x4EF6;&#x8FDB;&#x7A0B;&#x7684; heap snapshot&#xFF1B;</li>
<li><code>hap: take workbench heap snapshot</code> &#x751F;&#x6210;&#x4E3B;&#x8FDB;&#x7A0B;&#x548C;&#x6E32;&#x67D3;&#x8FDB;&#x7A0B;&#x7684; heap snapshot&#xFF1B;</li>
</ul>
</li>
</ul>
<p>&#x4F1A;&#x5728;&#x7528;&#x6237;&#x76EE;&#x5F55;&#x4E0B;&#x751F;&#x6210;&#x5FEB;&#x7167;&#x3002;<br>
windows &#x7528;&#x6237;&#x76EE;&#x5F55;&#xFF1A;${user}\AppData\Roaming\&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177;\heapsnapshot<br>
mac &#x7528;&#x6237;&#x76EE;&#x5F55;&#xFF1A;~/Library/Application Support/&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177;/heapsnapshot</p>
<h4 id="%E4%BB%A3%E7%A0%81%E8%87%AA%E5%8A%A8%E8%A1%A5%E5%85%A8">&#x4EE3;&#x7801;&#x81EA;&#x52A8;&#x8865;&#x5168;</h4>
<p>&#x589E;&#x52A0;&#x4E86; style &#x90E8;&#x5206;&#xFF0C;class &#x548C; id &#x7684;&#x8865;&#x5168;&#x3002;</p>
<p>&#x5982;&#x4E0B;&#x56FE;&#xFF0C; template &#x4E2D;&#x7684; class &#x6709; wrapper&#x3001;title&#x3001;content&#xFF0C; &#x5728; style &#x90E8;&#x5206;&#xFF0C;&#x8F93;&#x5165; . &#x4F1A;&#x63D0;&#x793A;&#x8FD9;&#x4E9B; class&#x3002;</p>
<p><img src="https://statres.quickapp.cn/quickapp/show/img/210923/ide-guide.png" alt="&#x5FEB;&#x5E94;&#x7528; IDE - &#x4EE3;&#x7801;&#x81EA;&#x52A8;&#x8865;&#x5168;" loading="lazy"></p>
<h4 id="%E4%BC%98%E5%8C%96%E3%80%8C%E8%BF%9C%E7%A8%8B%E9%A2%84%E8%A7%88%E3%80%8D%E8%AF%B7%E6%B1%82%E4%B8%AD%E7%9A%84%E5%8A%A8%E7%94%BB%E5%92%8C%E6%8F%90%E7%A4%BA">&#x4F18;&#x5316;&#x300C;&#x8FDC;&#x7A0B;&#x9884;&#x89C8;&#x300D;&#x8BF7;&#x6C42;&#x4E2D;&#x7684;&#x52A8;&#x753B;&#x548C;&#x63D0;&#x793A;</h4>
<p><img src="https://statres.quickapp.cn/quickapp/show/img/210914/v5.0_7.png" alt="&#x5FEB;&#x5E94;&#x7528; IDE - &#x4F18;&#x5316;&#x300C;&#x8FDC;&#x7A0B;&#x9884;&#x89C8;&#x300D;&#x8BF7;&#x6C42;&#x4E2D;&#x7684;&#x52A8;&#x753B;&#x548C;&#x63D0;&#x793A;" loading="lazy"></p>
<h4 id="%E4%B8%B0%E5%AF%8C%E6%8F%92%E4%BB%B6">&#x4E30;&#x5BCC;&#x63D2;&#x4EF6;</h4>
<p>&#x4E3A;&#x4E30;&#x5BCC;&#x63D2;&#x4EF6;&#x5E02;&#x573A;&#xFF0C;&#x6536;&#x96C6;&#x4E86;&#x4E00;&#x4E9B;&#x80FD;&#x591F;&#x65B9;&#x4FBF;&#x5F00;&#x53D1;&#x8005;&#x5F00;&#x53D1;&#x7684;&#x63D2;&#x4EF6;&#xFF0C;&#x5177;&#x4F53;&#x5982;&#x4E0B;&#xFF1A;</p>
<ul>
<li>Bracket Pair Colorizer&#xFF1A;&#x5141;&#x8BB8;&#x4F7F;&#x7528;&#x989C;&#x8272;&#x6807;&#x8BC6;&#x5339;&#x914D;&#x7684;&#x62EC;&#x53F7;&#x3002;&#x7528;&#x6237;&#x53EF;&#x4EE5;&#x5B9A;&#x4E49;&#x8981;&#x5339;&#x914D;&#x7684;&#x5B57;&#x7B26;&#x4EE5;&#x53CA;&#x8981;&#x4F7F;&#x7528;&#x7684;&#x989C;&#x8272;&#x3002;</li>
<li>Auto Rename Tag&#xFF1A;&#x81EA;&#x52A8;&#x91CD;&#x547D;&#x540D;&#x914D;&#x5BF9;&#x7684; HTML/XML &#x6807;&#x7B7E;&#x3002;</li>
<li>Tabnine&#xFF1A;&#x4EBA;&#x5DE5;&#x667A;&#x80FD;&#x4EE3;&#x7801;&#x52A9;&#x624B;&#xFF0C;&#x81EA;&#x52A8;&#x5B8C;&#x6210;&#x3001;AI &#x8F85;&#x52A9;&#x4EE3;&#x7801;&#x8865;&#x5168;&#x3001;AI &#x9A71;&#x52A8;&#x4EE3;&#x7801;&#x8865;&#x5168;&#x3001;AI &#x4EE3;&#x7801;&#x7247;&#x6BB5;&#x3001;&#x4EE3;&#x7801;&#x5EFA;&#x8BAE;&#x3001;&#x4EE3;&#x7801;&#x9884;&#x6D4B;&#x3001;&#x4EE3;&#x7801;&#x63D0;&#x793A;&#x6216;&#x5185;&#x5BB9;&#x8F85;&#x52A9;&#x3002;</li>
<li>Todo Tree&#xFF1A;&#x5FEB;&#x901F;&#x641C;&#x7D22;&#xFF08;&#x4F7F;&#x7528;ripgrep&#xFF09;&#x60A8;&#x7684;&#x5DE5;&#x4F5C;&#x533A;&#x4EE5;&#x67E5;&#x627E;TODO &#x548C; FIXME &#x7B49;&#x6CE8;&#x91CA;&#x6807;&#x7B7E;&#xFF0C;&#x5E76;&#x5C06;&#x5B83;&#x4EEC;&#x663E;&#x793A;&#x5728;&#x8D44;&#x6E90;&#x7BA1;&#x7406;&#x5668;&#x7A97;&#x683C;&#x7684;&#x6811;&#x89C6;&#x56FE;&#x4E2D;&#x3002;&#x5355;&#x51FB;&#x6811;&#x4E2D;&#x7684; TODO &#x5C06;&#x6253;&#x5F00;&#x6587;&#x4EF6;&#x5E76;&#x5C06;&#x5149;&#x6807;&#x653E;&#x5728;&#x5305;&#x542B; TODO &#x7684;&#x884C;&#x4E0A;&#x3002;</li>
<li>open in browser&#xFF1A;&#x5728;&#x6D4F;&#x89C8;&#x5668;&#x4E2D;&#x5FEB;&#x901F;&#x6253;&#x5F00;&#x5F53;&#x524D;&#x6587;&#x4EF6;&#x3002;</li>
<li>Better Comments&#xFF1A;&#x5E2E;&#x52A9;&#x60A8;&#x5728;&#x4EE3;&#x7801;&#x4E2D;&#x521B;&#x5EFA;&#x66F4;&#x4EBA;&#x6027;&#x5316;&#x7684;&#x6CE8;&#x91CA;&#x3002;</li>
<li>Github viscose theme&#xFF1A;GitHub &#x7684; VS Code &#x4E3B;&#x9898;&#x3002;</li>
<li>Footsteps&#xFF1A;&#x5728;&#x4EE3;&#x7801;&#x7684;&#x4E0D;&#x540C;&#x90E8;&#x5206;&#x4E4B;&#x95F4;&#x8DF3;&#x8F6C;&#x65F6;&#x4FDD;&#x6301;&#x4F60;&#x7684;&#x4F4D;&#x7F6E;&#x3002;</li>
</ul>
<p>&#x5173;&#x4E8E;&#x5FEB;&#x5E94;&#x7528; IDE &#x63D2;&#x4EF6;&#xFF0C;&#x5982;&#x60A8;&#x6709;&#x5174;&#x8DA3;&#x4E86;&#x89E3;&#x66F4;&#x591A;&#xFF0C;&#x53EF;&#x53C2;&#x89C1;&#x6587;&#x7AE0;&#xFF1A;<a href="https://quickapp.vivo.com.cn/how-to-use-plug-ins-to-improve-the-efficiency-of-quickapp-development/">&#x5982;&#x4F55;&#x4F7F;&#x7528;&#x63D2;&#x4EF6;&#x63D0;&#x5347;&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x6548;&#x7387;</a>&#x3002;</p>
<h4 id="%E5%88%B7%E6%96%B0%E9%A2%84%E8%A7%88%E5%92%8C-devtools">&#x5237;&#x65B0;&#x9884;&#x89C8;&#x548C; devtools</h4>
<p>&#x5728;&#x9884;&#x89C8;&#x8BBE;&#x7F6E;&#x4E2D;&#xFF0C;&#x589E;&#x52A0;&#x4E00;&#x4E2A;&#x5237;&#x65B0;&#x6309;&#x952E;&#xFF0C;&#x53EF;&#x4EE5;&#x5237;&#x65B0;&#x9884;&#x89C8;&#x548C; devtools&#x3002;</p>
<p><img src="https://statres.quickapp.cn/quickapp/show/img/210914/v5.0_5.png" alt="&#x5FEB;&#x5E94;&#x7528; IDE - &#x5237;&#x65B0;&#x9884;&#x89C8;&#x548C; devtools" loading="lazy"></p>
<h4 id="%E4%BF%AE%E5%A4%8D-devtools-%E6%96%AD%E5%BC%80%E8%BF%9E%E6%8E%A5-bug">&#x4FEE;&#x590D; devtools &#x65AD;&#x5F00;&#x8FDE;&#x63A5; bug</h4>
<p>&#x7535;&#x8111;&#x7761;&#x7720;&#x4E4B;&#x540E;&#xFF0C;devtools &#x65AD;&#x5F00;&#x8FDE;&#x63A5;&#xFF0C;&#x9884;&#x89C8;&#x7684; touch &#x6A21;&#x5F0F;&#x4F1A;&#x5931;&#x6548;&#x3002;&#x73B0;&#x5728;&#xFF0C;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x70B9;&#x51FB;&#x9884;&#x89C8;&#x4E0A;&#x65B9;&#x7684;&#x5237;&#x65B0;&#x6309;&#x952E;&#x3001;&#x4FDD;&#x5B58;&#x6587;&#x4EF6;&#x7B49;&#x65B9;&#x5F0F;&#xFF0C;&#x8BA9;&#x9884;&#x89C8;&#x548C; devtools &#x6062;&#x590D;&#x6B63;&#x5E38;&#x3002;</p>
<h2 id="%E5%B1%95%E6%9C%9B%E6%9C%AA%E6%9D%A5">&#x5C55;&#x671B;&#x672A;&#x6765;</h2>
<p>&#x5728;&#x63A5;&#x4E0B;&#x6765;&#x7684;&#x65E5;&#x5B50;&#x91CC;&#xFF0C;&#x6211;&#x4EEC;&#x5C06;&#x518D;&#x63A5;&#x518D;&#x5389;&#xFF0C;&#x4F7F;&#x5F97; IDE &#x4F7F;&#x7528;&#x4F53;&#x9A8C;&#x518D;&#x5347;&#x4E00;&#x4E2A;&#x53F0;&#x9636;&#x3002;&#x672A;&#x6765;&#xFF0C;&#x56E2;&#x961F;&#x4ECD;&#x5C06;&#x6301;&#x7EED;&#x5173;&#x6CE8;<strong>&#x6027;&#x80FD;</strong>&#x3001;<strong>&#x7A33;&#x5B9A;&#x6027;</strong>&#x3001;<strong>&#x517C;&#x5BB9;&#x6027;</strong>&#xFF0C;&#x8FD9;&#x4E9B;&#x5BF9;&#x4E8E;&#x7528;&#x6237;&#x548C;&#x6211;&#x4EEC;&#xFF0C;&#x90FD;&#x81F3;&#x5173;&#x91CD;&#x8981;&#x7684;&#x57FA;&#x672C;&#x9762;&#xFF1B;&#x540C;&#x65F6;&#x5C06;&#x6295;&#x5165;&#x66F4;&#x591A;&#x7CBE;&#x529B;&#x4E8E; IDE <strong>&#x9884;&#x89C8;</strong>&#x3001;&#x9884;&#x68C0;&#x6D4B;&#xFF0C;&#x529B;&#x4E89;&#x505A;&#x5230;&#x9884;&#x89C8;&#x4E4B;&#x5448;&#x73B0;&#xFF0C;&#x5373;&#x771F;&#x673A;&#x6240;&#x663E;&#xFF08;&#x76F8;&#x4FE1;&#x5728;&#x4E0D;&#x4E45;&#x4E4B;&#x540E;&#xFF0C;&#x5C06;&#x6709;&#x5927;&#x7684;&#x6539;&#x5584;&#xFF09;&#xFF1B;&#x5BF9;&#x4E8E;&#x65B0;&#x529F;&#x80FD;&#xFF0C;&#x4F1A;&#x6301;&#x8C28;&#x614E;&#x6001;&#x5EA6;&#xFF0C;&#x8BA4;&#x771F;&#x7814;&#x7A76;&#xFF0C;&#x529B;&#x4E89;&#x6BCF;&#x4E00;&#x70B9;&#x52AA;&#x529B;&#xFF0C;&#x90FD;&#x80FD;&#x4E3A;&#x60A8;&#x5E26;&#x6765;&#x5E94;&#x6709;&#x4EF7;&#x503C;&#xFF1B;&#x6700;&#x540E;&#xFF0C;&#x6211;&#x4EEC;&#x5C06;&#x59CB;&#x7EC8;&#x503E;&#x542C;&#x7528;&#x6237;&#x7684;&#x58F0;&#x97F3;&#xFF0C;&#x5982;&#x679C;&#x60A8;&#x6709;&#x4EFB;&#x4F55;&#x5EFA;&#x8BAE;&#x6216;&#x610F;&#x89C1;&#xFF0C;&#x8BF7;&#x53CA;&#x65F6;&#x544A;&#x77E5;&#xFF0C;&#x5C06;&#x5C3D;&#x53EF;&#x80FD;&#x6EE1;&#x8DB3;&#x60A8;&#x3002;</p>
<p>&#x5982;&#x679C;&#x60A8;&#x8FD8;&#x6CA1;&#x6709;&#x5C1D;&#x8BD5;&#x8FC7;&#x5FEB;&#x5E94;&#x7528; IDE&#xFF0C;&#x8BF7;<a href="https://www.quickapp.cn/docCenter/IDEPublicity">&#x4E0B;&#x8F7D;</a>&#x4EE5;&#x53CA;&#x5C1D;&#x8BD5;&#x4F7F;&#x7528;&#x5B83;&#xFF0C;&#x5982;&#x679C;&#x60A8;&#x6709;&#x4EFB;&#x4F55;&#x60F3;&#x6CD5;&#xFF0C;&#x8BF7;&#x53CA;&#x65F6;&#x8BA9;&#x6211;&#x4EEC;&#x77E5;&#x6653;&#x3002;</p>
<p>&#x518D;&#x6B21;&#x8868;&#x793A;&#x611F;&#x8C22;&#xFF01;&#x6700;&#x540E;&#xFF0C;&#x613F;&#x6240;&#x6709;&#x4EBA;&#xFF0C;&#x90FD;&#x53EF;&#x4EE5;&#xFF1A;<strong>&#x5DE5;&#x4F5C;&#x5F00;&#x5FC3;&#x4E0D;&#x52A0;&#x73ED;&#xFF0C;&#x751F;&#x6D3B;&#x5FEB;&#x4E50;&#x65E0;&#x5FE7;&#x8651;</strong>&#x3002;</p>
<p>&#x2500;&#x2500; &#x6765;&#x81EA;<code>&#x5FEB;&#x5E94;&#x7528;&#x5DE5;&#x5177;&#x5F00;&#x53D1;&#x56E2;&#x961F;</code>&#xFF0C;&#x4E8E; 2021 &#x5E74; 9 &#x6708; 22 &#x65E5;&#x3002;</p>
<hr>
<p>2021 &#x5E74; IDE &#x7248;&#x672C;&#x66F4;&#x65B0;&#x65F6;&#x95F4;&#x7EBF;&#xFF1A;</p>
<ul>
<li>9.2 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v5-0-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 5.0 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>7.26 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v4-1-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 4.1 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>6.30 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v4-0-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 4.0 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>5.27 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-10-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.10 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>4.13 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-9-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.9 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>3.11 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-8-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.8 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>2.4 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-7-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.7 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
</ul>
<p>2020 &#x5E74; IDE &#x7248;&#x672C;&#x66F4;&#x65B0;&#x65F6;&#x95F4;&#x7EBF;&#xFF1A;</p>
<ul>
<li>12.29 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-6-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.6 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>12.01 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-5-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.5 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>10.26 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-4-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.4 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>08.18 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-3-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.3 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>07.29 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-2-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.2 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>07.06 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-1-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.1 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
<li>06.01 <a href="https://quickapp.vivo.com.cn/quickapp-ide-v3-release/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177; 3.0 &#x7248;&#x672C;&#x53D1;&#x5E03;</a></li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[如何使用插件提升快应用开发效率]]></title><description><![CDATA[在快应用开发工具中，如何使用插件提升快应用开发效率。本文主要介绍了 tabnine， Auto Rename Tag，Bracket Pair Colorizer，Better Comments，Todo Tree，footsteps 等插件。]]></description><link>https://quickapp.vivo.com.cn/how-to-use-plug-ins-to-improve-the-efficiency-of-quickapp-development/</link><guid isPermaLink="false">63c4b94a77e2ca0006a8c895</guid><category><![CDATA[快应用开发工具]]></category><category><![CDATA[快应用插件]]></category><dc:creator><![CDATA[minxuan]]></dc:creator><pubDate>Tue, 14 Sep 2021 07:01:28 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><h2 id="prettier">Prettier</h2>
<p><a href="https://github.com/prettier/prettier">Prettier</a> &#x662F;&#x4E00;&#x4E2A;&#x6709;&#x89C1;&#x8BC6;&#x7684;&#x4EE3;&#x7801;&#x683C;&#x5F0F;&#x5316;&#x5DE5;&#x5177;&#x3002;&#x5B83;&#x901A;&#x8FC7;&#x89E3;&#x6790;&#x4EE3;&#x7801;&#x5E76;&#x4F7F;&#x7528;&#x81EA;&#x5DF1;&#x7684;&#x89C4;&#x5219;&#x91CD;&#x65B0;&#x6253;&#x5370;&#x5B83;&#xFF0C;&#x5E76;&#x8003;&#x8651;&#x6700;&#x5927;&#x884C;&#x957F;&#x6765;&#x5F3A;&#x5236;&#x6267;&#x884C;&#x4E00;&#x81F4;&#x7684;&#x6837;&#x5F0F;&#xFF0C;&#x5E76;&#x5728;&#x5FC5;&#x8981;&#x65F6;&#x5305;&#x88C5;&#x4EE3;&#x7801;&#x3002;&#x5982;&#x4ECA;&#xFF0C;&#x5B83;&#x5DF2;&#x6210;&#x4E3A;&#x89E3;&#x51B3;&#x6240;&#x6709;&#x4EE3;&#x7801;&#x683C;&#x5F0F;&#x95EE;&#x9898;&#x7684;&#x4F18;&#x9009;&#x65B9;&#x6848;&#xFF1B;&#x652F;&#x6301; <code>JavaScript</code>&#x3001; <code>Flow</code>&#x3001; <code>TypeScript</code>&#x3001; <code>CSS</code>&#x3001; <code>SCSS</code>&#x3001; <code>Less</code>&#x3001; <code>JSX</code>&#x3001; <code>Vue</code>&#x3001; <code>GraphQL</code>&#x3001; <code>JSON</code>&#x3001; <code>Markdown</code> &#x7B49;&#x8BED;&#x8A00;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x7ED3;&#x5408; ESLint &#x548C; Prettier&#xFF0C;&#x68C0;&#x6D4B;&#x4EE3;&#x7801;&#x4E2D;&#x6F5C;&#x5728;&#x95EE;&#x9898;&#x7684;&#x540C;&#x65F6;&#xFF0C;&#x8FD8;&#x80FD;&#x7EDF;&#x4E00;&#x56E2;&#x961F;&#x4EE3;&#x7801;&#x98CE;&#x683C;&#xFF0C;&#x4ECE;&#x800C;&#x4FC3;&#x4F7F;&#x5199;&#x51FA;&#x9AD8;&#x8D28;&#x91CF;&#x4EE3;&#x7801;&#xFF0C;&#x6765;&#x63D0;&#x5347;&#x5DE5;&#x4F5C;&#x6548;&#x7387;&#x3002;</p>
<p><img src="https://oss.nicelinks.site/prettier.io.png" alt="Prettier &#x5FEB;&#x5E94;&#x7528;" loading="lazy"></p>
<p>&#x5982;&#x679C;&#x60A8;&#x6709; Web &#x5F00;&#x53D1;&#x524D;&#x7AEF;&#x7ECF;&#x9A8C;&#xFF0C;&#x60F3;&#x5FC5;&#x5BF9; <a href="https://github.com/prettier/prettier">Prettier</a> &#x5DF2;&#x975E;&#x5E38;&#x719F;&#x6089;&#xFF1B;&#x5728;&#x5FEB;&#x5E94;&#x7528;&#x4E2D;&#xFF0C;&#x4E5F;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#xFF1B;&#x5B83;&#x4E0D;&#x4EC5;&#x80FD;&#x5E2E;&#x7740;&#x683C;&#x5F0F;&#x5316;&#x4EE3;&#x7801;&#xFF0C;&#x800C;&#x4E14;&#x8FD8;&#x53EF;&#x4EE5;&#x534F;&#x52A9;&#x53D1;&#x73B0;&#x4E00;&#x4E9B;&#x4E0D;&#x7B26;&#x5408;&#x89C4;&#x8303;&#x7684;&#x5199;&#x6CD5;&#x3002;&#x518D;&#x501F;&#x52A9; <code>husky</code>&#x3001;<code>lint-staged</code> &#x8FD9;&#x51E0;&#x6B3E;&#x5DE5;&#x5177;&#x5E93;&#xFF0C;&#x53EF;&#x9632;&#x6B62;&#x5C06;&#x4E0D;&#x89C4;&#x8303;&#x7684;&#x4EE3;&#x7801;&#x63D0;&#x4EA4;&#x5230;&#x8FDC;&#x7AEF;&#xFF0C;&#x8FD9;&#x5BF9;<strong>&#x7EDF;&#x4E00;&#x56E2;&#x961F;&#x4EE3;&#x7801;&#x98CE;&#x683C;</strong>&#xFF0C;&#x975E;&#x5E38;&#x5177;&#x6709;&#x4EF7;&#x503C;&#x3002;&#x5173;&#x4E8E; Prettier &#x7684;&#x4F7F;&#x7528;&#xFF0C;&#x6709;&#x5728;<a href="https://forum.lovejade.cn/d/72">&#x56E2;&#x961F;&#x5F00;&#x53D1;&#x5FEB;&#x5E94;&#x7528;&#xFF0C;&#x5982;&#x4F55;&#x7EDF;&#x4E00;&#x4EE3;&#x7801;&#x98CE;&#x683C;&#xFF1F;</a>&#x3001;<a href="https://forum.lovejade.cn/d/71-prettier">&#x5982;&#x4F55;&#x7528; Prettier &#x7F8E;&#x5316;&#x60A8;&#x7684;&#x5FEB;&#x5E94;&#x7528;&#x4EE3;&#x7801;&#xFF1F;</a>&#x7B49;&#x6587;&#x7AE0;&#x4E2D;&#xFF0C;&#x6709;&#x6BD4;&#x8F83;&#x8BE6;&#x5C3D;&#x7684;&#x8BF4;&#x660E;&#x3002;</p>
<h2 id="tabnine">Tabnine</h2>
<p>&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177;&#x81EA;&#x5E26;&#x7684;&#x8BED;&#x6CD5;&#x63D2;&#x4EF6;&#xFF0C;&#x652F;&#x6301; ux &#x6587;&#x4EF6;&#x7684;&#x81EA;&#x52A8;&#x8865;&#x5168;&#xFF0C;&#x53EF;&#x4EE5;&#x8865;&#x5168;&#x5FEB;&#x5E94;&#x7528;&#x7684;&#x8BED;&#x6CD5;&#x3002;&#x6BD4;&#x5982; <code>&lt;template&gt;</code> &#x4E2D;&#x7684;&#x6807;&#x7B7E;&#x3001;<code>&lt;script&gt;</code> &#x4E2D;&#x7684;&#x63A5;&#x53E3;&#x3001;<code>&lt;style&gt;</code> &#x4E2D;&#x7684;&#x6837;&#x5F0F;&#x5C5E;&#x6027;&#x7B49;&#x3002;</p>
<p>&#x4F46;&#x662F;&#x81EA;&#x5E26;&#x7684;&#x8BED;&#x6CD5;&#x63D2;&#x4EF6;&#xFF0C;&#x53EF;&#x80FD;&#x65E0;&#x6CD5;&#x6EE1;&#x8DB3;&#x7528;&#x6237;&#x590D;&#x6742;&#x7684;&#x3001;&#x4E2A;&#x6027;&#x5316;&#x7684;&#x8865;&#x5168;&#x9700;&#x6C42;&#x3002;&#x56E0;&#x6B64;&#xFF0C;&#x6211;&#x4EEC;&#x63A8;&#x8350;&#x5F00;&#x53D1;&#x8005;&#x540C;&#x65F6;&#x4F7F;&#x7528; Tabnine &#x63D2;&#x4EF6;&#x3002;</p>
<p>Tabnine &#x662F;&#x4E00;&#x6B3E; AI &#x4EE3;&#x7801;&#x8865;&#x5168;&#x5DE5;&#x5177;&#xFF0C;&#x7531;&#x7ECF;&#x8FC7; GitHub &#x53EF;&#x4FE1;&#x5F00;&#x6E90;&#x4EE3;&#x7801;&#x8BAD;&#x7EC3;&#x7684;&#x673A;&#x5668;&#x5B66;&#x4E60;&#x6A21;&#x578B;&#x63D0;&#x4F9B;&#x652F;&#x6301;&#xFF0C;&#x53EF;&#x4EE5;&#x5E2E;&#x52A9;&#x5F00;&#x53D1;&#x8005;&#x66F4;&#x5FEB;&#x5730;&#x7F16;&#x5199;&#x4EE3;&#x7801;&#x3002;&#x548C; GitHub &#x4E00;&#x6837;&#xFF0C;&#x5B83;&#x662F;&#x4E13;&#x4E1A;&#x5F00;&#x53D1;&#x4EBA;&#x5458;&#x7684;&#x5FC5;&#x5907;&#x5DE5;&#x5177;&#x3002;</p>
<h3 id="tabnine-basic">Tabnine Basic</h3>
<p>&#x5B89;&#x88C5;&#x63D2;&#x4EF6;&#x540E;&#xFF0C;&#x9ED8;&#x8BA4;&#x4E3A;&#x514D;&#x8D39;&#x7684; Tabnine Basic &#x7248;&#x672C;&#x3002;&#x5982;&#x4E0B;&#x56FE;&#x6240;&#x793A;&#xFF0C;&#x5DF2;&#x7ECF;&#x53EF;&#x4EE5;&#x8FDB;&#x884C;&#x667A;&#x80FD;&#x63D0;&#x793A;&#xFF1A;<br>
<img src="https://zhanstatic.vivo.com.cn/wukong/img/3606c8a7-c78c-4782-a5ed-09bf70f52903.png" alt="tabnine-basic" loading="lazy"></p>
<h3 id="tabnine-pro">Tabnine Pro</h3>
<p>&#x5982;&#x679C;&#x5E0C;&#x671B;&#x5F97;&#x5230;&#x66F4;&#x597D;&#x7684;&#x4F53;&#x9A8C;&#xFF0C;&#x53EF;&#x4EE5;&#x8D2D;&#x4E70; Tabnine Pro &#x7248;&#x672C;&#x3002;</p>
<p>Basic &#x548C; Pro &#x7248;&#x672C;&#x7684;&#x533A;&#x522B;&#x5728;&#x4E8E;&#xFF1A;Tabnine Pro &#x4F7F;&#x7528;&#x8D85;&#x8FC7; 10 &#x4EBF;&#x884C;&#x5F00;&#x6E90;&#x4EE3;&#x7801;&#x4E0A;&#x8BAD;&#x7EC3;&#x7684;&#x9AD8;&#x7EA7; AI &#x6A21;&#x578B;&#xFF0C;&#x5E76;&#x4E0E;&#x591A;&#x8FBE; 30 &#x4EBA;&#x7684;&#x56E2;&#x961F;&#x5408;&#x4F5C;&#x3002; Tabnine Basic &#x4F7F;&#x7528;&#x8F83;&#x5C0F;&#x7684; AI &#x6A21;&#x578B;&#x5E76;&#x4E0E;&#x4E09;&#x4EBA;&#x6216;&#x66F4;&#x5C11;&#x7684;&#x56E2;&#x961F;&#x5408;&#x4F5C;&#x3002;</p>
<p>&#x5BF9;&#x4E8E; Pro &#x7248;&#x672C;&#xFF0C;&#x70B9;&#x51FB;&#x72B6;&#x6001;&#x680F;&#x7684; <code>tabnine pro</code>&#xFF0C;&#x6253;&#x5F00; Tabnine &#x9762;&#x677F;&#xFF0C;&#x8F93;&#x5165; <code>API key</code> &#x5373;&#x53EF;&#x3002;<br>
<img src="https://zhanstatic.vivo.com.cn/wukong/img/3c6e8053-725c-4cf8-821a-f4237972da9b.png" alt="tabnine-pro" loading="lazy"></p>
<p>Pro &#x7248;&#x672C;&#xFF0C;&#x8FD8;&#x53EF;&#x4EE5;&#x9009;&#x62E9;&#x4E0A;&#x4F20;&#x4EE3;&#x7801;&#x5230;&#x4E91;&#x7AEF;&#x8FDB;&#x884C;&#x8BAD;&#x7EC3;&#x3002;&#x8BE5;&#x529F;&#x80FD;&#xFF0C;&#x5F00;&#x53D1;&#x8005;&#x53EF;&#x4EE5;&#x6839;&#x636E;&#x4EE3;&#x7801;&#x7684;&#x4FDD;&#x5BC6;&#x60C5;&#x51B5;&#xFF0C;&#x9009;&#x62E9;&#x662F;&#x5426;&#x5F00;&#x542F;&#x3002;</p>
<p><img src="https://zhanstatic.vivo.com.cn/wukong/img/d5df7c4e-016f-4f70-a16a-413e40cf45cb.png" alt="tabnine-cloud" loading="lazy"></p>
<h2 id="auto-rename-tag">Auto Rename Tag</h2>
<p>Auto Rename Tag&#xFF0C;&#x652F;&#x6301;&#x81EA;&#x52A8;&#x91CD;&#x547D;&#x540D;&#x914D;&#x5BF9;&#x7684; HTML/XML &#x6807;&#x7B7E;&#x3002;&#x5982;&#x4E0B;&#x56FE;&#xFF0C;&#x76F4;&#x63A5;&#x91CD;&#x547D;&#x540D;&#x524D;&#x9762;&#x7684;&#x6807;&#x7B7E;&#xFF0C;&#x540E;&#x9762;&#x5339;&#x914D;&#x7684;&#x6807;&#x7B7E;&#x4E5F;&#x4F1A;&#x8DDF;&#x7740;&#x6539;&#x53D8;&#x3002;</p>
<p><img src="https://zhanstatic.vivo.com.cn/wukong/img/546ec117-fa0f-4c2d-b5fd-7b35d957ef37.gif" alt="auto-rename-tag" loading="lazy"></p>
<p>&#x6CE8;&#xFF1A;&#x8BE5;&#x63D2;&#x4EF6;&#x9ED8;&#x8BA4;&#x652F;&#x6301; ux &#x6587;&#x4EF6;&#xFF0C;&#x4E0D;&#x9700;&#x8981;&#x53E6;&#x5916;&#x8FDB;&#x884C;&#x8BBE;&#x7F6E;&#x3002;</p>
<h2 id="bracket-pair-colorizer">Bracket Pair Colorizer</h2>
<p>&#x6709;&#x65F6;&#x5019;&#xFF0C;&#x6211;&#x4EEC;&#x7684;&#x4EE3;&#x7801;&#x4E2D;&#x4F1A;&#x6709;&#x8F83;&#x591A;&#x5C42;&#x7EA7;&#x7684;&#x6263;&#x53F7;&#xFF0C;&#x6BD4;&#x5982; <code>less</code> &#x4E2D;&#x7684; <code>{}</code>&#x3002;&#x5F53;&#x4EE3;&#x7801;&#x91CF;&#x591A;&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x5C31;&#x4E0D;&#x5BB9;&#x6613;&#x5FEB;&#x901F;&#x627E;&#x5230;&#x4EE3;&#x7801;&#x4F4D;&#x7F6E;&#x3002;&#x5982;&#x4E0B;&#x56FE;&#x6240;&#x793A;&#xFF1A;</p>
<p><img src="https://zhanstatic.vivo.com.cn/wukong/img/9ae6d98c-90dc-409b-9a2a-a8ca2e1a5d7c.png" alt="bracket-pair-colorizer" loading="lazy"></p>
<p>&#x8FD9;&#x79CD;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x53EF;&#x4EE5;&#x5B89;&#x88C5; Bracket Pair Colorizer &#x63D2;&#x4EF6;&#x3002;&#x8BE5;&#x63D2;&#x4EF6;&#x4F1A;&#x5BF9;&#x5339;&#x914D;&#x7684;&#x62EC;&#x53F7;&#x8FDB;&#x884C;&#x989C;&#x8272;&#x9AD8;&#x4EAE;&#xFF0C;&#x65B9;&#x4FBF;&#x5F00;&#x53D1;&#x8005;&#x5B9A;&#x4F4D;&#x4EE3;&#x7801;&#x5757;&#x7684;&#x8303;&#x56F4;&#x3002;&#x5982;&#x4E0B;&#x56FE;&#xFF0C;&#x4E0D;&#x540C;&#x5C42;&#x7EA7;&#x7684; <code>{}</code> &#x6709;&#x4E0D;&#x540C;&#x989C;&#x8272;&#x7684;&#x9AD8;&#x4EAE;&#xFF1B;&#x5149;&#x6807;&#x653E;&#x5728; <code>margin: @gap-2;</code> &#x65F6;&#xFF0C;&#x5BF9;&#x5E94;&#x7684;&#x8303;&#x56F4;&#x4E5F;&#x4F1A;&#x6709;&#x9AD8;&#x4EAE;&#x63D0;&#x793A;&#x3002;</p>
<p><img src="https://zhanstatic.vivo.com.cn/wukong/img/80d4c22c-1f7a-4bfc-8140-f11475af7c89.png" alt="bracket-pair-colorizer-less" loading="lazy"></p>
<p>&#x6CE8;&#xFF1A;IDE &#x63D2;&#x4EF6;&#x5E02;&#x573A;&#x4E2D;&#x7684; Bracket Pair Colorizer&#xFF0C;&#x5BF9; ux &#x6587;&#x4EF6;&#x8FDB;&#x884C;&#x4E86;&#x9002;&#x914D;&#x3002;</p>
<h3 id="%E9%85%8D%E7%BD%AE">&#x914D;&#x7F6E;</h3>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x8BE5;&#x63D2;&#x4EF6;&#x4F1A;&#x5BF9; ()&#x3001;[] &#x548C; {} &#x8FDB;&#x884C;&#x5339;&#x914D;&#xFF0C;&#x7528;&#x6237;&#x4E5F;&#x53EF;&#x4EE5;&#x914D;&#x7F6E;&#x81EA;&#x5B9A;&#x4E49;&#x62EC;&#x53F7;&#x5B57;&#x7B26;&#x3002;&#x6BD4;&#x5982;&#x60F3;&#x652F;&#x6301; html &#x6807;&#x7B7E;&#xFF0C;&#x53EF;&#x4EE5;&#x6309;&#x4EE5;&#x4E0B;&#x65B9;&#x5F0F;&#x914D;&#x7F6E;&#x3002;</p>
<ul>
<li>
<p>&#x70B9;&#x51FB;&#x8BBE;&#x7F6E;&#x6309;&#x952E;&#xFF0C;&#x6253;&#x5F00;&#x8BBE;&#x7F6E;&#x9762;&#x677F;&#xFF0C;&#x641C;&#x7D22; <code>bracketPairColorizer.consecutivePairColors</code>&#xFF0C;&#x70B9;&#x51FB; <code>&#x5728; setting.json &#x4E2D;&#x7F16;&#x8F91;</code>&#x3002;</p>
<p><img src="https://zhanstatic.vivo.com.cn/wukong/img/3f9d1b34-1c5c-498f-a5ce-2f5415ea6acc.png" alt="setting" loading="lazy"></p>
</li>
<li>
<p>&#x8BBE;&#x7F6E;&#x5982;&#x4E0B;&#xFF1A;</p>
<pre><code class="language-json">{
  &quot;bracketPairColorizer.consecutivePairColors&quot;: [
    &quot;()&quot;,
    &quot;[]&quot;,
    &quot;{}&quot;,
    [&quot;&lt;&quot;, &quot;&lt;/&quot;],
    [&quot;&lt;&quot;, &quot;/&gt;&quot;],
    [&quot;Gold&quot;, &quot;Orchid&quot;, &quot;LightSkyBlue&quot;],
    &quot;Red&quot;
  ]
}
</code></pre>
</li>
<li>
<p>&#x6548;&#x679C;&#x5982;&#x4E0B;&#xFF1A;<br>
<img src="https://zhanstatic.vivo.com.cn/wukong/img/430699f3-a699-4aac-bde9-ea423c3b471d.png" alt="bracketPairColorizer-html" loading="lazy"></p>
</li>
</ul>
<p>&#x5173;&#x4E8E;&#x5176;&#x4ED6;&#x914D;&#x7F6E;&#xFF0C;&#x8BF7;&#x67E5;&#x770B;&#x63D2;&#x4EF6;&#x8BE6;&#x60C5;&#x3002;</p>
<h3 id="%E5%91%BD%E4%BB%A4">&#x547D;&#x4EE4;</h3>
<p>&#x63D2;&#x4EF6;&#x652F;&#x6301;&#x6269;&#x5C55;&#x6216;&#x64A4;&#x9500;&#x5149;&#x6807;&#x8303;&#x56F4;&#x7684;&#x547D;&#x4EE4;&#xFF1A;</p>
<ul>
<li>&quot;bracket-pair-colorizer.expandBracketSelection&quot;&#xFF1A;&#x6269;&#x5C55;&#x5149;&#x6807;&#x8303;&#x56F4;</li>
<li>&quot;bracket-pair-colorizer.undoBracketSelection&quot;&#xFF1A;&#x64A4;&#x9500;&#x5149;&#x6807;&#x8303;&#x56F4;</li>
</ul>
<p>&#x4E5F;&#x53EF;&#x4EE5;&#x5728;&#x8BBE;&#x7F6E;&#x9762;&#x677F;&#x4E2D;&#xFF0C;&#x4E3A;&#x5176;&#x589E;&#x52A0;&#x5BF9;&#x5E94;&#x7684;&#x5FEB;&#x6377;&#x65B9;&#x5F0F;&#x3002;</p>
<h2 id="better-comments">Better Comments</h2>
<p>&#x4EE3;&#x7801;&#x4E2D;&#xFF0C;&#x7ECF;&#x5E38;&#x4F1A;&#x6709;&#x5404;&#x79CD;&#x6CE8;&#x91CA;&#x3002;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x6240;&#x6709;&#x6CE8;&#x91CA;&#x90FD;&#x662F;&#x4E00;&#x79CD;&#x989C;&#x8272;&#xFF0C;&#x8FD9;&#x6837;&#x5C31;&#x4E0D;&#x5BB9;&#x6613;&#x8BC6;&#x522B;&#x51FA;&#x91CD;&#x8981;&#x7684;&#x6CE8;&#x91CA;&#x3002;</p>
<p>&#x4E3A;&#x4E86;&#x8BA9;&#x6CE8;&#x91CA;&#x66F4;&#x6613;&#x8BFB;&#xFF0C;&#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; Better Comments &#x63D2;&#x4EF6;&#xFF0C;&#x8BA9;&#x4E0D;&#x540C;&#x7C7B;&#x578B;&#x7684;&#x6CE8;&#x91CA;&#x6709;&#x4E0D;&#x540C;&#x7684;&#x9AD8;&#x4EAE;&#x6837;&#x5F0F;&#x3002;&#x5982;&#x4E0B;&#x56FE;&#x6240;&#x793A;&#xFF0C;&#x6CE8;&#x91CA;&#x4E2D;&#x8F93;&#x5165; <code>!</code>&#x3001;<code>?</code>&#x3001; <code>//</code>&#x3001;<code>todo</code>&#x3001;<code>*</code>&#xFF0C;&#x6CE8;&#x91CA;&#x7684;&#x6837;&#x5F0F;&#x4E0D;&#x540C;&#xFF1A;</p>
<p><img src="https://zhanstatic.vivo.com.cn/wukong/img/25412ff8-eeec-4d54-b93b-6576a52e39e9.png" alt="better-comments" loading="lazy"></p>
<h3 id="%E8%87%AA%E5%AE%9A%E4%B9%89%E6%A0%87%E7%AD%BE">&#x81EA;&#x5B9A;&#x4E49;&#x6807;&#x7B7E;</h3>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;Better Comments &#x53EA;&#x8BBE;&#x7F6E;&#x4E86; <code>!</code>&#xFF08;&#x8B66;&#x544A;&#xFF09;&#x3001;<code>?</code>&#xFF08;&#x8BE2;&#x95EE;&#xFF09;&#x3001; <code>//</code>&#xFF08;&#x5220;&#x9664;&#xFF09;&#x3001;<code>todo</code>&#xFF08;&#x4EE3;&#x529E;&#xFF09;&#x3001;<code>*</code>&#xFF08;&#x9AD8;&#x4EAE;&#xFF09;&#x8FD9;&#x51E0;&#x79CD;&#x6807;&#x7B7E;&#x3002;&#x6211;&#x4EEC;&#x4E5F;&#x53EF;&#x4EE5;&#x6DFB;&#x52A0;&#x81EA;&#x5B9A;&#x4E49;&#x7684;&#x6807;&#x7B7E;&#xFF1A;</p>
<ul>
<li>
<p>&#x6253;&#x5F00;&#x8BBE;&#x7F6E;&#x9762;&#x677F;&#x3002;</p>
<p><img src="https://zhanstatic.vivo.com.cn/wukong/img/1b2a3c82-c9e1-4b23-a0b0-8ff819559516.png" alt="setting-panel" loading="lazy"></p>
</li>
<li>
<p>&#x5728;&#x8BBE;&#x7F6E;&#x9762;&#x677F;&#x641C;&#x7D22; <code>better-comments.tags</code>&#xFF0C;&#x5E76;&#x6253;&#x5F00; setting.json &#x8FDB;&#x884C;&#x7F16;&#x8F91;&#x3002;</p>
</li>
<li>
<p>&#x4FEE;&#x6539; <code>better-comments.tags</code>&#xFF0C;&#x6BD4;&#x5982;&#x589E;&#x52A0; <code>test</code> &#x6807;&#x7B7E;&#x3002;</p>
<pre><code class="language-json">&quot;better-comments.tags&quot;: [
    {
        &quot;tag&quot;: &quot;!&quot;,
        &quot;color&quot;: &quot;#FF2D00&quot;,
        &quot;strikethrough&quot;: false,
        &quot;underline&quot;: false,
        &quot;backgroundColor&quot;: &quot;transparent&quot;,
        &quot;bold&quot;: false,
        &quot;italic&quot;: false
    },
    {
        &quot;tag&quot;: &quot;?&quot;,
        &quot;color&quot;: &quot;#3498DB&quot;,
        &quot;strikethrough&quot;: false,
        &quot;underline&quot;: false,
        &quot;backgroundColor&quot;: &quot;transparent&quot;,
        &quot;bold&quot;: false,
        &quot;italic&quot;: false
    },
    {
        &quot;tag&quot;: &quot;//&quot;,
        &quot;color&quot;: &quot;#477777&quot;,
        &quot;strikethrough&quot;: true,
        &quot;underline&quot;: false,
        &quot;backgroundColor&quot;: &quot;transparent&quot;,
        &quot;bold&quot;: false,
        &quot;italic&quot;: false
    },
    {
        &quot;tag&quot;: &quot;todo&quot;,
        &quot;color&quot;: &quot;#e6b5b5&quot;,
        &quot;strikethrough&quot;: false,
        &quot;underline&quot;: false,
        &quot;backgroundColor&quot;: &quot;transparent&quot;,
        &quot;bold&quot;: false,
        &quot;italic&quot;: false
    },
    {
        &quot;tag&quot;: &quot;*&quot;,
        &quot;color&quot;: &quot;#98C379&quot;,
        &quot;strikethrough&quot;: false,
        &quot;underline&quot;: false,
        &quot;backgroundColor&quot;: &quot;transparent&quot;,
        &quot;bold&quot;: false,
        &quot;italic&quot;: false
    },
    {
        // &#x6DFB;&#x52A0; test
        &quot;tag&quot;: &quot;test&quot;,
        &quot;color&quot;: &quot;#98C379&quot;,
        &quot;strikethrough&quot;: false,
        &quot;underline&quot;: true,
        &quot;backgroundColor&quot;: &quot;transparent&quot;,
        &quot;bold&quot;: false,
        &quot;italic&quot;: false
    }
],
</code></pre>
</li>
<li>
<p>&#x6548;&#x679C;&#x5982;&#x4E0B;&#xFF1A;</p>
<p><img src="https://zhanstatic.vivo.com.cn/wukong/img/9c2acd7d-24d2-4dce-9375-57e53e24c51b.png" alt="better-comments-test" loading="lazy"></p>
</li>
</ul>
<h2 id="todo-tree">Todo Tree</h2>
<p>&#x5728;&#x9879;&#x76EE;&#x4E2D;&#xFF0C;&#x7ECF;&#x5E38;&#x4F1A;&#x6709;&#x5F85;&#x7F16;&#x8F91;&#x7684;&#x4EE3;&#x7801;&#xFF0C;&#x6211;&#x4EEC;&#x901A;&#x5E38;&#x4F1A;&#x589E;&#x52A0; <code>TODO</code> &#x7684;&#x6CE8;&#x91CA;&#x3002;&#x5F53;&#x6211;&#x4EEC;&#x8981;&#x7F16;&#x8F91;&#x8FD9;&#x90E8;&#x5206;&#x4EE3;&#x7801;&#x65F6;&#xFF0C;&#x81EA;&#x5DF1;&#x641C;&#x7D22;&#x4E0D;&#x662F;&#x5F88;&#x65B9;&#x4FBF;&#x3002;&#x8FD9;&#x65F6;&#xFF0C;&#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>Todo Tree</code> &#x63D2;&#x4EF6;&#xFF0C;&#x5E2E;&#x52A9;&#x6211;&#x4EEC;&#x5FEB;&#x901F;&#x5BFC;&#x822A;&#x5230; <code>TODO</code> &#x7684;&#x4EE3;&#x7801;&#x3002;</p>
<h3 id="%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95">&#x4F7F;&#x7528;&#x65B9;&#x6CD5;</h3>
<ul>
<li>&#x70B9;&#x51FB;&#x4FA7;&#x8FB9;&#x680F;&#x7684; <code>Todo Tree</code> &#x56FE;&#x6807;&#xFF0C;&#x8D44;&#x6E90;&#x9762;&#x677F;&#x4F1A;&#x68C0;&#x7D22;&#x5E76;&#x5C55;&#x793A;&#x9879;&#x76EE;&#x4E0B;&#x7684; <code>TODO</code> &#x548C; <code>FIXME</code>&#x3002;</li>
<li>&#x70B9;&#x51FB;&#x8D44;&#x6E90;&#x9762;&#x677F;&#x7684; <code>TODO</code> &#x6309;&#x952E;&#xFF0C;&#x53EF;&#x4EE5;&#x6253;&#x5F00;&#x5BF9;&#x5E94;&#x6587;&#x4EF6;&#x5E76;&#x9AD8;&#x4EAE;&#x6587;&#x4EF6;&#x4E2D;&#x7684; <code>TODO</code> &#x6587;&#x672C;&#x3002;</li>
</ul>
<p><img src="https://zhanstatic.vivo.com.cn/wukong/img/b6ebe66e-e0bb-4593-bdf4-6bc285c79eab.png" alt="todo-tree" loading="lazy"></p>
<h3 id="%E8%87%AA%E5%AE%9A%E4%B9%89%E6%A0%87%E7%AD%BE">&#x81EA;&#x5B9A;&#x4E49;&#x6807;&#x7B7E;</h3>
<p>Todo Tree &#x9ED8;&#x8BA4;&#x53EA;&#x652F;&#x6301; <code>TODO</code>, <code>FIXME</code>, <code>BUG</code> &#x7B49;&#x6807;&#x7B7E;&#xFF0C;&#x5982;&#x679C;&#x6211;&#x4EEC;&#x4E60;&#x60EF;&#x4F7F;&#x7528;&#x5C0F;&#x5199;&#x7684; <code>todo</code>&#xFF0C;&#x5C31;&#x4E0D;&#x4F1A;&#x751F;&#x6548;&#x3002;&#x8FD9;&#x79CD;&#x60C5;&#x51B5;&#xFF0C;&#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x8BBE;&#x7F6E; <code>todo-tree.general.tags</code> &#x5B57;&#x6BB5;&#x89E3;&#x51B3;&#x3002;&#x5982;&#x4E0B;&#x56FE;&#x6240;&#x793A;&#xFF0C;&#x70B9;&#x51FB;<code>&#x6DFB;&#x52A0;&#x9879;</code>&#xFF0C;&#x518D;&#x589E;&#x52A0;&#x81EA;&#x5DF1;&#x6240;&#x9700;&#x6807;&#x7B7E;&#x5373;&#x53EF;&#x3002;</p>
<p><img src="https://zhanstatic.vivo.com.cn/wukong/img/0b23da64-509d-4714-b6aa-996ea9e5b29a.png" alt="todo-tree-setting" loading="lazy"></p>
<p>Todo Tree &#x8FD8;&#x652F;&#x6301;&#x5176;&#x4ED6;&#x8BBE;&#x7F6E;&#xFF0C;&#x6BD4;&#x5982;&#x8BBE;&#x7F6E;&#x9AD8;&#x4EAE;&#x989C;&#x8272;&#xFF0C;&#x5982;&#x679C;&#x6709;&#x5174;&#x8DA3;&#x53EF;&#x67E5;&#x770B;&#x63D2;&#x4EF6;&#x8BE6;&#x60C5;&#x3002;</p>
<h2 id="footsteps">Footsteps</h2>
<p>footsteps &#x53EF;&#x4EE5;&#x9AD8;&#x4EAE;&#x663E;&#x793A;&#x6700;&#x8FD1;&#x7F16;&#x8F91;&#x7684;&#x4EE3;&#x7801;&#x5757;&#xFF0C;&#x5E76;&#x5728;&#x6700;&#x8FD1;&#x7F16;&#x8F91;&#x7684;&#x4EE3;&#x7801;&#x5757;&#x4E4B;&#x95F4;&#x8DF3;&#x8F6C;&#x3002;</p>
<p>&#x5982;&#x4E0B;&#x56FE;&#xFF0C;&#x7F16;&#x8F91;&#x540E;&#xFF0C;&#x4EE3;&#x7801;&#x4F1A;&#x6709;&#x7D2B;&#x8272;&#x7684;&#x80CC;&#x666F;&#x8272;&#x9AD8;&#x4EAE;&#xFF0C;&#x8D8A;&#x8FD1;&#x7F16;&#x8F91;&#x7684;&#x9AD8;&#x4EAE;&#x8D8A;&#x660E;&#x663E;&#x3002;&#x4F7F;&#x7528;&#x5FEB;&#x6377;&#x952E; <code>ctrl+alt+left</code> &#x548C; <code>ctrl+alt+right</code> &#x53EF;&#x4EE5;&#x5728;&#x4EE3;&#x7801;&#x5757;&#x4E4B;&#x95F4;&#x8DF3;&#x8F6C;&#x3002;<br>
<img src="https://github.com/Wattenberger/footsteps-vscode/blob/main/footsteps.gif?raw=true" alt="footsteps" loading="lazy"></p>
<p>&#x8BE5;&#x63D2;&#x4EF6;&#x4E5F;&#x652F;&#x6301;&#x8BBE;&#x7F6E;&#x9AD8;&#x4EAE;&#x989C;&#x8272;&#x3001;&#x4E0D;&#x900F;&#x660E;&#x5EA6;&#x7B49;&#xFF0C;&#x5177;&#x4F53;&#x53EF;&#x4EE5;&#x67E5;&#x770B;&#x63D2;&#x4EF6;&#x8BE6;&#x60C5;&#x3002;</p>
<h2 id="git-extension-pack">Git Extension Pack</h2>
<p>&#x5BF9;&#x4E8E;&#x5F00;&#x53D1;&#x8005;&#x800C;&#x8A00;&#xFF0C;&#x6211;&#x4EEC;&#x7ECF;&#x5E38;&#x9700;&#x8981;&#x7528; Git &#x7BA1;&#x7406;&#x9879;&#x76EE;&#x3002;Git Extension Pack &#x662F; Git &#x63D2;&#x4EF6;&#x5305;&#xFF0C;&#x53EF;&#x4EE5;&#x5E2E;&#x52A9;&#x5F00;&#x53D1;&#x8005;&#x66F4;&#x65B9;&#x4FBF;&#x5730;&#x4F7F;&#x7528; Git&#x3002;&#x8BE5;&#x63D2;&#x4EF6;&#x5305;&#x5305;&#x542B;&#x4EE5;&#x4E0B;&#x51E0;&#x4E2A;&#x6D41;&#x884C;&#x7684; Git &#x63D2;&#x4EF6;&#xFF1A;</p>
<h3 id="1-git-history-git-log">1. Git History (git log)</h3>
<p>&#x67E5;&#x770B; Git &#x65E5;&#x5FD7;&#x3001;&#x6587;&#x4EF6;&#x5386;&#x53F2;&#x6216;&#x884C;&#x5386;&#x53F2;&#x3002;</p>
<ul>
<li>
<p>&#x67E5;&#x770B; Git &#x5386;&#x53F2;&#x8BB0;&#x5F55;&#xFF08;git log&#xFF09;&#xFF08;&#x547D;&#x4EE4;&#xFF1A;git.viewHistory&#xFF09;</p>
<p>&#x5982;&#x4E0B;&#x56FE;&#x6240;&#x793A;&#xFF0C;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x5173;&#x952E;&#x8BCD;&#x641C;&#x7D22;&#x65E5;&#x5FD7;&#xFF1B;&#x53EF;&#x4EE5;&#x67E5;&#x770B;&#x67D0;&#x4E2A; commit &#x4FEE;&#x6539;&#x7684;&#x6587;&#x4EF6;&#xFF0C;&#x5E76;&#x4E0E;&#x4E4B;&#x524D;&#x7248;&#x672C;&#x6216;&#x5F53;&#x524D;&#x7248;&#x672C;&#x8FDB;&#x884C;&#x6BD4;&#x8F83;&#xFF1B;&#x53EF;&#x4EE5;&#x6DFB;&#x52A0; tag&#x3001;branch&#xFF0C;&#x8FD8;&#x652F;&#x6301; cherry-pick&#x3001;merge &#x7B49;&#x5E38;&#x7528;&#x7684;&#x64CD;&#x4F5C;&#x3002;</p>
<p><img src="https://raw.githubusercontent.com/DonJayamanne/gitHistoryVSCode/master/images/gitLogv3.gif" alt="git-history-log" loading="lazy"></p>
</li>
<li>
<p>&#x67E5;&#x770B;&#x6587;&#x4EF6;&#x5386;&#x53F2;&#x8BB0;&#x5F55;&#xFF08;&#x547D;&#x4EE4;&#xFF1A;git.viewFileHistory&#xFF09;<br>
<img src="https://raw.githubusercontent.com/DonJayamanne/gitHistoryVSCode/master/images/fileHistoryCommandv3.gif" alt="git-history-file" loading="lazy"></p>
</li>
<li>
<p>&#x67E5;&#x770B;&#x884C;&#x5386;&#x53F2;&#x8BB0;&#x5F55;&#xFF08;&#x547D;&#x4EE4;&#xFF1A;git.viewLineHistory&#xFF09;<br>
<img src="https://raw.githubusercontent.com/DonJayamanne/gitHistoryVSCode/master/images/lineHistoryCommandv3.gif" alt="git-history-line" loading="lazy"></p>
</li>
</ul>
<h3 id="2-gitlens">2. GitLens</h3>
<p>&#x5F00;&#x53D1;&#x8005;&#x7ECF;&#x5E38;&#x9700;&#x8981;&#x67E5;&#x770B; git &#x9879;&#x76EE;&#x7684;&#x5386;&#x53F2;&#xFF0C;&#x5982;&#x679C;&#x80FD;&#x5728;&#x4EE3;&#x7801;&#x4E2D;&#x76F4;&#x63A5;&#x67E5;&#x770B;&#x4F1A;&#x66F4;&#x52A0;&#x65B9;&#x4FBF;&#x3002;&#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x5B89;&#x88C5; GitLens&#xFF0C;&#x5B83;&#x4F1A;&#x5728;&#x4EE3;&#x7801;&#x4E2D;&#x76F4;&#x63A5;&#x5C55;&#x793A;&#x67D0;&#x884C;&#x4EE3;&#x7801;&#x7684;&#x4F5C;&#x8005;&#x3001;&#x4FEE;&#x6539;&#x65F6;&#x95F4;&#x3001;&#x4FEE;&#x6539;&#x65E5;&#x5FD7;&#xFF0C;&#x8FD8;&#x652F;&#x6301;&#x5BF9;&#x6BD4;&#x4E0D;&#x540C;&#x7248;&#x672C;&#x7684;&#x4EE3;&#x7801;&#x3002;</p>
<ul>
<li>
<p>&#x5F53;&#x524D;&#x884C;&#x5F52;&#x8D23;</p>
<p>&#x5982;&#x4E0B;&#x56FE;&#x6240;&#x793A;&#xFF0C;&#x5149;&#x6807;&#x653E;&#x5230;&#x4EE3;&#x7801;&#x4E0A;&#x67D0;&#x4E00;&#x884C;&#x65F6;&#xFF0C;&#x5F53;&#x524D;&#x884C;&#x672B;&#x5C3E;&#x4F1A;&#x663E;&#x793A;&#x4E00;&#x4E2A;&#x5F52;&#x8D23;&#x6CE8;&#x91CA;&#x3002;&#x5305;&#x542B;&#x5F53;&#x524D;&#x884C;&#x6700;&#x8FD1;&#x63D0;&#x4EA4;&#x7684;&#x4F5C;&#x8005;&#x3001;&#x4FEE;&#x6539;&#x65F6;&#x95F4;&#x548C;&#x4FEE;&#x6539;&#x65E5;&#x5FD7;&#x3002;</p>
<p><img src="https://raw.githubusercontent.com/eamodio/vscode-gitlens/main/images/docs/current-line-blame.png" alt="current-line-blame" loading="lazy"></p>
<ul>
<li>
<p>&#x901A;&#x8FC7;&#x547D;&#x4EE4; <code>gitlens.toggleLineBlame</code> &#x53EF;&#x4EE5;&#x6253;&#x5F00;/&#x5173;&#x95ED;&#x8BE5;&#x529F;&#x80FD;&#xFF0C;&#x9ED8;&#x8BA4;&#x662F;&#x6253;&#x5F00;&#x7684;&#x3002;</p>
</li>
<li>
<p>&#x9F20;&#x6807;&#x60AC;&#x505C;&#x5728;&#x5F52;&#x8D23;&#x6CE8;&#x91CA;&#x4E0A;&#x65F6;&#xFF0C;&#x4F1A;&#x663E;&#x793A;&#x63D0;&#x4EA4;&#x7684;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#x548C;&#x4E00;&#x4E9B;&#x94FE;&#x63A5;&#xFF0C;&#x70B9;&#x51FB;&#x94FE;&#x63A5;&#x53EF;&#x4EE5;&#x8FDB;&#x884C;&#x7248;&#x672C;&#x5BF9;&#x6BD4;&#x3001;&#x6253;&#x5F00; git &#x4ED3;&#x5E93;&#x7B49;&#x64CD;&#x4F5C;&#x3002;</p>
<p><img src="https://raw.githubusercontent.com/eamodio/vscode-gitlens/main/images/docs/hovers-current-line-details.png" alt="hovers-current-line-details" loading="lazy"></p>
</li>
</ul>
</li>
<li>
<p>&#x7248;&#x672C;&#x5BFC;&#x822A;</p>
<p>&#x5982;&#x4E0B;&#x56FE;&#x6240;&#x793A;&#xFF0C;&#x6253;&#x5F00;&#x6587;&#x4EF6;&#x540E;&#xFF0C;&#x70B9;&#x51FB; <code>Open Changes with Previous Revision</code> &#x6309;&#x952E;&#xFF0C;&#x53EF;&#x4EE5;&#x548C;&#x4E0A;&#x4E00;&#x4E2A;&#x63D0;&#x4EA4;&#x7248;&#x672C;&#x5BF9;&#x6BD4;&#xFF1B;&#x70B9;&#x51FB; <code>Open Changes with Next Revision</code> &#x6309;&#x952E;&#xFF0C;&#x53EF;&#x4EE5;&#x548C;&#x4E0B;&#x4E00;&#x4E2A;&#x63D0;&#x4EA4;&#x7248;&#x672C;&#x5BF9;&#x6BD4;&#x3002;</p>
<p><img src="https://raw.githubusercontent.com/eamodio/vscode-gitlens/main/images/docs/revision-navigation.gif" alt="revision-navigation" loading="lazy"></p>
<p>&#x53E6;&#x5916;&#xFF0C;Gitlens &#x8FD8;&#x652F;&#x6301;&#x4EE5;&#x4E0B;&#x547D;&#x4EE4;&#xFF0C;&#x53EF;&#x4EE5;&#x67E5;&#x770B;&#x884C;&#x7684;&#x5386;&#x53F2;&#x8BB0;&#x5F55;&#x3001;&#x5206;&#x652F;&#x6216; tag &#x7684;&#x5386;&#x53F2;&#x8BB0;&#x5F55;&#x3002;</p>
<ul>
<li><code>Open Line Changes with Previous Revision</code></li>
<li><code>Open Line Changes with Working File</code></li>
<li><code>Open Changes with Branch &#x6216; Tag...</code></li>
<li><code>Open Changes with Revision...</code></li>
</ul>
</li>
<li>
<p>Gitlens &#x89C6;&#x56FE;</p>
<p>&#x5982;&#x4E0B;&#x56FE;&#xFF0C;<code>&#x6E90;&#x4EE3;&#x7801;&#x7BA1;&#x7406;</code> &#x89C6;&#x56FE;&#x4E0B;&#xFF0C;&#x6709;&#x591A;&#x4E2A; Gitlens &#x7684;&#x89C6;&#x56FE;&#xFF1A;<code>commit</code>&#x3001;<code>file history</code>&#x3001;<code>branches</code>&#x3001;<code>remotes</code>&#x3001;<code>stashes</code>&#x3001;<code>tags</code>&#x3001;<code>search &amp; compare</code> &#x7B49;&#x3002;&#x901A;&#x8FC7;&#x8FD9;&#x4E9B;&#x89C6;&#x56FE;&#xFF0C;&#x53EF;&#x4EE5;&#x5FEB;&#x901F;&#x67E5;&#x627E; git &#x76F8;&#x5173;&#x7684;&#x4FE1;&#x606F;&#x3002;</p>
<p><img src="https://zhanstatic.vivo.com.cn/wukong/img/9fe4f77b-2368-4b78-bd7a-696eb13ad23f.png" alt="gitlens-view" loading="lazy"></p>
</li>
<li>
<p>&#x5176;&#x4ED6;&#x529F;&#x80FD;</p>
<p>&#x8FD9;&#x91CC;&#x53EA;&#x63CF;&#x8FF0; Gitlens &#x7684;&#x5E38;&#x7528;&#x529F;&#x80FD;&#xFF0C;&#x5176;&#x4ED6;&#x529F;&#x80FD;&#x8BF7;&#x67E5;&#x770B;&#x63D2;&#x4EF6;&#x8BE6;&#x60C5;&#x3002;</p>
</li>
</ul>
<h3 id="3-project-manager">3. Project Manager</h3>
<p>&#x7528;&#x4E8E;&#x7BA1;&#x7406;&#x591A;&#x4E2A;&#x9879;&#x76EE;&#xFF0C;&#x5FEB;&#x901F;&#x5207;&#x6362;&#x9879;&#x76EE;&#xFF0C;&#x53EF;&#x4EE5;&#x662F; git&#x3001;svn&#x3001;Mercurial &#x7B49;&#x7C7B;&#x578B;&#x7684;&#x9879;&#x76EE;&#x3002;</p>
<ul>
<li>
<p>&#x6DFB;&#x52A0;&#x9879;&#x76EE;&#x4FE1;&#x606F;</p>
<p>&#x5728;&#x7BA1;&#x7406;&#x9879;&#x76EE;&#x4E4B;&#x524D;&#xFF0C;&#x9700;&#x8981;&#x5148;&#x8F93;&#x5165;&#x9879;&#x76EE;&#x4FE1;&#x606F;&#x3002;</p>
<p>&#x65B9;&#x6CD5;&#x4E00;&#xFF1A;&#x8F93;&#x5165;&#x547D;&#x4EE4; <code>Project Manager: Edit Projects</code>&#xFF0C;&#x6700;&#x5F00;&#x59CB;&#x6CA1;&#x6709; project.json &#x6587;&#x4EF6;&#xFF0C;&#x9700;&#x8981;&#x70B9;&#x51FB;&#x201C;&#x624B;&#x52A8;&#x7F16;&#x8F91;&#x201D;&#x6309;&#x952E;&#x751F;&#x6210; project.json&#x3002;&#x7136;&#x540E;&#x7F16;&#x8F91;&#x9879;&#x76EE;&#x4FE1;&#x606F;&#xFF0C;&#x793A;&#x4F8B;&#x5982;&#x4E0B;&#xFF1A;</p>
<pre><code class="language-json">[
  {
    &quot;name&quot;: &quot;Pascal MI&quot;,
    &quot;rootPath&quot;: &quot;c:\\PascalProjects\\pascal-menu-insight&quot;,
    &quot;paths&quot;: [],
    &quot;group&quot;: &quot;&quot;
  },
  {
    &quot;name&quot;: &quot;Bookmarks&quot;,
    &quot;rootPath&quot;: &quot;$home\\Documents\\GitHub\\vscode-bookmarks&quot;,
    &quot;paths&quot;: [],
    &quot;group&quot;: &quot;&quot;
  },
  {
    &quot;name&quot;: &quot;Numbered Bookmarks&quot;,
    &quot;rootPath&quot;: &quot;$home\\Documents\\GitHub\\vscode-numbered-bookmarks&quot;,
    &quot;paths&quot;: [],
    &quot;group&quot;: &quot;&quot;
  }
]
</code></pre>
<p>&#x65B9;&#x6CD5;&#x4E8C;&#xFF1A;&#x70B9;&#x51FB;&#x4FA7;&#x8FB9;&#x680F;&#x7684;&#x63D2;&#x4EF6;&#x56FE;&#x6807;&#xFF0C;&#x6253;&#x5F00;&#x9879;&#x76EE;&#x7BA1;&#x7406;&#x5668;&#xFF0C;&#x70B9;&#x51FB;&#x4FDD;&#x5B58;&#x9879;&#x76EE;&#xFF0C;&#x5C06;&#x5F53;&#x524D;&#x9879;&#x76EE;&#x7684;&#x8DEF;&#x5F84;&#x4FDD;&#x5B58;&#x5230; project.json&#x3002;</p>
<p><img src="https://zhanstatic.vivo.com.cn/wukong/img/2c85678d-2461-4599-a052-21d13b3b354e.png" alt="project-manager" loading="lazy"></p>
</li>
<li>
<p>&#x6253;&#x5F00;&#x9879;&#x76EE;</p>
<p>&#x8F93;&#x5165;&#x547D;&#x4EE4; <code>Project Manager: List Projects to Open</code>&#xFF0C;&#x9009;&#x62E9;&#x8981;&#x6253;&#x5F00;&#x7684;&#x9879;&#x76EE;&#xFF0C;&#x5728;&#x5F53;&#x524D;&#x7A97;&#x53E3;&#x6253;&#x5F00;&#x9879;&#x76EE;&#x3002;&#x4E5F;&#x652F;&#x6301;&#x5728;&#x9879;&#x76EE;&#x7BA1;&#x7406;&#x5668;&#xFF0C;&#x901A;&#x8FC7;&#x53F3;&#x952E;&#x6253;&#x5F00;&#x3002;</p>
</li>
<li>
<p>&#x5728;&#x65B0;&#x7A97;&#x53E3;&#x6253;&#x5F00;&#x9879;&#x76EE;</p>
<p>&#x8F93;&#x5165;&#x547D;&#x4EE4; <code>Project Manager: List Projects to Open in New Window</code>&#xFF0C;&#x9009;&#x62E9;&#x8981;&#x6253;&#x5F00;&#x7684;&#x9879;&#x76EE;&#xFF0C;&#x4F1A;&#x65B0;&#x5EFA;&#x4E00;&#x4E2A;&#x7A97;&#x53E3;&#x6253;&#x5F00;&#x9879;&#x76EE;&#x3002;&#x4E5F;&#x652F;&#x6301;&#x5728;&#x9879;&#x76EE;&#x7BA1;&#x7406;&#x5668;&#xFF0C;&#x901A;&#x8FC7;&#x53F3;&#x952E;&#x6253;&#x5F00;&#x3002;</p>
</li>
<li>
<p>&#x5176;&#x4ED6;&#x547D;&#x4EE4;&#x548C;&#x8BBE;&#x7F6E;&#xFF0C;&#x8BF7;&#x67E5;&#x770B;&#x63D2;&#x4EF6;&#x8BE6;&#x60C5;&#x3002;</p>
</li>
</ul>
<h3 id="4-open-in-github-bitbucket-visualstudiocom">4. Open in GitHub / Bitbucket / VisualStudio.com</h3>
<p>&#x901A;&#x8FC7;&#x547D;&#x4EE4; <code>Open in GitHub</code>&#xFF0C;&#x53EF;&#x4EE5;&#x6253;&#x5F00; git &#x4ED3;&#x5E93;&#xFF0C;&#x5E76;&#x8DF3;&#x8F6C;&#x5230;&#x6E90;&#x7801;&#x5BF9;&#x5E94;&#x7684;&#x884C;&#x3002;</p>
<h2 id="gitlive">GitLive</h2>
<p>GitLive &#x63D2;&#x4EF6;&#x4E3A;&#x5F00;&#x53D1;&#x56E2;&#x961F;&#x63D0;&#x4F9B;&#x4E86;&#x8FDC;&#x7A0B;&#x5B9E;&#x65F6;&#x534F;&#x4F5C;&#x529F;&#x80FD;&#x3002;&#x5B89;&#x88C5;&#x63D2;&#x4EF6;&#x540E;&#xFF0C;&#x5F00;&#x53D1;&#x8005;&#x53EF;&#x4EE5;&#x5728;&#x63D0;&#x4EA4;&#x524D;&#x67E5;&#x770B;&#x56E2;&#x961F;&#x6210;&#x5458;&#x5904;&#x7406;&#x7684;&#x5185;&#x5BB9;&#xFF0C;&#x7F16;&#x5199;&#x4EE3;&#x7801;&#x6709;&#x51B2;&#x7A81;&#x65F6;&#x4F1A;&#x6536;&#x5230;&#x63D0;&#x793A;&#x4FE1;&#x606F;&#xFF0C;&#x53EF;&#x4EE5;&#x548C;&#x56E2;&#x961F;&#x6210;&#x5458;&#x89C6;&#x9891;&#x901A;&#x8BDD;&#x5E76;&#x5B9E;&#x65F6;&#x7F16;&#x5199;&#x4EE3;&#x7801;&#x3002;</p>
<p>GitLive &#x7684;&#x4F7F;&#x7528;&#x65B9;&#x5F0F;&#xFF0C;&#x53EF;&#x4EE5;&#x67E5;&#x770B;&#x5176;&#x4ECB;&#x7ECD;&#x89C6;&#x9891;&#xFF1A;</p>
<p><a href="https://git.live/video" target="_blank" rel="noreferrer noopener nofollow"><img src="https://uploads-ssl.webflow.com/6033cf9dce54c65d97d57571/6079428cf8596461b1a3e1ec_image%20%287%29.png" alt="&#x89C6;&#x9891;"></a></p>
<h2 id="%E6%82%A8%E5%8F%AF%E8%83%BD%E6%84%9F%E5%85%B4%E8%B6%A3%E7%9A%84%E6%96%87%E7%AB%A0">&#x60A8;&#x53EF;&#x80FD;&#x611F;&#x5174;&#x8DA3;&#x7684;&#x6587;&#x7AE0;</h2>
<ul>
<li><a href="https://forum.lovejade.cn/d/72">&#x56E2;&#x961F;&#x5F00;&#x53D1;&#x5FEB;&#x5E94;&#x7528;&#xFF0C;&#x5982;&#x4F55;&#x7EDF;&#x4E00;&#x4EE3;&#x7801;&#x98CE;&#x683C;&#xFF1F;</a></li>
<li><a href="https://quickapp.vivo.com.cn/quickapp-ide-getting-started/">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x5DE5;&#x5177;&#x5165;&#x95E8;&#x4ECB;&#x7ECD;</a></li>
<li><a href="https://forum.lovejade.cn/d/75-chrome-url">Chrome &#x4E3A;&#x4F55;&#x65E0;&#x6CD5;&#x901A;&#x8FC7; url &#x62C9;&#x8D77;&#x5FEB;&#x5E94;&#x7528;&#xFF1F;</a></li>
<li><a href="https://forum.lovejade.cn/d/72">&#x56E2;&#x961F;&#x5F00;&#x53D1;&#x5FEB;&#x5E94;&#x7528;&#xFF0C;&#x5982;&#x4F55;&#x7EDF;&#x4E00;&#x4EE3;&#x7801;&#x98CE;&#x683C;&#xFF1F;</a></li>
<li><a href="https://forum.lovejade.cn/d/71-prettier">&#x5982;&#x4F55;&#x7528; Prettier &#x7F8E;&#x5316;&#x60A8;&#x7684;&#x5FEB;&#x5E94;&#x7528;&#x4EE3;&#x7801;&#xFF1F;</a></li>
<li><a href="https://quickapp.vivo.com.cn/quickapp-ide-pretest/">&#x5982;&#x4F55;&#x901A;&#x8FC7; IDE &#x7684;&#x9884;&#x68C0;&#x6D4B;&#x529F;&#x80FD;&#x63D0;&#x9AD8;&#x5BA1;&#x6838;&#x901A;&#x8FC7;&#x7387;</a></li>
<li><a href="https://quickapp.vivo.com.cn/how-to-configure-code-snippets-gracefully-in-quickapp-development/">&#x5982;&#x4F55;&#x4F18;&#x96C5;&#x5730;&#x914D;&#x7F6E;&#x5FEB;&#x5E94;&#x7528;&#x7684;&#x4EE3;&#x7801;&#x7247;&#x6BB5;</a></li>
<li><a href="https://quickapp.vivo.com.cn/how-to-develop-quickapp-based-on-typescript/">&#x5982;&#x4F55;&#x57FA;&#x4E8E; Typescript &#x5F00;&#x53D1;&#x5FEB;&#x5E94;&#x7528;</a></li>
<li><a href="https://forum.lovejade.cn/d/59">&#x5FEB;&#x5E94;&#x7528;&#x5F00;&#x53D1;&#x4E2D;&#xFF0C;&#x5982;&#x4F55;&#x533A;&#x5206;&#x5404;&#x79CD;&#x73AF;&#x5883;&#xFF1F;</a></li>
<li><a href="https://forum.lovejade.cn/d/19-qa-spin">&#x5FEB;&#x5E94;&#x7528;&#x5B98;&#x65B9;&#x52A0;&#x8F7D;&#x52A8;&#x753B;&#x5E93;&#xFF1A;qa-spin</a></li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>