<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Time Friend</title><link>https://time-friend.com/zh/</link><description>Recent content on Time Friend</description><generator>Hugo</generator><language>zh-CN</language><lastBuildDate>Wed, 29 Jul 2026 15:15:07 +0800</lastBuildDate><atom:link href="https://time-friend.com/zh/index.xml" rel="self" type="application/rss+xml"/><item><title>用 /insights 审视你的编码习惯</title><link>https://time-friend.com/zh/archive/claude-code-insights/</link><pubDate>Mon, 27 Jul 2026 16:30:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/claude-code-insights/</guid><description>&lt;p&gt;Claude Code 用了一段时间, 自我感觉挺良好. 直到有朋友跟我说: &amp;ldquo;你试试 &lt;code&gt;/insights&lt;/code&gt;.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;运行 &lt;code&gt;claude&lt;/code&gt; 进入会话, 输入:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/insights
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;等个几十秒, 浏览器里自动弹出一个 HTML 报告. 它会分析你过去 30 天的 Claude Code 会话, 拆成几个板块: 你在什么项目上花了多少时间、最常用哪些工具、语言分布、以及——最扎心的——你的工作流里哪些地方在反复浪费 Token.&lt;/p&gt;
&lt;p&gt;所有数据都来自本地的 &lt;code&gt;~/.claude/&lt;/code&gt; 会话日志, 报告不会离开你的电脑.&lt;/p&gt;
&lt;h2 id="报告的结构"&gt;报告的结构&lt;/h2&gt;
&lt;h3 id="概览数据"&gt;概览数据&lt;/h3&gt;
&lt;p&gt;最上面一个 &amp;ldquo;At a Glance&amp;rdquo; 卡片, 展示核心统计: 会话数、总消息数、代码修改行数、活跃天数.&lt;/p&gt;
&lt;p&gt;我第一次跑出来是 38 个会话, 659 条消息, 22 天活跃. 看一眼大概就知道自己用得有多勤.&lt;/p&gt;
&lt;h3 id="使用模式"&gt;使用模式&lt;/h3&gt;
&lt;p&gt;报告用柱状图展示了几个维度:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;最常用的工具&lt;/strong&gt;: 你会发现自己的 Edit 用了多少次, Bash、Read、Write 各占多少比例&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;编程语言分布&lt;/strong&gt;: TypeScript、Python、Markdown 各占百分之几——这个分布有时候会让人意外&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;任务类型&lt;/strong&gt;: 代码生成、调试、重构、测试编写各占多少&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;会话时长&lt;/strong&gt;: 平均每条会话多久, 平均回复时间多少&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我第一次看到自己 18% 的时间花在 Markdown 上时, 重新思考了一下自己的工作流——原来写文档占了我这么多精力.&lt;/p&gt;
&lt;h3 id="使用风格分析"&gt;使用风格分析&lt;/h3&gt;
&lt;p&gt;报告会生成一段自然语言描述, 分析你的工作风格. 不止是数字, 而是一段像人写出来的评语.&lt;/p&gt;</description></item><item><title>从终端到团队, Agent 工作流怎么长大</title><link>https://time-friend.com/zh/archive/claude-code-scaling-workflows/</link><pubDate>Sat, 18 Apr 2026 17:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/claude-code-scaling-workflows/</guid><description>&lt;p&gt;头几个月, 我一个人在终端里用 Claude Code, 感觉效率提升很明显。但很快遇到一个问题: 我下班关了电脑, agent 也停了。我需要的东西, 只能在我坐在电脑前的时候才能跑。&lt;/p&gt;
&lt;p&gt;如果你的使用场景也是&amp;quot;只有我在的时候才用&amp;quot;, 那 Claude Code 完全够用。但当你开始想: 这个 CR 能不能自动帮我 review? 这个依赖更新能不能每周一自动跑? 你就需要想怎么让它离开你的电脑还能干活了。&lt;/p&gt;
&lt;h2 id="第一步-把重复劳动做成脚本"&gt;第一步: 把重复劳动做成脚本&lt;/h2&gt;
&lt;p&gt;最简单的方式就是把常用的 agent 任务写成脚本。比如我每两周要升级一次项目的依赖:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;claude -p &lt;span style="color:#e6db74"&gt;&amp;#34;把 package.json 里的依赖升到最新 minor 版本, 跑测试, 有 break 就修&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;用 &lt;code&gt;--output-format json&lt;/code&gt; 可以拿到结构化的输出。需要流式处理的话用 &lt;code&gt;stream-json&lt;/code&gt;, 每行一个 JSON 对象。&lt;/p&gt;
&lt;p&gt;再进一步, 把这些脚本扔到 crontab 或者 CI 里:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 在 GitHub Actions 或 crontab 里跑&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;claude -p &lt;span style="color:#e6db74"&gt;&amp;#34;review 最近变更的代码, 检查安全问题&amp;#34;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --output-format json --allowedTools &lt;span style="color:#e6db74"&gt;&amp;#34;Edit,Bash(git *)&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;--allowedTools&lt;/code&gt; 限制了 Claude 只能做什么操作——批量跑的时候尤其重要, 防止它乱搞。&lt;/p&gt;</description></item><item><title>Review Agent 的代码, 和 Review 同事的不一样</title><link>https://time-friend.com/zh/archive/claude-code-review-agent-code/</link><pubDate>Fri, 03 Apr 2026 13:25:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/claude-code-review-agent-code/</guid><description>&lt;p&gt;Review 同事写的代码, 和 review agent 写的代码, 是两套不同的事。&lt;/p&gt;
&lt;p&gt;一起干活久了, 多少知道同事写代码的习惯——谁喜欢用 reduce, 谁总忘记处理边界。但 agent 没有&amp;quot;习惯&amp;quot;, 它的每一次输出都取决于那次会话的上下文。&lt;/p&gt;
&lt;p&gt;Review agent 代码的时候, 我养了几个自己的检查点。&lt;/p&gt;
&lt;h2 id="第一-看它改了不该改的地方吗"&gt;第一: 看它改了不该改的地方吗&lt;/h2&gt;
&lt;p&gt;Agent 最大的问题不是写不对, 是管不住自己。它可能为了修一个 bug, 顺手把旁边的配置也改了, 或者把另一个函数的重命名顺便带上了。&lt;/p&gt;
&lt;p&gt;Diff 文件里所有不在任务范围内的改动, 都是危险信号。&lt;/p&gt;
&lt;h2 id="第二-看它处理边界了吗"&gt;第二: 看它处理边界了吗&lt;/h2&gt;
&lt;p&gt;Claude 写的 happy path 通常很漂亮。问题出在用户输入为空、网络请求超时、权限不足的时候——这些分支常常没覆盖。&lt;/p&gt;
&lt;p&gt;Review 的时候我会专门盯着 if/else 的分支看: 所有 else 和 catch 里的逻辑是真的处理了错误, 还是只是打了个 log 就过去了?&lt;/p&gt;
&lt;h2 id="第三-看测试是真测还是假测"&gt;第三: 看测试是真测还是假测&lt;/h2&gt;
&lt;p&gt;这是 agent 最喜欢偷懒的地方。写出来的测试看起来跑过了, 但仔细一看——mock 了整个函数, 断言了一个硬编码的值, 或者测了一个从来不会失败的条件。&lt;/p&gt;
&lt;p&gt;我有个检查习惯: 把测试里的数据换一批, 看看它还能不能过。换数据就挂的测试, 说明测的是假逻辑。&lt;/p&gt;
&lt;h2 id="第四-看代码风格是不是和项目一致"&gt;第四: 看代码风格是不是和项目一致&lt;/h2&gt;
&lt;p&gt;Agent 有自己的默认风格——它写出来的代码可能技术上没问题, 但跟你们项目里现有的代码风格格格不入。&lt;/p&gt;
&lt;p&gt;命名风格、错误处理模式、甚至空行的习惯——这些不一致不会让代码出 bug, 但会让维护的人很痛苦。如果发现风格不一致, 回 CLAUDE.md 里加一条规则, 下次就好了。&lt;/p&gt;</description></item><item><title>这五类任务别交给 Agent</title><link>https://time-friend.com/zh/archive/claude-code-tasks-to-avoid/</link><pubDate>Sun, 22 Mar 2026 08:50:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/claude-code-tasks-to-avoid/</guid><description>&lt;p&gt;用了几个月 agent, 很容易进入一种状态: 什么东西都想扔给它干。&lt;/p&gt;
&lt;p&gt;但有些任务真的不适合——不是 agent 能力不够, 是让它干的风险和收益不成正比。&lt;/p&gt;
&lt;h2 id="一涉及生产数据的操作"&gt;一、涉及生产数据的操作&lt;/h2&gt;
&lt;p&gt;直接在生产数据库上跑 SQL——哪怕是 &lt;code&gt;SELECT&lt;/code&gt;——我不放心。Claude 不会故意搞破坏, 但它可能因为理解偏差, 扫了全表导致数据库打嗝。操作生产环境的配置、直接改线上服务的部署配置——这类事我坚持自己来。回滚一次的时间比让 agent 操作省的时间多得多。&lt;/p&gt;
&lt;h2 id="二安全敏感的变更"&gt;二、安全敏感的变更&lt;/h2&gt;
&lt;p&gt;改登录逻辑、权限校验、加密解密——这些我从来不交给 agent。不是因为 Claude 写不对, 而是这类代码出事就是大事, 而且漏洞往往不在明面上。&lt;/p&gt;
&lt;p&gt;我的做法: agent 可以写 draft, 但每一行我都要亲自 review, 并且要额外找个同事再看一遍。不信任叠加——两层人眼比一层可靠。&lt;/p&gt;
&lt;h2 id="三需要人类判断的决策"&gt;三、需要人类判断的决策&lt;/h2&gt;
&lt;p&gt;&amp;ldquo;这个按钮是放左边还是右边&amp;quot;&amp;ldquo;这个错误信息用户能看懂吗&amp;quot;&amp;ldquo;这个 API 的返回值要不要加个字段&amp;rdquo;——这些没有对错之分, 只有&amp;quot;合不合适&amp;quot;的问题。&lt;/p&gt;
&lt;p&gt;Agent 没有产品 sense, 也没有用户的上下文。让它在两套方案里选一个, 它选的方案可能从技术角度看最优, 但从产品角度看完全不对。&lt;/p&gt;
&lt;h2 id="四模棱两可的看看"&gt;四、模棱两可的&amp;quot;看看&amp;rdquo;&lt;/h2&gt;
&lt;p&gt;&amp;ldquo;帮我看看这个项目有什么可以改进的地方&amp;rdquo;——没有范围、没有标准、没有截止条件。Claude 会去读几百个文件, 然后把上下文塞满, 最后给你一个泛泛的报告。&lt;/p&gt;
&lt;p&gt;如果你真的想做代码审查, 给范围: &amp;ldquo;只看 src/api/ 下的错误处理逻辑, 找潜在的空指针风险&amp;rdquo;。&lt;/p&gt;
&lt;h2 id="五跨多系统的协调"&gt;五、跨多系统的协调&lt;/h2&gt;
&lt;p&gt;需要改 A 服务、等 B 服务部署完、再看 C 服务的响应有没有变化——这种跨系统的流程, agent 做不了。不是因为技术不行, 而是每一步之间可能有你无法预料的依赖, agent 不知道什么时候该等、什么时候该继续。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;当然, 这些&amp;quot;不适合&amp;quot;的边界不是固定的。随着你越来越了解 agent 的能力边界, 有些之前不敢放手的任务, 后来发现其实可以。&lt;/p&gt;</description></item><item><title>Agent 和 Assistant 是两回事</title><link>https://time-friend.com/zh/archive/claude-code-agent-vs-assistant/</link><pubDate>Sat, 14 Mar 2026 15:40:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/claude-code-agent-vs-assistant/</guid><description>&lt;p&gt;刚用 Claude Code 的时候, 我花了不少时间纠结一个问题: 它到底是 agent 还是 assistant?&lt;/p&gt;
&lt;p&gt;看了不少文章, 大部分试图给这两个词划一条清晰的线——assistant 一次一步, agent 自主完成目标。但实际用下来的感受是, 大多数工具两种模式都能切, 分界线没那么分明。&lt;/p&gt;
&lt;p&gt;真正有意义的区别不是产品叫什么, 而是&lt;strong&gt;谁发起、谁控制、在哪里跑&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="assistant-模式-你每步都要盯着"&gt;Assistant 模式: 你每步都要盯着&lt;/h2&gt;
&lt;p&gt;用 Claude Code 最基础的用法就是这样: 你打一句 prompt, 它动一下, 你看一眼, 然后你打下一句。&lt;/p&gt;
&lt;p&gt;你在每一轮都掌握控制权。你决定下一步做什么, agent 只是执行。这种模式下:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你全程在场, 不太会出大问题&lt;/li&gt;
&lt;li&gt;但你的注意力被绑死了——它动一下你就要看一下&lt;/li&gt;
&lt;li&gt;适合探索性的工作: 调试、原型、架构讨论&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="agent-模式-定好目标就放手"&gt;Agent 模式: 定好目标就放手&lt;/h2&gt;
&lt;p&gt;把目标扔给 Claude, 它自己去读代码、改代码、跑测试, 最终给你一个结果。&lt;/p&gt;
&lt;p&gt;这时候你的角色变了——你不再是驾驶员, 而是定目标的人和审结果的人。中间的过程你不需要每步都看。&lt;/p&gt;
&lt;p&gt;这种模式下:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你的注意力可以解放出来, 同时干别的事&lt;/li&gt;
&lt;li&gt;但风险也高了——它可能走偏了等你回来才发现&lt;/li&gt;
&lt;li&gt;适合有清晰完成标准的任务: 重构、迁移、批量修测试&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="最实用的分法-看触发方式"&gt;最实用的分法: 看触发方式&lt;/h2&gt;
&lt;p&gt;抛开理论, 实际工作中最好用的区分方式其实是&lt;strong&gt;谁触发的&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你在终端里敲命令 → Assistant 模式&lt;/li&gt;
&lt;li&gt;定时任务跑起来的、GitHub Webhook 触发的、CI 里自动执行的 → Agent 模式&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我自己最有价值的体会是: 不用纠结它该叫 agent 还是 assistant, 而是建立一条 pipeline——用 assistant 模式试出一个可靠的工作流, 然后把它变成定时跑的 agent 任务。&lt;/p&gt;</description></item><item><title>几轮对话后 Claude 变笨了</title><link>https://time-friend.com/zh/archive/claude-code-advanced-practices/</link><pubDate>Fri, 06 Mar 2026 11:10:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/claude-code-advanced-practices/</guid><description>&lt;p&gt;用了几个月 Claude Code 之后, 我遇到了一个奇怪的现象: 同一个会话, 做到后面感觉 Claude 变蠢了。&lt;/p&gt;
&lt;p&gt;不是你的错觉, 也不是模型的问题。是上下文炸了。&lt;/p&gt;
&lt;h2 id="上下文是怎么炸的"&gt;上下文是怎么炸的&lt;/h2&gt;
&lt;p&gt;Claude 的工作记忆是有限的。会话一开始, 它清楚地记得目标是什么、做了哪些决策、还有哪些事没做完。到了第 50 轮, 上下文里塞满了走过的弯路、讨论过的方案、和你争论的对话历史。&lt;/p&gt;
&lt;p&gt;输出质量下降是必然的。&lt;/p&gt;
&lt;h2 id="每轮对话都是检查点"&gt;每轮对话都是检查点&lt;/h2&gt;
&lt;p&gt;Claude Code 有一个很方便的机制: &lt;strong&gt;每发出一条 prompt 就会自动创建一个快照&lt;/strong&gt;。不只是记对话, 还会快照被修改的文件状态。&lt;/p&gt;
&lt;p&gt;按两次 &lt;code&gt;Escape&lt;/code&gt; 或者输入 &lt;code&gt;/rewind&lt;/code&gt;, 会打开回退菜单。你可以选择:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;只回退对话&lt;/li&gt;
&lt;li&gt;只恢复代码&lt;/li&gt;
&lt;li&gt;两者都回退&lt;/li&gt;
&lt;li&gt;从某个节点开始压缩&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;有了这个, 你可以大胆地让 Claude 尝试高风险方案。不行就回退, 不丢任何代码。检查点会随会话保存, 关掉终端回来还能继续回退。&lt;/p&gt;
&lt;p&gt;但要注意: 检查点只追踪 Claude 通过编辑工具做的修改。通过 Bash 命令或外部进程改的东西不在此列。它不是 git 的替代品。&lt;/p&gt;
&lt;h2 id="几个习惯-保持上下文干净"&gt;几个习惯, 保持上下文干净&lt;/h2&gt;
&lt;h3 id="走偏了立刻打断"&gt;走偏了立刻打断&lt;/h3&gt;
&lt;p&gt;按 &lt;code&gt;Escape&lt;/code&gt; 中断它。按两次 &lt;code&gt;Escape&lt;/code&gt; 打开回退菜单, 可以回滚到之前的状态。&lt;/p&gt;
&lt;p&gt;我踩过的一个坑: 当 Claude 反复回到一个错误假设的时候, 我下意识用了 &lt;code&gt;/compact&lt;/code&gt;。结果它把那个错误假设也保留了, 问题没解决。正确做法是:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;最好的是 &lt;code&gt;/clear&lt;/code&gt; 清空, 用更精确的 prompt 重新开始&lt;/li&gt;
&lt;li&gt;如果你想保留当前的关键上下文, 用 &lt;code&gt;/compact 只保留 API 变更相关的部分, 丢掉调试过程&lt;/code&gt;——加上 focus 指令告诉它该留什么&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="常用命令"&gt;常用命令&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;/clear&lt;/code&gt;&lt;/strong&gt;: 任务之间清空上下文, 别让上个任务的逻辑污染下个任务&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;/compact&lt;/code&gt;&lt;/strong&gt;: 加 focus 指令, 用在长而连贯的会话里, 保留关键部分丢掉噪音&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Subagent&lt;/strong&gt;: 把大量研究类的工作交给它, 在独立上下文里完成, 还你一个总结&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;/rename&lt;/code&gt;&lt;/strong&gt;: 给重要的会话打标签, 方便之后找回&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="我自己用的土办法"&gt;我自己用的土办法&lt;/h3&gt;
&lt;p&gt;每次完成一个逻辑单元——一个函数、一个组件——就 &lt;code&gt;git commit&lt;/code&gt;, 然后 &lt;code&gt;/clear&lt;/code&gt;, 再开始下一个。&lt;/p&gt;</description></item><item><title>我的 CLAUDE.md 里都放了什么</title><link>https://time-friend.com/zh/archive/claude-code-configuration/</link><pubDate>Thu, 19 Feb 2026 16:20:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/claude-code-configuration/</guid><description>&lt;p&gt;最讽刺的事情是什么? 你一边抱怨&amp;quot;每次新会话都要重新跟 Claude 解释项目背景&amp;quot;, 一边项目根目录里根本没有 &lt;code&gt;CLAUDE.md&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;别笑, 我之前就是这个状态。&lt;/p&gt;
&lt;p&gt;后来发现有个偷懒的办法——直接跑 &lt;code&gt;/init&lt;/code&gt;。Claude 会自动分析你的项目结构、检测构建工具和测试框架, 生成一份初始的 CLAUDE.md。如果已经有 CLAUDE.md 了, &lt;code&gt;/init&lt;/code&gt; 不会覆盖, 而是建议改进。&lt;/p&gt;
&lt;h2 id="claudemd-的本质"&gt;CLAUDE.md 的本质&lt;/h2&gt;
&lt;p&gt;Claude Code 启动的时候会自动读这个文件, 把它当作用来理解项目的起点。你项目怎么跑测试、目录结构是什么、有哪些不能碰的约定——写进去, 它自己就知道了。&lt;/p&gt;
&lt;h3 id="第一类-命令"&gt;第一类: 命令&lt;/h3&gt;
&lt;p&gt;最常见的用法——把命令写进去, 省得每次说:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;## Commands
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;-&lt;/span&gt; 测试: npm test
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;-&lt;/span&gt; 构建: npm run build
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;-&lt;/span&gt; 单文件测试: npx jest src/xxx.test.ts
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;-&lt;/span&gt; Lint: npx eslint src/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;有了这些, Claude 自己知道该跑什么, 不用你再说&amp;quot;跑一下测试&amp;quot;。&lt;/p&gt;
&lt;h3 id="第二类-架构约定"&gt;第二类: 架构约定&lt;/h3&gt;
&lt;p&gt;有些东西 Claude 看代码看不出来:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;## Architecture
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;-&lt;/span&gt; 状态管理用 Zustand, 不用 Redux
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;-&lt;/span&gt; API 请求统一走 src/api/ 下的封装
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;-&lt;/span&gt; 不要直接改 src/core/ 里的文件, 只能通过扩展接口
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="第三类-团队规范"&gt;第三类: 团队规范&lt;/h3&gt;
&lt;p&gt;Linter 管不了, 但 review 的时候一定会被说的:&lt;/p&gt;</description></item><item><title>Agent 改完的代码, 你敢直接合吗</title><link>https://time-friend.com/zh/archive/claude-code-self-verification/</link><pubDate>Thu, 05 Feb 2026 09:45:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/claude-code-self-verification/</guid><description>&lt;p&gt;Claude 改完代码说了一声&amp;quot;Done&amp;quot;, 你看了一眼觉得差不多, 就合并了。然后周一线上挂了。&lt;/p&gt;
&lt;p&gt;没有可运行的检查, agent 觉得&amp;quot;做完了&amp;quot;和你觉得&amp;quot;做完了&amp;quot;是两码事。最贵的 bug 不是崩溃, 是安安静静返回了错误结果。&lt;/p&gt;
&lt;h2 id="最简单的-prompt-里加一句"&gt;最简单的: prompt 里加一句&lt;/h2&gt;
&lt;p&gt;最轻量的做法, 就是在 prompt 末尾加一句话:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;改完之后跑一下测试, 不通过就继续修.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Claude 改完代码会自己去跑 &lt;code&gt;npm test&lt;/code&gt;, 挂了就回头看代码, 修好了再跑。全过程不需要你介入。&lt;/p&gt;
&lt;p&gt;但这有个问题——它只按照自己理解的标准来验证。如果你的测试覆盖率不够, 或者&amp;quot;完成&amp;quot;的定义比跑通测试更复杂, 就需要更多层。&lt;/p&gt;
&lt;h2 id="分层往上加"&gt;分层往上加&lt;/h2&gt;
&lt;h3 id="第一层-prompt-内检查"&gt;第一层: prompt 内检查&lt;/h3&gt;
&lt;p&gt;就是上面说的, 告诉它跑测试。日常小改动用这个就够了。&lt;/p&gt;
&lt;h3 id="第二层-定义完成标准"&gt;第二层: 定义完成标准&lt;/h3&gt;
&lt;p&gt;在 prompt 里说清楚什么算&amp;quot;做完&amp;quot;:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;每次修改完运行 npm run build &amp;amp;&amp;amp; npm test, 把输出发给我.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这样你至少能看到它跑了什么、输出了什么, 不是它说 done 你就信。&lt;/p&gt;
&lt;h3 id="第三层-不让它糊弄"&gt;第三层: 不让它糊弄&lt;/h3&gt;
&lt;p&gt;加一句关键的:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;修复根因, 不要掩盖错误.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这能防止 agent 用空的 try-catch 或者假的 fallback 数据来敷衍你。&lt;/p&gt;
&lt;h3 id="第四层-goal-条件"&gt;第四层: &lt;code&gt;/goal&lt;/code&gt; 条件&lt;/h3&gt;
&lt;p&gt;把验证条件设成会话级的 goal, 每次修改后自动检查:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/goal 测试全部通过, 构建产物不超过 200KB
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Claude 会在每轮修改后重新检查, 不满足就继续改, 不需要你每次都说&amp;quot;再跑一下测试&amp;quot;。&lt;/p&gt;</description></item><item><title>写 Prompt 一次过的秘诀</title><link>https://time-friend.com/zh/archive/claude-code-effective-prompts/</link><pubDate>Thu, 22 Jan 2026 14:15:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/claude-code-effective-prompts/</guid><description>&lt;p&gt;用了一段时间 Claude Code, 你会发现大部分翻车的会话不是模型不行, 是你自己的 prompt 有问题。Claude 能猜你的意图, 但你没法指望它会读心。&lt;/p&gt;
&lt;h2 id="把任务范围卡死"&gt;把任务范围卡死&lt;/h2&gt;
&lt;p&gt;&amp;ldquo;帮我优化一下这段代码&amp;rdquo;——这种 prompt 出来什么结果全看运气。什么叫优化? 性能、可读性、还是裁掉冗余代码?&lt;/p&gt;
&lt;p&gt;好的 prompt 应该说清楚文件、场景和验证方式:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;给 src/auth.ts 写一个已登出用户的边缘用例测试, 不要用 mock.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;任务范围越小, 结果越可控。模糊的 prompt 只有在一种情况下有用——你真的想让 agent 给意见的时候。&amp;ldquo;这个文件你有什么改进建议&amp;quot;就很合适, 但记得限定范围, 别让它自己逛到几百个文件里去。&lt;/p&gt;
&lt;h2 id="指一个现成的例子"&gt;指一个现成的例子&lt;/h2&gt;
&lt;p&gt;Claude 从真实代码里学规范比从文字描述里学快得多。你不需要跟它解释&amp;quot;我们项目的命名规范是驼峰、接口前缀有 I 开头&amp;rdquo;——&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;参考 src/services/user.ts 的写法, 用同样的模式实现这个新接口.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;一句话, 比一百字描述都有用。&lt;/p&gt;
&lt;h2 id="报-bug-按固定格式来"&gt;报 Bug 按固定格式来&lt;/h2&gt;
&lt;p&gt;我 debug 的时候用这个格式, 很少出问题:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;症状: 用户登录后跳到 404 页面
位置: src/router/index.ts 第 42-56 行的路由守卫逻辑
修复标准: 登录后跳到 redirect 参数指定的页面, 没有 redirect 就去首页
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;再加一句 &amp;ldquo;先写一个能复现的测试再修&amp;rdquo;, 能防止它改完了但什么都没修。&lt;/p&gt;
&lt;h2 id="用-btw-处理临时小问题"&gt;用 &lt;code&gt;/btw&lt;/code&gt; 处理临时小问题&lt;/h2&gt;
&lt;p&gt;有时候你做到一半, 突然想确认一个不相关的事——&amp;ldquo;这个包的 API 签名是什么样的?&amp;quot;。如果用主会话问, 它会污染上下文。用 &lt;code&gt;/btw 这个包的 API 签名是什么&lt;/code&gt; 问, 答案会以浮层显示, 不进对话历史, 不占上下文。&lt;/p&gt;</description></item><item><title>用 Plan → Code 循环管住你的 Agent</title><link>https://time-friend.com/zh/archive/claude-code-plan-code-loop/</link><pubDate>Thu, 08 Jan 2026 10:30:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/claude-code-plan-code-loop/</guid><description>&lt;p&gt;刚用 Claude Code 的时候我有个毛病: 打开终端, 直接敲一句话告诉它帮我改什么, 然后看着它一顿操作, 最后发现方向完全不对。&lt;/p&gt;
&lt;p&gt;后来想明白一个道理——Agentic Coding 和写代码是两套不同的技能。写代码的时候你的手跟着脑子走, 但用 agent 的时候, 你的价值在于&amp;quot;定义目标&amp;quot;和&amp;quot;审核结果&amp;quot;, 而不是替它打字。&lt;/p&gt;
&lt;p&gt;那怎么让 agent 不走偏? 我总结了四个步骤: &lt;strong&gt;探索 → 规划 → 编码 → 提交&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="第一步-先探索-别动手"&gt;第一步: 先探索, 别动手&lt;/h2&gt;
&lt;p&gt;Plan 模式是 Claude Code 的只读模式。启动的时候加个参数:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;claude --permission-mode plan
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;会话里按 &lt;code&gt;Shift+Tab&lt;/code&gt; 可以在 Plan 和 Accept-Edits 之间切换, 或者直接打 &lt;code&gt;/plan&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;为什么要先探索? Claude 对项目的理解完全取决于你给了什么上下文。让它自己把相关文件读一遍, 画出一张地图, 比你凭直觉说&amp;quot;去改那个文件&amp;quot;要靠谱得多。&lt;/p&gt;
&lt;p&gt;碰到特别棘手的架构问题, 我习惯在 prompt 里加一句 &amp;ldquo;think carefully before proposing anything&amp;rdquo;。多数情况下, 它前面的推理越仔细, 后面的返工就越少。&lt;/p&gt;
&lt;p&gt;不过也别教条。如果任务很小——修个 typo、改个变量名、加一行日志——直接让它做就行, 不需要走完整个 plan 流程。官网文档也说了: 如果你能用一句话描述完改动内容, 那就跳过 plan。&lt;/p&gt;</description></item><item><title>博客 Logo 动画是怎么做的</title><link>https://time-friend.com/zh/archive/blog-architecture-animated-logo/</link><pubDate>Thu, 14 Aug 2025 17:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/blog-architecture-animated-logo/</guid><description>&lt;p&gt;网站左上角那个小方框, 是视频.&lt;/p&gt;
&lt;p&gt;默认灰度, hover 才亮起来, 颜色每次还不一样, 播放速度也会先快后缓. 像被惊醒了一下.&lt;/p&gt;
&lt;h1 id="为什么做这个"&gt;为什么做这个&lt;/h1&gt;
&lt;p&gt;之前 logo 是张静态 PNG. 总觉得缺了点呼吸感. 正好手头有一段素材, 就把 logo 从静态图换成了视频.&lt;/p&gt;
&lt;h1 id="mp4-没有-alpha-通道"&gt;mp4 没有 Alpha 通道&lt;/h1&gt;
&lt;p&gt;剪映导出时明明去掉了背景, 但 mp4 不支持透明通道, 透明部分被压成了黑色.&lt;/p&gt;
&lt;p&gt;桌面端用 &lt;code&gt;mix-blend-mode: screen&lt;/code&gt; 解决 — 黑色变完全透明, 只保留亮色部分:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;@&lt;span style="color:#66d9ef"&gt;media&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#f92672"&gt;hover&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#f92672"&gt;hover&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#f92672"&gt;and&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#f92672"&gt;pointer&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#f92672"&gt;fine&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; #header #logo { &lt;span style="color:#66d9ef"&gt;mix-blend-mode&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;screen&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;限定 &lt;code&gt;(hover: hover)&lt;/code&gt; 是因为移动端浏览器对 &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; 的 blend mode 支持普遍不好.&lt;/p&gt;
&lt;p&gt;移动端改用 &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; 做逐像素抠图: video 隐藏继续播放, canvas 每帧取画面, RGB 都低于 30 的像素 alpha 置 0:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;render&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;canvasCtx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;drawImage&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;videoEl&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;w&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;h&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;canvasCtx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getImageData&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;w&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;h&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;canvasCtx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;createImageData&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;w&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;h&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;] &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;30&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;] &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;30&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;] &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;30&lt;/span&gt;) &lt;span style="color:#f92672"&gt;?&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;255&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;canvasCtx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;putImageData&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;requestAnimationFrame&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;render&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这个性能取决于视频分辨率, logo 尺寸很小, 所以开销可以接受.&lt;/p&gt;</description></item><item><title>首页打字效果是如何实现的</title><link>https://time-friend.com/zh/archive/blog-architecture-typing-effect/</link><pubDate>Tue, 12 Aug 2025 11:50:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/blog-architecture-typing-effect/</guid><description>&lt;p&gt;打开首页会看到一行文字在逐字打字, 过几秒又换一句. 这个效果不复杂, 但很多人问怎么做的.&lt;/p&gt;
&lt;p&gt;这篇说一下实现方式.&lt;/p&gt;
&lt;h1 id="整体原理"&gt;整体原理&lt;/h1&gt;
&lt;p&gt;首页加载时, 从一个 JSON 文件里随机选一句台词, 用 Typed.js 这个库模拟打字效果.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;首页加载
 ↓
main.js 检测到当前是首页
 ↓
根据语言 (中文/英文) 确定取哪个字段
 ↓
从 /data/quotes.json 随机取一条
 ↓
传给 Typed.js, 开始打字动画
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id="数据来源-quotesjson"&gt;数据来源: quotes.json&lt;/h1&gt;
&lt;p&gt;台词存在 &lt;code&gt;static/data/quotes.json&lt;/code&gt; 里.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;en&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Hope is a good thing, maybe the best of things, and no good thing ever dies.&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;zh&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;希望是美好的，也许是世间最美好的事物，而美好的事物永不消逝。&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;author&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;The Shawshank Redemption&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;en&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Get busy living or get busy dying.&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;zh&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;忙着活，或忙着死。&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;author&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;The Shawshank Redemption&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;每条数据包含三个字段:&lt;/p&gt;</description></item><item><title>如何让博客支持离线访问</title><link>https://time-friend.com/zh/archive/blog-architecture-service-worker/</link><pubDate>Tue, 08 Jul 2025 15:30:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/blog-architecture-service-worker/</guid><description>&lt;p&gt;PWA 是个 buzzword, 说白了这个博客用到的 PWA 功能就两个: manifest.json 和 Service Worker. manifest.json 让浏览器知道&amp;quot;这是个应用&amp;quot;, Service Worker 让它在离线时也能工作.&lt;/p&gt;
&lt;p&gt;这篇重点说 Service Worker, 因为它比较复杂. manifest.json 很简单, 放在最后说.&lt;/p&gt;
&lt;h1 id="service-worker-是什么"&gt;Service Worker 是什么&lt;/h1&gt;
&lt;p&gt;简单说, Service Worker 是一个运行在浏览器背后的脚本. 它独立于网页, 在后台默默干活.&lt;/p&gt;
&lt;p&gt;你可以把它理解为&lt;strong&gt;浏览器和网络之间的中间人&lt;/strong&gt;. 正常情况下, 浏览器请求一个资源 (HTML, JS, 图片), 直接去服务器拿. 有了 Service Worker, 请求会先经过它:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;浏览器 → Service Worker → 网络 (或缓存)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Service Worker 可以决定: 这个请求是去网络拿, 还是直接从本地缓存返回, 还是两者都做.&lt;/p&gt;
&lt;p&gt;这个博客的 Service Worker 就是用 Workbox 生成的, 大约 5KB.&lt;/p&gt;
&lt;h1 id="有什么用"&gt;有什么用&lt;/h1&gt;
&lt;h2 id="离线访问"&gt;离线访问&lt;/h2&gt;
&lt;p&gt;这是最核心的功能. 如果用户访问过一次博客, Service Worker 会把静态资源缓存下来. 下次即使没有网络, 也能打开之前看过的文章.&lt;/p&gt;</description></item><item><title>我是怎么给博客加页面统计的</title><link>https://time-friend.com/zh/archive/blog-architecture-analytics/</link><pubDate>Sun, 15 Jun 2025 13:20:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/blog-architecture-analytics/</guid><description>&lt;p&gt;写博客不知道有没有人看, 会很空虚. 统计不是为了 KPI, 就是图一乐.&lt;/p&gt;
&lt;p&gt;这个博客的页面统计有两套系统, 各管各的.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Busuanzi&lt;/strong&gt; 显示在文章页面上, 读者能看到每篇文章被看了多少次. 它是开源的, 不需要注册, 脚本一引就行.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Google Analytics&lt;/strong&gt; 在后台跑, 只有我自己能看到. 用来分析流量来源, 用户分布, 热门内容等.&lt;/p&gt;
&lt;p&gt;两套互不干扰.&lt;/p&gt;
&lt;h1 id="busuanzi-前端展示"&gt;Busuanzi (前端展示)&lt;/h1&gt;
&lt;p&gt;Busuanzi 是不蒜子的英文名, 一个极简的阅读统计工具. 没有后台, 没有 Dashboard, 只有一个计数器和一段 JS 脚本.&lt;/p&gt;
&lt;h2 id="引入脚本"&gt;引入脚本&lt;/h2&gt;
&lt;p&gt;在 &lt;code&gt;layouts/partials/js.html&lt;/code&gt; 里加载:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ if .IsPage }}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;async&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ end }}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;只在文章页加载, 首页和列表页不用.&lt;/p&gt;
&lt;h2 id="显示阅读量"&gt;显示阅读量&lt;/h2&gt;
&lt;p&gt;在文章页模板 &lt;code&gt;layouts/_default/single.html&lt;/code&gt; 里:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;article-tag&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;i&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;fa fa-eye&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;i&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;span&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;busuanzi_container_page_pv&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;span&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;busuanzi_value_page_pv&amp;#34;&lt;/span&gt;&amp;gt;0&amp;lt;/&lt;span style="color:#f92672"&gt;span&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;/&lt;span style="color:#f92672"&gt;span&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;div&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Busuanzi 的脚本加载后会自动查找 &lt;code&gt;id=&amp;quot;busuanzi_value_page_pv&amp;quot;&lt;/code&gt; 的元素, 把阅读量填进去. 数据存在 Busuanzi 的服务端, 不需要自己维护.&lt;/p&gt;</description></item><item><title>评论系统怎么接入博客的</title><link>https://time-friend.com/zh/archive/blog-architecture-giscus/</link><pubDate>Tue, 06 May 2025 10:30:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/blog-architecture-giscus/</guid><description>&lt;p&gt;博客不能没有评论. 但又不想为了一个评论功能去搞数据库和 moderation. Giscus 是一个折中方案.&lt;/p&gt;
&lt;p&gt;这个博客的评论系统用的是 Giscus. 它基于 GitHub Discussions. 所有评论都直接存在 GitHub 仓库里, 不需要自建数据库, 不需要第三方服务.&lt;/p&gt;
&lt;h1 id="整体流程"&gt;整体流程&lt;/h1&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;用户打开文章页
 ↓
加载 giscus.app/client.js
 ↓
Giscus 脚本读取 data- 属性配置
 ↓
根据 mapping=&amp;#34;pathname&amp;#34; 取当前 URL 路径
 ↓
用 GitHub Discussions API 查询匹配的 Discussion
 ↓
找到 → 渲染评论框和已有评论
未找到 → 显示&amp;#34;留个评论吧&amp;#34;输入框
 ↓
用户写评论 → 点击发布
 ↓
跳转 GitHub OAuth 授权 (首次需要)
 ↓
评论通过 API 写入仓库的 Discussions
 ↓
Giscus WebSocket 监听变更 → 实时更新评论区
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;整个过程用户无感知, 不需要离开页面.&lt;/p&gt;
&lt;h1 id="哪里对接"&gt;哪里对接&lt;/h1&gt;
&lt;p&gt;评论系统以 script 标签嵌入页面. 在 &lt;code&gt;layouts/partials/comments.html&lt;/code&gt; 里:&lt;/p&gt;</description></item><item><title>我是怎么部署这个博客的</title><link>https://time-friend.com/zh/archive/blog-architecture-deployment/</link><pubDate>Thu, 10 Apr 2025 15:44:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/blog-architecture-deployment/</guid><description>&lt;p&gt;静态文件总得找个地方放, 还得让全世界都能访问.&lt;/p&gt;
&lt;h1 id="部署平台-cloudflare-pages"&gt;部署平台: Cloudflare Pages&lt;/h1&gt;
&lt;p&gt;选 Cloudflare Pages 而不是其他平台, 原因有三:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;全球 CDN&lt;/strong&gt;: Cloudflare 有遍布全球的边缘节点, 无论访客在哪, 都能从最近的节点加载页面&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;零配置 HTTPS&lt;/strong&gt;: 自动签发和续期 SSL 证书, 不需要手动处理&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;免费额度够用&lt;/strong&gt;: 对于个人博客来说, 带宽和构建次数完全够用&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;配置很简单, 在 Cloudflare Pages 控制台创建一个项目, 关联 GitHub 仓库. 构建命令和输出目录在 GitHub Actions 里控制, 不需要在控制台配.&lt;/p&gt;
&lt;p&gt;有个坑: Cloudflare Pages 默认分配的域名是 &lt;code&gt;&amp;lt;project&amp;gt;.pages.dev&lt;/code&gt;, 项目名一旦确定就不能改. 想换只能删掉重建. 我那会儿随便打了个名字, 后来想改发现不行, 只能留着.&lt;/p&gt;
&lt;h1 id="cicd-流程"&gt;CI/CD 流程&lt;/h1&gt;
&lt;p&gt;完整的部署流程由 GitHub Actions 管理:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Deploy to Cloudflare Pages&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;on&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;push&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;branches&lt;/span&gt;: [&lt;span style="color:#ae81ff"&gt;master]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;workflow_dispatch&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;jobs&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;build&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;runs-on&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;ubuntu-latest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;steps&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;uses&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;actions/checkout@v4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;uses&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;peaceiris/actions-hugo@v3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;with&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;hugo-version&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;0.164.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;extended&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;uses&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;actions/setup-node@v4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;with&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;node-version&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;24&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;cache&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;npm&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Install dependencies&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;run&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;npm ci&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Patch theme for Hugo compatibility&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;run&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;bash scripts/patch-theme.sh&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Build&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;run&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;npm run build&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Deploy to Cloudflare Pages&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;run&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;npx wrangler pages deploy public --project-name=time-friend&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;env&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;CLOUDFLARE_API_TOKEN&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;${{ secrets.CLOUDFLARE_API_TOKEN }}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;CLOUDFLARE_ACCOUNT_ID&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;${{ secrets.CLOUDFLARE_ACCOUNT_ID }}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;触发条件是 push 到 master 分支. 也支持手动触发 (&lt;code&gt;workflow_dispatch&lt;/code&gt;), 方便在不改代码的情况下重新部署.&lt;/p&gt;</description></item><item><title>博客的 Google SEO 是怎么做的</title><link>https://time-friend.com/zh/archive/blog-architecture-google-seo/</link><pubDate>Tue, 25 Mar 2025 11:08:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/blog-architecture-google-seo/</guid><description>&lt;p&gt;这篇文章只讲 Google SEO. 其他搜索引擎不搞, 原因很简单: 流量大头在 Google, 把 Google 做好就够了.&lt;/p&gt;
&lt;h1 id="结构化数据"&gt;结构化数据&lt;/h1&gt;
&lt;p&gt;这是最重要的部分. 结构化数据让 Google 在搜索结果里展示 rich result, 包括发布时间, 作者, 摘要等信息.&lt;/p&gt;
&lt;p&gt;每篇文章在构建时自动注入 JSON-LD:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ if .IsPage }}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;type&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;application/ld+json&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;@context&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;https://schema.org&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;@type&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Article&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;headline&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Title }}&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;datePublished&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Date.Format &amp;#34;&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2006&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;01&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;02&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;T15&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;04&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;05&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Z07&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;00&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34; }}&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;dateModified&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Lastmod.Format &amp;#34;&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2006&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;01&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;02&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;T15&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;04&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;05&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Z07&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;00&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34; }}&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;author&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;@type&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Person&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Site.Params.author }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;{{ if .Description }}{{ .Description }}{{ else }}{{ .Summary | plainify }}{{ end }}&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;url&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Permalink }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {{ &lt;span style="color:#66d9ef"&gt;with&lt;/span&gt; .&lt;span style="color:#a6e22e"&gt;Params&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;tags&lt;/span&gt; }}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ,&lt;span style="color:#e6db74"&gt;&amp;#34;keywords&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;{{ delimit . &amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34; }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {{ &lt;span style="color:#a6e22e"&gt;end&lt;/span&gt; }}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ end }}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;关键字段:&lt;/p&gt;</description></item><item><title>博客的构建流水线是怎么跑的</title><link>https://time-friend.com/zh/archive/blog-architecture-build-pipeline-pwa/</link><pubDate>Wed, 05 Mar 2025 16:30:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/blog-architecture-build-pipeline-pwa/</guid><description>&lt;p&gt;文章写完之后, 总不能手动一条条部署. 自动化的目的很简单: push 完代码就什么都不用管了.&lt;/p&gt;
&lt;p&gt;本质上就两件事: 把 Markdown 变成静态文件扔到网上去, 顺便把构建流程自动化.&lt;/p&gt;
&lt;h1 id="gulp-任务"&gt;Gulp 任务&lt;/h1&gt;
&lt;p&gt;整个构建就两个 Gulp 任务, 串行跑:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;gulp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;task&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;default&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;gulp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;series&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;build&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;generate-service-worker&amp;#39;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="build"&gt;build&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;gulp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;task&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;build&amp;#39;&lt;/span&gt;, () =&amp;gt; &lt;span style="color:#a6e22e"&gt;gulp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./&amp;#39;&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;pipe&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;shell&lt;/span&gt;([&lt;span style="color:#e6db74"&gt;&amp;#39;hugo --buildFuture --minify&amp;#39;&lt;/span&gt;])));
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;一行代码. 调用 Hugo 构建, &lt;code&gt;--buildFuture&lt;/code&gt; 允许发布未来日期的内容, &lt;code&gt;--minify&lt;/code&gt; 在构建时做 HTML/CSS/JS 压缩.&lt;/p&gt;
&lt;p&gt;为什么用 gulp-shell 而不是直接调用 Hugo? 因为后续需要在构建完成后做一些处理, Gulp 作为编排工具把任务串起来比较方便. 如果用 npm script 串命令也可以, 但 Gulp 的 task 定义更清晰, 错误处理也更直接.&lt;/p&gt;
&lt;h2 id="generate-service-worker"&gt;generate-service-worker&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;gulp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;task&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;generate-service-worker&amp;#39;&lt;/span&gt;, () =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;workbox&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;generateSW&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;globDirectory&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./public&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;globPatterns&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;&amp;#39;**/*.{woff2,woff,js,css,png.jpg}&amp;#39;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;globIgnores&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;&amp;#39;sw.js&amp;#39;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;swDest&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`./public/sw.js`&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;clientsClaim&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;skipWaiting&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;runtimeCaching&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#a6e22e"&gt;urlPattern&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;/.*\.js/&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;handler&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;NetworkFirst&amp;#39;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#a6e22e"&gt;urlPattern&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;/.*\.css/&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;handler&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;StaleWhileRevalidate&amp;#39;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#a6e22e"&gt;urlPattern&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;/.*\.(?:png|jpg|jpeg|svg|gif)/&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;handler&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;CacheFirst&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;options&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;cacheName&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;images&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;expiration&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;maxEntries&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;50&lt;/span&gt; } } },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#a6e22e"&gt;urlPattern&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;/.*\.html/&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;handler&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;NetworkFirst&amp;#39;&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;then&lt;/span&gt;(() =&amp;gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;info&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;Service Worker 生成完成&amp;#39;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt; =&amp;gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;warn&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;Service Worker 生成失败: &amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这个任务用 Workbox 自动生成 SW, 具体原理和缓存策略在 &lt;a href="https://time-friend.com/zh/archive/blog-architecture-service-worker/"&gt;PWA 与 Service Worker&lt;/a&gt; 那篇里讲了.&lt;/p&gt;</description></item><item><title>我的博客主题是如何定制的</title><link>https://time-friend.com/zh/archive/blog-architecture-theme-customization/</link><pubDate>Sat, 15 Feb 2025 09:15:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/blog-architecture-theme-customization/</guid><description>&lt;p&gt;主题用的 &lt;code&gt;hugo-cactus-dark&lt;/code&gt;, 一个暗色主题, 干净, 没什么花哨的东西. 完全够用.&lt;/p&gt;
&lt;p&gt;但原版主题只覆盖了基础功能. 我需要双语切换, Giscus 评论, 页面统计, 结构化数据, 这些原版都没有. 所以直接 fork 了一份, 在 &lt;code&gt;layouts/&lt;/code&gt; 里覆盖掉需要改的模板.&lt;/p&gt;
&lt;h1 id="覆盖了哪些"&gt;覆盖了哪些&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;layouts/&lt;/code&gt; 目录下的模板优先级高于主题里的同名文件. 我只覆盖需要改的部分, 不需要动的就留给主题.&lt;/p&gt;
&lt;p&gt;这个东西开发的时候有个烦人的点: Hugo 对模板有缓存. 你改了 &lt;code&gt;layouts/&lt;/code&gt; 下的文件, 有时候浏览器还是用旧版本. 不是 Hugo 的锅, 是浏览器缓存了 HTML. 清一下或者开无痕模式就好.&lt;/p&gt;
&lt;h2 id="headhtml"&gt;head.html&lt;/h2&gt;
&lt;p&gt;改动最大的一个. 原版只输出了基本的 meta 和样式引用. 这里加了一堆东西:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;!-- 搜索引擎验证 --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;meta&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;360-site-verification&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;xxx&amp;#34;&lt;/span&gt; /&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;meta&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;sogou_site_verification&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;xxx&amp;#34;&lt;/span&gt; /&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;!-- 双语 hreflang --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ if .IsTranslated }}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ range .Translations }}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;link&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rel&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;alternate&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;hreflang&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Lang }}&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Permalink }}&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ end }}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;link&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rel&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;alternate&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;hreflang&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Lang }}&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Permalink }}&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ end }}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;!-- Open Graph --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;meta&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;og:locale&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;{{ if eq .Lang &amp;#34;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;zh&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;}}&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;zh_CN&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;{{&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;else&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;}}&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;en_US&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;{{&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;end&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;}}&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;meta&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;og:title&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Title }}&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;meta&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;og:image&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Params.image | absURL }}&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;meta&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;property&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;og:description&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Summary | truncate 200 }}&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;!-- Canonical --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;link&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rel&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;canonical&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Permalink }}&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;!-- 结构化数据 --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ if .IsPage }}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;type&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;application/ld+json&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;@context&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;https://schema.org&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;@type&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Article&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;headline&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Title }}&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;datePublished&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Date.Format &amp;#34;&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2006&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;01&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;02&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;T15&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;04&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;05&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Z07&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;00&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34; }}&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;dateModified&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Lastmod.Format &amp;#34;&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2006&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;01&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;02&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;T15&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;04&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;05&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Z07&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;00&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34; }}&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;author&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; { &lt;span style="color:#e6db74"&gt;&amp;#34;@type&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Person&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;{{ .Site.Params.author }}&amp;#34;&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ end }}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;为什么要加 Open Graph? 因为文章分享到社交媒体时, 预览卡片需要这些 meta. 没有的话就只显示一个光秃秃的链接.&lt;/p&gt;</description></item><item><title>博客多语言是怎么实现的</title><link>https://time-friend.com/zh/archive/blog-architecture-i18n/</link><pubDate>Mon, 20 Jan 2025 14:21:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/blog-architecture-i18n/</guid><description>&lt;p&gt;写技术博客有个尴尬: 中文内容国内读者看, 但海外流量也不少. 干脆中英文都上.&lt;/p&gt;
&lt;p&gt;这个博客是中英双语的. 同一篇文章有中文版和英文版, 各自有独立的 URL, 互不影响.&lt;/p&gt;
&lt;p&gt;i18n 分两层: 一是&lt;strong&gt;内容&lt;/strong&gt;的国际化 (文章本身有中英文版本), 二是&lt;strong&gt;界面&lt;/strong&gt;的国际化 (按钮, 菜单, 提示文字跟着语言切换).&lt;/p&gt;
&lt;h1 id="内容国际化"&gt;内容国际化&lt;/h1&gt;
&lt;h2 id="目录结构"&gt;目录结构&lt;/h2&gt;
&lt;p&gt;Hugo 的 &lt;code&gt;module.mounts&lt;/code&gt; 来做语言映射:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;module&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;mounts&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;source&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;content/en&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;target&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;content&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;lang&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;en&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;source&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;content&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;target&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;content&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;lang&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;zh&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;excludeFiles&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#39;en/**&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;英文内容从 &lt;code&gt;content/en&lt;/code&gt; 取, 中文内容从 &lt;code&gt;content&lt;/code&gt; 取, 排除掉 &lt;code&gt;en/&lt;/code&gt; 目录. 这样中文和英文文件互不干扰, 各自在独立的目录下.&lt;/p&gt;
&lt;p&gt;中文文章在 &lt;code&gt;content/archive/&lt;/code&gt; 下, 英文文章在 &lt;code&gt;content/en/archive/&lt;/code&gt; 下.&lt;/p&gt;
&lt;h2 id="translationkey-配对"&gt;translationKey 配对&lt;/h2&gt;
&lt;p&gt;用 Hugo 的 &lt;code&gt;translationKey&lt;/code&gt; 来配对文章. 同一篇文章的中英文版本用同一个 key:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 中文文章&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;translationKey&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;zh0189&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;title&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Git系列之关于add命令的一些事&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;slug&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;git-series-about-add-command&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 英文文章&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;translationKey&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;zh0189&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;title&lt;/span&gt;: &lt;span style="color:#f92672"&gt;Git Series&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;About the Add Command&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;slug&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;git-series-about-add-command&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Hugo 会自动把这两个页面识别为翻译对. 模板里用 &lt;code&gt;.Translations&lt;/code&gt; 拿到对应语言的版本, 用来做语言切换.&lt;/p&gt;</description></item><item><title>我的博客架构长什么样</title><link>https://time-friend.com/zh/archive/blog-architecture-overview/</link><pubDate>Fri, 10 Jan 2025 10:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/blog-architecture-overview/</guid><description>&lt;p&gt;很多人好奇这个博客是怎么搭的.&lt;/p&gt;
&lt;p&gt;看起来很简单,但背后东西不少.算不上大工程,但从工程角度确实折腾了不少东西.双语架构,自动化构建, PWA, Google SEO 等等.&lt;/p&gt;
&lt;p&gt;所以打算写个系列,把现在的这套东西记录下来.用什么,为什么这么选,代码怎么写的,性能上怎么考虑的.&lt;/p&gt;
&lt;h1 id="整体架构"&gt;整体架构&lt;/h1&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Markdown 内容 (中英双语)
 ↓
 Hugo SSG (extended, v0.164)
 ↓
 自定义主题 (fork cactus-dark, 大改)
 ↓
 Gulp Pipeline
 ├── hugo --minify
 └── Workbox generateSW
 ↓
 Cloudflare Pages (GitHub Actions CI)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;三层: 内容层, 构建层, 部署层. 没有数据库, 没有后端, 全是静态文件.&lt;/p&gt;
&lt;h2 id="为什么用-hugo"&gt;为什么用 Hugo&lt;/h2&gt;
&lt;p&gt;我是前端, 喜欢用前端圈的东西. Hugo 是用 Go 写的, 文章多了以后构建速度就是快. 两百多篇文章, 几秒就构建完了. 这就是核心原因.&lt;/p&gt;
&lt;p&gt;构建快了, 更新博客的心理负担就小. 这是一个正反馈.&lt;/p&gt;
&lt;p&gt;Go 模板用起来也挺顺手, 变量作用域, 管道语法, partial 系统, 该有的都有. 不过刚开始接触的时候, &lt;code&gt;{{ range }}&lt;/code&gt; 和 &lt;code&gt;{{ with }}&lt;/code&gt; 的区别可能会绕一下.&lt;/p&gt;</description></item><item><title>Long Time No See</title><link>https://time-friend.com/zh/archive/long-time-no-see/</link><pubDate>Wed, 19 Jun 2024 19:02:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/long-time-no-see/</guid><description>&lt;p&gt;Hello everyone,&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s been almost three years since I last updated my blog. So much has changed since then. I want to share some of my recent experiences with you.&lt;/p&gt;
&lt;p&gt;First, my whole family and I have moved to a new country. It was a big change for us. We are still getting used to everything.&lt;/p&gt;
&lt;p&gt;In my job, I&amp;rsquo;ve noticed that front-end technology is not as demanding as I thought it would be. Instead, good communication in English has become the most important skill for me. English is now the main barrier in my life. It affects my job, my promotion, and everything in my career.&lt;/p&gt;</description></item><item><title>Mac 最小化所有应用快捷键</title><link>https://time-friend.com/zh/archive/mac-shortcut-to-minimize-all-applications/</link><pubDate>Wed, 31 Mar 2021 22:30:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/mac-shortcut-to-minimize-all-applications/</guid><description>&lt;p&gt;平时使用Mac 的时候,桌面太多的应用窗口.&lt;/p&gt;
&lt;p&gt;一直以来没办法跟windows一样可以一键显示桌面.&lt;/p&gt;
&lt;p&gt;研究了一下,在Mac上还是有办法做到一样的效果的.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Command+Option+H+M
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>2020年终有感</title><link>https://time-friend.com/zh/archive/2020-year-end-reflections/</link><pubDate>Thu, 04 Mar 2021 16:41:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/2020-year-end-reflections/</guid><description>&lt;p&gt;终于可以在这个关键的时间节点写出这篇文章了,虽然现在已经是2021年的3月了.
但是一直没有找到一个很好的机会可以将这一篇文章写出来.&lt;/p&gt;
&lt;p&gt;因为疫情原因,我知道大家的2020年有太多讲不完的故事.
我也一样,这一年也是我成长关键的一年.&lt;/p&gt;
&lt;h2 id="关于工作"&gt;关于工作&lt;/h2&gt;
&lt;p&gt;因为去年对跨端方面有了一定的进展,公司组织架构调整之后,成立了轻应用小组.
专门做跨端方向的技术研究来支撑公司的业务发展.&lt;/p&gt;
&lt;p&gt;一年下来,遇到的问题极多对于我来说压力也极大,时常因为一些很难解决的问题导致业务可能上不了线.
但是问题总是在上线之前找到解决方案.这种事情发生了太多,对于我个人来说,心也得到了非常大的历练.
一年下来,我的口头禅就变成了&lt;code&gt;这个问题不大&lt;/code&gt;.
不仅给自己打气,作为团队里面bug兜底的男人,也不断给碰到问题的同学一些信心.
这可能是我前端生涯中碰到问题最多,最难的一年了.但是成果还是相当不错的.
我们在一年时间里,将我们的服务拓展到了8个端~
在此期间,也不能说没有放弃的念头,因为碰到的疑难杂症越多,大家倒是信心满满~
很多时候,大家可能觉着,就算自己解决不了,至少还有我兜着~
我承认,其中肯定有赌的成分,但是如果时间期限是一年的话,我们赌赢了.
但是带来一个问题,因为疑难杂症的问题解决多了,成就感触发的越来越难.&lt;/p&gt;
&lt;p&gt;但是在业务方面,虽然大家很努力,但是并没有实质性的进展.这让人很疲惫.
在疫情面前,大部分公司或多或少都有类似的问题.
就好像不管用什么办法,数据都像是死猪不怕开水烫一般,没有实质性的波澜~&lt;/p&gt;
&lt;p&gt;这让大家都非常的疲惫,希望在下一个阶段可以重新找回自己.&lt;/p&gt;
&lt;h2 id="关于自己"&gt;关于自己&lt;/h2&gt;
&lt;p&gt;说到找回自己,我刚刚在想,我是否曾经得到过自己.
或者说自己对自己有了一定的误解.
对于程序员的自己来说,可能曾经每天都可以进入心流状态的我来说是怀念的.
进入心流就是一整天,下班的时候可能才会有一些烦恼的事情进入大脑,大部分时间都是一个亢奋又沉浸的世界.&lt;/p&gt;</description></item><item><title>使用Taro开发各端的顺序建议</title><link>https://time-friend.com/zh/archive/recommended-order-for-developing-taro-multi-platform-applications/</link><pubDate>Wed, 16 Dec 2020 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/recommended-order-for-developing-taro-multi-platform-applications/</guid><description>&lt;h2 id="以最小成本开发taro各端"&gt;以最小成本开发Taro各端&lt;/h2&gt;
&lt;p&gt;现在公司里面的所有小程序,快应用,rn等等都在使用Taro在开发.&lt;/p&gt;
&lt;p&gt;如果只兼容一端的话,使用Taro开发,没有任何问题.&lt;/p&gt;
&lt;p&gt;但是又想一次开发,各端正常运行的话,在很多的细节上是要花一点心思的.&lt;/p&gt;
&lt;p&gt;每一端有每一端的难.&lt;/p&gt;
&lt;h2 id="开发难度排序"&gt;开发难度排序&lt;/h2&gt;
&lt;p&gt;华为快应用 &amp;gt; 快应用 &amp;gt; React Native &amp;gt; Swan小程序 &amp;gt; 微信小程序 &amp;gt; H5&lt;/p&gt;
&lt;h3 id="关于快应用"&gt;关于快应用&lt;/h3&gt;
&lt;p&gt;在开发过程中,如果有涉及到快应用的业务,建议优先开发快应用.&lt;/p&gt;
&lt;p&gt;快应用的布局标准跟js容器环境跟其他的小程序或者是H5有一定的差异.&lt;/p&gt;
&lt;p&gt;并且华为快应用与其他快应用有很多莫名其妙的差异.&lt;/p&gt;
&lt;p&gt;如果涉及到快应用,请谨慎对待开发时间.&lt;/p&gt;
&lt;p&gt;目前看来,快应用的对UI布局的支持与小程序有一定的差异.虽然使用Taro的样式区分,快应用与小程序确实可以使用一套同样的代码同时跑在两端上.&lt;/p&gt;
&lt;p&gt;但是在开发过程中,他们之间的差异有太多意想不到(快应用不符合W3C规范)的差异,建议UI布局相关的代码,各端单独布局.业务相关的可以使用一套代码. 就是布局样式独立,行为保持一致.&lt;/p&gt;
&lt;p&gt;不然会花掉太多的布局差异抹平的工作.&lt;/p&gt;
&lt;h3 id="关于react-native"&gt;关于React Native&lt;/h3&gt;
&lt;p&gt;React Native在UI布局上也只是部分支持W3C标准.虽然布局上不能跟小程序H5一样灵活,&lt;/p&gt;
&lt;p&gt;对比起快应用来,并不会多出一个要额外兼容的华为快应用.&lt;/p&gt;
&lt;p&gt;目前Taro封装的React Native的特性与小程序是非常接近的,
如果不过多调用太多冷门的API,基本上还是可以独立开发完成大部分UI编程.&lt;/p&gt;
&lt;p&gt;如果RN想要调用原生APP的组件,在目前开来会带来相当大的沟通成本.&lt;/p&gt;
&lt;p&gt;在开发中本身ios与安卓就有一定的特性差异,放到RN里实现后又会带来其他的差异.&lt;/p&gt;
&lt;p&gt;并且开发人员从一个人变成了三个人.&lt;/p&gt;
&lt;p&gt;如果桥接的组件太过于复杂,开发人员可能会有一种还不如自己独立开发的抱怨.&lt;/p&gt;
&lt;p&gt;这个时候多端一起开发,时间不一定会比独立开发要快.&lt;/p&gt;
&lt;h3 id="关于-swan小程序"&gt;关于 Swan小程序&lt;/h3&gt;
&lt;p&gt;Swan小程序与微信小程序已经非常接近了.&lt;/p&gt;
&lt;p&gt;就我们现有业务来说除了wifi不能实现以外,其他的基本上都跟微信小程序保持了一致.&lt;/p&gt;
&lt;p&gt;目前开发中,IDE的卡顿是Swan小程序最不好的开发体验.&lt;/p&gt;
&lt;p&gt;迭代中,swan小程序的基础库兼容方面也做得不是很好,&lt;/p&gt;
&lt;p&gt;好几次遇到莫名其妙的问题,都是因为基础库兼容不好导致的.&lt;/p&gt;</description></item><item><title>使用Taro开发的快应用如何优化体积</title><link>https://time-friend.com/zh/archive/how-to-optimize-bundle-size-for-quick-apps-developed-with-taro/</link><pubDate>Tue, 15 Dec 2020 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/how-to-optimize-bundle-size-for-quick-apps-developed-with-taro/</guid><description>&lt;h2 id="快应用重复打包问题"&gt;快应用重复打包问题&lt;/h2&gt;
&lt;p&gt;使用Taro开发快应用,有一个问题绝对不能忽视,那就是体积问题.&lt;/p&gt;
&lt;p&gt;因为快应用打包的特性(1080以下)多个页面里,如果重复应用了一个第三方库,那么这个库的代码会一起打到这个页面中,导致一样的代码会存在多个页面中.&lt;/p&gt;
&lt;p&gt;因为目前1080版本的快应用没有全面铺开.如果你贸然升级自己快应用的最低平台版本号为1080.
你将会失去大量低版本的用户.&lt;/p&gt;
&lt;h2 id="官方给出的解决方案-1080以下版本"&gt;官方给出的解决方案 (1080以下版本)&lt;/h2&gt;
&lt;p&gt;当然快应用官方也意识到了这个问题,给出了最早期的解决方案.&lt;/p&gt;
&lt;p&gt;那就是将多个页面会依赖到的代码,全部在快应用初始化的时候挂载到全局变量上面.&lt;/p&gt;
&lt;p&gt;其他页面使用的时候,直接引用全局变量就可以了.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 入口文件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;day&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;day&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;globalRef&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Object.&lt;span style="color:#a6e22e"&gt;getPrototypeOf&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;global&lt;/span&gt;) &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;global&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;globalRef&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;day&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;day&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 页面使用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;globalRef&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Object.&lt;span style="color:#a6e22e"&gt;getPrototypeOf&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;global&lt;/span&gt;) &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;global&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;day&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;globalRef&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;day&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;day&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="分析项目使用了哪些公共代码"&gt;分析项目使用了哪些公共代码&lt;/h2&gt;
&lt;p&gt;重复打包的内容,npm依赖会占大头,也有可能是自己写的公共代码.&lt;/p&gt;
&lt;h3 id="我们的项目用到了哪些npm依赖"&gt;我们的项目用到了哪些npm依赖?&lt;/h3&gt;
&lt;p&gt;Taro打包之后,&lt;code&gt;dist/quickapp&lt;/code&gt; 下的构建产物会单独把所有项目能用到的npm包放到 &lt;code&gt;src/npm/&lt;/code&gt; 目录下.&lt;/p&gt;
&lt;h3 id="公共代码分析"&gt;公共代码分析&lt;/h3&gt;
&lt;p&gt;只要一个js被多个page引用,就必须会造成重复打包的问题.&lt;/p&gt;
&lt;h2 id="使用taro的-alias-特性解决重复打包的问题"&gt;使用Taro的 alias 特性解决重复打包的问题&lt;/h2&gt;
&lt;p&gt;alias 是应用路径别名的特性,他的实现原理很简单,在config文件中制定好路径替换规则.&lt;/p&gt;
&lt;p&gt;在taro打包的时候,直接替换应用路径成为正确的应用路径就可以了.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;@src&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;src&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;@plugin&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;src/plugin&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;@components&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;src/components&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="如何使用alias解决我们的打包问题"&gt;如何使用alias解决我们的打包问题&lt;/h3&gt;
&lt;p&gt;既然 alias有替换应用路径的问题,再加上我们的第三方库只要挂载到全局变量中就可以让所有页面都可以使用到.&lt;/p&gt;
&lt;p&gt;两个特性结合起来的解决方案就是这样的.&lt;/p&gt;
&lt;h4 id="第一步修改npm的alias"&gt;第一步,修改npm的alias&lt;/h4&gt;
&lt;p&gt;为什么要这样做,看到第二步你就会明白.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;classnames.ex 文件为classnames的映射文件.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;classnames&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;src/replacement/classnames.ex&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;prop-types&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;src/replacement/prop-types.ex&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;mobx&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;src/replacement/mobx.ex&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="第二步-制作替身依赖"&gt;第二步, 制作替身依赖&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;拷贝 &lt;code&gt;dist/quickapp/src/npm&lt;/code&gt; 中的内容到&lt;code&gt;src/replacement/npm&lt;/code&gt;中.&lt;/li&gt;
&lt;li&gt;在&lt;code&gt;src/replacement&lt;/code&gt;下新建一个&lt;code&gt;index.js&lt;/code&gt;文件,大致内容如下&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;crypt&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./npm/crypt/crypt&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;classnames&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./npm/classnames&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;globalRef&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Object.&lt;span style="color:#a6e22e"&gt;getPrototypeOf&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;global&lt;/span&gt;) &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;global&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;globalRef&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;classnames&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;classnames&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;globalRef&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;crypt&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;crypt&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="3"&gt;
&lt;li&gt;制作npm依赖映射的文件&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;看到这一步,你应该就会明白为什么alias为什么会将正常的npm依赖路径替换到一个映射文件.&lt;/p&gt;</description></item><item><title>TensorFlow中的Tensor是什么?</title><link>https://time-friend.com/zh/archive/what-is-a-tensor-in-tensorflow/</link><pubDate>Fri, 18 Sep 2020 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/what-is-a-tensor-in-tensorflow/</guid><description>&lt;h2 id="tensor张量"&gt;Tensor(张量)&lt;/h2&gt;
&lt;p&gt;“张量”一词最初由威廉·罗恩·哈密顿在1846年引入。对，就是那个发明四元数的哈密顿：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/643fca018187d79da1be1bc50f3beb7544c7ff56ffd50d0b4d332952034daa1b.png" alt="图 3"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Tensor实际上就是一个多维数组（multidimensional array）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Tensor的目的是能够创造更高维度的矩阵、向量。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/61f12309aef252eb15cb7e168026f7bab180ea4a8cca2726d0ae4454c6003ba6.png" alt="图 1"&gt;&lt;/p&gt;
&lt;h3 id="色彩的例子"&gt;色彩的例子&lt;/h3&gt;
&lt;p&gt;彩色图像文件（RGB）一般都会处理成3-d tensor，每个2d array中的element表示一个像素，R代表Red，G代表Green，B代表Blue&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/9d8d1f97a751a320d7ba127a3722691950609d6e21edc6fc1e983923d72096c8.png" alt="图 2"&gt;&lt;/p&gt;
&lt;h2 id="多维数组"&gt;多维数组&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/6e86be5b727b21425ed87b5d2971b5f6ea9fa38cfe56455931faacd288085206.png" alt="图 4"&gt;&lt;/p&gt;
&lt;p&gt;把三维张量画成一个立方体：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/0a29499dadc3caf5094316c2a6570a54489f552f36989a67590a2e717b654278.png" alt="图 5"&gt;&lt;/p&gt;
&lt;p&gt;更高维的张量:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/f0cd642725a7b5b30592837c1fe8ec518816a170e57f74e577f1dfbcfaf6bb06.png" alt="图 6"&gt;&lt;/p&gt;
&lt;h2 id="初始化一个向量"&gt;初始化一个向量&lt;/h2&gt;
&lt;h3 id="0维"&gt;0维&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;tf&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;tensor&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;print&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="1维"&gt;1维&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;tf&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;tensor&lt;/span&gt;([&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;]).&lt;span style="color:#a6e22e"&gt;print&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// or
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;tf&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;tensor1d&lt;/span&gt;([&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;]).&lt;span style="color:#a6e22e"&gt;print&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="2维"&gt;2维&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;tf&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;tensor&lt;/span&gt;([[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;], [&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;]]).&lt;span style="color:#a6e22e"&gt;print&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// or
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;tf&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;tensor2d&lt;/span&gt;([[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;], [&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;]]).&lt;span style="color:#a6e22e"&gt;print&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="3维"&gt;3维&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;tf&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;tensor&lt;/span&gt;([[[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;], [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;]], [[&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;], [&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;]]]).&lt;span style="color:#a6e22e"&gt;print&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// or
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;tf&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;tensor3d&lt;/span&gt;([[[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;], [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;]], [[&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;], [&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;]]]).&lt;span style="color:#a6e22e"&gt;print&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="4维"&gt;4维&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;tf&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;tensor&lt;/span&gt;([[[[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;], [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;]], [[&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;], [&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;]]]]).&lt;span style="color:#a6e22e"&gt;print&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// or
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;tf&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;tensor4d&lt;/span&gt;([[[[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;], [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;]], [[&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;], [&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;]]]]).&lt;span style="color:#a6e22e"&gt;print&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="5维"&gt;5维&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;tf&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;tensor&lt;/span&gt;([[[[[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;], [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;]], [[&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;], [&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;]]]]]).&lt;span style="color:#a6e22e"&gt;print&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// or
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;tf&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;tensor5d&lt;/span&gt;([[[[[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;], [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;]], [[&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;], [&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;]]]]]).&lt;span style="color:#a6e22e"&gt;print&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="6维"&gt;6维&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;tf&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;tensor&lt;/span&gt;([[[[[[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;],[&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;]],[[&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;],[&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;]]],[[[&lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;],[&lt;span style="color:#ae81ff"&gt;6&lt;/span&gt;]],[[&lt;span style="color:#ae81ff"&gt;7&lt;/span&gt;],[&lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;]]]]]]).&lt;span style="color:#a6e22e"&gt;print&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// or
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;tf&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;tensor6d&lt;/span&gt;([[[[[[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;],[&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;]],[[&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;],[&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;]]],[[[&lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;],[&lt;span style="color:#ae81ff"&gt;6&lt;/span&gt;]],[[&lt;span style="color:#ae81ff"&gt;7&lt;/span&gt;],[&lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;]]]]]]).&lt;span style="color:#a6e22e"&gt;print&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Mac系统开启Chrome 跟 Edge的网页强制暗黑模式</title><link>https://time-friend.com/zh/archive/enable-forced-dark-mode-for-chrome-and-edge-on-mac/</link><pubDate>Thu, 17 Sep 2020 22:30:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/enable-forced-dark-mode-for-chrome-and-edge-on-mac/</guid><description>&lt;h2 id="开启强制暗黑模式"&gt;开启强制暗黑模式&lt;/h2&gt;
&lt;h3 id="chrome"&gt;Chrome&lt;/h3&gt;
&lt;p&gt;进入浏览器,地址栏输入:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;chrome://flags/#enable-force-dark
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="edge"&gt;Edge&lt;/h3&gt;
&lt;p&gt;进入浏览器,地址栏输入:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;edge://flags/#enable-force-dark
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="操作"&gt;操作&lt;/h3&gt;
&lt;p&gt;将第一项 Disabled 改成 Enabled,然后重启浏览器&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/5993f9393f0452e64281d912952d43d05ca1d0e7077ff83eaba4317c97047fa8.png" alt="图 2"&gt;&lt;/p&gt;
&lt;p&gt;生效:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/cdb9fe5995ddf99bd6282102f9126e5ec34558bb599385cd95c5a598063e2395.png" alt="图 3"&gt;&lt;/p&gt;</description></item><item><title>Mac系统如何关掉Chrome的跨域限制</title><link>https://time-friend.com/zh/archive/how-to-disable-chrome-cors-restrictions-on-mac/</link><pubDate>Wed, 16 Sep 2020 22:30:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/how-to-disable-chrome-cors-restrictions-on-mac/</guid><description>&lt;h2 id="关掉chrome-跨域限制"&gt;关掉Chrome 跨域限制&lt;/h2&gt;
&lt;p&gt;因为调试经常需要Chrome关掉跨域限制,网上的方法大多是windows的,&lt;/p&gt;
&lt;p&gt;这里今天记录一下:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;open -n -a /Applications/Google&lt;span style="color:#ae81ff"&gt;\ &lt;/span&gt;Chrome.app/Contents/MacOS/Google&lt;span style="color:#ae81ff"&gt;\ &lt;/span&gt;Chrome &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;--args --user-data-dir&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/tmp/chrome_dev_test&amp;#34;&lt;/span&gt; --disable-web-security
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>数学篇 - 数据结构丶编程语句丶基础算法与数学的关系(笔记)</title><link>https://time-friend.com/zh/archive/math-relationship-between-data-structures-programming-statements-basic-algorithms-and-mathematics/</link><pubDate>Tue, 15 Sep 2020 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/math-relationship-between-data-structures-programming-statements-basic-algorithms-and-mathematics/</guid><description>&lt;p&gt;看到很多人说,数据结构,算法不能算作数学.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;不同的数据结构，都是在编程中运用数学思维的产物。
每种数据结构都有自身的特点，有利于我们更方便地实现某种特定的数学模型.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="数据结构"&gt;数据结构&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;别小看这些数据结构，它们其实就是一个个解决问题的“模型”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="数组-array"&gt;数组 (Array)&lt;/h3&gt;
&lt;p&gt;特点: 可以通过下标，直接定位到所需的数据,适合随机访问.常常和循环语句相结合，来实现迭代法，例如二分查找、斐波那契数列等等&lt;/p&gt;
&lt;p&gt;缺点: 数组只对稠密的数列更有效。如果数列非常稀疏，那么很多数组的元素就是无效值，浪费了存储空间。此外，数组中元素的插入和删除也比较麻烦，需要进行数据的批量移动。&lt;/p&gt;
&lt;p&gt;如何解决稀疏数列问题: &lt;code&gt;链表&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="链表-linked-list"&gt;链表 (Linked List)&lt;/h3&gt;
&lt;p&gt;链表中的结点存储了数据，而链表结点之间的相连关系，在 &lt;code&gt;JavaScript&lt;/code&gt; 语言中是通过对象引用来实现的。&lt;/p&gt;
&lt;p&gt;特点: 不能通过下标来直接访问数据，而是必须按照存储的结构逐个读取&lt;/p&gt;
&lt;p&gt;优势: 不必事先规定数据的数量，也不再需要保存无效的值，表示稀疏的数列时可以更有效的利用存储空间，同时也利于数据的动态插入和删除&lt;/p&gt;
&lt;p&gt;缺点: 于数组而言，链表无法支持快速地随机访问，进行读写操作时就更耗时&lt;/p&gt;
&lt;h3 id="哈希表-hash"&gt;哈希表 (Hash)&lt;/h3&gt;
&lt;p&gt;哈希表就可以通过数组和链表来构造,之前我们通过&lt;code&gt;余数&lt;/code&gt;来实现哈希表.&lt;/p&gt;
&lt;p&gt;优势：如果关键字已知则存取速度极快，插入块&lt;/p&gt;
&lt;p&gt;缺点：删除慢，如果不知道关键则存取很慢，对存储空间使用不充分,会出现哈希冲突&lt;/p&gt;
&lt;h3 id="树-tree"&gt;树 (Tree)&lt;/h3&gt;
&lt;p&gt;优点：查找，插入，删除都快，树总是平衡的。类似的树对磁盘存储有用,不会出现哈希冲突&lt;/p&gt;
&lt;p&gt;缺点：算法复杂&lt;/p&gt;
&lt;h3 id="图graph"&gt;图(Graph)&lt;/h3&gt;
&lt;p&gt;图是另一种非线性数据结构。在图结构中，数据结点一般称为顶点，而边是顶点的有序偶对。如果两个顶点之间存在一条边，那么就表示这两个顶点具有相邻关系&lt;/p&gt;
&lt;h3 id="栈--stack"&gt;栈 ( Stack)&lt;/h3&gt;
&lt;p&gt;先进后出的。在我们进行函数递归的时候，函数调用和返回的顺序，也是先进后出，所以，栈体现了递归的思想，可以实现基于递归的编程&lt;/p&gt;
&lt;h3 id="队列-queue"&gt;队列 (Queue)&lt;/h3&gt;
&lt;p&gt;先进先出的数据结构，先进入队列的元素会优先得到处理.&lt;/p&gt;
&lt;p&gt;在消息队列中,实现了生产者和消费者的松耦合，对消费者起到了保护作用，使它不容易被数据洪流冲垮。&lt;/p&gt;
&lt;h2 id="编程语句"&gt;编程语句&lt;/h2&gt;
&lt;h3 id="布尔表达式"&gt;布尔表达式&lt;/h3&gt;
&lt;p&gt;体现了逻辑代数中逻辑和集合的概念&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;表达式&lt;/span&gt;) {&lt;span style="color:#a6e22e"&gt;函数体1&lt;/span&gt;} &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {&lt;span style="color:#a6e22e"&gt;函数体2&lt;/span&gt;} &lt;span style="color:#75715e"&gt;// 若表达式为真，执行函数体1，否则执行函数体2。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="循环语句"&gt;循环语句&lt;/h2&gt;
&lt;p&gt;循环语句是&lt;code&gt;迭代法（Newton's method）&lt;/code&gt;的体现&lt;/p&gt;
&lt;h2 id="函数的调用"&gt;函数的调用&lt;/h2&gt;
&lt;p&gt;可以调用自己，也可以调用其他不同的函数。如果不断地调用自己，这就体现了&lt;code&gt;递归&lt;/code&gt;的思想。&lt;/p&gt;
&lt;h3 id="sql-语言中的-join-操作"&gt;SQL 语言中的 Join 操作&lt;/h3&gt;
&lt;p&gt;Join 有多种类型，每种类型其实都对应了一种&lt;code&gt;集合的操作&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id="基础算法"&gt;基础算法&lt;/h2&gt;
&lt;h3 id="算法复杂度分析"&gt;算法复杂度分析&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;四则运算&lt;/code&gt;、&lt;code&gt;主次分明&lt;/code&gt;、&lt;code&gt;齐头并进&lt;/code&gt;、&lt;code&gt;排列组合&lt;/code&gt;、&lt;code&gt;一图千言&lt;/code&gt;和&lt;code&gt;时空互换&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;这些法则体现了数学中的&lt;code&gt;运算优先级&lt;/code&gt;、&lt;code&gt;数量级&lt;/code&gt;、&lt;code&gt;多元变量&lt;/code&gt;、&lt;code&gt;图论&lt;/code&gt;等思想&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;在平时学习编程的时候，你可以多从数学的角度出发，思考其背后的数学模型。&lt;/p&gt;
&lt;p&gt;这样不仅有利于你对现有知识的融会贯通，还可以帮助你优化数据结构和算法&lt;/p&gt;</description></item><item><title>数学篇 - 朴素贝叶斯(Naive Bayes)分类算法(笔记)</title><link>https://time-friend.com/zh/archive/math-naive-bayes-classification-algorithm/</link><pubDate>Mon, 14 Sep 2020 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/math-naive-bayes-classification-algorithm/</guid><description>&lt;h2 id="朴素贝叶斯naive-bayes"&gt;朴素贝叶斯(Naive Bayes)&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;“用客观的新信息更新我们最初关于某个事物的信念后，我们就会得到一个新的、改进了的信念。”
&amp;mdash;- 数学家托马斯·贝叶斯(Thomas Bayes，1702～1761)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;当你不能准确知悉一个事物的本质时，你可以依靠与事物特定本质相关的事件出现的多少去判断其本质属性的概率。&lt;/p&gt;
&lt;p&gt;支持某项属性的事件发生得愈多，则该属性成立的可能性就愈大。&lt;/p&gt;
&lt;p&gt;1774年，法国数学家皮埃尔-西蒙·拉普拉斯(Pierre-Simon Laplace，1749-1827)独立地再次发现了贝叶斯公式。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/3d6c983eec1f9283cb79904d2cc4cc1c7ee9654d73874ce1daf498b94fd23358.png" alt="图 16"&gt;&lt;/p&gt;
&lt;p&gt;换种写法:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/a1ace7950302e8e260f8397ea6c765ad2affa502ebc48d64f8b437e03eaf57ac.png" alt="图 17"&gt;&lt;/p&gt;
&lt;h2 id="让计算机分辨水果"&gt;让计算机分辨水果&lt;/h2&gt;
&lt;p&gt;我们需要将水果的特征转化为计算机所能理解的数据。最常用的方式就是提取现实世界中的对象之属性，并将这些转化为数字。&lt;/p&gt;
&lt;p&gt;比如：形状、外皮颜色、斑马纹理、重量、握感、口感。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/a99743fd96d79a2d6d343ef81f988c32f9ea4b28a8ad5c2391c2658ba60c188b.png" alt="图 19"&gt;&lt;/p&gt;
&lt;p&gt;将这些形容转化成数字,把重量由连续值转化成了离散值，这是因为朴素贝叶斯处理的都是离散值&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/c6c05b372ef0736d10734971409f755698ca90913095af1e752a7ecee88f9e7a.png" alt="图 20"&gt;&lt;/p&gt;
&lt;p&gt;扩大样本,仅仅 3 个水果还不足以构成朴素贝叶斯分类所需的训练样本&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/d485cea0f343ac13f4056b4ec0042563ae0866e275ab17b45ad7aecedc4f41f9.png" alt="图 21"&gt;&lt;/p&gt;
&lt;h3 id="我们如何使用贝叶斯公式"&gt;我们如何使用贝叶斯公式&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;用先验概率和条件概率估计后验概率。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/a725fc90f77e944d101977ea08e273e05f77c4160eb3ecf861a952a8719b8ac1.png" alt="图 22"&gt;&lt;/p&gt;
&lt;p&gt;假定数据对象的不同属性对其归类影响时是相互独立的。此时若数据对象 o 中同时出现属性 fi 与 fj，则对象 o 属于类别 c 的概率就是这样&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;朴素贝叶斯算法是假设各个特征之间相互独立,才可以两边相等,这也是朴素贝叶斯分类有朴素一词的来源&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/890407d644aa61250ee7e983ec0fd8e161679f7ff7e29a02bab486922a42e607.png" alt="图 23"&gt;&lt;/p&gt;
&lt;p&gt;用 10 个水果的数据，来建立朴素贝叶斯模型&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/6ec393ee25603bb065911573df41cc0ce291e26087cb78c1a2f80b64e3739eb1.png" alt="图 24"&gt;&lt;/p&gt;
&lt;h4 id="平滑smoothing"&gt;平滑（Smoothing）&lt;/h4&gt;
&lt;p&gt;会出现结果为 0 的情况，因此我们通常取一个比这个数据集里最小统计概率还要小的极小值，来代替“零概率”。比如，我们这里取 0.01。在填充训练数据中从来没有出现过的属性值的时候，我们就会使用这种技巧，我们给这种技巧起个名字就叫作平滑（Smoothing）。&lt;/p&gt;
&lt;h3 id="例题"&gt;例题:&lt;/h3&gt;
&lt;p&gt;假设我们有一个新的水果，它的形状是圆形，口感是甜的，那么根据朴素贝叶斯，它属于苹果、甜橙和西瓜的概率分别是多少呢？&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/e7bb1d2b6d6271b843f6fe43a407494899f04695c881ed0971f8ad09b862abdb.png" alt="图 25"&gt;&lt;/p&gt;
&lt;p&gt;apple 表示分类为苹果，shape-2 表示形状属性的值为 2（也就是圆形），taste-2 表示口感属性的值为 2。以此类推，我们还可计算该水果属于甜橙和西瓜的概率。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/566411191bd8528f098fcae1cb13f0ff42a4b689de1e6f364b8dfbd38ebeb8f3.png" alt="图 26"&gt;&lt;/p&gt;
&lt;p&gt;比较这三个数值，0.00198&amp;lt;0.00798&amp;lt;0.26934，所以计算机可以得出的结论，该水果属于甜橙的可能性是最大的&lt;/p&gt;
&lt;h3 id="朴素贝叶斯分类主要包括这几个步骤"&gt;朴素贝叶斯分类主要包括这几个步骤&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;准备数据&lt;/code&gt;：针对水果分类这个案例，我们收集了若干水果的实例，并从水果的常见属性入手，将其转化为计算机所能理解的数据。这种数据也被称为训练样本。&lt;/p&gt;</description></item><item><title>数学篇 - 概率之联合概率、条件概率、边缘概率和贝叶斯法则(笔记)</title><link>https://time-friend.com/zh/archive/math-probability-joint-conditional-marginal-probability-and-bayes-theorem/</link><pubDate>Sun, 13 Sep 2020 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/math-probability-joint-conditional-marginal-probability-and-bayes-theorem/</guid><description>&lt;blockquote&gt;
&lt;p&gt;公式符号解释: &lt;code&gt;P(A|B).是B已知下的A的条件概率&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="联合概率joint-probability"&gt;联合概率（Joint Probability）&lt;/h2&gt;
&lt;p&gt;各种解释描述,便于理解:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;联合概率指的是包含多个条件且所有条件同时成立的概率，记作P(X=a,Y=b)或P(a,b)，有的书上也习惯记作P(ab)，但是这种记法个人不太习惯，所以下文采用以逗号分隔的记法。一定要注意是所有条件同时成立！&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;两个以上事件的交集的概率&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/134caf5fa4c114e6825b4e32eb93a1187310e208764246a05043523aad78cbec.png" alt="图 12"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;例子：从一副扑克牌中抽出一张红色的4的概率为P(红4) = 2/52 = 1/26。（一副扑克牌有52张牌，想抽到的是红心4和方块4）。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="条件概率conditional-probability"&gt;条件概率（Conditional Probability）&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;条件概率是已知某（些）事件已经发生的前提下，另一（些）事件发生的概率。已知事件B已经发生时，事件A发生的条件概率写作P(A|B)。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;条件概率表示在条件Y=b成立的情况下，X=a的概率，记作P(X=a|Y=b)或P(a|b)，&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;例子：已知我们抽到了一张红色的牌，这张牌是4的概率为P(4|红) = 2/26 = 1/13 （一副扑克牌有52张牌，26张红色的，26张黑色的。现在因为我们已经抽到了一张红色的牌，我们知道我们抽取的范围是26张牌，因此第一个除数是26）。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="联合概率与条件概率的区别"&gt;联合概率与条件概率的区别&lt;/h2&gt;
&lt;h3 id="解释1"&gt;解释1:&lt;/h3&gt;
&lt;p&gt;P(AB) 联合概率：池子没变。&lt;/p&gt;
&lt;p&gt;P(A|B) 条件概率：池子变小了！！！！！！&lt;/p&gt;
&lt;p&gt;所以如果用条件概率来算联合概率的话：池子不能小，给我乘回去！！！！&lt;/p&gt;
&lt;p&gt;P(A|B) x P(B) = P(AB)&lt;/p&gt;
&lt;h3 id="解释2"&gt;解释2:&lt;/h3&gt;
&lt;p&gt;当我们想要知道抽到一张红色的4的扑克牌的概率（红色和4的联合概率）时，我想让你想象一下，把所有52张牌面朝下放置，然后随机选中一张。在这52张牌中，有2张是红色的，同时数字是4（红心4和方块4）。所以联合概率是2/52 = 1/26。&lt;/p&gt;
&lt;p&gt;而当我们想要知道已知抽中的牌是红色的时候，抽中数字是4的牌的概率，即条件概率P(4|红)时，我想让你再想象一下有52张牌。不过，在随机抽取一张牌之前，你给所有扑克牌排了个序，选中了所有26张红色的牌。现在你把这26张牌面朝下放置，然后随机选择一张牌。同样，这些红色的牌中有两张数字为4，所以条件概率是2/26 = 1/13&lt;/p&gt;
&lt;h3 id="公式描述"&gt;公式描述&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/d6562409852e71d9261a5a2f423d9f03249fb7869fe6dc51d64bba002de1e9ba.png" alt="图 13"&gt;&lt;/p&gt;
&lt;h2 id="边缘概率"&gt;边缘概率&lt;/h2&gt;
&lt;p&gt;解释:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;对于离散型随机变量，我们可以通过通过联合概率 P(x, y) 在 y 上求和，就可以得到 P(x)。对于连续型随机变量，我们可以通过联合概率 P(x, y) 在 y 上的积分(无限求和)，推导出概率 P(x)。这个时候，我们称 P(x) 为边缘概率。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;边缘概率是与联合概率对应的，P(X=a)或P(Y=b)，这类仅与单个随机变量有关的概率称为边缘概率&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="贝叶斯定理-bayes-theorem"&gt;贝叶斯定理 (Bayes&amp;rsquo; Theorem）&lt;/h2&gt;
&lt;p&gt;英国数学家托马斯·贝叶斯（Thomas Bayes）在1763年发表的一篇论文中，首先提出了这个定理。而这篇论文是在他死后才由他的一位朋友发表出来的。在这篇论文中，他为了解决一个“逆向概率”问题，而提出了贝叶斯定理。&lt;/p&gt;
&lt;p&gt;在贝叶斯写这篇文章之前，人们已经能够计算“正向概率”，比如杜蕾斯举办了一个抽奖，抽奖桶里有10个球，其中2个白球，8个黑球，抽到白球就算你中奖。你伸手进去随便摸出1颗球，摸出中奖球的概率是多大。根据频率概率的计算公式，你可以轻松的知道中奖的概率是2/10。&lt;/p&gt;</description></item><item><title>数学篇 - 概率之随机变量与分布(笔记)</title><link>https://time-friend.com/zh/archive/math-probability-random-variables-and-distributions/</link><pubDate>Sat, 12 Sep 2020 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/math-probability-random-variables-and-distributions/</guid><description>&lt;h2 id="随机变量-random-variable-"&gt;随机变量（ random variable )&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;设随机试验的样本空间为S SS，X = X ( e ) X=X(e)X=X(e)是定义在样本空间S SS上的实值单值函数。称X = X ( e ) X=X(e)X=X(e)为随机变量。&lt;/li&gt;
&lt;li&gt;本质是关于基本事件的函数，自变量是基本事件，因变量是函数值。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="随机试验"&gt;随机试验：&lt;/h3&gt;
&lt;p&gt;满足:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;(1)可重复性:试验在相同条件下可重复进行；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;(2)可知性:每次试验的可能结果不止一个，并且事先能明确试验所有可能的结果；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;(3)不确定性:进行一次试验之前不能确定哪一个结果会出现，但必然会出现结果中的一个。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="样本空间"&gt;样本空间：&lt;/h3&gt;
&lt;p&gt;随机试验的所有基本结果组成的集合称为样本空间。样本空间的元素称为样本点或基本事件。即样本空间本质是一个集合，每一个元素都是一次随机试验的结果。&lt;/p&gt;
&lt;h3 id="样本和随机变量"&gt;样本和随机变量:&lt;/h3&gt;
&lt;p&gt;数理统计里的样本具有二重性，即样本既可以看作是一组观测值又可以看作是随机变量。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;第一，在抽样之前。无法确定样本的观测值，所以可以看成是随机变量。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;第二，样本在抽取以后，经观测，样本抽有了具体的观测值，故又可以看成是一组确定的值。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="概率分布"&gt;概率分布&lt;/h2&gt;
&lt;p&gt;我们拿最简单的抛硬币事件来看。从理论上说来，出现正面和反面的概率都是 50%&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/37ad586a7450df254377069cf6cb942221abec1888d7f4479f847d9052399caf.png" alt="图 2"&gt;&lt;/p&gt;
&lt;h3 id="使用代码来尝试"&gt;使用代码来尝试&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;flipCoin&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;index&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;index&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;index&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 对随机数四舍五入
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;randomNum&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Math.&lt;span style="color:#a6e22e"&gt;round&lt;/span&gt;(Math.&lt;span style="color:#a6e22e"&gt;random&lt;/span&gt;())
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 随机为1则为正面
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;randomNum&lt;/span&gt; &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;正面&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;反面&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;flipCoin&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;尝试10次结果:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/ae33d052a617115dd55e6ba4b518174d2e32882ca4d0011ef8c14d882906ca4a.png" alt="图 3"&gt;&lt;/p&gt;
&lt;p&gt;尝试1000次&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/ded88ad6ca997dbfbf9424b9b83159d1d16b329611da5902fc2734b219c16362.png" alt="图 4"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;统计的采样次数越多，越趋近于我们理论上的情况&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;概率分布描述的其实就是随机变量的概率规律。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="离散分布模型"&gt;离散分布模型&lt;/h2&gt;
&lt;h3 id="伯努利分布bernoulli-distribution"&gt;伯努利分布（Bernoulli Distribution）&lt;/h3&gt;
&lt;p&gt;这是单个随机变量的分布，而且这个变量的取值只有两个，0 或 1。&lt;/p&gt;</description></item><item><title>数学篇 - 树的深度优先搜索与广度优先搜索(笔记)</title><link>https://time-friend.com/zh/archive/math-tree-depth-first-search-and-breadth-first-search/</link><pubDate>Fri, 11 Sep 2020 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/math-tree-depth-first-search-and-breadth-first-search/</guid><description>&lt;h2 id="如何使用递归和栈实现深度优先搜索"&gt;如何使用递归和栈实现深度优先搜索？&lt;/h2&gt;
&lt;p&gt;深度优先搜索的过程和递归调用在逻辑上是一致的。&lt;/p&gt;
&lt;h3 id="写一个-treenode类代码支持插入节点"&gt;写一个 TreeNode类代码,支持插入节点&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;TreeNode&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;constructor&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;key&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;key&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;key&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;sons&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;insert&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;key&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;node&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;TreeNode&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;key&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;sons&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;push&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;node&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;node&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="尝试创建一棵树"&gt;尝试创建一棵树&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;str&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;hello word&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;str2&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;abcdefg&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 根节点
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;root&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;TreeNode&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;root&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;createTree&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;str&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;root&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;createTree&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;str2&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;root&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;createTree&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;strs&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;parent&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;strs&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt; &lt;span style="color:#f92672"&gt;!==&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;found&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;parent&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;sons&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;find&lt;/span&gt;((&lt;span style="color:#a6e22e"&gt;item&lt;/span&gt;)=&amp;gt;&lt;span style="color:#a6e22e"&gt;item&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;key&lt;/span&gt; &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;strs&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;found&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;newStrs&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;strs&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;slice&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;createTree&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;newStrs&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;parent&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;node&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;parent&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;insert&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;strs&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;newStrs&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;strs&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;slice&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;createTree&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;newStrs&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;node&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;strs&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt; &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;创建完毕&amp;#39;&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;root&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;root&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="开始深度优先搜索"&gt;开始深度优先搜索&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 使用栈来实现深度优先搜索
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 大致思路是将所有的结点push到数组中,然后取最后一个处理,边删边处理.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 直到没有为止
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dfsByStack&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;root&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;stack&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; []; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 创建堆栈对象，js使用数组代替堆栈,其中每个元素都是TreeNode类型
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;stack&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;push&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;root&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// 初始化的时候，压入根结点
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;stack&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;) { &lt;span style="color:#75715e"&gt;// 只要栈里还有结点，就继续下去
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 取出刚刚push进去的节点
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;node&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;stack&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;pop&lt;/span&gt;(); &lt;span style="color:#75715e"&gt;// 弹出栈顶的结点 拿到第一个进去的结点
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;node&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;sons&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 已经到达叶子结点了，输出
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;已经到达叶子结点&amp;#39;&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;node&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;key&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 非叶子结点，遍历它的每个子结点
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 注意，这里使用了一个临时的栈stackTemp
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 这样做是为了保持遍历的顺序，和递归遍历的顺序是一致的
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 如果不要求一致，可以直接压入stack
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;stackTemp&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;index&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;index&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;node&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;sons&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;index&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;son&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;node&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;sons&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;index&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;son&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;key&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;stackTemp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;push&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;son&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 将各个节点放入栈中排序
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 顺序反过来
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;stackTemp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;stack&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;push&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;stackTemp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;pop&lt;/span&gt;());
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="广度优先搜索breadth-first-search"&gt;广度优先搜索（Breadth First Search)&lt;/h2&gt;
&lt;p&gt;广度优先搜索BFS（Breadth First Search）也称为宽度优先搜索，它是一种先生成的结点先扩展的策略。
。&lt;/p&gt;</description></item><item><title>数学篇 - 树的概念(笔记)</title><link>https://time-friend.com/zh/archive/math-tree-concepts/</link><pubDate>Thu, 10 Sep 2020 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/math-tree-concepts/</guid><description>&lt;h2 id="树的基本概念"&gt;树的基本概念&lt;/h2&gt;
&lt;p&gt;树是由结点或顶点和边组成的(可能是非线性的)且不存在着任何环的一种数据结构。没有结点的树称为空(null或empty)树。一棵非空的树包括一个根结点，还(很可能)有多个附加结点，所有结点构成一个多级分层结构。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;树是一种特殊的图 (后续文章会提到图).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="前缀树-prefix-tree-字典树---trie"&gt;前缀树 prefix tree (字典树 - trie)&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/dc55d3f7c58c5e38030f58b6a11af37a8535c56b0dfd02b2b9401da912c11247.png" alt="图 8"&gt;&lt;/p&gt;
&lt;h3 id="有向树"&gt;有向树&lt;/h3&gt;
&lt;p&gt;它的边是有方向的。而树是没有简单回路的连通图。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/d338189fc4a8f481e78f1b2dfc233092a86de06c3cde4aa1b4b66c0bbc4d0974.png" alt="图 4"&gt;&lt;/p&gt;
&lt;p&gt;以结点 v 为出发点的边的数量，我们叫作 v 的&lt;code&gt;出度&lt;/code&gt;。而以 v为 终点的边之数量，称为 v 的&lt;code&gt;入度&lt;/code&gt;。在上图中，结点 v2​ 的入度是 1，出度是 2。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/ef20833f4e203927f14b2cd38fb4aa4a745189edcd2a9bb7f718cf3ccbe724fc.png" alt="图 6"&gt;&lt;/p&gt;
&lt;h3 id="回路和连通"&gt;回路和连通&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/78550e24c117088c62a2ccb3a770704d8f6a1aa3c0b8335f5f3e45ff2c9d40a3.png" alt="图 5"&gt;&lt;/p&gt;
&lt;h3 id="高度与结点"&gt;高度与结点&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/eee7e70c2d8c6917c8315cc3d6d57e183450a66161268acd129933c0d50a70c3.png" alt="图 7"&gt;&lt;/p&gt;
&lt;h2 id="二叉树"&gt;二叉树&lt;/h2&gt;
&lt;p&gt;二叉树又分为：完美二叉树，完全二叉树，完满二叉树&lt;/p&gt;
&lt;h3 id="完美二叉树满二叉树"&gt;完美二叉树(满二叉树)&lt;/h3&gt;
&lt;p&gt;除了叶子节点之外的每一个节点都有两个子节点,每一层(包括最后一层)都被完全填充
&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/4bf41f860a4d23494c030df8f4bba58a7e13fd76d6a1c865d719bd1408907e2a.png" alt="图 1"&gt;&lt;/p&gt;
&lt;h3 id="完全二叉树"&gt;完全二叉树&lt;/h3&gt;
&lt;p&gt;完全二叉树从根结点到倒数第二层满足完美二叉树，最后一层可以不完全填充，其叶子结点都靠左对齐
&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/36856163c4ab4de51257b6a164490c7fa91b36850273ece7db420fea7b25cd5d.png" alt="图 2"&gt;&lt;/p&gt;
&lt;h3 id="完满二叉树"&gt;完满二叉树&lt;/h3&gt;
&lt;p&gt;所有非叶子结点的度都是2
换句话说：只要你有孩子，你就必然是有两个孩子。
&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/2cf115b05053cd1f809651a82255731d9bc1d5a0269ca7228de1ecefccba5a0e.png" alt="图 3"&gt;&lt;/p&gt;</description></item><item><title>数学篇 - 动态规划,编辑距离的计算(笔记)</title><link>https://time-friend.com/zh/archive/math-dynamic-programming-edit-distance-calculation/</link><pubDate>Wed, 09 Sep 2020 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/math-dynamic-programming-edit-distance-calculation/</guid><description>&lt;h2 id="动态规划-dynamic-programming"&gt;动态规划 （Dynamic Programming）&lt;/h2&gt;
&lt;p&gt;很多人也简称DP,动态规划需要通过子问题的最优解，推导出最终问题的最优解，因此这种方法特别注重子问题之间的转移关系。我们通常把这些子问题之间的转移称为&lt;code&gt;状态转移&lt;/code&gt;，并把用于刻画这些状态转移的表达式称为&lt;code&gt;状态转移方程&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id="编辑距离-莱文斯坦距离又称levenshtein距离"&gt;编辑距离 (莱文斯坦距离,又称Levenshtein距离)&lt;/h2&gt;
&lt;p&gt;俄罗斯科学家弗拉基米尔·莱文斯坦（毕业于莫斯科国立大学数学和力学系）在1965年提出，他因对纠错码理论和信息理论的贡献，于2006年获得IEEE Richard W. Hamming奖章。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;定义：莱文斯坦距离也称编辑距离，指的是将文本 A 编辑成文本 B 需要的最少变动次数（每次只能增加、删除或修改一个字）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;用途：可以用来计算字符串的相似度，文本相似度, 拼写纠错和抄袭侦测等等&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;优点：准确率很高，编辑距离算出来很小，文本相似度肯定很高。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;缺点：召回率不高，由于编辑距离与文本的顺序有关。在文字相同，文字顺序变化很大的情况下，相似度会变得很低。比如“正大光明”和“光明正大”其实是一个意思。但编辑距离是4，完全不匹配&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="计算解析"&gt;计算解析：&lt;/h3&gt;
&lt;p&gt;首先定义的单字符编辑操作有且仅有三种：&lt;/p&gt;
&lt;p&gt;插入（Insertion）&lt;/p&gt;
&lt;p&gt;删除（Deletion）&lt;/p&gt;
&lt;p&gt;替换（Substitution）&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/189c427b9aadfa7c501b025f85ca4186591db79eae686e3a3acabbc0cdbf5d11.png" alt="图 1"&gt;&lt;/p&gt;
&lt;h3 id="搜索推荐关键词的应用"&gt;搜索推荐关键词的应用&lt;/h3&gt;
&lt;p&gt;计算 &lt;code&gt;mouuse&lt;/code&gt; 与 &lt;code&gt;mouse&lt;/code&gt;的编辑距离&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/1e9ab12ce6f3535ab43e7403c067b6fc2b4a972c129bf86731b0b54477f702a4.png" alt="图 2"&gt;&lt;/p&gt;
&lt;h3 id="表格推导"&gt;表格推导&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/39bfcba830d765875f8e29a1672e4d61b1d4891f0343f4da6d0390693cb64013.png" alt="图 3"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这里面求最小值的 min 函数里有三个参数，分别对应三种情况的编辑距离，分别是：替换、插入和删除字符。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="代码实现"&gt;代码实现&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @Description: 使用状态转移方程，计算两个字符串之间的编辑距离
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @param a-第一个字符串，b-第二个字符串
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @return let-两者之间的编辑距离
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getStrDistance&lt;/span&gt;( &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 初始用于记录化状态转移的二维表
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;d&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;index&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;index&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;index&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;d&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;push&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Array(&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 如果i为0，且j大于等于0，那么d[i, j]为j
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;j&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;j&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;j&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;d&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;][&lt;span style="color:#a6e22e"&gt;j&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;j&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 如果i大于等于0，且j为0，那么d[i, j]为i
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;d&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;][&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 当前二维数组的状态
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// [
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// [0, 1, 2, 3,4, 5, 6 ],
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// [ 1, &amp;lt;5 empty items&amp;gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// [ 2, &amp;lt;5 empty items&amp;gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// [ 3, &amp;lt;5 empty items&amp;gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// [ 4, &amp;lt;5 empty items&amp;gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// [ 5, &amp;lt;5 empty items&amp;gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// [ 6, &amp;lt;5 empty items&amp;gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// ]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 实现状态转移方程
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;j&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;j&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;j&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;r&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;charAt&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;) &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;charAt&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;j&lt;/span&gt;)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;r&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 给所有的格志做应有的标记
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 坐标加1是为了从第二个格子开始记录数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;first_append&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;d&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;][&lt;span style="color:#a6e22e"&gt;j&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;] &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;second_append&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;d&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;][&lt;span style="color:#a6e22e"&gt;j&lt;/span&gt;] &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 当前格志记录之前对比的差异
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;replace&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;d&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;][&lt;span style="color:#a6e22e"&gt;j&lt;/span&gt;] &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;r&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;charAt&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;) , &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;charAt&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;j&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;first_append&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;second_append&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 求得first_append, second_append,replace三个最小的一个
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 分别对应三种情况的编辑距离，分别是：替换、插入和删除字符
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;min&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Math.&lt;span style="color:#a6e22e"&gt;min&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;first_append&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;second_append&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;min&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Math.&lt;span style="color:#a6e22e"&gt;min&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;min&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;replace&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 所有的差异累积
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;d&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;][&lt;span style="color:#a6e22e"&gt;j&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;min&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 当前二维数组的状态
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// [
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// [0, 1, 2, 3, 4, 5, 6],
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// [1, 0, 1, 2, 3, 4, 5],
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// [2, 1, 1, 2, 3, 4, 5],
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// [3, 2, 2, 2, 3, 4, 5],
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// [4, 3, 3, 2, 2, 3, 4],
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// [5, 4, 4, 3, 3, 2, 3],
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// [6, 5, 5, 4, 4, 3, 2]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// ]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 输出最终的累积值,就是他们的编辑距离
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;d&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;][&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="尾巴"&gt;尾巴&lt;/h2&gt;
&lt;p&gt;这一节有点懵,记录一下后续再查更多资料深入理解了.
例子理解的还行,一到应用就嗝屁.还是要多做题&amp;hellip;&lt;/p&gt;</description></item><item><title>数学篇 - 组合,解决赛程规划与自然语言处理(笔记)</title><link>https://time-friend.com/zh/archive/math-combination-solve-schedule-planning-and-lottery/</link><pubDate>Tue, 08 Sep 2020 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/math-combination-solve-schedule-planning-and-lottery/</guid><description>&lt;h2 id="组合"&gt;组合&lt;/h2&gt;
&lt;p&gt;组合（combination）是一个数学名词。一般地，从n个不同的元素中，任取m（m≤n）个元素为一组，叫作从n个不同元素中取出m个元素的一个组合。我们把有关求组合的个数的问题叫作组合问题。&lt;/p&gt;
&lt;p&gt;对于所有 m 取值的组合之全集合，我们可以叫作全组合（All Combination）。例如对于集合{1, 2, 3}而言，全组合就是{空集, {1}, {2}, {3}, {1, 2}, {1,3} {2, 3}, {1, 2, 3}}。&lt;/p&gt;
&lt;h2 id="如何安排世界杯赛程"&gt;如何安排世界杯赛程&lt;/h2&gt;
&lt;p&gt;想让全部的 32 支球队都和其他球队进行一次主客场的比赛.&lt;/p&gt;
&lt;p&gt;自己不可能和自己比赛，不可重复的排列中，主场球队有 32 种选择，而客场球队有 31 种选择。那么一共要进行多少场比赛呢？很简单，就是 &lt;code&gt;32x31=992&lt;/code&gt; 场！&lt;/p&gt;
&lt;p&gt;在实际情况中,赛程设计并没有这样做.&lt;/p&gt;
&lt;p&gt;这就是为什么要将所有 32 支队伍分成 8 个小组先进行小组赛的原因。一旦分成小组，每个小组的赛事就是 (4x3)/2=6 场。所有小组赛就是 6x8=48 场。&lt;/p&gt;
&lt;p&gt;加上在 16 强阶段开始采取淘汰制，两两淘汰，所以需要 8+4+2+2=16 场淘汰赛（最后一次加 2 是因为还有 3、4 名的决赛），那么整个世界杯决赛阶段就是 48+16=64 场比赛。&lt;/p&gt;
&lt;p&gt;这两两配对比赛的场次，我是如何计算出来的？让我引出今天的概念，组合（Combination）。&lt;/p&gt;
&lt;h2 id="让计算机来组合队伍"&gt;让计算机来组合队伍&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/b7fab79358476b5a14b566571c7e5ff1915189b170274e1c706005069e43b3df.png" alt="图 1"&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/*
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @Description: 使用函数的递归（嵌套）调用，找出所有可能的队伍组合
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @param teams-目前还剩多少队伍没有参与组合，result-保存当前已经组合的队伍
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @return void
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;teams&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;&amp;#34;t1&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;t2&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;t3&amp;#34;&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;combine&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;teams&lt;/span&gt;,[],&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;combine&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;teams&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;result&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;m&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 挑选完了m个元素，输出结果
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;result&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;m&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;result&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;teams&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 从剩下的队伍中，选择一队，加入结果
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;newResult&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [].&lt;span style="color:#a6e22e"&gt;concat&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;result&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;newResult&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;push&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;teams&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 只考虑当前选择之后的所有队伍
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rest_teams&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;teams&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;slice&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;teams&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 递归调用，对于剩余的队伍继续生成组合
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;combine&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;rest_teams&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;newResult&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;m&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;有没有发现,这个算法跟上一篇的密码爆破思想非常接近.&lt;/p&gt;</description></item><item><title>数学篇 - 排列,解决田忌赛马与密码爆破问题(笔记)</title><link>https://time-friend.com/zh/archive/math-permutation-solve-tianji-horse-racing-and-password-cracking/</link><pubDate>Mon, 07 Sep 2020 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/math-permutation-solve-tianji-horse-racing-and-password-cracking/</guid><description>&lt;h2 id="田忌赛马的故事"&gt;田忌赛马的故事&lt;/h2&gt;
&lt;p&gt;田忌是齐国有名的将领，他常常和齐王赛马，可是总是败下阵来，心中非常不悦。孙膑想帮田忌一把。他把这些马分为上、中、下三等。他让田忌用自己的下等马来应战齐王的上等马，用上等马应战齐王的中等马，用中等马应战齐王的下等马。三场比赛结束后，田忌只输了第一场，赢了后面两场，最终赢得与齐王的整场比赛。&lt;/p&gt;
&lt;h2 id="排列概念"&gt;排列概念&lt;/h2&gt;
&lt;p&gt;从 n 个不同的元素中取出 m（1≤m≤n）个不同的元素，按照一定的顺序排成一列，这个过程就叫&lt;code&gt;排列（Permutation）&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;当 m=n 这种特殊情况出现的时候,这就是&lt;code&gt;全排列（All Permutation）&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="田忌赛马的排列图"&gt;田忌赛马的排列图&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/de799500620468a7d1fcf9a4941166f975385c21a75a39ab66eab8791557d1d1.png" alt="图 1"&gt;&lt;/p&gt;
&lt;h3 id="最终排列的数量"&gt;最终排列的数量&lt;/h3&gt;
&lt;p&gt;排列总数的计算 3x2x1=6&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;对于 n 个元素的全排列，所有可能的排列数量就是 &lt;code&gt;nx(n-1)x(n-2)x…x2x1&lt;/code&gt;，也就是 n!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;对于 n 个元素里取出&lt;code&gt; m (0&amp;lt;m≤n)&lt;/code&gt; 个元素的不重复排列数量是 &lt;code&gt;nx(n-1)x(n-2)x…x(n - m + 1)&lt;/code&gt;，也就是 n!/(n-m)!&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="使用代码计算田忌赛马的各种情况"&gt;使用代码计算田忌赛马的各种情况&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 齐王的马与速度
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;q_horses_time&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;q1&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;q2&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;q3&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 田忌的马与速度
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;t_horses_time&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;t1&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1.5&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;t2&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2.5&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;t3&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;3.5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 他们马的名字
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;q_horses&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;&amp;#34;q1&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;q2&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;q3&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;t_horses&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;&amp;#34;t1&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;t2&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;t3&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @Description: 使用函数的递归（嵌套）调用，找出所有可能的马匹出战顺序
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @param horses-目前还剩多少马没有出战，result-保存当前已经出战的马匹及顺序
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @return void
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;permutate&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;horses&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;result&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 所有马匹都已经出战，判断哪方获胜，输出结果
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;horses&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// console.log(result);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;compare&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;result&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;q_horses&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;horses&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 从剩下的未出战马匹中，选择一匹，加入结果
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;new_result&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [].&lt;span style="color:#a6e22e"&gt;concat&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;result&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;new_result&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;push&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;horses&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 将已选择的马匹从未出战的列表中移出
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rest_horses&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [].&lt;span style="color:#a6e22e"&gt;concat&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;horses&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;rest_horses&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;splice&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 递归调用，对于剩余的马匹继续生成排列
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 相当于自己与自己嵌套for循环,打乱顺序
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;permutate&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;rest_horses&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;new_result&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;compare&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;t&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;q&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 田忌的赛马时间
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;t_won_cnt&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;t&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;t_horses_time&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;t&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;]] &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;q_horses_time&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;q&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;]]) &lt;span style="color:#a6e22e"&gt;t_won_cnt&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 时间对比,本次是三局两胜
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;t_won_cnt&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;t&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;田忌获胜！&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;齐王获胜！&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 开始计算
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;permutate&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;t_horses&lt;/span&gt;, [])
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;田忌获胜的概率是 1/6&lt;/p&gt;</description></item><item><title>数学篇 - 递归,分而治之，从归并排序到MapReduce(笔记)</title><link>https://time-friend.com/zh/archive/math-recursion-divide-and-conquer-from-merge-sort-to-mapreduce/</link><pubDate>Sun, 06 Sep 2020 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/math-recursion-divide-and-conquer-from-merge-sort-to-mapreduce/</guid><description>&lt;p&gt;黄申老师的标题实在是太好了,找不到更好的标题来描述今天学习的内容.啊哈哈~&lt;/p&gt;
&lt;h2 id="归并排序中的分治思想"&gt;归并排序中的分治思想&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;问题: 对一堆杂乱无序的数字，按照从小到大或者从大到小的规则进行排序&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id="有序情况"&gt;有序情况&lt;/h4&gt;
&lt;p&gt;尝试合并有序数组{1, 2, 5, 8}和{3, 4, 6}的过程。
&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/ba8272d5cbead0e8168ecf222e0ddc87bd2a089a7ffb236f5b6b9c38b435723d.png" alt="图 1"&gt;&lt;/p&gt;
&lt;h4 id="乱序情况"&gt;乱序情况&lt;/h4&gt;
&lt;p&gt;尝试把问题不断简化，也就是把数列不断简化，一直简化到只剩 1 个数。1 个数本身就是有序的，&lt;/p&gt;
&lt;p&gt;把将长度为 n 的数列，每次简化为长度为 n-1 的数列，直至长度为 1。不过，这样的处理没有并行性，要进行 n-1 次的归并操作，但是效率会很低.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/a4e5044079ca4e287a13e3f34d81f1bd712222c31aae713439cb9c4afb449e99.png" alt="图 2"&gt;&lt;/p&gt;
&lt;h4 id="引入分而治之divide-and-conquer的思想"&gt;引入分而治之（Divide and Conquer）的思想&lt;/h4&gt;
&lt;p&gt;分而治之，我们通常简称为分治。它的思想就是，将一个复杂的问题，分解成两个甚至多个规模相同或类似的子问题，然后对这些子问题再进一步细分，直到最后的子问题变得很简单，很容易就能被求解出来，这样这个复杂的问题就求解出来了。&lt;/p&gt;
&lt;p&gt;一个数组的排序
&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/561575b5a08832ca432284406d793732de813a010178fa24246130241575c2c8.png" alt="图 3"&gt;&lt;/p&gt;
&lt;p&gt;两个数组排序后合并&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/4d11bc859f11b67592da63cb7335032a6d94d283191b15ad36130aff960d34ae.png" alt="图 4"&gt;&lt;/p&gt;
&lt;p&gt;最重要的思想在于如何拆解问题
&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/4af4e60683c72eb81042cad628130719a794e454987742f2ed6ac090bfb5be4e.png" alt="图 5"&gt;&lt;/p&gt;
&lt;p&gt;归并排序的不同阶段&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/695f43d5f338aa5f49fe970a32bd9d5cff4ab39a763b2eb407474fa3a0dc5b91.png" alt="图 6"&gt;&lt;/p&gt;
&lt;h3 id="使用递归的方式来实现已上思路"&gt;使用递归的方式来实现已上思路&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 递归拆分数组
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;merge_sort&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;to_sort&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 非法数据,直接返回[]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;to_sort&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; [];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 如果分解到只剩一个数，返回该数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;to_sort&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;to_sort&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 将数组分解成左右两半
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;mid&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;to_sort&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// js中的splice会操作原数组内容,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 前半段取出来之后,后半段直接取原数组的变量应用就好了
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;left&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [].&lt;span style="color:#a6e22e"&gt;concat&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;to_sort&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;splice&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;mid&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;right&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [].&lt;span style="color:#a6e22e"&gt;concat&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;to_sort&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 嵌套调用，对两半分别进行排序
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;left&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;merge_sort&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;left&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;right&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;merge_sort&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;right&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 合并排序后的两半
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;merged&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;merge&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;left&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;right&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;merged&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 数组合并排序
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;merge&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;) &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;) &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 后续会降结果push到这个数组中来
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;merged_one&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// a,b数组的index
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ai&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bi&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 轮流从两个数组中取出较小的值，放入合并后的数组中
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;ai&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bi&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;ai&lt;/span&gt;] &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;bi&lt;/span&gt;]) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;merged_one&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;push&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;ai&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;ai&lt;/span&gt; &lt;span style="color:#f92672"&gt;++&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;merged_one&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;push&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;bi&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;bi&lt;/span&gt; &lt;span style="color:#f92672"&gt;++&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 将某个数组内剩余的数字放入合并后的数组中
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;ai&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ai&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;merged_one&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;push&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bi&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;merged_one&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;push&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;merged_one&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;arr&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;6&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;7&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;9&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;排序结果&amp;#39;&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;merge_sort&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;arr&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 排序结果 [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="分而治之思想在分布式系统中"&gt;分而治之思想在分布式系统中&lt;/h2&gt;
&lt;p&gt;当需要排序的数组很大（比如达到 1024GB 的时候），我们没法把这些数据都塞入一台普通机器的内存里。该怎么办呢？有一个办法，我们可以把这个超级大的数据集，分解为多个更小的数据集（比如 16GB 或者更小），然后分配到多台机器，让它们并行地处理。&lt;/p&gt;</description></item><item><title>数学篇 - 递归,复杂问题分解(笔记)</title><link>https://time-friend.com/zh/archive/math-recursion-decompose-complex-problems/</link><pubDate>Sat, 05 Sep 2020 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/math-recursion-decompose-complex-problems/</guid><description>&lt;h2 id="递归与循环"&gt;递归与循环&lt;/h2&gt;
&lt;p&gt;理论上所有递归能做到的循环都能实现.&lt;/p&gt;
&lt;p&gt;递归和循环其实都是迭代法的实现，而且在某些场合下，它们的实现是可以相互转化的。&lt;/p&gt;
&lt;h2 id="为什么要使用递归"&gt;为什么要使用递归&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;既然递归的函数值返回过程和基于循环的迭代法一致，我们直接用迭代法不就好了，为什么还要用递归的数学思想和编程方法呢？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="如何在限定总和的情况下求所有可能的加和方式"&gt;如何在限定总和的情况下，求所有可能的加和方式？&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;假设有四种面额的钱币，1 元、2 元、5 元和 10 元，要奖励别人10元，那可以奖赏 1 张 10 元，或者 10 张 1 元，或者 5 张 1 元外加 1 张 5 元等等。最终会有多少种方案?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/685328b2212b37eeb3e874636dd38d7cc2fee83886cc07741a9f5a5f9a82aa8c.png" alt="图 2"&gt;&lt;/p&gt;
&lt;h2 id="如何把复杂的问题简单化"&gt;如何把复杂的问题简单化？&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 面额
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rewards&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @Description: 使用函数的递归（嵌套）调用，找出所有可能的奖赏组合
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @param totalReward-奖赏总金额，result-保存当前的解
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @return void
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;totalReward&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;result&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 如果所有奖励全部给完
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;totalReward&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 拿到复合条件的结果,输出
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;result&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 如果奖励的钱超过当初设想的奖励(钱给多了),
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 则不是我们想要的结果
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;totalReward&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;) { &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//根据不同面额触发,让他们开始递归
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rewards&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;newResult&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [].&lt;span style="color:#a6e22e"&gt;concat&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;result&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// 由于有4种情况，需要clone当前的解并传入被调用的函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;newResult&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;push&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;rewards&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;]); &lt;span style="color:#75715e"&gt;// 记录当前的选择
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// totalReward - rewards[i]相当于还有多少钱没有给
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 交给下一个递归去解决该给多少钱的问题
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;totalReward&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rewards&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;], &lt;span style="color:#a6e22e"&gt;newResult&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// 剩下的问题，留给嵌套调用去解决
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 给出10块钱的不同方案
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;,[])
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果是循环解决这样的问题,是不是相对没有这样简洁?&lt;/p&gt;</description></item><item><title>数学篇 - 数学归纳法,给计算机注入灵魂(笔记)</title><link>https://time-friend.com/zh/archive/math-mathematical-induction-inject-soul-into-computer/</link><pubDate>Fri, 04 Sep 2020 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/math-mathematical-induction-inject-soul-into-computer/</guid><description>&lt;h2 id="什么是数学归纳法"&gt;什么是数学归纳法？&lt;/h2&gt;
&lt;p&gt;在棋盘上放麦粒的规则是，第一格放一粒，第二格放两粒，以此类推，每一小格内都比前一小格多一倍的麦子，直至放满 64 个格子。你发现第 1 格到第 8 格的麦子数分别是：1、2、4、8、16、32、64、128。&lt;/p&gt;
&lt;h3 id="找规律"&gt;找规律&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/873afd7eccb11857ce37c70086e24e186089ea2e8e93daf7ea8677ee5746460e.png" alt="图 9"&gt;&lt;/p&gt;
&lt;p&gt;对于类似这种无穷数列的问题，我们通常可以采用&lt;code&gt;数学归纳法（Mathematical Induction）&lt;/code&gt;来证明&lt;/p&gt;
&lt;h2 id="数学归纳法步骤"&gt;数学归纳法步骤&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;证明基本情况（通常是 n=1 的时候）是否成立；&lt;/li&gt;
&lt;li&gt;假设 n=k−1 成立，再证明 n=k 也是成立的（k 为任意大于 1 的自然数）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;和使用迭代法的计算相比，数学归纳法最大的特点就在于“归纳”二字。它已经总结出了规律。只要我们能够证明这个规律是正确的，就没有必要进行逐步的推算，可以节省很多时间和资源。&lt;/p&gt;
&lt;h3 id="代码示例"&gt;代码示例&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;grid&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;63&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;time&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;归纳法耗时&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`舍罕王给了这么多粒: &lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt; Math.&lt;span style="color:#a6e22e"&gt;pow&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;grid&lt;/span&gt;) &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;timeEnd&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;归纳法耗时&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;递归调用的代码和数学归纳法的逻辑是一致的,但是数学归纳法实现的运行时间几乎为 0&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;数学归纳法需要我们能做出合理的命题假设，然后才能进行证明。&lt;/p&gt;</description></item><item><title>数学篇 - 迭代法,让每次计算都更接近真像(笔记)</title><link>https://time-friend.com/zh/archive/math-iterative-method-get-closer-to-truth/</link><pubDate>Thu, 03 Sep 2020 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/math-iterative-method-get-closer-to-truth/</guid><description>&lt;h2 id="什么是迭代法iterative-method"&gt;什么是迭代法（Iterative Method）？&lt;/h2&gt;
&lt;p&gt;就是不断地用旧的变量值，递推计算新的变量值。&lt;/p&gt;
&lt;h3 id="小故事"&gt;小故事:&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;古印度国王舍罕酷爱下棋，他打算重赏国际象棋的发明人宰相西萨·班·达依尔。这位聪明的大臣指着象棋盘对国王说：“陛下，我不要别的赏赐，请您在这张棋盘的第一个小格内放入一粒麦子，在第二个小格内放入两粒，第三小格内放入给四粒，以此类推，每一小格内都比前一小格加一倍的麦子，直至放满 64 个格子，然后将棋盘上所有的麦粒都赏给您的仆人我吧！”国王自以为小事一桩，痛快地答应了。可是，当开始放麦粒之后，国王发现，还没放到第二十格，一袋麦子已经空了。随着，一袋又一袋的麦子被放入棋盘的格子里，国王很快看出来，即便拿来全印度的粮食，也兑现不了对达依尔的诺言。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;通过一个函数来计算最后麦子的数量.
&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/2ef3e94c5ea97c2db46680a3d0e8050b7ba122b31a9c14b75b9f7a0f9273b977.png" alt="图 1"&gt;&lt;/p&gt;
&lt;h3 id="用计算机语言其实特别适合"&gt;用计算机语言其实特别适合&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getNumberOfWheat&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;grid&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;numberOfWheatInGrid&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// 当前格子里麦粒的数量 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;numberOfWheatInGrid&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// 第一个格子里麦粒的数量 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 先放一粒米
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;sum&lt;/span&gt; &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;numberOfWheatInGrid&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;grid&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;++&lt;/span&gt;) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;numberOfWheatInGrid&lt;/span&gt; &lt;span style="color:#f92672"&gt;*=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 当前格子里麦粒的数量是前一格的2倍 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;sum&lt;/span&gt; &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;numberOfWheatInGrid&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 累计麦粒总数 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;sum&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 计算64格的数量
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;getNumberOfWheat&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;64&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="具体应用"&gt;具体应用？&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;求数值的精确或者近似解&lt;/code&gt;。典型的方法包括二分法（Bisection method）和牛顿迭代法（Newton’s method）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;在一定范围内查找目标值&lt;/code&gt;。典型的方法包括二分查找。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;机器学习算法中的迭代&lt;/code&gt;。相关的算法或者模型有很多，比如 K- 均值算法（K-means clustering）、PageRank 的马尔科夫链（Markov chain）、梯度下降法（Gradient descent）等等。迭代法之所以在机器学习中有广泛的应用，是因为&lt;code&gt;很多时候机器学习的过程，就是根据已知的数据和一定的假设，求一个局部最优解&lt;/code&gt;。而迭代法可以帮助学习算法逐步搜索，直至发现这种解。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="实践二分法求方程的精确或者近似解"&gt;实践二分法求方程的精确或者近似解&lt;/h3&gt;
&lt;p&gt;题: 找 10 的平方根&lt;/p&gt;
&lt;p&gt;思路: 我们需要先看 1 到 10 的中间数值，也就是 11/2=5.5。5.5 的平方是大于 10 的，所以我们要一个更小的数值，就看 5.5 和 1 之间的 3.25。由于 3.25 的平方也是大于 10 的，继续查看 3.25 和 1 之间的数值，也就是 2.125。这时，2.125 的平方小于 10 了，所以看 2.125 和 3.25 之间的值，一直继续下去，直到发现某个数的平方正好是 10&lt;/p&gt;</description></item><item><title>数学篇 - 余数与哈希函数(笔记)</title><link>https://time-friend.com/zh/archive/math-remainder-and-hash-function/</link><pubDate>Wed, 02 Sep 2020 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/math-remainder-and-hash-function/</guid><description>&lt;h2 id="余数"&gt;余数&lt;/h2&gt;
&lt;h3 id="例1"&gt;例1:&lt;/h3&gt;
&lt;p&gt;今天是星期三，你想知道 50 天之后是星期几，那你可以这样算，拿 50 除以 7（因为一个星期有 7 天），然后余 1，最后在今天的基础上加一天，这样你就能知道 50 天之后是星期四了&lt;/p&gt;
&lt;h3 id="例2"&gt;例2:&lt;/h3&gt;
&lt;p&gt;如果你要展示 1123 条数据，每页 10 条，那该怎么计算总共的页数呢？我想你肯定是拿 1123 除以 10，最后得到商是 112，余数是 3，所以你的总页数就是 112+1=113，而最后的余数就是多出来，凑不够一页的数据。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;余数总是在一个固定的范围内&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="同余定理"&gt;同余定理&lt;/h2&gt;
&lt;p&gt;数学上，两个整数除以同一个整数，若得相同余数，则二整数同余&lt;/p&gt;
&lt;h3 id="如何理解"&gt;如何理解&lt;/h3&gt;
&lt;p&gt;100 天里，所有星期一的这些天都是同余的，所有星期二的这些天就是同余的，同理，星期三、星期四等等这些天也都是同余的&lt;/p&gt;
&lt;h2 id="哈希-hash"&gt;哈希 Hash&lt;/h2&gt;
&lt;p&gt;将任意长度的输入，通过哈希算法，压缩为某一固定长度的输出&lt;/p&gt;
&lt;p&gt;想想星期的概念:
&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/fb46f02c67b2c960e4508d742017fda08a61c36c80c9ffb177b2505f9f95de41.png" alt="图 1"&gt;&lt;/p&gt;
&lt;p&gt;将数据取余
&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/d6f4f7d47fddefdb2498b24200aee9d4cb5e8c89cc0077acd50d6964c4bd63fe.png" alt="图 2"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ps. size指的是有限空间的数目而不是大小&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在这个公式中，x 表示等待被转换的数值，而 size 表示有限存储空间的数目，mod 表示取余操作。通过余数，你就能将任何数值，转换为有限范围内的一个数值，然后根据这个新的数值，来确定将数据存放在何处。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/fe3564b8d6dcaa4e3147f270c00a0d6672c751eb270d366f583d032fd7cfa8cc.png" alt="图 6"&gt;&lt;/p&gt;
&lt;p&gt;假设有两条记录，它们的记录标号分别是 1 和 101。我们把这些模 100 之后余数都是 1 的，存放到第 1 个可用空间里。以此类推，将余数为 2 的 2、102、202 等，存放到第 2 个可用空间，将 100、200、300 等存放到第 100 个可用空间里。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/43f4278f979a39f5678d0a80ed6d92dc704812101c053537bcb3705c46f4fa22.png" alt=""&gt;&lt;/p&gt;
&lt;p&gt;再复杂一点
&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/3fd8f07c1314585e5ad2a8294f60af0832debbd8b602d142c6503e6b93eb4f4b.png" alt="图 4"&gt;&lt;/p&gt;</description></item><item><title>数学篇 - 计算机的源头二进制(笔记)</title><link>https://time-friend.com/zh/archive/math-computer-origin-binary/</link><pubDate>Tue, 01 Sep 2020 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/math-computer-origin-binary/</guid><description>&lt;h2 id="计算机起源"&gt;计算机起源&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;计算机的起源是数学中的二进制计数法&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="什么是二进制计数法"&gt;什么是二进制计数法？&lt;/h2&gt;
&lt;h3 id="日常的十进制"&gt;日常的十进制&lt;/h3&gt;
&lt;p&gt;阿拉伯数字由从 0 到 9 这样 10 个计数符号组成，并采取进位制法,每10进一位,2871为例&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/294a1909e34794530f44814c77647d1aa7c7c6b487067889af4a1a85b3b857da.png" alt="图 7"&gt;&lt;/p&gt;
&lt;p&gt;其中 ^ 表示幂或次方运算。十进制的数位（千位、百位、十位等）全部都是 10^n 的形式。需要特别注意的是，任何非 0 数字的 0 次方均为 1。在这个新的表示式里，10 被称为十进制计数法的&lt;code&gt;基数&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="二进制"&gt;二进制&lt;/h3&gt;
&lt;p&gt;我们将基数改为2,就可以理解二进制的展示了.例如110101.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;二进制的数位就是 2^n 的形式&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/d20e54352a5b95a9caafef829f9d00c5b1e4186fa0323d446e62bd624ea6c7e0.png" alt="图 8"&gt;&lt;/p&gt;
&lt;h3 id="其他进制"&gt;其他进制&lt;/h3&gt;
&lt;p&gt;我们只要基于基数的改动,就可以使用任一进制来展示我们的数字.&lt;/p&gt;
&lt;h3 id="javascript-进制转换"&gt;JavaScript 进制转换&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;parseInt(&lt;span style="color:#a6e22e"&gt;num&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;); &lt;span style="color:#75715e"&gt;//八进制转十进制
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;parseInt(&lt;span style="color:#a6e22e"&gt;num&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;16&lt;/span&gt;); &lt;span style="color:#75715e"&gt;//十六进制转十进制 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;parseInt(&lt;span style="color:#a6e22e"&gt;num&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;toString&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//十进制转八进制 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;parseInt(&lt;span style="color:#a6e22e"&gt;num&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;toString&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;16&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//十进制转十六进制 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;parseInt(&lt;span style="color:#a6e22e"&gt;num&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;toString&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//二进制转八进制 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;parseInt(&lt;span style="color:#a6e22e"&gt;num&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;toString&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;16&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//二进制转十六进制
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;parseInt(&lt;span style="color:#a6e22e"&gt;num&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;toString&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//八进制转二进制 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;parseInt(&lt;span style="color:#a6e22e"&gt;num&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;toString&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;16&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//八进制转十六进制 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;parseInt(&lt;span style="color:#a6e22e"&gt;num&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;16&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;toString&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//十六进制转二进制 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;parseInt(&lt;span style="color:#a6e22e"&gt;num&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;16&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;toString&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//十六进制转八进制
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="计算机为什么使用二进制"&gt;计算机为什么使用二进制？&lt;/h2&gt;
&lt;p&gt;组成计算机系统的逻辑电路通常只有两个状态，即开关的接通与断开。&lt;/p&gt;
&lt;h2 id="二进制的位操作"&gt;二进制的位操作&lt;/h2&gt;
&lt;h3 id="向左移位"&gt;向左移位&lt;/h3&gt;
&lt;p&gt;二进制 110101 向左移一位，就是在末尾添加一位 0，因此 110101 就变成了 1101010&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/0145c13e717d6c03fe7cce4710684fc603d232ee67c68acbf28adcb97607e0ff.png" alt="图 9"&gt;&lt;/p&gt;
&lt;p&gt;如果将 1101010 换算为十进制，就是 106，你有没有发现，106 正好是 53 的 2 倍&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;二进制左移一位，其实就是将数字翻倍。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id="数字溢出"&gt;数字溢出&lt;/h4&gt;
&lt;p&gt;所谓数字溢出，就是二进制数的位数超过了系统所指定的位数。目前主流的系统都支持至少 32 位的整型数字&lt;/p&gt;</description></item><item><title>Puppeteer在工作中是如何伪装自己的(爬虫与反爬虫)</title><link>https://time-friend.com/zh/archive/how-puppeteer-disguises-itself-in-work-crawler-and-anti-crawler/</link><pubDate>Sat, 29 Aug 2020 20:32:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/how-puppeteer-disguises-itself-in-work-crawler-and-anti-crawler/</guid><description>&lt;p&gt;为了更好保护我们的数据与程序安全.&lt;/p&gt;
&lt;p&gt;今天就介绍一下,如何检测访问我们的web程序是否为无头浏览器,
以及他们的一些反检测的方法.&lt;/p&gt;
&lt;h2 id="webdriver检测"&gt;Webdriver检测&lt;/h2&gt;
&lt;p&gt;一般来说,如果是无头浏览器模式下, &lt;code&gt;navigator.webdriver&lt;/code&gt; 会返回 &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="检测方式"&gt;检测方式&lt;/h3&gt;
&lt;p&gt;最简单的检测方式&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;navigator&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;webdriver&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 针对无头浏览器的操作
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="使用defineproperty删除webdriver后如何检测"&gt;使用defineProperty删除webdriver后如何检测&lt;/h4&gt;
&lt;p&gt;如果对方使用以下方式删除了webdriver属性,其实还是有办法检测的&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Object.&lt;span style="color:#a6e22e"&gt;defineProperty&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;navigator&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;webdriver&amp;#39;&lt;/span&gt;, {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; () =&amp;gt; &lt;span style="color:#66d9ef"&gt;undefined&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="应对方案"&gt;应对方案&lt;/h4&gt;
&lt;p&gt;以下方式,还是可以检测出来&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;webdriver&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;in&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;navigator&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;navigator&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;hasOwnProperty&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;webdriver&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="绕过方法"&gt;绕过方法&lt;/h3&gt;
&lt;p&gt;直接删掉webdriver属性,这是我目前验证成功的方法.
目前其他网上找到的方法已经无效.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;page&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;evaluateOnNewDocument&lt;/span&gt;(() =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;newProto&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;navigator&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;__proto__&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;delete&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;newProto&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;webdriver&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;navigator&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;__proto__&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;newProto&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="chrome属性检测"&gt;chrome属性检测&lt;/h2&gt;
&lt;h3 id="检测方式-1"&gt;检测方式&lt;/h3&gt;
&lt;p&gt;在无头浏览器模式下,全局对象下的chrome对象是没有 &lt;code&gt;runtime&lt;/code&gt;属性的&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;window.&lt;span style="color:#a6e22e"&gt;chrome&lt;/span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#f92672"&gt;!&lt;/span&gt;window.&lt;span style="color:#a6e22e"&gt;chrome&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;runtime&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 无头浏览器模式...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="绕过方法-1"&gt;绕过方法&lt;/h3&gt;
&lt;p&gt;所以绕过方法也很简单,我们只需要伪造一个&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;window.&lt;span style="color:#a6e22e"&gt;navigator&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;chrome&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;runtime&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果是Puppeteer 我们跟上面一样,只要提前运行一下上面的代码就好了.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;page&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;evaluateOnNewDocument&lt;/span&gt;(() =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; window.&lt;span style="color:#a6e22e"&gt;navigator&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;chrome&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;runtime&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="尾巴"&gt;尾巴&lt;/h2&gt;
&lt;p&gt;其他网络上的方法我都尝试过,可以成功的我都放在了这里.
因为浏览器跟反爬虫方式时时刻刻都会更新,所以可能当你看到这篇文章的时候.
有的方式已经不能用了,但是核心点还是要善于观察力与对比.
所有的形式都可以有伪装与绕过的方法.大致思路都跟上面提到的差不多.&lt;/p&gt;</description></item><item><title>Taro跨端开发之让Taro UI支持React Native</title><link>https://time-friend.com/zh/archive/making-taro-ui-support-react-native/</link><pubDate>Thu, 27 Aug 2020 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/making-taro-ui-support-react-native/</guid><description>&lt;h2 id="taro-ui-不支持rn的窘境"&gt;Taro UI 不支持RN的窘境&lt;/h2&gt;
&lt;p&gt;Taro UI 文档上很早就说明会有可能支持rn了,但是快一年多了,因为taro ui团队人力的问题一直没有兼容到rn.&lt;/p&gt;
&lt;p&gt;业务紧迫,我们等不到那一天了.自己动手丰衣足食.&lt;/p&gt;
&lt;h2 id="taro-传统组件打包在rn上的问题"&gt;Taro 传统组件打包在RN上的问题&lt;/h2&gt;
&lt;p&gt;一般来说,组件库打完包之后 dist/index.js文件会是这样的.&lt;/p&gt;
&lt;p&gt;根据运行时的环境变量区分是否要引入哪一个组件库.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;process&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;env&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;TARO_ENV&lt;/span&gt; &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;weapp&amp;#39;&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./weapp/ui&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;process&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;env&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;TARO_ENV&lt;/span&gt; &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;h5&amp;#39;&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./h5/ui&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./weapp/ui&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;理想模式下,只要加入一个rn的环境判断,就可以做到rn组件库的引入了.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;process&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;env&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;TARO_ENV&lt;/span&gt; &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;weapp&amp;#39;&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./weapp/ui&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;process&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;env&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;TARO_ENV&lt;/span&gt; &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;h5&amp;#39;&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./h5/ui&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;process&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;env&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;TARO_ENV&lt;/span&gt; &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;rn&amp;#39;&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 理想模式,只需要加这一段
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./rn/ui&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./weapp/ui&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;可是现实不是这样的,rn如果引入组件库的索引文件,是dist/index.js,他会提前把所有端的代码全部预执行一遍.&lt;/p&gt;
&lt;p&gt;代码还没有真正运行,就因为其他端的代码不兼容,直接报错了. 所以这样硬核的引入方法是不可行的.&lt;/p&gt;
&lt;h2 id="rn组件库代码与其他端代码完全隔离"&gt;rn组件库代码与其他端代码完全隔离&lt;/h2&gt;
&lt;h3 id="uijs文件的改动"&gt;ui.js文件的改动&lt;/h3&gt;
&lt;p&gt;在src下边有一个ui.js文件,大致内容是这样的:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Taro&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;@tarojs/taro&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./style/index.scss&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;as&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;AActionSheet&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./components/action-sheet&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;as&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;AActionSheetItem&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./components/action-sheet/body/item&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;as&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;AText&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./components/text&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;as&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;AToast&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./components/toast&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;as&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;AButton&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./components/button&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 其他组件...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;为了更好的在原来组件库上做rn的兼容,利用taro可以根据文件后缀名区分端的特性就排上用场了.
需要新建一个&lt;code&gt;ui.rn.js&lt;/code&gt;&lt;/p&gt;</description></item><item><title>Taro跨端开发之多业务模块管理 React Native篇(终篇)</title><link>https://time-friend.com/zh/archive/multi-business-module-management-react-native-final/</link><pubDate>Tue, 25 Aug 2020 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/multi-business-module-management-react-native-final/</guid><description>&lt;h2 id="react-native-热更新方案"&gt;React Native 热更新方案&lt;/h2&gt;
&lt;p&gt;rn的业务越来越庞大,同时协同的团队越来越多. rn的动态化就必须提上日程了.
对于rn热更新,首当其冲的问题就是分包.&lt;/p&gt;
&lt;p&gt;rn的基础库很大,再加上我们依赖了很多的三方库.这些代码就必须在分包的时候单独剥离出来.
业务包让他比较纯粹的只有业务代码. 这样就可以保证业务包的体积比较小,保证热更新时候的速度.&lt;/p&gt;
&lt;h3 id="使用metro分包"&gt;使用metro分包&lt;/h3&gt;
&lt;p&gt;React Native 提供的 metro 自带分包功能。metro我们本来就一直在用,只要在metro打包的时候,提供相应的打包规则.
就可以实现rn的分包了.&lt;/p&gt;
&lt;p&gt;示例: ios打包&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;node ./node_modules/react-native/local-cli/cli.js bundle --platform ios --dev false --entry-file rn入口文件.js --bundle-output ./xxx/ --assets-dest ./xxx/ --config /&lt;span style="color:#f92672"&gt;{&lt;/span&gt;你的绝对路径&lt;span style="color:#f92672"&gt;}&lt;/span&gt;/你的metro配置文件.js
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="metro-关键api介绍"&gt;metro 关键api介绍&lt;/h3&gt;
&lt;p&gt;我们分包需要用的选项主要是两个：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;createModuleIdFactory：这个函数传入要打包的 module 文件的绝对路径，返回这个 module 在打包的时候生成的 id。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;processModuleFilter：这个函数传入 module 信息，返回一个 boolean 值，false 则表示这个文件不打入当前的包。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="主工程分包"&gt;主工程分包&lt;/h3&gt;
&lt;p&gt;之前我们有提到过我们有一个项目是主工程,里面没有任何的业务代码.只有一些代码运行需要的所有依赖.&lt;/p&gt;
&lt;p&gt;我们需要将所有的依赖全部收集起来,当业务模块打包的时候,发现本地有这个依赖就可以使用 &lt;code&gt;processModuleFilter&lt;/code&gt;方法排除掉.&lt;/p&gt;
&lt;p&gt;因为我们的主工程与业务项目的依赖版本都是高度统一的.
所以我们node_modules下面的依赖包路径都是完全一致的.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://time-friend.com/archive/h8gasmt9u5c/"&gt;Taro跨端开发之依赖管理&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;主工程的metro配置文件示例:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;createModuleIdFactory&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;path&lt;/span&gt; =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 在这里我们拿到依赖的文件路径,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 我们需要在这个函数块中,将路径以收集并且将这些数据生成文件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 部署到我们内网的服务器中
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 当业务模块需要打包的时候,是否要将代码打进包中,将以这个文件为依据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;serializer&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;createModuleIdFactory&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;createModuleIdFactory&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;主工程入口文件示例:&lt;/p&gt;</description></item><item><title>Taro跨端开发之多业务模块管理 React Native篇(中)</title><link>https://time-friend.com/zh/archive/multi-business-module-management-react-native-part-2/</link><pubDate>Sun, 23 Aug 2020 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/multi-business-module-management-react-native-part-2/</guid><description>&lt;h2 id="实现一个简单的模块管理工具解决npm拉取业务模块慢的问题"&gt;实现一个简单的模块管理工具,解决npm拉取业务模块慢的问题&lt;/h2&gt;
&lt;p&gt;使用npm拉取git仓库,速度其实还是可以接受的.
主要慢的地方在于 &lt;code&gt;postinstall&lt;/code&gt;的时候需要在npm拉取git仓库的时候,需要重新构建项目代码.还有一点就是业务模块也有依赖,npm install的时候也需要重新拉取相同的依赖.&lt;/p&gt;
&lt;p&gt;这两个步骤其实是可以省略的,解决的办法就是可以实现一个简单的模块管理工具来替代npm加载业务模块的处理.&lt;/p&gt;
&lt;h3 id="创建一个配置文件"&gt;创建一个配置文件&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Module1&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;url&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;http://xxx1.git&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;moduleName&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;模块名称&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;develop&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;taro&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Module2&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;url&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;http://xxx2.git&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;moduleName&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;模块名称&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;develop&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;taro&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;因为每一个项目都会用到这一个文件,把这个文件放到服务器上.
在业务模块初始化的时候,自动拉取解析这个文件.再使用nodejs拉取相应的git仓库.&lt;/p&gt;
&lt;h3 id="拉取git仓库"&gt;拉取git仓库&lt;/h3&gt;
&lt;p&gt;使用&lt;code&gt;download-git-repo&lt;/code&gt;拉取git仓库的代码放到node_modules目录下.
这样在项目中,我就可以引用普通npm一样引入这个仓库的代码了.&lt;/p&gt;
&lt;p&gt;这是&lt;code&gt;download-git-repo&lt;/code&gt;的地址与使用方法
&lt;a href="https://www.npmjs.com/package/download-git-repo"&gt;https://www.npmjs.com/package/download-git-repo&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="模拟npm生命周期"&gt;模拟npm生命周期&lt;/h3&gt;
&lt;p&gt;代码拉下来之后,还需要用postinstall来构建业务代码,
所以需要使用nodejs遍历以下业务模块的目录,读取目录下的每一个packages.json.&lt;/p&gt;
&lt;p&gt;如果有npm钩子的,就执行一下里面的script.&lt;/p&gt;
&lt;p&gt;大致示例代码如下:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 示例代码,仅供参考
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;spawn&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;cross-spawn&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fse&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;fs-extra&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;packageData&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fse&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;readJsonSync&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./packages.json&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;packageData&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;scripts&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;preinstall&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;spawn&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;sync&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;npm&amp;#39;&lt;/span&gt;,[&lt;span style="color:#e6db74"&gt;&amp;#39;run&amp;#39;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;preinstall&amp;#39;&lt;/span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;packageData&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;scripts&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;postinstall&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;spawn&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;sync&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;npm&amp;#39;&lt;/span&gt;,[&lt;span style="color:#e6db74"&gt;&amp;#39;run&amp;#39;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;postinstall&amp;#39;&lt;/span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="并发执行业务模块的npm钩子"&gt;并发执行业务模块的npm钩子&lt;/h3&gt;
&lt;p&gt;在npm执行postinstall的时候,并不是全部一股脑的全部执行.&lt;/p&gt;
&lt;p&gt;使用 yarn 安装依赖的时候,同时最多可以4个模块执行(npm install 没有具体研究).
所以构建业务模块的时候,总是会出现一个一个等的情况.&lt;/p&gt;</description></item><item><title>Taro跨端开发之多业务模块管理 React Native篇(上)</title><link>https://time-friend.com/zh/archive/multi-business-module-management-react-native-part-1/</link><pubDate>Fri, 21 Aug 2020 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/multi-business-module-management-react-native-part-1/</guid><description>&lt;h2 id="原生rn项目与taro如何共存"&gt;原生RN项目与Taro如何共存?&lt;/h2&gt;
&lt;p&gt;我们团队一开始就有实践原生React Native的项目,很长一段时间,&lt;/p&gt;
&lt;p&gt;所有的业务模块都是在一个项目里面开发维护,时间久了这个项目就变成了一个巨无霸项目.&lt;/p&gt;
&lt;p&gt;再加上后来引进了基于Taro开发的rn项目,为了保证原生与Taro的RN共存,&lt;/p&gt;
&lt;p&gt;不管是原生rn项目还是taro项目的package.json文件的main对外导出的索引文件格式都是一致的.&lt;/p&gt;
&lt;p&gt;我们使用以下方案来维护我们的代码.&lt;/p&gt;
&lt;h2 id="使用npm来管理我们的业务模块"&gt;使用npm来管理我们的业务模块&lt;/h2&gt;
&lt;h3 id="rn业务的主工程"&gt;RN业务的主工程&lt;/h3&gt;
&lt;p&gt;这是我最初实践的方案,首先我们创建一个项目为RN的主工程.&lt;/p&gt;
&lt;p&gt;里面没有任何的业务代码,只有在根目录下有一个index.js的业务索引文件.&lt;/p&gt;
&lt;p&gt;它大概是这样的:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;AppRegistry&lt;/span&gt;} &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;react-native&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Module1&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Module1&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Module2&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Module2&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Module3&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Module3&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;AppRegistry&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;registerComponent&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;Module1&amp;#39;&lt;/span&gt;, () =&amp;gt; &lt;span style="color:#a6e22e"&gt;Module1&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;AppRegistry&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;registerComponent&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;Module2&amp;#39;&lt;/span&gt;, () =&amp;gt; &lt;span style="color:#a6e22e"&gt;Module2&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;AppRegistry&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;registerComponent&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;Module3&amp;#39;&lt;/span&gt;, () =&amp;gt; &lt;span style="color:#a6e22e"&gt;Module3&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;之前的一篇文章我已经提到,我们所有的模块依赖都是统一的,并且版本锁死.&lt;/p&gt;
&lt;p&gt;有兴趣的可以点击查看:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://time-friend.com/archive/h8gasmt9u5c/"&gt;Taro跨端开发之依赖管理&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;所以我的主工程的依赖与业务模块的依赖是保持一致的.&lt;/p&gt;
&lt;h3 id="使用npm管理业务模块"&gt;使用NPM管理业务模块&lt;/h3&gt;
&lt;p&gt;我们会把所有的业务模块当成npm来管理,因为npm有很多的生命周期钩子使用.&lt;/p&gt;
&lt;p&gt;在统一了npm script 命令之后,很容易统一管理他们.&lt;/p&gt;
&lt;p&gt;当然这些业务模块我们不会把他发布到npm服务器上,因为业务代码会频繁变动,如果每一次提交都要上传到npm服务器,自然会添加开发人员的代码管理成本(发布npm包很烦的)&lt;/p&gt;
&lt;p&gt;所以我们使用 &lt;code&gt;npm + git&lt;/code&gt; 地址来拉取我们的业务模块.&lt;/p&gt;
&lt;p&gt;例如:&lt;/p&gt;
&lt;h4 id="主工程的packagejson"&gt;主工程的package.json&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;base&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;version&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;0.0.6&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;scripts&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;build&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;构建rn的相关操作&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;},
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;dependencies&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;公共依赖包&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;1.0.0&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;Module1&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;http://xxx.com/webfront/Module1.git&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;Module2&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;http://xxx.com/webfront/Module2.git&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;Module3&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;http://xxx.com/webfront/Module3.git&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="业务模块的packagejson"&gt;业务模块的package.json&lt;/h4&gt;
&lt;p&gt;业务模块添加了postinstall,在使用npm拉取业务模块成功之后,业务模块会在 &lt;code&gt;node_modules&lt;/code&gt; 中构建自己的项目,提供主工程的&lt;code&gt;index.js&lt;/code&gt;使用&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;buz&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;version&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;0.0.1&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;main&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;main.js&amp;#34;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;// main字段要指向rn的索引文件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;scripts&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;build&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;构建rn的相关操作&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;postinstall&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;npm run build&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;},
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;dependencies&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;公共依赖包&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;1.0.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="统一对外输出的mainjs文件"&gt;统一对外输出的main.js文件&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;use strict&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 根据端的环境变量判断是否对外输出什么文件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;process&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;env&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;TARO_ENV&lt;/span&gt; &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;weapp&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;process&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;env&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;TARO_ENV&lt;/span&gt; &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;h5&amp;#39;&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./dist/index&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;} &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// taro系工程,标准对外输出
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Object.&lt;span style="color:#a6e22e"&gt;defineProperty&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;__esModule&amp;#34;&lt;/span&gt;, {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;value&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;_interopRequireDefault&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;) { &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;__esModule&lt;/span&gt; &lt;span style="color:#f92672"&gt;?&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt; }; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;_app&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;_interopRequireDefault&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;./rn_temp/app&amp;#34;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;APP&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;_app&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;default&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="业务模块之间相互调试"&gt;业务模块之间相互调试&lt;/h3&gt;
&lt;p&gt;业务与业务之间肯定会有相互联调的情况,以上的方案业务模块只能独立运行自己的代码,当我们想要跳转到其他RN页面的时候,那就不行了.&lt;/p&gt;</description></item><item><title>Taro跨端开发之依赖管理问题</title><link>https://time-friend.com/zh/archive/dependency-management-issues/</link><pubDate>Thu, 20 Aug 2020 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/dependency-management-issues/</guid><description>&lt;p&gt;目前我们通过Taro触达的端已经有:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;微信小程序&lt;/li&gt;
&lt;li&gt;QQ小程序&lt;/li&gt;
&lt;li&gt;百度小程序&lt;/li&gt;
&lt;li&gt;React Native&lt;/li&gt;
&lt;li&gt;H5&lt;/li&gt;
&lt;li&gt;快应用&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;为了快速的让业务可以触达到各端,我们每一个业务模块都是独立的.&lt;/p&gt;
&lt;p&gt;他们根据业务需要,分别兼容到不同的端,等到构建的时候再将其进行组装成为一个完整的项目.&lt;/p&gt;
&lt;p&gt;为了满足以上需要,并且可以灵活开发.所以每一个业务模块都是可以独立开发,独立运行的,可以不依赖主工程.&lt;/p&gt;
&lt;p&gt;目前来说项目之间的关系已经比较类似&lt;code&gt;微前端&lt;/code&gt;了.&lt;/p&gt;
&lt;p&gt;因为大部分端(除了&lt;code&gt;React Native&lt;/code&gt;) 都不能做到热更新,所以相对微前端架构而言小程序们做不到&lt;code&gt;独立部署&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/d6454e7c0d292a7a302dc0d0bc9c8c48256752fc683e3f0e46b6591b201ad7b9.png" alt="图 1"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;关于Taro + React Native部分,后面会有专门的文章跟大家介绍我们是怎么玩的.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;今天就跟大家介绍一下,多业务,多团队,多端的代码管理中我们遇到的第一个问题: &lt;code&gt;依赖管理问题&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="所有项目依赖统一管理"&gt;所有项目依赖统一管理&lt;/h2&gt;
&lt;p&gt;因为业务模块很多,我们项目工程的差异必须保持高度统一,其中包括依赖.&lt;/p&gt;
&lt;h3 id="核心依赖集中管理"&gt;核心依赖集中管理&lt;/h3&gt;
&lt;p&gt;现在我们团队开发的跨端模块已经有几十个.为了方便管理,&lt;/p&gt;
&lt;p&gt;我将所有的依赖封装成了一个&lt;code&gt;npm包&lt;/code&gt;,里面没有任何的业务代码,只有稳定的依赖.&lt;/p&gt;
&lt;p&gt;所有的项目都会引入这个核心的依赖,以保证所有项目可以稳定运行.&lt;/p&gt;
&lt;h3 id="非核心依赖版本管理问题"&gt;非核心依赖版本管理问题&lt;/h3&gt;
&lt;p&gt;如果是非核心依赖,我们将使用我们自研的&lt;code&gt;cli&lt;/code&gt;工具强行修改package.json里面的版本号.&lt;/p&gt;
&lt;p&gt;持续集成的过程中,所有的跨端项目都会通过这个cli工具在&lt;code&gt;npm install&lt;/code&gt;执行之前修改我们的项目配置.其中就包括了我们的依赖.&lt;/p&gt;
&lt;p&gt;我们修改过&lt;code&gt;cli&lt;/code&gt;工具之后,所有的跨端项目都会更新到最新的依赖配置.&lt;/p&gt;
&lt;h3 id="个别项目特殊处理办法"&gt;个别项目特殊处理办法&lt;/h3&gt;
&lt;p&gt;所有项目的依赖全部统一之后,总会有一些特殊原因个别项目的依赖会有一点区别.&lt;/p&gt;
&lt;p&gt;这里就必须要提到&lt;code&gt;package.json&lt;/code&gt;的 &lt;code&gt;resolutions&lt;/code&gt;属性.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;resolutions&lt;/code&gt; 字段用于解析选择性版本，可以通过此功能自定义依赖版本。&lt;/p&gt;
&lt;p&gt;这样npm就会将多版本共存的版本,强行指定某一版本,满足个别项目的特定需求.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/0a9ce7a425c583573c877efd0ce648a9c3992b90d4f272621a3850afa523cfa3.png" alt="图 1"&gt;&lt;/p&gt;
&lt;p&gt;如果我要所有的 &lt;code&gt;B&lt;/code&gt; 强行指定2.0&lt;/p&gt;
&lt;p&gt;使用方法如下:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// package.json 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 这样B这个依赖库,就被强行指定版本了
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;resolutions&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;B&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;2.0.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;resolutions的解释,你可以在这里查看更多:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://classic.yarnpkg.com/zh-Hans/docs/selective-version-resolutions"&gt;https://classic.yarnpkg.com/zh-Hans/docs/selective-version-resolutions&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;当然你也可以使用这个工具,将依赖强制指定版本:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.npmjs.com/package/npm-force-resolutions"&gt;https://www.npmjs.com/package/npm-force-resolutions&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="第三方依赖稳定性问题"&gt;第三方依赖稳定性问题&lt;/h2&gt;
&lt;p&gt;我们在开发周期比较长的前端项目的时候,必然会遇到依赖管理的问题.&lt;/p&gt;
&lt;p&gt;我们在开发项目的时候,我们用了大量的三方库.这些三方的依赖库时不时的会更新自己的代码.&lt;/p&gt;
&lt;p&gt;第三方依赖库的代码更新会很容易造成代码运行的不稳定,&lt;/p&gt;
&lt;p&gt;比如昨天还跑的好好的项目,另一位刚刚接手的同学重新安装依赖之后项目就完全跑不起来了.&lt;/p&gt;
&lt;p&gt;或者自己机器跑的好好的代码,扔到打包机上重新打包之后就完全跑不起来.&lt;/p&gt;
&lt;p&gt;因为三方依赖库用的太多,很多时候并不能很快速的定位到项目为什么跑不起来.&lt;/p&gt;
&lt;p&gt;特别是开发RN项目的时候,一个依赖更新的问题可能会定位一个大半天才能找到罪魁祸首(曾经的我为了这种事情浪费了大量的青春).&lt;/p&gt;</description></item><item><title>Taro跨端开发之跨端开发新时代的思考与举措</title><link>https://time-friend.com/zh/archive/thoughts-and-measures-on-new-era-of-cross-platform-development/</link><pubDate>Tue, 16 Jun 2020 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/thoughts-and-measures-on-new-era-of-cross-platform-development/</guid><description>&lt;h2 id="新时代"&gt;新时代&lt;/h2&gt;
&lt;p&gt;跨端框架的出现,前端的浏览器兼容过渡到了客户端平台兼容的新时代.&lt;/p&gt;
&lt;p&gt;对于初创公司而言,这种框架可以快速试错与降低人力与时间成本.&lt;/p&gt;
&lt;h2 id="为什么选择taro"&gt;为什么选择Taro&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;并不是说Taro方案有多优秀,就当前时间节点看来目前的所有跨端框架都还处于完善阶段.最完善的端可能就是小程序与H5了.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;但是对于有着对跨端开发有着强烈需求的公司来说,这些还远远不够.&lt;/p&gt;
&lt;p&gt;只是第一眼看上去Taro比较适合我们的现有业务.后续各种端的数量增大,如何从容对待.&lt;/p&gt;
&lt;p&gt;目前也还是未知数.就团队而言,前端输出突然猛增,其他配套设施没跟上等于随时翻车.目前我们面临的最大问题就是测试资源的问题.&lt;/p&gt;
&lt;p&gt;对于跨端技术而言,目前相对完善且符合公司业务的技术框架可以选择&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Taro&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;uni-app&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;一个类React, 一个类Vue.&lt;/p&gt;
&lt;p&gt;在框架层面,两种技术框架提供着非常接近的多端兼容方案.&lt;/p&gt;
&lt;p&gt;最大的不同是React 与 Vue的区别.当然,uni-app 提供了小程序容器方案.&lt;/p&gt;
&lt;p&gt;taro这边目前还没有.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;就目前对Taro来看,直接实现Taro to uni小程序理论上是可以实现的.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在Taro next版本中,已经支持对vue语法, 那这样后续是否会出现多端框架to多端框架的局面呢?&lt;/p&gt;
&lt;p&gt;回到问题本身,为什么我们选择Taro呢,&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;团队组建之初使用React技术栈&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;我们在RN端有了一定的探索&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Taro支持快应用&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;就历史包袱来看,选择Taro过渡成本是相对较小的.&lt;/p&gt;
&lt;h2 id="目标"&gt;目标&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;一处代码,多端运行.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;减少维护成本&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;多端快速上线&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;如果就快速上线来看,人力成本在短期内看,是非常可观的.但是一旦项目变大,团队变得也越大的时候.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;自动化测试,而项目工程化没有跟上,那就直接天堂变地狱.&lt;/p&gt;
&lt;h2 id="处境与心态"&gt;处境与心态&lt;/h2&gt;
&lt;p&gt;目前使用taro开发单端,基本上没有太大的问题.目前遇到的问题,都有办法可以解决的.&lt;/p&gt;
&lt;p&gt;唯一占用开发工作量的是,如何处理代码在多端中的兼容问题.&lt;/p&gt;
&lt;p&gt;所以处理兼容问题的方法与技巧还有多端开发的意识就尤为重要了.&lt;/p&gt;
&lt;p&gt;还有一个就是开发者的心态问题,因为要开发多端,多端差异还是会有的.&lt;/p&gt;
&lt;p&gt;在开发多端的同时,也要学习多端的开发方式.一来二去的,很容易形态奔溃.&lt;/p&gt;
&lt;p&gt;但是如果跨越了这一时期,了解了各端的特点,后续面对一些问题都会游刃有余了~&lt;/p&gt;
&lt;h2 id="适配最佳路径"&gt;适配最佳路径&lt;/h2&gt;
&lt;p&gt;经过各种实践,我们认为一下开发的兼容路径是相对简单的.&lt;/p&gt;
&lt;p&gt;在适配的过程中,主要还是样式的问题比较多.如果反向适配,会极其痛苦,&lt;/p&gt;
&lt;p&gt;因为你之前写的任意一行代码,都可能是后面的bug.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;可能在后续的发展中,这种类似短板问题会越来越不明显.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;但是就现在来看,合适的适配路径,是你必须要关注的重要问题.&lt;/p&gt;
&lt;p&gt;RN &amp;ndash;&amp;gt; 快应用 &amp;ndash;&amp;gt; 小程序 &amp;ndash;&amp;gt; 其他小程序 &amp;ndash;&amp;gt; H5&lt;/p&gt;
&lt;h2 id="脑洞--展望"&gt;脑洞 &amp;amp; 展望&lt;/h2&gt;
&lt;p&gt;就目前跨端框架发展趋势的话会不会发生以下事件?&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;一款跨端框架直接兼容另一款框架,直接吃掉所有端?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;开源一款类小程序的容器,直接替代react Native 与 weex?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;多端测试框架(一套测试用例,测试所有端)会不会应运而生?&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="尾巴"&gt;尾巴&lt;/h2&gt;
&lt;p&gt;后续的这段时间,我会把以下问题与团队实践整理出文章供大家思考.&lt;/p&gt;</description></item><item><title>Switch XCI转NSP工具 - 4NXCI下载</title><link>https://time-friend.com/zh/archive/switch-xci-to-nsp-tool-download/</link><pubDate>Sun, 02 Feb 2020 19:02:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/switch-xci-to-nsp-tool-download/</guid><description>&lt;h2 id="4nxci-是将-xci-文件转换为-nsp-的工具"&gt;4NXCI 是将 XCI 文件转换为 NSP 的工具&lt;/h2&gt;
&lt;p&gt;目前只支持windows,其他系统不支持&lt;/p&gt;
&lt;h3 id="github地址"&gt;Github地址:&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://github.com/The-4n/4NXCI"&gt;https://github.com/The-4n/4NXCI&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="下载地址"&gt;下载地址&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://github.com/The-4n/4NXCI/releases"&gt;https://github.com/The-4n/4NXCI/releases&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="使用方法"&gt;使用方法&lt;/h2&gt;
&lt;h2 id="gui工具"&gt;GUI工具&lt;/h2&gt;
&lt;p&gt;命令用不习惯的可以下载GUI的版本,文件命名大致为&lt;code&gt;4nxci-v4.03_GUI.zip &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/4a89dd91123467dc70d9633e66182469cf9c5e2d0a555bc62b0a379a3f41da8b.png" alt="图 1"&gt;&lt;/p&gt;
&lt;h3 id="命令行工具"&gt;命令行工具&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#ae81ff"&gt;\4&lt;/span&gt;nxci.exe &lt;span style="color:#f92672"&gt;[&lt;/span&gt;options...&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &amp;lt;path_to_file.xci&amp;gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Options: 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-k, --keyset 设置keyset文件路径, 默认为 ./keys.dat 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-h, --help 显示帮助信息
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-t, --tempdir 设置临时文件夹
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-o, --outdir 设置导出文件夹
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-r, --rename 设置导出的nsp文件的文件名
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;--keepncaid 保持当前ncas ID 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="关于keyset-文件"&gt;关于keyset 文件&lt;/h2&gt;
&lt;p&gt;拷贝以下代码放到一个txt文件中,然后重命名为 &lt;code&gt;keys.dat&lt;/code&gt;
使用GUI或者命令行工具导入就可以了&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;master_key_00 = C2CAAFF089B9AED55694876055271C7D
master_key_01 = 54E1B8E999C2FD16CD07B66109ACAAA6
master_key_02 = 4F6B10D33072AF2F250562BFF06B6DA3
master_key_03 = 84E04EC20B9373818C540829CF147F3D
master_key_04 = CFA2176790A53FF74974BFF2AF180921
master_key_05 = C1DBEDCEBF0DD6956079E506CFA1AF6E
master_key_06 = 0AA90E6330CDC12D819B3254D11A4E1E
header_key = AEAAB1CA08ADF9BEF12991F369E3C567D6881E4E4A6A47A51F6E4877062D542D
aes_kek_generation_source = 4D870986C45D20722FBA1053DA92E8A9
aes_key_generation_source = 89615EE05C31B6805FE58F3DA24F7AA8
key_area_key_application_source = 7F59971E629F36A13098066F2144C30D
key_area_key_ocean_source = 327D36085AD1758DAB4E6FBAA555D882
key_area_key_system_source = 8745F1BBA6BE79647D048BA67B5FDA4A
titlekek_source = 1EDC7B3B60E6B4D878B81715985E629B
aes_kek_generation_source = 4d870986c45d20722fba1053da92e8a9
aes_key_generation_source = 89615ee05c31b6805fe58f3da24f7aa8
bis_kek_source = 34c1a0c48258f8b4fa9e5e6adafc7e4f
eticket_rsa_kek = 19c8b441d318802bad63a5beda283a84
eticket_rsa_kek_source = dba451124ca0a9836814f5ed95e3125b
eticket_rsa_kekek_source = 466e57b74a447f02f321cde58f2f5535
header_kek_source = 1f12913a4acbf00d4cde3af6d523882a
header_key = aeaab1ca08adf9bef12991f369e3c567d6881e4e4a6a47a51f6e4877062d542d
header_key_source = 5a3ed84fdec0d82631f7e25d197bf5d01c9b7bfaf628183d71f64d73f150b9d2
key_area_key_application_00 = ef979e289a132c23d39c4ec5a0bba969
key_area_key_application_01 = cdedbab97b69729073dfb2440bff2c13
key_area_key_application_02 = 75716ed3b524a01dfe21456ce26c7270
key_area_key_application_03 = f428306544cf5707c25eaa8bc0583fd1
key_area_key_application_04 = 798844ec099eb6a04b26c7c728a35a4d
key_area_key_application_05 = a57c6eecc5410ada22712eb3ccbf45f1
key_area_key_application_06 = 2a60f6c4275df1770651d5891b8e73ec
key_area_key_application_07 = 32221bd6ed19b938bec06b9d36ed9e51
key_area_key_application_08 = fb20aa9e3dbf67350e86479eb431a0b3
key_area_key_application_09 = ce8d5fa79e220d5f48470e9f21be018b
key_area_key_application_source = 7f59971e629f36a13098066f2144c30d
key_area_key_ocean_00 = b33813e4c9c4399c75fabc673ab4947b
key_area_key_ocean_01 = c54166efa8c9c0f6511fa8b580191677
key_area_key_ocean_02 = 3061ce73461e0b0409d6a33da85843c8
key_area_key_ocean_03 = 06f170025a64921c849df168e74d37f2
key_area_key_ocean_04 = dc857fd6dc1c6213076ec7b902ec5bb6
key_area_key_ocean_05 = 131d76b70bd8a60036d8218c15cb610f
key_area_key_ocean_06 = 17d565492ba819b0c19bed1b4297b659
key_area_key_ocean_07 = 37255186f7678324bf2b2d773ea2c412
key_area_key_ocean_08 = 4115c119b7bd8522ad63c831b6c816a6
key_area_key_ocean_09 = 792bfc652870cca7491d1685384be147
key_area_key_ocean_source = 327d36085ad1758dab4e6fbaa555d882
key_area_key_system_00 = 6dd02aa15b440d6231236b6677de86bc
key_area_key_system_01 = 4ab155e7f29a292037fd147592770b12
key_area_key_system_02 = b7a74adeaf89c2a198c327bdff322d7d
key_area_key_system_03 = d5aab1acd23a8aec284a316df859d377
key_area_key_system_04 = 9b44b45b37de9d14754b1d22c2ca742c
key_area_key_system_05 = 0012e957530d3dc7af34fbbe6fd44559
key_area_key_system_06 = 01744e3b0818445cd54ee9f89da43192
key_area_key_system_07 = d0d30e46f5695b875f11522c375c5a80
key_area_key_system_08 = bd06cb1b86bd5c433667470a09eb63de
key_area_key_system_09 = e19f788f658eda8bbf34a1dd2a9503a9
key_area_key_system_source = 8745f1bba6be79647d048ba67b5fda4a
keyblob_00 = f759024f8199101dddc1ef91e6eecf37e24b95ac9272f7ae441d5d8060c843a48322d21cdd06d4fc958c68d3800eb4db939ffbec930177f77d136144ff615aa8835e811bb958deda218f8486b5a10f531b30cb9d269645ac9fc25c53fc80525e56bd3602988a9fcf06bbf99ca910ad6530791d512c9d57e17abf49220de6419bf4eca1685c1e4df77f19db7b44a985ca
keyblob_01 = bd27264ae07e979756411d0c66e679e3c50851f3e902d9c2cd1a438b948159a517ec1566c10570326ea2697ee62da46f14bb5d581bfc06fd0c9387ea33d2d4dc63e7809ba90f03dd2c7112ffbfa548951b9b8c688b5e4f2951d24a73da29c668154a5d4838dba71ee068ace83fe720e8c2a495c596f73525dc3c05994b40ad27f8c60322f75cd548b821af9162e16f76
keyblob_02 = a3d4a8e153b8e6ae6e6aef3e8f219cb4b7790f47856accc76268f9afa99a1ff8b1a72f63d1f99f480a3c1532078bb59abdd25203cfb12a38b33e9ba6a09afb6f24283b3ba76a0161230a73669ddf5493c2b7919d094fd795b484794854f71e4f4c672245d7770e29397722444d111b4229cdbf35707b70634ea8f140766e884cc580cb1e2d9aa9866ffef920010fc409
keyblob_03 = 1558f525ae8c5be9243fb6d8a8b0a8ee0e886a59035668740a936619b7a5c83e821198b171d18e51445054df68688e45703b936818a827d8e540dd6bef2e11ec9ddc6cfe5fc736dd769b9f6e0a23a62e2e5f49e86143646a04ec3a23f828373a336a5c224a91f8a0c6c6a7b5844dd6415804209f83c943aeca9cfd856db6bd4ec32009c8cb268ed053052c9237dfd8bc
keyblob_04 = 9fbeb1957fc1629e08b753a9086d6e01ffb4f11466b7417e3fa7f5f1efb754406704fd75afaf91a408a0b524c1fc80d36c2046fa4757412efe4c11e382f72e8a10d90ed580017d9deb87af2549b6b02661af48ff94f6072c0fef7fc2833b8bdae503898e2e927ac0663e8b6391dd4f1d685313935e2c48ece7d177c88bc9c883ede36c3677495784b838d7265c6ba7a1
keyblob_05 = 94a92da1d73c2b3e165c891ced5607fc6628ca2a0654f3fbc05711c063377c6e9c96a9d0192e530dd510e4fd41aa62ef4213c5f6e059e7e21db098a9b22d1e6c29bee148aaef15c52549d9165de96e85b0d029ecdc5843e2f32cb18be707eec61909cf3385d45bc2a4c8d76e9bfad5a40c4b92dcb982aa50d474897ac9ebb5351a7015dcc277a08f1214ad41384d7941
keyblob_key_00 = 4f5a86ec7c47b6b8663e0bbc199dcafa
keyblob_key_01 = 746c6b5e8f62b3f418ade81ddcde7619
keyblob_key_02 = 1b24583f656650fc214bf2b59d8de0fd
keyblob_key_03 = 71a7924e6c03baac7f2b99fac10c6201
keyblob_key_04 = 8f91661e8fc6ff81930ddea915ced49d
keyblob_key_05 = e1e960a7edf905dcd3b125d8377f7600
keyblob_key_source_00 = df206f594454efdc7074483b0ded9fd3
keyblob_key_source_01 = 0c25615d684ceb421c2379ea822512ac
keyblob_key_source_02 = 337685ee884aae0ac28afd7d63c0433b
keyblob_key_source_03 = 2d1f4880edeced3e3cf248b5657df7be
keyblob_key_source_04 = bb5a01f988aff5fc6cff079e133c3980
keyblob_key_source_05 = d8cce1266a353fcc20f32d3b517de9c0
keyblob_mac_key_00 = c98dd8afff06306bc72495e8c89eed4a
keyblob_mac_key_01 = 240d461913b37f6bc74027001581542c
keyblob_mac_key_02 = f4915b454f3a03661955cf4579d59876
keyblob_mac_key_03 = 323a27241392a8cad2b3c87086b211d2
keyblob_mac_key_04 = 5620355b2d504e4af5bd5cde9875b035
keyblob_mac_key_05 = c08712b1e1ff64f9e66fb6298ba27d6b
keyblob_mac_key_source = 59c7fb6fbe9bbe87656b15c0537336a5
master_kek_00 = f759024f8199101dddc1ef91e6eecf37
master_kek_01 = bd27264ae07e979756411d0c66e679e3
master_kek_02 = a3d4a8e153b8e6ae6e6aef3e8f219cb4
master_kek_03 = 1558f525ae8c5be9243fb6d8a8b0a8ee
master_kek_04 = 9fbeb1957fc1629e08b753a9086d6e01
master_kek_05 = 94a92da1d73c2b3e165c891ced5607fc
master_kek_source_06 = 374b772959b4043081f6e58c6d36179a
master_kek_source_07 = 9a3ea9abfd56461c9bf6487f5cfa095c
master_kek_source_08 = dedce339308816f8ae97adec642d4141
master_kek_source_09 = 1aec11822b32387a2bedba01477e3b67
master_key_00 = c2caaff089b9aed55694876055271c7d
master_key_01 = 54e1b8e999c2fd16cd07b66109acaaa6
master_key_02 = 4f6b10d33072af2f250562bff06b6da3
master_key_03 = 84e04ec20b9373818c540829cf147f3d
master_key_04 = cfa2176790a53ff74974bff2af180921
master_key_05 = c1dbedcebf0dd6956079e506cfa1af6e
master_key_06 = 0aa90e6330cdc12d819b3254d11a4e1e
master_key_07 = 929f86fbfe4ef7732892bf3462511b0e
master_key_08 = 23cfb792c3cb50cd715da0f84880c877
master_key_09 = 75c93b716255319b8e03e14c19dea64e
master_key_10 = 73767484C73088F629B0EEB605F64AA6
master_key_source = d8a2410ac6c59001c61d6a267c513f3c
package1_key_00 = f4eca1685c1e4df77f19db7b44a985ca
package1_key_01 = f8c60322f75cd548b821af9162e16f76
package1_key_02 = c580cb1e2d9aa9866ffef920010fc409
package1_key_03 = c32009c8cb268ed053052c9237dfd8bc
package1_key_04 = ede36c3677495784b838d7265c6ba7a1
package1_key_05 = 1a7015dcc277a08f1214ad41384d7941
package2_key_00 = a35a19cb14404b2f4460d343d178638d
package2_key_01 = a0dd1eacd438610c85a191f02c1db8a8
package2_key_02 = 7e5ba2aafd57d47a85fd4a57f2076679
package2_key_03 = bf03e9889fa18f0d7a55e8e9f684323d
package2_key_04 = 09df6e361e28eb9c96c9fa0bfc897179
package2_key_05 = 444b1a4f9035178b9b1fe262462acb8e
package2_key_06 = 442cd9c21cfb8914587dc12e8e7ed608
package2_key_07 = 70c821e7d6716feb124acbac09f7b863
package2_key_08 = 8accebcc3d15a328a48365503f8369b6
package2_key_09 = f562a7c6c42e3d4d3d13ffd504d77346
package2_key_source = fb8b6a9c7900c849efd24d854d30a0c7
per_console_key_source = 4f025f0eb66d110edc327d4186c2f478
retail_specific_aes_key_source = e2d6b87a119cb880e822888a46fba195
rsa_oaep_kek_generation_source = a8ca938434127fda82cc1aa5e807b112
rsa_private_kek_generation_source = ef2cb61a56729b9157c38b9316784ddd
save_mac_kek_source = d89c236ec9124e43c82b038743f9cf1b
save_mac_key = 536b210e185bccae8e36c622891bf7f6
save_mac_key_source = e4cd3d4ad50f742845a487e5a063ea1f
sd_card_kek_source = 88358d9c629ba1a00147dbe0621b5432
sd_card_nca_key_source = 5841a284935b56278b8e1fc518e99f2b67c793f0f24fded075495dca006d99c2
sd_card_save_key_source = 2449b722726703a81965e6e3ea582fdd9a951517b16e8f7f1f68263152ea296a
sd_seed = fd324d2dcf64f196f78b83f66786f71d
secure_boot_key = 9add3555ee6479259837e9e4eb42286d
ssl_rsa_kek = b011100660d1dccbad1b1b733afa9f95
ssl_rsa_kek_source_x = 7f5bb0847b25aa67fac84be23d7b6903
ssl_rsa_kek_source_y = 9a383bf431d0bd8132534ba964397de3
titlekek_00 = 62a24d6e6d0d0e0abf3554d259be3dc9
titlekek_01 = 8821f642176969b1a18021d2665c0111
titlekek_02 = 5d15b9b95a5739a0ac9b20f600283962
titlekek_03 = 1b3f63bcb67d4b06da5badc7d89acce1
titlekek_04 = e45c1789a69c7afbbf1a1e61f2499459
titlekek_05 = ddc67f7189f4527a37b519cb051eee21
titlekek_06 = b1532b9d38ab036068f074c0d78706ac
titlekek_07 = 81dc1b1783df268789a6a0edbf058343
titlekek_08 = 47dfe4bf0eeda88b17136b8005ab08ea
titlekek_09 = adaa785d90e1a9c182ac07bc276bf600
titlekek_source = 1edc7b3b60e6b4d878b81715985e629b
tsec_key = 06d4c3db4a0c6692ffab54b2c70b6935
aes_kek_generation_source = 4d870986c45d20722fba1053da92e8a9
aes_key_generation_source = 89615ee05c31b6805fe58f3da24f7aa8
bis_kek_source = 34c1a0c48258f8b4fa9e5e6adafc7e4f
eticket_rsa_kek = 19c8b441d318802bad63a5beda283a84
eticket_rsa_kek_source = dba451124ca0a9836814f5ed95e3125b
eticket_rsa_kekek_source = 466e57b74a447f02f321cde58f2f5535
header_kek_source = 1f12913a4acbf00d4cde3af6d523882a
header_key = aeaab1ca08adf9bef12991f369e3c567d6881e4e4a6a47a51f6e4877062d542d
header_key_source = 5a3ed84fdec0d82631f7e25d197bf5d01c9b7bfaf628183d71f64d73f150b9d2
key_area_key_application_00 = ef979e289a132c23d39c4ec5a0bba969
key_area_key_application_01 = cdedbab97b69729073dfb2440bff2c13
key_area_key_application_02 = 75716ed3b524a01dfe21456ce26c7270
key_area_key_application_03 = f428306544cf5707c25eaa8bc0583fd1
key_area_key_application_04 = 798844ec099eb6a04b26c7c728a35a4d
key_area_key_application_05 = a57c6eecc5410ada22712eb3ccbf45f1
key_area_key_application_06 = 2a60f6c4275df1770651d5891b8e73ec
key_area_key_application_07 = 32221bd6ed19b938bec06b9d36ed9e51
key_area_key_application_08 = fb20aa9e3dbf67350e86479eb431a0b3
key_area_key_application_09 = ce8d5fa79e220d5f48470e9f21be018b
key_area_key_application_source = 7f59971e629f36a13098066f2144c30d
key_area_key_ocean_00 = b33813e4c9c4399c75fabc673ab4947b
key_area_key_ocean_01 = c54166efa8c9c0f6511fa8b580191677
key_area_key_ocean_02 = 3061ce73461e0b0409d6a33da85843c8
key_area_key_ocean_03 = 06f170025a64921c849df168e74d37f2
key_area_key_ocean_04 = dc857fd6dc1c6213076ec7b902ec5bb6
key_area_key_ocean_05 = 131d76b70bd8a60036d8218c15cb610f
key_area_key_ocean_06 = 17d565492ba819b0c19bed1b4297b659
key_area_key_ocean_07 = 37255186f7678324bf2b2d773ea2c412
key_area_key_ocean_08 = 4115c119b7bd8522ad63c831b6c816a6
key_area_key_ocean_09 = 792bfc652870cca7491d1685384be147
key_area_key_ocean_source = 327d36085ad1758dab4e6fbaa555d882
key_area_key_system_00 = 6dd02aa15b440d6231236b6677de86bc
key_area_key_system_01 = 4ab155e7f29a292037fd147592770b12
key_area_key_system_02 = b7a74adeaf89c2a198c327bdff322d7d
key_area_key_system_03 = d5aab1acd23a8aec284a316df859d377
key_area_key_system_04 = 9b44b45b37de9d14754b1d22c2ca742c
key_area_key_system_05 = 0012e957530d3dc7af34fbbe6fd44559
key_area_key_system_06 = 01744e3b0818445cd54ee9f89da43192
key_area_key_system_07 = d0d30e46f5695b875f11522c375c5a80
key_area_key_system_08 = bd06cb1b86bd5c433667470a09eb63de
key_area_key_system_09 = e19f788f658eda8bbf34a1dd2a9503a9
key_area_key_system_source = 8745f1bba6be79647d048ba67b5fda4a
keyblob_00 = f759024f8199101dddc1ef91e6eecf37e24b95ac9272f7ae441d5d8060c843a48322d21cdd06d4fc958c68d3800eb4db939ffbec930177f77d136144ff615aa8835e811bb958deda218f8486b5a10f531b30cb9d269645ac9fc25c53fc80525e56bd3602988a9fcf06bbf99ca910ad6530791d512c9d57e17abf49220de6419bf4eca1685c1e4df77f19db7b44a985ca
keyblob_01 = bd27264ae07e979756411d0c66e679e3c50851f3e902d9c2cd1a438b948159a517ec1566c10570326ea2697ee62da46f14bb5d581bfc06fd0c9387ea33d2d4dc63e7809ba90f03dd2c7112ffbfa548951b9b8c688b5e4f2951d24a73da29c668154a5d4838dba71ee068ace83fe720e8c2a495c596f73525dc3c05994b40ad27f8c60322f75cd548b821af9162e16f76
keyblob_02 = a3d4a8e153b8e6ae6e6aef3e8f219cb4b7790f47856accc76268f9afa99a1ff8b1a72f63d1f99f480a3c1532078bb59abdd25203cfb12a38b33e9ba6a09afb6f24283b3ba76a0161230a73669ddf5493c2b7919d094fd795b484794854f71e4f4c672245d7770e29397722444d111b4229cdbf35707b70634ea8f140766e884cc580cb1e2d9aa9866ffef920010fc409
keyblob_03 = 1558f525ae8c5be9243fb6d8a8b0a8ee0e886a59035668740a936619b7a5c83e821198b171d18e51445054df68688e45703b936818a827d8e540dd6bef2e11ec9ddc6cfe5fc736dd769b9f6e0a23a62e2e5f49e86143646a04ec3a23f828373a336a5c224a91f8a0c6c6a7b5844dd6415804209f83c943aeca9cfd856db6bd4ec32009c8cb268ed053052c9237dfd8bc
keyblob_04 = 9fbeb1957fc1629e08b753a9086d6e01ffb4f11466b7417e3fa7f5f1efb754406704fd75afaf91a408a0b524c1fc80d36c2046fa4757412efe4c11e382f72e8a10d90ed580017d9deb87af2549b6b02661af48ff94f6072c0fef7fc2833b8bdae503898e2e927ac0663e8b6391dd4f1d685313935e2c48ece7d177c88bc9c883ede36c3677495784b838d7265c6ba7a1
keyblob_05 = 94a92da1d73c2b3e165c891ced5607fc6628ca2a0654f3fbc05711c063377c6e9c96a9d0192e530dd510e4fd41aa62ef4213c5f6e059e7e21db098a9b22d1e6c29bee148aaef15c52549d9165de96e85b0d029ecdc5843e2f32cb18be707eec61909cf3385d45bc2a4c8d76e9bfad5a40c4b92dcb982aa50d474897ac9ebb5351a7015dcc277a08f1214ad41384d7941
keyblob_key_00 = 4f5a86ec7c47b6b8663e0bbc199dcafa
keyblob_key_01 = 746c6b5e8f62b3f418ade81ddcde7619
keyblob_key_02 = 1b24583f656650fc214bf2b59d8de0fd
keyblob_key_03 = 71a7924e6c03baac7f2b99fac10c6201
keyblob_key_04 = 8f91661e8fc6ff81930ddea915ced49d
keyblob_key_05 = e1e960a7edf905dcd3b125d8377f7600
keyblob_key_source_00 = df206f594454efdc7074483b0ded9fd3
keyblob_key_source_01 = 0c25615d684ceb421c2379ea822512ac
keyblob_key_source_02 = 337685ee884aae0ac28afd7d63c0433b
keyblob_key_source_03 = 2d1f4880edeced3e3cf248b5657df7be
keyblob_key_source_04 = bb5a01f988aff5fc6cff079e133c3980
keyblob_key_source_05 = d8cce1266a353fcc20f32d3b517de9c0
keyblob_mac_key_00 = c98dd8afff06306bc72495e8c89eed4a
keyblob_mac_key_01 = 240d461913b37f6bc74027001581542c
keyblob_mac_key_02 = f4915b454f3a03661955cf4579d59876
keyblob_mac_key_03 = 323a27241392a8cad2b3c87086b211d2
keyblob_mac_key_04 = 5620355b2d504e4af5bd5cde9875b035
keyblob_mac_key_05 = c08712b1e1ff64f9e66fb6298ba27d6b
keyblob_mac_key_source = 59c7fb6fbe9bbe87656b15c0537336a5
master_kek_00 = f759024f8199101dddc1ef91e6eecf37
master_kek_01 = bd27264ae07e979756411d0c66e679e3
master_kek_02 = a3d4a8e153b8e6ae6e6aef3e8f219cb4
master_kek_03 = 1558f525ae8c5be9243fb6d8a8b0a8ee
master_kek_04 = 9fbeb1957fc1629e08b753a9086d6e01
master_kek_05 = 94a92da1d73c2b3e165c891ced5607fc
master_kek_source_06 = 374b772959b4043081f6e58c6d36179a
master_kek_source_07 = 9a3ea9abfd56461c9bf6487f5cfa095c
master_kek_source_08 = dedce339308816f8ae97adec642d4141
master_kek_source_09 = 1aec11822b32387a2bedba01477e3b67
master_key_00 = c2caaff089b9aed55694876055271c7d
master_key_01 = 54e1b8e999c2fd16cd07b66109acaaa6
master_key_02 = 4f6b10d33072af2f250562bff06b6da3
master_key_03 = 84e04ec20b9373818c540829cf147f3d
master_key_04 = cfa2176790a53ff74974bff2af180921
master_key_05 = c1dbedcebf0dd6956079e506cfa1af6e
master_key_06 = 0aa90e6330cdc12d819b3254d11a4e1e
master_key_07 = 929f86fbfe4ef7732892bf3462511b0e
master_key_08 = 23cfb792c3cb50cd715da0f84880c877
master_key_09 = 75c93b716255319b8e03e14c19dea64e
master_key_0a = 73767484C73088F629B0EEB605F64AA6
master_key_source = d8a2410ac6c59001c61d6a267c513f3c
package1_key_00 = f4eca1685c1e4df77f19db7b44a985ca
package1_key_01 = f8c60322f75cd548b821af9162e16f76
package1_key_02 = c580cb1e2d9aa9866ffef920010fc409
package1_key_03 = c32009c8cb268ed053052c9237dfd8bc
package1_key_04 = ede36c3677495784b838d7265c6ba7a1
package1_key_05 = 1a7015dcc277a08f1214ad41384d7941
package2_key_00 = a35a19cb14404b2f4460d343d178638d
package2_key_01 = a0dd1eacd438610c85a191f02c1db8a8
package2_key_02 = 7e5ba2aafd57d47a85fd4a57f2076679
package2_key_03 = bf03e9889fa18f0d7a55e8e9f684323d
package2_key_04 = 09df6e361e28eb9c96c9fa0bfc897179
package2_key_05 = 444b1a4f9035178b9b1fe262462acb8e
package2_key_06 = 442cd9c21cfb8914587dc12e8e7ed608
package2_key_07 = 70c821e7d6716feb124acbac09f7b863
package2_key_08 = 8accebcc3d15a328a48365503f8369b6
package2_key_09 = f562a7c6c42e3d4d3d13ffd504d77346
package2_key_source = fb8b6a9c7900c849efd24d854d30a0c7
per_console_key_source = 4f025f0eb66d110edc327d4186c2f478
retail_specific_aes_key_source = e2d6b87a119cb880e822888a46fba195
rsa_oaep_kek_generation_source = a8ca938434127fda82cc1aa5e807b112
rsa_private_kek_generation_source = ef2cb61a56729b9157c38b9316784ddd
save_mac_kek_source = d89c236ec9124e43c82b038743f9cf1b
save_mac_key = 536b210e185bccae8e36c622891bf7f6
save_mac_key_source = e4cd3d4ad50f742845a487e5a063ea1f
sd_card_kek_source = 88358d9c629ba1a00147dbe0621b5432
sd_card_nca_key_source = 5841a284935b56278b8e1fc518e99f2b67c793f0f24fded075495dca006d99c2
sd_card_save_key_source = 2449b722726703a81965e6e3ea582fdd9a951517b16e8f7f1f68263152ea296a
sd_seed = fd324d2dcf64f196f78b83f66786f71d
secure_boot_key = 9add3555ee6479259837e9e4eb42286d
ssl_rsa_kek = b011100660d1dccbad1b1b733afa9f95
ssl_rsa_kek_source_x = 7f5bb0847b25aa67fac84be23d7b6903
ssl_rsa_kek_source_y = 9a383bf431d0bd8132534ba964397de3
titlekek_00 = 62a24d6e6d0d0e0abf3554d259be3dc9
titlekek_01 = 8821f642176969b1a18021d2665c0111
titlekek_02 = 5d15b9b95a5739a0ac9b20f600283962
titlekek_03 = 1b3f63bcb67d4b06da5badc7d89acce1
titlekek_04 = e45c1789a69c7afbbf1a1e61f2499459
titlekek_05 = ddc67f7189f4527a37b519cb051eee21
titlekek_06 = b1532b9d38ab036068f074c0d78706ac
titlekek_07 = 81dc1b1783df268789a6a0edbf058343
titlekek_08 = 47dfe4bf0eeda88b17136b8005ab08ea
titlekek_09 = adaa785d90e1a9c182ac07bc276bf600
titlekek_source = 1edc7b3b60e6b4d878b81715985e629b
tsec_key = 06d4c3db4a0c6692ffab54b2c70b6935
xci_header_key = 01C58FE7002D135AB29A3F69339574B1
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>2019 年终有感</title><link>https://time-friend.com/zh/archive/2019-year-end-reflections/</link><pubDate>Sun, 29 Dec 2019 21:29:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/2019-year-end-reflections/</guid><description>&lt;p&gt;今年可谓是充实的一年,进了新公司.一切的都变了,职场非常顺利.也很感谢自己的同事这一年里对我的帮助与启发.&lt;/p&gt;
&lt;p&gt;相对2018,是一个飞跃性的成长.越想越觉得应该早点来到这样的公司,充分展示自己.&lt;/p&gt;
&lt;p&gt;在新公司里把之前所有关于前端自动化的设想全部在公司全面落地.
微前端架构也在公司的后台管理系统上得到了真正的应用.
并且在基于Taro多端同构的应用上取得了一定的成绩.&lt;/p&gt;
&lt;h2 id="我的团队"&gt;我的团队&lt;/h2&gt;
&lt;p&gt;在公司做了几件漂亮事之后,我重新又开始带团队,这一次跟以往完全不一样.
大家磨合的很好,彻彻底底的感受到了合作的魅力.
最终大家的成绩都得到了公司的认可,都拿到了满意的绩效.&lt;/p&gt;
&lt;p&gt;接下来的三个月,我会推动可支持多端的组件库建设,一款真正可以支持 H5,微信小程序,RN的组件库.
大家对此都表示非常的积极,要是做成了,我觉得这是一个非常了不起的事情.
希望今年的第一季度可以有一个很好的结果.&lt;/p&gt;
&lt;h2 id="关于博客"&gt;关于博客&lt;/h2&gt;
&lt;p&gt;今年可能更新博客不是特别频繁,最主要的原因还是忙(懒).
本来想好好介绍一下我们的自动化方案,还有一些多端同构方面的探索与沉淀的.
最终还是没有写出来.2020年的话,还是要把这些沉淀与思考输出出来最好.&lt;/p&gt;
&lt;h2 id="关于技术"&gt;关于技术&lt;/h2&gt;
&lt;p&gt;今年的技术,都是对去年设想真正的落地,包括微前端,自动化,多端同构方面.
但是最近我一直问自己,如何做到1个人干十个人的活.
一直问一直问,就总会有很多想法冒出来,不管是低代码也好,D2C也好都是非常好的提效工具.&lt;/p&gt;
&lt;p&gt;近期团队开始对Taro的D2C开始探索,初步算了一下.编写UI代码的最大可以提升12倍.
用D2C的方式去构建多端应用的话,很多的样式问题可以机械化的解决,这样大家说不定都可以直接忽略样式在多端之间的差异.
并且基于设计稿,可以一分钟写一个页面.这对团队来说是一个质的飞跃.
这是一个非常好的方向.&lt;/p&gt;
&lt;h2 id="关于2020"&gt;关于2020&lt;/h2&gt;
&lt;p&gt;该干的还是得继续干,有的同事还是在痴迷自动化方面得事情.&lt;/p&gt;
&lt;p&gt;我感觉就现在得团队来说,工程自动化再花很多心思去做的话,对于现在的收益是在递减的.&lt;/p&gt;
&lt;p&gt;因为现有的自动化架构已经完全满足现在的开发需要了.我想我们更多的是在其他地方下功夫.来做到团队效率的整体提升.&lt;/p&gt;
&lt;p&gt;2020年上半年,会跟设计部门合作一个对外网站,主要分享公司的技术与设计的沉淀.到时候就请大家拭目以待吧.&lt;/p&gt;</description></item><item><title>持续集成 - 代码质量扫描</title><link>https://time-friend.com/zh/archive/continuous-integration-code-quality-scanning/</link><pubDate>Sun, 15 Dec 2019 23:15:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/continuous-integration-code-quality-scanning/</guid><description>&lt;p&gt;为了方便管理公司的代码质量,让代码质量扫描跟持续集成结合到一起是重要的一步.
目前公司比较年轻,但是在短短的一年时间里,也有了接近300个前端项目.&lt;/p&gt;
&lt;p&gt;这么多的前端项目,我们如何保证代码质量就成了一个很重要的事情.&lt;/p&gt;
&lt;p&gt;代码项目太多,codereview是必要的.但是人肉codereview不能保证效率.
因为个人水平的差距,与公司规范的熟悉程度.不能保证所有项目的规范一致性.
还有一些潜在的bug也有可能会被漏掉.&lt;/p&gt;
&lt;p&gt;我们公司是基于Gitlab CI/CD,所以以下说明是基于Gitlab的方式.但是思路的运用是相通的,有需要的人可以借鉴思路.&lt;/p&gt;
&lt;h2 id="修改gitlab-ciyml"&gt;修改.gitlab-ci.yml&lt;/h2&gt;
&lt;p&gt;为了方便每一个项目接入,我们对配置做了很小的改动.
并且每一个项目的配置的修改都是一样的,就是为了方便无脑的复制粘贴.&lt;/p&gt;
&lt;p&gt;我们还做了一个cli工具,里面包含代码扫描的一切功能.安装在runner的机器上.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;image&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;node:11.10.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;stages&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;codereview&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 添加一个codereview的stage&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;codereview&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;stage&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;codereview&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;script&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;cli codereview&lt;/span&gt; &lt;span style="color:#75715e"&gt;# cli工具触发codereview&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;tags&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;fe&lt;/span&gt; &lt;span style="color:#75715e"&gt;#runner的tag,根据自己的情况自行修改&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="cli-触发代码扫描做什么"&gt;cli 触发代码扫描做什么?&lt;/h1&gt;
&lt;h2 id="执行sonarqube扫描"&gt;执行SonarQube扫描&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;关于SonarQube的安装,网上有很多教程请自行搜索.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;在执行runner的机器上安装 &lt;code&gt;sonar-scanner&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;npm i sonar-scanner -g
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="2"&gt;
&lt;li&gt;利用自研的cli工具,在项目根目录生成sonar 扫描的配置文件.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 获取gitlab 注入ci的环境变量
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;CI_PROJECT_NAME&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;CI_PROJECT_ID&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;} &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;process&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;env&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 基于gitlab的项目id生成一个sonar的projectKey
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;projectBuffer&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Buffer&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;from&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;sonar&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;CI_PROJECT_ID&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;projectKey&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;projectBuffer&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;toString&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;hex&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 检测代码目录
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 一般来说 src都是前端项目业务代码的目录
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//因为公司的nodejs项目是基于egg框架的,也有可能是app
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;existsSrc&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fs&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;existsSync&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;process&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;cwd&lt;/span&gt;()&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/src/`&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// sonar配置文件模板
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;sonarProject&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;sonar.projectKey=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;projectKey&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;sonar.projectName=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;CI_PROJECT_NAME&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;sonar.projectVersion=1.0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;sonar.sources=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;existsSrc&lt;/span&gt; &lt;span style="color:#f92672"&gt;?&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;src&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;app&amp;#39;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;sonar.binaries=bin
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;sonar.host.url=http://xxx.你部署sonar的服务地址.com 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;sonar.login=admin
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;sonar.password=admin
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;sonar.sourceEncoding=UTF-8
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 生成一个路径
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;sPath&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;resolve&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;process&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;cwd&lt;/span&gt;(), &lt;span style="color:#e6db74"&gt;&amp;#39;sonar-project.properties&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 写入sonar的配置
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fs&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;writeFileSync&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;sPath&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;sonarProject&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 执行sonar的代码扫描,并且上传代码质量报告
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;shelljs&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exec&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;sonar-scanner&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="执行jscpd分析代码重复率"&gt;执行jscpd分析代码重复率&lt;/h2&gt;
&lt;p&gt;尽管sonar已经提供了代码重复率的报告,但是并不是很容易看懂,到底代码哪里重复.
我们使用jscpd来分析项目的重复率.并且输出友好的报告.&lt;/p&gt;</description></item><item><title>FREE-TO-SHOT - 马</title><link>https://time-friend.com/zh/archive/horse-photo/</link><pubDate>Sat, 07 Dec 2019 21:32:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/horse-photo/</guid><description>&lt;p&gt;摄于 2019年12月7日 乌鲁木齐&lt;/p&gt;
&lt;p&gt;&lt;img src="https://tuchong.pstatp.com/1928176/f/484098812.jpg" alt="马"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://tuchong.pstatp.com/1928176/f/136103021.jpg" alt="马"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://tuchong.pstatp.com/1928176/f/589808781.jpg" alt="马"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://tuchong.pstatp.com/1928176/f/556778411.jpg" alt="马"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://tuchong.pstatp.com//1928176/f/311215253.jpg" alt="马"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://tuchong.pstatp.com/1928176/f/186630815.jpg" alt="马"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://tuchong.pstatp.com/1928176/f/81773594.jpg" alt="马"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://tuchong.pstatp.com/1928176/f/190497554.jpg" alt="马"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://tuchong.pstatp.com/1928176/f/494388088.jpg" alt="马"&gt;&lt;/p&gt;</description></item><item><title>持续集成 - 使用Gilab CI进行前端项目的持续集成</title><link>https://time-friend.com/zh/archive/continuous-integration-using-gitlab-ci-for-frontend-projects/</link><pubDate>Fri, 20 Sep 2019 23:15:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/continuous-integration-using-gitlab-ci-for-frontend-projects/</guid><description>&lt;p&gt;市面上的持续集成平台有很多,今天介绍Gitlab的CI.&lt;/p&gt;
&lt;p&gt;从Gitlab 8.0开始,Gitlab CI 就集成在了Gitlab中.&lt;/p&gt;
&lt;p&gt;使用方法非常简单,只要我们在项目的根目录创建一个 &lt;code&gt;.gitlab-ci.yml&lt;/code&gt;文件,添加一个Runner,就直接接入了Gitlab CI.&lt;/p&gt;
&lt;p&gt;接入方式非常的简单便捷.目前我们在前端脚手架中放一个&lt;code&gt;.gitlab-ci.yml&lt;/code&gt;文件,后续每一个前端项目都可以按照标准直接接入Gitlab CI.&lt;/p&gt;
&lt;h1 id="gitlab-runner"&gt;GitLab Runner&lt;/h1&gt;
&lt;p&gt;所有的Gitlab任务都会放在Gitlab Runner中执行.&lt;/p&gt;
&lt;p&gt;GitLab Runner的安装环境,根据你的需求而定,一个gitlab 可以注册的Runner是没有限制的.&lt;/p&gt;
&lt;p&gt;普通的前端项目直接安装在Linux中就可以了,如果是小程序或者RN这种项目,目前我是直接找了一台mac mini来安装Runner.&lt;/p&gt;
&lt;h2 id="gitlab-runner安装"&gt;GitLab Runner安装&lt;/h2&gt;
&lt;p&gt;安装Runner 非常简单, 这里晒出Gitlab的官方安装教程,你可以根据你的系统环境自行下载.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://docs.gitlab.com/runner/install/"&gt;安装Gitlab Runner 官方文档&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="注册runner"&gt;注册Runner&lt;/h2&gt;
&lt;p&gt;Runner安装好之后,想要关联到你的Gitlab,需要注册Runner.&lt;/p&gt;
&lt;p&gt;这里给大家介绍群组的runner注册方式,个人项目的runner方式注册基本一致&lt;/p&gt;
&lt;p&gt;&lt;a href="https://docs.gitlab.com/runner/register/"&gt;注册Gitlab Runner 官方文档&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;大致流程为:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;打开Gitlab网站,选择群组-&amp;gt; 设置-&amp;gt; CI/CD -&amp;gt; 展开Runner -&amp;gt; 你会看到注册Runner的Token与Url&lt;/li&gt;
&lt;li&gt;安装好Runner的机器上,运行 &lt;code&gt;sudo gitlab-runner register&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;输入 你Gitlab的 URL&lt;/li&gt;
&lt;li&gt;输入 Token&lt;/li&gt;
&lt;li&gt;输入 Runner 的名字&lt;/li&gt;
&lt;li&gt;选择 Runner 的类型,没有特殊需求直接选shell&lt;/li&gt;
&lt;li&gt;完成&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="配置runner"&gt;配置Runner&lt;/h2&gt;
&lt;p&gt;Runner的配置文件会以执行的用户身份不同而不同&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;当GitLab Runner以root身份执行时 &lt;code&gt;/etc/gitlab-runner/config.toml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;当GitLab Runner以非root身份执行时 &lt;code&gt;~/.gitlab-runner/config.toml&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="runner的全局配置"&gt;Runner的全局配置&lt;/h3&gt;
&lt;p&gt;这里我只说关键的两点&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;concurrent&lt;/code&gt; 配置会限制整个GitLab Runner能并发处理job的数量,如果你发现你的runner当前时间全局只能执行一个job的时候,
可以检查concurrent是否默认配置为1.不然多个job同一时段并发的时候,会造成job排队的现象.&lt;/p&gt;</description></item><item><title>前端微服务化进阶4 - 跨框架共享组件(微件化)</title><link>https://time-friend.com/zh/archive/micro-frontend-advanced-4-cross-framework-shared-components-widgetization/</link><pubDate>Sat, 22 Jun 2019 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/micro-frontend-advanced-4-cross-framework-shared-components-widgetization/</guid><description>&lt;p&gt;在微前端中,我们可以根据自己的业务需求,让子模块使用不同框架技术栈.虽然到了这一步已经很美好了,那这就是微前端的终点吗?&lt;/p&gt;
&lt;p&gt;答案是否定的,微前端的边界还可以更进一步的拓宽.&lt;/p&gt;
&lt;p&gt;上一篇微前端的文章 &lt;a href="https://time-friend.com/archive/qh7x5i5szfh/"&gt;https://time-friend.com/archive/qh7x5i5szfh/&lt;/a&gt; 给大家介绍了,如何在相同技术栈的子模块之间,相互调用React组件.&lt;/p&gt;
&lt;p&gt;那今天要说的就是,如何在不同技术栈之间的子模块相调用不同技术栈的组件.&lt;/p&gt;
&lt;p&gt;最终,我们只需要根据我们的需求调用相关功能的组件,我们不需要管他是 react ,vue或者是angular写的.&lt;/p&gt;
&lt;p&gt;你只管用,只知道他是一个组件就好了,不用关心太多~ 对于团队的组件积累,是有极大好处的.&lt;/p&gt;
&lt;h2 id="场景"&gt;场景&lt;/h2&gt;
&lt;p&gt;一般情况下,一个公司的前端团队的技术栈都是统一的.但也有前端团队使用不统一技术栈的时候.
比如:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;时代的变迁,升级技术栈导致内部技术栈不统一&lt;/li&gt;
&lt;li&gt;项目众多,因为需求不一致,其他的技术栈对于项目更加有力&lt;/li&gt;
&lt;li&gt;&amp;hellip;其他管理原因&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;当我们已经使用微前端架构来构建我们的项目的时候,我们的子模块有可能因为我们项目的需求导致使用了其他的技术栈,&lt;/p&gt;
&lt;p&gt;如果我们使用了其他的技术栈,我们原来封装的组件就不能在新的项目中用了,所以我们需要要求组件可以跨框架共享使用.&lt;/p&gt;
&lt;h2 id="我们该怎么做"&gt;我们该怎么做?&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://static.alili.tech/images/micro/microComponent.png" alt=""&gt;&lt;/p&gt;
&lt;p&gt;这里有提到微件仓库模块,这是一个单独的项目.你可以理解是以前的旧项目,当你需要这个旧项目的某一个组件的时候,可以直接从这个项目里面拿.&lt;/p&gt;
&lt;p&gt;你也可以做成一个只提供组件的项目,毕竟在运行时一个子模块挂载到我们的项目中来是没有任何资源消耗的.&lt;/p&gt;
&lt;p&gt;我们只要知道我们需要的组件从哪里来就行了,然后根据组件还有之前定义好的路由找到这个组件,调用他,使用他就好了.&lt;/p&gt;
&lt;h2 id="基于web-component封装我们的组件"&gt;基于Web component封装我们的组件&lt;/h2&gt;
&lt;p&gt;不同框架开发的组件,差异很大.想要串在一起使用,基本上是不可能的.
好在目前所有的框架都支持让组件以webcomponent的形式存在.&lt;/p&gt;
&lt;p&gt;react: &lt;a href="https://react.docschina.org/docs/web-components.html"&gt;https://react.docschina.org/docs/web-components.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;vue : &lt;a href="https://github.com/vuejs/vue-web-component-wrapper"&gt;https://github.com/vuejs/vue-web-component-wrapper&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;angular: &lt;a href="https://www.angular.cn/guide/elements#transforming-components-to-custom-elements"&gt;https://www.angular.cn/guide/elements#transforming-components-to-custom-elements&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="关于web-components-的详细介绍"&gt;关于Web Components 的详细介绍&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://developer.mozilla.org/zh-CN/docs/Web/Web_Components"&gt;https://developer.mozilla.org/zh-CN/docs/Web/Web_Components&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="加载性能"&gt;加载性能&lt;/h2&gt;
&lt;p&gt;如果一个页面依赖了很多跨框架的组件,必然出现网络方面的性能问题.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://static.alili.tech/images/micro/microComponent2.png" alt=""&gt;&lt;/p&gt;
&lt;p&gt;我们会在请求的中间加一层node服务,当页面请求多个跨框架的组件的时候,我们的node就会合并成单个文件,并且保存在硬盘上.&lt;/p&gt;
&lt;p&gt;所以说,当这个页面被请求过之后,页面零散的组件便会合并在一起,第二次其他用户请求就不会有这种合并文件的处理,直接返回静态资源给客户端.&lt;/p&gt;
&lt;p&gt;这种方式也不会对nodejs有太多额外的压力,&lt;/p&gt;
&lt;p&gt;因为现在的页面结构还是相对静态稳定的,没有太多的动态定制化的东西.这个方案足以应付大多数的应用场景.&lt;/p&gt;
&lt;h2 id="尾巴"&gt;尾巴&lt;/h2&gt;
&lt;p&gt;经过不停的探索,微前端终于走到了微件化的这一步,感慨颇多~&lt;/p&gt;
&lt;p&gt;我们从一个窗口只能加载单个页面,
再到多个页面(SPA),
再到现在的多个项目(微前端),
然后再可以控制不同组件在多个项目之间随意组合(微件化).&lt;/p&gt;
&lt;p&gt;微前端的应用边界应该还可以拓展的更宽,还可以开发出更多惊喜的操作.&lt;/p&gt;
&lt;h1 id="相关系列文章"&gt;相关系列文章&lt;/h1&gt;
&lt;p&gt;&lt;a href="https://time-friend.com/tags/microfrontend/"&gt;https://time-friend.com/tags/microfrontend/&lt;/a&gt;&lt;/p&gt;</description></item><item><title>前端微服务化进阶3 - 跨模块共享组件</title><link>https://time-friend.com/zh/archive/micro-frontend-advanced-3-cross-module-shared-components/</link><pubDate>Sun, 12 May 2019 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/micro-frontend-advanced-3-cross-module-shared-components/</guid><description>&lt;p&gt;前端微服务化之后,我们会面临一个问题: 模块之间重复代码不能复用的问题.&lt;/p&gt;
&lt;p&gt;如果使用npm管理我们的重复代码,我们会多出维护npm包的成本.
在子模块更新npm包版本,也是一件很麻烦的事情.
在js文件体积上也没有任何的优化.&lt;/p&gt;
&lt;h1 id="组件共享"&gt;组件共享&lt;/h1&gt;
&lt;p&gt;今天我们就来聊一聊如何在多个模块中同时使用一个组件.&lt;/p&gt;
&lt;h2 id="思路"&gt;思路&lt;/h2&gt;
&lt;p&gt;在base模块管理公共组件,将组件封装成动态组件,这样在打包的时候我们就可以将该组件切割成单独文件了.
当其他的子模块需要这个组件的时候,向Base模块动态获取.&lt;/p&gt;
&lt;h2 id="实践"&gt;实践&lt;/h2&gt;
&lt;h3 id="动态组件的封装"&gt;动态组件的封装&lt;/h3&gt;
&lt;p&gt;为了让其他模块可以按需加载我们的公共组件,我们需要对已有的组件封装成动态组件.&lt;/p&gt;
&lt;p&gt;我这里使用的是 &lt;code&gt;umi/dynamic&lt;/code&gt;,&lt;/p&gt;
&lt;p&gt;他是基于https://github.com/jamiebuilds/react-loadable 封装了一层.
有兴趣的小伙伴可以自行了解.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;React&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;react&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dynamic&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;umi/dynamic&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;PageLoading&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;@/components/PageLoading&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Demo&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dynamic&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt;( &lt;span style="color:#e6db74"&gt;`../Demo`&lt;/span&gt;), {&lt;span style="color:#a6e22e"&gt;loading&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; () =&amp;gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;PageLoading&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Demo&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="对外提供获取动态组件的方法"&gt;对外提供获取动态组件的方法&lt;/h3&gt;
&lt;p&gt;在加载Base模块的时候,我们可以在window下暴露一个调用该模块动态组件的方法&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;window.&lt;span style="color:#a6e22e"&gt;getDynamicComponent&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;component&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;component&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;import&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`@/components/dynamic/&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;component&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="子模块调用公共组件"&gt;子模块调用公共组件&lt;/h3&gt;
&lt;p&gt;因为base模块提供了一个获取公共组件的全局方法,
我们就可以在任何模块任何需要调用公共组件的地方去是使用它了.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 获取组件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;component&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; window.&lt;span style="color:#a6e22e"&gt;getDynamicComponent&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;Demo&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;为了方便这种公共组件的使用,我们可以将这一方法封装成一个组件.
在调用公共组件,我们只需要声明就好了.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;React&lt;/span&gt;, { &lt;span style="color:#a6e22e"&gt;Component&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;react&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Matrix 在黑客帝国中是母体的意思
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Matrix&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;extends&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Component&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;state&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;DynamicComponent&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;defaultProps&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;$name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;componentWillMount&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;renderComponent&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;componentWillReceiveProps&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;nextProps&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;props&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;nextProps&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;renderComponent&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;renderComponent&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;$name&lt;/span&gt; } &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;props&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;$name&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;component&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; window.&lt;span style="color:#a6e22e"&gt;getDynamicComponent&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;$name&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;setState&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;DynamicComponent&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;component&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;setState&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;DynamicComponent&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;render&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;DynamicComponent&lt;/span&gt; } &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;state&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 继承所有props
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;DynamicComponent&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;DynamicComponent&lt;/span&gt; {...&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;props&lt;/span&gt;} &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在实际页面中调用我们的公共组件&lt;/p&gt;</description></item><item><title>前端微服务化进阶2 - 本地开发指南</title><link>https://time-friend.com/zh/archive/micro-frontend-advanced-2-local-development-guide/</link><pubDate>Mon, 22 Apr 2019 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/micro-frontend-advanced-2-local-development-guide/</guid><description>&lt;p&gt;使用&lt;code&gt;single-spa&lt;/code&gt;构建我们的微服务化的前端应用之后,其实有一个问题会一直困扰着我们,
就是如何有效的开发?如何与我们平时开发的前端应用一样简单,容易上手.
今天就以umi子模块为例,希望给到大家一个思路&lt;/p&gt;
&lt;p&gt;今天我就介绍一种方法,希望对大家有帮助.&lt;/p&gt;
&lt;h2 id="模块加载器"&gt;模块加载器&lt;/h2&gt;
&lt;p&gt;是否还记得我之前的模块加载器, &lt;a href="https://time-friend.com/archive/1a60cede/"&gt;https://time-friend.com/archive/1a60cede/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;我们只需要将原来模块的加载器,封装成npm包.&lt;/p&gt;
&lt;p&gt;然后在我们开发子模块项目的时候,运行我们的加载器
&lt;img src="https://static.alili.tech/images/micro/localdev.png" alt=""&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// umi src/app.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bootstrap&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;@demo/demo-module-dev-loader&amp;#39;&lt;/span&gt; &lt;span style="color:#75715e"&gt;//封装过后的npm包
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;store&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;store&amp;#39;&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// 我们用于通讯的store文件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;render&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;oldRender&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;process&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;env&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;NODE_ENV&lt;/span&gt; &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;development&amp;#39;&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;oldRender&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; window.&lt;span style="color:#a6e22e"&gt;fetch&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./project.json&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;currentProject&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;json&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;bootstrap&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;store&lt;/span&gt;, 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;prefix&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;currentProject&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;prefix&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;oldRender&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="module-dev-loader"&gt;module-dev-loader&lt;/h2&gt;
&lt;p&gt;我们的demo-module-dev-loader里一样会有一个 Bootstrap.js文件,我们对他进行一些小的修改.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;as&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;singleSpa&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;single-spa&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;registerApp&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;registerLocal&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./Register&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bootstrap&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;local&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 拿到我们的项目配置文件,但是我们的本地是没有这个文件的.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 我们需要通过webpack代理到我们的线上测试环境,来拿到这个文件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 我们需要通过webpack代理到我们的线上测试环境,来拿到这个文件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 我们需要通过webpack代理到我们的线上测试环境,来拿到这个文件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 重要的事情说三遍
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;projectConfig&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; window.&lt;span style="color:#a6e22e"&gt;SystemJS&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;/project.config.js&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; window.&lt;span style="color:#a6e22e"&gt;fetch&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;/project.json&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;currentProject&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;json&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; {&lt;span style="color:#a6e22e"&gt;projects&lt;/span&gt;} &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;projectConfig&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 移除当前项目,因为当前项目会使用registerLocal方法注册
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;projects&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;projects&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;filter&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;ele&lt;/span&gt; =&amp;gt; &lt;span style="color:#a6e22e"&gt;ele&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#f92672"&gt;!==&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;currentProject&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 注册我们的线上测试环境的
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;index&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;index&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;projects&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;index&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;project&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;projects&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;index&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;registerApp&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;project&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;project&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;store&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;project&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;store&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;base&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;project&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;base&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;prefix&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;project&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;prefix&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 重点!!!
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 注册本地正在开发的模块
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;local&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;registerLocal&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;local&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;singleSpa&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;start&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="registerlocal-方法展示"&gt;registerLocal 方法展示&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Register.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 在原来registerApp上做了一些删减,大概的原理是一模一样的
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;registerLocal&lt;/span&gt;({&lt;span style="color:#a6e22e"&gt;base&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;prefix&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;store&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;local&amp;#39;&lt;/span&gt;}){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 导入store模块
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;storeModule&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {}, &lt;span style="color:#a6e22e"&gt;customProps&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;globalEventDistributor&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;globalEventDistributor&lt;/span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;storeModule&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;store&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;storeInstance&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 注册应用于事件派发器
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;storeModule&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;storeInstance&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;globalEventDistributor&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 取出 redux storeInstance
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;customProps&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;store&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;storeModule&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;storeInstance&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 注册到全局
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;globalEventDistributor&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;registerStore&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;storeModule&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;storeInstance&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;singleSpa&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;registerApplication&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; ()=&amp;gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;base&lt;/span&gt; &lt;span style="color:#f92672"&gt;?&lt;/span&gt; (() =&amp;gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;) &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;hashPrefix&lt;/span&gt;({&lt;span style="color:#a6e22e"&gt;prefix&lt;/span&gt;}),&lt;span style="color:#a6e22e"&gt;customProps&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 原来的registerApp方法,与以前一模一样,没有改动.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 为了方便对比registerLocal,所以列出来 供大家参考
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;registerApp&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 导入store模块
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;storeModule&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {}, &lt;span style="color:#a6e22e"&gt;customProps&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;globalEventDistributor&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;globalEventDistributor&lt;/span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 尝试导入store
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;try&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;storeModule&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;store&lt;/span&gt; &lt;span style="color:#f92672"&gt;?&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; window.&lt;span style="color:#a6e22e"&gt;SystemJS&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;store&lt;/span&gt;) &lt;span style="color:#f92672"&gt;:&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;storeInstance&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;} &lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;e&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`Could not load store of app &lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;.`&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;e&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//如果失败则不注册该模块
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 注册应用于事件派发器
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;storeModule&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;storeInstance&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;globalEventDistributor&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 取出 redux storeInstance
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;customProps&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;store&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;storeModule&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;storeInstance&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 注册到全局
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;globalEventDistributor&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;registerStore&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;storeModule&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;storeInstance&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;singleSpa&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;registerApplication&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; ()=&amp;gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; window.&lt;span style="color:#a6e22e"&gt;SystemJS&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;), &lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;base&lt;/span&gt; &lt;span style="color:#f92672"&gt;?&lt;/span&gt; (() =&amp;gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;) &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;hashPrefix&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;), &lt;span style="color:#a6e22e"&gt;customProps&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="umi插件"&gt;umi插件&lt;/h2&gt;
&lt;p&gt;我们的umi插件也需要修改&lt;/p&gt;</description></item><item><title>前端微服务化进阶1 - 基于umi的子模块方案</title><link>https://time-friend.com/zh/archive/micro-frontend-advanced-1-umi-based-submodule-solution/</link><pubDate>Sat, 13 Apr 2019 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/micro-frontend-advanced-1-umi-based-submodule-solution/</guid><description>&lt;p&gt;距离第一篇聊前端微服务的文章已经时隔大半年,很多人对此感兴趣.&lt;/p&gt;
&lt;p&gt;今天我们就聊一聊,我们如何基于umi来打造一个更完善的前端微服务的子模块.&lt;/p&gt;
&lt;p&gt;如果你用的是react以外的前端技术栈,
我的很多处理做法也可以应用在其他技术栈上.&lt;/p&gt;
&lt;p&gt;希望对你也有所帮助.&lt;/p&gt;
&lt;h1 id="优秀的umi框架"&gt;优秀的umi框架&lt;/h1&gt;
&lt;p&gt;在前端中后台项目上,前端微服务化的需求相对是比较旺盛一些的.&lt;/p&gt;
&lt;p&gt;说到中后台,很多企业都是基于antd的组件来构建自己的项目.&lt;/p&gt;
&lt;p&gt;自去年的&lt;code&gt;see conf&lt;/code&gt;之后,蚂蚁的一款&lt;code&gt;可插拔的企业级 react 应用框架&lt;/code&gt; umi发布了.&lt;/p&gt;
&lt;p&gt;这款框架与antd息息相关,antd结合umi使用那是相当的自然与流畅.&lt;/p&gt;
&lt;p&gt;可以说,基于umi与antd构建的项目非常的漂亮.这么优秀的框架,如果让他适用于我们的前端微服务架构,岂不美哉?&lt;/p&gt;
&lt;p&gt;umi也有相关的类似微服务方案: &lt;a href="https://github.com/umijs/umi-example-monorepo"&gt;https://github.com/umijs/umi-example-monorepo&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;但是umi提供的方案,有很大的局限性.
如果可以接入single-spa的微服务方案,独立开发,独立部署等等的前端微服务化红利,
会让你的项目日后有更大的发展空间.&lt;/p&gt;
&lt;h1 id="基于umi插件机制做到前端微服务化"&gt;基于umi插件机制做到前端微服务化&lt;/h1&gt;
&lt;p&gt;umi 提供了非常强大的插件机制,正是由于这一点,我们才可以让umi也可以接入到微服务架构中来&lt;/p&gt;
&lt;h2 id="umi插件介绍"&gt;umi插件介绍&lt;/h2&gt;
&lt;p&gt;umi插件的基本介绍:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://umijs.org/zh/plugin/"&gt;https://umijs.org/zh/plugin/&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="umi插件开发"&gt;umi插件开发&lt;/h2&gt;
&lt;p&gt;这里介绍了如何开发一个简单的umi插件:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://umijs.org/zh/plugin/develop.html"&gt;https://umijs.org/zh/plugin/develop.html&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="接入single-spa的umi插件"&gt;接入single-spa的umi插件&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;api&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;opts&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 以下的所有代码都写在这里面哦
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="渲染入口处理方法"&gt;渲染入口处理方法&lt;/h2&gt;
&lt;p&gt;定义一个动态的元素,当我们的base app 需要加载子模块的时候,会渲染出子模块需要渲染元素.&lt;/p&gt;
&lt;p&gt;我们的子模块找到了自己模块需要渲染的节点的时候,就会渲染出来.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;domElementGetterStr&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; function domElementGetter() {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; let el = document.getElementById(&amp;#39;submodule-page&amp;#39;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; if (!el) {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; el = document.createElement(&amp;#39;div&amp;#39;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; el.id = &amp;#39;submodule-page&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; let timer = null
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; timer = setInterval(() =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; if (document.querySelector(&amp;#39;#submoduleContent.submoduleContent&amp;#39;)) {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; document.querySelector(&amp;#39;#submoduleContent.submoduleContent&amp;#39;).appendChild(el)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; clearInterval(timer)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; timer = null
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; }, 100)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; return el
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; }`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="使用single-spa-react"&gt;使用single-spa-react&lt;/h2&gt;
&lt;p&gt;在umi的入口文件导入&lt;code&gt;single-spa-react&lt;/code&gt; ,根据模块的属性来判断模块在运行时是否渲染在root节点上还是指定节点&lt;/p&gt;</description></item><item><title>记一次MongoDB迁移 - 备份与恢复</title><link>https://time-friend.com/zh/archive/mongodb-migration-backup-and-restore/</link><pubDate>Wed, 27 Mar 2019 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/mongodb-migration-backup-and-restore/</guid><description>&lt;p&gt;最近对自己的的爬虫数据库做了一次迁移,所以在这里记录一下mongodb的备份与恢复&lt;/p&gt;
&lt;h2 id="mongodb数据备份"&gt;MongoDB数据备份&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mongodump -h dbhost -d dbname -o dbdirectory
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;-h： MongDB所在服务器地址，例如：127.0.0.1，如果没有改的话一般是：127.0.0.1:27017&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;-d： 需要备份的数据库名字，例如：test&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;-o： 备份的数据存放位置，例如：/home/root/xxx，&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="mongodb数据恢复"&gt;MongoDB数据恢复&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mongorestore -h &amp;lt;hostname&amp;gt;&amp;lt;:port&amp;gt; -d dbname &amp;lt;path&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&amp;ndash;host &amp;lt;:port&amp;gt;, -h &amp;lt;:port&amp;gt;： MongoDB所在服务器地址，默认为： localhost:27017&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;ndash;db , -d ： 需要备份的数据库名字，例如：test&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;ndash;drop： 先删除现有的数据,再恢复数据&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;path&gt;： 指定备份文件的目录&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;ndash;dir： 指定备份文件的目录,不能同时指定 &lt;path&gt; 和 &amp;ndash;dir 选项。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>一个两年前.gitattributes文件导致的bug</title><link>https://time-friend.com/zh/archive/gitattributes-bug-from-two-years-ago/</link><pubDate>Thu, 24 Jan 2019 19:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/gitattributes-bug-from-two-years-ago/</guid><description>&lt;h1 id="起因"&gt;起因&lt;/h1&gt;
&lt;p&gt;一时兴起,我打开了我两年前写的一个前端项目开始代码审查.
这个项目我一个人写了两年,大概十几万行代码的样子.&lt;/p&gt;
&lt;p&gt;发现这个项目的git居然把所有的代码文件都识别成了二进制文件.
这个问题,之前困扰了我很久,却一直找不到原因.导致我的代码没有对比记录.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;再顽固的问题也有水落石出的一天&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;说巧不巧,今天偏偏找到了问题的源头.&lt;/p&gt;
&lt;h1 id="gitattributes"&gt;.gitattributes&lt;/h1&gt;
&lt;p&gt;最后发现是因为&lt;code&gt;.gitattributes&lt;/code&gt;文件有一行配置因为换行问题.导致所有text的文件都识别成了二进制文件.&lt;/p&gt;
&lt;h2 id="gitattributes的作用"&gt;.gitattributes的作用&lt;/h2&gt;
&lt;p&gt;.gitattributes文件是一个简单的text文本文件，它的作用是重新定义指定文件的属性, 指定非文本文件的对比合并方式&lt;/p&gt;
&lt;h3 id="编写规则"&gt;编写规则&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;pattern attr1 attr2 ...
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="示例"&gt;示例&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;*.ttf binary
*.woff binary
*.eot binary
*.otf binary
* text=auto
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面这段代码表示,将一些字体文件指定为二进制文件,当提交代码的时候git不会diff这些文件的变动详情.
他只会告诉你,文件变动了,但是不会告诉你具体哪里变了.&lt;/p&gt;</description></item><item><title>LintCode 最长公共前缀</title><link>https://time-friend.com/zh/archive/lintcode-longest-common-prefix/</link><pubDate>Sat, 19 Jan 2019 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/lintcode-longest-common-prefix/</guid><description>&lt;p&gt;编写一个函数来查找字符串数组中的最长公共前缀。&lt;/p&gt;
&lt;p&gt;如果不存在公共前缀，返回空字符串 &amp;ldquo;&amp;quot;。&lt;/p&gt;
&lt;h2 id="示例-1"&gt;示例 1:&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;输入: [&amp;#34;flower&amp;#34;,&amp;#34;flow&amp;#34;,&amp;#34;flight&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;输出: &amp;#34;fl&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="示例-2"&gt;示例 2:&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;输入: [&amp;#34;dog&amp;#34;,&amp;#34;racecar&amp;#34;,&amp;#34;car&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;输出: &amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;解释: 输入不存在公共前缀。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;说明:&lt;/p&gt;
&lt;p&gt;所有输入只包含小写字母 a-z 。&lt;/p&gt;
&lt;h1 id="javascript"&gt;JavaScript&lt;/h1&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @param {string[]} strs
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @return {string}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;longestCommonPrefix&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;strs&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;strs&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt; &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;)&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;current&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;prefix&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;index&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;isTrue&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;strs&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;][&lt;span style="color:#a6e22e"&gt;index&lt;/span&gt;]) { &lt;span style="color:#75715e"&gt;//以第一个单词为基准
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;current&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;strs&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;][&lt;span style="color:#a6e22e"&gt;index&lt;/span&gt;]; &lt;span style="color:#75715e"&gt;// 以第一个单词为基准
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;strs&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;((&lt;span style="color:#a6e22e"&gt;strs&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;] &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;)[&lt;span style="color:#a6e22e"&gt;index&lt;/span&gt;] &lt;span style="color:#f92672"&gt;!==&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;current&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;isTrue&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;break&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;isTrue&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;index&lt;/span&gt; &lt;span style="color:#f92672"&gt;++&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;prefix&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;prefix&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;current&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;break&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;prefix&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>LintCode 买卖股票的最佳时机 II</title><link>https://time-friend.com/zh/archive/lintcode-best-time-to-buy-and-sell-stock-ii/</link><pubDate>Sat, 12 Jan 2019 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/lintcode-best-time-to-buy-and-sell-stock-ii/</guid><description>&lt;p&gt;给定一个数组，它的第 i 个元素是一支给定股票第 i 天的价格。&lt;/p&gt;
&lt;p&gt;设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易（多次买卖一支股票）。&lt;/p&gt;
&lt;p&gt;注意：你不能同时参与多笔交易（你必须在再次购买前出售掉之前的股票）。&lt;/p&gt;
&lt;h2 id="示例-1"&gt;示例 1:&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;输入: [7,1,5,3,6,4]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;输出: 7
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;解释: 在第 2 天（股票价格 = 1）的时候买入，在第 3 天（股票价格 = 5）的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;随后，在第 4 天（股票价格 = 3）的时候买入，在第 5 天（股票价格 = 6）的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="示例-2"&gt;示例 2:&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;输入: [1,2,3,4,5]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;输出: 4
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;解释: 在第 1 天（股票价格 = 1）的时候买入，在第 5 天 （股票价格 = 5）的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 注意你不能在第 1 天和第 2 天接连购买股票，之后再将它们卖出。
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 因为这样属于同时参与了多笔交易，你必须在再次购买前出售掉之前的股票。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="示例-3"&gt;示例 3:&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;输入: [7,6,4,3,1]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;输出: 0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="javascript"&gt;JavaScript&lt;/h1&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @param {number[]} prices
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * @return {number}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;maxProfit&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;prices&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;n&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;prices&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;forEach&lt;/span&gt;((&lt;span style="color:#a6e22e"&gt;element&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;index&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;element&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;prices&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;index&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;]){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;n&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;prices&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;index&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;] &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;element&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;n&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;n&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Canvas 处理跨域图片终极方案</title><link>https://time-friend.com/zh/archive/canvas-cross-origin-image/</link><pubDate>Thu, 10 Jan 2019 16:14:25 +0000</pubDate><guid>https://time-friend.com/zh/archive/canvas-cross-origin-image/</guid><description>&lt;p&gt;浏览器因为安全问题,是不允许Canvas使用 &lt;code&gt;getImageData``toDataURL&lt;/code&gt; 处理跨域获取的图片的.&lt;/p&gt;
&lt;h1 id="传统解决方法"&gt;传统解决方法&lt;/h1&gt;
&lt;h2 id="1服务器需要配置access-control-allow-origin"&gt;1.服务器需要配置Access-Control-Allow-Origin&lt;/h2&gt;
&lt;p&gt;相信这一行代码,大家见过太多,我就赘述了&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;header(&amp;#34;Access-Control-Allow-Origin: 你的域名&amp;#34;);
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="2设置crossorigin属性"&gt;2.设置crossOrigin属性&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;canvas&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; document.&lt;span style="color:#a6e22e"&gt;createElement&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;canvas&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;context&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;canvas&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getContext&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;2d&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;img&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Image&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;img&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;crossOrigin&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;anonymous&amp;#39;&lt;/span&gt;; &lt;span style="color:#75715e"&gt;//就是这行代码
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;img&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;onload&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; () {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;context&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;drawImage&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;context&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getImageData&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;width&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;height&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;img&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;src&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;https://avatars3.xxxx.com/u/496048&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;到这里,你的跨域问题已经基本解决. 但是因为一些客观因素后端工程师拒绝帮你设置跨域头,那你该怎么办?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;终极解决方案&lt;/p&gt;
&lt;p&gt;大致思路是 使用ajax获取到图片,然后使用 &lt;code&gt;FileReader&lt;/code&gt;转成base64;再使用canvas处理base64格式的图片就好了.&lt;/p&gt;
&lt;h2 id="获取图片的base64"&gt;获取图片的base64&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getBase64&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;imgUrl&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Promise(((&lt;span style="color:#a6e22e"&gt;resolve&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;reject&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; window.&lt;span style="color:#a6e22e"&gt;URL&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; window.&lt;span style="color:#a6e22e"&gt;URL&lt;/span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; window.&lt;span style="color:#a6e22e"&gt;webkitURL&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 声明一个XMLHttpRequest
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;xhr&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;XMLHttpRequest&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 获取图片
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;xhr&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;open&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;get&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;imgUrl&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;xhr&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;responseType&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;blob&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;xhr&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;send&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;xhr&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;onload&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; () {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;status&lt;/span&gt; &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;200&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 得到一个blob对象
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;blob&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;response&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;oFileReader&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;FileReader&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;oFileReader&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;onloadend&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;e&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;base64&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;e&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;target&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;result&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//拿到base64 传出结果
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;resolve&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;base64&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;oFileReader&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;onerror&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;e&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;reject&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;oFileReader&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;readAsDataURL&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;blob&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="canvas-操作图片"&gt;Canvas 操作图片&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;base64&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getBase64&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;imgSrc&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;img&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Image&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;img&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;src&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;base64&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// canvas 处理
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;canvas&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; document.&lt;span style="color:#a6e22e"&gt;createElement&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;canvas&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;context&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;canvas&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getContext&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;2d&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;img&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;onload&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; () =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;context&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;drawImage&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;context&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getImageData&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;width&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;height&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;今天就到这里&lt;/p&gt;</description></item><item><title>Git大小写不敏感导致的烦人问题</title><link>https://time-friend.com/zh/archive/git-case-insensitive-issue/</link><pubDate>Wed, 09 Jan 2019 19:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/git-case-insensitive-issue/</guid><description>&lt;blockquote&gt;
&lt;p&gt;因为同事把一个文件夹的小写改成了大写,导致我本地的提交不能直接push rebase 等一些列操作.恼的很~&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;error: The following untracked working tree files would be overwritten by checkout:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; xxx.js
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Please move or remove them before you can switch branches.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Aborting
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="解决办法"&gt;解决办法&lt;/h1&gt;
&lt;p&gt;设置为大小写敏感(问题解决后,一定要还原配置)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git config core.ignorecase false
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;尽管设置大小写敏感之后,始终会影响其他分支的代码,所以不建议一直使用这个配置,当问题解决之后,还是要改回去.&lt;/p&gt;
&lt;h1 id="改回默认"&gt;改回默认&lt;/h1&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git config core.ignorecase true
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# or&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git config --unset core.ignorecase
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="尾巴"&gt;尾巴&lt;/h1&gt;
&lt;p&gt;平时编码的时候,还是千万不要直接重命名大小写,自己本地看起来没有什么问题.在别人问题上却是大问题.&lt;/p&gt;
&lt;p&gt;如果发生了类似问题的,应该在源头解决(谁机器上重命名的,谁改回去).如果不解决的,应该拖出去打~~&lt;/p&gt;</description></item><item><title>Visual-Studio-Code 下的 jsconfig.json</title><link>https://time-friend.com/zh/archive/vscode-jsconfig/</link><pubDate>Tue, 08 Jan 2019 19:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/vscode-jsconfig/</guid><description>&lt;p&gt;今天聊聊 Visual-Studio-Code 的jsconfig.json配置小技巧.&lt;/p&gt;
&lt;h1 id="jsconfigjson-是什么"&gt;jsconfig.json 是什么?&lt;/h1&gt;
&lt;p&gt;如果你的项目中有一个 &lt;code&gt;jsconfig.json&lt;/code&gt;文件的话,这个文件的配置可以对你的文件所在目录下的所有js代码做出个性化支持.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Tip: 如果你在项目中新加了这个文件,记得重启一下vscode哦~&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="例子"&gt;例子&lt;/h1&gt;
&lt;h2 id="exclude-属性"&gt;exclude 属性&lt;/h2&gt;
&lt;p&gt;当vscode扫描项目代码的时候,如果遇到了node_module的话是会变得很慢的.&lt;/p&gt;
&lt;p&gt;如果想要编辑器的性能有一个提升的话,我们应该排除这个文件夹.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;exclude&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;node_modules&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="include-属性"&gt;include 属性&lt;/h2&gt;
&lt;p&gt;当然还有相对的&lt;code&gt;include&lt;/code&gt;属性&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;include&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;src/**/*&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="webpack-aliases-的支持"&gt;webpack aliases 的支持&lt;/h2&gt;
&lt;p&gt;如果我们在我们的webpack里面配置的路径的别名,心细的小朋友就发现了.
我们的vscode不能根据别名路径导入的包跳转文件了.所以我们还需要&lt;code&gt;jsconfig.json&lt;/code&gt;的支持.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;compilerOptions&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;baseUrl&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;.&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;paths&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;@component&amp;#34;&lt;/span&gt;: [&lt;span style="color:#e6db74"&gt;&amp;#34;./src/component&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;jsconfig.json&lt;/code&gt;的配置是&lt;code&gt;tsconfig.json&lt;/code&gt;的子集,&lt;/p&gt;
&lt;p&gt;以后有机会的话聊一聊&lt;code&gt;tsconfig.json&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;今天就到这里~&lt;/p&gt;</description></item><item><title>前端面试知识点收集 - JavaScript篇</title><link>https://time-friend.com/zh/archive/interview-javascript/</link><pubDate>Mon, 07 Jan 2019 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/interview-javascript/</guid><description>&lt;h2 id="javascript-面试知识点总结"&gt;JavaScript 面试知识点总结&lt;/h2&gt;
&lt;h4 id="1-介绍-js-的基本数据类型"&gt;1. 介绍 js 的基本数据类型。&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;js 一共有六种基本数据类型，分别是 Undefined、Null、Boolean、Number、String，还有在 ES6 中新增的 Symbol 类型，
代表创建后独一无二且不可变的数据类型，它的出现我认为主要是为了解决可能出现的全局变量冲突的问题。
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="2-javascript-有几种类型的值你能画一下他们的内存图吗"&gt;2. JavaScript 有几种类型的值？你能画一下他们的内存图吗？&lt;/h4&gt;
&lt;p&gt;涉及知识点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;栈：原始数据类型（Undefined、Null、Boolean、Number、String）&lt;/li&gt;
&lt;li&gt;堆：引用数据类型（对象、数组和函数）&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;两种类型的区别是：存储位置不同。
原始数据类型直接存储在栈（stack）中的简单数据段，占据空间小、大小固定，属于被频繁使用数据，所以放入栈中存储。

引用数据类型存储在堆（heap）中的对象，占据空间大、大小不固定。如果存储在栈中，将会影响程序运行的性能；引用数据类型在
栈中存储了指针，该指针指向堆中该实体的起始地址。当解释器寻找引用值时，会首先检索其在栈中的地址，取得地址后从堆中获得实
体。
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;回答：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;js 可以分为两种类型的值，一种是基本数据类型，一种是复杂数据类型。

基本数据类型....（参考1）

复杂数据类型指的是 Object 类型，所有其他的如 Array、Date 等数据类型都可以理解为 Object 类型的子类。

两种类型间的主要区别是它们的存储位置不同，基本数据类型的值直接保存在栈中，而复杂数据类型的值保存在堆中，通过使用在栈中
保存对应的指针来获取堆中的值。
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;详细资料可以参考：
&lt;a href="https://blog.csdn.net/lxcao/article/details/52749421"&gt;《JavaScript 有几种类型的值？》&lt;/a&gt;
&lt;a href="https://blog.csdn.net/jiangjuanjaun/article/details/80327342"&gt;《JavaScript 有几种类型的值？能否画一下它们的内存图；》&lt;/a&gt;&lt;/p&gt;
&lt;h4 id="3-什么是堆什么是栈它们之间有什么区别和联系"&gt;3. 什么是堆？什么是栈？它们之间有什么区别和联系？&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;堆和栈的概念存在于数据结构中和操作系统内存中。

在数据结构中，栈中数据的存取方式为先进后出。而堆是一个优先队列，是按优先级来进行排序的，优先级可以按照大小来规定。完全
二叉树是堆的一种实现方式。

在操作系统中，内存被分为栈区和堆区。

栈区内存由编译器自动分配释放，存放函数的参数值，局部变量的值等。其操作方式类似于数据结构中的栈。

堆区内存一般由程序员分配释放，若程序员不释放，程序结束时可能由垃圾回收机制回收。
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;详细资料可以参考：
&lt;a href="https://www.zhihu.com/question/19729973"&gt;《什么是堆？什么是栈？他们之间有什么区别和联系？》&lt;/a&gt;&lt;/p&gt;
&lt;h4 id="4-内部属性-class-是什么"&gt;4. 内部属性 [[Class]] 是什么？&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;所有 typeof 返回值为 &amp;#34;object&amp;#34; 的对象（如数组）都包含一个内部属性 [[Class]]（我们可以把它看作一个内部的分类，而非
传统的面向对象意义上的类）。这个属性无法直接访问，一般通过 Object.prototype.toString(..) 来查看。例如：

Object.prototype.toString.call( [1,2,3] );
// &amp;#34;[object Array]&amp;#34;

Object.prototype.toString.call( /regex-literal/i );
// &amp;#34;[object RegExp]&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="5-介绍-js-有哪些内置对象"&gt;5. 介绍 js 有哪些内置对象？&lt;/h4&gt;
&lt;p&gt;涉及知识点：&lt;/p&gt;</description></item><item><title>前端面试知识点收集 - HTML篇</title><link>https://time-friend.com/zh/archive/interview-html/</link><pubDate>Sun, 06 Jan 2019 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/interview-html/</guid><description>&lt;h2 id="html-面试知识点总结"&gt;HTML 面试知识点总结&lt;/h2&gt;
&lt;h4 id="1-doctype-的作用是什么"&gt;1. DOCTYPE 的作用是什么？&lt;/h4&gt;
&lt;p&gt;相关知识点：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;IE5.5 引入了文档模式的概念，而这个概念是通过使用文档类型（DOCTYPE）切换实现的。

&amp;lt;!DOCTYPE&amp;gt;声明位于 HTML 文档中的第一行，处于 &amp;lt;html&amp;gt; 标签之前。告知浏览器的解析器用什么文档标准解析这个文档。

DOCTYPE 不存在或格式不正确会导致文档以兼容模式呈现。
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;回答（参考1-5）：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;!DOCTYPE&amp;gt; 声明一般位于文档的第一行，它的作用主要是告诉浏览器以什么样的模式来解析文档。一般指定了之后会以标准模式来
进行文档解析，否则就以兼容模式进行解析。在标准模式下，浏览器的解析规则都是按照最新的标准进行解析的。而在兼容模式下，浏
览器会以向后兼容的方式来模拟老式浏览器的行为，以保证一些老的网站的正确访问。

在 html5 之后不再需要指定 DTD 文档，因为 html5 以前的 html 文档都是基于 SGML 的，所以需要通过指定 DTD 来定义文
档中允许的属性以及一些规则。而 html5 不再基于 SGML 了，所以不再需要使用 DTD。
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="2-标准模式与兼容模式各有什么区别"&gt;2. 标准模式与兼容模式各有什么区别？&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;标准模式的渲染方式和 JS 引擎的解析方式都是以该浏览器支持的最高标准运行。在兼容模式中，页面以宽松的向后兼容的方式显示
，模拟老式浏览器的行为以防止站点无法工作。
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="3-html5-为什么只需要写-doctype-html而不需要引入-dtd"&gt;3. HTML5 为什么只需要写 &lt;code&gt;&amp;lt;!DOCTYPE HTML&amp;gt;&lt;/code&gt;，而不需要引入 DTD？&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;HTML5 不基于 SGML，因此不需要对 DTD 进行引用，但是需要 DOCTYPE 来规范浏览器的行为（让浏览器按照它们应该的方式来运
行）。

而 HTML4.01 基于 SGML ，所以需要对 DTD 进行引用，才能告知浏览器文档所使用的文档类型。
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="4-sgml--html-xml-和-xhtml-的区别"&gt;4. SGML 、 HTML 、XML 和 XHTML 的区别？&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;SGML 是标准通用标记语言，是一种定义电子文档结构和描述其内容的国际标准语言，是所有电子文档标记语言的起源。

HTML 是超文本标记语言，主要是用于规定怎么显示网页。

XML 是可扩展标记语言是未来网页语言的发展方向，XML 和 HTML 的最大区别就在于 XML 的标签是可以自己创建的，数量无限多，
而 HTML 的标签都是固定的而且数量有限。

XHTML 也是现在基本上所有网页都在用的标记语言，他其实和 HTML 没什么本质的区别，标签都一样，用法也都一样，就是比 HTML 
更严格，比如标签必须都用小写，标签都必须有闭合标签等。
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="5-dtd-介绍"&gt;5. DTD 介绍&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;DTD（ Document Type Definition 文档类型定义）是一组机器可读的规则，它们定义 XML 或 HTML 的特定版本中所有允许元
素及它们的属性和层次关系的定义。在解析网页时，浏览器将使用这些规则检查页面的有效性并且采取相应的措施。

DTD 是对 HTML 文档的声明，还会影响浏览器的渲染模式（工作模式）。
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="6-行内元素定义"&gt;6. 行内元素定义&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;HTML4 中，元素被分成两大类: inline （内联元素）与 block（块级元素）。一个行内元素只占据它对应标签的边框所包含的空
间。

常见的行内元素有 a b span img strong sub sup button input label select textarea
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="7-块级元素定义"&gt;7. 块级元素定义&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;块级元素占据其父元素（容器）的整个宽度，因此创建了一个“块”。

常见的块级元素有 div ul ol li dl dt dd h1 h2 h3 h4 h5 h6 p 
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="8-行内元素与块级元素的区别"&gt;8. 行内元素与块级元素的区别？&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;HTML4中，元素被分成两大类：inline （内联元素）与 block （块级元素）。

（1） 格式上，默认情况下，行内元素不会以新行开始，而块级元素会新起一行。
（2） 内容上，默认情况下，行内元素只能包含文本和其他行内元素。而块级元素可以包含行内元素和其他块级元素。
（3） 行内元素与块级元素属性的不同，主要是盒模型属性上：行内元素设置 width 无效，height 无效（可以设置 line-hei
 ght），设置 margin 和 padding 的上下不会对其他元素产生影响。
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="9-html5-元素的分类"&gt;9. HTML5 元素的分类&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;HTML4中，元素被分成两大类: inline（内联元素）与 block（块级元素）。但在实际的开发过程中，因为页面表现的需要，前
端工程师经常把 inline 元素的 display 值设定为 block （比如 a 标签），也经常把 block 元素的 display 值设定为
inline 之后更是出现了 inline-block 这一对外呈现 inline 对内呈现 block 的属性。因此，简单地把 HTML 元素划分为
inline 与 block 已经不再符合实际需求。

HTML5中，元素主要分为7类：Metadata Flow Sectioning Heading Phrasing Embedded Interactive
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="10-空元素定义"&gt;10. 空元素定义&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;标签内没有内容的 HTML 标签被称为空元素。空元素是在开始标签中关闭的。

常见的空元素有：br hr img input link meta
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="11-link-标签定义"&gt;11. link 标签定义&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;link 标签定义文档与外部资源的关系。

link 元素是空元素，它仅包含属性。 此元素只能存在于 head 部分，不过它可出现任何次数。

link 标签中的 rel 属性定义了当前文档与被链接文档之间的关系。常见的 stylesheet 指的是定义一个外部加载的样式表。
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="12-页面导入样式时使用-link-和-import-有什么区别"&gt;12. 页面导入样式时，使用 link 和 @import 有什么区别？&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;（1）从属关系区别。 @import 是 CSS 提供的语法规则，只有导入样式表的作用；link 是 HTML 提供的标签，不仅可以加
 载 CSS 文件，还可以定义 RSS、rel 连接属性、引入网站图标等。

（2）加载顺序区别。加载页面时，link 标签引入的 CSS 被同时加载；@import 引入的 CSS 将在页面加载完毕后被加载。

（3）兼容性区别。@import 是 CSS2.1 才有的语法，故只可在 IE5+ 才能识别；link 标签作为 HTML 元素，不存在兼容
 性问题。

（4）DOM 可控性区别。可以通过 JS 操作 DOM ，插入 link 标签来改变样式；由于 DOM 方法是基于文档的，无法使用 @i
 mport 的方式插入样式。
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="13-你对浏览器的理解"&gt;13. 你对浏览器的理解？&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;浏览器的主要功能是将用户选择的 web 资源呈现出来，它需要从服务器请求资源，并将其显示在浏览器窗口中，资源的格式通常
是 HTML，也包括 PDF、image 及其他格式。用户用 URI（Uniform Resource Identifier 统一资源标识符）来指定所请
求资源的位置。

HTML 和 CSS 规范中规定了浏览器解释 html 文档的方式，由 W3C 组织对这些规范进行维护，W3C 是负责制定 web 标准的
组织。

但是浏览器厂商纷纷开发自己的扩展，对规范的遵循并不完善，这为 web 开发者带来了严重的兼容性问题。

简单来说浏览器可以分为两部分，shell 和 内核。

其中 shell 的种类相对比较多，内核则比较少。shell 是指浏览器的外壳：例如菜单，工具栏等。主要是提供给用户界面操作，
参数设置等等。它是调用内核来实现各种功能的。内核才是浏览器的核心。内核是基于标记语言显示内容的程序或模块。也有一些
 浏览器并不区分外壳和内核。从 Mozilla 将 Gecko 独立出来后，才有了外壳和内核的明确划分。
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="14-介绍一下你对浏览器内核的理解"&gt;14. 介绍一下你对浏览器内核的理解？&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;主要分成两部分：渲染引擎和 JS 引擎。

渲染引擎的职责就是渲染，即在浏览器窗口中显示所请求的内容。默认情况下，渲染引擎可以显示 html、xml 文档及图片，它也
可以借助插件（一种浏览器扩展）显示其他类型数据，例如使用 PDF 阅读器插件，可以显示 PDF 格式。

JS 引擎：解析和执行 javascript 来实现网页的动态效果。

最开始渲染引擎和 JS 引擎并没有区分的很明确，后来 JS 引擎越来越独立，内核就倾向于只指渲染引擎。
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="15-常见的浏览器内核比较"&gt;15. 常见的浏览器内核比较&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Trident：这种浏览器内核是 IE 浏览器用的内核，因为在早期 IE 占有大量的市场份额，所以这种内核比较流行，以前有很多
网页也是根据这个内核的标准来编写的，但是实际上这个内核对真正的网页标准支持不是很好。但是由于 IE 的高市场占有率，微
软也很长时间没有更新 Trident 内核，就导致了 Trident 内核和 W3C 标准脱节。还有就是 Trident 内核的大量 Bug 等
安全问题没有得到解决，加上一些专家学者公开自己认为 IE 浏览器不安全的观点，使很多用户开始转向其他浏览器。

Gecko：这是 Firefox 和 Flock 所采用的内核，这个内核的优点就是功能强大、丰富，可以支持很多复杂网页效果和浏览器扩
展接口，但是代价是也显而易见就是要消耗很多的资源，比如内存。

Presto：Opera 曾经采用的就是 Presto 内核，Presto 内核被称为公认的浏览网页速度最快的内核，这得益于它在开发时的
天生优势，在处理 JS 脚本等脚本语言时，会比其他的内核快3倍左右，缺点就是为了达到很快的速度而丢掉了一部分网页兼容性。

Webkit：Webkit 是 Safari 采用的内核，它的优点就是网页浏览速度较快，虽然不及 Presto 但是也胜于 Gecko 和 Trid
ent，缺点是对于网页代码的容错性不高，也就是说对网页代码的兼容性较低，会使一些编写不标准的网页无法正确显示。WebKit 
前身是 KDE 小组的 KHTML 引擎，可以说 WebKit 是 KHTML 的一个开源的分支。

Blink：谷歌在 Chromium Blog 上发表博客，称将与苹果的开源浏览器核心 Webkit 分道扬镳，在 Chromium 项目中研发 B
link 渲染引擎（即浏览器核心），内置于 Chrome 浏览器之中。其实 Blink 引擎就是 Webkit 的一个分支，就像 webkit 是
KHTML 的分支一样。Blink 引擎现在是谷歌公司与 Opera Software 共同研发，上面提到过的，Opera 弃用了自己的 Presto 
内核，加入 Google 阵营，跟随谷歌一起研发 Blink。
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;详细的资料可以参考：
&lt;a href="http://www.cnblogs.com/fullhouse/archive/2011/12/19/2293455.html"&gt;《浏览器内核的解析和对比》&lt;/a&gt;
&lt;a href="https://blog.csdn.net/Summer_15/article/details/71249203"&gt;《五大主流浏览器内核的源起以及国内各大浏览器内核总结》&lt;/a&gt;&lt;/p&gt;</description></item><item><title>前端面试知识点收集 - CSS篇</title><link>https://time-friend.com/zh/archive/interview-css/</link><pubDate>Sat, 05 Jan 2019 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/interview-css/</guid><description>&lt;h2 id="css-面试知识点总结"&gt;CSS 面试知识点总结&lt;/h2&gt;
&lt;h4 id="1介绍一下标准的-css-的盒子模型低版本-ie-的盒子模型有什么不同的"&gt;1.介绍一下标准的 CSS 的盒子模型？低版本 IE 的盒子模型有什么不同的？&lt;/h4&gt;
&lt;p&gt;相关知识点：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;（1）有两种盒子模型：IE盒模型（border-box）、W3C标准盒模型（content-box）
（2）盒模型：分为内容（content）、填充（padding）、边界（margin）、边框（border）四个部分

IE盒模型和W3C标准盒模型的区别：

（1）W3C标准盒模型：属性width，height只包含内容content，不包含border和padding
（2）IE盒模型：属性width，height包含content、border和padding，指的是content
+padding+border。

在ie8+浏览器中使用哪个盒模型可以由box-sizing（CSS新增的属性）控制，默认值为content-box，即标准盒模型；
如果将box-sizing设为border-box则用的是IE盒模型。如果在ie6，7，8中DOCTYPE缺失会将盒子模型解释为IE
盒子模型。若在页面中声明了DOCTYPE类型，所有的浏览器都会把盒模型解释为W3C盒模型。
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;回答：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;盒模型都是由四个部分组成的，分别是margin、border、padding和content。

标准盒模型和IE盒模型的区别在于设置width和height时，所对应的范围不同。标准盒模型的width和height属性的
范围只包含了content，而IE盒模型的width和height属性的范围包含了border、padding和content。

一般来说，我们可以通过修改元素的box-sizing属性来改变元素的盒模型。
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;详细的资料可以参考：
&lt;a href="https://juejin.im/post/59ef72f5f265da4320026f76"&gt;《CSS 盒模型详解》&lt;/a&gt;&lt;/p&gt;
&lt;h4 id="2css-选择符有哪些"&gt;2.CSS 选择符有哪些？&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;（1）id选择器（#myid）
（2）类选择器（.myclassname）
（3）标签选择器（div,h1,p）
（4）后代选择器（h1 p）
（5）相邻后代选择器（子）选择器（ul&amp;gt;li）
（6）兄弟选择器（li~a）
（7）相邻兄弟选择器（li+a）
（8）属性选择器（a[rel=&amp;#34;external&amp;#34;]）
（9）伪类选择器（a:hover,li:nth-child）
（10）伪元素选择器（::before、::after）
（11）通配符选择器（*）
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="3before-和after-中双冒号和单冒号有什么区别解释一下这-2-个伪元素的作用"&gt;3.::before 和:after 中双冒号和单冒号有什么区别？解释一下这 2 个伪元素的作用。&lt;/h4&gt;
&lt;p&gt;相关知识点：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;单冒号（:）用于CSS3伪类，双冒号（::）用于CSS3伪元素。（伪元素由双冒号和伪元素名称组成）
双冒号是在当前规范中引入的，用于区分伪类和伪元素。不过浏览器需要同时支持旧的已经存在的伪元素写法，
比如:first-line、:first-letter、:before、:after等，
而新的在CSS3中引入的伪元素则不允许再支持旧的单冒号的写法。

想让插入的内容出现在其它内容前，使用::before，否者，使用::after；
在代码顺序上，::after生成的内容也比::before生成的内容靠后。
如果按堆栈视角，::after生成的内容会在::before生成的内容之上。
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;回答：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;在css3中使用单冒号来表示伪类，用双冒号来表示伪元素。但是为了兼容已有的伪元素的写法，在一些浏览器中也可以使用单冒号
来表示伪元素。

伪类一般匹配的是元素的一些特殊状态，如hover、link等，而伪元素一般匹配的特殊的位置，比如after、before等。
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="4伪类与伪元素的区别"&gt;4.伪类与伪元素的区别&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;css引入伪类和伪元素概念是为了格式化文档树以外的信息。也就是说，伪类和伪元素是用来修饰不在文档树中的部分，比如，一句
话中的第一个字母，或者是列表中的第一个元素。

伪类用于当已有的元素处于某个状态时，为其添加对应的样式，这个状态是根据用户行为而动态变化的。比如说，当用户悬停在指定的
元素时，我们可以通过:hover来描述这个元素的状态。

伪元素用于创建一些不在文档树中的元素，并为其添加样式。它们允许我们为元素的某些部分设置样式。比如说，我们可以通过::be
fore来在一个元素前增加一些文本，并为这些文本添加样式。虽然用户可以看到这些文本，但是这些文本实际上不在文档树中。

有时你会发现伪元素使用了两个冒号（::）而不是一个冒号（:）。这是CSS3的一部分，并尝试区分伪类和伪元素。大多数浏览
器都支持这两个值。按照规则应该使用（::）而不是（:），从而区分伪类和伪元素。但是，由于在旧版本的W3C规范并未对此进行
特别区分，因此目前绝大多数的浏览器都支持使用这两种方式表示伪元素。
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;详细资料可以参考：
&lt;a href="http://www.alloyteam.com/2016/05/summary-of-pseudo-classes-and-pseudo-elements/"&gt;《总结伪类与伪元素》&lt;/a&gt;&lt;/p&gt;
&lt;h4 id="5css-中哪些属性可以继承"&gt;5.CSS 中哪些属性可以继承？&lt;/h4&gt;
&lt;p&gt;相关资料：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;每个CSS属性定义的概述都指出了这个属性是默认继承的，还是默认不继承的。这决定了当你没有为元素的属性指定值时该如何计算
值。

当元素的一个继承属性没有指定值时，则取父元素的同属性的计算值。只有文档根元素取该属性的概述中给定的初始值（这里的意思应
该是在该属性本身的定义中的默认值）。

当元素的一个非继承属性（在Mozilla code里有时称之为reset property）没有指定值时，则取属性的初始值initial v
alue（该值在该属性的概述里被指定）。

有继承性的属性：

（1）字体系列属性
font、font-family、font-weight、font-size、font-style、font-variant、font-stretch、font-size-adjust

（2）文本系列属性
text-indent、text-align、text-shadow、line-height、word-spacing、letter-spacing、
text-transform、direction、color

（3）表格布局属性
caption-side border-collapse empty-cells

（4）列表属性
list-style-type、list-style-image、list-style-position、list-style

（5）光标属性
cursor

（6）元素可见性
visibility

（7）还有一些不常用的；speak，page，设置嵌套引用的引号类型quotes等属性


注意：当一个属性不是继承属性时，可以使用inherit关键字指定一个属性应从父元素继承它的值，inherit关键字用于显式地
指定继承性，可用于任何继承性/非继承性属性。
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;回答：&lt;/p&gt;</description></item><item><title>前端面试知识点收集 - 综合篇</title><link>https://time-friend.com/zh/archive/interview-comprehensive/</link><pubDate>Fri, 04 Jan 2019 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/interview-comprehensive/</guid><description>&lt;h2 id="html-httpweb-综合问题"&gt;$HTML， HTTP，web 综合问题&lt;/h2&gt;
&lt;h3 id="常见排序算法的时间复杂度空间复杂度"&gt;常见排序算法的时间复杂度,空间复杂度&lt;/h3&gt;
&lt;p&gt;&lt;img src="img/sort-compare.png" alt="排序算法比较"&gt;&lt;/p&gt;
&lt;h3 id="前端需要注意哪些-seo"&gt;前端需要注意哪些 SEO&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;合理的 title、description、keywords：搜索对着三项的权重逐个减小，title 值强调重点即可，重要关键词出现不要超过 2 次，而且要靠前，不同页面 title 要有所不同；description 把页面内容高度概括，长度合适，不可过分堆砌关键词，不同页面 description 有所不同；keywords 列举出重要关键词即可&lt;/li&gt;
&lt;li&gt;语义化的 HTML 代码，符合 W3C 规范：语义化代码让搜索引擎容易理解网页&lt;/li&gt;
&lt;li&gt;重要内容 HTML 代码放在最前：搜索引擎抓取 HTML 顺序是从上到下，有的搜索引擎对抓取长度有限制，保证重要内容一定会被抓取&lt;/li&gt;
&lt;li&gt;重要内容不要用 js 输出：爬虫不会执行 js 获取内容&lt;/li&gt;
&lt;li&gt;少用 iframe：搜索引擎不会抓取 iframe 中的内容&lt;/li&gt;
&lt;li&gt;非装饰性图片必须加 alt&lt;/li&gt;
&lt;li&gt;提高网站速度：网站速度是搜索引擎排序的一个重要指标&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="web-开发中会话跟踪的方法有哪些"&gt;web 开发中会话跟踪的方法有哪些&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;cookie&lt;/li&gt;
&lt;li&gt;session&lt;/li&gt;
&lt;li&gt;url 重写&lt;/li&gt;
&lt;li&gt;隐藏 input&lt;/li&gt;
&lt;li&gt;ip 地址&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="img的title和alt有什么区别"&gt;&lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt;的&lt;code&gt;title&lt;/code&gt;和&lt;code&gt;alt&lt;/code&gt;有什么区别&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;title&lt;/code&gt;是&lt;a href="http://www.w3.org/TR/html-markup/global-attributes.html#common.attrs.core"&gt;global attributes&lt;/a&gt;之一，用于为元素提供附加的 advisory information。通常当鼠标滑动到元素上的时候显示。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;alt&lt;/code&gt;是&lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt;的特有属性，是图片内容的等价描述，用于图片无法加载时显示、读屏器阅读图片。可提图片高可访问性，除了纯装饰图片外都必须设置有意义的值，搜索引擎会重点分析。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="doctype-是什么举例常见-doctype-及特点"&gt;doctype 是什么,举例常见 doctype 及特点&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;!doctype&amp;gt;&lt;/code&gt;声明必须处于 HTML 文档的头部，在&lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt;标签之前，HTML5 中不区分大小写&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;!doctype&amp;gt;&lt;/code&gt;声明不是一个 HTML 标签，是一个用于告诉浏览器当前 HTMl 版本的指令&lt;/li&gt;
&lt;li&gt;现代浏览器的 html 布局引擎通过检查 doctype 决定使用兼容模式还是标准模式对文档进行渲染，一些浏览器有一个接近标准模型。&lt;/li&gt;
&lt;li&gt;在 HTML4.01 中&lt;code&gt;&amp;lt;!doctype&amp;gt;&lt;/code&gt;声明指向一个 DTD，由于 HTML4.01 基于 SGML，所以 DTD 指定了标记规则以保证浏览器正确渲染内容&lt;/li&gt;
&lt;li&gt;HTML5 不基于 SGML，所以不用指定 DTD&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;常见 dotype：&lt;/p&gt;</description></item><item><title>幕后英雄Abstract syntax tree抽象语法树</title><link>https://time-friend.com/zh/archive/abstract-syntax-tree-ast-behind-the-scenes-hero/</link><pubDate>Thu, 03 Jan 2019 17:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/abstract-syntax-tree-ast-behind-the-scenes-hero/</guid><description>&lt;h1 id="抽象语法树-ast"&gt;抽象语法树 AST&lt;/h1&gt;
&lt;p&gt;在计算机科学中，抽象语法树，或简称语法树，是源代码语法结构的一种抽象表示.&lt;/p&gt;
&lt;p&gt;这里介绍一个网站 &lt;a href="https://astexplorer.net"&gt;https://astexplorer.net&lt;/a&gt; ,可以让你清晰的看到一段js,css以及其他语言被转换成语法树的样子.&lt;/p&gt;
&lt;p&gt;在我们的浏览器中,也会对我们的js代码解析成抽象语法书然后再进一步的分析以及下一步的操作.&lt;/p&gt;
&lt;p&gt;语法树就前端而言,被利用在各种地方,代码语法的检查，代码风格的检查，代码的格式化，代码的高亮，代码错误提示，代码自动补全,比如:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;eslint&lt;/li&gt;
&lt;li&gt;JSHint&lt;/li&gt;
&lt;li&gt;babel&lt;/li&gt;
&lt;li&gt;webpack&lt;/li&gt;
&lt;li&gt;rollup&lt;/li&gt;
&lt;li&gt;UglifyJS2&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;等等等等&amp;hellip; 根本数不过来.&lt;/p&gt;
&lt;h2 id="举个例子"&gt;举个例子&lt;/h2&gt;
&lt;p&gt;一段代码被解析成语法树后的样子
目前业界对抽象语法树是有规范的,
感兴趣的朋友可以查看这个网址: &lt;a href="https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Parser_API#Node_objects"&gt;SpiderMonkey&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;str&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;我是字符串&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;to AST&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Program&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;start&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;end&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;17&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;body&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;VariableDeclaration&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;start&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;end&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;17&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;declarations&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;VariableDeclarator&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;start&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;end&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;16&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Identifier&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;start&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;end&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;7&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;str&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;init&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Literal&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;start&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;9&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;end&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;16&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;我是字符串&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;raw&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#39;我是字符串&amp;#39;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;kind&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;let&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;sourceType&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;module&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="nodejs解析抽象语法树的工具"&gt;Node.js解析抽象语法树的工具&lt;/h1&gt;
&lt;h2 id="常用js解析工具"&gt;常用js解析工具&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;esprima&lt;/li&gt;
&lt;li&gt;traceur&lt;/li&gt;
&lt;li&gt;acorn&lt;/li&gt;
&lt;li&gt;shift&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="使用esprima举个例子"&gt;使用esprima举个例子&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# node环境&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; var esprima &lt;span style="color:#f92672"&gt;=&lt;/span&gt; require&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;esprima&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; var program &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;const answer = 42&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; esprima.tokenize&lt;span style="color:#f92672"&gt;(&lt;/span&gt;program&lt;span style="color:#f92672"&gt;)&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt; &lt;span style="color:#f92672"&gt;{&lt;/span&gt; type: &lt;span style="color:#e6db74"&gt;&amp;#39;Keyword&amp;#39;&lt;/span&gt;, value: &lt;span style="color:#e6db74"&gt;&amp;#39;const&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;}&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;{&lt;/span&gt; type: &lt;span style="color:#e6db74"&gt;&amp;#39;Identifier&amp;#39;&lt;/span&gt;, value: &lt;span style="color:#e6db74"&gt;&amp;#39;answer&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;}&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;{&lt;/span&gt; type: &lt;span style="color:#e6db74"&gt;&amp;#39;Punctuator&amp;#39;&lt;/span&gt;, value: &lt;span style="color:#e6db74"&gt;&amp;#39;=&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;}&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;{&lt;/span&gt; type: &lt;span style="color:#e6db74"&gt;&amp;#39;Numeric&amp;#39;&lt;/span&gt;, value: &lt;span style="color:#e6db74"&gt;&amp;#39;42&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;}&lt;/span&gt; &lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; esprima.parseScript&lt;span style="color:#f92672"&gt;(&lt;/span&gt;program&lt;span style="color:#f92672"&gt;)&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;{&lt;/span&gt; type: &lt;span style="color:#e6db74"&gt;&amp;#39;Program&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; body:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt; &lt;span style="color:#f92672"&gt;{&lt;/span&gt; type: &lt;span style="color:#e6db74"&gt;&amp;#39;VariableDeclaration&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; declarations: &lt;span style="color:#f92672"&gt;[&lt;/span&gt;Object&lt;span style="color:#f92672"&gt;]&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; kind: &lt;span style="color:#e6db74"&gt;&amp;#39;const&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;}&lt;/span&gt; &lt;span style="color:#f92672"&gt;]&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sourceType: &lt;span style="color:#e6db74"&gt;&amp;#39;script&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>2018 年终有感</title><link>https://time-friend.com/zh/archive/2018-year-end-reflections/</link><pubDate>Sat, 29 Dec 2018 21:29:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/2018-year-end-reflections/</guid><description>&lt;p&gt;今天是今年的最后一个工作日,现在我在高铁上.已经习惯在高铁上用电脑折腾点什么.
回想起来,不知道在高铁上发过多少次版本,fix掉了多少个bug.啊哈哈~&lt;/p&gt;
&lt;p&gt;回看今年的2018,对于我来说是传奇的,是曲折的,甚至是有点丧的.幸运的是个人成长并没有客观原因而耽误.&lt;/p&gt;
&lt;h2 id="我的团队"&gt;我的团队&lt;/h2&gt;
&lt;p&gt;回想到今年7月份,亲手组建的前端团队因为大环境的原因而解散,确实是很痛心的.
如果按照正常来发展,我想应该可以打造成我心目中的Dream Team了吧.至少各个对技术是那么的有热情.&lt;/p&gt;
&lt;h2 id="成长要与时间赛跑"&gt;成长要与时间赛跑&lt;/h2&gt;
&lt;p&gt;不过一切都没有关系,今年也不过刚满26,以后有的是机会.我经常这样安慰我自己.恐怕再过两年,这就不是自我安慰的理由了.
唯一要做的就是个人成长必须要与时间赛跑.&lt;/p&gt;
&lt;p&gt;今年去参加ng china的时候,让我非常有印象的一场演讲是雪狼的.
其中有一段大意是根据我们现在信息爆炸的年代,我们的成长应该古人早十年:&lt;/p&gt;
&lt;p&gt;二十而立&lt;/p&gt;
&lt;p&gt;三十不惑&lt;/p&gt;
&lt;p&gt;四十知天命&lt;/p&gt;
&lt;p&gt;五十耳顺&lt;/p&gt;
&lt;p&gt;六十从心所欲&lt;/p&gt;
&lt;p&gt;对此,我是十份赞同的.&lt;/p&gt;
&lt;h2 id="焦虑的一年"&gt;焦虑的一年&lt;/h2&gt;
&lt;p&gt;2018年对于我来说,是焦虑的一年.因为自身的焦虑,促使自己每天都在不断学习与进步~
当然今年也错过了很多不错的机会.现在想起来,还是自己太年轻了,没有见过大人物,看到偶像立马就怂了.
不过还是随时整装待发,随时面对新挑战.&lt;/p&gt;
&lt;h2 id="关于博客"&gt;关于博客&lt;/h2&gt;
&lt;p&gt;今年博客可以说是大升级了,界面看起来差不多,但是内部基本上重写了一遍.
还专门做了SEO,甚至还跑到 segmentfault 去打了一个星期的广告,哈哈哈~
虽然宣传效果没有达到预期~&lt;/p&gt;
&lt;p&gt;以前没有专门的做统计,自10月上线统计以来,看了一下网站的总访问量已经到达了10W+.
我不知道其他的博客主的网站数据是怎么样的,但是按照现在趋势.
访问量还是在缓慢的增加.每天看到那些统计数据,还是非常有意思的.&lt;/p&gt;
&lt;p&gt;从之前每周强制写一篇,到现在的每周强制自己写三篇.写一些自己正在做的,看到的,有意思的技术总结.有时候是一些很小的技术点,有一些也是我研究了很久,有一定系统性的东西.写博客对我来说是一种非常有效率的学习方式.以后应该还会坚持.不过也说不上坚持吧,渐渐的已经成为了一种爱好与习惯.
希望这种习惯,可以让自己的技能可以有发挥的地方.有一个组织与自己互利互惠,相互成长,得到各自想要的东西.&lt;/p&gt;
&lt;h2 id="关于家庭"&gt;关于家庭&lt;/h2&gt;
&lt;p&gt;关于家庭,今年1月份我儿子小可乐出生了,直到小可乐出生很久,我都没能让自己非常喜欢小孩.
不知道是因为自己是独生子或者从来没有跟自己年龄小的人相处的原因. 现在看,我身边的朋友大多都比我大个五六七八岁的.
但是现在,相处的越久发现这种与儿子的羁绊越来越深.希望以后可以跟他成为好朋友,甚至是好兄弟,好导师.&lt;/p&gt;
&lt;p&gt;至少我们现在看到的世界,比我们父辈的那一代要大很多. 我们要学习父辈的智慧,重新看待与审视这个世界.
智慧这个东西,很有意思~ 不管放在哪个时代都是可以直接复用的.&lt;/p&gt;
&lt;h2 id="关于技术"&gt;关于技术&lt;/h2&gt;
&lt;p&gt;今年我有听到一些话,让我深深的陷入思考.我一同事跟我说: &amp;ldquo;我对技术没有你那么高的热情,我只是为了谋生&amp;rdquo;.
我很排斥这种说法,但是又不得不承认很多人是这样. 这是不是很多时候面试,别人问你是不是计算机专业出身的一样.&lt;/p&gt;
&lt;p&gt;我问自己,我学习这么多的知识是谋生吗? 最终我想了想,得到了答案: 学习这些技术是一个让我理解这个世界的途径.
我想我能有一个这样的理解,是因为我比较幸运吧~ 虽然生活压力还是有的,但也没有那么大&lt;del&gt;是吧? (突然脑子想到那个段子&lt;/del&gt;)&lt;/p&gt;
&lt;p&gt;我一直觉得我有一个问题,我眼中总是只能看到比我优秀的人,看着他们如此优秀,让自己无比焦虑.&lt;/p&gt;
&lt;p&gt;有时候我对自己说,我是不是偶尔也向后看看? 可以自己释怀很多~ 但是很多时候又觉得自己办不到?
这算不算习惯性见贤思齐的一种表现~ 我觉得这是病,时间久了多多少少还是会有一些问题的.&lt;/p&gt;
&lt;h2 id="关于2019"&gt;关于2019&lt;/h2&gt;
&lt;p&gt;2019我觉得没有什么可计划的,要是真有计划那也是把2018年一直坚持的事情继续做下去.&lt;/p&gt;</description></item><item><title>聊聊HTTP的X-Forwarded-For 和 X-Real-IP</title><link>https://time-friend.com/zh/archive/talking-about-http-x-forwarded-for-and-x-real-ip/</link><pubDate>Sat, 29 Dec 2018 16:14:25 +0000</pubDate><guid>https://time-friend.com/zh/archive/talking-about-http-x-forwarded-for-and-x-real-ip/</guid><description>&lt;p&gt;最近在看&lt;a href="https://binaryify.github.io/NeteaseCloudMusicApi/#/?id=%E8%B0%83%E7%94%A8%E5%89%8D%E9%A1%BB%E7%9F%A5"&gt;网易云音乐API nodejs&lt;/a&gt;这个项目的文档的时候.&lt;/p&gt;
&lt;p&gt;发现调用须知里,有一段是这样的说的:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;由于网易限制,此项目在国外服务器上使用会受到限制,如需解决 , 可使用大陆服务器或者使用代理 , 感谢 @hiyangguo提出的解决方法: 在 &amp;lsquo;util.js&amp;rsquo; 的 &amp;lsquo;headers&amp;rsquo; 处增加 X-Real-IP&amp;rsquo;:&amp;lsquo;211.161.244.70&amp;rsquo; // 任意国内 IP 即可解决&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;网易云音乐的接口调用对国外加了限制,想要跳过这样的限制的话,就必须在headers里修改&lt;code&gt;X-Real-IP&lt;/code&gt; 就可以解决.&lt;/p&gt;
&lt;p&gt;那&lt;code&gt;X-Real-IP&lt;/code&gt;是什么?是干什么用的?&lt;/p&gt;
&lt;h1 id="x-real-ip"&gt;X-Real-IP&lt;/h1&gt;
&lt;p&gt;X-Real-IP，这是一个自定义头部字段。X-Real-IP 通常被 HTTP 代理用来表示与它产生 TCP 连接的设备 IP，这个设备可能是其他代理，也可能是真正的请求端。需要注意的是，X-Real-IP 目前并不属于任何标准，&lt;/p&gt;
&lt;p&gt;跟他非常相关的,还有一个&lt;code&gt;X-Forwarded-For&lt;/code&gt;的自定义头部字段.&lt;/p&gt;
&lt;h1 id="x-forwarded-for"&gt;X-Forwarded-For&lt;/h1&gt;
&lt;p&gt;X-Forwarded-For 是一个 HTTP 扩展头部。HTTP/1.1（RFC 2616）协议并没有对它的定义，它最开始是由 Squid 这个缓存代理软件引入，用来表示 HTTP 请求端真实 IP。如今它已经成为事实上的标准，被各大 HTTP 代理、负载均衡等转发服务广泛使用，并被写入 RFC 7239（Forwarded HTTP Extension）标准之中。&lt;/p&gt;
&lt;p&gt;格式:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;X-Forwarded-For: client, proxy1, proxy2
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;如果一个 HTTP 请求到达服务器之前，经过了三个代理 Proxy1、Proxy2、Proxy3，IP 分别为 IP1、IP2、IP3，用户真实 IP 为 IP0，那么按照 XFF 标准，服务端最终会收到以下信息：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;X-Forwarded-For: IP0, IP1, IP2
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;X-Forwarded-For&lt;/code&gt; 会记录用户ip与每次转发用的代理服务器ip.&lt;/p&gt;
&lt;p&gt;而这时,我们之前提到的 &lt;code&gt;X-Real-IP&lt;/code&gt; 会是ip0,是用户发送请求的ip地址.&lt;/p&gt;</description></item><item><title>Angular路径别名配置</title><link>https://time-friend.com/zh/archive/angular-path-alias-configuration/</link><pubDate>Thu, 27 Dec 2018 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/angular-path-alias-configuration/</guid><description>&lt;p&gt;angular cli 内置了 webpack,所以也是可以配置路径别名的.
而且配置的方式几乎是一样的.&lt;/p&gt;
&lt;h1 id="配置路径别名"&gt;配置路径别名&lt;/h1&gt;
&lt;p&gt;找到你的项目根目录的 &lt;code&gt;tsconfig.json&lt;/code&gt; 文件.&lt;/p&gt;
&lt;p&gt;注意: 如果你的配置不生效,需要查看你的&lt;code&gt;baseUrl&lt;/code&gt;是否配置正确.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;compilerOptions&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;baseUrl&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;./src/&amp;#34;&lt;/span&gt;, 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;paths&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;@app/*&amp;#34;&lt;/span&gt;: [&lt;span style="color:#e6db74"&gt;&amp;#34;app/*&amp;#34;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;@services/*&amp;#34;&lt;/span&gt;: [&lt;span style="color:#e6db74"&gt;&amp;#34;app/services/*&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="配置之前"&gt;配置之前&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;Api&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;../../../../../services/api.service&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;xxx&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;../../../../../services/api.xxx&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="配置之后"&gt;配置之后&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;Api&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;@services/api.service&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;xxx&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;@services/api.xxx&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;一些开发中的小技巧,希望可以帮到你.&lt;/p&gt;</description></item><item><title>Typescript的福音:Json To Interface</title><link>https://time-friend.com/zh/archive/json-to-interface/</link><pubDate>Tue, 25 Dec 2018 19:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/json-to-interface/</guid><description>&lt;p&gt;在我们使用ts的时候,我们需要写大量的 Interface.&lt;/p&gt;
&lt;p&gt;但是我们一条json数据的字段实在是太多了,一个一个写的话不仅会花费大量的时间.&lt;/p&gt;
&lt;p&gt;在团队内部推广Typescript,因为使用问题导致推广层层阻碍,最后放弃使用屡见不鲜.&lt;/p&gt;
&lt;p&gt;今天推荐的这个插件,希望可以帮到你.&lt;/p&gt;
&lt;h1 id="json-to-ts-插件"&gt;JSON to TS 插件&lt;/h1&gt;
&lt;h2 id="安装"&gt;安装&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ext install json-to-ts
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="复制到剪贴板后-运行快捷键-ctrl--alt--v"&gt;复制到剪贴板后 运行快捷键 (Ctrl + Alt + V)&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://github.com/MariusAlch/vscode-json-to-ts/raw/master/./images/clipboard.gif" alt=""&gt;&lt;/p&gt;
&lt;h2 id="鼠标选中后-运行快捷键-ctrl--alt--s"&gt;鼠标选中后 运行快捷键 (Ctrl + Alt + S)&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://github.com/MariusAlch/vscode-json-to-ts/raw/master/./images/selection.gif" alt=""&gt;&lt;/p&gt;
&lt;h1 id="已知问题"&gt;已知问题&lt;/h1&gt;
&lt;h2 id="linux-已知问题"&gt;linux 已知问题&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Command failed: xclip -selection clipboard -o
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="解决方法"&gt;解决方法&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt-get install xclip
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Centos7 如何使用yum升级git到最新版本</title><link>https://time-friend.com/zh/archive/centos7-upgrade-git-with-yum/</link><pubDate>Mon, 24 Dec 2018 20:32:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/centos7-upgrade-git-with-yum/</guid><description>&lt;h1 id="yum-upgrade-并不能升级git到最新版本"&gt;yum upgrade 并不能升级git到最新版本&lt;/h1&gt;
&lt;p&gt;在centos7 默认的git版本是1.8.x&lt;/p&gt;
&lt;h2 id="查看本机git版本"&gt;查看本机git版本&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git --version
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git version 1.8.3.1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果你想使用yum升级到2.0+的版本&lt;/p&gt;
&lt;h2 id="直接yum升级并不会升级到最新版本"&gt;直接yum升级并不会升级到最新版本&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;yum -y upgrade git
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git version 1.8.3.1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;但是我又不想下载源码包,在本机编译然后输出环境变量那种方式.
还是太麻烦了.&lt;/p&gt;
&lt;h1 id="yum升级git版本到20"&gt;yum升级git版本到2.0+&lt;/h1&gt;
&lt;h2 id="git第三方仓库安装ius"&gt;Git第三方仓库安装（IUS）&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 安装使用里面说的自动化安装脚本&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;curl https://setup.ius.io | sh
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;yum search git 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 删除本机git,安装git2u&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;yum remove -y git | yum -y install git2u
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 查看当前版本&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git --version
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 成功升级&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; git version 2.16.4
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>推荐一个Angular Electron 开箱即用的项目工程模板</title><link>https://time-friend.com/zh/archive/angular-electron-template/</link><pubDate>Thu, 20 Dec 2018 19:02:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/angular-electron-template/</guid><description>&lt;p&gt;在angular官网是有提供官方的 electron 的angular版本的模板.
但是版本是2.0的实在是太旧了.估计也不会再有人维护了吧.
但是至今还挂载官网上.
让很多新手,至少让我刚开始的时候误以为没有一个比较新的好用的electron的模板,可以快速的创建项目.&lt;/p&gt;
&lt;h1 id="angular-electron"&gt;Angular-electron&lt;/h1&gt;
&lt;p&gt;这里推荐一个完成度非常高的模板,开箱即用&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/maximegris/angular-electron"&gt;https://github.com/maximegris/angular-electron&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Angular7 + Electron主进程与渲染进程通讯问题</title><link>https://time-friend.com/zh/archive/angular-electron-ipc/</link><pubDate>Wed, 19 Dec 2018 19:02:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/angular-electron-ipc/</guid><description>&lt;h1 id="electron-中的进程分类"&gt;Electron 中的进程分类&lt;/h1&gt;
&lt;p&gt;在 Electron 中，存在两种进程：&lt;code&gt;主进程&lt;/code&gt;和&lt;code&gt;渲染进程&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;渲染进程&lt;/code&gt;你可以理解为view层,也就是我们非常熟悉的显示页面的进程.
在这里你可以调用nodejs接口的能力,也可以做我们已经非常熟悉的浏览器操作.
但是你想要调用主进程才能做的一些操作的时候,就需要一个通讯机制,告诉主进程你要干嘛干嘛.&lt;/p&gt;
&lt;h1 id="ipc通讯"&gt;IPC通讯&lt;/h1&gt;
&lt;h2 id="渲染层向主进程发送通知"&gt;渲染层向主进程发送通知&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//index.html,渲染进程发送通知
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;onst&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;electron&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;electron&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ipcRenderer&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;electron&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;ipcRenderer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;ipcRenderer&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;send&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;main-process-messages&amp;#39;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;hellow&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// main.js 主进程接收通知
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;ipcMain&lt;/span&gt; } &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;electron&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;ipcMain&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;on&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;main-process-messages&amp;#39;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;event&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;message&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;message&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="主进程向渲染进程发送通知"&gt;主进程向渲染进程发送通知&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// main.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;mainWindow&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;webContents&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;send&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;main-process-messages&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;main-process-messages show&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//index.html,渲染进程中接收消息
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;electron&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;electron&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ipcRenderer&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;electron&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;ipcRenderer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;ipcRenderer&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;on&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;main-process-messages&amp;#39;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;event&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;message&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;alert&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;message&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="在angular工程中如何使用"&gt;在Angular工程中如何使用&lt;/h1&gt;
&lt;p&gt;当你在angular工程中直接&lt;code&gt;require('electron')&lt;/code&gt;是会直接报错的.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ERROR in ./node_modules/electron/index.js
Module not found: Error: Can&amp;#39;t resolve &amp;#39;fs&amp;#39; in &amp;#39;###/node_modules/electron&amp;#39;
ERROR in ./node_modules/electron/index.js
Module not found: Error: Can&amp;#39;t resolve &amp;#39;path&amp;#39; in &amp;#39;###/node_modules/electron&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;那我们该怎么办呢.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;创建一个 &lt;code&gt;electron.service.ts&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 示例代码
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;Injectable&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;@angular/core&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; {} &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;electron&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Fs&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;fs&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;@&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Injectable&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;providedIn&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;root&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ElectronService&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;constructor&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// check if platform is electron
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;isElectron&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;boolean&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; window &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; window[&lt;span style="color:#e6db74"&gt;&amp;#39;process&amp;#39;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; window[&lt;span style="color:#e6db74"&gt;&amp;#39;process&amp;#39;&lt;/span&gt;].&lt;span style="color:#a6e22e"&gt;type&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;isElectron&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fs&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;typeof&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Fs&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; window[&lt;span style="color:#e6db74"&gt;&amp;#39;require&amp;#39;&lt;/span&gt;](&lt;span style="color:#e6db74"&gt;&amp;#39;fs&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Electron&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;App&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; window[&lt;span style="color:#e6db74"&gt;&amp;#39;require&amp;#39;&lt;/span&gt;](&lt;span style="color:#e6db74"&gt;&amp;#39;electron&amp;#39;&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;remote&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;electron&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; window[&lt;span style="color:#e6db74"&gt;&amp;#39;require&amp;#39;&lt;/span&gt;](&lt;span style="color:#e6db74"&gt;&amp;#39;electron&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;当我们需要electron的时候,直接引入这个service就好了.&lt;/p&gt;</description></item><item><title>从零搭建 Angular7 + Electron 桌面应用</title><link>https://time-friend.com/zh/archive/angular7-electron-setup/</link><pubDate>Tue, 18 Dec 2018 19:02:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/angular7-electron-setup/</guid><description>&lt;h1 id="electron-是什么"&gt;Electron 是什么？&lt;/h1&gt;
&lt;p&gt;Electron 是一个可以用 JavaScript、HTML 和 CSS 构建桌面应用程序的库。这些应用程序能打包到 Mac、Windows 和 Linux 系统上运行，也能上架到 Mac 和 Windows 的 App Store。
意思就是说,你只要拥有前端开发的能力,也可以轻松开发跨平台的桌面应用.&lt;/p&gt;
&lt;h2 id="electron的主进程和渲染进程"&gt;Electron的『主进程』和『渲染进程』&lt;/h2&gt;
&lt;p&gt;Electron 有两种进程：『主进程』和『渲染进程』。部分模块只能在两者之一上运行，而有些则无限制。主进程更多地充当幕后角色，而渲染进程则是应用程序的各个窗口。&lt;/p&gt;
&lt;h3 id="主进程"&gt;主进程&lt;/h3&gt;
&lt;p&gt;主进程，通常是一个命名为 main.js 的文件，该文件是每个 Electron 应用的入口。它控制了应用的生命周期（从打开到关闭）。它既能调用原生元素，也能创建新的（多个）渲染进程。另外，Node API 是内置其中的。&lt;/p&gt;
&lt;h3 id="渲染进程"&gt;渲染进程&lt;/h3&gt;
&lt;p&gt;渲染进程是应用的一个浏览器窗口。与主进程不同，它能存在多个（注：一个 Electron 应用只能存在一个主进程）并且相互独立（它也能是隐藏的）。&lt;/p&gt;
&lt;p&gt;主窗口通常被命名为 index.html。它们就像典型的 HTML 文件，但 Electron 赋予了它们完整的 Node API。因此，这也是它与浏览器的区别。&lt;/p&gt;
&lt;h2 id="进程之间的通讯-ipc"&gt;进程之间的通讯 (IPC)&lt;/h2&gt;
&lt;p&gt;想要再网页里调用主进程的功能,比如关闭窗口,最小化全屏等主线程才能控制的功能.
Electron提供了通讯的机制,这就是IPC.后续会慢慢介绍IPC的使用.&lt;/p&gt;
&lt;h1 id="angular7--electron"&gt;Angular7 + Electron&lt;/h1&gt;
&lt;p&gt;介绍完Electron的一些基础概念之后,
这里教大家徒手搭建一个基于ng7的桌面应用工程.&lt;/p&gt;
&lt;h2 id="1-安装最新angular-cli"&gt;1. 安装最新&lt;code&gt;angular-cli&lt;/code&gt;&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;npm i -g @angular/cli
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="2-生成一个angular工程"&gt;2. 生成一个&lt;code&gt;angular&lt;/code&gt;工程&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ng new electro-angular7
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="3-安装最新版electron"&gt;3. 安装最新版&lt;code&gt;electron&lt;/code&gt;&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd electro-angular7
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;npm install --save-dev electron@latest
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="4-在项目根目录添加主进程-mainjs文件"&gt;4. 在项目根目录添加&lt;code&gt;主进程&lt;/code&gt; main.js文件&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;BrowserWindow&lt;/span&gt; , &lt;span style="color:#a6e22e"&gt;ipcMain&lt;/span&gt; } &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;electron&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;path&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;path&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 保持对window对象的全局引用，如果不这么做的话，当JavaScript对象被
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 垃圾回收的时候，window对象将会自动的关闭
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;win&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;createWindow&lt;/span&gt; () {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 创建浏览器窗口。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;win&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;BrowserWindow&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;width&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1000&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;height&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;670&lt;/span&gt; ,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 然后加载应用的 index.html。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;win&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;loadURL&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`file://&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;__dirname&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/dist/electro-angular7/index.html`&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 打开开发者工具
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;win&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;webContents&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;openDevTools&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 当 window 被关闭，这个事件会被触发。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;win&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;on&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;closed&amp;#39;&lt;/span&gt;, () =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 取消引用 window 对象，如果你的应用支持多窗口的话，
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 通常会把多个 window 对象存放在一个数组里面，
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 与此同时，你应该删除相应的元素。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;win&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Electron 会在初始化后并准备
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 创建浏览器窗口时，调用这个函数。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 部分 API 在 ready 事件触发后才能使用。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;on&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;ready&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;createWindow&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 当全部窗口关闭时退出。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;on&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;window-all-closed&amp;#39;&lt;/span&gt;, () =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 在 macOS 上，除非用户用 Cmd + Q 确定地退出，
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 否则绝大部分应用及其菜单栏会保持激活。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;process&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;platform&lt;/span&gt; &lt;span style="color:#f92672"&gt;!==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;darwin&amp;#39;&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;quit&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;on&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;activate&amp;#39;&lt;/span&gt;, () =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 在macOS上，当单击dock图标并且没有其他窗口打开时，
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 通常在应用程序中重新创建一个窗口。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;win&lt;/span&gt; &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;createWindow&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 在这个文件中，你可以续写应用剩下主进程代码。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 也可以拆分成几个文件，然后用 require 导入。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// ipc通讯相关代码
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 登录窗口最小化
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;ipcMain&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;on&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;window-min&amp;#39;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;win&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;minimize&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 登录窗口最大化
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;ipcMain&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;on&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;window-max&amp;#39;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;win&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;isMaximized&lt;/span&gt;()) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;win&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;restore&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;win&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;maximize&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;ipcMain&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;on&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;window-close&amp;#39;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;win&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;close&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="5-packagejson-文件修改"&gt;5. package.json 文件修改&lt;/h2&gt;
&lt;p&gt;添加main.js的位置与npm scripts electron命令&lt;/p&gt;</description></item><item><title>记2018年最后一次前端分享(提供Slides)</title><link>https://time-friend.com/zh/archive/2018-last-frontend-sharing-with-slides/</link><pubDate>Thu, 13 Dec 2018 21:32:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/2018-last-frontend-sharing-with-slides/</guid><description>&lt;script src='https://time-friend.com/js/lazyload.js'&gt;&lt;/script&gt;
&lt;script&gt;
 $(function(){
 let str = ""
 for(var i = 2;i&lt;=81;i++){
 var count ="";
 if(i&lt;10){
 count = "00"+ i;
 }else if(i&lt;100&amp;&amp;i&gt;=10){
 count = "0"+ i;
 }
 
 str = str + '&lt;img class="lazyload" data-src="https://static.alili.tech/images/slides/vueConfSlides/vueConfSlides.'+ count +'.jpeg" style="margin-bottom:10px" src="https://time-friend.com/images/squares.svg" /&gt;'
 }
 $('.imageBox').html(str)
 var images = document.querySelectorAll(".lazyload");
 lazyload(images);
 })
&lt;/script&gt;
&lt;div class='imageBox'&gt;&lt;/div&gt;</description></item><item><title>使用husky提升Code-Review的效率</title><link>https://time-friend.com/zh/archive/husky-code-review/</link><pubDate>Tue, 04 Dec 2018 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/husky-code-review/</guid><description>&lt;p&gt;在code review的时候,代码风格是其中审查的指标之一.在审查代码风格其实是有一定工作量的.&lt;/p&gt;
&lt;p&gt;为了减少代码审查的工作量,我们何不把代码风格在提交代码之前就规范掉?&lt;/p&gt;
&lt;p&gt;这样我们就可以在代码审查中节约出很多时间,来做更多的其他更有意义的事情.&lt;/p&gt;
&lt;h1 id="git-hooks"&gt;git hooks&lt;/h1&gt;
&lt;p&gt;在git中提供了hook,就是在触发&lt;code&gt;代码提交&lt;/code&gt;,&lt;code&gt;push&lt;/code&gt;等一系列操作的时候,提供了触发其他程序的钩子.&lt;/p&gt;
&lt;p&gt;如何操作,本文不多赘述.&lt;/p&gt;
&lt;p&gt;有兴趣的同学可以查看文档: &lt;a href="https://git-scm.com/docs/githooks"&gt;https://git-scm.com/docs/githooks&lt;/a&gt;&lt;/p&gt;
&lt;h1 id="husky"&gt;husky&lt;/h1&gt;
&lt;p&gt;如果看过githooks的文档,是不是觉得会有一点繁琐?&lt;/p&gt;
&lt;p&gt;这里介绍一个工具 &lt;code&gt;husky&lt;/code&gt; 可以解决你的问题.&lt;/p&gt;
&lt;h3 id="安装"&gt;安装&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;npm install husky --save-dev
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后修改 package.json，增加配置：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;husky&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;hooks&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;pre-commit&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;eslint .&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果你只是局部安装了 &lt;code&gt;eslint&lt;/code&gt;,请使用以下配置&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;lint-staged&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;src/**/*.js&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;node_modules/.bin/eslint&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;最后尝试 Git 提交，你就会很快收到反馈：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git commit -m &lt;span style="color:#e6db74"&gt;&amp;#34;this is a commit&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这样,我们就可以在代码提交之前验证一下我们的代码lint是否通过.&lt;/p&gt;
&lt;p&gt;对于一些以前从来没有用过eslint的项目来说.突然引入这种工具.&lt;/p&gt;
&lt;p&gt;你可能面临的是把所有文件都按照eslint都格式化一遍.那不是疯了吗?&lt;/p&gt;
&lt;h1 id="lint-staged"&gt;lint-staged&lt;/h1&gt;
&lt;p&gt;这里再安利一个工具,可以实现 eslint只检查本次提交的文件.
这样我们就可以做到渐进式的改善我们的代码质量.&lt;/p&gt;
&lt;h3 id="安装-1"&gt;安装&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;npm install lint-staged --save-dev
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="修改-packagejson-配置"&gt;修改 package.json 配置：&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;husky&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;hooks&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;pre-commit&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;lint-staged&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;lint-staged&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;src/**/*.js&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;eslint&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="在lint-staged执行前执行更多的自定义命令"&gt;在lint-staged执行前执行更多的自定义命令&lt;/h2&gt;
&lt;p&gt;这一点让我非常的喜欢,为我们提供了更多的自由度.&lt;/p&gt;</description></item><item><title>让团队保持Code-Review习惯的三大法宝</title><link>https://time-friend.com/zh/archive/code-review-habits/</link><pubDate>Fri, 30 Nov 2018 14:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/code-review-habits/</guid><description>&lt;p&gt;之前跟大家聊过代码审查,想要在团队中保持团队代码审查习惯,是相当困难的.
我们必须要有合理的流程,工具与制度的支持,才能基本保证我们代码审查效率与质量.&lt;/p&gt;
&lt;h1 id="流程支持gitflow"&gt;流程支持:Gitflow&lt;/h1&gt;
&lt;p&gt;之前有介绍Gitflow的工作流.&lt;/p&gt;
&lt;p&gt;大致如下:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;开发者在本地仓库中新建一个专门的分支开发功能。&lt;/li&gt;
&lt;li&gt;开发者push分支修改到公开的Git仓库中。&lt;/li&gt;
&lt;li&gt;开发者通过Git发起一个Merge Request。&lt;/li&gt;
&lt;li&gt;团队的其它成员代码审查，讨论并修改。&lt;/li&gt;
&lt;li&gt;项目维护者合并功能到官方仓库中并关闭Merge Request。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="工具支持"&gt;工具支持&lt;/h1&gt;
&lt;h2 id="强制使用eslint"&gt;强制使用eslint&lt;/h2&gt;
&lt;p&gt;强制使用eslint,在代码未提交之前,是用husky等工具做强制eslint.
保证提交之后的代码,必须先过一遍eslint.&lt;/p&gt;
&lt;h2 id="规范提交代码的类型"&gt;规范提交代码的类型&lt;/h2&gt;
&lt;p&gt;我们自己内部开发了一款简单的命令行工具,可以在我们提交代码的时候,定义本次提交的类型.&lt;/p&gt;
&lt;p&gt;方便我们后续在代码审查的时候,更加容易的理解修改的内容.&lt;/p&gt;
&lt;h3 id="类型如下"&gt;类型如下&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;bug修复&lt;/li&gt;
&lt;li&gt;新特性&lt;/li&gt;
&lt;li&gt;样式修复&lt;/li&gt;
&lt;li&gt;代码重构&lt;/li&gt;
&lt;li&gt;测试代码&lt;/li&gt;
&lt;li&gt;代码回滚&lt;/li&gt;
&lt;li&gt;bug修复&lt;/li&gt;
&lt;li&gt;文档更新&lt;/li&gt;
&lt;li&gt;临时提交&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="命令行使用方式"&gt;命令行使用方式&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;? What do you want to do? 代码提交
? 请选择Git提交类型？ (Use arrow keys)
❯ * fixed : bug修复
 * feature : 新特性
 * style : 样式修复
 * refactor : 代码重构
 * test : 测试代码
 * revert : 代码回滚
 * doc : 文档更新
(Move up and down to reveal more choices)
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="code-climate"&gt;Code Climate&lt;/h2&gt;
&lt;p&gt;Code Climate是一款代码测试工具,它可以帮助你进行代码冗余检测、质量评估，同时支持多种语言，如PHP, Ruby, JavaScript, CSS, Golang, Python 等。&lt;/p&gt;</description></item><item><title>cheeriojs加载html时中文会默认解析成unicode的问题</title><link>https://time-friend.com/zh/archive/cheeriojs-chinese-parsed-to-unicode-issue/</link><pubDate>Thu, 29 Nov 2018 20:32:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/cheeriojs-chinese-parsed-to-unicode-issue/</guid><description>&lt;h2 id="cheeriojs-解析中文为unicode问题"&gt;cheeriojs 解析中文为unicode问题&lt;/h2&gt;
&lt;p&gt;在使用&lt;code&gt;cheeriojs&lt;/code&gt;的时候我发现,每当使用&lt;code&gt;html&lt;/code&gt;方法,中文会默认解析成 unicode.&lt;/p&gt;
&lt;p&gt;使用方式如下:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;cheerio&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;cheerio&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;cheerio&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;load&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;&amp;lt;title&amp;gt;我是中文,我将会被解析成unicode&amp;lt;/title&amp;gt;&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;$&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;title&amp;#39;&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;html&lt;/span&gt;());
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;当使用&lt;code&gt;text&lt;/code&gt;方法的时候,并不会出现以上问题&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;cheerio&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;cheerio&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;cheerio&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;load&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;&amp;lt;title&amp;gt;我是中文,我将会被解析成unicode&amp;lt;/title&amp;gt;&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;$&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;title&amp;#39;&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;text&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="解决"&gt;解决&lt;/h2&gt;
&lt;h3 id="默认配置"&gt;默认配置&lt;/h3&gt;
&lt;p&gt;当我们load html内容的时候,其实&lt;code&gt;cheerio&lt;/code&gt;是有默认配置的.
html解析是使用的&lt;code&gt;htmlparser2&lt;/code&gt;这个库,所以&lt;code&gt;htmlparser2&lt;/code&gt;的配置在cheerio也是适用的.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;cheerio&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;cheerio&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;cheerio&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;load&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;&amp;lt;title&amp;gt;我是中文,我将会被解析成unicode&amp;lt;/title&amp;gt;&amp;#39;&lt;/span&gt;,{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;withDomLvl1&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;normalizeWhitespace&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;xmlMode&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;decodeEntities&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="修改默认配置"&gt;修改默认配置&lt;/h3&gt;
&lt;p&gt;我们只需要将&lt;code&gt;decodeEntities&lt;/code&gt;修改成 false,就可以解决我们的问题.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;decodeEntities&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;像这样&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;cheerio&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;cheerio&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;cheerio&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;load&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;&amp;lt;title&amp;gt;我是中文,我将不会被解析成unicode&amp;lt;/title&amp;gt;&amp;#39;&lt;/span&gt;,{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;decodeEntities&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>从前端角度来看声明式编程与命令式编程</title><link>https://time-friend.com/zh/archive/declarative-vs-imperative-programming/</link><pubDate>Mon, 26 Nov 2018 11:46:35 +0000</pubDate><guid>https://time-friend.com/zh/archive/declarative-vs-imperative-programming/</guid><description>&lt;h1 id="引入概念"&gt;引入概念&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;声明式编程：告诉“机器”你想要的是什么(what)，让机器想出如何去做(how)。&lt;/li&gt;
&lt;li&gt;命令式编程：命令“机器”如何去做事情(how)，这样不管你想要的是什么(what)，它都会按照你的命令实现。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;怎么去解释以上两句话呢?&lt;/p&gt;
&lt;p&gt;我们带着这两个概念,用我们最熟悉的技术来解释两种编程范式&lt;/p&gt;
&lt;h1 id="声明式编程-declarative-programming"&gt;声明式编程 （Declarative Programming）&lt;/h1&gt;
&lt;p&gt;告诉“机器”你想要的是什么(what)，让机器想出如何去做(how)。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...more code
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;head&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;body&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;box&amp;#34;&lt;/span&gt;&amp;gt;声明式编程&amp;lt;/&lt;span style="color:#f92672"&gt;div&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;body&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;html&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;#box {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;width&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;100&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;height&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;100&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;color&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;#fff&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;background&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;#000&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="命令式编程-imperative-programming"&gt;命令式编程 (Imperative Programming）&lt;/h1&gt;
&lt;p&gt;命令“机器”如何去做事情(how)，这样不管你想要的是什么(what)，它都会按照你的命令实现。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;oDIv&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; document.&lt;span style="color:#a6e22e"&gt;createElement&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;div&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;text&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; document.&lt;span style="color:#a6e22e"&gt;createTextNode&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;命令式编程&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;oDIv&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;appendChild&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;text&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;oDIv&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;id&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;box&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;oDIv&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;style&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;width&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;100&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;px&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;oDIv&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;style&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;height&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;100&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;px&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;oDIv&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;style&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;color&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;#FFF&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;oDIv&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;style&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;background&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;#000&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;document.&lt;span style="color:#a6e22e"&gt;body&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;appendChild&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;oDIv&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="总结"&gt;总结&lt;/h1&gt;
&lt;p&gt;以上两个例子,得到的结果是一模一样的.&lt;/p&gt;
&lt;p&gt;在我看来,声明式的背后是代码实现的高度抽象,声明式会让工作得到简化.&lt;/p&gt;</description></item><item><title>Angular模板的安全导航( ?. )</title><link>https://time-friend.com/zh/archive/angular-safe-navigation-operator/</link><pubDate>Sun, 25 Nov 2018 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/angular-safe-navigation-operator/</guid><description>&lt;p&gt;这是非常实用,也是在Angular开发中经常要使用的操作符.
而在react于vue中原生并不自带这样的特性.&lt;/p&gt;
&lt;h1 id="安全导航操作符---"&gt;安全导航操作符 ( ?. )&lt;/h1&gt;
&lt;p&gt;在我们日常开发中,在访问属性路径的时候.&lt;/p&gt;
&lt;p&gt;如果因为一些客观原因导致了路径中出现了 &lt;code&gt;null&lt;/code&gt;,&lt;code&gt;undefined&lt;/code&gt;,再往下取值,整个程序就会直接报错.导致程序不能往下运行.&lt;/p&gt;
&lt;p&gt;举个例子&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;{ &lt;span style="color:#75715e"&gt;// 有时候,有可能这个属性不存在
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;d&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt; &lt;span style="color:#75715e"&gt;//正常取值
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt; &lt;span style="color:#75715e"&gt;//如果这个属性有时候不存在,这样取值的话,也只是取到一个 undefined,并不会报错
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt; &lt;span style="color:#75715e"&gt;//当b属性不存在的时候,在undefined下取值,就绝对会造成程序崩溃
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;安全导航就是要解决以上都问题,我们只要在不确定的属性前的 &lt;code&gt;.&lt;/code&gt;改成 &lt;code&gt;?.&lt;/code&gt;就可以不需要报错了,当没有取到值的时候,会默认为空.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ &lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;&lt;span style="color:#f92672"&gt;?&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;&lt;span style="color:#f92672"&gt;?&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt; }}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在写模板的时候是不是很方便呢? 简直不能太棒了好伐~&lt;/p&gt;
&lt;p&gt;妈妈再也不用担心后台给的数据很奇怪导致我前端报错了~~~~~&lt;/p&gt;</description></item><item><title>使用Travis CI自动化部署你的Hugo,Hexo博客</title><link>https://time-friend.com/zh/archive/automated-deployment-hugo-hexo-blog-with-travis-ci/</link><pubDate>Tue, 20 Nov 2018 16:14:25 +0000</pubDate><guid>https://time-friend.com/zh/archive/automated-deployment-hugo-hexo-blog-with-travis-ci/</guid><description>&lt;h1 id="travis-ci-是什么"&gt;Travis CI 是什么?&lt;/h1&gt;
&lt;p&gt;Travis CI 是在线托管的 CI 服务，用 Travis 来进行持续集成，不需要自己搭服务器。最重要的是，它对开源项目是免费的。
如果公司是用的是 gitlab,也有提供相应的持续集成服务.这里就过多赘述.&lt;/p&gt;
&lt;h1 id="travis-ci-配置文件"&gt;Travis CI 配置文件&lt;/h1&gt;
&lt;p&gt;Travis 要求项目的根目录下面，必须有一个&lt;code&gt;.travis.yml&lt;/code&gt;文件。&lt;/p&gt;
&lt;p&gt;当你的仓库有提交的时候,travis 会自动执行你下面配置的行为.&lt;/p&gt;
&lt;h1 id="travis-ci-的钩子与生命周期"&gt;Travis CI 的钩子与生命周期&lt;/h1&gt;
&lt;h2 id="travis-的钩子"&gt;Travis 的钩子&lt;/h2&gt;
&lt;p&gt;Travis 有不同的阶段,他提供了 7 个钩子。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;before_install：install 阶段之前执行&lt;/li&gt;
&lt;li&gt;before_script：script 阶段之前执行&lt;/li&gt;
&lt;li&gt;after_failure：script 阶段失败时执行&lt;/li&gt;
&lt;li&gt;after_success：script 阶段成功时执行&lt;/li&gt;
&lt;li&gt;before_deploy：deploy 步骤之前执行&lt;/li&gt;
&lt;li&gt;after_deploy：deploy 步骤之后执行&lt;/li&gt;
&lt;li&gt;after_script：script 阶段之后执行&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="生命周期"&gt;生命周期&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;before_install&lt;/li&gt;
&lt;li&gt;install&lt;/li&gt;
&lt;li&gt;before_script&lt;/li&gt;
&lt;li&gt;script&lt;/li&gt;
&lt;li&gt;aftersuccess or afterfailure&lt;/li&gt;
&lt;li&gt;[OPTIONAL] before_deploy&lt;/li&gt;
&lt;li&gt;[OPTIONAL] deploy&lt;/li&gt;
&lt;li&gt;[OPTIONAL] after_deploy&lt;/li&gt;
&lt;li&gt;after_script&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id="travisyml"&gt;.travis.yml&lt;/h1&gt;
&lt;p&gt;下面是我的博客部署配置,也是我项目&lt;code&gt;.travis.yml&lt;/code&gt;文件的内容.&lt;/p&gt;
&lt;h2 id="hugo"&gt;hugo&lt;/h2&gt;
&lt;p&gt;这是我的 hugo 部署配置,仅供参考&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;language&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;node_js&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;node_js&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;10.13.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;install&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;wget https://github.com/gohugoio/hugo/releases/download/v0.51/hugo_0.51_Linux-64bit.deb&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;sudo dpkg -i hugo*.deb&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;hugo version&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;rm -rf public&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;npm install&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;hugo --buildFuture&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;gulp&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;echo &amp;#39;Build done!&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;after_success&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;git config --global user.name &amp;#34;Fan&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;git config --global user.email &amp;#34;你的邮箱&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;git clone https://${ACCESS_TOKEN}@github.com/Num142857/alili.tech.git container&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;rm -rf container/*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;cp -r public/* container&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;cd container&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;git add .&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;git commit -m &amp;#39;Travis upate blog&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;git push -u origin gh-pages -f&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="hexo"&gt;Hexo&lt;/h2&gt;
&lt;p&gt;这是我的 hexo 部署配置,仅供参考.&lt;/p&gt;</description></item><item><title>让你的Hugo博客支持echarts图表</title><link>https://time-friend.com/zh/archive/make-your-hugo-blog-support-echarts-charts/</link><pubDate>Mon, 19 Nov 2018 16:14:25 +0000</pubDate><guid>https://time-friend.com/zh/archive/make-your-hugo-blog-support-echarts-charts/</guid><description>&lt;p&gt;在之前hexo构建的博客里,有使用到图表,但是现在迁移到hugo之后,就没有相关的插件支持了.&lt;/p&gt;
&lt;p&gt;所以自己动手丰衣足食.&lt;/p&gt;
&lt;p&gt;在hugo中有支持一种特性叫做 &lt;code&gt;Shortcodes&lt;/code&gt;.简单的来说就是一个可以传参的小模板.&lt;/p&gt;
&lt;h1 id="创建shortcodes"&gt;创建Shortcodes&lt;/h1&gt;
&lt;p&gt;创建 &lt;code&gt;./layouts/Shortcodes/echarts.html&lt;/code&gt;文件&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;echarts{{ .Get `height` }}&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;style&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;width: 100%;height: {{.Get `height`}}px;margin: 0 auto&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;div&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;https://cdn.bootcss.com/echarts/3.8.0/echarts.common.min.js&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;type&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;text/javascript&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 基于准备好的dom，初始化echarts实例
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;myChart&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;echarts&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;init&lt;/span&gt;(document.&lt;span style="color:#a6e22e"&gt;getElementById&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;echarts{{ .Get `height` }}&amp;#39;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 指定图表的配置项和数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;option&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;JSON&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;parse&lt;/span&gt;({{ .&lt;span style="color:#a6e22e"&gt;Inner&lt;/span&gt; }})
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 使用刚指定的配置项和数据显示图表。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;myChart&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;setOption&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;option&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="使用"&gt;使用&lt;/h1&gt;
&lt;p&gt;在 Shortcodes 插入echarts的配置数据,这样你就可以再页面中看到一个完整的图表了&lt;/p&gt;
&lt;div id='raw'&gt;
&lt;p style="opacity: 0;"&gt;
Time Friend - Be a friend of time, long-term thinking, documenting growth
本文资源来源互联网，仅供学习研究使用，版权归该资源的合法拥有者所有，
&lt;/p&gt;

 &lt;script&gt;
 $(function () {
 var html = "\n\u003cpre\u003e\n\u003ccode class=\u0022language-json hljs\u0022\u003e\n\u003cspan class=\u0022hljs-string\u0022\u003e\u0022{{\u0022\u003c\/span\u003e \u0026lt; echarts height=\u003cspan class=\u0022hljs-string\u0022\u003e\u0022400\u0022\u003c\/span\u003e \u0026gt; \u003cspan class=\u0022hljs-string\u0022\u003e\u0022}}\u0022\u003c\/span\u003e\n\u003cbr\u003e\n{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022textStyle\u0022\u003c\/span\u003e:{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022color\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022#fff\u0022\u003c\/span\u003e},\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022title\u0022\u003c\/span\u003e:{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022text\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u00222018年11月国内浏览器数据统计\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022subtext\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022浏览器数据分析\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022x\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022center\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022textStyle\u0022\u003c\/span\u003e:{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022color\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022#fff\u0022\u003c\/span\u003e}},\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022tooltip\u0022\u003c\/span\u003e:{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022trigger\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022item\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022formatter\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022{a} \u0026lt;br\/\u0026gt;{b} : {c} ({d}%)\u0022\u003c\/span\u003e},\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022legend\u0022\u003c\/span\u003e:{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022type\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022scroll\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022orient\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022vertical\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022right\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e10\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022top\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e120\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022bottom\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e20\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022data\u0022\u003c\/span\u003e:[\u003cspan class=\u0022hljs-string\u0022\u003e\u0022Chrome\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-string\u0022\u003e\u0022IE 9.0\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-string\u0022\u003e\u0022IE 11.0\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-string\u0022\u003e\u0022QQ\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-string\u0022\u003e\u0022IE 8.0\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-string\u0022\u003e\u00222345\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-string\u0022\u003e\u0022搜狗高速\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-string\u0022\u003e\u0022Firefox\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-string\u0022\u003e\u0022Safari\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-string\u0022\u003e\u0022其他\u0022\u003c\/span\u003e],\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022textStyle\u0022\u003c\/span\u003e:{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022color\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022#fff\u0022\u003c\/span\u003e}},\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022series\u0022\u003c\/span\u003e:[{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022name\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022浏览器用户比例\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022type\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022pie\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022radius\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u002255%\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022center\u0022\u003c\/span\u003e:[\u003cspan class=\u0022hljs-string\u0022\u003e\u002250%\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-string\u0022\u003e\u002260%\u0022\u003c\/span\u003e],\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022data\u0022\u003c\/span\u003e:[{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022name\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022Chrome\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022value\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e46.88\u003c\/span\u003e},{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022name\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022IE 9.0\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022value\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e7.4\u003c\/span\u003e},{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022name\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022IE 11.0\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022value\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e6.21\u003c\/span\u003e},{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022name\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022QQ\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022value\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e5.75\u003c\/span\u003e},{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022name\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022IE 8.0\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022value\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e5.74\u003c\/span\u003e},{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022name\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u00222345\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022value\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e5.68\u003c\/span\u003e},{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022name\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022搜狗高速\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022value\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e4.74\u003c\/span\u003e},{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022name\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022Firefox\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022value\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e2.54\u003c\/span\u003e},{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022name\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022Safari\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022value\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e2.48\u003c\/span\u003e},{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022name\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022其他\u0022\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022value\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e12.59\u003c\/span\u003e}],\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022itemStyle\u0022\u003c\/span\u003e:{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022emphasis\u0022\u003c\/span\u003e:{\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022shadowBlur\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e10\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022shadowOffsetX\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-number\u0022\u003e0\u003c\/span\u003e,\u003cspan class=\u0022hljs-attr\u0022\u003e\u0022shadowColor\u0022\u003c\/span\u003e:\u003cspan class=\u0022hljs-string\u0022\u003e\u0022rgba(0, 0, 0, 0.5)\u0022\u003c\/span\u003e}}}]}\n\u003cbr\u003e\n\u003cspan class=\u0022hljs-string\u0022\u003e\u0022{{\u0022\u003c\/span\u003e \u0026lt; \/echarts \u0026gt; \u003cspan class=\u0022hljs-string\u0022\u003e\u0022}}\u0022\u003c\/span\u003e\n\u003c\/code\u003e\n\u003c\/pre\u003e\n"
 html = html.replace(/"{/g, "{")
 html = html.replace(/{"/g, "{")
 html = html.replace(/"}/g, "}")
 html = html.replace(/}"/g, "}")
 $('#raw').html(html);

 let postTitle = $('.posttitle').text()
 let postContentTitle = $('#raw &gt; h1').text()
 if(postTitle === postContentTitle){
 $('#raw &gt; h1').hide()
 }
 $('button.preview').hide()
 })

 &lt;/script&gt;
&lt;/div&gt;

&lt;h1 id="效果"&gt;效果&lt;/h1&gt;
&lt;div id="echarts400" style="width: 100%;height: 400px;margin: 0 auto"&gt;&lt;/div&gt;
&lt;script src="https://cdn.bootcss.com/echarts/3.8.0/echarts.common.min.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;
 
 var myChart = echarts.init(document.getElementById('echarts400'));
 
 var option = JSON.parse("\n {\"textStyle\":{\"color\":\"#fff\"},\"title\":{\"text\":\"2018年11月国内浏览器数据统计\",\"subtext\":\"浏览器数据分析\",\"x\":\"center\",\"textStyle\":{\"color\":\"#fff\"}},\"tooltip\":{\"trigger\":\"item\",\"formatter\":\"{a} \u003cbr/\u003e{b} : {c} ({d}%)\"},\"legend\":{\"type\":\"scroll\",\"orient\":\"vertical\",\"right\":10,\"top\":120,\"bottom\":20,\"data\":[\"Chrome\",\"IE 9.0\",\"IE 11.0\",\"QQ\",\"IE 8.0\",\"2345\",\"搜狗高速\",\"Firefox\",\"Safari\",\"其他\"],\"textStyle\":{\"color\":\"#fff\"}},\"series\":[{\"name\":\"浏览器用户比例\",\"type\":\"pie\",\"radius\":\"55%\",\"center\":[\"50%\",\"60%\"],\"data\":[{\"name\":\"Chrome\",\"value\":46.88},{\"name\":\"IE 9.0\",\"value\":7.4},{\"name\":\"IE 11.0\",\"value\":6.21},{\"name\":\"QQ\",\"value\":5.75},{\"name\":\"IE 8.0\",\"value\":5.74},{\"name\":\"2345\",\"value\":5.68},{\"name\":\"搜狗高速\",\"value\":4.74},{\"name\":\"Firefox\",\"value\":2.54},{\"name\":\"Safari\",\"value\":2.48},{\"name\":\"其他\",\"value\":12.59}],\"itemStyle\":{\"emphasis\":{\"shadowBlur\":10,\"shadowOffsetX\":0,\"shadowColor\":\"rgba(0, 0, 0, 0.5)\"}}}]}\n")
 
 myChart.setOption(option);
&lt;/script&gt;</description></item><item><title>Hugo平台博文指定时间之后不显示?</title><link>https://time-friend.com/zh/archive/hugo-articles-not-displaying-after-specified-time/</link><pubDate>Sun, 18 Nov 2018 16:14:25 +0000</pubDate><guid>https://time-friend.com/zh/archive/hugo-articles-not-displaying-after-specified-time/</guid><description>&lt;p&gt;自从博客切换到Hugo之后,是遇到了一些坑.&lt;/p&gt;
&lt;p&gt;明明正确添加到文章,页面时间调整到今天,或者是今天之后缺不能显示在文章列表里.&lt;/p&gt;
&lt;p&gt;原因是Hugo模板在循环遍历文件的时候,只要超过当前时间的文章都不会出现.&lt;/p&gt;
&lt;h2 id="时区问题"&gt;时区问题&lt;/h2&gt;
&lt;p&gt;如果你的文章时间没有指定时区的话.&lt;/p&gt;
&lt;p&gt;像这样&lt;code&gt;2018-11-19 16:14:25&lt;/code&gt;,很有可能文章不会显示.&lt;/p&gt;
&lt;p&gt;Hugo时间统一为格林威治时间,因为中国的时间比格林威治时间早8个小时.
格林威治时间没有到你配置的时间的时候,文章是不会出现在文章列表里的.&lt;/p&gt;
&lt;h2 id="解决方案"&gt;解决方案&lt;/h2&gt;
&lt;p&gt;本地服务&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hugo server --buildFuture
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;页面生成&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hugo --buildFuture
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Hugo博客百度SEO终极优化,熊掌号自动推送</title><link>https://time-friend.com/zh/archive/hugo-template-seo-optimization/</link><pubDate>Sat, 17 Nov 2018 16:14:25 +0000</pubDate><guid>https://time-friend.com/zh/archive/hugo-template-seo-optimization/</guid><description>&lt;p&gt;在切换到Hugo平台之后,比较头疼的是之前hexo很多seo的插件不能使用了.
下面跟大家说一下我的seo优化方案.&lt;/p&gt;
&lt;h1 id="meta标签优化"&gt;Meta标签优化&lt;/h1&gt;
&lt;h2 id="description"&gt;Description&lt;/h2&gt;
&lt;p&gt;meta description，被认为是最有用的meta标签，是网站的简介信息。
content控制在100个字符以内比较好。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;meta&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;description&amp;#39;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;itemprop&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;description&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;{{ if .Description }}{{ .Description }}{{ else }}{{if .IsPage}}{{substr .Summary 0 100}}{{ end }}{{ end }}&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="keywords"&gt;Keywords&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ if .Keywords }} 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;meta&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;keywords&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;{{ delimit .Keywords &amp;#34;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;}}&amp;#34;&lt;/span&gt; &amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{else}}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;meta&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;keywords&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;{{ delimit .Site.Params.Keywords &amp;#34;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;}}&amp;#34;&lt;/span&gt; &amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ end }}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="百度熊掌号推送"&gt;百度熊掌号推送&lt;/h1&gt;
&lt;p&gt;说到seo熊掌号是必不可少的了,他可以做到24小时之内收录.所以这个必须不能放过.&lt;/p&gt;
&lt;h2 id="gulp"&gt;gulp&lt;/h2&gt;
&lt;p&gt;在这里我要使用gulp来做我的自动化任务管理工具&lt;/p&gt;
&lt;h3 id="安装gulp需要的模块"&gt;安装gulp需要的模块&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;npm init
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;npm install gulp --save
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;npm install xml2js --save
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;npm install xmlhttprequest --save
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="在项目根目录创建一个gulpfilejs文件"&gt;在项目根目录创建一个&lt;code&gt;gulpfile.js&lt;/code&gt;文件&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 导入相关依赖
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;gulp&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;gulp&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fs&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;fs&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;xml2js&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;xml2js&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;parser&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;xml2js&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Parser&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;XMLHttpRequest&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;xmlhttprequest&amp;#34;&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;XMLHttp&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 注册百度站长与熊掌号,百度会提供下面的数据给你
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;xz_appid&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;xxxxx&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;xz_token&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;xxxxx&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;baidu_token&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;xxxxx&amp;#39;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//熊掌号每天需要提交的url数量
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 注意这个数字必须要跟百度允许提交的url数量一致,如果多了会提交失败.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;xzCount&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 创建一个任务
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;gulp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;task&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;baiduSeo&amp;#39;&lt;/span&gt;, () =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 读取sitemap.xml文件并且转换成json
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fs&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;readFile&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;__dirname&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;/public/sitemap.xml&amp;#39;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;parser&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;parseString&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;result&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 把读取的数据传入这个函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;urlSubmit&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;result&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;urlset&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;url&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;Done&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 提交url的方法
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;urlSubmit&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;urls&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 最新内容提交
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;new_target&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;http://data.zz.baidu.com/urls?appid=&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;xz_appid&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;amp;token=&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;xz_token&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;amp;type=realtime&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 历史提交
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;history_target&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;http://data.zz.baidu.com/urls?appid=&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;xz_appid&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;amp;token=&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;xz_token&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;amp;type=batch&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 百度站长
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;baidu_target&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;http://data.zz.baidu.com/urls?site=https://你的域名&amp;amp;token=&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;baidu_token&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// MIP
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;MIP_target&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;http://data.zz.baidu.com/urls?site=https://你的域名&amp;amp;token=&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;baidu_token&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;amp;type=mip&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// AMP
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;AMP_target&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;http://data.zz.baidu.com/urls?site=https://你的域名&amp;amp;token=&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;baidu_token&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;amp;type=amp&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 最新url,看熊掌号情况而定
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;urls&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;urls&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;map&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;item&lt;/span&gt;=&amp;gt;&lt;span style="color:#a6e22e"&gt;item&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;loc&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;allUrls&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;urls&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;join&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;\n&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;new_urls_Arr&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;urls&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;slice&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;xzCount&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;new_urls&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;new_urls_Arr&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;join&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;\n&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;info&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;百度站长开始提交&amp;#39;&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;new_urls&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;sendData&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;baidu_target&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;new_urls&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;百度站长提交成功&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;info&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;熊掌号开始提交&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;sendData&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;new_target&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;new_urls&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;熊掌号提交完成&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 提交历史url 每天最多500w条
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;info&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;历史数据开始提交&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;sendData&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;history_target&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;allUrls&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;历史数据提交完成&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;info&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;MIP 开始提交&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;sendData&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;MIP_target&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;allUrls&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;MIP提交成功&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;info&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;AMP 开始提交&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;sendData&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;AMP_target&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;allUrls&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;AMP提交成功&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 提交数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;sendData&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;target&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;urls&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;message&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;xhr&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;XMLHttpRequest&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;xhr&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;open&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;POST&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;target&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;xhr&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;setRequestHeader&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;Content-type&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;text/plain&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;xhr&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;onload&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; () {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;responseText&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;message&lt;/span&gt;){&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;info&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;message&lt;/span&gt;)}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;xhr&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;send&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;urls&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;gulp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;task&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;default&amp;#34;&lt;/span&gt;,[
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;baiduSeo&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;配置好以上都文件之后&lt;/p&gt;</description></item><item><title>博客构建工具Hugo的基本使用</title><link>https://time-friend.com/zh/archive/basic-usage-of-hugo-blog-building-tool/</link><pubDate>Thu, 15 Nov 2018 16:14:25 +0000</pubDate><guid>https://time-friend.com/zh/archive/basic-usage-of-hugo-blog-building-tool/</guid><description>&lt;p&gt;最终还是把博客迁移到了&lt;code&gt;Hugo&lt;/code&gt;,当初最纠结的是这套主题在&lt;code&gt;Hugo&lt;/code&gt;平台上没有.
但是脑子一热，花了两三天时间。这套主题。全部迁移到了&lt;code&gt;Hugo&lt;/code&gt;平台。
接下来就给大家介绍一下&lt;code&gt;Hugo&lt;/code&gt;的使用以及踩到的坑,以及解决方案.&lt;/p&gt;
&lt;h1 id="hugo的性能"&gt;Hugo的性能&lt;/h1&gt;
&lt;p&gt;正是因为hexo的性能不能满足,在生成静态文件的时候极其不稳定.而且时间也相对比较长一些.
在相同页面数量的情况下,处理速度hugo是hexo20倍及以上.这才是我换Hugo的原因.&lt;/p&gt;
&lt;h1 id="配置文件"&gt;配置文件&lt;/h1&gt;
&lt;p&gt;两个平台有很多共通的地方,迁移起来有很多工作是非常顺其自然的.
在配置文件上hugo也是可以使用yaml的,所以从hexo迁移过来会相对好很多.
其次hugo还可以使用json作为配置文件,为用户提供了很多选择.&lt;/p&gt;
&lt;h1 id="hugo的基本使用"&gt;Hugo的基本使用&lt;/h1&gt;
&lt;h2 id="mac平台下"&gt;Mac平台下&lt;/h2&gt;
&lt;p&gt;Mac下Hugo提供了homebrew安装的方式，非常简便。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew install hugo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Debian and Ubuntu平台下&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt-get install hugo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="windows平台下"&gt;Windows平台下&lt;/h2&gt;
&lt;p&gt;Windows下Hugo提供了Chocolatey方式的安装，通过如下命令即可。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;choco install hugo -confirm
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;验证安装&lt;/p&gt;
&lt;p&gt;安转完成后，我们打开终端，输入如下命令进行验证是否安装成功&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;hugo version
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="创建一个站点"&gt;创建一个站点&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;hugo new site quickstart
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="添加一个主题"&gt;添加一个主题&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cd quickstart;\
git init;\
git submodule add https://github.com/budparr/gohugo-theme-ananke.git themes/ananke;\

# 编辑你的 config.toml 配置文件
# 添加一个叫 Ananke 的主题
echo &amp;#39;theme = &amp;#34;ananke&amp;#34;&amp;#39; &amp;gt;&amp;gt; config.toml
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="新建一篇文章"&gt;新建一篇文章&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;hugo new posts/my-first-post.md
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="本地开启hugo服务"&gt;本地开启Hugo服务&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;hugo server -D
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="构建静态站点"&gt;构建静态站点&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;hugo
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Hexo Process Out of Memory 内存溢出问题</title><link>https://time-friend.com/zh/archive/hexo-process-out-of-memory/</link><pubDate>Tue, 13 Nov 2018 21:32:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/hexo-process-out-of-memory/</guid><description>&lt;h2 id="hexo内存溢出问题"&gt;hexo内存溢出问题&lt;/h2&gt;
&lt;p&gt;当hexo生成文章大概在1000左右的时候,便有可能出现该问题.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="解决方法"&gt;解决方法:&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 找到hexo 命令的位置&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;which hexo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;编辑hexo命令的bin文件的第一行为以下内容.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#!/usr/bin/env node --max_old_space_size=8192
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;便暂时解决内存溢出的问题.&lt;/p&gt;
&lt;h2 id="hexo的性能"&gt;hexo的性能&lt;/h2&gt;
&lt;p&gt;hexo的性能相对hugo确实差太多,同样1000+的页面,用hugo却只用了不到2s.
这让我开始开始犹豫是否要放弃使用hexo.&lt;/p&gt;</description></item><item><title>Code-Review工具推荐以及使用报告</title><link>https://time-friend.com/zh/archive/code-review-tools/</link><pubDate>Mon, 12 Nov 2018 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/code-review-tools/</guid><description>&lt;p&gt;随之团队的扩大，统一编码规范，提高编码质量，变得尤为重要。代码审查作为可以有效提高代码质量的方式之一,有必要在公司推行代码审查制度.
让团队养成代码审查的习惯,提高代码质量,提前规避不必要的问题.&lt;/p&gt;
&lt;p&gt;为了更加高效的代码审核,需要一款代码审查工具.所以才有了这份使用报告.&lt;/p&gt;
&lt;p&gt;下面是我在使用中,尝试使用的一些工具.以及一些使用上的评价与总结.&lt;/p&gt;
&lt;h3 id="1codestriker"&gt;1) &lt;a href="http://codestriker.sourceforge.net/index.html" title="best code review tools for programmers "&gt;CodeStriker&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;CodeStriker免费和开源的web应用程序,可以帮助开发人员基于web的代码审查。开发者canensures问题,评论和决策是记录在一个数据库,并提供一个舒适的工作空间实际执行代码检查。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://i0.wp.com/devzum.com/wp-content/uploads/2015/04/codestriker-e1427936836285.png"&gt;&lt;img src="http://i0.wp.com/devzum.com/wp-content/uploads/2015/04/codestriker-e1427936836285.png?resize=600%2C480" alt="技术分享"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;价格: 免费&lt;/li&gt;
&lt;li&gt;UI交互: ★&lt;/li&gt;
&lt;li&gt;安装维护 :★★★&lt;/li&gt;
&lt;li&gt;易学程度: ★★★★★&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;总结: CodeStriker 对于一个代码审查工具来说,功能上已经可以基本满足.但是因为开发时间太过久远,已经很长时间没有人在维护了,而且UI比较有历史的味道.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="2rhodecode"&gt;2) &lt;a href="https://rhodecode.com/" title="best code review tools for programmers "&gt;RhodeCode&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;RhodeCode也是一个很好的工具,回顾你的代码并找出代码中的bug和问题并删除后检查代码。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://i0.wp.com/devzum.com/wp-content/uploads/2015/04/rhodecode-e1427936979546.png"&gt;&lt;img src="http://i0.wp.com/devzum.com/wp-content/uploads/2015/04/rhodecode-e1427936979546.png?resize=600%2C375" alt="技术分享"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;价格: 社区版本免费,企业版本收费&lt;/li&gt;
&lt;li&gt;UI交互: ★★★★&lt;/li&gt;
&lt;li&gt;安装维护 :★★★&lt;/li&gt;
&lt;li&gt;易学程度: ★★★★★&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;总结: RhodeCode在使用使用过程中,还是比较优秀的.工具的安装部署使用docker也比较方便.使用上比较顺畅,可以作为使用的备选软件.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="3code-brag"&gt;3) &lt;a href="http://codebrag.com/" title="best code review tools for programmers "&gt;Code Brag&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Codebrag是一个简单的和轻量级的工具,代码审查,让这一过程为您的团队工作。它有助于解决一些问题像非阻塞的代码评审,智能电子邮件通知,内联注释,喜欢得多。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://i0.wp.com/devzum.com/wp-content/uploads/2015/04/codeberg-e1427937091542.png"&gt;&lt;img src="http://i0.wp.com/devzum.com/wp-content/uploads/2015/04/codeberg-e1427937091542.png?resize=600%2C375" alt="技术分享"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;价格: 免费&lt;/li&gt;
&lt;li&gt;UI交互: ★★★★&lt;/li&gt;
&lt;li&gt;安装维护 :★★★★&lt;/li&gt;
&lt;li&gt;易学程度: ★★★★★&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;总结: Codebrag 是一款开源工具,安装起来不算难.也有一定程度上的社交属性.在使用期间官网在国内打不开,软件的安装资源不是很好获取.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="4phabricator"&gt;4) &lt;a href="http://phabricator.org/" title="best code review tools for programmers "&gt;Phabricator&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Phabricator是一个开源软件和web应用程序包括代码评审,主持GIT / Hg / SVN,发现错误时,浏览源代码和审计等&lt;/p&gt;</description></item><item><title>如何通过 Code-Review 帮助团队提升代码质量</title><link>https://time-friend.com/zh/archive/code-review-quality/</link><pubDate>Thu, 08 Nov 2018 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/code-review-quality/</guid><description>&lt;h1 id="代码审查解决方案"&gt;代码审查解决方案&lt;/h1&gt;
&lt;p&gt;最近在推进公司的代码审查.
经过几天的研究之后,整理出一些问题与解决方案.&lt;/p&gt;
&lt;h2 id="当前面临的问题"&gt;当前面临的问题&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;没有一个好的工具方便代码审查&lt;/li&gt;
&lt;li&gt;没有一个好的代码标准代码审查&lt;/li&gt;
&lt;li&gt;没有一个流程强制执行代码审查&lt;/li&gt;
&lt;li&gt;没有一个固定职责的人来代码审查&lt;/li&gt;
&lt;li&gt;代码审查之后的修改跟踪问题&lt;/li&gt;
&lt;li&gt;代码审查者与代码修复者鼓励机制&lt;/li&gt;
&lt;li&gt;跨团队资源调配的时候,容易造成过多的代码&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="解决方案"&gt;解决方案&lt;/h1&gt;
&lt;h2 id="加入merge-request工作流"&gt;加入Merge Request工作流&lt;/h2&gt;
&lt;p&gt;在Gitlab上做代码审查,我们需要在我们现有的git工作流上加入Merge Request.&lt;/p&gt;
&lt;h2 id="工作方式"&gt;工作方式&lt;/h2&gt;
&lt;p&gt;Merge Request可以和功能分支工作流、Gitflow工作流或Forking工作流一起使用。过程是这样的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;开发者在本地仓库中新建一个专门的分支开发功能。&lt;/li&gt;
&lt;li&gt;开发者push分支修改到公开的Git仓库中。&lt;/li&gt;
&lt;li&gt;开发者通过Git发起一个Merge Request。&lt;/li&gt;
&lt;li&gt;团队的其它成员代码审查，讨论并修改。&lt;/li&gt;
&lt;li&gt;项目维护者合并功能到官方仓库中并关闭Merge Request。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="结合到我们现有工作流当中"&gt;结合到我们现有工作流当中&lt;/h2&gt;
&lt;p&gt;我们现在代码管理的工作流叫: Gitflow工作流&lt;/p&gt;
&lt;p&gt;Gitflow工作流和功能分支工作流类似，但围绕项目发布定义一个严格的分支模型。&lt;/p&gt;
&lt;p&gt;在Gitflow工作流中使用Merge Request让开发者在发布分支或是维护分支上工作时，可以有个方便的地方对关于发布分支或是维护分支的问题进行交流。&lt;/p&gt;
&lt;p&gt;Gitflow工作流中Merge Request的使用过程：当一个功能、发布或是热修复分支需要Review时，开发者简单发起一个Merge Request，团队的其它成员会通过Bitbucket收到通知。&lt;/p&gt;
&lt;p&gt;新功能一般合并到develop分支，而发布和热修复则要同时合并到develop分支和master分支上。Merge Request可能用做所有合并的正式管理。&lt;/p&gt;
&lt;h1 id="审查流程"&gt;审查流程&lt;/h1&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-flow" data-lang="flow"&gt;开始=&amp;gt;start: 代码作者通过git 克隆代码到本地
结束=&amp;gt;end: 结束代码审查
修改代码=&amp;gt;operation: 修改代码并且提交
pr=&amp;gt;operation: 发起 Merge Request
通知=&amp;gt;operation: gitlab 通知相关审核人员
审核=&amp;gt;operation: 审核人员开始审核代码
关闭=&amp;gt;operation: 关闭Merge Request
合并=&amp;gt;operation: 合并代码
代码审核中=&amp;gt;condition: 是否过审

开始-&amp;gt;修改代码-&amp;gt;pr-&amp;gt;通知-&amp;gt;审核-&amp;gt;代码审核中
关闭-&amp;gt;合并-&amp;gt;结束
代码审核中(yes)-&amp;gt;关闭
代码审核中(no)-&amp;gt;修改代码
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id="结合gitlab做代码审查"&gt;结合GitLab做代码审查&lt;/h1&gt;
&lt;h2 id="项目角色介绍"&gt;项目角色介绍&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;角色&lt;/th&gt;
					&lt;th&gt;描述&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Owner&lt;/td&gt;
					&lt;td&gt;Git 系统管理员&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Master&lt;/td&gt;
					&lt;td&gt;Git 项目开发人员&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Reporter&lt;/td&gt;
					&lt;td&gt;Git 项目测试人员&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Guest&lt;/td&gt;
					&lt;td&gt;访客&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="角色权限"&gt;角色权限&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://img-blog.csdn.net/20171124111537924?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbWFzdGVyX3lhbw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt=""&gt;&lt;/p&gt;</description></item><item><title>升级Mac 10.14 mojave后辅助功能空白无法添加问题</title><link>https://time-friend.com/zh/archive/mac-10-14-mojave-accessibility-blank-cannot-add-issue/</link><pubDate>Sun, 04 Nov 2018 22:30:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/mac-10-14-mojave-accessibility-blank-cannot-add-issue/</guid><description>&lt;p&gt;最近系统升级到Mac mojave 10.14后发现安全性与隐私中的辅助功能是空白的,而且App无论如何都添加不了。
我的macbook pro正常,但是我的mac mini 出现了该问题.让人很是头疼.&lt;/p&gt;
&lt;h1 id="问题原因"&gt;问题原因&lt;/h1&gt;
&lt;p&gt;应该是升级导致&lt;code&gt;/Library/Application\ Support/com.apple.TCC&lt;/code&gt;损坏或权限异常,出现了问题.&lt;/p&gt;
&lt;h1 id="解决方法"&gt;解决方法&lt;/h1&gt;
&lt;p&gt;执行下面两行命令后重启系统,就可以恢复正常.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo chmod &lt;span style="color:#ae81ff"&gt;777&lt;/span&gt; /Library/Application&lt;span style="color:#ae81ff"&gt;\ &lt;/span&gt;Support/com.apple.TCC
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo rm -rf /Library/Application&lt;span style="color:#ae81ff"&gt;\ &lt;/span&gt;Support/com.apple.TCC/TCC.db
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 重启系统&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>2018年11月国内浏览器数据统计</title><link>https://time-friend.com/zh/archive/2018-11-browser-statistics/</link><pubDate>Thu, 01 Nov 2018 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/2018-11-browser-statistics/</guid><description>&lt;div id="echarts400" style="width: 100%;height: 400px;margin: 0 auto"&gt;&lt;/div&gt;
&lt;script src="https://cdn.bootcss.com/echarts/3.8.0/echarts.common.min.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;
 
 var myChart = echarts.init(document.getElementById('echarts400'));
 
 var option = JSON.parse("\n {\"textStyle\":{\"color\":\"#fff\"},\"title\":{\"text\":\"2018年11月国内浏览器数据统计\",\"subtext\":\"浏览器数据分析\",\"x\":\"center\",\"textStyle\":{\"color\":\"#fff\"}},\"tooltip\":{\"trigger\":\"item\",\"formatter\":\"{a} \u003cbr/\u003e{b} : {c} ({d}%)\"},\"legend\":{\"type\":\"scroll\",\"orient\":\"vertical\",\"right\":10,\"top\":120,\"bottom\":20,\"data\":[\"Chrome\",\"IE 9.0\",\"IE 11.0\",\"QQ\",\"IE 8.0\",\"2345\",\"搜狗高速\",\"Firefox\",\"Safari\",\"其他\"],\"textStyle\":{\"color\":\"#fff\"}},\"series\":[{\"name\":\"浏览器用户比例\",\"type\":\"pie\",\"radius\":\"55%\",\"center\":[\"50%\",\"60%\"],\"data\":[{\"name\":\"Chrome\",\"value\":46.88},{\"name\":\"IE 9.0\",\"value\":7.4},{\"name\":\"IE 11.0\",\"value\":6.21},{\"name\":\"QQ\",\"value\":5.75},{\"name\":\"IE 8.0\",\"value\":5.74},{\"name\":\"2345\",\"value\":5.68},{\"name\":\"搜狗高速\",\"value\":4.74},{\"name\":\"Firefox\",\"value\":2.54},{\"name\":\"Safari\",\"value\":2.48},{\"name\":\"其他\",\"value\":12.59}],\"itemStyle\":{\"emphasis\":{\"shadowBlur\":10,\"shadowOffsetX\":0,\"shadowColor\":\"rgba(0, 0, 0, 0.5)\"}}}]}\n")
 
 myChart.setOption(option);
&lt;/script&gt;</description></item><item><title>在Webpack与Systemjs中构建你的Single-SPA微前端应用</title><link>https://time-friend.com/zh/archive/single-spa-webpack-systemjs/</link><pubDate>Wed, 31 Oct 2018 01:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/single-spa-webpack-systemjs/</guid><description>&lt;p&gt;这里给大家介绍一下基于Single-SPA编写的微前端应用在各种当下流行的构建工具中的使用方法.&lt;/p&gt;
&lt;h1 id="webpack-2"&gt;Webpack 2+&lt;/h1&gt;
&lt;p&gt;在Webpack 2+版本中,支持import（）做代码分片. 在其他项目中 webpack2+的使用已经相当的广泛,这里就不做过多赘述.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; {&lt;span style="color:#a6e22e"&gt;registerApplication&lt;/span&gt;} &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;single-spa&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;registerApplication&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;app-name&amp;#39;&lt;/span&gt;, () =&amp;gt; &lt;span style="color:#66d9ef"&gt;import&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./my-app.js&amp;#39;&lt;/span&gt;), &lt;span style="color:#a6e22e"&gt;activeWhen&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;activeWhen&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; window.&lt;span style="color:#a6e22e"&gt;location&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;pathname&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;indexOf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;/my-app&amp;#39;&lt;/span&gt;) &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="systemjs"&gt;SystemJS&lt;/h1&gt;
&lt;p&gt;在之前我们的项目中使用的就是SystemJS,方便部署应用后的二次构建.用起来页非常的方便.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; {&lt;span style="color:#a6e22e"&gt;registerApplication&lt;/span&gt;} &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;single-spa&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Import the registered application with a SystemJS.import call
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;registerApplication&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;app-name-1&amp;#39;&lt;/span&gt;, () =&amp;gt; &lt;span style="color:#a6e22e"&gt;SystemJS&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./my-app.js&amp;#39;&lt;/span&gt;), &lt;span style="color:#a6e22e"&gt;activeWhen&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Alternatively, use the more out-of-date System.import (instead of SystemJS.import)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;registerApplication&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;app-name-2&amp;#39;&lt;/span&gt;, () =&amp;gt; &lt;span style="color:#a6e22e"&gt;System&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./my-other-app.js&amp;#39;&lt;/span&gt;), &lt;span style="color:#a6e22e"&gt;activeWhen&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;activeWhen&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; window.&lt;span style="color:#a6e22e"&gt;location&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;pathname&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;indexOf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;/my-app&amp;#39;&lt;/span&gt;) &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="webpack-1"&gt;Webpack 1&lt;/h1&gt;
&lt;p&gt;Webpack 1 不支持基于Promise的代码拆分.&lt;/p&gt;
&lt;p&gt;想要按需加载,就必须在使用中用Promise二次的包装一次require.ensure&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; {&lt;span style="color:#a6e22e"&gt;registerApplication&lt;/span&gt;} &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;single-spa&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//app1 不使用按需加载与代码拆分 :(
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;app1&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./app1&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 不用按需加载与代码拆分,直接注册 :(
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;registerApplication&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;app-1&amp;#39;&lt;/span&gt;, () =&amp;gt; Promise.&lt;span style="color:#a6e22e"&gt;resolve&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;app1&lt;/span&gt;), &lt;span style="color:#a6e22e"&gt;activeWhen&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// app-2使用依赖加载方法
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;registerApplication&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;app-2&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;app2InPromise&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;activeWhen&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 重新包装一次
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;app2InPromise&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Promise((&lt;span style="color:#a6e22e"&gt;resolve&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;reject&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;ensure&lt;/span&gt;([&lt;span style="color:#e6db74"&gt;&amp;#39;./app-2.js&amp;#39;&lt;/span&gt;], &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt; =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;resolve&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./app-2.js&amp;#39;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;reject&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;activeWhen&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; window.&lt;span style="color:#a6e22e"&gt;location&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;pathname&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;indexOf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;/my-app&amp;#39;&lt;/span&gt;) &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Single-SPA微前端框架的使用Demo汇总</title><link>https://time-friend.com/zh/archive/single-spa-demo-guide/</link><pubDate>Wed, 31 Oct 2018 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/single-spa-demo-guide/</guid><description>&lt;p&gt;这些是在 github 能找到的 single-spa 微前端的 Demo:&lt;/p&gt;
&lt;h2 id="single-spa-examples"&gt;&lt;a href="https://github.com/CanopyTax/single-spa-examples"&gt;single-spa-examples&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;这是一个 single-spa 做的官方例子,这是&lt;a href="http://single-spa.surge.sh"&gt;在线 demo&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="simple-single-spa-webpack-example"&gt;&lt;a href="https://github.com/joeldenning/simple-single-spa-webpack-example"&gt;simple-single-spa-webpack-example&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;这是基于 webpack 构建的使用例子,webpakc 版本可能有点低,但是思想是一样的.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="single-spa-angular-cli-examples"&gt;&lt;a href="https://github.com/PlaceMe-SAS/single-spa-angular-cli-examples"&gt;single-spa-angular-cli-examples&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;基于 angular-cli 做的 angular 例子,适用于 angular 2.0+ 的版本.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="single-spa-es5-angularjs"&gt;&lt;a href="https://github.com/joeldenning/single-spa-es5-angularjs"&gt;single-spa-es5-angularjs&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;angularjs 的例子,也就是 angularjs1.0 的版本.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="single-spa-portal-example"&gt;&lt;a href="https://github.com/me-12/single-spa-portal-example"&gt;single-spa-portal-example&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;这已经是一个非常完整的多技术栈用例了,里面集成了多技术栈与模块之间通讯的思路,非常值得研究.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="microfrontend-base-demo"&gt;&lt;a href="https://github.com/Num142857/microfrontend-base-demo"&gt;microfrontend-base-demo&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;这是在我们项目中萃取的 base 模块 demo&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="microfrontend-submodule-demo"&gt;&lt;a href="https://github.com/Num142857/microfrontend-submodule-demo"&gt;microfrontend-submodule-demo&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;这是在我们项目中萃取的子模块 demo&lt;/p&gt;</description></item><item><title>Git删除所有提交记录解决方案</title><link>https://time-friend.com/zh/archive/git-delete-all-commits-solution/</link><pubDate>Tue, 30 Oct 2018 19:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/git-delete-all-commits-solution/</guid><description>&lt;p&gt;如果你之前的项目提交了一些敏感数据,或者要清除以前提交的记录,给出下面解决方案.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 1. 检出一个新的分支&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git checkout --orphan latest_branch
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 2. 暂存所有文件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git add -A
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 3. 提交刚刚暂存的文件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git commit -am &lt;span style="color:#e6db74"&gt;&amp;#34;commit message&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 4. 删除最原始的分支&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git branch -D master
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 5. 重命名当的第分支&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git branch -m master
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 6. 提交你的记录到远程仓库&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git push -f origin master
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>让你的Hexo博客支持熊掌号URL自动推送,百度24小时收录</title><link>https://time-friend.com/zh/archive/hexo-baidu-seo/</link><pubDate>Wed, 24 Oct 2018 21:32:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/hexo-baidu-seo/</guid><description>&lt;p&gt;百度推出熊掌号,为了让 hexo 支持熊掌号推送,我在 &lt;code&gt;hexo-baidu-url-submit&lt;/code&gt; 这个插件的基础上加上了熊掌号推送功能.
当天推送的 24 小时内会直接收录. 用这个,百度的收录速度是非常快的.&lt;/p&gt;
&lt;p&gt;以后再也不用等百度收录等到死也不会理你了.&lt;/p&gt;
&lt;h1 id="熊掌号支持"&gt;熊掌号支持&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;package.json&lt;/code&gt; 里面的内容改为&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; &amp;#34;hexo-baidu-url-submit&amp;#34;: &amp;#34;https://github.com/Num142857/hexo-baidu-url-submit&amp;#34;,
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="baidu_url_submit-配置"&gt;baidu_url_submit 配置&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;baidu_url_submit:
 count: 1000 ## 提交最新的一个链接
 host: time-friend.com ## 在百度站长平台中注册的域名
 token: xxxxx ## 请注意这是您的秘钥， 所以请不要把博客源代码发布在公众仓库里!
 path: baidu_urls.txt ## 文本文档的地址， 新链接会保存在此文本文档里
 xz_appid: &amp;#39;xxxxxx&amp;#39; ## 你的熊掌号 appid
 xz_token: &amp;#39;xxxxxx&amp;#39; ## 你的熊掌号 token
 xz_count: 10 ## 从所有的提交的数据当中选取最新的10条,该数量跟你的熊掌号而定
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="deploy-配置"&gt;deploy 配置&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;deploy:
- type: baidu_url_submitter # 百度
- type: baidu_xz_url_submitter # 百度熊掌号
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Node.js爬虫技巧-使用Puppeteer下载图片或文件</title><link>https://time-friend.com/zh/archive/nodejs-crawler-tips-download-images-or-files-with-puppeteer/</link><pubDate>Tue, 23 Oct 2018 20:32:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/nodejs-crawler-tips-download-images-or-files-with-puppeteer/</guid><description>&lt;blockquote&gt;
&lt;p&gt;一些网站的图片不允许外链,我们想要下载这些网站的图片通过Puppeteer是比较好解决的.
今天就给大家介绍一个爬虫技巧,通过Puppeteer下载你想要的图片或者文件.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="怎么通过puppeteer下载"&gt;怎么通过Puppeteer下载?&lt;/h1&gt;
&lt;p&gt;我们需要额外依赖的库 &lt;code&gt;fs-extra&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;代码很简单,主要代码可以简化到两三行&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fse&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;fs-extra&amp;#39;&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// 需要依赖的库,你想用原生fs也是没有问题的
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 主要代码
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;viewSource&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;page&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;goto&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;url&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fse&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;outputFile&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`path`&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;viewSource&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;buffer&lt;/span&gt;()) &lt;span style="color:#75715e"&gt;//下载到你想要的路径
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>任天堂Switch 6.0+ 系统菜单汉化</title><link>https://time-friend.com/zh/archive/nintendo-switch-system-menu-localization/</link><pubDate>Mon, 15 Oct 2018 19:02:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/nintendo-switch-system-menu-localization/</guid><description>&lt;h1 id="任天堂switch汉化补丁"&gt;任天堂Switch汉化补丁&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;仅支持6.0 和6.0.1系统&lt;/li&gt;
&lt;li&gt;简体中文/繁体中文&lt;/li&gt;
&lt;li&gt;支持大气层、ReiNX、RajNX、SXOS（TXOS）&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id="下载地址"&gt;下载地址&lt;/h1&gt;
&lt;h2 id="汉化安装器"&gt;汉化安装器&lt;/h2&gt;
&lt;p&gt;汉化安装器：https://share.weiyun.com/5HNlw1J （强烈推荐）&lt;/p&gt;
&lt;h2 id="覆盖版当安装器闪退时使用覆盖前要把原来的文件删干净"&gt;覆盖版：（当安装器闪退时使用，覆盖前要把原来的文件删干净。）&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;简体中文：https://share.weiyun.com/59MqPxr&lt;/li&gt;
&lt;li&gt;繁体中文：https://share.weiyun.com/52w0vp8&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="reinx汉化专用版本"&gt;ReiNX汉化专用版本：&lt;/h2&gt;
&lt;p&gt;完整支持汉化，已经修复DOOM和2K19的问题
&lt;a href="https://share.weiyun.com/58azYtc"&gt;https://share.weiyun.com/58azYtc&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;源码来自https://github.com/Reisyukaku/ReiNX&lt;/p&gt;
&lt;h1 id="地址覆盖"&gt;地址覆盖&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;大气层覆盖到atmosphere/titles&lt;/li&gt;
&lt;li&gt;ReiNX覆盖到ReiNX/titles&lt;/li&gt;
&lt;li&gt;SXOS覆盖到sxos/titles&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="汉化安装器教程"&gt;汉化安装器教程：&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;首先，用读卡器把SD卡插入电脑。&lt;/li&gt;
&lt;li&gt;打开SD卡的盘。&lt;/li&gt;
&lt;li&gt;把Nintendo Switch系统汉化补丁.exe 放入卡内。&lt;/li&gt;
&lt;li&gt;运行Nintendo Switch系统汉化补丁.exe&lt;/li&gt;
&lt;li&gt;看提示选择。&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id="faq"&gt;FAQ&lt;/h1&gt;
&lt;h2 id="汉化影响游戏吗"&gt;汉化影响游戏吗？&lt;/h2&gt;
&lt;p&gt;一般汉化导致游戏崩溃是文本出错的原因，新的汉化已经修复大部分的问题。当然实际效果仍需测试。&lt;/p&gt;
&lt;h2 id="51系统能用吗"&gt;5.1系统能用吗？&lt;/h2&gt;
&lt;p&gt;虽然5.1系统安装6.0的汉化可以开机。但不保证稳定性。也不保证能用。&lt;/p&gt;
&lt;h2 id="安装程序打不开怎么办"&gt;安装程序打不开怎么办？&lt;/h2&gt;
&lt;p&gt;安装
&lt;a href="https://www.microsoft.com/zh-CN/download/details.aspx?id=48145"&gt;Visual C++ Redistributable for Visual Studio 2015&lt;/a&gt;
安装程序不支持32位系统，所以用覆盖版就行。&lt;/p&gt;
&lt;h2 id="安装汉化后无法开机怎么办"&gt;安装汉化后无法开机怎么办？&lt;/h2&gt;
&lt;p&gt;别急，卸载汉化即可，不会影响原系统。&lt;/p&gt;
&lt;h2 id="部分游戏崩溃的问题"&gt;部分游戏崩溃的问题&lt;/h2&gt;
&lt;p&gt;如果你的游戏本身打了汉化补丁，是有可能崩溃的（目前已知龙珠超宇宙2）。&lt;/p&gt;
&lt;p&gt;部分游戏崩溃是破解工具本身的问题。比如SXOS2.0极不稳定。大气层某些游戏无法运行与存档。如果你用的是SXOS 2.xx ，运行XCI游戏有很大几率崩溃，应该与汉化无关。&lt;/p&gt;
&lt;p&gt;SXOS (2.0, 2.0.1, 2.1) XCI游戏待机死机的问题如果你的游戏本身使用了汉化，待机很大几率死机。与系统汉化无关。&lt;/p&gt;
&lt;h2 id="关于601系统"&gt;关于6.0.1系统&lt;/h2&gt;
&lt;p&gt;根据测试，6.0.1系统没有对文本做改动，所以6.0的汉化是完全可以兼容的。&lt;/p&gt;
&lt;h1 id="注意事项"&gt;注意事项&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;文件拷贝不建议使用mac系统!!!&lt;/li&gt;
&lt;li&gt;文件拷贝不建议使用mac系统!!!&lt;/li&gt;
&lt;li&gt;文件拷贝不建议使用mac系统!!!&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="参考资料"&gt;参考资料&lt;/h1&gt;
&lt;p&gt;&lt;a href="https://www.91wii.com/forum.php?mod=viewthread&amp;amp;tid=96891"&gt;https://www.91wii.com/forum.php?mod=viewthread&amp;tid=96891&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Switch的NSP和XCI什么区别？</title><link>https://time-friend.com/zh/archive/difference-between-switch-nsp-and-xci/</link><pubDate>Sun, 14 Oct 2018 19:02:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/difference-between-switch-nsp-and-xci/</guid><description>&lt;p&gt;最近在折腾Switch, 在游戏安装中出现了两种游戏格式,分别是&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;xci&lt;/li&gt;
&lt;li&gt;nsp&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="他们之间到底有什么区别"&gt;他们之间到底有什么区别?&lt;/h2&gt;
&lt;p&gt;在实际使用中:
xci，扔到内存卡里就可以使用,
nsp，需要安装之后才能使用
简单理解就是，xci是绿色版软件（正确说应该是ISO），nsp是安装版软件。&lt;/p&gt;
&lt;p&gt;因为xci相当于卡带，不需要安装，需要切换.
nsp相当于数字版，需要安装，安装完直接能玩&lt;/p&gt;
&lt;p&gt;所有的DLC或者更新包之类的都是nsp格式.&lt;/p&gt;
&lt;p&gt;当我们使用xci格式的软件的时候,想要安装更新升级包的时候,其实都是nsp格式的,直接安装nsp效果都是一样的.&lt;/p&gt;
&lt;p&gt;平常使用中,我喜欢nsp,安装过后就可以直接打开软件了,不需要再切换一次.个人觉得使用nsp是一劳永逸的.&lt;/p&gt;
&lt;h2 id="关于汉化"&gt;关于汉化&lt;/h2&gt;
&lt;p&gt;其实都是可以汉化的.两种格式只有使用上的差别,其他的并没有差别.&lt;/p&gt;</description></item><item><title>Nintendo Switch破解原理</title><link>https://time-friend.com/zh/archive/nintendo-switch-hack-principle/</link><pubDate>Thu, 11 Oct 2018 19:02:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/nintendo-switch-hack-principle/</guid><description>&lt;h1 id="nintendo-switch"&gt;Nintendo Switch&lt;/h1&gt;
&lt;p&gt;Nintendo Switch ，是任天堂出品的电子游戏机 ，于2017年3月3日在日本、北美、欧洲和香港发售，同年12月1日在韩国与台湾发售。 拥有可拆卸控制器和可分离式主机，游戏载体使用了专用卡匣 。
主机处理器使用了NVIDIA定制的Tegra X1系统芯片 ，这是任天堂首次采用NVIDIA的系统芯片。
任天堂Switch主机的内置存储空间为32GB，可使用microSD进行扩充，最高支持microSDXC标准，最大支持2TB容量； 主机在初始系统1.0.0时只能支持到microSD标准，发售同日提供的系统2.0 .0更新使其可支持microSDXC标准。&lt;/p&gt;
&lt;h1 id="破解原理"&gt;破解原理&lt;/h1&gt;
&lt;p&gt;Nintendo Switch（任天堂switch） 的CPU使用的是Nvidia X1 T210的处理器，存在一个可进入的工程模式（Recovery Mode），简称RCM，
Nintendo Switch的右joycon连接口中隐藏着一个特殊金属引脚（pin10）。如果在开机时，按住音量键+，并且将这个引脚接地（pin1,7,9），Nintendo Switch就能进入工程模式（RCM），从而设法运行自制代码。&lt;/p&gt;
&lt;p&gt;你可以在淘宝上轻易买到这个短接器。也可以通过锡纸，别针或者3D打印等很方便的制作。短接器的作用就是将这个特殊引脚接地。
由上可知， Nintendo Switch破解依赖的是基于Nvidia X1 T210的处理器的工程模式。注入（发射）特殊代码引导自制系统或程序。达成破解。&lt;/p&gt;
&lt;p&gt;这个方法不会被封堵，普通的系统更新补并不会影响破解。无法通过软件层面封堵。因为工程模式启动的优先级高于系统。不论以后更新什么系统，进入RCM（工程模式是没有问题的），在即将到来的6.0版本，也只是更改了游戏文件的存储方式，变相的防范破解，目前TX1.9版本已经加入了破解。&lt;/p&gt;
&lt;p&gt;正因为破解是基于开机短接进入工程模式的原理，在任意一次关机后，破解就会失效，需要重新进行破解。&lt;/p&gt;
&lt;h1 id="破解后可做什么有没有什么问题"&gt;破解后可做什么，有没有什么问题&lt;/h1&gt;
&lt;p&gt;Nintendo Switch 的系统本质上可以看作是一个改版的LINUX的操作系统，.通过破解后，编译新的程序，可以Dump你手中的实体卡带游戏，导出存档，甚至可以看小说，听音乐，作为其他游戏主机的模拟器。玩破解游戏只是其中的一个功能。
所以，在放入存储卡时候，因为系统格式化的不同，也会存在一次升级的情况，这是由于不同系统对于文件存储分区的逻辑不同导致的。&lt;/p&gt;
&lt;p&gt;扩展阅读：破解后您可以安装一个真正的发行版的Linux系统Lakka，&lt;/p&gt;
&lt;p&gt;着力推荐国内开发者的Lakka系统，这是独立于国外的一个项目，让我们感谢他。
最强模拟器系统 lakka修改模拟游戏分辨率和纹理和安装教程
&lt;a href="https://www.91wii.com/thread-96053-1-1.html"&gt;https://www.91wii.com/thread-96053-1-1.html&lt;/a&gt;&lt;/p&gt;
&lt;h1 id="关于ban机"&gt;关于BAN机&lt;/h1&gt;
&lt;p&gt;由于任天堂在联网时会验证游戏文件头（每个游戏的文件头都是唯一的），所以玩破解游戏，修改存档等，都会导致被Ban，目前主要体现为两种，
普通BAN：具体的表现为无法联机游戏，无法进Eshop（商店），同时会由错误代码出现，但是目前游戏正常更新（例如更新中文语言）并不受影响。您可以理解为Ban机是限制了网络功能。
更为严厉的ban机措施，大家称之为Super Ban，具体的表现为联网后出现错误代码2137-7403，同时主机无法更新，游戏和dlc也无法更新，也就说，任天堂将你的主机序列号加入黑名单，直接断开所有同任天堂的联系。&lt;/p&gt;
&lt;p&gt;您可以破解之后，进行系统备份。但目前已经出现有朋友因为不熟悉备份恢复流程变砖，所以这里不放链接，如果您要做这个事情， 记得“一机一码”，自己的备份文件只能自己用，不能用别人的。同时恢复分区的时候，要留意不要恢复错的文件，一旦误操作，是不可恢复的变砖。&lt;/p&gt;
&lt;p&gt;我更建议，破解后断开网络，等要联网之前，重置主机再联网，可以大概率从正。这个风险较小。&lt;/p&gt;
&lt;h1 id="破解方式"&gt;破解方式&lt;/h1&gt;
&lt;p&gt;目前，Nintendo Switch的破解存在两个大的分支。
一类是免费的大气层/REI/破解TX安装器等。此类只能支持NSP格式游戏安装。略微复杂
一类是收费的TX OS。此类支持卡带DUPM出来的XCI格式，同时支持NSP安装。&lt;/p&gt;
&lt;p&gt;因为代码公开，所以破解方式也变得逐渐多样化，希望您了解具体原理，而不是纠结于具体哪种破解方式，大致来说，论坛中简单热门的就是最好的破解方式。论坛中有不少不错的整合包，您可以任选其一进行安装。&lt;/p&gt;
&lt;p&gt;参考资料: &lt;a href="https://www.91wii.com/thread-93105-1-1.html"&gt;https://www.91wii.com/thread-93105-1-1.html&lt;/a&gt;&lt;/p&gt;</description></item><item><title>使用Eggjs(koa) &amp; web3.js开发你的以太坊Dapp</title><link>https://time-friend.com/zh/archive/develop-ethereum-dapp-with-eggjs-koa-web3js/</link><pubDate>Wed, 10 Oct 2018 19:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/develop-ethereum-dapp-with-eggjs-koa-web3js/</guid><description>&lt;h1 id="eggjs"&gt;Eggjs&lt;/h1&gt;
&lt;p&gt;Eggjs 是阿里开源的企业级基于 Koa2 的 Node.js 框架.
eggjs 基本上是开箱即用,奉行『约定优于配置』.在日常开发中,用起来非常顺畅.
而且生态也比较完善,koa2 的插件都可以对接到框架中来.&lt;/p&gt;
&lt;h2 id="eggjs-目录结构"&gt;Egg.js 目录结构&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;egg-project
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── package.json
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── app.js &lt;span style="color:#f92672"&gt;(&lt;/span&gt;可选&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── agent.js &lt;span style="color:#f92672"&gt;(&lt;/span&gt;可选&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── app
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;| ├── router.js
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── controller
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ | └── home.js
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── service &lt;span style="color:#f92672"&gt;(&lt;/span&gt;可选&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ | └── user.js
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── middleware &lt;span style="color:#f92672"&gt;(&lt;/span&gt;可选&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ | └── response_time.js
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── schedule &lt;span style="color:#f92672"&gt;(&lt;/span&gt;可选&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ | └── my_task.js
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── public &lt;span style="color:#f92672"&gt;(&lt;/span&gt;可选&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ | └── reset.css
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── view &lt;span style="color:#f92672"&gt;(&lt;/span&gt;可选&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ | └── home.tpl
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ └── extend &lt;span style="color:#f92672"&gt;(&lt;/span&gt;可选&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── helper.js &lt;span style="color:#f92672"&gt;(&lt;/span&gt;可选&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── request.js &lt;span style="color:#f92672"&gt;(&lt;/span&gt;可选&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── response.js &lt;span style="color:#f92672"&gt;(&lt;/span&gt;可选&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── context.js &lt;span style="color:#f92672"&gt;(&lt;/span&gt;可选&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── application.js &lt;span style="color:#f92672"&gt;(&lt;/span&gt;可选&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ └── agent.js &lt;span style="color:#f92672"&gt;(&lt;/span&gt;可选&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── config
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;| ├── plugin.js
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;| ├── config.default.js
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── config.prod.js
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;| ├── config.test.js &lt;span style="color:#f92672"&gt;(&lt;/span&gt;可选&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;| ├── config.local.js &lt;span style="color:#f92672"&gt;(&lt;/span&gt;可选&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;| └── config.unittest.js &lt;span style="color:#f92672"&gt;(&lt;/span&gt;可选&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;└── test
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ├── middleware
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; | └── response_time.test.js
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; └── controller
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; └── home.test.js
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如上，由框架约定的目录：&lt;/p&gt;</description></item><item><title>2018年10月国内浏览器数据统计</title><link>https://time-friend.com/zh/archive/2018-10-browser-statistics/</link><pubDate>Mon, 01 Oct 2018 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/2018-10-browser-statistics/</guid><description>&lt;div id="echarts400" style="width: 100%;height: 400px;margin: 0 auto"&gt;&lt;/div&gt;
&lt;script src="https://cdn.bootcss.com/echarts/3.8.0/echarts.common.min.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;
 
 var myChart = echarts.init(document.getElementById('echarts400'));
 
 var option = JSON.parse("\n {\"textStyle\":{\"color\":\"#fff\"},\"title\":{\"text\":\"2018年10月国内浏览器数据统计\",\"subtext\":\"浏览器数据分析\",\"x\":\"center\",\"textStyle\":{\"color\":\"#fff\"}},\"tooltip\":{\"trigger\":\"item\",\"formatter\":\"{a} \u003cbr/\u003e{b} : {c} ({d}%)\"},\"legend\":{\"type\":\"scroll\",\"orient\":\"vertical\",\"right\":10,\"top\":120,\"bottom\":20,\"data\":[\"Chrome\",\"IE 9.0\",\"IE 11.0\",\"2345\",\"QQ\",\"IE 8.0\",\"搜狗高速\",\"Safari\",\"Firefox\",\"其他\"],\"textStyle\":{\"color\":\"#fff\"}},\"series\":[{\"name\":\"浏览器用户比例\",\"type\":\"pie\",\"radius\":\"55%\",\"center\":[\"50%\",\"60%\"],\"data\":[{\"name\":\"Chrome\",\"value\":47.08},{\"name\":\"IE 9.0\",\"value\":7.89},{\"name\":\"IE 11.0\",\"value\":5.97},{\"name\":\"2345\",\"value\":5.9},{\"name\":\"QQ\",\"value\":5.88},{\"name\":\"IE 8.0\",\"value\":5.59},{\"name\":\"搜狗高速\",\"value\":4.68},{\"name\":\"Safari\",\"value\":2.43},{\"name\":\"Firefox\",\"value\":2.42},{\"name\":\"其他\",\"value\":12.16}],\"itemStyle\":{\"emphasis\":{\"shadowBlur\":10,\"shadowOffsetX\":0,\"shadowColor\":\"rgba(0, 0, 0, 0.5)\"}}}]}\n")
 
 myChart.setOption(option);
&lt;/script&gt;</description></item><item><title>Centos7环境下启动Upsource失败解决办法</title><link>https://time-friend.com/zh/archive/centos-upsource-fix/</link><pubDate>Sat, 29 Sep 2018 19:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/centos-upsource-fix/</guid><description>&lt;h2 id="报错"&gt;报错&lt;/h2&gt;
&lt;p&gt;Centos7环境下启动Upsource的时候出现以下报错,我在Mac上启动upsource的时候一切正常.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[Upsource Error] Failed to start JetBrains Upsource 2018.2 due to unexpected exception: Native random generator does not seem to have enough entropy for JetBrains Upsource 2018.2 to start. [Upsource Error] You can fix it by switching to PRNG (with -Djava.security.egd=/dev/zrandom) or by reconfiguring your operation system to provide more random bits.12
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="解决办法"&gt;解决办法&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;复制 upsource.jvmoptions.dist ==&amp;gt; upsource.jvmoptions&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cp $upsource_path/conf/upsource.jvmoptions.dist $upsource_path/conf/upsource.jvmoptions
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="2"&gt;
&lt;li&gt;编辑 $upsource_path/conf/upsource.jvmoptions文件,最后一行加上:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;-Djava.security.egd=/dev/zrandom
&lt;/code&gt;&lt;/pre&gt;&lt;ol start="3"&gt;
&lt;li&gt;启动&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$upsource_path/bin/upsource.sh start
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>利用ngrok给你的机器打个洞 - 内网穿透</title><link>https://time-friend.com/zh/archive/punch-hole-in-your-machine-with-ngrok-internal-network-penetration/</link><pubDate>Wed, 12 Sep 2018 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/punch-hole-in-your-machine-with-ngrok-internal-network-penetration/</guid><description>&lt;p&gt;我有很多自己的个人代码是跑在家里的服务器中的.一般来说都是自动化的处理我的一些生活问题,与数据收集等相关活动.
所以一般没有客户端访问家里服务器的需求.
但是很多时候脑子突发奇想.有一些小点子,一些小的bug或者小的优化,代码修改完成之后,有一个部署到需求.
因为家里服务器没有一个稳定的外网IP的,外网不能直接连接服务器.
所以我们需要 &lt;code&gt;内网穿透&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id="内网穿透"&gt;内网穿透&lt;/h1&gt;
&lt;p&gt;家里用的是小米路由器,小米路由器里面集成了花生壳,理论上是可以做到内网穿透的.无奈的是,一直都没有配置成功过.&lt;/p&gt;
&lt;p&gt;网上找过很多内网穿透的工具:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;花生壳&lt;/li&gt;
&lt;li&gt;NAT&lt;/li&gt;
&lt;li&gt;frp&lt;/li&gt;
&lt;li&gt;ngrok&lt;/li&gt;
&lt;li&gt;localtunnel&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ngrok"&gt;ngrok&lt;/h2&gt;
&lt;p&gt;选择ngrok的原因很简单,配置方便,并且支持tcp协议.
支持tcp协议代表,我可以直接在外面用SSH来访问家里的机器.&lt;/p&gt;
&lt;h3 id="用法"&gt;用法&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;首先你需要去&lt;a href="https://ngrok.com/"&gt;官网&lt;/a&gt;注册一个账号&lt;/li&gt;
&lt;li&gt;下载ngrok,并且解压到一个你喜欢的目录下面&lt;/li&gt;
&lt;li&gt;去官网复制你的授权码&lt;/li&gt;
&lt;li&gt;授权ngrok&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ngrok authtoken 授权码
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="http"&gt;http&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ngrok http &lt;span style="color:#ae81ff"&gt;8080&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="tcp"&gt;tcp&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ngrok tcp &lt;span style="color:#ae81ff"&gt;22&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src="https://ngrok.com/static/img/ngrok-demo-static.png" alt=""&gt;&lt;/p&gt;
&lt;p&gt;最终你会得到,一个外网可以访问的地址.
用这个地址就可以直接访问到你本机的端口了.&lt;/p&gt;
&lt;p&gt;当我们拥有这样一个公网地址之后,我们就可以ssh来控制家里的机器
或者使用github的webhook来做一切你想要做的事情.&lt;/p&gt;</description></item><item><title>前端微服务化解决方案8 - 二次构建</title><link>https://time-friend.com/zh/archive/micro-frontend-solution-8-secondary-build/</link><pubDate>Fri, 07 Sep 2018 01:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/micro-frontend-solution-8-secondary-build/</guid><description>&lt;h1 id="二次构建"&gt;二次构建&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;进一步优化我们的微前端性能&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在微前端这种形势的架构,每个模块都会输出固定的文件,比如之前说的:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;项目配置文件&lt;/li&gt;
&lt;li&gt;Store.js 文件&lt;/li&gt;
&lt;li&gt;main.js 渲染入口文件&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;这三个,是微前端架构中每个模块必要的三个文件.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在模块加载器启动整个项目的时候,都必须要加载所有模块的配置文件与 Store.js 文件.
在前面的文章中有说 &lt;code&gt;配置自动化&lt;/code&gt;的问题,这其实就是一种简单的二次构建.
虽然每一个模块的配置文件体积不是很大,但是每一个文件都会加载,是项目启动的必要文件.
每一个文件都会占一个 http 请求,每一个文件的阻塞都会影响项目的启动时间.&lt;/p&gt;
&lt;p&gt;所以,我们的&lt;code&gt;Store.js&lt;/code&gt;也必须是要优化的.
当然如果我们的模块数量不是很多的话,我们没有优化的必要.但是一旦项目变得更加庞大,有好几十个模块.
我们不可能一次加载几十个文件,我们必须要在项目部署之后,还要对整个项目重新再次构建来优化与整合我们的项目.&lt;/p&gt;
&lt;p&gt;我们的 Store.js 是一个 amd 模块,所以我们需要一个合并 amd 模块的 工具.&lt;/p&gt;
&lt;h1 id="grunt-or-gulp"&gt;Grunt or Gulp&lt;/h1&gt;
&lt;p&gt;像这样的场景,用 grunt,gulp 这样的任务管理工具再合适不过了.
不管这两个工具好像已经是上个世纪的东西了,但是他的生态还是非常完善的.用在微前端的二次构建中非常合适.&lt;/p&gt;
&lt;p&gt;例如 Gulp:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;gulp&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;gulp&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;concat&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;gulp-concat&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;gulp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;task&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;storeConcat&amp;#34;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; () {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;gulp&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;project/**/Store.js&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;pipe&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;concat&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Store.js&amp;#34;&lt;/span&gt;)) &lt;span style="color:#75715e"&gt;//合并后的文件名
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;pipe&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;gulp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;dest&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;project/&amp;#34;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;像这样的优化点还有非常多,在项目发布之后,在二次构建与优化代码.
在后期庞大的项目中,是有很多空间来提升我们项目的性能的.&lt;/p&gt;
&lt;p&gt;未完待续 &amp;hellip;&lt;/p&gt;
&lt;h1 id="相关文章"&gt;相关文章&lt;/h1&gt;
&lt;p&gt;&lt;a href="http://time-friend.com/archive/ea599f7c/"&gt;前端微服务化解决方案 1 - 思考&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://time-friend.com/archive/11052bf4/"&gt;前端微服务化解决方案 2 - Single-SPA&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://time-friend.com/archive/1a60cede/"&gt;前端微服务化解决方案 3 - 模块加载器&lt;/a&gt;&lt;/p&gt;</description></item><item><title>前端微服务化解决方案7 - 静态数据共享</title><link>https://time-friend.com/zh/archive/micro-frontend-solution-7-static-data/</link><pubDate>Thu, 06 Sep 2018 01:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/micro-frontend-solution-7-static-data/</guid><description>&lt;p&gt;在前面的一些介绍,相信你对微前端已经有了一个相对完整的认知.
下面介绍一下,再开发过程中我的一些小技巧与处理方法.&lt;/p&gt;
&lt;h1 id="动态入口"&gt;动态入口&lt;/h1&gt;
&lt;p&gt;当有新的子模块会挂载到项目中的时候,在 UI 中肯定需要一个新的入口进入子模块的 UI.
而这样一个入口,是需要动态生成的.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://static.alili.tech/images/micro/base-demo.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;例如:图中左边的菜单,不应该是代码写死的.而是根据每个模块提供的数据自动生成的.&lt;/p&gt;
&lt;p&gt;不然每次发布新的模块,我们都需要在最外面的这个框架修改代码.这样就谈不上什么独立部署了.&lt;/p&gt;
&lt;h1 id="静态数据共享"&gt;静态数据共享&lt;/h1&gt;
&lt;p&gt;想要达到上面所的效果,我们可以这样做.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// ~/common/menu.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;isUrl&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;../utils/utils&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;menuData&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;模块1&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;icon&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;table&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;module1&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;rank&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;children&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Page1&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;page1&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Page2&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;page2&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Page3&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;page3&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;originParentPath&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;/&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;formatter&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;parentPath&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;originParentPath&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;parentAuthority&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 在这里,我们对外导出 这个模块的菜单数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;menuData&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Store.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;createStore&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;combineReducers&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;redux&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;menuDate&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./common/menu&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;createHistory&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;history/createBrowserHistory&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;history&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;createHistory&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 我们拿到数据之后,用一个reducer函数返回我们的菜单数据.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;menu&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;menuDate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 最终以Store.js对外导出我们的菜单数据,在注册的时候,每个应用都可以拿到这个数据了
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;storeInstance&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;createStore&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;combineReducers&lt;/span&gt;({ &lt;span style="color:#a6e22e"&gt;namespace&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; () =&amp;gt; &lt;span style="color:#e6db74"&gt;&amp;#39;list&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;menu&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;render&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;to&lt;/span&gt; }))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;当我们的 Base 模块,拿到所有子模块的菜单数据,把他们合并后,就可以渲染出正确的菜单了.&lt;/p&gt;</description></item><item><title>前端微服务化解决方案6 - 构建与部署</title><link>https://time-friend.com/zh/archive/micro-frontend-solution-6-build-deploy/</link><pubDate>Wed, 05 Sep 2018 01:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/micro-frontend-solution-6-build-deploy/</guid><description>&lt;h1 id="微前端打包构建"&gt;微前端打包构建&lt;/h1&gt;
&lt;p&gt;微前端项目的打包,是有一些需要注意的点
以 webpack 为例:&lt;/p&gt;
&lt;h2 id="amd-模块"&gt;amd 模块&lt;/h2&gt;
&lt;p&gt;在之前的文章,我们有提到我们的加载器,是基于 System.js 来做的.
所以我们微前端的模块最终打包,是要符合模块规范的.
我们使用的是&lt;code&gt;amd模块&lt;/code&gt;规范来构建我们的模块.&lt;/p&gt;
&lt;h2 id="指定基础路径"&gt;指定基础路径&lt;/h2&gt;
&lt;p&gt;因为模块打包后,调用模块出口文件的,是模块加载器.
为了清晰的管理每个模块,并且正确的加载到我们每一个模块的资源,
我们给模块的资源都指定一个&lt;code&gt;publicPath&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;下面给出一个简单的 webpack 配置,这些配置我只是列出一些必要选项.
并不是一个完整的 webpack 配置,后续我会提供完整的微前端的 Demo,提供大家参考
这些配置都是基于 &lt;code&gt;create-react-app&lt;/code&gt; 的配置做的修改.
只要明白了配置的意图,明白我们打包出来的最终是一个什么样的包,
不管打包工具以后怎么变,技术栈怎么变,最后都是可以对接到微前端中来.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这里给出 &lt;code&gt;project.json&lt;/code&gt; 的内容,便于后面的配置文件的阅读&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// project.json
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;//模块名称
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;path&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;/project&amp;#34;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;//模块url前缀
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;prefix&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;/module-prefix/&amp;#34;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;//模块文件路径前缀
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;main&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;/module-prefix/main.js&amp;#34;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;//模块渲染出口文件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;store&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;/module-prefix/store.js&amp;#34;&lt;/span&gt;,&lt;span style="color:#75715e"&gt;//模块对外接口
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;base&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 是否为baseapp
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 引入项目配置文件,也是前面说的 模块加载器必要文件之一
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;projectConfig&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./project.json&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;config&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;entry&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;paths&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;appIndexJs&lt;/span&gt;, &lt;span style="color:#75715e"&gt;//出口文件,模块加载器必要文件之一
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;store&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;paths&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;store&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 对外api的reducer文件,模块加载器必要文件之一
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;output&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;paths&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;appBuild&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;filename&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;[name].js?n=[chunkhash:8]&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;chunkFilename&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;static/js/[name].[chunkhash:8].chunk.js&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;publicPath&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;projectConfig&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;prefix&lt;/span&gt;, &lt;span style="color:#75715e"&gt;//在output中指定模块配置好的 publicPath
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;libraryTarget&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;amd&amp;#39;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;//对外输出 amd模块,便于 system.js加载
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;library&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;projectConfig&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;, &lt;span style="color:#75715e"&gt;//模块的名称
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;rules&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;oneOf&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;test&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;/\.bmp$/&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;/\.gif$/&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;/\.jpe?g$/&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;/\.png$/&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// loader: &amp;#39;happypack/loader?id=url&amp;#39;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;loaders&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;loader&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;resolve&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;url-loader&amp;#39;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;options&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;limit&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;5000&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;static/media/[name].[hash:8].[ext]&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;publicPath&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;projectConfig&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;prefix&lt;/span&gt;, &lt;span style="color:#75715e"&gt;//我们需要在静态文件的loader加上publicPath
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;test&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;/\.(js|jsx|mjs)$/&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;include&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;paths&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;appSrc&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;loader&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;happypack/loader?id=babel&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;options&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;static/js/[name].[hash:8].[ext]&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;publicPath&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;projectConfig&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;prefix&lt;/span&gt;, &lt;span style="color:#75715e"&gt;//在静态文件的loader加上publicPath
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;loader&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;resolve&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;file-loader&amp;#39;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;exclude&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;/\.(js|jsx|mjs)$/&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;/\.html$/&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;/\.json$/&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;options&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;static/media/[name].[hash:8].[ext]&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;publicPath&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;projectConfig&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;prefix&lt;/span&gt;, &lt;span style="color:#75715e"&gt;//在静态文件的loader加上publicPath
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="部署"&gt;部署&lt;/h1&gt;
&lt;p&gt;前端单页面的部署,不管怎么自动化,工具怎么变.
都是把打包好的静态文件,放到服务器的正确位置下.
微前端的部署,是一个应用聚合的过程,我们如何把一个个模块最后接入到一个完整的项目中的呢?&lt;/p&gt;</description></item><item><title>前端微服务化解决方案5 - 路由分发</title><link>https://time-friend.com/zh/archive/micro-frontend-solution-5-route-distribution/</link><pubDate>Tue, 04 Sep 2018 01:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/micro-frontend-solution-5-route-distribution/</guid><description>&lt;h1 id="路由分发式微前端"&gt;路由分发式微前端&lt;/h1&gt;
&lt;h2 id="从应用分发路由到路由分发应用"&gt;从应用分发路由到路由分发应用&lt;/h2&gt;
&lt;p&gt;用这句话来解释,微前端的路由,再合适不过来.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;路由分发式微前端，即通过路由将不同的业务分发到不同的、独立前端应用上。其通常可以通过 HTTP 服务器的反向代理来实现，又或者是应用框架自带的路由来解决。
就当前而言，通过路由分发式的微前端架构应该是采用最多、最易采用的 “微前端” 方案。但是这种方式看上去更像是多个前端应用的聚合，即我们只是将这些不同的前端应用拼凑到一起，使他们看起来像是一个完整的整体。但是它们并不是，每次用户从 A 应用到 B 应用的时候，往往需要刷新一下页面。 &amp;ndash; 引用自 phodal &lt;a href="https://microfrontend.cn"&gt;微前端的那些事儿&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在&lt;a href="https://time-friend.com/2018/09/03/Architecture/%E5%89%8D%E7%AB%AF%E5%8D%95%E9%A1%B5%E5%BA%94%E7%94%A8%E5%BE%AE%E6%9C%8D%E5%8A%A1%E5%8C%96%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%883%20-%20%E6%A8%A1%E5%9D%97%E5%8A%A0%E8%BD%BD%E5%99%A8/"&gt;模块加载器&lt;/a&gt;那一章的示例代码,已经非常充分了展示了路由分发应用的步骤.&lt;/p&gt;
&lt;p&gt;在单页面前端的路由,目前有两种形式,
一种是所有主流浏览器都兼容多 hash 路由,
基本原理为 url 的 hash 值的改变,触发了浏览器 onhashchange 事件,来触发组件的更新&lt;/p&gt;
&lt;p&gt;还有一种是高级浏览器才支持的 History API,
在 &lt;code&gt;window.history.pushState(null, null, &amp;quot;/profile/&amp;quot;);&lt;/code&gt;的时候触发组件的更新&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// hash 模式,项目路由用的是hash模式会用到该函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;hashPrefix&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;location&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;isShow&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//如果该应用 有多个需要匹配的路劲
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;isArray&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;forEach&lt;/span&gt;((&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;location&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;hash&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;startsWith&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`#&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;isShow&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 普通情况
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;location&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;hash&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;startsWith&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`#&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;url&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;isShow&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;isShow&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// pushState 模式
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;pathPrefix&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;location&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;isShow&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//如果该模块 有多个需要匹配的路径
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;isArray&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;forEach&lt;/span&gt;((&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;location&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;pathname&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;indexOf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;) &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;isShow&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 普通情况
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;location&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;pathname&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;indexOf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;url&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;) &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;isShow&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;isShow&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 应用注册
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;registerApp&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 第三个参数为,该模块是否显示
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;singleSpa&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;registerApplication&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;, &lt;span style="color:#75715e"&gt;// 模块名字
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; () =&amp;gt; &lt;span style="color:#a6e22e"&gt;SystemJS&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;), &lt;span style="color:#75715e"&gt;// 模块渲染的入口文件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;base&lt;/span&gt; &lt;span style="color:#f92672"&gt;?&lt;/span&gt; () =&amp;gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;pathPrefix&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// 模块显示的条件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; );
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="路由分发应用"&gt;路由分发应用&lt;/h3&gt;
&lt;p&gt;当 url 前缀,与配置中的 url 前缀保持一致的时候,
singleSpa 会激活对应的模块,然后把模块内容渲染出来.&lt;/p&gt;</description></item><item><title>前端微服务化解决方案4 - 消息总线</title><link>https://time-friend.com/zh/archive/micro-frontend-solution-4-message-bus/</link><pubDate>Mon, 03 Sep 2018 01:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/micro-frontend-solution-4-message-bus/</guid><description>&lt;blockquote&gt;
&lt;p&gt;微前端的消息总线,主要的功能是搭建模块与模块之间通讯的桥梁.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="黑盒子"&gt;黑盒子&lt;/h1&gt;
&lt;h2 id="问题-1"&gt;问题 1:&lt;/h2&gt;
&lt;p&gt;应用微服务化之后,每一个单独的模块都是一个黑盒子,
里面发生了什么,状态改变了什么,外面的模块是无从得知的.
比如&lt;code&gt;模块A&lt;/code&gt;想要根据&lt;code&gt;模块B&lt;/code&gt;的某一个内部状态进行下一步行为的时候,黑盒子之间没有办法通信.这是一个大麻烦.&lt;/p&gt;
&lt;h2 id="问题-2"&gt;问题 2&lt;/h2&gt;
&lt;p&gt;每一个模块之间都是有生命周期的.当模块被卸载的时候,如何才能保持后续的正常的通信?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ps. 我们必须要解决这些问题,模块与模块之间的通讯太有必要了.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="打破壁垒"&gt;打破壁垒&lt;/h1&gt;
&lt;p&gt;在 github 上&lt;a href="https://github.com/me-12/single-spa-portal-example"&gt;single-spa-portal-example&lt;/a&gt;,给出来一解决方案.&lt;/p&gt;
&lt;p&gt;基于 Redux 实现前端微服务的消息总线(不会影响在编写代码的时候使用其他的状态管理工具).&lt;/p&gt;
&lt;p&gt;大概思路是这样的:
&lt;img src="https://github.com/me-12/single-spa-portal-example/raw/master/docs/inter-app-communication.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;每一个模块,会对外提供一个 Store.js.&lt;/p&gt;
&lt;p&gt;这个文件里面的内容,大致是这样的.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;createStore&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;combineReducers&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;redux&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;initialState&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;refresh&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;render&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;state&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;initialState&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;action&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;switch&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;action&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;type&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;case&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;REFRESH&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; { ...&lt;span style="color:#a6e22e"&gt;state&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;refresh&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;state&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;refresh&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;state&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 向外输出 Store
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;storeInstance&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;createStore&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;combineReducers&lt;/span&gt;({ &lt;span style="color:#a6e22e"&gt;namespace&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; () =&amp;gt; &lt;span style="color:#e6db74"&gt;&amp;#34;base&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;render&lt;/span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;对于这样的代码,有没有很熟悉?
对,他就是一个普通的 Store 文件,
每一个模块对外输出的&lt;code&gt;Store.js&lt;/code&gt;,就是一个模块的 Store.&lt;/p&gt;
&lt;h1 id="storejs-如何被使用"&gt;Store.js 如何被使用?&lt;/h1&gt;
&lt;p&gt;我们需要在模块加载器中,导出这个 Store.js&lt;/p&gt;
&lt;p&gt;于是我们对模块加载器中的&lt;code&gt;Register.js&lt;/code&gt;文件 (该文件在上一章出现过,不懂的同学可以往回看)&lt;/p&gt;
&lt;p&gt;进行了以下改造:&lt;/p&gt;</description></item><item><title>前端微服务化解决方案3 - 模块加载器</title><link>https://time-friend.com/zh/archive/micro-frontend-solution-3-module-loader/</link><pubDate>Mon, 03 Sep 2018 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/micro-frontend-solution-3-module-loader/</guid><description>&lt;p&gt;微前端的模块加载器,主要功能为:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;项目配置文件的加载&lt;/li&gt;
&lt;li&gt;项目对外接口文件的加载(消息总线会用到,后续会提)&lt;/li&gt;
&lt;li&gt;项目入口文件的加载&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;以上也是每一个单模块,不可缺少的三部分&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="配置文件"&gt;配置文件&lt;/h1&gt;
&lt;p&gt;我们实践微前端的过程中,我们对每个模块项目,都有一个对外的配置文件.
是模块在注册到 singe-spa 时候所用到的信息.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;//模块名称
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;path&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;/project&amp;#34;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;//模块url前缀
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;prefix&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;/module-prefix/&amp;#34;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;//模块文件路径前缀
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;main&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;/module-prefix/main.js&amp;#34;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;//模块渲染出口文件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;store&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;/module-prefix/store.js&amp;#34;&lt;/span&gt;,&lt;span style="color:#75715e"&gt;//模块对外接口
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;base&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 当模块被定性为baseApp的时候,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 不管url怎么变化,项目也是会被渲染的,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 使用场景为,模块职责主要为整个框架的布局或者一直被渲染,不会改变的部分
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;当我们的模块,有多种 url 前缀的时候,path 也可以为数组形式&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;path&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;&amp;#34;/project-url-path1/&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;/project-url-path2/&amp;#34;&lt;/span&gt;], &lt;span style="color:#75715e"&gt;//项目url前缀
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="配置自动化"&gt;配置自动化&lt;/h1&gt;
&lt;p&gt;我们每个模块都有上面所描述的配置文件,当我们的项目多个模块的时候,我们需要把所有模块的配置文件聚合起来.
我这里也有写一个脚本.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.npmjs.com/package/micro-auto-config"&gt;micro-auto-config&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;使用方法:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;npm install micro-auto-config -g
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 在项目根目录,用pm2启动该脚本,便可启动这个项目的配置自动化&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;pm2 start micro-auto-config
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;大概思路是:当模块部署,服务器检测到项目文件发生改变,便开始找出所有模块的配置文件,把他们合并到一起.
以数组包对象的形式输出一个总体的新配置文件 &lt;code&gt;project.config.js&lt;/code&gt;.
当我们一个模块配置有更新,部署到线上的时候,项目配置文件会自动更新.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="模块加载器"&gt;模块加载器&lt;/h2&gt;
&lt;p&gt;这个文件直接引入到 html 中,也就是上一篇文章中的&lt;code&gt;single-spa-config.js&lt;/code&gt; 升级版.
在加载模块的时候,我们使用 SystemJS 作为我们的模块加载工具.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;use strict&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;../libs/es6-promise.auto.min&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;as&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;singleSpa&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;single-spa&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;registerApp&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;./Register&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bootstrap&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// project.config.js 文件为所有模块的配置集合
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;projectConfig&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;SystemJS&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/project.config.js&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 遍历,注册所有模块
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;projectConfig&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;projects&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;forEach&lt;/span&gt;((&lt;span style="color:#a6e22e"&gt;element&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;registerApp&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;element&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;element&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;url&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;element&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;prefix&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;store&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;element&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;store&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;base&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;element&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;base&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;element&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 项目启动
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;singleSpa&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;start&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;bootstrap&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="registerjs"&gt;Register.js&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;../libs/system&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;../libs/es6-promise.auto.min&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;as&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;singleSpa&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;single-spa&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// hash 模式,项目路由用的是hash模式会用到该函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;hashPrefix&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;location&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;isShow&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//如果该应用 有多个需要匹配的路劲
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;isArray&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;forEach&lt;/span&gt;((&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;location&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;hash&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;startsWith&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`#&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;isShow&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 普通情况
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;location&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;hash&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;startsWith&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`#&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;url&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;isShow&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;isShow&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// pushState 模式
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;pathPrefix&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;location&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;isShow&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//如果该模块 有多个需要匹配的路径
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;isArray&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;forEach&lt;/span&gt;((&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;location&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;pathname&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;indexOf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;) &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;isShow&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 普通情况
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;location&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;pathname&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;indexOf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;url&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;) &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;isShow&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;isShow&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 应用注册
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;registerApp&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;singleSpa&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;registerApplication&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; () =&amp;gt; &lt;span style="color:#a6e22e"&gt;SystemJS&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;base&lt;/span&gt; &lt;span style="color:#f92672"&gt;?&lt;/span&gt; () =&amp;gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;pathPrefix&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; );
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//数组判断 用于判断是否有多个url前缀
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;isArray&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;o&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Object.&lt;span style="color:#a6e22e"&gt;prototype&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;toString&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;call&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;o&lt;/span&gt;) &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;[object Array]&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;未完待续 &amp;hellip;&lt;/p&gt;</description></item><item><title>前端微服务化解决方案2 - Single-SPA</title><link>https://time-friend.com/zh/archive/micro-frontend-solution-2-single-spa/</link><pubDate>Sun, 02 Sep 2018 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/micro-frontend-solution-2-single-spa/</guid><description>&lt;h1 id="技术选型"&gt;技术选型&lt;/h1&gt;
&lt;p&gt;经过各种技术调研我们最终选择的方案是基于 &lt;a href="https://single-spa.js.org/"&gt;Single-SPA&lt;/a&gt; 来实现我们的前端微服务化.&lt;/p&gt;
&lt;video style="width:100%" src="https://static.alili.tech/data/video/Single-Spa%20Intro.mp4" controls="controls"&gt;
你的浏览器不支持视频
&lt;/video&gt;
&lt;h1 id="single-spa"&gt;Single-SPA&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;一个用于前端微服务化的 JavaScript 前端解决方案&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;使用 Single-SPA 之后,你可以这样做:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;(兼容各种技术栈)在同一个页面中使用多种技术框架(React, Vue, AngularJS, Angular, Ember 等任意技术框架),并且不需要刷新页面.&lt;/li&gt;
&lt;li&gt;(无需重构现有代码)使用新的技术框架编写代码,现有项目中的代码无需重构.&lt;/li&gt;
&lt;li&gt;(更优的性能)每个独立模块的代码可做到按需加载,不浪费额外资源.&lt;/li&gt;
&lt;li&gt;每个独立模块可独立运行.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下面是一个微前端的演示页面 (你可能需要科学的上网)
&lt;a href="https://single-spa.surge.sh/"&gt;https://single-spa.surge.sh/&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;以上是官方例子,但是官方例子中并没有解决一个问题.就是各种技术栈的路由实现方式大相径庭,如何做到路由之间的协同?
后续文章会讲解,如何解决这样的问题.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="单体应用对比前端微服务化"&gt;单体应用对比前端微服务化&lt;/h2&gt;
&lt;h3 id="普通的前端单体应用"&gt;普通的前端单体应用&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://static.alili.tech/images/micro/current.png" alt=""&gt;&lt;/p&gt;
&lt;h3 id="微前端架构"&gt;微前端架构&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://static.alili.tech/images/micro/mf.png" alt=""&gt;&lt;/p&gt;
&lt;h1 id="single-spa-的简单用法"&gt;Single-SPA 的简单用法&lt;/h1&gt;
&lt;h2 id="1创建一个-html-文件"&gt;1.创建一个 HTML 文件&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;html&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;body&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;root&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;div&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;single-spa-config.js&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;/&lt;span style="color:#f92672"&gt;body&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;html&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="2创建-single-spa-configjs-文件"&gt;2.创建 single-spa-config.js 文件&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// single-spa-config.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;as&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;singleSpa&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;single-spa&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 加载react 项目的入口js文件 (模块加载)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;loadingFunction&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; () =&amp;gt; &lt;span style="color:#66d9ef"&gt;import&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;./react/app.js&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 当url前缀为 /react的时候.返回 true (底层路由)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;activityFunction&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;location&lt;/span&gt;) =&amp;gt; &lt;span style="color:#a6e22e"&gt;location&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;pathname&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;startsWith&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/react&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 注册应用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;singleSpa&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;registerApplication&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;react&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;loadingFunction&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;activityFunction&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//singleSpa 启动
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;singleSpa&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;start&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="封装-react-项目的渲染出口文件"&gt;封装 React 项目的渲染出口文件&lt;/h2&gt;
&lt;p&gt;我们把渲染 react 的入口文件修改成这样,便可接入到 single-spa&lt;/p&gt;</description></item><item><title>前端微服务化解决方案1 - 思考</title><link>https://time-friend.com/zh/archive/micro-frontend-solution-1-thinking/</link><pubDate>Sat, 01 Sep 2018 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/micro-frontend-solution-1-thinking/</guid><description>&lt;blockquote&gt;
&lt;p&gt;近几年,微服务架构在后端技术社区大红大紫,它被认为是 IT 软件架构的未来技术方向.我们如何借鉴后端微服务的思想来构建一个现代化前端应用?
在这里我提供一个可以在产品中真正可以落地的前端微服务解决方案.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src="https://user-gold-cdn.xitu.io/2017/12/27/16098869b848027e?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt=""&gt;&lt;/p&gt;
&lt;h1 id="微服务化后端前后端对比"&gt;微服务化后端前后端对比&lt;/h1&gt;
&lt;h2 id="后端微服务化的优势"&gt;后端微服务化的优势:&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;复杂度可控: 体积小、复杂度低，每个微服务可由一个小规模开发团队完全掌控，易于保持高可维护性和开发效率。&lt;/li&gt;
&lt;li&gt;独立部署: 由于微服务具备独立的运行进程，所以每个微服务也可以独立部署。&lt;/li&gt;
&lt;li&gt;技术选型灵活: 微服务架构下，技术选型是去中心化的。每个团队可以根据自身服务的需求和行业发展的现状，自由选择最适合的技术栈。&lt;/li&gt;
&lt;li&gt;容错: 当某一组建发生故障时，在单一进程的传统架构下，故障很有可能在进程内扩散，形成应用全局性的不可用。&lt;/li&gt;
&lt;li&gt;扩展: 单块架构应用也可以实现横向扩展，就是将整个应用完整的复制到不同的节点。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="前端微服务化后的优势"&gt;前端微服务化后的优势:&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;复杂度可控: 每一个 UI 业务模块由独立的前端团队开发,避免代码巨无霸,保持开发时的高速编译,保持较低的复杂度,便于维护与开发效率。&lt;/li&gt;
&lt;li&gt;独立部署: 每一个模块可单独部署,颗粒度可小到单个组件的 UI 独立部署,不对其他模块有任何影响。&lt;/li&gt;
&lt;li&gt;技术选型灵活: 也是最具吸引力的,在同一项目下可以使用如今市面上所有前端技术栈,也包括未来的前端技术栈。&lt;/li&gt;
&lt;li&gt;容错: 单个模块发生错误,不影响全局。&lt;/li&gt;
&lt;li&gt;扩展: 每一个服务可以独立横向扩展以满足业务伸缩性，与资源的不必要消耗；&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id="我们何时需要前端微服务化"&gt;我们何时需要前端微服务化?&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;项目技术栈过于老旧,相关技能的开发人员少,功能扩展吃力,重构成本高,维护成本高.&lt;/li&gt;
&lt;li&gt;项目过于庞大,代码编译慢,开发体差,需要一种更高维度的解耦方案.&lt;/li&gt;
&lt;li&gt;单一技术栈无法满足你的业务需求&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id="其中面临的问题与挑战"&gt;其中面临的问题与挑战&lt;/h1&gt;
&lt;p&gt;我们即将面临以下问题:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;我们如何实现在一个页面里渲染多种技术栈?&lt;/li&gt;
&lt;li&gt;不同技术栈的独立模块之间如何通讯?&lt;/li&gt;
&lt;li&gt;如何通过路由渲染到正确的模块?&lt;/li&gt;
&lt;li&gt;在不同技术栈之间的路由该如何正确触发?&lt;/li&gt;
&lt;li&gt;项目代码别切割之后,通过何种方式合并到一起?&lt;/li&gt;
&lt;li&gt;我们的每一个模块项目如何打包?&lt;/li&gt;
&lt;li&gt;前端微服务化后我们该如何编写我们的代码?&lt;/li&gt;
&lt;li&gt;独立团队之间该如何协作?&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;后续的文章我会一一解答以上问题,一起挖掘前端微服务的潜力.
跳出概念,实实在在的落地到你的项目中.
未完待续 &amp;hellip;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="相关文章"&gt;相关文章&lt;/h1&gt;
&lt;p&gt;&lt;a href="http://time-friend.com/archive/ea599f7c/"&gt;前端微服务化解决方案 1 - 思考&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://time-friend.com/archive/11052bf4/"&gt;前端微服务化解决方案 2 - Single-SPA&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://time-friend.com/archive/1a60cede/"&gt;前端微服务化解决方案 3 - 模块加载器&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://time-friend.com/archive/a9a1f81b/"&gt;前端微服务化解决方案 4 - 消息总线&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://time-friend.com/archive/5ff0b366/"&gt;前端微服务化解决方案 5 - 路由分发&lt;/a&gt;&lt;/p&gt;</description></item><item><title>2018年09月国内浏览器数据统计</title><link>https://time-friend.com/zh/archive/2018-09-browser-statistics/</link><pubDate>Sat, 01 Sep 2018 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/2018-09-browser-statistics/</guid><description>&lt;div id="echarts400" style="width: 100%;height: 400px;margin: 0 auto"&gt;&lt;/div&gt;
&lt;script src="https://cdn.bootcss.com/echarts/3.8.0/echarts.common.min.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;
 
 var myChart = echarts.init(document.getElementById('echarts400'));
 
 var option = JSON.parse("\n{\"textStyle\":{\"color\":\"#fff\"},\"title\":{\"text\":\"2018年11月国内浏览器数据统计\",\"subtext\":\"浏览器数据分析\",\"x\":\"center\",\"textStyle\":{\"color\":\"#fff\"}},\"tooltip\":{\"trigger\":\"item\",\"formatter\":\"{a} \u003cbr/\u003e{b} : {c} ({d}%)\"},\"legend\":{\"type\":\"scroll\",\"orient\":\"vertical\",\"right\":10,\"top\":120,\"bottom\":20,\"data\":[\"Chrome\",\"IE 9.0\",\"IE 11.0\",\"QQ\",\"IE 8.0\",\"2345\",\"搜狗高速\",\"Firefox\",\"Safari\",\"其他\"],\"textStyle\":{\"color\":\"#fff\"}},\"series\":[{\"name\":\"浏览器用户比例\",\"type\":\"pie\",\"radius\":\"55%\",\"center\":[\"50%\",\"60%\"],\"data\":[{\"name\":\"Chrome\",\"value\":46.88},{\"name\":\"IE 9.0\",\"value\":7.4},{\"name\":\"IE 11.0\",\"value\":6.21},{\"name\":\"QQ\",\"value\":5.75},{\"name\":\"IE 8.0\",\"value\":5.74},{\"name\":\"2345\",\"value\":5.68},{\"name\":\"搜狗高速\",\"value\":4.74},{\"name\":\"Firefox\",\"value\":2.54},{\"name\":\"Safari\",\"value\":2.48},{\"name\":\"其他\",\"value\":12.59}],\"itemStyle\":{\"emphasis\":{\"shadowBlur\":10,\"shadowOffsetX\":0,\"shadowColor\":\"rgba(0, 0, 0, 0.5)\"}}}]}\n")
 
 myChart.setOption(option);
&lt;/script&gt;</description></item><item><title>Network笔记整理 - 网络协议与网络分层</title><link>https://time-friend.com/zh/archive/network-notes-network-protocols-and-network-layering/</link><pubDate>Thu, 30 Aug 2018 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/network-notes-network-protocols-and-network-layering/</guid><description>&lt;p&gt;《圣经》中有一个通天塔的故事,上帝为了阻止人类联合起来，就让人类说不同的语言。人类没法儿沟通，达不成“协议”，通天塔的计划就失败了。&lt;/p&gt;
&lt;p&gt;千年之后,一群工程师为了解决这一问题,制定了各种协议与标准,让各种设备可以通过协议通信,进而通过互联网实现了让世界互联.&lt;/p&gt;
&lt;p&gt;就像我们现在写的代码,用着通用的程序语言,世界也就随之打通了.我们的计算机语言也算是一种协议.&lt;/p&gt;
&lt;p&gt;想要让世界互联,让计算机们都联合起来,就必须要用到网络协议让他们相互协作,来完成共同的目标.&lt;/p&gt;
&lt;h2 id="协议三要素"&gt;协议三要素&lt;/h2&gt;
&lt;p&gt;(1) 语义。每一段内容需要代表某种意义
(2) 语法。每一段内容符合一定规则的格式,
(3) 时序。每一段任务的执行顺序.&lt;/p&gt;
&lt;h2 id="网络分层"&gt;网络分层&lt;/h2&gt;
&lt;p&gt;网络分层就是将网络节点所要完成的数据的发送或转发、打包或拆包，控制信息的加载或拆出等工作，分别由不同的硬件和软件模块去完成。&lt;/p&gt;
&lt;p&gt;简单的来说一个完整的HTTP请求,途中需要经过数次传送,期间需要不通的都软件与硬件模块去完成相应的工作.
我们对相应的阶段的不通特性做出来相应的分类.每种网络分层,都有相应的协议标准做数据传送.&lt;/p&gt;
&lt;p&gt;就像是一家公司,不通层级的人会用着不通的沟通方式来打交道.网络也大概如此.&lt;/p&gt;
&lt;h2 id="我们常用的网络协议有哪些"&gt;我们常用的网络协议有哪些?&lt;/h2&gt;
&lt;p&gt;我们的网络在通讯过程中,要通过哪些设备,哪些协议才能做到一次完整的通讯?&lt;/p&gt;
&lt;p&gt;网络层次可划分为五层因特网协议栈和七层因特网协议栈&lt;/p&gt;
&lt;h3 id="五层模型"&gt;五层模型&lt;/h3&gt;
&lt;p&gt;因特网协议栈共有五层：应用层、传输层、网络层、链路层和物理层。不同于OSI七层模型这也是实际使用中使用的分层方式。
（1）应用层
支持网络应用，应用协议仅仅是网络应用的一个组成部分，运行在不同主机上的进程则使用应用层协议进行通信。
（2）传输层
负责为信源和信宿提供应用程序进程间的数据传输服务，这一层上主要定义了两个传输协议，传输控制协议即TCP和用户数据报协议UDP。
（3）网络层
负责将数据报独立地从信源发送到信宿，主要解决路由选择、拥塞控制和网络互联等问题。
（4）数据链路层
负责将IP数据报封装成合适在物理网络上传输的帧格式并传输，或将从物理网络接收到的帧解封，取出IP数据报交给网络层。
（5）物理层
负责将比特流在结点间传输，即负责物理传输。该层的协议既与链路有关也与传输介质有关&lt;/p&gt;
&lt;h3 id="五层模型对应的协议"&gt;五层模型对应的协议&lt;/h3&gt;
&lt;p&gt;物理层：以太网 · 调制解调器 · 电力线通信(PLC) · SONET/SDH · G.709 · 光导纤维 · 同轴电缆 · 双绞线等&lt;/p&gt;
&lt;p&gt;数据链路层：Wi-Fi(IEEE 802.11) · WiMAX(IEEE 802.16) ·ATM · DTM · 令牌环 · 以太网 ·FDDI · 帧中继 · GPRS · EVDO ·HSPA · HDLC · PPP · L2TP ·PPTP · ISDN·STP 等&lt;/p&gt;</description></item><item><title>Linux - Centos 时区设置</title><link>https://time-friend.com/zh/archive/linux-centos-timezone-setting/</link><pubDate>Mon, 30 Jul 2018 20:32:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/linux-centos-timezone-setting/</guid><description>&lt;h2 id="timedatectl-命令"&gt;timedatectl 命令&lt;/h2&gt;
&lt;h3 id="查看当前时区状态"&gt;查看当前时区状态&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ timedatectl status
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Local time: Fri 2018-08-31 13:42:42 CST
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Universal time: Fri 2018-08-31 05:42:42 UTC
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; RTC time: n/a
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Time zone: Asia/Shanghai &lt;span style="color:#f92672"&gt;(&lt;/span&gt;CST, +0800&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; NTP enabled: n/a
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;NTP synchronized: yes
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; RTC in local TZ: no
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; DST active: n/a
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="设置时区为上海"&gt;设置时区为上海&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ timedatectl set-timezone Asia/Shanghai &lt;span style="color:#75715e"&gt;# 设置系统时区为上海&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="其他操作"&gt;其他操作&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ timedatectl list-timezones &lt;span style="color:#75715e"&gt;# 列出所有时区&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ timedatectl set-local-rtc &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 将硬件时钟调整为与本地时钟一致, 0 为设置为 UTC 时间&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>MongoDB - 在Egg中使用MondoDB</title><link>https://time-friend.com/zh/archive/mongodb-in-eggjs/</link><pubDate>Fri, 18 May 2018 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/mongodb-in-eggjs/</guid><description>&lt;p&gt;MongoDB官方有提供node操作数据库的 driver 及 API : &lt;a href="https://github.com/mongodb/node-mongodb-native"&gt;node-mongodb-native&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;在egg社区也有基于该插件二次封装的egg插件 &lt;a href="https://github.com/brickyang/egg-mongo-native"&gt;egg-mongo-native&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;对一些方法做了一些二次封装,也可以调用原版的方法.&lt;/p&gt;
&lt;h2 id="配置"&gt;配置&lt;/h2&gt;
&lt;p&gt;官方文档也有相关的配置说明,但是我在实际使用中碰到了一些问题.
下面我给出正确的配置方法,供大家使用.其他相关知识请参照该插件都官方文档.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// {app_root}/config/config.default.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;appInfo&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;config&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;config&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;mongo&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;client&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;host&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;127.0.0.1&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;port&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;27017&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;dandelion&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;config&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="开启插件"&gt;开启插件&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// config/plugin.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;plugin&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;mongo&lt;/span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;enable&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;package&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;egg-mongo-native&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;要跟以上配置一样,才能正确使用该插件.&lt;/p&gt;
&lt;p&gt;其他复杂配置请参照该插件的官方文档.
&lt;a href="https://github.com/brickyang/egg-mongo-native"&gt;egg-mongo-native&lt;/a&gt;&lt;/p&gt;</description></item><item><title>MongoDB - 文档的基本操作 (二)</title><link>https://time-friend.com/zh/archive/mongodb-document-basic-operations-part-2/</link><pubDate>Sun, 13 May 2018 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/mongodb-document-basic-operations-part-2/</guid><description>&lt;h2 id="文档更新"&gt;文档更新&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;语法: update(&lt;filter&gt;, &lt;update&gt;, &lt;options&gt;)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#更新rank字段&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.update&lt;span style="color:#f92672"&gt;({&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;title&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;怪物猎人世界评测&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;}&lt;/span&gt;, &lt;span style="color:#f92672"&gt;{&lt;/span&gt;$set: &lt;span style="color:#f92672"&gt;{&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;rank&amp;#34;&lt;/span&gt;: 10&lt;span style="color:#f92672"&gt;}&lt;/span&gt; &lt;span style="color:#f92672"&gt;})&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 更新整条数据为:{&amp;#34;rank&amp;#34;: 99}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.update&lt;span style="color:#f92672"&gt;({&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;title&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;怪物猎人世界评测&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;}&lt;/span&gt;, &lt;span style="color:#f92672"&gt;{&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;rank&amp;#34;&lt;/span&gt;: 99&lt;span style="color:#f92672"&gt;})&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 更新多条记录multi: true,如果为false,则是更新查询到的第一条记录&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.update&lt;span style="color:#f92672"&gt;({&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;tag&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;it&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;}&lt;/span&gt;, &lt;span style="color:#f92672"&gt;{&lt;/span&gt;$set: &lt;span style="color:#f92672"&gt;{&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;rank&amp;#34;&lt;/span&gt;: 60&lt;span style="color:#f92672"&gt;}}&lt;/span&gt;, &lt;span style="color:#f92672"&gt;{&lt;/span&gt;multi: true&lt;span style="color:#f92672"&gt;})&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="操作文档字段的函数"&gt;操作文档字段的函数&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;$inc:递加&lt;/li&gt;
&lt;li&gt;$mul:相乘&lt;/li&gt;
&lt;li&gt;$rename:改名&lt;/li&gt;
&lt;li&gt;$set:新增or修改&lt;/li&gt;
&lt;li&gt;$unset:字段删除&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 字段值递增,结果为: 字段值 + 1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.update&lt;span style="color:#f92672"&gt;({&lt;/span&gt;title:&lt;span style="color:#e6db74"&gt;&amp;#34;怪物猎人世界评测&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;}&lt;/span&gt;, &lt;span style="color:#f92672"&gt;{&lt;/span&gt;$inc: &lt;span style="color:#f92672"&gt;{&lt;/span&gt;rank: 1&lt;span style="color:#f92672"&gt;}})&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 字段值相乘操作,结果为: 字段值 * 2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.update&lt;span style="color:#f92672"&gt;({&lt;/span&gt;title:&lt;span style="color:#e6db74"&gt;&amp;#34;怪物猎人世界评测&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;}&lt;/span&gt;, &lt;span style="color:#f92672"&gt;{&lt;/span&gt;$mul: &lt;span style="color:#f92672"&gt;{&lt;/span&gt;rank: 2&lt;span style="color:#f92672"&gt;}})&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 字段重命名&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.update&lt;span style="color:#f92672"&gt;({&lt;/span&gt;title:&lt;span style="color:#e6db74"&gt;&amp;#34;怪物猎人世界评测&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;}&lt;/span&gt;, &lt;span style="color:#f92672"&gt;{&lt;/span&gt;$rename: &lt;span style="color:#f92672"&gt;{&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;rank&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;score&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;}})&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 设置或者添加字段&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.update&lt;span style="color:#f92672"&gt;({&lt;/span&gt;title:&lt;span style="color:#e6db74"&gt;&amp;#34;怪物猎人世界评测&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;}&lt;/span&gt;, &lt;span style="color:#f92672"&gt;{&lt;/span&gt;$set: &lt;span style="color:#f92672"&gt;{&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;istop&amp;#34;&lt;/span&gt;: true&lt;span style="color:#f92672"&gt;}})&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 删除istop 字段&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.update&lt;span style="color:#f92672"&gt;({&lt;/span&gt;title:&lt;span style="color:#e6db74"&gt;&amp;#34;怪物猎人世界评测&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;}&lt;/span&gt;, &lt;span style="color:#f92672"&gt;{&lt;/span&gt;$unset: &lt;span style="color:#f92672"&gt;{&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;istop&amp;#34;&lt;/span&gt;: true&lt;span style="color:#f92672"&gt;}})&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="文档特殊更新"&gt;文档特殊更新&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;upsert:有则更新，无则追加&lt;/li&gt;
&lt;li&gt;remove:条件删除数据&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ mongo
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 更新整条数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.update&lt;span style="color:#f92672"&gt;({&lt;/span&gt;title:&lt;span style="color:#e6db74"&gt;&amp;#34;其实创造比大志好玩&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;}&lt;/span&gt;, &lt;span style="color:#f92672"&gt;{&lt;/span&gt;title:&lt;span style="color:#e6db74"&gt;&amp;#34;其实创造比大志好玩&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;rank&amp;#34;&lt;/span&gt;:5,&lt;span style="color:#e6db74"&gt;&amp;#34;tag&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;game&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;})&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#更新或者添加数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.update&lt;span style="color:#f92672"&gt;({&lt;/span&gt;title:&lt;span style="color:#e6db74"&gt;&amp;#34;其实创造比大志好玩&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;}&lt;/span&gt;, &lt;span style="color:#f92672"&gt;{&lt;/span&gt;title:&lt;span style="color:#e6db74"&gt;&amp;#34;其实创造比大志好玩&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;rank&amp;#34;&lt;/span&gt;:5,&lt;span style="color:#e6db74"&gt;&amp;#34;tag&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;game&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;}&lt;/span&gt;, &lt;span style="color:#f92672"&gt;{&lt;/span&gt;upsert:true&lt;span style="color:#f92672"&gt;})&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 删除数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.remove&lt;span style="color:#f92672"&gt;({&lt;/span&gt;title:&lt;span style="color:#e6db74"&gt;&amp;#34;其实创造比大志好玩&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;})&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="索引"&gt;索引&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;getIndexes() 获取索引&lt;/li&gt;
&lt;li&gt;createIndex({&amp;hellip;}, {&amp;hellip;}) 添加索引&lt;/li&gt;
&lt;li&gt;dropIndex({&amp;hellip;}) 删除索引&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 获取索引&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.getIndexes&lt;span style="color:#f92672"&gt;()&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 创建rank为降序索引&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.createIndex&lt;span style="color:#f92672"&gt;({&lt;/span&gt;rank:-1&lt;span style="color:#f92672"&gt;})&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 删除索引&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.dropIndex&lt;span style="color:#f92672"&gt;({&lt;/span&gt;rank:-1&lt;span style="color:#f92672"&gt;})&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 创建一个升序索引,并且不能重复,后续title重复则添加失败&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.createIndex&lt;span style="color:#f92672"&gt;({&lt;/span&gt;title:1&lt;span style="color:#f92672"&gt;}&lt;/span&gt;, &lt;span style="color:#f92672"&gt;{&lt;/span&gt;unique:true&lt;span style="color:#f92672"&gt;})&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>MongoDB - 文档的基本操作 (一)</title><link>https://time-friend.com/zh/archive/mongodb-document-basic-operations-part-1/</link><pubDate>Sat, 12 May 2018 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/mongodb-document-basic-operations-part-1/</guid><description>&lt;h2 id="文档增删"&gt;文档增删&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 创建集合&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.createCollection&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;posts&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 插入一条数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.insert&lt;span style="color:#f92672"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;... &lt;span style="color:#f92672"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;... title: &lt;span style="color:#e6db74"&gt;&amp;#34;我的第一篇博客&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;... content: &lt;span style="color:#e6db74"&gt;&amp;#34;已经开始写博客了，太激动了。&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;... &lt;span style="color:#f92672"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;... &lt;span style="color:#f92672"&gt;)&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 查询数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.find&lt;span style="color:#f92672"&gt;()&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 插入另一条数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.insert&lt;span style="color:#f92672"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;... &lt;span style="color:#f92672"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;... title: &lt;span style="color:#e6db74"&gt;&amp;#34;我的第二篇博客&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;... content: &lt;span style="color:#e6db74"&gt;&amp;#34;写点什么好呢？&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;... tag: &lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;未分类&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;... &lt;span style="color:#f92672"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;... &lt;span style="color:#f92672"&gt;)&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 使用js for 来循环插入数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt;&lt;span style="color:#f92672"&gt;(&lt;/span&gt;var i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 3; i &amp;lt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;10; i++ &lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#f92672"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;... db.posts.insert&lt;span style="color:#f92672"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;... title: &lt;span style="color:#e6db74"&gt;&amp;#34;我的第&amp;#34;&lt;/span&gt; + i + &lt;span style="color:#e6db74"&gt;&amp;#34;篇博客&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;... &lt;span style="color:#f92672"&gt;})&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;... &lt;span style="color:#f92672"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 查询数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.find&lt;span style="color:#f92672"&gt;()&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 查看数据count&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.count&lt;span style="color:#f92672"&gt;()&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 删除集合所有数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.remove&lt;span style="color:#f92672"&gt;({})&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.find&lt;span style="color:#f92672"&gt;()&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="文档带条件查询"&gt;文档带条件查询&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 查询tag 为game的数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.find&lt;span style="color:#f92672"&gt;({&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;tag&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;game&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;})&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 查询 rank大于或等于4的数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.find&lt;span style="color:#f92672"&gt;({&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;rank&amp;#34;&lt;/span&gt;: &lt;span style="color:#f92672"&gt;{&lt;/span&gt;$gte: 4&lt;span style="color:#f92672"&gt;}})&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 查询 rank大于或等于4的数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.find&lt;span style="color:#f92672"&gt;({&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;rank&amp;#34;&lt;/span&gt;: &lt;span style="color:#f92672"&gt;{&lt;/span&gt;$gt: 4&lt;span style="color:#f92672"&gt;}})&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 查询 rank小于或等于4的数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.find&lt;span style="color:#f92672"&gt;({&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;rank&amp;#34;&lt;/span&gt;: &lt;span style="color:#f92672"&gt;{&lt;/span&gt;$lte: 4&lt;span style="color:#f92672"&gt;}})&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 查询 rank小于4的数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.find&lt;span style="color:#f92672"&gt;({&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;rank&amp;#34;&lt;/span&gt;: &lt;span style="color:#f92672"&gt;{&lt;/span&gt;$lt: 4&lt;span style="color:#f92672"&gt;}})&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 正则查询&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.find&lt;span style="color:#f92672"&gt;({&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;title&amp;#34;&lt;/span&gt;: /u/&lt;span style="color:#f92672"&gt;})&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 多条件查询&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.find&lt;span style="color:#f92672"&gt;({&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;title&amp;#34;&lt;/span&gt;: /u/, &lt;span style="color:#e6db74"&gt;&amp;#34;rank&amp;#34;&lt;/span&gt;:&lt;span style="color:#f92672"&gt;{&lt;/span&gt;$gte:5&lt;span style="color:#f92672"&gt;}&lt;/span&gt; &lt;span style="color:#f92672"&gt;})&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# $or 或条件查询&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.find&lt;span style="color:#f92672"&gt;({&lt;/span&gt;$or: &lt;span style="color:#f92672"&gt;[{&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;title&amp;#34;&lt;/span&gt;: /u/&lt;span style="color:#f92672"&gt;}&lt;/span&gt;, &lt;span style="color:#f92672"&gt;{&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;rank&amp;#34;&lt;/span&gt;:&lt;span style="color:#f92672"&gt;{&lt;/span&gt;$gte:4&lt;span style="color:#f92672"&gt;}}]&lt;/span&gt; &lt;span style="color:#f92672"&gt;})&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# $in 包含, 查询rank中又3,4的数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.find&lt;span style="color:#f92672"&gt;({&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;rank&amp;#34;&lt;/span&gt;: &lt;span style="color:#f92672"&gt;{&lt;/span&gt;$in: &lt;span style="color:#f92672"&gt;[&lt;/span&gt;3,4&lt;span style="color:#f92672"&gt;]}&lt;/span&gt; &lt;span style="color:#f92672"&gt;})&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 判断是否存在&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.find&lt;span style="color:#f92672"&gt;({&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;istop&amp;#34;&lt;/span&gt;: &lt;span style="color:#f92672"&gt;{&lt;/span&gt;$exists: true&lt;span style="color:#f92672"&gt;}&lt;/span&gt; &lt;span style="color:#f92672"&gt;})&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 查询文章中有三个标签的数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.find&lt;span style="color:#f92672"&gt;({&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;tag&amp;#39;&lt;/span&gt;: &lt;span style="color:#f92672"&gt;{&lt;/span&gt;$size: 3&lt;span style="color:#f92672"&gt;}})&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 获取所有的tag类型,distinct作用是获取集合中指定字段的不重复值，并以数组的形式返回&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.posts.distinct&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;tag&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="mongodb-与-rdbms-where-语句比较"&gt;MongoDB 与 RDBMS Where 语句比较&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;操作&lt;/th&gt;
					&lt;th&gt;格式&lt;/th&gt;
					&lt;th&gt;范例&lt;/th&gt;
					&lt;th&gt;RDBMS中的类似语句&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;等于&lt;/td&gt;
					&lt;td&gt;{&lt;key&gt;:&lt;value&gt;}&lt;/td&gt;
					&lt;td&gt;db.col.find({&amp;ldquo;by&amp;rdquo;:&amp;ldquo;test&amp;rdquo;}).pretty()&lt;/td&gt;
					&lt;td&gt;where by = &amp;rsquo;test'&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;小于&lt;/td&gt;
					&lt;td&gt;{&lt;key&gt;:{$lt:&amp;lt;value%}}&lt;/td&gt;
					&lt;td&gt;db.col.find({&amp;ldquo;likes&amp;rdquo;:{$lt:50}}).pretty()&lt;/td&gt;
					&lt;td&gt;where likes &amp;lt; 50&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;小于或等于&lt;/td&gt;
					&lt;td&gt;{&lt;key&gt;:{$lte:&amp;lt;value%}}&lt;/td&gt;
					&lt;td&gt;db.col.find({&amp;ldquo;likes&amp;rdquo;:{$lte:50}}).pretty()&lt;/td&gt;
					&lt;td&gt;where likes &amp;lt;= 50&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;大于&lt;/td&gt;
					&lt;td&gt;{&lt;key&gt;:{$gt:&amp;lt;value%}}&lt;/td&gt;
					&lt;td&gt;db.col.find({&amp;ldquo;likes&amp;rdquo;:{$gt:50}}).pretty()&lt;/td&gt;
					&lt;td&gt;where likes &amp;gt; 50&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;大于或等于&lt;/td&gt;
					&lt;td&gt;{&lt;key&gt;:{$gte:&amp;lt;value%}}&lt;/td&gt;
					&lt;td&gt;db.col.find({&amp;ldquo;likes&amp;rdquo;:{$gte:50}}).pretty()&lt;/td&gt;
					&lt;td&gt;where likes &amp;gt;= 50&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;不等于&lt;/td&gt;
					&lt;td&gt;{&lt;key&gt;:{$ne:&amp;lt;value%}}&lt;/td&gt;
					&lt;td&gt;db.col.find({&amp;ldquo;likes&amp;rdquo;:{$ne:50}}).pretty()&lt;/td&gt;
					&lt;td&gt;where likes != 50&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="指定抽出字段"&gt;指定抽出字段&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;语法: db.[collection_name].find({}, {field1: true, field2: 1})&lt;/p&gt;</description></item><item><title>MongoDB - 数据库与集合的基本操作</title><link>https://time-friend.com/zh/archive/mongodb-database-and-collection-basic-operations/</link><pubDate>Fri, 11 May 2018 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/mongodb-database-and-collection-basic-operations/</guid><description>&lt;h1 id="数据库基本操作"&gt;数据库基本操作&lt;/h1&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 进入命令行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ mongo
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#帮助&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; help
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#退出&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; exit
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#显示所有数据库&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; show dbs;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#进入或者创建集合&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; use aliliblog;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#查看当前数据库状态&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.stats&lt;span style="color:#f92672"&gt;()&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 删除数据库&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.dropDatabase&lt;span style="color:#f92672"&gt;()&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="操作集合collection"&gt;操作集合（Collection）&lt;/h1&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 查看集合&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; show collections;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 创建集合&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.createCollection&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;users&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 集合重命名&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.users.renameCollection&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;staff&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;; // users -&amp;gt; staff
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 集合删除&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; db.staff.drop&lt;span style="color:#f92672"&gt;()&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>MongoDB - 基本概念与其他数据库对比</title><link>https://time-friend.com/zh/archive/mongodb-basic-concepts-and-comparison-with-other-databases/</link><pubDate>Thu, 10 May 2018 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/mongodb-basic-concepts-and-comparison-with-other-databases/</guid><description>&lt;h1 id="基本概念"&gt;基本概念&lt;/h1&gt;
&lt;h2 id="nosql"&gt;NoSql&lt;/h2&gt;
&lt;p&gt;在NoSql的数据库中，操作数据都是通过指令或程序语言完成的。&lt;/p&gt;
&lt;p&gt;在MongoDB中使用过JavaScript和JSON数据结构，来操作和管理数据的。&lt;/p&gt;
&lt;h2 id="mongodb数据库与关系型数据库对比"&gt;MongoDB数据库与关系型数据库对比&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;MongoDB&lt;/th&gt;
					&lt;th&gt;关系型数据库&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;数据库（Database)&lt;/td&gt;
					&lt;td&gt;数据库（Database）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;集合（Collection）&lt;/td&gt;
					&lt;td&gt;数据表（Table）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;文档（Document）&lt;/td&gt;
					&lt;td&gt;记录（Record）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="mongodb与rdbms对应的术语"&gt;MongoDB与RDBMS对应的术语&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;MongoDB&lt;/th&gt;
					&lt;th&gt;RDBMS&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;数据库&lt;/td&gt;
					&lt;td&gt;数据库&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;集合&lt;/td&gt;
					&lt;td&gt;表格&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;文档&lt;/td&gt;
					&lt;td&gt;行&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;字段&lt;/td&gt;
					&lt;td&gt;列&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;嵌入文档&lt;/td&gt;
					&lt;td&gt;表联合&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;主键 (MongoDB 提供了 key 为 _id )&lt;/td&gt;
					&lt;td&gt;主键&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="mongodb-数据类型"&gt;MongoDB 数据类型&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;数据类型&lt;/th&gt;
					&lt;th&gt;描述&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;String&lt;/td&gt;
					&lt;td&gt;字符串。存储数据常用的数据类型。在 MongoDB 中，UTF-8 编码的字符串才是合法的。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Integer&lt;/td&gt;
					&lt;td&gt;整型数值。用于存储数值。根据你所采用的服务器，可分为 32 位或 64 位。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Boolean&lt;/td&gt;
					&lt;td&gt;布尔值。用于存储布尔值（真/假）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Double&lt;/td&gt;
					&lt;td&gt;双精度浮点值。用于存储浮点值。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Min/Max keys&lt;/td&gt;
					&lt;td&gt;将一个值与 BSON（二进制的 JSON）元素的最低值和最高值相对比。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Array&lt;/td&gt;
					&lt;td&gt;用于将数组或列表或多个值存储为一个键。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Timestamp&lt;/td&gt;
					&lt;td&gt;时间戳。记录文档修改或添加的具体时间。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Object&lt;/td&gt;
					&lt;td&gt;用于内嵌文档。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Null&lt;/td&gt;
					&lt;td&gt;用于创建空值。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Symbol&lt;/td&gt;
					&lt;td&gt;符号。该数据类型基本上等同于字符串类型，但不同的是，它一般用于采用特殊符号类型的语言。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Date&lt;/td&gt;
					&lt;td&gt;日期时间。用 UNIX 时间格式来存储当前日期或时间。你可以指定自己的日期时间：创建 Date 对象，传入年月日信息。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Object ID&lt;/td&gt;
					&lt;td&gt;对象 ID。用于创建文档的 ID。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Binary Data&lt;/td&gt;
					&lt;td&gt;二进制数据。用于存储二进制数据。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Code&lt;/td&gt;
					&lt;td&gt;代码类型。用于在文档中存储 JavaScript 代码。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Regular&lt;/td&gt;
					&lt;td&gt;expression	正则表达式类型。用于存储正则表达式。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;</description></item><item><title>MongoDB - 安装与启动</title><link>https://time-friend.com/zh/archive/mongodb-installation-and-startup/</link><pubDate>Wed, 09 May 2018 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/mongodb-installation-and-startup/</guid><description>&lt;h1 id="什么是mongodb"&gt;什么是MongoDB？&lt;/h1&gt;
&lt;p&gt;MongoDB是一个面向文档的免费数据库，多用于数据采集和分散处理(Map/Reduce)，特别是在大数据处理方面比较擅长。&lt;/p&gt;
&lt;p&gt;MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。&lt;/p&gt;
&lt;p&gt;MongoDB 是一个介于关系数据库和非关系数据库之间的产品，是非关系数据库当中功能最丰富，最像关系数据库的。&lt;/p&gt;
&lt;h2 id="macos-os安装与启动"&gt;macOS OS安装与启动&lt;/h2&gt;
&lt;h3 id="安装"&gt;安装&lt;/h3&gt;
&lt;p&gt;最简单的是通过 brew 安装&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew update
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 就这样mac上就安装好了&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew install mongodb
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 如果你需要最新的开发版本&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew install mongodb --devel
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="启动"&gt;启动&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#新建默认数据文件夹&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mkdir -p /data/db
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 直接启动&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mongod
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 指定路径启动&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mongod --dbpath &amp;lt;path to data directory&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 连接默认端口数据库&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mongo
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#指定端口连接数据库&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mongo --host 127.0.0.1:27017
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="centos安装与启动"&gt;centOS安装与启动&lt;/h2&gt;
&lt;h3 id="安装-1"&gt;安装&lt;/h3&gt;
&lt;p&gt;新建一个文件 &lt;code&gt;/etc/yum.repos.d/mongodb-org-4.0.repo &lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;mongodb-org-4.0&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;name&lt;span style="color:#f92672"&gt;=&lt;/span&gt;MongoDB Repository
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;baseurl&lt;span style="color:#f92672"&gt;=&lt;/span&gt;https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.0/x86_64/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gpgcheck&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;enabled&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gpgkey&lt;span style="color:#f92672"&gt;=&lt;/span&gt;https://www.mongodb.org/static/pgp/server-4.0.asc
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;通过yum安装数据库&lt;/p&gt;</description></item><item><title>以太坊开发之搭建宠物商店</title><link>https://time-friend.com/zh/archive/ethereum-development-build-pet-shop/</link><pubDate>Sat, 21 Apr 2018 19:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/ethereum-development-build-pet-shop/</guid><description>&lt;p&gt;truffle的宠物商店是一个了解以太坊开发的一个很不错的例子.
跟着官方提供的demo与教程,可以完整的感受一下整个流程的开发.&lt;/p&gt;
&lt;h2 id="ganache"&gt;Ganache&lt;/h2&gt;
&lt;p&gt;为了环境需要,并且快速的在本地搭建一个私有链环境.
truffle推出了一个可视化私有链客户端:
&lt;a href="http://truffleframework.com/ganache/"&gt;Ganache下载地址&lt;/a&gt;
下载之后运行,你会看到这样一个界面:
&lt;img src="https://static.alili.tech/images/Jietu20180421-213717.jpg" alt=""&gt;&lt;/p&gt;
&lt;h2 id="初始化你的项目"&gt;初始化你的项目&lt;/h2&gt;
&lt;p&gt;首先我们新建一个目录,并且初始化一下项目&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ mkdir pet-shop
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ cd pet-shop
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ truffle unbox pet-shop
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="项目目录结构"&gt;项目目录结构&lt;/h2&gt;
&lt;p&gt;这里只列出了重要的目录与文件&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;├── bs-config.json
├── contracts //合约目录
│   └── Migrations.sol //合约文件
├── migrations // 部署脚本
│   └── 1_initial_migration.js
├── package-lock.json
├── package.json
├── src // 前端代码目录
├── test // 测试代码目录
└── truffle.js // truffle配置文件
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="编写智能合约"&gt;编写智能合约&lt;/h2&gt;
&lt;p&gt;在contracts/目录中,创建一个Adoption.sol文件
文件内容:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;pragma&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;solidity&lt;/span&gt; &lt;span style="color:#f92672"&gt;^&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0.4&lt;/span&gt;.&lt;span style="color:#ae81ff"&gt;17&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;contract&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Adoption&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;address&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;16&lt;/span&gt;] &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;adopters&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// 声明一个地址变量,用于保存领养者地址
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 领养宠物
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;adopt&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;uint&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;petId&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;returns&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;uint&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;petId&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;petId&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;15&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// 确保宠物id正确,为0到15之间,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 如果不符合条件就会回滚 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//msg.sender 为调用这个函数的人的地址
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;adopters&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;petId&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;msg&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;sender&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// 保存调用这地址 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;petId&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 返回领养者
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getAdopters&lt;/span&gt;() &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;view&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;returns&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;address&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;16&lt;/span&gt;]) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;adopters&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="编译你的智能合约"&gt;编译你的智能合约&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ truffle compile
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;//输出
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Compiling ./contracts/Adoption.sol...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Writing artifacts to ./build/contracts
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这样你就会发现你的项目多了一个build文件夹,
里面存放这里刚刚写好的智能合约编译完成的json文件&lt;/p&gt;</description></item><item><title>以太坊开发之Solidity初学者的编辑器 -- remix-ide</title><link>https://time-friend.com/zh/archive/ethereum-development-solidity-beginner-editor-remix-ide/</link><pubDate>Fri, 20 Apr 2018 19:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/ethereum-development-solidity-beginner-editor-remix-ide/</guid><description>&lt;p&gt;在以太坊应用的开发中智能合约的开发是避不开的.
就目前来说,我发现的remix-ide是对新人最有好的开发工具了.
不需要其他任何的环境,就可以直接部署调试.
如果我发现了更加友好的,我会在以后的博客里推荐.&lt;/p&gt;
&lt;h2 id="安装"&gt;安装&lt;/h2&gt;
&lt;p&gt;remix就是一个普通的npm包&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ npm i remix-ide -g
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="启动"&gt;启动&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ remix-ide
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;默认会启动本地8080端口,打开浏览器 &lt;code&gt;http://localhost:8080&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://static.alili.tech/images/localhost_8080_.png" alt=""&gt;&lt;/p&gt;
&lt;h2 id="使用"&gt;使用&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;首先我们要勾选自动编译
&lt;img src="https://static.alili.tech/images/Jietu20180421-180045.jpg" alt=""&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;2. 切换到 Run ,环境选择 javascript VM
&lt;img src="https://static.alili.tech/images/Jietu20180421-180308.jpg" alt=""&gt;&lt;/p&gt;
&lt;h2 id="部署你的程序"&gt;部署你的程序&lt;/h2&gt;
&lt;p&gt;点击create按钮,就可以部署你的智能合约了.
如下图,便是部署了智能合约的样子,因为每次部署都会消耗掉相应的余额.
所以这个用户的余额从刚才的 &lt;code&gt;100&lt;/code&gt;以太币变成了现在的 &lt;code&gt;99.999999999...&lt;/code&gt;
&lt;img src="https://static.alili.tech/images/Jietu20180421-180547.jpg" alt=""&gt;&lt;/p&gt;
&lt;h2 id="调试你的程序"&gt;调试你的程序&lt;/h2&gt;
&lt;p&gt;部署完成之后,我们发现下面出现了一个有函数名称的按钮与输入框.
输入框内可填写该函数的参数.点击一下函数名,便可执行该函数了.
执行结果,会在中间下面的控制台显示.
&lt;img src="https://static.alili.tech/images/Jietu20180421-182023.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;点击一下控制台信息的detail按钮,便可看到函数详细的输出信息&lt;/p&gt;
&lt;p&gt;&lt;img src="https://static.alili.tech/images/Jietu20180421-182131.jpg" alt=""&gt;&lt;/p&gt;</description></item><item><title>以太坊开发之一切从脚手架truffle开始</title><link>https://time-friend.com/zh/archive/ethereum-truffle-setup/</link><pubDate>Thu, 19 Apr 2018 19:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/ethereum-truffle-setup/</guid><description>&lt;p&gt;这个礼拜开始学习区块链开发,为了公司区块链项目开始之前有一定的知识储备.
在博客做一下知识复盘.&lt;/p&gt;
&lt;h2 id="truffle是什么"&gt;truffle是什么&lt;/h2&gt;
&lt;p&gt;Truffle是针对基于以太坊的Solidity语言的一套开发框架。本身是基于JavaScript实现的。
虽然是使用我们熟悉的JavaScript实现,
但是truffle主要还只是一个编译与发布&lt;code&gt;智能合约&lt;/code&gt;的一个工具(当然还有其他的功能).&lt;/p&gt;
&lt;h2 id="solidity是什么"&gt;Solidity是什么&lt;/h2&gt;
&lt;p&gt;在区块链应用的开发中,Solidity语言你或许大致的可以理解为编写后台的一种语言. 在专业术语里,这种后台代码叫做 &lt;code&gt;智能合约&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="truffle的主要作用"&gt;truffle的主要作用&lt;/h2&gt;
&lt;p&gt;Truffle在区块链应用的开发中,主要是提供两个重要的功能.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;编译智能合约&lt;/li&gt;
&lt;li&gt;发布智能合约&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="安装"&gt;安装&lt;/h2&gt;
&lt;p&gt;跟普通的npm包一样,用npm直接安装&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 全局安装truffle&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ npm i truffle -g
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="初始化你的项目"&gt;初始化你的项目&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 我们新建一个目录 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ mkdir myproject
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ cd myproject
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#初始化&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ truffle init
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 执行命令后&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Downloading...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Unpacking...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Setting up...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Unbox successful. Sweet!
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Commands:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# truffle的其他操作 编译,发布,测试&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Compile: truffle compile
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Migrate: truffle migrate
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Test contracts: truffle test
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;完成之后你会看到以下目录&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; contract/ - 智能合约Solidity代码
 migrations/ - 智能合约发布的脚本
 test/ - 测试文件
 truffle.js - Truffle的配置文件
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;下面是初始化自动生成的Solidity代码,以后一部分开发工作主要就是写这东西.
编译完成之后,再使用前端js调用这些方法.&lt;/p&gt;</description></item><item><title>使用verdaccio搭建更加简单的私有npm服务器</title><link>https://time-friend.com/zh/archive/build-simple-private-npm-server-with-verdaccio/</link><pubDate>Tue, 10 Apr 2018 22:30:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/build-simple-private-npm-server-with-verdaccio/</guid><description>&lt;p&gt;cnpm.org这种私有npm服务器搭建已经很简单了,
但是相对于verdaccio的简单那是完全没有办法比的.
因为verdaccio实在是太简单了.&lt;/p&gt;
&lt;h3 id="介绍"&gt;介绍&lt;/h3&gt;
&lt;p&gt;verdaccio是一个轻量级的私有NPM的Registry（从 Sinopia fork过来的，sinopia最后一次更新是在几年前了）。最开始是打算使用cnpmjs这个来搭建私有的npm仓库但是搭建完成之后存在一些问题，所以使用了Sinopia;&lt;/p&gt;
&lt;p&gt;接下来我将简单介绍一下 verdaccio的使用.&lt;/p&gt;
&lt;h3 id="在你的服务器安装verdaccio"&gt;在你的服务器安装verdaccio&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ npm i verdaccio -g
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="启动"&gt;启动&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#直接输入 verdaccio 命令&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ verdaccio
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;// 如果启动成功会显示以下信息
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Verdaccio doesn‘t need superuser privileges. Don‘t run it und
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; warn --- config file - /root/.config/verdaccio/config.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; warn --- http address - http://localhost:4873/ - verdaccio/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我们也可以用pm2启动 (也是我选择使用的方法)&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-bash" data-lang="bash"&gt;$ pm2 start verdaccio
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="配置"&gt;配置&lt;/h3&gt;
&lt;p&gt;系统默认的配置文件在 &lt;code&gt;/root/.config/verdaccio/config.yaml&lt;/code&gt;
下面是我现在的配置,大家可以简单的参考一下.
基本上没有改什么.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# This is the default config file. It allows all users to do anything,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# so don&amp;#39;t use it on production systems.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Look here for more config file examples:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# https://github.com/verdaccio/verdaccio/tree/master/conf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#这里是你默认存储的包的位置,我根据我自己的情况做了相应修改&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#storage: /root/.local/share/verdaccio/storage&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;storage&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;/data01/verdaccio/storage&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#端口号,地址要这样设置外面才好访问&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;listen&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0.0.0.0&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;4873&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;auth&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;htpasswd&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;file&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;./htpasswd&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Maximum amount of users allowed to register, defaults to &amp;#34;+inf&amp;#34;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# You can set this to -1 to disable registration.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;#max_users: 1000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#npm设置我直接代理了淘宝的源&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#这样我就不需要再去主动同步包了,本地请求不到的直接请求淘宝源&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;uplinks&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;npmjs&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;url&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;https://registry.npm.taobao.org&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;packages&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#39;@*/*&amp;#39;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# scoped packages&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;access&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;$all&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;publish&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;$authenticated&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;proxy&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;npmjs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#39;**&amp;#39;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# allow all users (including non-authenticated users) to read and&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# publish all packages&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# you can specify usernames/groupnames (depending on your auth plugin)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# and three keywords: &amp;#34;$all&amp;#34;, &amp;#34;$anonymous&amp;#34;, &amp;#34;$authenticated&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;access&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;$all&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# allow all known users to publish packages&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# (anyone can register by default, remember?)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;publish&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;$authenticated&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# if package is not available locally, proxy requests to &amp;#39;npmjs&amp;#39; registry&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;proxy&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;npmjs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# log settings&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;logs&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - {&lt;span style="color:#f92672"&gt;type&lt;/span&gt;: &lt;span style="color:#f92672"&gt;stdout, format&lt;/span&gt;: &lt;span style="color:#f92672"&gt;pretty, level&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;http}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;#- {type: file, path: verdaccio.log, level: info}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Git push卡住解决办法</title><link>https://time-friend.com/zh/archive/git-push-stuck-solution/</link><pubDate>Mon, 09 Apr 2018 19:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/git-push-stuck-solution/</guid><description>&lt;p&gt;博客的每天英语是直接爬的扇贝英语,为了不直接请求代理接口(会相对比较慢).
所以每天我的程序每天会生成相应的数据文件,前端直接ajax获取就好了.
博客内容也会每天自动发布,达到每天更新名言名句的效果.
好久没管,发现很多git提交的内容没有push.手动直接push之后发现有800多个修改地方没有push.&lt;/p&gt;
&lt;p&gt;手动push的时候直接卡住了.
就像这样:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;master 9447645&lt;span style="color:#f92672"&gt;]&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; file changed, &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; insertion&lt;span style="color:#f92672"&gt;(&lt;/span&gt;+&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Counting objects: 20, &lt;span style="color:#66d9ef"&gt;done&lt;/span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Compressing objects: 100% &lt;span style="color:#f92672"&gt;(&lt;/span&gt;876/876&lt;span style="color:#f92672"&gt;)&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;done&lt;/span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Writing objects: 100% &lt;span style="color:#f92672"&gt;(&lt;/span&gt;876/876&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;网上找了个方法,解决了这个问题:
添加sendpack.sideband属性并置为false&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 全局的：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git config –global sendpack.sideband false
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 仓库的：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git config –local sendpack.sideband false
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我只在我的本地仓库设置一下,然后再执行 &lt;code&gt;git push&lt;/code&gt;就成功了&lt;/p&gt;</description></item><item><title>Linux - SSH连接远程服务器直接执行command时PATH不全解决方案</title><link>https://time-friend.com/zh/archive/linux-ssh-path-issue-non-interactive/</link><pubDate>Thu, 15 Mar 2018 20:32:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/linux-ssh-path-issue-non-interactive/</guid><description>&lt;h2 id="non-interactive-mode下path不全"&gt;non-interactive mode下PATH不全&lt;/h2&gt;
&lt;p&gt;ssh &lt;a href="mailto:username@desktop.domain"&gt;username@desktop.domain&lt;/a&gt; &amp;lsquo;command&amp;rsquo;这种是典型的non-interactive shell，PATH不全.&lt;/p&gt;
&lt;h2 id="原因"&gt;原因&lt;/h2&gt;
&lt;p&gt;Linux系统中一种常用的判断是否是交互shell的方式就是通过PS1变量，虽然还有其他的方式，不过现在.bashrc中是通过PS1来判断是否为interactive mode。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# .bashrc文件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# If not running interactively, don&amp;#39;t do anything &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt; -z &lt;span style="color:#e6db74"&gt;&amp;#34;PS1&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="解决方案"&gt;解决方案&lt;/h2&gt;
&lt;p&gt;将必要的export PATH的声明，全部移到[ -z &amp;ldquo;PS1&amp;rdquo; ] &amp;amp;&amp;amp; return 之前。保证在non-interactive mode下，PATH的设置也都会生效。&lt;/p&gt;</description></item><item><title>Centos7环境下启动Puppeteer失败解决办法</title><link>https://time-friend.com/zh/archive/centos7-puppeteer-startup-failure-solution/</link><pubDate>Sun, 25 Feb 2018 19:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/centos7-puppeteer-startup-failure-solution/</guid><description>&lt;blockquote&gt;
&lt;p&gt;小贴士: 在centos6环境下,是不能启动puppeteer的,在centos6下,很多puppeteer依赖库是不存在的.所以如果你想在centos6上运行puppeteer,建议还是放弃,把时间花在其他地方比较值得.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="缺少依赖"&gt;缺少依赖&lt;/h1&gt;
&lt;p&gt;在新的centos7上运行puppeteer往往会运行失败,很多时候会报这样的错:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;...node_modules/puppeteer/.local-chromium/linux-496140/chrome-linux/chrome: error while loading shared libraries: libpangocairo-1.0.so.0: cannot open shared object file: No such file or directory
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这样的错表示,缺少依赖.&lt;/p&gt;
&lt;p&gt;下面列出,你的系统可能需要安装的依赖库,使用yum安装&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#字体&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;yum install ipa-gothic-fonts xorg-x11-fonts-100dpi xorg-x11-fonts-75dpi xorg-x11-utils xorg-x11-fonts-cyrillic xorg-x11-fonts-Type1 xorg-x11-fonts-misc -y
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#依赖库&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;yum install pango.x86_64 libXcomposite.x86_64 libXcursor.x86_64 libXdamage.x86_64 libXext.x86_64 libXi.x86_64 libXtst.x86_64 cups-libs.x86_64 libXScrnSaver.x86_64 libXrandr.x86_64 GConf2.x86_64 alsa-lib.x86_64 atk.x86_64 gtk3.x86_64 -y
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="禁用沙箱模式"&gt;禁用沙箱模式&lt;/h1&gt;
&lt;p&gt;在Linux环境下,往往还会出现以下错误:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/GoogleChrome/puppeteer/issues/290"&gt;https://github.com/GoogleChrome/puppeteer/issues/290&lt;/a&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;(node:30559) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Failed to connect to chrome!
(node:30559) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="js示例代码"&gt;js示例代码&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;puppeteer&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;puppeteer&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;(&lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; () =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//禁用沙箱模式
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;browser&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;puppeteer&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;launch&lt;/span&gt;({&lt;span style="color:#a6e22e"&gt;args&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;&amp;#39;--no-sandbox&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;--disable-setuid-sandbox&amp;#39;&lt;/span&gt;]});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;page&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;browser&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;newPage&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;browser&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;close&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;})();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Linux - vim vi学习笔记</title><link>https://time-friend.com/zh/archive/linux-vim-vi-learning-notes/</link><pubDate>Sat, 17 Feb 2018 20:32:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/linux-vim-vi-learning-notes/</guid><description>&lt;p&gt;很多时候在mac也好linux也好,因为经常要使用到,但是操作与其他的编辑器差别又很大,所以专门学习一下,在使用的时候也不至于非常多迷惑.在学习中要多练多用才会熟练于心.&lt;/p&gt;
&lt;h1 id="vimvi-的三种模式"&gt;vim/vi 的三种模式&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;命令模式（Command mode）&lt;/li&gt;
&lt;li&gt;输入模式（Insert mode）&lt;/li&gt;
&lt;li&gt;底线命令模式（Last line mode）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="命令模式command-mode"&gt;命令模式（Command mode）&lt;/h2&gt;
&lt;p&gt;当我们使用vim打开一个文件的时候,会进入命令模式.在命令模式下并不能输入编辑文本.
在命令模式下,可以输入以下切换到其他模式&lt;/p&gt;
&lt;h3 id="切换到输入模式"&gt;切换到输入模式&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;i
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;想要会到命令模式需要按一下 esc 按键.&lt;/p&gt;
&lt;h3 id="切换到底线命令模式"&gt;切换到底线命令模式&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;:
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;想要会到命令模式需要按一下 esc 按键.&lt;/p&gt;
&lt;h1 id="具体操作"&gt;具体操作&lt;/h1&gt;
&lt;h2 id="光标的移动"&gt;光标的移动&lt;/h2&gt;
&lt;p&gt;光标的移动我们可以使用普通的方向键,也可以有vi独有的方式&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;按键&lt;/th&gt;
					&lt;th&gt;行为&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;h 或 向左箭头键(←)&lt;/td&gt;
					&lt;td&gt;光标向左移动一个字符&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;j 或 向下箭头键(↓)&lt;/td&gt;
					&lt;td&gt;光标向下移动一个字符&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;k 或 向上箭头键(↑)&lt;/td&gt;
					&lt;td&gt;光标向上移动一个字符&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;l 或 向右箭头键(→)&lt;/td&gt;
					&lt;td&gt;光标向右移动一个字符&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="各种输入模式的切换"&gt;各种输入模式的切换&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;按键&lt;/th&gt;
					&lt;th&gt;行为&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;i, I&lt;/td&gt;
					&lt;td&gt;进入输入模式(Insert mode)：为『从目前光标所在处输入』， I 为『在目前所在行的第一个非空格符处开始输入』&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;a A&lt;/td&gt;
					&lt;td&gt;为『从目前光标所在的下一个字符处开始输入』， A 为『从光标所在行的最后一个字符处开始输入』。(常用)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;o, O&lt;/td&gt;
					&lt;td&gt;进入输入模式(Insert mode) 这是英文字母 o 的大小写。o 为『在目前光标所在的下一行处输入新的一行』； O 为在目前光标所在处的上一行输入新的一行！(常用)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;r, R&lt;/td&gt;
					&lt;td&gt;取代模式: r 只会取代光标所在的那一个字符一次；R会一直取代光标所在的文字，直到按下 ESC 为止；(常用)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;[Esc]&lt;/td&gt;
					&lt;td&gt;退出编辑模式，回到一般模式中(常用)&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="复制与删除"&gt;复制与删除&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;按键&lt;/th&gt;
					&lt;th&gt;行为&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;x, X&lt;/td&gt;
					&lt;td&gt;在一行字当中，x 为向后删除一个字符 (相当于 [del] 按键)， X 为向前删除一个字符(相当[backspace] 亦即是退格键) (常用)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;nx	n&lt;/td&gt;
					&lt;td&gt;为数字，连续向后删除 n 个字符。举例来说，我要连续删除 10 个字符， 『10x』。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;dd&lt;/td&gt;
					&lt;td&gt;删除游标所在的那一整行(常用)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;ndd&lt;/td&gt;
					&lt;td&gt;n 为数字。删除光标所在的向下 n 行，例如 20dd 则是删除 20 行 (常用)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;d1G&lt;/td&gt;
					&lt;td&gt;删除光标所在到第一行的所有数据&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;dG&lt;/td&gt;
					&lt;td&gt;删除光标所在到最后一行的所有数据&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;d$&lt;/td&gt;
					&lt;td&gt;删除游标所在处，到该行的最后一个字符&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;d0&lt;/td&gt;
					&lt;td&gt;那个是数字的 0 ，删除游标所在处，到该行的最前面一个字符&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;yy&lt;/td&gt;
					&lt;td&gt;复制游标所在的那一行(常用)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;nyy&lt;/td&gt;
					&lt;td&gt;n 为数字。复制光标所在的向下 n 行，例如 20yy 则是复制 20 行(常用)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;y1G&lt;/td&gt;
					&lt;td&gt;复制游标所在行到第一行的所有数据&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;yG&lt;/td&gt;
					&lt;td&gt;复制游标所在行到最后一行的所有数据&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;y0&lt;/td&gt;
					&lt;td&gt;复制光标所在的那个字符到该行行首的所有数据&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;y$&lt;/td&gt;
					&lt;td&gt;复制光标所在的那个字符到该行行尾的所有数据&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;p, P&lt;/td&gt;
					&lt;td&gt;p 为将已复制的数据在光标下一行贴上，P 则为贴在游标上一行！ 举例来说，我目前光标在第 20 行，且已经复制了 10 行数据。则按下 p 后， 那 10 行数据会贴在原本的 20 行之后，亦即由 21 行开始贴。但如果是按下 P 呢？ 那么原本的第 20 行会被推到变成 30 行。 (常用)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;J&lt;/td&gt;
					&lt;td&gt;将光标所在行与下一行的数据结合成同一行&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;c&lt;/td&gt;
					&lt;td&gt;重复删除多个数据，例如向下删除 10 行，[ 10cj ]&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;u&lt;/td&gt;
					&lt;td&gt;复原前一个动作。(常用)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;[Ctrl]+r&lt;/td&gt;
					&lt;td&gt;重做上一个动作。(常用)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;.&lt;/td&gt;
					&lt;td&gt;不要怀疑！这就是小数点！意思是重复前一个动作的意思。 如果你想要重复删除、重复贴上等等动作，按下小数点『.』就好了！ (常用)&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;u 与 [Ctrl]+r 是很常用的指令！一个是复原，另一个则是重做一次～ 利用这两个功能按键，你的编辑，嘿嘿！很快乐的啦！&lt;/p&gt;</description></item><item><title>Linux - 安装nginx步骤</title><link>https://time-friend.com/zh/archive/linux-install-nginx-steps/</link><pubDate>Tue, 16 Jan 2018 20:32:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/linux-install-nginx-steps/</guid><description>&lt;h3 id="安装nginx相关的依赖"&gt;安装nginx相关的依赖&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;yum install gcc
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;yum install pcre-devel
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;yum install zlib zlib-devel
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;yum install openssl openssl-devel
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;当然你也可以一起安装&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="下载nginx的tar压缩包"&gt;下载nginx的tar压缩包&lt;/h3&gt;
&lt;p&gt;进入网页 &lt;a href="http://nginx.org/download/"&gt;http://nginx.org/download/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;选择你需要的版本:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 进入local文件夹&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cd /usr/local
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 我选择了一个相对较新的版本,下载到当前目录&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; wget http://nginx.org/download/nginx-1.13.9.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 解压&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tar -xvf nginx-1.13.9.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# 重命名&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; mv nginx-1.13.9.tar.gz nginx
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;#进入nginx目录&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cd nginx
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;#执行以下命令&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ./configure
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;#编译&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; make
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;进行以上步骤之后,你的nginx就已经安装完毕了&lt;/p&gt;
&lt;h3 id="nginx常用命令"&gt;nginx常用命令&lt;/h3&gt;
&lt;p&gt;以下操作全都是在nginx目录下进行&lt;/p&gt;
&lt;h4 id="启动"&gt;启动:&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;./sbin/nginx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="停止"&gt;停止:&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;./sbin/nginx -s stop
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#或者&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;./sbin/nginx -s quit
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="重启"&gt;重启:&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;./sbin/nginx -s reload
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="查看进程命令"&gt;查看进程命令&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ps -ef | grep nginx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>一个没有界面的Chrome浏览器：Puppeteer</title><link>https://time-friend.com/zh/archive/a-headless-chrome-browser-puppeteer/</link><pubDate>Thu, 21 Dec 2017 20:32:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/a-headless-chrome-browser-puppeteer/</guid><description>&lt;h2 id="puppeteer介绍"&gt;Puppeteer介绍&lt;/h2&gt;
&lt;p&gt;Puppeteer是一个node库，提供了一组用来操纵Chrome的API。
相对PhantomJS来说，他可以直接在你的node项目里面直接调用Chrome的API。
以后很多的自动化测试，爬虫都可以基于Puppeteer来做。&lt;/p&gt;
&lt;h2 id="安装"&gt;安装&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm install puppeteer
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="使用"&gt;使用&lt;/h2&gt;
&lt;h3 id="截屏"&gt;截屏&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;puppeteer&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;puppeteer&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;(&lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; () =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;browser&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;puppeteer&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;launch&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;page&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;browser&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;newPage&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;page&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;goto&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;https://example.com&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;page&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;screenshot&lt;/span&gt;({&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;example.png&amp;#39;&lt;/span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;browser&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;close&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;})();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="保存页面为pdf"&gt;保存页面为PDF&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;puppeteer&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;puppeteer&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;(&lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; () =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;browser&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;puppeteer&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;launch&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;page&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;browser&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;newPage&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;page&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;goto&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;https://news.ycombinator.com&amp;#39;&lt;/span&gt;, {&lt;span style="color:#a6e22e"&gt;waitUntil&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;networkidle2&amp;#39;&lt;/span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;page&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;pdf&lt;/span&gt;({&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;hn.pdf&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;format&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;A4&amp;#39;&lt;/span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;browser&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;close&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;})();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Puppeteer 还提供了很多的Chrome API
&lt;a href=""&gt;https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md&lt;/a&gt;&lt;/p&gt;</description></item><item><title>算法复杂度分析</title><link>https://time-friend.com/zh/archive/algorithm-complexity-analysis/</link><pubDate>Tue, 19 Dec 2017 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/algorithm-complexity-analysis/</guid><description>&lt;p&gt;一切都是为了统计代码执行的效率&lt;/p&gt;
&lt;h2 id="事后统计法"&gt;事后统计法&lt;/h2&gt;
&lt;p&gt;通过统计、监控，就能得到算法执行的时间和占用的内存大小&lt;/p&gt;
&lt;h2 id="大-o-复杂度表示法"&gt;大 O 复杂度表示法&lt;/h2&gt;
&lt;p&gt;随着数据规模的增长，算法的执行时间和空间占用，按照多项式的比例增长&lt;/p&gt;
&lt;h3 id="时间复杂度的好坏排序"&gt;时间复杂度的好坏排序&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/35125f99fc7c79d019449ecdf8ef04434feaef35ccc580fd22326dffe1e58ca6.png" alt="图 1"&gt;&lt;/p&gt;
&lt;p&gt;O(1)（常数阶）&amp;lt; O(logn)（对数阶）&amp;lt; O(n)（线性阶）&amp;lt; O(nlogn)（线性对数阶）&amp;lt; O(n^2)（平方阶）&amp;lt; O(n^3)（立方阶）&amp;lt; O(2^n)（指数阶）&amp;lt; O(n!)（阶乘阶）&lt;/p&gt;
&lt;h3 id="常数阶o1"&gt;常数阶O(1)&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 8;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; j &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 6;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; sum &lt;span style="color:#f92672"&gt;=&lt;/span&gt; i &lt;span style="color:#f92672"&gt;+&lt;/span&gt; j;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="线性阶on"&gt;线性阶O(n)&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt;(i&lt;span style="color:#f92672"&gt;=&lt;/span&gt;1; i&lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt;n; &lt;span style="color:#f92672"&gt;++&lt;/span&gt;i)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; j &lt;span style="color:#f92672"&gt;=&lt;/span&gt; i;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; j&lt;span style="color:#f92672"&gt;++&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="对数阶-ologn"&gt;对数阶 O(logn)&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; i&lt;span style="color:#f92672"&gt;=&lt;/span&gt;1;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (i &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; n) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; i &lt;span style="color:#f92672"&gt;*&lt;/span&gt; 2;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="线性对数阶onlogn"&gt;线性对数阶O(nlogN)&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt;(m&lt;span style="color:#f92672"&gt;=&lt;/span&gt;1; m&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;n; m&lt;span style="color:#f92672"&gt;++&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 1;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(i&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;n)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; i &lt;span style="color:#f92672"&gt;*&lt;/span&gt; 2;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="omnomn"&gt;O(m+n)、O(m*n)&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;cal&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; m, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; n) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; sum_1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 0;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 1;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (; i &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; m; &lt;span style="color:#f92672"&gt;++&lt;/span&gt;i) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sum_1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; sum_1 &lt;span style="color:#f92672"&gt;+&lt;/span&gt; i;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; sum_2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 0;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; j &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 1;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (; j &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; n; &lt;span style="color:#f92672"&gt;++&lt;/span&gt;j) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sum_2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; sum_2 &lt;span style="color:#f92672"&gt;+&lt;/span&gt; j;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; sum_1 &lt;span style="color:#f92672"&gt;+&lt;/span&gt; sum_2;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="平方阶on"&gt;平方阶O(n²)&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt;(x&lt;span style="color:#f92672"&gt;=&lt;/span&gt;1; i&lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt;n; x&lt;span style="color:#f92672"&gt;++&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt;(i&lt;span style="color:#f92672"&gt;=&lt;/span&gt;1; i&lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt;n; i&lt;span style="color:#f92672"&gt;++&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; j &lt;span style="color:#f92672"&gt;=&lt;/span&gt; i;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; j&lt;span style="color:#f92672"&gt;++&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="最好最坏复杂度"&gt;最好最坏复杂度&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;最好情况时间复杂度就是，在最理想的情况下，执行这段代码的时间复杂度&lt;/p&gt;</description></item><item><title>基于shipit-deploy实现的多服务器自动化部署方案</title><link>https://time-friend.com/zh/archive/multi-server-automated-deployment-with-shipit-deploy/</link><pubDate>Sun, 17 Dec 2017 20:32:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/multi-server-automated-deployment-with-shipit-deploy/</guid><description>&lt;p&gt;为什么要自动化部署，我这里就不多赘述了。&lt;/p&gt;
&lt;p&gt;基于shipit-deploy的自动化部署，可以实现以下效果&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一键部署多台服务器。&lt;/li&gt;
&lt;li&gt;一键回滚多台服务器。&lt;/li&gt;
&lt;li&gt;本地操作，不需要登录服务器。&lt;/li&gt;
&lt;li&gt;方便定制，方便扩展，实现自动化。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="使用"&gt;使用&lt;/h2&gt;
&lt;h3 id="1下载安装"&gt;1.下载安装&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm install --save-dev shipit-cli
npm install --save-dev shipit-deploy
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="2与服务器建立信任关系"&gt;2.与服务器建立信任关系&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ssh-copy-id USER@REMOTE_HOST
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="3配置"&gt;3.配置&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;shipit&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;shipit-deploy&amp;#39;&lt;/span&gt;)(&lt;span style="color:#a6e22e"&gt;shipit&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;shipit-pm2&amp;#39;&lt;/span&gt;)(&lt;span style="color:#a6e22e"&gt;shipit&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;shipit-cnpmjs&amp;#39;&lt;/span&gt;)(&lt;span style="color:#a6e22e"&gt;shipit&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;shipit&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;initConfig&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;workspace&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;/tmp/github-monitor&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;deployTo&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;/tmp/deploy_to&amp;#39;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;//服务器的目标路径
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;repositoryUrl&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;https://github.com/user/repo.git&amp;#39;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;//git仓库地址
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;ignores&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;&amp;#39;.git&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;node_modules&amp;#39;&lt;/span&gt;], &lt;span style="color:#75715e"&gt;//排除的文件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;keepReleases&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#75715e"&gt;//发布保留的版本数量
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;deleteOnRollback&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;key&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;/path/to/key&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;shallowClone&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;cnpm&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;remote&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;dev&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; { &lt;span style="color:#75715e"&gt;//开发服务器部署
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;servers&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;&amp;#39;user@devServer1&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;user@devServer1&amp;#39;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#a6e22e"&gt;branch&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;dev&amp;#39;&lt;/span&gt; &lt;span style="color:#75715e"&gt;//需要发布的git分支,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;pm2&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;json&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;pm2-dev-app.json&amp;#39;&lt;/span&gt; &lt;span style="color:#75715e"&gt;//开发环境的pm2启动配置
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&lt;span style="color:#960050;background-color:#1e0010"&gt;，&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;prod&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; { &lt;span style="color:#75715e"&gt;//生产服务器部署
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;servers&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;&amp;#39;user@prodServer1&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;user@prodServer2&amp;#39;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	 &lt;span style="color:#a6e22e"&gt;branch&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;master&amp;#39;&lt;/span&gt; &lt;span style="color:#75715e"&gt;//需要发布的git分支,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;pm2&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;json&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;pm2-prod-app.json&amp;#39;&lt;/span&gt; &lt;span style="color:#75715e"&gt;//生产jam环境的pm2启动配置
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;pm2-prod-app.json 示例：&lt;/p&gt;</description></item><item><title>Linux - 使用ssh-copy-id命令实现ssh Linux免密码登陆</title><link>https://time-friend.com/zh/archive/linux-ssh-copy-id-passwordless-login/</link><pubDate>Sat, 16 Dec 2017 20:32:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/linux-ssh-copy-id-passwordless-login/</guid><description>&lt;h3 id="1-生成公钥和私钥"&gt;1. 生成公钥和私钥&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ssh-keygen -t rsa
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;按照提示输入完后，会在~/.ssh目录下生成id_rsa和id_rsa.pub这两个文件&lt;/p&gt;
&lt;h3 id="2与服务器建立联系"&gt;2.与服务器建立联系&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ssh-copy-id root@192.168.0.100 //示例ip
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;接下来会要求输入连接密码，验证成功后&lt;/p&gt;
&lt;h3 id="3无密码登陆服务器"&gt;3.无密码登陆服务器&lt;/h3&gt;
&lt;p&gt;尝试以下命令，看是不是直接登陆成功了：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ssh root@192.168.0.100
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;就是这么简单&lt;/p&gt;</description></item><item><title>开启Express，Egg.js，Koa.js 的Gzip模式</title><link>https://time-friend.com/zh/archive/enable-gzip-express-egg-koa/</link><pubDate>Wed, 13 Dec 2017 20:32:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/enable-gzip-express-egg-koa/</guid><description>&lt;p&gt;为了缩小接口与静态文件的下载体积，在服务器资源可观的情况下我们可以开启Gzip。&lt;/p&gt;
&lt;h3 id="express"&gt;Express&lt;/h3&gt;
&lt;p&gt;Express 4.0以下版本&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;express&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;express&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;express&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;use&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;express&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;compress&lt;/span&gt;()); &lt;span style="color:#75715e"&gt;//主要是这句
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Express 4.0以上版本(包含4.0)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;compression&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;compression&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;express&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;express&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;express&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;use&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;compression&lt;/span&gt;());
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="eggjs"&gt;Egg.js&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// app/middleware/compress.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// koa-compress 暴露的接口(`(options) =&amp;gt; middleware`)和框架对中间件要求一致
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;koa-compress&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// config/config.default.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;middleware&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [ &lt;span style="color:#e6db74"&gt;&amp;#39;compress&amp;#39;&lt;/span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;compress&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;threshold&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2048&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="koajs"&gt;Koa.js&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;koa&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;koa&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;compress&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;koa-compress&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;koa&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;options&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;threshold&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2048&lt;/span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;use&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;compress&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;options&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Apache,Nginx,Express,Egg.js 支持前端HTML5 History 模式</title><link>https://time-friend.com/zh/archive/apache-nginx-express-eggjs-support-frontend-html5-history-mode/</link><pubDate>Sat, 02 Dec 2017 22:30:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/apache-nginx-express-eggjs-support-frontend-html5-history-mode/</guid><description>&lt;p&gt;当你使用 history 模式时，URL 就像正常的 url，例如 &lt;a href="http://xxx.com/user/id"&gt;http://xxx.com/user/id&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;想要完美支持这种模式，还需要后台配置支持。当应用是个单页客户端应用，如果后台没有正确的配置，当用户在浏览器直接访问 &lt;a href="http://xxx.com/user/id"&gt;http://xxx.com/user/id&lt;/a&gt; 就会返回 404。&lt;/p&gt;
&lt;p&gt;后端支持案例：&lt;/p&gt;
&lt;h3 id="apache"&gt;Apache&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-XML" data-lang="XML"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;IfModule&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;mod_rewrite.c&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; RewriteEngine On
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; RewriteBase /
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; RewriteRule ^index\.html$ - [L]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; RewriteCond %{REQUEST_FILENAME} !-f
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; RewriteCond %{REQUEST_FILENAME} !-d
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; RewriteRule . /index.html [L]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;/IfModule&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="nginx"&gt;nginx&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;location / {
 try_files $uri $uri/ /index.html;
}
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="nodejs-express"&gt;Node.js (Express)&lt;/h3&gt;
&lt;p&gt;如果是Express 可以使用connect-history-api-fallback
&lt;a href=""&gt;https://github.com/bripkens/connect-history-api-fallback&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="eggjs"&gt;Egg.js&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// app/middleware/history_fallback.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; () =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;historyFallback&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;ctx&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;next&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;next&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;ctx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;status&lt;/span&gt; &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;404&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#f92672"&gt;!&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;ctx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;body&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;ctx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;acceptJSON&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;ctx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;body&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Not Found&amp;#39;&lt;/span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;ctx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;render&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;index&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// config/config.default.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;middleware&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [ &lt;span style="color:#e6db74"&gt;&amp;#39;historyFallback&amp;#39;&lt;/span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Egg.js 如何支持单页面应用</title><link>https://time-friend.com/zh/archive/eggjs-how-to-support-single-page-application/</link><pubDate>Fri, 01 Dec 2017 22:30:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/eggjs-how-to-support-single-page-application/</guid><description>&lt;ol&gt;
&lt;li&gt;在config/plugin.js 启用ejs //其他的模板引擎也行&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;ejs&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;enable&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;package&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;egg-view-ejs&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="2"&gt;
&lt;li&gt;配置静态目录&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//config/config.{env}.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;config&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;prefix&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;/&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;dir&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;join&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;appInfo&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;baseDir&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;app/view/&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="3"&gt;
&lt;li&gt;模板配置&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//config/config.{env}.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;config&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;view&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;defaultExt&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;.html&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;mapping&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;.ejs&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;ejs&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;.html&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;ejs&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="4"&gt;
&lt;li&gt;配置根目录路由映射&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// app/router.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt; =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;router&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;/&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;controller&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;home&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;index&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="5"&gt;
&lt;li&gt;配置路由相应的控制器&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// app/controller/home.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;Controller&lt;/span&gt; } &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;egg&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;HomeController&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;extends&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Controller&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;index&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;ctx&lt;/span&gt; } &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// render index.html
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ctx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;render&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;index&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;HomeController&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;完成以上配置，便可以与单页面应用作结合了&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>在自己搭建的cnpm发布公司私有代码</title><link>https://time-friend.com/zh/archive/publish-private-code-to-self-hosted-cnpm/</link><pubDate>Sat, 25 Nov 2017 22:30:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/publish-private-code-to-self-hosted-cnpm/</guid><description>&lt;h3 id="配置"&gt;配置&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;需要先将原先的 config/config.js 中添加一些配置属性：&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;enablePrivate&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;, &lt;span style="color:#75715e"&gt;// 任何人都可以发布包
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;admins&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;admin&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;test@company.com&amp;#39;&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 管理员权限
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;scopes&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;&amp;#39;@company&amp;#39;&lt;/span&gt;], &lt;span style="color:#75715e"&gt;// 私有包必须依附于 scope 下
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="重新启动-cnpm"&gt;重新启动 cnpm&lt;/h3&gt;
&lt;p&gt;进入cnpm目录&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm stop // 停止服务
npm start //启动服务
&lt;/code&gt;&lt;/pre&gt;&lt;ol start="3"&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在 package.json 文件中加入代码：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; &amp;#34;name&amp;#34;: &amp;#34;@company/testjs&amp;#34;, // 包名，之前必须加入 scope 名
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="npm登陆"&gt;npm登陆&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; npm login --registry=http://192.168.0.100:7001 // 注册之前的用户
 Username: admin // 管理员名
 Password: 1234 //你想要的密码
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt; npm publish --registry=http://192.168.80.130:7001
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;发布成功&lt;/p&gt;
&lt;h3 id="安装刚刚发布的包"&gt;安装刚刚发布的包&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; npm install @company/test -registry=http://192.168.0.100:7001
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>在公司搭建私有的cnpm服务器</title><link>https://time-friend.com/zh/archive/build-private-cnpm-server-in-company/</link><pubDate>Fri, 24 Nov 2017 22:30:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/build-private-cnpm-server-in-company/</guid><description>&lt;p&gt;现在的js的项目越来越多。如果我们把代码开源。我们会把这些代码发布到npm。
但是npm是公共的，公司的代码毕竟不会公开在网上。
于是我们就有必要搭建一个自己的npm服务器。把公司私有的代码发布在自己公司的npm服务器上。
这样我们就可以即方便的下载我们想要的代码。也可以不把这些代码放在开源平台上面&lt;/p&gt;
&lt;h2 id="安装的基本步骤"&gt;安装的基本步骤&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;在linu安装mysql&lt;/li&gt;
&lt;li&gt;npm install cnpm.org 下载cnpm.org的代码&lt;/li&gt;
&lt;li&gt;配置好cnpm.org的数据库配置&lt;/li&gt;
&lt;li&gt;npm start&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在安装过程中，我们只有这简单的4步。不管哪里遇到各种各样的问题，都不会脱离这4个步骤。&lt;/p&gt;
&lt;h2 id="开始吧"&gt;开始吧&lt;/h2&gt;
&lt;h3 id="在linux安装mysql"&gt;在linux安装mysql&lt;/h3&gt;
&lt;p&gt;网上有很多相关教程，请自行搜索。如果有需要我会重新开一篇来讲述安装步骤。
我们假设这里我们创建了一个用户为：root 密码：root1234&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;创建数据库&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;CREATE DATABASE cnpmjs
&lt;/code&gt;&lt;/pre&gt;&lt;ol start="2"&gt;
&lt;li&gt;建表：&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在cnpm.org代码里，doc/db.sql文件里面有创建cnpm.org的相关表的sql语句&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;mysql&amp;gt; use cnpmjs;
mysql&amp;gt; source docs/db.sql
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="在代码里配置sql信息"&gt;在代码里配置sql信息&lt;/h3&gt;
&lt;p&gt;在cnpm.org代码里的 config/config.js配置我们的数据库连接信息.&lt;/p&gt;
&lt;p&gt;找到以下mysqlServers相关代码,配置大致如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;mysqlServers&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;host&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;port&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;3306&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;user&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;root&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;password&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;root1234&amp;#39;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;// 这是我们刚刚创建的账户跟密码
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="安装cnpmorg-的相关js依赖这是jser们再熟悉不过的了"&gt;安装cnpm.org 的相关js依赖（这是jser们再熟悉不过的了）&lt;/h3&gt;
&lt;p&gt;进入cnpm.org代码目录&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm install
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="最后一步"&gt;最后一步&lt;/h3&gt;
&lt;p&gt;当里的js依赖装好了之后，cnpm.org的数据库配置也配置好了以后。
再命令行里 运行一下命令：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm start
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;好了，我们的cnpm服务器就这样简单的搭建成功了。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;默认web端口为：7002，当你浏览器输入这台机器的ip加端口便可以访问 cnpm.org应用的web页面了。
本机访问则是：http://localhost:7002&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;registry 默认端口为： 7001&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;如果在其他机器始终访问不了你的应用。请检查你的服务器防火墙哦。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="尝试使用"&gt;尝试使用&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; npm install webpack -g --registry=http://192.168.0.100:7001 // IP为你搭建服务器的地址，不要忘加端口号
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;如果你觉得以上方式麻烦可以设置里本机npm 默认registry&lt;/p&gt;</description></item><item><title>Visual-Studio-Code隐藏从ts生成的额外js与map文件</title><link>https://time-friend.com/zh/archive/vscode-hide-generated-js-and-map-files-from-ts/</link><pubDate>Wed, 22 Nov 2017 20:32:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/vscode-hide-generated-js-and-map-files-from-ts/</guid><description>&lt;p&gt;打开【文件】&amp;gt;【首选项】&amp;gt;【工作区设置】，放入以下代码：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;// 将设置放入此文件中以覆盖默认值和用户设置。
{
 &amp;#34;files.exclude&amp;#34;: {
 // exclude .js and .js.map files, when in a TypeScript project
 &amp;#34;node_modules&amp;#34;: true,
 &amp;#34;**/*.js&amp;#34;: { &amp;#34;when&amp;#34;: &amp;#34;$(basename).ts&amp;#34;},
 &amp;#34;**/*.js.map&amp;#34;: true
 }
}
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>让Visual-Studio-Code按照ESLint规则格式化你的代码</title><link>https://time-friend.com/zh/archive/vscode-eslint-format/</link><pubDate>Sun, 05 Nov 2017 19:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/vscode-eslint-format/</guid><description>&lt;p&gt;项目加入ESLint之后,大家的代码是工整了许多.
但是因为刚刚不熟悉ESLint的规则,很多时候都在数进退多少空格,双引号还是单引号的删改切换.&lt;/p&gt;
&lt;p&gt;严重影响了开发效率与心情!!!!
严重影响了开发效率与心情!!!!
严重影响了开发效率与心情!!!!&lt;/p&gt;
&lt;p&gt;重要的事情说三遍!!!&lt;/p&gt;
&lt;p&gt;下面介绍一种利用Visual-Studio-Code ESLint插件,配置之后,可以自动格式化成ESLint规定的格式&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在Visual-Studio-Code 安装 ESLint插件&lt;/li&gt;
&lt;li&gt;widnows 点击 文件&amp;gt;首选项&amp;gt;设置 / mac 点击Code&amp;gt;首选项&lt;/li&gt;
&lt;li&gt;搜索 eslint.autoFixOnSave, 找到之后修改为 true&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;重启你的Visual-Studio-Code,当你打开代码文件的后,直接保存文件.
代码会自动格式化成ESLint规定的格式.大大的提高了开发效率,并且统一了代码规范&lt;/p&gt;
&lt;p&gt;下面分享一下我们项目里的一些ESLint规则&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;rules:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;{&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 具体规则
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;accessor-pairs&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;2,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// getter/setter成对出现
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;arrow-spacing&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;[1,&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;{&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;before&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;true,&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;after&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;true&lt;/span&gt; }&lt;span style="color:#960050;background-color:#1e0010"&gt;],&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 箭头函数前后有空格
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;array-bracket-spacing&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;never&amp;#39;&lt;/span&gt;]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 数组内前后无空格
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;block-spacing&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;always&amp;#39;&lt;/span&gt;]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 单行{}前后有空格
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;brace-style&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;tbs&amp;#39;&lt;/span&gt;, { &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;allowSingleLine&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;true&lt;/span&gt; }]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// {}换行，单行不用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;camelcase&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, { &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;properties&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;never&amp;#39;&lt;/span&gt; }]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 属性名可以不是驼峰
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;comma-dangle&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;only-multiline&amp;#39;&lt;/span&gt;]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 数组/对象最后一个必须有,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;comma-spacing&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, { &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;before&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;false,&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;after&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;true&lt;/span&gt; }]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// ,前有空格, 后无空格
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;comma-style&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;last&amp;#39;&lt;/span&gt;]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// ,在最后，不能换行
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;constructor-super&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// super()在必须构造函数内
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;curly&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;multi-line&amp;#39;&lt;/span&gt;]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// if/while等函数可以多行不带{}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;dot-location&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;property&amp;#39;&lt;/span&gt;]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// .的位置可以在换行
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;eol-last&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 文件末尾需要空白行
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;eqeqeq&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;allow-&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;&lt;/span&gt;]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 必须===, null除外
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;generator-star-spacing&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, { &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;before&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;true,&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;after&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;true&lt;/span&gt; }]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// generator函数前后有空格
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;handle-callback-err&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;^(err|error)$&amp;#39;&lt;/span&gt; ]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 有err/error必须处理异常
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;indent&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, { &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;SwitchCase&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;1&lt;/span&gt; }]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 缩进2格，switch中1格
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;jsx-quotes&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;prefer-single&amp;#39;&lt;/span&gt;]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// jsx属性用单引号
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;key-spacing&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, { &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;beforeColon&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;false,&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;afterColon&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;true&lt;/span&gt; }]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 对象属性前有空格, 后无空格
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;keyword-spacing&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, { &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;before&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;true,&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;after&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;true&lt;/span&gt; }]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 关键词前后有空格, 如if-else
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;new-cap&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, { &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;newIsCap&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;true,&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;capIsNew&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;false&lt;/span&gt; }]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// new后必须大写开头构造函数, 大写开头不一定要new
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;new-parens&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// new的构造函数必须带参数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;object-curly-spacing&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;always&amp;#39;&lt;/span&gt;, { &lt;span style="color:#960050;background-color:#1e0010"&gt;objectsInObjects:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;false&lt;/span&gt; }]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 对象{}前后有空格, 对象内的对象例外
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-array-constructor&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// Array(10)-&amp;gt;yes, Array(1, 2)-&amp;gt;no
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-caller&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止caller/callee
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-class-assign&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止赋值class
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-cond-assign&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 条件不能有赋值
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-const-assign&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止赋值常量(const)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-control-regex&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// reg中不能有控制符号
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-debugger&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;process.env.NODE_ENV&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;===&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;production&amp;#39;&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;?&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// node环境prod禁用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-delete-var&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 不能delete变量，可以用在对象
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-dupe-args&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 参数不能重复
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-dupe-class-members&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// class中方法不能有重复
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-dupe-keys&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 对象key不能重复
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-duplicate-case&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// switch不能有重复case
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-empty-character-class&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// reg中不能有空字符串
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-empty-pattern&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 解构不能有空解构模式
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-eval&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 不能用eval
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-ex-assign&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 不能复制catch中的error
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-extend-native&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 不能扩展Object原型
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-extra-bind&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// bind的函数体中要有明确的this
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-extra-boolean-cast&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止多余的Boolean转换
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-extra-parens&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;functions&amp;#39;&lt;/span&gt;]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 函数中禁止多余的括号
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-fallthrough&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// switch需要break
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-floating-decimal&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// float中0不能省略
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-func-assign&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止赋值函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-implied-eval&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止隐性eval
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-inner-declarations&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;functions&amp;#39;&lt;/span&gt;]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止在条件中声明function
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-invalid-regexp&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止无用的reg
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-irregular-whitespace&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止不规则空格
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-iterator&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止使用__iterator__属性
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-label-var&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止label var
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-labels&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, { &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;allowLoop&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;false,&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;allowSwitch&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;false&lt;/span&gt; }]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止label表达式
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-lone-blocks&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止无用的{}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-mixed-spaces-and-tabs&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// space和tab不混用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-multi-spaces&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止多空格
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-multi-str&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止多行的string
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-multiple-empty-lines&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, { &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;max&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;1&lt;/span&gt; }]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止多空行，最大1行
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-native-reassign&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止赋值原生对象(window/Object...)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-negated-in-lhs&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// !(key in object)-&amp;gt;yes, !key in object-&amp;gt;no
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-new-object&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// new Object()-&amp;gt;no
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-new-require&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// new require(xxx)-&amp;gt;no
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-new-symbol&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// new Symbol(xxx)-&amp;gt;no
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-new-wrappers&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// String/Number等不能用new
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-obj-calls&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止calling全局对象属性，如Math/JSON
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-octal&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止八进制文字
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-octal-escape&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止八进制转义
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-path-concat&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// __dirname和__filename禁止string拼接
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-proto&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止使用__proto__
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-redeclare&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止重新复制var
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-regex-spaces&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止reg出现多个空格
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-return-assign&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;except-parens&amp;#39;&lt;/span&gt;]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止return中赋值
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-self-assign&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止自身赋值
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-self-compare&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止自身比较, 如果NaN-&amp;gt;Number.isNaN
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-sequences&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止,操作符
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-shadow-restricted-names&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止跟踪严格模式下部分关键词
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-spaced-func&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// function的()不要空格
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-sparse-arrays&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// array不能用空元素
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-this-before-super&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// super()前不能用this
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-throw-literal&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止直接throw内容，必须是Error()
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-trailing-spaces&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止多余的空格
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-undef&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止使用未赋值变量
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-undef-init&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 变量不能初始化为undefined
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-unexpected-multiline&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止有疑义的多行表达式
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-unmodified-loop-condition&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 循环中的变量要在循环中修改
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-unneeded-ternary&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, { &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;defaultAssignment&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;false&lt;/span&gt; }]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止不必要的三元操作符
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-unreachable&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// return/throw等之后不应有表达式
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-unsafe-finally&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止不安全的finally
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-unused-vars&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, { &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;vars&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;all&amp;#39;,&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;args&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;none&amp;#39;&lt;/span&gt; }]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止不使用的变量，参数可以
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-useless-call&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止无用的call
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-useless-computed-key&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止无用的计算属性
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-useless-constructor&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁止无用的constructor
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-whitespace-before-property&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 属性前不能有空格
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-with&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁用with
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;one-var&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, { &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;initialized&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;never&amp;#39;&lt;/span&gt; }]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 只能一个var, 初始化不检查
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;operator-linebreak&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;after&amp;#39;&lt;/span&gt;, { &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;overrides&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;{&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;?&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;before&amp;#39;,&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;:&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;before&amp;#39;&lt;/span&gt; } &lt;span style="color:#960050;background-color:#1e0010"&gt;}&lt;/span&gt;]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 操作符换行, 默认在行末, ?和:在下一行前
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;padded-blocks&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;never&amp;#39;&lt;/span&gt;]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 作用域中没有padded的空行
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;quotes&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;single&amp;#39;&lt;/span&gt;, { &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;avoidEscape&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;true,&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;allowTemplateLiterals&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;true&lt;/span&gt; }]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 使用单引号, 转义或者模版可以例外
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;semi&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;never&amp;#39;&lt;/span&gt;]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 禁用结尾;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;semi-spacing&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, { &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;before&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;false,&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;after&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;true&lt;/span&gt; }]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// ;前有空格, 后无空格
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;space-before-blocks&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;always&amp;#39;&lt;/span&gt;]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 作用域前有空格
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;space-in-parens&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;never&amp;#39;&lt;/span&gt;]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 括号内无空格
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;space-infix-ops&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 插入的操作符需要空格, 如+/-
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;space-unary-ops&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, { &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;words&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;true,&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;nonwords&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;false&lt;/span&gt; }]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 操作符单词类要空格(new/delete), 非单词不要空格(++/--/!)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;spaced-comment&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;always&amp;#39;&lt;/span&gt;, { &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;markers&amp;#39;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;[&amp;#39;!&amp;#39;,&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;,&amp;#39;,&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;/&amp;#39;,&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;-&amp;#39;]&lt;/span&gt; }]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 注释要空格，markers为例外
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;template-curly-spacing&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;never&amp;#39;&lt;/span&gt;]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 模版字符串中变量无空格
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;use-isnan&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 使用isNaN
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;valid-typeof&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// typeof的字符串必须正确
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;wrap-iife&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;any&amp;#39;&lt;/span&gt;]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 立即调用的function必须有括号
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;yield-star-spacing&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;both&amp;#39;&lt;/span&gt;]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// yield的*前后有空格
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;yoda&amp;#39;:&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;never&amp;#39;&lt;/span&gt;]&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 条件中变量在前
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;prefer-const&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 能用const场景用const
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;no-useless-escape&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 不检查escape
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#39;space-before-function-paren&amp;#39;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt; &lt;span style="color:#75715e"&gt;// 函数括号无空格
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;react/jsx-uses-react&amp;#34;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;error&amp;#34;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;react/jsx-uses-vars&amp;#34;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;error&amp;#34;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Redux先放一边,开启MobX的新玩法</title><link>https://time-friend.com/zh/archive/redux-to-mobx/</link><pubDate>Sat, 04 Nov 2017 19:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/redux-to-mobx/</guid><description>&lt;h2 id="mobx"&gt;Mobx&lt;/h2&gt;
&lt;p&gt;Mobx是一个简单的,高扩展的状态管理工具.Mobx与Redux一样是为了解决react管理状态的一种工具.
但是在写代码体验上,会好过Redux.&lt;/p&gt;
&lt;h3 id="安装"&gt;安装&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm install mobx --save

//配合React: 
npm install mobx-react --save
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="一个简单的计数器"&gt;一个简单的计数器&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;React&lt;/span&gt;, { &lt;span style="color:#a6e22e"&gt;Component&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;react&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ReactDOM&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;react-dom&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;observer&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;mobx-react&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;observable&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;computed&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;action&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;MobX&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Store&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;@&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;observable&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;count&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;@&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;action&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;count&lt;/span&gt; &lt;span style="color:#f92672"&gt;++&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;minus&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;count&lt;/span&gt; &lt;span style="color:#f92672"&gt;--&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;countStore&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Store&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;@&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;observer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;CountComponent&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;extends&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Component&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;render&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;div&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;h2&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;{ &lt;span style="color:#a6e22e"&gt;countStore&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;count&lt;/span&gt; }&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;/h2&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;button&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;key&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;add&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;onClick&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{&lt;span style="color:#a6e22e"&gt;countStore&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;add&lt;/span&gt;}&lt;span style="color:#f92672"&gt;&amp;gt;+&amp;lt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;/button&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;button&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;key&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;minus&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;onClick&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{&lt;span style="color:#a6e22e"&gt;countStore&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;minus&lt;/span&gt;}&lt;span style="color:#f92672"&gt;&amp;gt;-&amp;lt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;/button&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;/div&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;ReactDOM&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;render&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;CountComponent&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; document.&lt;span style="color:#a6e22e"&gt;getElementById&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;root&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>在你的React项目中使用Decorator 装饰器</title><link>https://time-friend.com/zh/archive/react-decorator/</link><pubDate>Wed, 01 Nov 2017 19:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/react-decorator/</guid><description>&lt;h2 id="使用装饰器"&gt;使用装饰器&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;目前只支持Babel/Typescript两种预编译器&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="babel"&gt;Babel:&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm install babel-plugin-transform-decorators-legacy --save-dev
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在你的 .babelrc配置文件中开启,没有 .babelrc文件的话,可以新建一个.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;{
 &amp;#34;presets&amp;#34;: [
 &amp;#34;es2015&amp;#34;,
 &amp;#34;stage-1&amp;#34;
 ],
 &amp;#34;plugins&amp;#34;: [&amp;#34;transform-decorators-legacy&amp;#34;]
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;插件的顺序千万要注意,非常重要：transform-decorators-legacy 应该放在插件的第一个。&lt;/p&gt;
&lt;p&gt;当使用react native的时候，下面这个预设可以代替 transform-decorators-legacy&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;{
 &amp;#34;presets&amp;#34;: [&amp;#34;stage-2&amp;#34;, &amp;#34;react-native-stage-0/decorator-support&amp;#34;]
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="在create-react-app中使用装饰器"&gt;在create-react-app中使用装饰器&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm run eject
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;安装相关插件:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;//针对react
npm install babel-preset-stage-2 --save-dev
npm install babel-preset-react-native-stage-0 --save-dev
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;根目录下创建.babelrc
{
&amp;ldquo;presets&amp;rdquo;: [&amp;ldquo;react-native-stage-0/decorator-support&amp;rdquo;]
}&lt;/p&gt;
&lt;h2 id="typescript"&gt;TypeScript&lt;/h2&gt;
&lt;p&gt;如果你的项目已经开始使用TypeScript,那我们只需要在tsconfig.json文件中的 experimentalDecorators 设置为 true&lt;/p&gt;
&lt;p&gt;这样,我们就可以使用ES7新特性装饰器了&lt;/p&gt;
&lt;h2 id="在vscode-移除不支持decorator特性的语法警告提示"&gt;在vscode 移除不支持decorator特性的语法警告提示&lt;/h2&gt;
&lt;p&gt;在项目根目录创建tsconfig.json&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;{
 &amp;#34;compilerOptions&amp;#34;: {
 &amp;#34;experimentalDecorators&amp;#34;: true,
 &amp;#34;allowJs&amp;#34;: true
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;重启你的vscode,你会发现语法警告没有了.&lt;/p&gt;</description></item><item><title>将博客搬至CSDN</title><link>https://time-friend.com/zh/archive/move-blog-to-csdn/</link><pubDate>Sun, 24 Sep 2017 00:04:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/move-blog-to-csdn/</guid><description>&lt;p&gt;将博客搬至CSDN&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.csdn.net/m0_48741717"&gt;https://blog.csdn.net/m0_48741717&lt;/a&gt;&lt;/p&gt;</description></item><item><title>我的博客即将同步至腾讯云+社区</title><link>https://time-friend.com/zh/archive/my-blog-will-sync-to-tencent-cloud/</link><pubDate>Sun, 24 Sep 2017 00:04:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/my-blog-will-sync-to-tencent-cloud/</guid><description>&lt;p&gt;我的博客即将同步至腾讯云+社区，邀请大家一同入驻：https://cloud.tencent.com/developer/support-plan?invite_code=onqmnob0dh5k&lt;/p&gt;</description></item><item><title>Git系列之关于add命令的一些事</title><link>https://time-friend.com/zh/archive/git-series-about-add-command/</link><pubDate>Sun, 10 Sep 2017 19:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/git-series-about-add-command/</guid><description>&lt;h2 id="基本用法"&gt;基本用法&lt;/h2&gt;
&lt;p&gt;通常是通过git add &lt;path&gt;的形式把&lt;path&gt;添加到索引库中，&lt;/p&gt;
&lt;p&gt;&lt;path&gt;可以是文件也可以是目录:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;git add &amp;lt;path&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;如果有很多改动,可以用以下命令来一次添加所有改变的文件:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; git add -A .
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;将所有修改添加到暂存区,包括添加新文件和编辑过的文件不包括删除的文件:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ git add . 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;表示添加所有内容:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;git add -A
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;表示添加编辑或者删除的文件，不包括新添加的文件:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;git add -u
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;如果不小心执行了以下命令:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;git add * -f(force) //添加被忽略的文件。
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;可以吃一个后悔药:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;git reset HEAD
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>React系列之父组件如何传递Props给this.props.children</title><link>https://time-friend.com/zh/archive/react-pass-props-to-children/</link><pubDate>Fri, 08 Sep 2017 19:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/react-pass-props-to-children/</guid><description>&lt;h3 id="问题"&gt;问题&lt;/h3&gt;
&lt;p&gt;React使用router之后,以下形式会经常出现.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;props&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;children&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;可是这样渲染出来的组件,父组件如何传递props给它呢?&lt;/p&gt;
&lt;h3 id="解决"&gt;解决&lt;/h3&gt;
&lt;p&gt;我们可以这样传递porps给子组件:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;React&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;cloneElement&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;props&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;children&lt;/span&gt;,{&lt;span style="color:#a6e22e"&gt;A&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;xxx&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;B&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;xxx2&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;C&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;xxx3&lt;/span&gt;}) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>MySQL的安全模式</title><link>https://time-friend.com/zh/archive/mysql-safe-mode/</link><pubDate>Sat, 26 Aug 2017 23:36:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/mysql-safe-mode/</guid><description>&lt;p&gt;今天delete一条数据的时候,出现了以下错误.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column To disable safe mode, toggle the option in Preferences -&amp;gt; SQL Queries and reconnect.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;因为MySql运行在safe-updates模式下.&lt;/p&gt;
&lt;p&gt;想要解除该模式,运行以下命令:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;SET SQL_SAFE_UPDATES = 0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;为了安全，建议执行完操作后，再恢复成默认状态1&lt;/p&gt;</description></item><item><title>MySQL的Access denied for user问题</title><link>https://time-friend.com/zh/archive/mysql-access-denied-for-user/</link><pubDate>Fri, 25 Aug 2017 23:36:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/mysql-access-denied-for-user/</guid><description>&lt;h2 id="问题"&gt;问题&lt;/h2&gt;
&lt;p&gt;在另一台服务器连接MySQL的时候,出现了 Access denied for user &amp;lsquo;root&amp;rsquo;@&amp;lsquo;xxx.xxx.xxx.xxx&amp;rsquo; (using password: YES) 的报错提示.&lt;/p&gt;
&lt;p&gt;这是数据库赋权的问题.&lt;/p&gt;
&lt;h2 id="解决办法"&gt;解决办法&lt;/h2&gt;
&lt;p&gt;在MySQL服务器上使用root登录后，执行如下sql语句：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;mysql -u root -p
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;然后输入你的密码.&lt;/p&gt;
&lt;p&gt;然后执行以下命令:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;GRANT ALL PRIVILEGES ON *.* TO &amp;#39;你的账户&amp;#39;@&amp;#39;%&amp;#39; IDENTIFIED BY &amp;#39;你的密码&amp;#39; WITH GRANT OPTION;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;执行成功后:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;FLUSH PRIVILEGES;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;然后再尝试连接你的数据库,应该就可以了.&lt;/p&gt;</description></item><item><title>利用Chrome DevTools调试Node.js</title><link>https://time-friend.com/zh/archive/debug-nodejs-with-chrome-devtools/</link><pubDate>Tue, 08 Aug 2017 00:04:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/debug-nodejs-with-chrome-devtools/</guid><description>&lt;h2 id="前提"&gt;前提&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Node.js 6.3+；&lt;/li&gt;
&lt;li&gt;Chrome 55+;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="配置chrome-最新的版本已经不需要这一步"&gt;配置Chrome (最新的版本已经不需要这一步);&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;输入url：chrome://flags/#enable-devtools-experiments 进入开发者实验室&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;启用加亮的选项&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;重启Chrome&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;打开 DevTools Setting -&amp;gt; Experiments;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;连续按Shift 6次,显示隐藏的选项&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;找到 Node debugging,并且勾上. (新版本已经没有这个选项,默认就是开启状态.所以chrome就不用配置了)&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src="http://files.jb51.net/file_images/article/201702/2017216143309201.png?2017116143318" alt=""&gt;&lt;/p&gt;
&lt;h2 id="运行nodejs"&gt;运行Node.js&lt;/h2&gt;
&lt;p&gt;只要在命令语句 加上 &amp;ndash;inspect,后面跟上你想要执行的文件;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;node --inspect app.js 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src="https://static.alili.tech/images/debug.png" alt=""&gt;&lt;/p&gt;
&lt;p&gt;复制控制台输出的:&lt;/p&gt;
&lt;p&gt;chrome-devtools:// 协议地址&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;chrome-devtools://devtools/remote/serve_file/xxxxxxxxx&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;粘贴到浏览器地址栏,你就可以使用Chrome的控制台调试你的node应用了.&lt;/p&gt;</description></item><item><title>React系列之用create-react-native-app创建React Native应用</title><link>https://time-friend.com/zh/archive/create-react-native-app/</link><pubDate>Sun, 30 Jul 2017 19:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/create-react-native-app/</guid><description>&lt;p&gt;之前在介绍create-react-app的时候稍微提了一下create-react-native-app.&lt;/p&gt;
&lt;p&gt;这东西其实用起来还是蛮有意思的.这东西最大的好处就是如果你没有安装Xcode,Android Studio这些工具的时候,也是可以在电脑上调试React Native 应用的.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这里说的电脑包括 Mac Windows Linux!!!!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/react-community/create-react-native-app/"&gt;create-react-native-app&lt;/a&gt;&lt;/p&gt;
&lt;h1 id="create-react-native-app-安装"&gt;Create React Native App 安装&lt;/h1&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ npm install -g create-react-native-app
$ create-react-native-app my-app
$ cd my-app/
$ npm start
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;安装 &lt;a href="https://expo.io"&gt;Expo&lt;/a&gt; 这个APP在你的iphone或者安卓手机上. npm start 之后,控制台会出现一个二维码.用这个Expo 扫描这个二维码,就可以马上在你的手机上直接进行远程调试了.那是相当的方便啊.但是速度还是相对桌面模拟器调试慢一点.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://static.alili.tech/images/expo-qrcode.png" alt=""&gt;&lt;/p&gt;
&lt;h1 id="expo的桌面开发工具-expo-xde"&gt;Expo的桌面开发工具 Expo XDE&lt;/h1&gt;
&lt;p&gt;&lt;a href="https://expo.io/tools"&gt;Expo XDE&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;我们不仅可以在控制里运行整个项目,用XDE也可以.并且支持使用模拟器直接在电脑里直接调试程序.速度不错,完全可以接受.&lt;/p&gt;
&lt;p&gt;只不过我Mac的模拟器在安装expo的时候,花了好长的一段时间.如果大家有遇到类似的情况一定要耐心的等一等.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://static.alili.tech/images/xde.png" alt=""&gt;&lt;/p&gt;</description></item><item><title>聊聊HTTP的MIME</title><link>https://time-friend.com/zh/archive/talking-about-http-mime/</link><pubDate>Wed, 26 Jul 2017 16:14:25 +0000</pubDate><guid>https://time-friend.com/zh/archive/talking-about-http-mime/</guid><description>&lt;h2 id="mime是什么"&gt;MIME是什么?&lt;/h2&gt;
&lt;p&gt;MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型;&lt;/p&gt;
&lt;p&gt;在最早的HTTP协议中,没有附加的数据类型信息.&lt;/p&gt;
&lt;p&gt;所有传送的数据都被客户程序解释为超文本标记语言HTML 文档，而为了支持多媒体数据类型，HTTP协议中就使用了附加在文档之前的MIME数据类型信息来标识数据类型。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;每个MIME类型由两部分组成，前面是数据的大类别，例如声音audio、图象image等，后面定义具体的种类。&lt;/p&gt;
&lt;h2 id="常见的mime类型通用型"&gt;常见的MIME类型(通用型)：&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;超文本标记语言文本 .html text/html&lt;/li&gt;
&lt;li&gt;xml文档 .xml text/xml&lt;/li&gt;
&lt;li&gt;XHTML文档 .xhtml application/xhtml+xml&lt;/li&gt;
&lt;li&gt;普通文本 .txt text/plain&lt;/li&gt;
&lt;li&gt;RTF文本 .rtf application/rtf&lt;/li&gt;
&lt;li&gt;PDF文档 .pdf application/pdf&lt;/li&gt;
&lt;li&gt;Microsoft Word文件 .word application/msword&lt;/li&gt;
&lt;li&gt;PNG图像 .png image/png&lt;/li&gt;
&lt;li&gt;GIF图形 .gif image/gif&lt;/li&gt;
&lt;li&gt;JPEG图形 .jpeg,.jpg image/jpeg&lt;/li&gt;
&lt;li&gt;au声音文件 .au audio/basic&lt;/li&gt;
&lt;li&gt;MIDI音乐文件 mid,.midi audio/midi,audio/x-midi&lt;/li&gt;
&lt;li&gt;RealAudio音乐文件 .ra, .ram audio/x-pn-realaudio&lt;/li&gt;
&lt;li&gt;MPEG文件 .mpg,.mpeg video/mpeg&lt;/li&gt;
&lt;li&gt;AVI文件 .avi video/x-msvideo&lt;/li&gt;
&lt;li&gt;GZIP文件 .gz application/x-gzip&lt;/li&gt;
&lt;li&gt;TAR文件 .tar application/x-tar&lt;/li&gt;
&lt;li&gt;任意的二进制数据 application/octet-stream&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="用于wap服务器的mime类型有"&gt;用于WAP服务器的MIME类型有：&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;MRP文件（国内普遍的手机）.mrp application/octet-stream&lt;/li&gt;
&lt;li&gt;IPA文件(IPHONE) .ipa application/iphone-package-archive&lt;/li&gt;
&lt;li&gt;Debian软件包格式 .deb application/x-debian-package-archive&lt;/li&gt;
&lt;li&gt;APK文件(安卓系统) .apk application/vnd.android.package-archive&lt;/li&gt;
&lt;li&gt;CAB文件(Windows Mobile) .cab application/vnd.cab-com-archive&lt;/li&gt;
&lt;li&gt;XAP文件(Windows Phone 7) .xap application/x-silverlight-app&lt;/li&gt;
&lt;li&gt;SIS文件(symbian平台/S60V1) .sis application/vnd.symbian.install-archive *&lt;/li&gt;
&lt;li&gt;SISX文件(symbian平台/S60V3/V5) .sisx application/vnd.symbian.epoc/x-sisx-app&lt;/li&gt;
&lt;li&gt;JAR、JAD文件(JAVA平台手机通用格式) .jar .jad&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;服务器在发送真正的数据之前，就要先发送标志数据的MIME类型的信息，这个信息使用Content-type关键字进行定义.&lt;/p&gt;</description></item><item><title>HTTP的URI格式说明</title><link>https://time-friend.com/zh/archive/http-uri-format/</link><pubDate>Tue, 25 Jul 2017 16:14:25 +0000</pubDate><guid>https://time-friend.com/zh/archive/http-uri-format/</guid><description>&lt;p&gt;下面是URI的各个组成部分&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; 权限 路径
 ┌───────────────┴───────────────┐┌───┴────┐
 abc://username:password@example.com:123/path/data?key=value&amp;amp;key2=value2#fragid1
 └┬┘ └───────┬───────┘ └────┬────┘ └┬┘ └─────────┬─────────┘ └──┬──┘
 协议 用户信息 主机名 端口 查询参数 片段
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>让Webpack支持sftp上传文件</title><link>https://time-friend.com/zh/archive/make-webpack-support-sftp-upload/</link><pubDate>Tue, 18 Jul 2017 11:43:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/make-webpack-support-sftp-upload/</guid><description>&lt;p&gt;今天介绍两个插件,可以让你的webpack支持上传文件到你的ftp服务器.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/iAmHades/sftp-webpack-plugin"&gt;sftp-webpack-plugin&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="安装sftp-webpack-plugin"&gt;安装sftp-webpack-plugin&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm install sftp-webpack-plugin --save-dev
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="使用"&gt;使用&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;SftpWebpackPlugin&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;sftp-webpack-plugin&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;config&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;plugins&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;SftpWebpackPlugin&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;port&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;your port&amp;#39;&lt;/span&gt;,&lt;span style="color:#75715e"&gt;//服务器端口
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;host&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;your host&amp;#39;&lt;/span&gt;,&lt;span style="color:#75715e"&gt;//服务器地址
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;username&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;your username&amp;#39;&lt;/span&gt;,&lt;span style="color:#75715e"&gt;//用户名
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;password&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;your password&amp;#39;&lt;/span&gt;,&lt;span style="color:#75715e"&gt;//密码
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;you neeed upload file path &amp;#39;&lt;/span&gt;,&lt;span style="color:#75715e"&gt;//你的本地路径
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;to&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;you want to destination&amp;#39;&lt;/span&gt;&lt;span style="color:#75715e"&gt;//服务器上的路径
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="webpack-sftp-client"&gt;webpack-sftp-client&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://github.com/sqhtiamo/webpack-sftp-client"&gt;webpack-sftp-client&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="安装webpack-sftp-client"&gt;安装webpack-sftp-client&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm install webpack-sftp-client --save-dev
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="使用-1"&gt;使用&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;WebpackSftpClient&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;webpack-sftp-client&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;config&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;plugins&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;WebpackSftpClient&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;port&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;22&amp;#39;&lt;/span&gt;,&lt;span style="color:#75715e"&gt;//服务器端口
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;host&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;exmaple.com&amp;#39;&lt;/span&gt;,&lt;span style="color:#75715e"&gt;//服务器地址
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;username&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;root&amp;#39;&lt;/span&gt;,&lt;span style="color:#75715e"&gt;//用户名
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;password&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;password&amp;#39;&lt;/span&gt;,&lt;span style="color:#75715e"&gt;//登录密码
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./build/&amp;#39;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;//本地路径
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;remotePath&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;/data/website/demo/&amp;#39;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;//服务器路径
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;verbose&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt; &lt;span style="color:#75715e"&gt;//控制台显示详细信息
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;})]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>React系列之分享一个自适应高的iframe组件</title><link>https://time-friend.com/zh/archive/react-adaptive-iframe/</link><pubDate>Mon, 17 Jul 2017 19:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/react-adaptive-iframe/</guid><description>&lt;p&gt;在网页里面先要嵌入iframe,总是得要解决iframe高度的问题.&lt;/p&gt;
&lt;p&gt;那我们在React下,该怎么做到呢?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;FullheightIframe&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;extends&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Component&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;constructor&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;super&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;state&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;iFrameHeight&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;0px&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;render&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;iframe&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;style&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{ {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;width&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;100%&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;height&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;state&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;iFrameHeight&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;overflow&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;visible&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;onLoad&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{() =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ReactDOM&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;findDOMNode&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;setState&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;iFrameHeight&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;contentWindow&lt;/span&gt;.document.&lt;span style="color:#a6e22e"&gt;body&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;scrollHeight&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;px&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;ref&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;iframe&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;props&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;width&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;100%&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;height&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;state&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;iFrameHeight&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;scrolling&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;no&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;frameBorder&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; );
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Macbook Pro蓝牙不可用问题</title><link>https://time-friend.com/zh/archive/macbook-pro-bluetooth-unavailable-issue/</link><pubDate>Sun, 16 Jul 2017 22:30:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/macbook-pro-bluetooth-unavailable-issue/</guid><description>&lt;p&gt;前两天早上去公司,电脑一开机.发现鼠标不能用了.&lt;/p&gt;
&lt;p&gt;乱鼓捣了一翻,原来电脑蓝牙变成了一个波浪线.显示蓝牙不可用.&lt;/p&gt;
&lt;p&gt;鼓捣了好久,电脑系统也升级到最新版本了.重启好几次,蓝牙还是不可用状态.&lt;/p&gt;
&lt;p&gt;百度了一下,网上也有类似的问题的解决办法.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;1.关机


2.同时按下shift+control+option+power,保持5秒


3.先按下power键，紧接着同时按下option+command+p+r,
等待mac发出4声Duang~的声音后松手，系统就会自动开机


4.蓝牙恢复正常
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;但是有网友试过之后,是成功的呀.&lt;/p&gt;
&lt;p&gt;我照着这方法,试了好几次,蓝牙还是不可用.但是在电脑的恢复模式,鼠标是可用的.说明蓝牙并没有坏.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;最后我把电脑所有连接usb的设备全部拔掉.重新再试了一次.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;奇迹发生了,蓝牙恢复正常了.如果有朋友遇到了类似情况,最好跟我一样把所有USB设备拔掉.然后照着上面方法试着弄一次.应该是可以解决问题的.&lt;/p&gt;</description></item><item><title>发布基于nodejs的阿里云API签名生成工具 -- AliToSing</title><link>https://time-friend.com/zh/archive/publish-alitosign-aliyun-api-signature-tool/</link><pubDate>Sun, 16 Jul 2017 00:04:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/publish-alitosign-aliyun-api-signature-tool/</guid><description>&lt;p&gt;基于 nodejs 的阿里云 API 签名生成工具&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/Num142857/AliToSign"&gt;Github AliToSign&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://help.aliyun.com/document_detail/29747.html?spm=5176.doc29743.2.4.SAqOxJ"&gt;阿里云签名官方说明&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;安装方法:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm install alitosign --save
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;使用方法:&lt;/p&gt;
&lt;p&gt;例子:&lt;a href="https://help.aliyun.com/document_detail/29749.html?spm=5176.doc29744.6.592.RG61hE"&gt;添加域名&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;alitosign&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;alitosign&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;querystring&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;querystring&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;moment&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;moment&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;http&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;http&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//基本上调用接口都需要的公共参数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;originParams&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;AccessKeyId&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;xxxxxxx&amp;#34;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;//AccessKeyId 获得方法请参照官方文档
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Format&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;JSON&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Version&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;2015-01-09&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;SignatureMethod&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;HMAC-SHA1&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;SignatureVersion&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;1.0&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;AddDomain&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//复制一份公共参数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;params&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Object.&lt;span style="color:#a6e22e"&gt;assign&lt;/span&gt;({}, &lt;span style="color:#a6e22e"&gt;originParams&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//在新的对象上添加你想调用的该接口必要参数,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//每个接口都不一样,具体请查阅官方文档
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Action&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;AddDomain&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;DomainName&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;time-friend.com&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;GroupId&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;2223&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//添加时间戳
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Timestamp&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;moment&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;utc&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;format&lt;/span&gt;(); &lt;span style="color:#75715e"&gt;//要用格林威治时间;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;SignatureNonce&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Date().&lt;span style="color:#a6e22e"&gt;getTime&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//生成签名
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;signParams&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;alitosign&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//将包含签名属性的对象转换成query格式的字符串
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;queryParams&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;querystring&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;stringify&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;signParams&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//拼接url
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;url&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`http://alidns.aliyuncs.com/?`&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;queryParams&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//调用接口
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;url&lt;/span&gt;, (&lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;on&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;data&amp;#34;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//序列化之后,就可以拿到你想要的数据了
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;oData&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;JSON&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;parse&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>React系列之让create-react-app支持导入less</title><link>https://time-friend.com/zh/archive/create-react-app-less/</link><pubDate>Fri, 14 Jul 2017 19:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/create-react-app-less/</guid><description>&lt;p&gt;目前来说,create-react-app并不支持直接导入LESS;
这里我就介绍一下,如何让它支持LESS的导入.&lt;/p&gt;
&lt;p&gt;create-react-app是基于webpack的,只是没有暴露webpack.config相关的文件.想要支持less,肯定是要修改webpack的配置文件的.
以下命令可以做到暴露出配置文件来:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm run eject
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;运行完毕之后,你会看见多出了一个config文件夹.
里面有webpack.config.dev.js和webpack.config.prod.js等配置文件.&lt;/p&gt;
&lt;p&gt;接下来,安装less-loader&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm install less-loader less --save-dev
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;然后修改webpack.config.dev.js文件,&lt;/p&gt;
&lt;p&gt;我们只需要修改两个地方&lt;/p&gt;
&lt;h2 id="第一-找到下面代码"&gt;第一: 找到下面代码&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;exclude&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;/\.html$/&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;/\.(js|jsx)$/&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;/\.css$/&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;/\.json$/&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;/\.bmp$/&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;/\.gif$/&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;/\.jpe?g$/&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;/\.png$/&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;将.css改为.(css|less)，内容变为：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;exclude&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;/\.html$/&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;/\.(js|jsx)$/&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;/\.(css|less)$/&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;/\.json$/&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;/\.bmp$/&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;/\.gif$/&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;/\.jpe?g$/&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;/\.png$/&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="第二个找到test-css"&gt;第二个：找到test: /.css$/&lt;/h2&gt;
&lt;p&gt;更改为test: /.(css|less)$/&lt;/p&gt;
&lt;p&gt;并在下面的use数组里面增加less-loader&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;loader&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;resolve&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;less-loader&amp;#39;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// compiles Less to CSS
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;更改完以后这部分代码大概长这个样子：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;test&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;/\.(css|less)$/&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;use&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;resolve&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;style-loader&amp;#39;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;loader&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;resolve&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;css-loader&amp;#39;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;options&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;importLoaders&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;loader&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;resolve&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;less-loader&amp;#39;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// compiles Less to CSS
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;生产环境的配置跟上面也差不多.&lt;/p&gt;</description></item><item><title>React系列之JSX</title><link>https://time-friend.com/zh/archive/react-series-jsx/</link><pubDate>Thu, 13 Jul 2017 19:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/react-series-jsx/</guid><description>&lt;p&gt;JSX是一个有趣的东西。它看似像一个模板语言，但是又具备javascript的所有能力。&lt;/p&gt;
&lt;p&gt;在React中，JSX用来生成React元素。&lt;/p&gt;
&lt;p&gt;我们使用create-react-app创建一个APP后：&lt;/p&gt;
&lt;h2 id="一段jsx代码"&gt;一段JSX代码&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;React&lt;/span&gt;, { &lt;span style="color:#a6e22e"&gt;Component&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;react&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ReactDOM&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;react-dom&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;App&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;extends&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Component&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;render&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;className&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;App&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;我是一个APP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;/div&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; );
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;ReactDOM&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;render&lt;/span&gt;(&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;App&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt;, document.&lt;span style="color:#a6e22e"&gt;getElementById&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;root&amp;#39;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="我们可以在jsx中内嵌表达式"&gt;我们可以在JSX中内嵌表达式&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//插入数据 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;data&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;小明&amp;#34;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ele&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;div&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;我的名字是&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;{&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;} &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;/div&amp;gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//计算
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ele1&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;div&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; {&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;} &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;/div&amp;gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//三元表达式
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ele2&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;div&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; {&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;&lt;span style="color:#f92672"&gt;?&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;我是小明&amp;#34;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;：&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;我不是小明&amp;#34;&lt;/span&gt;} &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;/div&amp;gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//在属性里
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ele3&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;img&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{&lt;span style="color:#a6e22e"&gt;date&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;xxx&lt;/span&gt;} &lt;span style="color:#f92672"&gt;/&amp;gt;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;p&gt;因为JSX使用Babel编译后,本身自己就是一个对象.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ele&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;className&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;user&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Hello&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;World&lt;/span&gt;&lt;span style="color:#f92672"&gt;!&amp;lt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;/div&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;编译后:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;element&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;React&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;createElement&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;div&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {&lt;span style="color:#a6e22e"&gt;className&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;user&amp;#39;&lt;/span&gt;},
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Hello World!&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;所以,这就是JSX可以与js代码混写的原因.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;switchView&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;className&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;user&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Hello&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;World&lt;/span&gt;&lt;span style="color:#f92672"&gt;!&amp;lt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;/div&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;className&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;user&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Hello&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Ming&lt;/span&gt;&lt;span style="color:#f92672"&gt;!&amp;lt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;/div&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;编译后:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;switchView&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;React&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;createElement&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;div&amp;#39;&lt;/span&gt;,{&lt;span style="color:#a6e22e"&gt;className&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;user&amp;#39;&lt;/span&gt;},&lt;span style="color:#e6db74"&gt;&amp;#39;Hello world!&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;React&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;createElement&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;div&amp;#39;&lt;/span&gt;,{&lt;span style="color:#a6e22e"&gt;className&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;user&amp;#39;&lt;/span&gt;},&lt;span style="color:#e6db74"&gt;&amp;#39;Hello Ming!&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="防止xxs攻击"&gt;防止XXS攻击&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;lt;span&amp;gt;我是HTML代码?&amp;lt;/span&amp;gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ele&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;div&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;{&lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;}&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;/div&amp;gt; &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//会直接输入&amp;lt;span&amp;gt;我是HTML代码?&amp;lt;/span&amp;gt;,不会把这一段变成HTML
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="元素的class"&gt;元素的class&lt;/h2&gt;
&lt;p&gt;因为在ES6里,class是关键字(不再是保留字).所以写的时候要注意,修改为className.&lt;/p&gt;</description></item><item><title>React系列之从一个脚手架开始说起:create-react-app</title><link>https://time-friend.com/zh/archive/react-create-app/</link><pubDate>Wed, 12 Jul 2017 19:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/react-create-app/</guid><description>&lt;p&gt;React的全家桶实在太过于庞大。如果初学者想直接品味React的魅力，这里介绍一个官方的脚手架。使用方法特别简单。&lt;/p&gt;
&lt;h2 id="create-react-app"&gt;create-react-app&lt;/h2&gt;
&lt;h3 id="大概使用方法"&gt;大概使用方法&lt;/h3&gt;
&lt;p&gt;安装&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm install -g create-react-app
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;创建一个app&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;create-react-app my-app
cd my-app/
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;文件结构：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;my-app
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│ └── favicon.ico
│ └── index.html
│ └── manifest.json
└── src
 └── App.css
 └── App.js
 └── App.test.js
 └── index.css
 └── index.js
 └── logo.svg
 └── registerServiceWorker.js
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;启动应用：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm start
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;用浏览器打开 http://localhost:3000/ 就可以直接看到你的应用了。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://camo.githubusercontent.com/506a5a0a33aebed2bf0d24d3999af7f582b31808/687474703a2f2f692e696d6775722e636f6d2f616d794e66434e2e706e67" alt=""&gt;&lt;/p&gt;
&lt;p&gt;如果你想打包你的应用：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm run build
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="特点"&gt;特点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;不需要配置；&lt;/li&gt;
&lt;li&gt;对 React, JSX, ES6 和 Flow 可以直接编译；&lt;/li&gt;
&lt;li&gt;开发服务器；&lt;/li&gt;
&lt;li&gt;浏览器热加载的功能；&lt;/li&gt;
&lt;li&gt;JavaScript 文件中可以直接 import CSS 和图片；&lt;/li&gt;
&lt;li&gt;自动处理 CSS 的兼容问题，无需添加 -webkit 前缀；&lt;/li&gt;
&lt;li&gt;集成好了编译命令，编译后直接发布成产品，包含 sourcemaps。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;哎哟，路边又捡了一个叫 create-react-native-app 的脚手架:&lt;/p&gt;</description></item><item><title>npm、yarn包管理工具切换淘宝源</title><link>https://time-friend.com/zh/archive/npm-yarn-switch-taobao-registry/</link><pubDate>Sat, 01 Jul 2017 20:32:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/npm-yarn-switch-taobao-registry/</guid><description>&lt;p&gt;因为一些特殊原因，npm、Yarn等包管理软件在国内下载总是有一点慢。
可以切换为淘宝源，直接从国内的服务器直接拉取。
这里做一个笔记：&lt;/p&gt;
&lt;h2 id="npm"&gt;NPM&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm config set registry https://registry.npm.taobao.org --global
npm config set disturl https://npm.taobao.org/dist --global
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;如果不能开心的使用以上配置,可以尝试以下方法:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm config set registry http://registry.cnpmjs.org
npm info underscore 
//（如果上面配置正确这个命令会有字符串response）
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="yarn"&gt;yarn&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;yarn config set registry https://registry.npm.taobao.org --global
yarn config set disturl https://npm.taobao.org/dist --global
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;如果出现EACCES: permission denied这样的权限报错，
修复/usr/local目录的所有权：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo chown -R `whoami` /usr/local
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>跨域还可以这样玩,使用CSS3特性做跨域</title><link>https://time-friend.com/zh/archive/css-cross-domain/</link><pubDate>Tue, 20 Jun 2017 16:14:25 +0000</pubDate><guid>https://time-friend.com/zh/archive/css-cross-domain/</guid><description>&lt;h2 id="csst-css-text-transformation"&gt;CSST (CSS Text Transformation)&lt;/h2&gt;
&lt;p&gt;通过CSS3的content获取内容。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;利用js动态创建一个link插入到文档中, 请求css文件.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;利用 &lt;code&gt;computedStyle = window.getComputedStyle&lt;/code&gt; 获取指定元素的style 对象&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;利用 &lt;code&gt;computedStyle .content&lt;/code&gt; 获取内容&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;服务端可以返回的 css 文件内容：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; @&lt;span style="color:#66d9ef"&gt;keyframes&lt;/span&gt; &lt;span style="color:#f92672"&gt;anima&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;from&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;to&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;opacity&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; @&lt;span style="color:#66d9ef"&gt;-webkit-keyframes&lt;/span&gt; &lt;span style="color:#f92672"&gt;anima&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;from&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;to&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;opacity&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; #CSST {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;content&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;${text}&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;animation&lt;/span&gt;: anima &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;s&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;-webkit-&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;animation&lt;/span&gt;: anima &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;s&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;${text}就是我们要填充的数据&lt;/p&gt;
&lt;p&gt;监听函数 animationstart/webkitAnimationStart 来判断css是否加载完成&lt;/p&gt;
&lt;p&gt;给#CSST元素设置动画&lt;/p&gt;
&lt;p&gt;js逻辑：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;handle&lt;/span&gt; () {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;computedStyle&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getComputedStyle&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;span&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;computedStyle&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;content: %s&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;match&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;match&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;/[\w+=\/]+/&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// base64解码
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;match&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; decodeURIComponent(&lt;span style="color:#a6e22e"&gt;escape&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;atob&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;match&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;])));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;ex&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fn&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;ex&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;CSST&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; document.&lt;span style="color:#a6e22e"&gt;getElementById&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;CSST&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//监听事件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;CSST&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;addEventListener&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;animationstart&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;handler&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;CSST&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;addEventListener&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;webkitAnimationStart&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;handler&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;元素动画启动,就可以获取到 content 里的内容了&lt;/p&gt;</description></item><item><title>Object.defineProperty与Proxy的共同之处</title><link>https://time-friend.com/zh/archive/object-defineproperty-and-proxy-common-ground/</link><pubDate>Thu, 01 Jun 2017 11:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/object-defineproperty-and-proxy-common-ground/</guid><description>&lt;p&gt;在看vue文档的时候发现一个有意思的地方.
就是关于Object.defineProperty的利用与Proxy有相似之处.非常有意思.&lt;/p&gt;
&lt;p&gt;文档是这样说的:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;把一个普通 JavaScript 对象传给 Vue 实例的 data 选项，Vue 将遍历此对象所有的属性，并使用 Object.defineProperty 把这些属性全部转为 getter/setter。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="objectdefineproperty"&gt;Object.defineProperty&lt;/h2&gt;
&lt;p&gt;语法：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Object.&lt;span style="color:#a6e22e"&gt;defineProperty&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;prop&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;descriptor&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;obj：必需。目标对象&lt;/li&gt;
&lt;li&gt;prop：必需。需定义或修改的属性的名字&lt;/li&gt;
&lt;li&gt;descriptor：必需。目标属性所拥有的特性&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;返回值:&lt;/p&gt;
&lt;p&gt;传入函数的对象。即第一个参数obj&lt;/p&gt;
&lt;h2 id="gettersetter-存取器描述"&gt;getter/setter 存取器描述&lt;/h2&gt;
&lt;p&gt;当使用存取器描述属性的特性的时候，允许设置以下特性属性：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Object.&lt;span style="color:#a6e22e"&gt;defineProperty&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;newKey&amp;#34;&lt;/span&gt;,{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; (){} &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;undefined&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;set&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;value&lt;/span&gt;){} &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;undefined&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;当设置或获取对象的某个属性的值的时候，可以提供getter/setter方法。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;initValue&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;hello&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Object.&lt;span style="color:#a6e22e"&gt;defineProperty&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;newKey&amp;#34;&lt;/span&gt;,{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; (){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//当获取值的时候触发的函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;initValue&lt;/span&gt;; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;set&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;value&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//当设置值的时候触发的函数,设置的新值通过参数value拿到
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;initValue&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;value&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//获取值
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;( &lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;newKey&lt;/span&gt; ); &lt;span style="color:#75715e"&gt;//hello
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//设置值
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;newKey&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;change value&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;( &lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;newKey&lt;/span&gt; ); &lt;span style="color:#75715e"&gt;//change value
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;是不是很神奇?&lt;/p&gt;
&lt;p&gt;但是看到这里,突然想到之前文章里提到过的ES6里新增的Proxy.&lt;/p&gt;
&lt;p&gt;举个例子:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;proxyObj&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Proxy(&lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;,{ &lt;span style="color:#75715e"&gt;//proxyObj会继承obj
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;set&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;alert&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;我被修改了&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;alert&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;我被获取了&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//修改属性
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;proxyObj&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;; &lt;span style="color:#75715e"&gt;//属性被修改后,之前设置的handler会被触发
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// 2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;今天就到这里,祝儿童节快乐.&lt;/p&gt;</description></item><item><title>聊聊Vue的事件修饰符</title><link>https://time-friend.com/zh/archive/vue-event-modifiers/</link><pubDate>Thu, 25 May 2017 19:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/vue-event-modifiers/</guid><description>&lt;h2 id="事件修饰符"&gt;事件修饰符&lt;/h2&gt;
&lt;p&gt;说到vue的事件修饰符,相对angularJs来说,实在是太爽了,大大增加了可读性.&lt;/p&gt;
&lt;p&gt;在日常开发中,经常要调用event.preventDefault 或者event.stopPropagation等方法.&lt;/p&gt;
&lt;p&gt;没有事件修饰符的话,我们会这样写:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//AngularJS
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;$scope&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;fn&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;message&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;event&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;event&lt;/span&gt;) &lt;span style="color:#a6e22e"&gt;event&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;preventDefault&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;alert&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;message&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//vue 也可以这样
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;methods&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fn&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;message&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;event&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 现在我们可以访问原生事件对象
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;event&lt;/span&gt;) &lt;span style="color:#a6e22e"&gt;event&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;preventDefault&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;alert&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;message&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在vue中提供了更加方便的写法:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;!-- 阻止单击事件冒泡 --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;a&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;v-on:click&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;.&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;stop&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;doThis&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;a&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;!-- 提交事件不再重载页面 --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;form&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;v-on:submit&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;.&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;prevent&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;onSubmit&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;form&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;!-- 修饰符可以串联 --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;a&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;v-on:click&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;.&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;stop&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;.&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;prevent&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;doThat&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;a&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;!-- 只有修饰符 --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;form&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;v-on:submit&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;.&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;prevent&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;form&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;!-- 添加事件侦听器时使用事件捕获模式 --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;v-on:click&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;.&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;capture&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;doThis&amp;#34;&lt;/span&gt;&amp;gt;...&amp;lt;/&lt;span style="color:#f92672"&gt;div&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;!-- 只当事件在该元素本身（而不是子元素）触发时触发回调 --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;div&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;v-on:click&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;.&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;self&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;doThat&amp;#34;&lt;/span&gt;&amp;gt;...&amp;lt;/&lt;span style="color:#f92672"&gt;div&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;!-- 点击事件将只会触发一次 --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;a&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;v-on:click&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;.&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;once&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;doThis&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;a&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="修饰键"&gt;修饰键&lt;/h2&gt;
&lt;p&gt;在键盘的事件里,Vue也提供了很方便的处理.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;!-- 只有在 keyCode 是 13 时调用 vm.submit() --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;input&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;v-on:keyup&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;.&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;13&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;submit&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;还有更爽的按键别名:&lt;/p&gt;</description></item><item><title>一个关于微信SPA页面webview的缓存问题</title><link>https://time-friend.com/zh/archive/wechat-spa-webview-cache-issue/</link><pubDate>Wed, 22 Feb 2017 16:14:25 +0000</pubDate><guid>https://time-friend.com/zh/archive/wechat-spa-webview-cache-issue/</guid><description>&lt;h2 id="一个低级问题"&gt;一个低级问题&lt;/h2&gt;
&lt;p&gt;因为公司微信项目用的是angular路由的单页面应用.所以切换页面是基于hash值做到的.&lt;/p&gt;
&lt;p&gt;我们遇到了一个问题,每一次部署新的网页代码到服务器上.
在Android微信客户端,总是要过好多天.甚至要重新卸载微信.重新打开页面之后,才会更新页面.(iPhone上却没有这个问题)&lt;/p&gt;
&lt;p&gt;如果版本正式上线之后,遇到了紧急bug.那将是一场灾难啊.&lt;/p&gt;
&lt;h2 id="解决办法"&gt;解决办法&lt;/h2&gt;
&lt;h3 id="给url加上时间戳"&gt;给url加上时间戳&lt;/h3&gt;
&lt;p&gt;首先想到的解决办法是,在网址后面加上时间戳,就像是这样:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;xxx.com#/home/test/page/?t=(我是时间戳)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;可是页面在安卓客户端却没有任何改善&lt;/p&gt;
&lt;p&gt;这是为什么,是微信客户端的bug吗?&lt;/p&gt;
&lt;p&gt;并不是,是时间戳加错了位置.&lt;/p&gt;
&lt;p&gt;我们换一种方式.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;xxx.com?t=(我是时间戳)#/home/test/page/
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这个时候,我们发现安卓微信客户端的缓存问题迎刃而解了.&lt;/p&gt;
&lt;h2 id="牵引出一个问题"&gt;牵引出一个问题&lt;/h2&gt;
&lt;p&gt;为什么我们的时间戳放在最后面,浏览器取了缓存的代码.&lt;/p&gt;
&lt;p&gt;首先我们看看URL的格式:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;protocol :// hostname[:port] / path / [;parameters][?query]#hash
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;我们的时间戳用的是 &amp;ldquo;?&amp;rdquo; 分隔符,也就是query参数.&lt;/p&gt;
&lt;p&gt;第一次,我们把query参数放在了&amp;quot;#&amp;ldquo;后面.于是我们的时间戳,也就是所谓的query参数,成了hash值.&lt;/p&gt;
&lt;p&gt;不管是什么符号,什么字符,只要是放在了&amp;rdquo;#&amp;ldquo;后面的,都是hash值.&lt;/p&gt;
&lt;p&gt;因为HTTP请求并不包括hash,所以不管我们怎么修改#号后面的时间戳,服务器接收到的请求,都是一样的.&lt;/p&gt;
&lt;p&gt;重要的事情说三遍:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HTTP请求不包括hash&lt;/li&gt;
&lt;li&gt;HTTP请求不包括hash&lt;/li&gt;
&lt;li&gt;HTTP请求不包括hash&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Hexo的DTraceProviderBindings MODULE_NOT_FOUND问题</title><link>https://time-friend.com/zh/archive/hexo-dtrace-provider-bindings-module-not-found/</link><pubDate>Sun, 19 Feb 2017 21:32:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/hexo-dtrace-provider-bindings-module-not-found/</guid><description>&lt;p&gt;最近在mac上安装Hexo,老是报错 DTraceProviderBindings MODULE_NOT_FOUND;&lt;/p&gt;
&lt;h2 id="第一种报错"&gt;第一种报错&lt;/h2&gt;
&lt;p&gt;报错命令如下:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;{ [Error: Cannot find module &amp;#39;./build/Release/DTraceProviderBindings&amp;#39;] code: &amp;#39;MODULE_NOT_FOUND&amp;#39; }
{ [Error: Cannot find module &amp;#39;./build/default/DTraceProviderBindings&amp;#39;] code: &amp;#39;MODULE_NOT_FOUND&amp;#39; }
{ [Error: Cannot find module &amp;#39;./build/Debug/DTraceProviderBindings&amp;#39;] code: &amp;#39;MODULE_NOT_FOUND&amp;#39; }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;虽然hexo的生成 发布功能没有影响.但是每次运行命令的时候,就会报错.表示很不能忍;&lt;/p&gt;
&lt;p&gt;网上的普遍方法是:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm install hexo --no-optional
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;但是,我的电脑还是没有效果;&lt;/p&gt;
&lt;p&gt;最后我重装了 hexo-cli&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm uninstall hexo-cli -g
npm install hexo-cli -g
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;我的报错问题就解决了.&lt;/p&gt;
&lt;h2 id="第二种报错"&gt;第二种报错&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;{ Error: Cannot find module &amp;#39;./build/Release/DTraceProviderBindings&amp;#39;
at Function.Module._resolveFilename (module.js:469:15)
at Function.Module._load (module.js:417:25)
at Module.require (module.js:497:17)
at require (internal/module.js:20:19)
at Object.&amp;lt;anonymous&amp;gt; (/usr/local/lib/node_modules/.dtrace-provider_npminstall/dtrace-provider/0.8.0/dtrace-provider/
dtrace-provider.js:17:23)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.require (module.js:497:17)
at require (internal/module.js:20:19)
at Object.&amp;lt;anonymous&amp;gt; (/usr/local/lib/node_modules/hexo-cli/node_modules/bunyan/lib/bunyan.js:79:18)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32) code: &amp;#39;MODULE_NOT_FOUND&amp;#39; }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;问题是因为安装的过程中,各种奇奇怪怪的问题导致hexo-cli的依赖库 dtrace-provider 没有安装成功.&lt;/p&gt;</description></item><item><title>Express设置CORS,让浏览器可以跨域访问你的服务器</title><link>https://time-friend.com/zh/archive/express-set-cors-cross-origin/</link><pubDate>Sat, 18 Feb 2017 21:32:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/express-set-cors-cross-origin/</guid><description>&lt;p&gt;说到前端跨域,确实让很多前端宝宝们捏了一把汗.&lt;/p&gt;
&lt;p&gt;跨域的解决方法可谓是八仙过海.各种黑科技,各种黑魔法.让人看的目瞪口呆.(不了解的,可以去搜)&lt;/p&gt;
&lt;p&gt;但是都没有相当完美的解决方案,都是可以这样却不能那样.&lt;/p&gt;
&lt;p&gt;今天要说的就是目前跨域的终极解决方案(IE8以及更低版本的IE浏览器不支持)&lt;/p&gt;
&lt;h2 id="cross-origin-resource-sharing-简称-cors"&gt;Cross-Origin Resource Sharing (简称 CORS);&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;express&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;express&amp;#39;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;express&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//设置CORS
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;all&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;*&amp;#39;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;req&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;next&lt;/span&gt;) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;header&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Access-Control-Allow-Origin&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;*&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//第二个参数,是一个*号,表示任意域名下的页面都可以都可以请求请求这台服务器;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//设置指定域名:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//res.header(&amp;#34;Access-Control-Allow-Origin&amp;#34;, &amp;#34;http://baidu.com&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//这样,baidu.com下面的网页,就可以ajax请求你的服务器了
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;header&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Access-Control-Allow-Headers&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;X-Requested-With&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;header&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Access-Control-Allow-Methods&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;PUT,POST,GET,DELETE,OPTIONS&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//第二个参数,为对方可以以哪种HTTP请求方式请求你的服务器,根据自己的情况酌情设置
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;header&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;X-Powered-By&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39; 3.2.1&amp;#39;&lt;/span&gt;) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;header&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Content-Type&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;application/json;charset=utf-8&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;next&lt;/span&gt;(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;/&amp;#39;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;req&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;) { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;send&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;你已经成功访问该服务器&amp;#34;&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;listen&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;3000&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>让Node.js像浏览器一样Fetch你想要的</title><link>https://time-friend.com/zh/archive/make-nodejs-fetch-like-browser/</link><pubDate>Fri, 17 Feb 2017 20:32:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/make-nodejs-fetch-like-browser/</guid><description>&lt;p&gt;上一篇简单的介绍了Node.js http模块的get与post方式,
但是因为post的配置还是比较繁琐,今天推荐一个模块:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.npmjs.com/package/node-fetch"&gt;node-fetch&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="安装"&gt;安装&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm install node-fetch --save
&lt;/code&gt;&lt;/pre&gt;&lt;!-- more --&gt;
&lt;h2 id="使用"&gt;使用&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fetch&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;node-fetch&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// HTML 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;fetch&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;https://github.com/&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;then&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;text&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }).&lt;span style="color:#a6e22e"&gt;then&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;body&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;body&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// JSON 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;fetch&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;https://api.github.com/users/github&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;then&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;json&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }).&lt;span style="color:#a6e22e"&gt;then&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;json&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;json&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 当网络发生错误
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;fetch&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;http://domain.invalid/&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// stream 流
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fs&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;fs&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;fetch&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;https://assets-cdn.github.com/images/modules/logos_page/Octocat.png&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;then&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dest&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fs&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;createWriteStream&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./octocat.png&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;body&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;pipe&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;dest&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// buffer 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fileType&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;file-type&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;fetch&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;https://assets-cdn.github.com/images/modules/logos_page/Octocat.png&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;then&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;buffer&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }).&lt;span style="color:#a6e22e"&gt;then&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;buffer&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fileType&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;buffer&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// meta 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;fetch&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;https://github.com/&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;then&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;ok&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;status&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;statusText&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;headers&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;raw&lt;/span&gt;());
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;headers&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;content-type&amp;#39;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// POST请求 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;fetch&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;http://httpbin.org/post&amp;#39;&lt;/span&gt;, { &lt;span style="color:#a6e22e"&gt;method&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;POST&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;body&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;a=1&amp;#39;&lt;/span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;then&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;json&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }).&lt;span style="color:#a6e22e"&gt;then&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;json&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;json&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// post with stream from resumer 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;resumer&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;resumer&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;stream&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;resumer&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;queue&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;a=1&amp;#39;&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;end&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;fetch&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;http://httpbin.org/post&amp;#39;&lt;/span&gt;, { &lt;span style="color:#a6e22e"&gt;method&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;POST&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;body&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;stream&lt;/span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;then&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;json&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }).&lt;span style="color:#a6e22e"&gt;then&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;json&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;json&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// post 表单数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;FormData&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;form-data&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;form&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;FormData&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;form&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;append&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;a&amp;#39;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;fetch&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;http://httpbin.org/post&amp;#39;&lt;/span&gt;, { &lt;span style="color:#a6e22e"&gt;method&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;POST&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;body&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;form&lt;/span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;then&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;json&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }).&lt;span style="color:#a6e22e"&gt;then&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;json&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;json&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// post 表单数据并且修改header 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;FormData&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;form-data&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;form&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;FormData&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;form&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;append&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;a&amp;#39;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;fetch&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;http://httpbin.org/post&amp;#39;&lt;/span&gt;, { &lt;span style="color:#a6e22e"&gt;method&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;POST&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;body&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;form&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;headers&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;form&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getHeaders&lt;/span&gt;() })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;then&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;json&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }).&lt;span style="color:#a6e22e"&gt;then&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;json&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;json&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// node 0.12+, yield with co 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;co&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;co&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;co&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;yield&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fetch&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;https://api.github.com/users/github&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;json&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;yield&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;json&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="api"&gt;API&lt;/h2&gt;
&lt;h3 id="fetchurl-options"&gt;fetch(url, options)&lt;/h3&gt;
&lt;p&gt;返回一个 Promise 对象&lt;/p&gt;</description></item><item><title>Node.js之http模块的get与post请求</title><link>https://time-friend.com/zh/archive/nodejs-http-module-get-and-post-requests/</link><pubDate>Thu, 16 Feb 2017 20:32:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/nodejs-http-module-get-and-post-requests/</guid><description>&lt;p&gt;在前端,经常要使用ajax获取,提交数据到服务端.
服务端当然也可以像另一个服务端发起同样的请求.&lt;/p&gt;
&lt;p&gt;今天,说一下Node.js如何向另一个服务端发起请求.&lt;/p&gt;
&lt;h2 id="get请求"&gt;GET请求&lt;/h2&gt;
&lt;p&gt;写法还是相当简单,跟angular的$http.get有一点点的像.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;http&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;http&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;http://baidu.com&amp;#34;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;response&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;response&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;!-- more --&gt;
&lt;h2 id="post请求"&gt;POST请求&lt;/h2&gt;
&lt;p&gt;相对get,post的写法繁琐了很多.&lt;/p&gt;
&lt;p&gt;虽然过程很清晰,但是对于写惯了各种前端框架封装的ajax后,还是难以接受的.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;http&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;http&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;querystring&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;querystring&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//json转换为字符串
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;data&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;querystring&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;stringify&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;1&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;text&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;hello&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;options&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;host&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;xxx.xxx.xxx&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;/xxx/xxx/xxx/&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;method&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;POST&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;headers&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Content-Type&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;application/x-www-form-urlencoded&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Content-Length&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Buffer&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;byteLength&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;req&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;request&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;options&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;setEncoding&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;utf8&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;on&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;data&amp;#39;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;chunk&lt;/span&gt;) { &lt;span style="color:#75715e"&gt;//拼接数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;body: &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;chunk&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;on&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;end&amp;#39;&lt;/span&gt;,&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;chunk&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;body: &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;chunk&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;req&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;write&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;req&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;end&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>利用Node.js获取公网IP</title><link>https://time-friend.com/zh/archive/get-public-ip-with-nodejs/</link><pubDate>Wed, 15 Feb 2017 21:30:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/get-public-ip-with-nodejs/</guid><description>&lt;p&gt;因为树莓派放在家里,因为运营商的关系,公网ip是一直会变的.
那我们要怎么样才能快捷的拿到当前网络的公网ip呢?&lt;/p&gt;
&lt;p&gt;今天介绍一个小工具,可以简单的获取到公网ip.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.npmjs.com/package/public-ip"&gt;public-ip&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="安装"&gt;安装&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm install --save public-ip
&lt;/code&gt;&lt;/pre&gt;&lt;!-- more --&gt;
&lt;h3 id="使用"&gt;使用&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;const publicIp = require(&amp;#39;public-ip&amp;#39;);
 
publicIp.v4().then(ip =&amp;gt; { 
 console.log(ip);
 //=&amp;gt; &amp;#39;46.5.21.123&amp;#39; 
});
 
publicIp.v6().then(ip =&amp;gt; {
 console.log(ip);
 //=&amp;gt; &amp;#39;fe80::200:f8ff:fe21:67cf&amp;#39; 
});
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="设置https"&gt;设置HTTPS&lt;/h4&gt;
&lt;p&gt;如果使用https,会基于&lt;a href="https://github.com/major/icanhaz"&gt; icanhazip.com &lt;/a&gt; 服务来查询的.&lt;/p&gt;
&lt;p&gt;相对来说会安全一些,但是也会稍微的慢一些.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;
publicIp.v4({
 https:true //默认false
}).then(ip =&amp;gt; { 
 console.log(ip);
 //=&amp;gt; &amp;#39;46.5.21.123&amp;#39; 
});
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="设置超时时间"&gt;设置超时时间&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;
publicIp.v4({
 timeout:5000 //默认5000毫秒
}).then(ip =&amp;gt; { 
 console.log(ip);
 //=&amp;gt; &amp;#39;46.5.21.123&amp;#39; 
});
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>基于Github与Coding等代码托管平台的自动化部署</title><link>https://time-friend.com/zh/archive/automated-deployment-based-on-github-and-coding-code-hosting-platforms/</link><pubDate>Tue, 14 Feb 2017 22:30:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/automated-deployment-based-on-github-and-coding-code-hosting-platforms/</guid><description>&lt;p&gt;自从玩起了树莓派,每天都要经常把代码更新到树莓派上.&lt;/p&gt;
&lt;p&gt;但是次数太频繁了,重复的事情就要做一遍又一遍.非常的浪费时间.&lt;/p&gt;
&lt;p&gt;发现Github跟Codeing都有webhook功能,&lt;/p&gt;
&lt;p&gt;于是我便有了一个想法:&lt;/p&gt;
&lt;p&gt;想每次git push 更新代码的时候,
利用托管平台的webhook通知我的树莓派,
接收到通知后,自动更新托管平台的最新代码,并且自动重启.&lt;/p&gt;
&lt;p&gt;这样不就节约很多时间了吗?&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;在npmjs.com上搜索有没有相关功能的模块,果然有:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.npmjs.com/package/github-webhook-handler"&gt;github-webhook-handler&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.npmjs.com/package/coding-webhook-handler"&gt;coding-webhook-handler&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;接下来我们以coding为例,来写一个自动部署的小程序.&lt;/p&gt;
&lt;p&gt;先准备一段树莓派接受到通知后,运行的一段sh代码&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#! /bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd /home/pi/workspace/xxx //打开项目所在的目录
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git reset --hard origin/master
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git clean -f
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git pull origin master //拉取并且合并代码
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cnpm install //安装模块
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;pm2 reload app //pm2 重新启动程序
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;下面是js代码&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;http&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;http&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;spawn&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;child_process&amp;#39;&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;spawn&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;createHandler&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;coding-webhook-handler&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;handler&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;createHandler&lt;/span&gt;({ &lt;span style="color:#75715e"&gt;//配置好coding的参数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;/&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;token&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;dsdsdsdsds&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;createServer&lt;/span&gt;((&lt;span style="color:#a6e22e"&gt;req&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;) =&amp;gt; { &lt;span style="color:#75715e"&gt;//开启一个服务,接收托管平台发送过来的通知
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;handler&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;req&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;, (&lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;statusCode&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;404&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;end&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;no such location&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Hi!&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}).&lt;span style="color:#a6e22e"&gt;listen&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;7878&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;runCommand&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;cmd&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;args&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;callback&lt;/span&gt;) =&amp;gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;child&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;spawn&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;cmd&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;args&lt;/span&gt;); &lt;span style="color:#75715e"&gt;//运行sh代码
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;response&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;; &lt;span style="color:#75715e"&gt;//接收托管平台发送过来的内容
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;child&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;stdout&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;on&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;data&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;buffer&lt;/span&gt; =&amp;gt; &lt;span style="color:#a6e22e"&gt;response&lt;/span&gt; &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;buffer&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;toString&lt;/span&gt;());
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;child&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;stdout&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;on&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;end&amp;#34;&lt;/span&gt;, () =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;callback&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;response&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;handler&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;on&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;error&amp;#34;&lt;/span&gt;, (&lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;Error:&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;message&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//输出错误信息
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;handler&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;on&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;*&amp;#39;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;event&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;event&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;event&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;event&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;payload&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;event&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;protocol&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;event&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;host&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;event&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;url&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;handler&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;on&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;push&amp;#34;&lt;/span&gt;, (&lt;span style="color:#a6e22e"&gt;event&lt;/span&gt;) =&amp;gt; { &lt;span style="color:#75715e"&gt;//push事件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;event:&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;event&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;event&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;runCommand&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;sh&amp;#39;&lt;/span&gt;, [&lt;span style="color:#e6db74"&gt;&amp;#39;./auto_build.sh&amp;#39;&lt;/span&gt;], &lt;span style="color:#a6e22e"&gt;txt&lt;/span&gt; =&amp;gt; { &lt;span style="color:#75715e"&gt;//运行sh代码
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;txt&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//输出托管平台发来的信息
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>利用Node.js生成阿里云API签名</title><link>https://time-friend.com/zh/archive/generate-aliyun-api-signature-with-nodejs/</link><pubDate>Mon, 13 Feb 2017 21:32:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/generate-aliyun-api-signature-with-nodejs/</guid><description>&lt;p&gt;想要调用阿里云的云解析API,必须要生成阿里云所要求的签名.
&lt;a href="https://help.aliyun.com/document_detail/29747.html?spm=5176.doc29743.2.4.SAqOxJ"&gt;签名机制&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;网上一直没有找到nodejs相关获取签名的代码.
按照阿里云的要求,我自己写了一段程序,便于大家轻松的生成签名.&lt;/p&gt;
&lt;!-- more --&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;querystring&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;querystring&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;crypto&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;crypto&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getSignatureParams&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;StringToSign&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;GET&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;amp;&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;percentEncode&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/&amp;#34;&lt;/span&gt;) &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;amp;&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;percentEncode&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;uriSort&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Signture&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getSignture&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;StringToSign&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Signature&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Signture&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;; &lt;span style="color:#75715e"&gt;//返回带签名的完整uri
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;percentEncode&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;str&lt;/span&gt;) { &lt;span style="color:#75715e"&gt;//百分比编码 uri
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;s&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; encodeURI(&lt;span style="color:#a6e22e"&gt;str&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;s&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;replace&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;/ /g&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;%20&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;replace&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;/\//g&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;%2F&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;replace&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;/\+/g&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;%20&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;replace&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;/\*/g&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;%2A&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;replace&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;/\%7E/g&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;~&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;replace&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;/\=/g&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;%3D&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;replace&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;/\&amp;amp;/g&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;%26&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;replace&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;/\:/g&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;%253A&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getSignture&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;Signature&lt;/span&gt;) { &lt;span style="color:#75715e"&gt;//计算HMAC
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 47awTgVxfVEBL8hewkBgYD6kEvuJn0 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;crypto&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;createHmac&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;sha1&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;testsecret&amp;amp;&amp;#34;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//你的secret
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;update&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;Signature&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;digest&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;toString&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;base64&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;uriSort&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;uri&lt;/span&gt;) { &lt;span style="color:#75715e"&gt;//uri参数排序
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;arr&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;querystring&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;stringify&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;uri&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;split&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;amp;&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;arr&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;arr&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;sort&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;str&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [].&lt;span style="color:#a6e22e"&gt;forEach&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;call&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;arr&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;s&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;arr&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;str&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;str&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;s&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;str&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;str&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;s&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;amp;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;str&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>关闭Mac系统的SIP与卸载Mac上的输入法</title><link>https://time-friend.com/zh/archive/disable-mac-sip-and-uninstall-input-methods/</link><pubDate>Sat, 21 Jan 2017 22:30:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/disable-mac-sip-and-uninstall-input-methods/</guid><description>&lt;p&gt;mac电脑上,有的多余的输入法,发现竟然删不掉.每次切换输入法的时候总是要多按几次切换.表示极其的不爽.&lt;/p&gt;
&lt;p&gt;首先就是系统默认的输入法.&lt;/p&gt;
&lt;h2 id="关闭-mac-系统的-sip"&gt;关闭 mac 系统的 SIP&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;重启系统，按住 Command + R 进入恢复模式。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;点击顶部菜单栏 实用工具 中的 终端 。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;输入以下命令来禁用 SIP 保护机制。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;csrutil disable
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;执行后输出以下信息表示禁用成功。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Successfully disabled System Integrity Protection. Please restart the machine &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; the changes to take effect.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;最后重启系统即可。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="重新打开-sip-方法"&gt;重新打开 SIP 方法&lt;/h2&gt;
&lt;p&gt;在恢复模式下的终端输入以下命令&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;csrutil enable
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="卸载系统输入法"&gt;卸载系统输入法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;安装Xcode或下载“Property List Editor”，因为需要打开(.plist)格式文件&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;打开“终端”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在“终端”里输入命令&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo open ~/Library/Preferences/com.apple.HIToolbox.plist
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;回车，输入用户账户的密码&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.cr173.com/up/2017-1/201701161151525689893.png" alt=""&gt;&lt;/p&gt;
&lt;p&gt;我们选中“Root”—“AppleEnabledInputSources”， 一个一个点开,查找你想要删除的输入法，然后删除。&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.cr173.com/up/2017-1/201701161152373133375.png" alt=""&gt;&lt;/p&gt;
&lt;p&gt;最后重启Mac&lt;/p&gt;
&lt;h2 id="qq输入法等第三方输入法"&gt;QQ输入法等第三方输入法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;首先打开活动监视器，把QQ输入法进程关闭。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Finder界面按下 shift+command+G, 输入：/library/input methods（系统的资料库）, 进入文件夹，找到qq输入法，删掉。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Finder界面按下 shift+command+G, 输入：~/library/input methods （个人文件夹的资料库）， 进入文件夹，找到qq输入法，删掉。&lt;/p&gt;</description></item><item><title>Raspberry之时间自动校准</title><link>https://time-friend.com/zh/archive/raspberry-auto-time-calibration/</link><pubDate>Fri, 20 Jan 2017 22:30:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/raspberry-auto-time-calibration/</guid><description>&lt;p&gt;应该是树莓派系统版本的问题,网上很多方法开启网络时间协议(时间自动校准)已经失效.对于我这样的小白来说,试了很多种方法,都没有成功.&lt;/p&gt;
&lt;p&gt;今天来说说正确的开启姿势;&lt;/p&gt;
&lt;p&gt;树莓派没有默认开启时间自动校准功能的.需要打开NTP（Network Time Protocol，网络时间协议）才可以尽可能的保证时间的准确度.&lt;/p&gt;
&lt;h3 id="启用ntp"&gt;启用NTP：&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo timedatectl set-ntp true
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;接下来我们来看看时间是否正确:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;pi@raspberrypi:~ $ date
2017年 03月 20日 星期一 21:38:41 CST
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;很明显时间都正确了.如果时间差了24小时以内,那大概是时区错了.&lt;/p&gt;</description></item><item><title>POST请求要比GET安全吗</title><link>https://time-friend.com/zh/archive/post-vs-get-security/</link><pubDate>Mon, 16 Jan 2017 11:46:35 +0000</pubDate><guid>https://time-friend.com/zh/archive/post-vs-get-security/</guid><description>&lt;p&gt;从学习发送请求的第一天,老师就告诉我们.
POST请求,要比GET请求要安全.&lt;/p&gt;
&lt;h2 id="为什么"&gt;为什么?&lt;/h2&gt;
&lt;p&gt;在利用from发送请求的时代.get请求会夹带信息在地址栏里,而post不会.post会把信息放在body里面.&lt;/p&gt;
&lt;p&gt;因为参数放在地址栏里的get请求,会让别人看得见.一些信息难免会暴露.&lt;/p&gt;
&lt;p&gt;所以得出,post要比get更加安全.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;后来公司新来了一名后台小哥,他说post要比get更安全,于是没有经过任何人同意,把所有的新增接口都设计成了post.当我联调的时候,看着这一连串的post请求,一脸懵逼.开发这么久,我从来不觉得这会有安全问题的存在.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;公司前端都是AngularJs的SPA应用. 所以每次发送请求的方式都是Ajax.并不存在get请求的参数会暴露在地址栏的情况.&lt;/p&gt;
&lt;p&gt;如果所有的接口,全部变成了post,那我们的代码会变成什么样子呢?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//查找数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;$http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;post&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;xxx.xxx.xxx&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//增加数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;$http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;post&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;xxx.xxx.xxx&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//修改数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;$http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;post&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;xxx.xxx.xxx&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//删除数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;$http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;post&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;xxx.xxx.xxx&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;所有的请求都是post,根本没有任何语义,一塌糊涂,非常不利于查看.&lt;/p&gt;
&lt;p&gt;大家都知道,请求方式都好几种.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GET&lt;/li&gt;
&lt;li&gt;POST&lt;/li&gt;
&lt;li&gt;HEAD&lt;/li&gt;
&lt;li&gt;PUT&lt;/li&gt;
&lt;li&gt;DELETE&lt;/li&gt;
&lt;li&gt;OPTIONS&lt;/li&gt;
&lt;li&gt;TRACE&lt;/li&gt;
&lt;li&gt;CONNECT&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对于增删改查都有相应的方式,那我们的代码:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//查找数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;$http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;xxx.xxx.xxx&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//增加数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;$http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;post&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;xxx.xxx.xxx&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//修改数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;$http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;put&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;xxx.xxx.xxx&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//删除数据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;$http&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;delete&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;xxx.xxx.xxx&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="小结"&gt;小结:&lt;/h2&gt;
&lt;p&gt;在SPA应用里,POST并没有跟GET上有所谓安全性的差异.我们应该使用更加适合的请求方式,来发送以及请求数据.&lt;/p&gt;</description></item><item><title>Raspberry之开机启动pm2</title><link>https://time-friend.com/zh/archive/raspberry-startup-pm2/</link><pubDate>Thu, 12 Jan 2017 20:32:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/raspberry-startup-pm2/</guid><description>&lt;p&gt;我玩树莓派的过程简直可以用坎坷来形容,研究了十几个小时才安装上Node.js.&lt;/p&gt;
&lt;p&gt;接下来想要做开机启动pm2,又折腾了十几个小时.网上的方法因为跟不上版本的迭代更新了,导致各种失败.&lt;/p&gt;
&lt;p&gt;接下来,介绍一下让pm2在树莓派上开机启动的方法&lt;/p&gt;
&lt;p&gt;首先下载pm2&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cnpm install pm2 -g
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;运行需要run的代码&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;pm2 start app.js
&lt;/code&gt;&lt;/pre&gt;&lt;!-- more --&gt;
&lt;p&gt;保存这时候pm2运行的状态,以便开机启动后,pm2 可以重新跑app.js&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo pm2 save //系统会生成一个文件 &amp;#39;/home/pi/.pm2/dump.pm2&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;(重点)接下来我们要锁定这个文件,不允许任何方式的修改&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo chattr +i /home/pi/.pm2/dump.pm2
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;设置开机启动&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo pm2 startup systemd -u pi --hp /home/pi

sudo reboot //重启查看开机启动的效果
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;通过以上步骤,我们就可以成功的开机启动pm2 并且运行app.js&lt;/p&gt;
&lt;p&gt;如果我们以后想修改pm2 开机启动的配置,我们需要解锁dump.pm2文件,&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;pm2 start xxx.js //运行另一个程序
sudo chattr -i /home/pi/.pm2/dump.pm2 //解锁文件

sudo pm2 save //保存配置
sudo chattr +i /home/pi/.pm2/dump.pm2 //重新加锁
sudo pm2 startup systemd -u pi --hp /home/pi //设置开机启动

sudo reboot 重启操作系统
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;以上就是修改pm2开机启动配置的方法了,是不是简单得不能再简单?&lt;/p&gt;
&lt;p&gt;(这么简单的步骤,居然浪费了一天的时间,才找到方法,不过我很喜欢这样的感觉)&lt;/p&gt;</description></item><item><title>Raspberry之安装Node.js</title><link>https://time-friend.com/zh/archive/raspberry-install-nodejs/</link><pubDate>Wed, 11 Jan 2017 22:30:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/raspberry-install-nodejs/</guid><description>&lt;p&gt;我安装的树莓派系统是自带Node.js的,但是版本非常的低.而且没有npm.
为了安装新版的nodejs,我折腾了十几个小时,网上的方法各种失败.&lt;/p&gt;
&lt;p&gt;最终终于安装成功了,接下来我介绍一下我的安装方法.&lt;/p&gt;
&lt;h3 id="下载nodejs"&gt;下载Node.js&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://nodejs.org/en/download/"&gt;Node.js 下载页面&lt;/a&gt;&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;我们选择Linux Binaries (ARM) ARMv7的版本,复制下载链接&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;wget https://nodejs.org/dist/v6.9.5/node-v6.9.5-linux-armv7l.tar.xz
tar -xzf node-v6.9.5-linux-armv7l.tar.xz //解压安装包
sudo mv node-v6.9.5-linux-armv7l /usr/local/bin/node/
sudo ln /usr/local/bin/node/bin/node /usr/local/bin/node
sudo ln -s /usr/local/bin/node/lib/node_modules/npm/bin/npm /usr/local/bin/npm
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;好了,这时候我们在任意目录下输入:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;node -v
npm -v 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;node 是最新版本的了,npm 也有了&lt;/p&gt;
&lt;p&gt;因为在国内,用npm下载包的话,会经常不稳定,这时候我们可以用到 cnpm,
输入以下命令:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ npm install -g cnpm --registry=https://registry.npm.taobao.org
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;下载完成之后,我们安装模块的时候:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ cnpm install [name]
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Raspberry之外网访问树莓派</title><link>https://time-friend.com/zh/archive/raspberry-external-network-access/</link><pubDate>Tue, 10 Jan 2017 20:53:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/raspberry-external-network-access/</guid><description>&lt;p&gt;我想在公司的时候,也可以操作我家里的树莓派.
可是家里的ip地址是动态的,那我应该怎么办呢?&lt;/p&gt;
&lt;p&gt;经过各种网上一顿搜索之后,利用路由器的端口转发或者DMZ,可以做到外网访问内网.&lt;/p&gt;
&lt;p&gt;可是我设置完之后,并没有成功.折腾了好久,没有找到原因.最后以失败告终.(我怀疑我买到了假路由器).&lt;/p&gt;
&lt;p&gt;各种方案尝试过之后,利用花生壳可以做到外网访问内网,花生壳的叫法是:&lt;/p&gt;
&lt;p&gt;内网穿透&lt;/p&gt;
&lt;p&gt;进入花生壳的下载地址,选择树莓派版本&lt;/p&gt;
&lt;p&gt;&lt;a href="http://hsk.oray.com/download/"&gt;下载页面&lt;/a&gt;&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;复制最新版本的花生壳树莓派版本的最新版下载路径&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;wget http://download.oray.com/peanuthull/embed/phddns_raspberry.tgz //下载花生壳
tar zxvf phddns_raspberry.tgz //解压安装包
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src="http://file.oray.com/service/1507/20150721135050987.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;解压完成后，在当前路径下执行cd phddns2，进入phddns2文件夹，执行./oraynewph start
，如提示Oraynewph start success说明花生壳成功安装运行。&lt;/p&gt;
&lt;p&gt;其实我运行oraynewph start的时候并没有成功,&lt;/p&gt;
&lt;p&gt;如果你也碰到同样的情况的话可以输入以下命令:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$&amp;gt; sudo mkdir -p /usr/oray-app
$&amp;gt; sudo tar -zxvf ./oraynewph.tgz -C /usr/oray-app/
$&amp;gt; sudo rm -rf oraynewph.tgz
$&amp;gt; sudo mv ./parse /usr/oray-app/parse
$&amp;gt; sudo mv ./oray_serve /etc/init.d/oray_serve
$&amp;gt; sudo mv ./oraynewph /bin/oraynewph
$&amp;gt; cd ..
$&amp;gt; rm -rf phddns2
$&amp;gt; sudo touch /tmp/oraynewph_log
$&amp;gt; sudo update-rc.d oray_serve defaults
$&amp;gt; sudo /usr/oray-app/bin/oraynewph -s 0.0.0.0 &amp;amp;&amp;gt;/dev/null &amp;amp;
$&amp;gt; sudo /usr/oray-app/bin/oraysl -a 127.0.0.1 -p 16062 -s phsle01.oray.net:80 -d
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src="http://file.oray.com/service/1507/20150721135050957.jpg" alt=""&gt;&lt;/p&gt;</description></item><item><title>Raspberry之利用SSH操作树莓派</title><link>https://time-friend.com/zh/archive/raspberry-operate-via-ssh/</link><pubDate>Tue, 10 Jan 2017 17:53:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/raspberry-operate-via-ssh/</guid><description>&lt;p&gt;各种搜索,各种折腾之后,终于给我的小树莓派安装好了操作系统.
但是,这PIXEL OS图形操作界面,各种莫名其妙点不动的bug.
折腾了好几个小时之后,让我各种抓狂.&lt;/p&gt;
&lt;p&gt;因为是刚刚接触Linux,很多问题需要在网上搜索,PC跟树莓派之间切换来切换去实在是不好受.&lt;/p&gt;
&lt;p&gt;下面就介绍,用另一台电脑通过SSH来控制树莓派的方法.来解决以上各种抓狂的问题.&lt;/p&gt;
&lt;p&gt;在树莓派打开命令行:&lt;/p&gt;
&lt;p&gt;输入 sudo raspi-config&lt;/p&gt;
&lt;p&gt;&lt;img src="http://img.blog.csdn.net/20161012150453948" alt=""&gt;&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;选择Advanced Options&lt;/p&gt;
&lt;p&gt;&lt;img src="http://img.blog.csdn.net/20161012150617215" alt=""&gt;&lt;/p&gt;
&lt;p&gt;选择SSH&lt;/p&gt;
&lt;p&gt;&lt;img src="http://img.blog.csdn.net/20161012150654787" alt=""&gt;&lt;/p&gt;
&lt;p&gt;选择yes&lt;/p&gt;
&lt;p&gt;&lt;img src="http://img.blog.csdn.net/20161012150753381" alt=""&gt;&lt;/p&gt;
&lt;p&gt;SSH 已经启用&lt;/p&gt;
&lt;p&gt;&lt;img src="http://img.blog.csdn.net/20161012150827171" alt=""&gt;&lt;/p&gt;
&lt;p&gt;然后打开PC的命令行(我用的是macOS,命令行直接可以用ssh)&lt;/p&gt;
&lt;p&gt;输入:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ssh pi@192.168.1.xxx 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;地址为树莓派的ip地址,如果不知道,在树莓派命令行输入 ifconfig,就可以看到了&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.geekfan.net/wp-content/uploads/4768718a07fec72ff908aa6cde5b21a9.png" alt=""&gt;&lt;/p&gt;
&lt;p&gt;然后输入密码,如果还没有修改过用户pi的密码的话,默认密码就是:raspberry&lt;/p&gt;
&lt;p&gt;随后就可以尽情的玩耍了&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.geekfan.net/wp-content/uploads/313ee0ee381651b70e8550ed77cd969f.png" alt=""&gt;&lt;/p&gt;</description></item><item><title>Raspberry之系统安装</title><link>https://time-friend.com/zh/archive/raspberry-system-installation/</link><pubDate>Tue, 10 Jan 2017 12:43:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/raspberry-system-installation/</guid><description>&lt;p&gt;年过完了，某宝商家终于开始工作发货了。
年前的时候，就想买一个树莓派来玩一玩。可是我运气不好，商家已经准备回家过年了。&lt;/p&gt;
&lt;p&gt;昨天在某宝下单。今天就拿到了。我买的是Raspberry-Pi3 Modle B。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://static.alili.tech/images/pi-2.jpg" alt=""&gt;&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;树莓派并没有自带硬盘，所以想要安装系统的话，要自己准备TF卡或者U盘。&lt;/p&gt;
&lt;p&gt;接下来，就要去树莓派的官网下载系统了。
官方安装系统工具，NOOBS非常的简单。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.raspberrypi.org/downloads/noobs/"&gt;下载地址&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;下载完成后,我们就可以按照以下步骤来安装系统了.&lt;/p&gt;
&lt;p&gt;1,把下载的zip包解压到TF卡里&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.geekfan.net/wp-content/uploads/img_5249b9158d98d.png" alt=""&gt;&lt;/p&gt;
&lt;p&gt;2,把TF卡插入树莓派,并且用HDMI接入显示器,鼠标键盘,接上电源.&lt;/p&gt;
&lt;p&gt;这时,树莓派被点亮,显示器会出现以下内容:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.geekfan.net/wp-content/uploads/img_524d91f199b4f.png" alt=""&gt;&lt;/p&gt;
&lt;p&gt;3,这时按下shift按键,会进入恢复系统界面&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.geekfan.net/wp-content/uploads/img_524d9fb0d8009.png" alt=""&gt;&lt;/p&gt;
&lt;p&gt;选择你想要安装的系统,点击安装.&lt;/p&gt;
&lt;p&gt;等待几分钟,系统就安装好了.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://cms-bucket.nosdn.127.net/catchpic/7/7b/7b1fc28118e3151df0ef1dca46241171.jpg?imageView&amp;amp;thumbnail=550x0" alt=""&gt;&lt;/p&gt;
&lt;p&gt;重启进入桌面后,这桌面操作系统叫 PIXEL OS;基于 Debian.&lt;/p&gt;
&lt;p&gt;PIXEL 的意思是“Raspberry-Pi Improved Xwindows Environment, Lightweight”，即“树莓派改进的轻量级 Xwindows 环境”.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://cms-bucket.nosdn.127.net/catchpic/6/61/6173eda98e60a1c16da897c34db2d91d.png?imageView&amp;amp;thumbnail=550x0" alt=""&gt;&lt;/p&gt;</description></item><item><title>关于我在工作中项目调试的方法</title><link>https://time-friend.com/zh/archive/debugging-methods/</link><pubDate>Wed, 04 Jan 2017 11:46:35 +0000</pubDate><guid>https://time-friend.com/zh/archive/debugging-methods/</guid><description>&lt;h2 id="移动端调试"&gt;移动端调试&lt;/h2&gt;
&lt;p&gt;想要在pc上调试移动端页面,需要做下面几个步骤&lt;/p&gt;
&lt;h3 id="pc"&gt;PC&lt;/h3&gt;
&lt;p&gt;1.下载 &lt;a href="https://mp.weixin.qq.com/wiki/10/e5f772f4521da17fa0d7304f68b97d7e.html"&gt;微信web开发者工具&lt;/a&gt;;&lt;/p&gt;
&lt;p&gt;2.打开微信开发者工具,选择移动调试&lt;/p&gt;
&lt;p&gt;3.选择一个请求,把cookie复制出来&lt;/p&gt;
&lt;p&gt;4.在电脑chrome打开开发者工具,切换到console输入以下代码 (用于鉴权)&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; document.cookie=&amp;#34;你刚刚复制的cookie&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;5.如果是微信页面,需要用chrome模拟微信浏览器的 user-agent,教程如下:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://wangbaiyuan.cn/analog-ua-implementation-access-to-open-only-on-the-app-page.html"&gt;模拟UA实现访问只能在微信上打开的网页&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;如果觉得麻烦,可以直接使用微信开发者工具自带的浏览器打开微信页面,里面的user agent,默认是为心里的&lt;/p&gt;
&lt;p&gt;做完以上步骤,你就可以正常在电脑上打开移动页面,或者微信网页了&lt;/p&gt;
&lt;h3 id="微信开发者模式"&gt;微信开发者模式&lt;/h3&gt;
&lt;p&gt;如果你的微信帐号被添加到了公众号web开发者名列.
你可以在微信web开发者工具 直接输入最原始的链接地址,便可以在电脑上调试了.(因为后台需要跳转好几次,来拿到cookie.最终微信复制出来的地址,是拿不到数据的)&lt;/p&gt;
&lt;p&gt;该方法,要把代码部署到服务器上,才可以调试.目前项目的自动化做得还算方便.只要 grunt $build,代码就会自动部署到服务器.&lt;/p&gt;
&lt;p&gt;如果想在本地开发环境,直接调试.只要拿到cookie,就可以解决所有问题.&lt;/p&gt;
&lt;p&gt;微信web开发者工具的调试器与chrome一致,所以复制出cookie也是很方便的了.接下来,参照以上PC的调试方法.&lt;/p&gt;
&lt;h3 id="mac"&gt;mac&lt;/h3&gt;
&lt;p&gt;如果你用mac 并且有iphone,可以使用以下方法&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.cnblogs.com/fakeCoder/p/5923290.html"&gt;使用safari对webview进行调试&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;注:无视教程第三步,也不需要xcode.只要是webview 都可以直接调试&lt;/p&gt;</description></item><item><title>我也写一个Canvas惊悚的粒子效果</title><link>https://time-friend.com/zh/archive/canvas-particle-effect/</link><pubDate>Sun, 04 Sep 2016 11:46:35 +0000</pubDate><guid>https://time-friend.com/zh/archive/canvas-particle-effect/</guid><description>&lt;p&gt;预览:
&lt;a href="http://time-friend.com/examples/canvas/1.html"&gt;Canvas简单粒子效果预览&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;html&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;head&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;meta&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;charset&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;UTF-8&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;title&lt;/span&gt;&amp;gt;Canvas简单粒子效果预览&amp;lt;/&lt;span style="color:#f92672"&gt;title&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;style&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;html&lt;/span&gt;&lt;span style="color:#f92672"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;body&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;margin&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;padding&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;height&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;100&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;%&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;overflow&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;hidden&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;/&lt;span style="color:#f92672"&gt;style&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;head&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;body&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;canvas&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;dotCanvas&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;canvas&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; () {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//创建canvas对象
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;domConvas&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; document.&lt;span style="color:#a6e22e"&gt;getElementById&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;dotCanvas&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;oCanvas&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;domConvas&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getContext&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;2d&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;winWidth&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; document.&lt;span style="color:#a6e22e"&gt;documentElement&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;clientWidth&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;winHeight&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; document.&lt;span style="color:#a6e22e"&gt;documentElement&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;clientHeight&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//设置宽高
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;domConvas&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;width&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;winWidth&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;domConvas&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;height&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;winHeight&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//初始化点,并且随机给出每一个点的位置与速度
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dots&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;300&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;dots&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;push&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;x&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; Math.&lt;span style="color:#a6e22e"&gt;random&lt;/span&gt;() &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;winWidth&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;y&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; Math.&lt;span style="color:#a6e22e"&gt;random&lt;/span&gt;() &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;winHeight&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;xm&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;amen&lt;/span&gt;() &lt;span style="color:#f92672"&gt;?&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2.5&lt;/span&gt;) &lt;span style="color:#f92672"&gt;*&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;amen&lt;/span&gt;() &lt;span style="color:#f92672"&gt;?&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;ym&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;amen&lt;/span&gt;() &lt;span style="color:#f92672"&gt;?&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2.5&lt;/span&gt;) &lt;span style="color:#f92672"&gt;*&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;amen&lt;/span&gt;() &lt;span style="color:#f92672"&gt;?&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;max&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;6000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//随机函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;amen&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#f92672"&gt;!!&lt;/span&gt;(Math.&lt;span style="color:#a6e22e"&gt;random&lt;/span&gt;() &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;) &lt;span style="color:#f92672"&gt;%&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;dotMove&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//开始运动
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dotMove&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//清空canvas,便于重绘
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;oCanvas&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;clearRect&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;winWidth&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;winHeight&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//给出点新的位置,开始移动
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;dots&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;forEach&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;dot&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;index&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;dot&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;x&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dot&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;x&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dot&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;xm&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;dot&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;y&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dot&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;y&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dot&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;ym&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//粒子超出屏幕处理
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;dot&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;x&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dot&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;x&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;winWidth&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;dot&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;xm&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dot&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;xm&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;dot&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;y&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dot&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;y&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;winHeight&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;dot&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;ym&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dot&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;ym&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//重绘画布
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;oCanvas&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;fillRect&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;dot&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;x&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;dot&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;y&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//根据距离画线
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dots&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dot2&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dots&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;dot2&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dot&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;continue&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;gou&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dot&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;y&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dot2&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;y&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;gu&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dot&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;x&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dot2&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;x&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//勾股定理
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;xian&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;gou&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;gou&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;gu&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;gu&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;xian&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dot2&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;max&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//如果符合条件 开始画线
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;oCanvas&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;beginPath&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;oCanvas&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;strokeStyle&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;rgba(0,0,0,1)&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;oCanvas&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;lineWidth&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;oCanvas&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;moveTo&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;dot&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;x&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;dot&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;y&lt;/span&gt;); &lt;span style="color:#75715e"&gt;//画线的起点
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;oCanvas&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;lineTo&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;dot2&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;x&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;dot2&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;y&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//画线的终点
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;oCanvas&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;stroke&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//每秒60帧刷新
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;requestAnimationFrame&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;dotMove&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;/&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;body&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;html&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>置换与非置换元素</title><link>https://time-friend.com/zh/archive/replaced-and-non-replaced-elements/</link><pubDate>Mon, 29 Aug 2016 17:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/replaced-and-non-replaced-elements/</guid><description>&lt;p&gt;突然的听到了这个概念.以前从来没有听过.于是就查了查多了解一下.&lt;/p&gt;
&lt;h2 id="置换和非置换元素"&gt;置换和非置换元素&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;置换元素(replaced element)一般是指有默认就有样式的元素,比如:img, input, textarea, select, object&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;非置换元素(non-replaced element)反之,就是除了:img, input, textarea, select, object 等置换元素以外的其他元素。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>JavaScript的运算符优先级</title><link>https://time-friend.com/zh/archive/javascript-operator-precedence/</link><pubDate>Thu, 25 Aug 2016 11:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/javascript-operator-precedence/</guid><description>&lt;h2 id="javascript-运算符"&gt;JavaScript 运算符&lt;/h2&gt;
&lt;p&gt;下表列出了 JavaScript 运算符，并按优先级顺序从高到低排列。 具有相同优先级的运算符按从左至右的顺序计算&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;运算符&lt;/th&gt;
					&lt;th&gt;说明&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;.[ ] ( )&lt;/td&gt;
					&lt;td&gt;字段访问、数组索引、函数调用和表达式分组&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;++ &amp;ndash; - ~ ! delete new typeof void&lt;/td&gt;
					&lt;td&gt;一元运算符、返回数据类型、对象创建、未定义的值&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;/ %|相乘、相除、求余数&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;ul&gt;
&lt;li&gt;+|相加、相减、字符串串联
&amp;laquo; &amp;raquo; &amp;raquo;&amp;gt;|移位
&amp;lt; &amp;lt;= &amp;gt; &amp;gt;= instanceof|小于、小于或等于、大于、大于或等于、是否为特定类的实例
== != === !==|相等、不相等、全等，不全等
&amp;amp; |按位“与”
^|按位“异或”
| | 按位“或”
&amp;amp;&amp;amp; |逻辑“与”
|| | 逻辑“或”
?: |条件运算
= OP=|赋值、赋值运算（如 += 和 &amp;amp;=）
, |多个计算&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>fetch遇到了一个坑</title><link>https://time-friend.com/zh/archive/fetch-trap/</link><pubDate>Wed, 08 Jun 2016 22:52:35 +0000</pubDate><guid>https://time-friend.com/zh/archive/fetch-trap/</guid><description>&lt;p&gt;fetch 在跨域的情况下,不带cookie;&lt;/p&gt;
&lt;p&gt;解决办法:&lt;/p&gt;
&lt;p&gt;带上参数{credentials: &amp;lsquo;include&amp;rsquo;}后才可以在请求里面带上cookie&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;fetch&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;doAct.action&amp;#39;&lt;/span&gt;, {&lt;span style="color:#a6e22e"&gt;credentials&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;include&amp;#39;&lt;/span&gt;}).&lt;span style="color:#a6e22e"&gt;then&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>关于HTML5 History API</title><link>https://time-friend.com/zh/archive/html5-history-api/</link><pubDate>Mon, 06 Jun 2016 23:52:35 +0000</pubDate><guid>https://time-friend.com/zh/archive/html5-history-api/</guid><description>&lt;p&gt;关于HTML5 History API&lt;/p&gt;
&lt;p&gt;html5加强了history,
在spa页面里面,有两种方法可以修改了网址页面不用刷新,&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;修改页面的hash值,&lt;/li&gt;
&lt;li&gt;利用html5加强后了的pushState&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;先说所有浏览器都可以使用hash
hash 就是我们以前所说的锚点
我们对他并不陌生,
我们可以通过&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;location&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;hash&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;212345&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;!-- more --&gt;
&lt;p&gt;就可以设置网址的hash值,下面是表现形式:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.xxx.com#212345"&gt;www.xxx.com#212345&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在html里利用a标签也是可以修改hash的&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;a&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;#123456&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;a&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;当我们修改hash的时候,我们会触发一个事件:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-JavaScript" data-lang="JavaScript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;window.&lt;span style="color:#a6e22e"&gt;onhashchange&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//do something
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;hash暂且说到这里,下面我们说 pushState&lt;/p&gt;
&lt;p&gt;pushState 是history下面的方法&lt;/p&gt;
&lt;p&gt;所以我们调用的时候是:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-JavaScript" data-lang="JavaScript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;history&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;pushState&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;pushState系列 一共有两个方法,一个事件&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;history.pushState(state, title, url);
history.replaceState(state, title, url);

window.onpopstate
&lt;/code&gt;&lt;/pre&gt;&lt;h5 id="pushstate"&gt;pushState&lt;/h5&gt;
&lt;p&gt;pushState一共有三个参数,&lt;/p&gt;
&lt;p&gt;state: 可以放任意你想放的数据，它将附加到新url上，作为该页面信息的一个补充。&lt;/p&gt;
&lt;p&gt;title: 顾名思义，就是document.title。不过这个参数目前并无作用，浏览器目前会选择忽略它。&lt;/p&gt;
&lt;p&gt;url: 新url，也就是你要显示在地址栏上的url。&lt;/p&gt;
&lt;p&gt;pushState 运行之后,可以记录history&lt;/p&gt;
&lt;h5 id="replacestate"&gt;replaceState&lt;/h5&gt;
&lt;p&gt;也三个参数,作用跟上面是一样的&lt;/p&gt;
&lt;p&gt;唯一的不同点是不会记录history&lt;/p&gt;
&lt;h5 id="windowonpopstate"&gt;window.onpopstate&lt;/h5&gt;
&lt;p&gt;history.pushState()不会触发这个事件
history.replaceState()也不会触发这个事件,&lt;/p&gt;
&lt;p&gt;当页面前进回退的时候会触发这个事件&lt;/p&gt;
&lt;p&gt;事件可以拿到PopStateEvent对象,可以获取到很多关于state的信息&lt;/p&gt;</description></item><item><title>关于FormData文件上传</title><link>https://time-friend.com/zh/archive/formdata-file-upload/</link><pubDate>Fri, 03 Jun 2016 23:46:35 +0000</pubDate><guid>https://time-friend.com/zh/archive/formdata-file-upload/</guid><description>&lt;p&gt;关于文件上传&lt;/p&gt;
&lt;p&gt;在新时代里,使用input file 选取文件,
然后我们查到这dom对象的时候,把这个对象传进 Formdata,&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;filedata&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; document.&lt;span style="color:#a6e22e"&gt;getElementById&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;file&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;formData&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;FormData&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;formData&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;append&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;file&amp;#39;&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;filedata&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;xhr&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;XMLHttpRequest&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;xhr&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;open&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;post&amp;#39;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;url&amp;#39;&lt;/span&gt;,&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;xhr&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;send&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;formData&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;xhr&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;onreadystatechange&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;xhr&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;readyState&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;xhr&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;staus&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;200&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;do&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;something&lt;/span&gt;....
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;!-- more --&gt;
&lt;p&gt;or&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//假设 html已经有一个form,并且包含一个input type=&amp;#34;file&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;form&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; document.&lt;span style="color:#a6e22e"&gt;getElementById&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;form&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//我们只要传进 FormData 就可以了
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;formData&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;FormData&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;form&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;xhr&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;XMLHttpRequest&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;xhr&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;open&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;post&amp;#39;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;url&amp;#39;&lt;/span&gt;,&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;xhr&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;send&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;formData&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;xhr&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;onreadystatechange&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;xhr&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;readyState&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;xhr&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;staus&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;200&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;do&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;something&lt;/span&gt;....
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在没有FormData的年代,我们是用form上传文件&lt;/p&gt;
&lt;p&gt;用js创建一个form表单,里面放几个input,
然后提交 也能完成表单提交&lt;/p&gt;</description></item><item><title>AngularJS的按需加载(3)</title><link>https://time-friend.com/zh/archive/angularjs-lazy-loading-3/</link><pubDate>Wed, 01 Jun 2016 23:55:35 +0000</pubDate><guid>https://time-friend.com/zh/archive/angularjs-lazy-loading-3/</guid><description>&lt;p&gt;上一篇大概的描述了一下Angular的启动过程,&lt;/p&gt;
&lt;p&gt;如果想要在自己的项目里,异步的加载第三方模块,就是按照上一篇的主要逻辑再跑一遍.&lt;/p&gt;
&lt;p&gt;这样子,第三方的模块的方法才能全部加载到angular里.&lt;/p&gt;
&lt;!-- more --&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;config&lt;/span&gt;([
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;$controllerProvider&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;$compileProvider&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;$filterProvider&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;$provide&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;$injector&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;$controllerProvider&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;$compileProvider&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;$filterProvider&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;$provide&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;$injector&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//像第一篇说的那样,把内部方法暴露出来
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;controller&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$controllerProvider&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;register&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;directive&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$compileProvider&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;directive&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;filter&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$filterProvider&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;register&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;factory&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$provide&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;factory&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;service&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$provide&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;service&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;provider&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$provide&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;provider&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;value&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$provide&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;value&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;constant&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$provide&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;constant&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;decorator&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$provide&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;decorator&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//并且定义一个全局的函数,方便以后随便调用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//加载三方模块下的代码,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; window.&lt;span style="color:#a6e22e"&gt;addModule&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;moduleName&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;angular&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;moduleName&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ngProviders&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;$controllerProvider&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$controllerProvider&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;$compileProvider&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$compileProvider&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;$filterProvider&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$filterProvider&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;$provide&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$provide&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;requires&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;requires&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;addModule&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;requires&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;angular&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;forEach&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;_invokeQueue&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;args&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;provider&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ngProviders&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;args&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;]] &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$injector&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;args&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;provider&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;args&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;]].&lt;span style="color:#a6e22e"&gt;apply&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;provider&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;args&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;angular&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;forEach&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;_configBlocks&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;args&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;provider&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ngProviders&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;$injector&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;args&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;provider&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;args&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;]].&lt;span style="color:#a6e22e"&gt;apply&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;provider&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;args&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;angular&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;forEach&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;_runBlocks&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;args&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;$injector&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;invoke&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;args&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>AngularJS的按需加载(2)</title><link>https://time-friend.com/zh/archive/angularjs-lazy-loading-2/</link><pubDate>Tue, 31 May 2016 20:34:35 +0000</pubDate><guid>https://time-friend.com/zh/archive/angularjs-lazy-loading-2/</guid><description>&lt;p&gt;上一篇我们实现了最简单的AngularJS的按需加载,&lt;/p&gt;
&lt;p&gt;可以通过替换Angular的内部方法,再使用require.js配合$q完成了按需加载.&lt;/p&gt;
&lt;p&gt;今天来说说Angular如何按需加载第三方module;&lt;/p&gt;
&lt;p&gt;在此之前,我们得先弄清楚Angular是如何启动的.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://sfault-image.b0.upaiyun.com/179/316/1793163034-56fde93e313cd_articlex" alt=""&gt;&lt;/p&gt;
&lt;!-- more --&gt;
&lt;h5 id="setupmoduleloader方法"&gt;setupModuleLoader方法&lt;/h5&gt;
&lt;p&gt;在上图中,我们得注意一个非常主要的方法;&lt;/p&gt;
&lt;p&gt;setupModuleLoader方法,顾名思义 —— 模块加载器;&lt;/p&gt;
&lt;p&gt;此方法最后返回的对象为:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;moduleInstance&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;_invokeQueue&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;invokeQueue&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;_runBlocks&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;runBlocks&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;requires&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;requires&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;provider&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;invokeLater&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;$provide&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;provider&amp;#39;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;factory&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;invokeLater&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;$provide&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;factory&amp;#39;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;service&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;invokeLater&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;$provide&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;service&amp;#39;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;value&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;invokeLater&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;$provide&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;value&amp;#39;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;constant&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;invokeLater&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;$provide&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;constant&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;unshift&amp;#39;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;animation&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;invokeLater&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;$animateProvider&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;register&amp;#39;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;filter&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;invokeLater&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;$filterProvider&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;register&amp;#39;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;controller&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;invokeLater&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;$controllerProvider&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;register&amp;#39;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;directive&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;invokeLater&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;$compileProvider&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;directive&amp;#39;&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;config&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;config&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;run&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;block&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;runBlocks&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;push&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;block&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;看着这对象的格式,有没有特别熟悉?&lt;/p&gt;
&lt;p&gt;当我们运行&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;angular.module(&amp;#39;app&amp;#39;,[]);

//或者

angular.module(&amp;#39;app&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;我们新建一个module或者获取一个module的时候,
返回的就是这个对象.&lt;/p&gt;
&lt;p&gt;当我们做链式操作的时候,
angular.module(&amp;lsquo;app&amp;rsquo;,[]).config().run().controller();&lt;/p&gt;
&lt;p&gt;每一步操作,返回的都是它,所以我们才可以做链式操作;&lt;/p&gt;
&lt;p&gt;当angular初始化完成之后,开始在dom里寻找ng-app属性;&lt;/p&gt;
&lt;p&gt;当找到ng-app后,拿到ng-app的value后才开始启动 angular;
内部运行bootstrap方法;&lt;/p&gt;
&lt;p&gt;如果要选择手动启动的话也可以这样:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;angular.bootstrap(document, [&amp;#39;moduleName&amp;#39;]);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;当bootstrap的时候angular在做什么呢?&lt;/p&gt;
&lt;h4 id="dobootstrap方法"&gt;doBootstrap方法&lt;/h4&gt;
&lt;p&gt;在源码里中的bootstrap方法里有一个doBootstrap方法:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;doBootstrap&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;element&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;jqLite&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;element&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//判断是否启动
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;element&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;injector&lt;/span&gt;()) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;tag&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;element&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;] &lt;span style="color:#f92672"&gt;===&lt;/span&gt; document) &lt;span style="color:#f92672"&gt;?&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;document&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;startingTag&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;element&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;throw&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ngMinErr&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;btstrpd&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;App Already Bootstrapped with this Element &amp;#39;{0}&amp;#39;&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;tag&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;replace&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;/&amp;lt;/&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;&amp;amp;lt;&amp;#39;&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;replace&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;/&amp;gt;/&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;&amp;amp;gt;&amp;#39;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//angular.bootstrap(document, [&amp;#39;moduleName&amp;#39;]);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//这里的modules就是之前我们bootstrap时候传进来的 moduleName
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//modules ==&amp;gt; [&amp;#39;moduleName&amp;#39;]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;modules&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;modules&lt;/span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; [];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;modules&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;unshift&lt;/span&gt;([&lt;span style="color:#e6db74"&gt;&amp;#39;$provide&amp;#39;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;$provide&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;$provide&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;value&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;$rootElement&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;element&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .....
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//重点来了 createInjector
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;injector&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;createInjector&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;modules&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;config&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;strictDi&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;injector&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;invoke&lt;/span&gt;([&lt;span style="color:#e6db74"&gt;&amp;#39;$rootScope&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;$rootElement&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;$compile&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;$injector&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bootstrapApply&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;scope&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;element&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;compile&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;injector&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;scope&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;$apply&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;element&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;data&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;$injector&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;injector&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;compile&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;element&lt;/span&gt;)(&lt;span style="color:#a6e22e"&gt;scope&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; );
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;injector&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="createinjector方法"&gt;createInjector方法&lt;/h4&gt;
&lt;p&gt;我们看这个方法主要做了什么&lt;/p&gt;</description></item><item><title>AngularJS的按需加载(1)</title><link>https://time-friend.com/zh/archive/angularjs-lazy-loading-1/</link><pubDate>Mon, 30 May 2016 16:14:25 +0000</pubDate><guid>https://time-friend.com/zh/archive/angularjs-lazy-loading-1/</guid><description>&lt;p&gt;今天来聊一聊一直困扰了我很久的问题.AngularJS的按需加载.&lt;/p&gt;
&lt;p&gt;angular的好处这里就不用多说,
但是用久了你会发现,一个网站所有的 Controller, Service, Directive等等,全部加载完了,
页面才开始跑.&lt;/p&gt;
&lt;p&gt;小项目,代码少.不会感觉太大问题.&lt;/p&gt;
&lt;p&gt;但是页面多了,那主页越来越臃肿.有用的,没用的通通加载进来.
虽说全部加载,页面第一次打开会慢很多,之后打开的页面速度会极快.
但是,这一点都不Smart.&lt;/p&gt;
&lt;p&gt;那有什么办法可以做到按需加载呢?&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;其实很简单,看代码:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;config&lt;/span&gt;([
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;$controllerProvider&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;$compileProvider&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;$filterProvider&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;$provide&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;$controllerProvider&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;$compileProvider&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;$filterProvider&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;$provide&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;controller&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$controllerProvider&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;register&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;directive&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$compileProvider&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;directive&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;filter&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$filterProvider&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;register&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;factory&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$provide&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;factory&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;service&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$provide&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;service&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;provider&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$provide&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;provider&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;value&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$provide&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;value&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;constant&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$provide&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;constant&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;decorator&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$provide&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;decorator&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我们要先把angular的方法替换成内部使用的方法,&lt;/p&gt;
&lt;p&gt;这样我们在后面才可以正常的按需加载Controller, Service, Directive&amp;hellip;&lt;/p&gt;
&lt;p&gt;接下来,我们选择一个模块加载器,
流行的加载器有很多,Require.js,Sea.js,System.js 等等.&lt;/p&gt;
&lt;p&gt;选一个最经典的 Require.js;&lt;/p&gt;
&lt;p&gt;下面是按需加载的小demo
&lt;a href="https://github.com/incomparable9527/demo.Angular-async"&gt;Github Demo&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;我们先配置好,require的config;&lt;/p&gt;
&lt;p&gt;app.bootstrap.js&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;config&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;paths&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;angular&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;http://cdn.bootcss.com/angular.js/1.5.6/angular.min&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;ui.router&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;http://cdn.bootcss.com/angular-ui-router/0.2.18/angular-ui-router.min&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;app&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;app&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;shim&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;ui.router&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;deps&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;&amp;#39;angular&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;接下来是 app.js&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;define&lt;/span&gt;([
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;angular&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;ui.router&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;], &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;angular&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;app&amp;#39;&lt;/span&gt;, [&lt;span style="color:#e6db74"&gt;&amp;#39;ui.router&amp;#39;&lt;/span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;config&lt;/span&gt;([
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;$controllerProvider&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;$compileProvider&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;$filterProvider&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;$provide&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;$controllerProvider&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;$compileProvider&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;$filterProvider&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;$provide&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;controller&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$controllerProvider&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;register&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;directive&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$compileProvider&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;directive&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;filter&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$filterProvider&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;register&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;factory&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$provide&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;factory&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;service&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$provide&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;service&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;provider&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$provide&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;provider&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;value&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$provide&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;value&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;constant&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$provide&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;constant&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;decorator&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$provide&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;decorator&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;config&lt;/span&gt;([
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;$stateProvider&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;$urlRouterProvider&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;$stateProvider&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;$urlRouterProvider&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;$urlRouterProvider&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;otherwise&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;/home&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;$stateProvider&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;state&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;home&amp;#39;&lt;/span&gt;, {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;url&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;/home&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;templateUrl&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;view/testTemplate.html&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;controller&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;testController&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;resolve&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;deps&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;$q&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;$rootScope&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;$q&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;$rootScope&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;deferred&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$q&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;defer&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;([&lt;span style="color:#e6db74"&gt;&amp;#39;../view/testController&amp;#39;&lt;/span&gt;], &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;$rootScope&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;$apply&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;deferred&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;resolve&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;deferred&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;promise&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;下面是模版代码,主要是为了测试控制器是否加载成功&lt;/p&gt;</description></item><item><title>Journey</title><link>https://time-friend.com/zh/archive/journey/</link><pubDate>Sat, 28 May 2016 14:19:04 +0000</pubDate><guid>https://time-friend.com/zh/archive/journey/</guid><description>&lt;p&gt;&lt;img src="https://static.alili.tech/images/journey.jpg" alt="journey"&gt;&lt;/p&gt;</description></item><item><title>微信浏览器动态修改Title</title><link>https://time-friend.com/zh/archive/wechat-browser-dynamically-modify-title/</link><pubDate>Thu, 26 May 2016 11:43:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/wechat-browser-dynamically-modify-title/</guid><description>&lt;h2 id="微信浏览器动态修改title"&gt;微信浏览器动态修改Title&lt;/h2&gt;
&lt;p&gt;为什么会有这么一篇文章?之前在做spa页面开发的时候,发现了一件非常匪夷所思的事情.&lt;/p&gt;
&lt;p&gt;下面这段代码在微信浏览器里,是无效的.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;document.&lt;span style="color:#a6e22e"&gt;title&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;我是标题&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;标题第一次生成后,就无法在改变.&lt;/p&gt;
&lt;p&gt;不过没有关系,&lt;/p&gt;
&lt;p&gt;下面我们用黑魔法般的代码,来完成微信浏览器里title的修改.&lt;/p&gt;
&lt;!-- more --&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;document.&lt;span style="color:#a6e22e"&gt;title&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;我是标题&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;iframe&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; document.&lt;span style="color:#a6e22e"&gt;createElement&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;iframe&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;iframe&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;src&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;/favicon.ico&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;document.&lt;span style="color:#a6e22e"&gt;body&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;appendChild&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;iframe&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;iframe&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;onload&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;setTimeout&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; document.&lt;span style="color:#a6e22e"&gt;body&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;removeChild&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;iframe&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;就是这样,title改变了.&lt;/p&gt;</description></item><item><title>JavaScript的奇淫技巧</title><link>https://time-friend.com/zh/archive/javascript-tricks/</link><pubDate>Wed, 25 May 2016 11:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/javascript-tricks/</guid><description>&lt;h2 id="类型转换"&gt;类型转换&lt;/h2&gt;
&lt;h3 id="数组转字符串"&gt;数组转字符串&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;arr&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;6&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;str&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;arr&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&lt;/span&gt;; &lt;span style="color:#75715e"&gt;//1,2,3,4,5,6
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="字符串转数字"&gt;字符串转数字&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;str&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;999&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;num&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;str&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;; &lt;span style="color:#75715e"&gt;//999
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;str&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;999&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;num&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;str&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#75715e"&gt;//999
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="字符串转数字-1"&gt;字符串转数字&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;str&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;999&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;num&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;str&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// 999
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="向下取整"&gt;向下取整&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;num&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;~~&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1.23232656&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;num&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;563.933333&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// 563
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;!-- more --&gt;
&lt;h3 id="boolean-转换"&gt;boolean 转换&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bool&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;!!&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// false
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bool&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;!!&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;null&amp;#39;&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bool&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;!!&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;undefined&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// false
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bool&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;!!&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;undefined&amp;#39;&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bool&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;!!&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// false
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bool&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;!!&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;0&amp;#39;&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bool&lt;/span&gt;&lt;span style="color:#f92672"&gt;=!!&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bool&lt;/span&gt;&lt;span style="color:#f92672"&gt;=!!&lt;/span&gt;[]; &lt;span style="color:#75715e"&gt;// true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bool&lt;/span&gt;&lt;span style="color:#f92672"&gt;=!!&lt;/span&gt;{}; &lt;span style="color:#75715e"&gt;// true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bool&lt;/span&gt;&lt;span style="color:#f92672"&gt;=!!&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Boolean(&lt;span style="color:#e6db74"&gt;&amp;#39;false&amp;#39;&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bool&lt;/span&gt;&lt;span style="color:#f92672"&gt;=!!&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Boolean(&lt;span style="color:#e6db74"&gt;&amp;#39;true&amp;#39;&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="判断对象下面是否有此属性"&gt;判断对象下面是否有此属性&lt;/h2&gt;
&lt;h3 id="直接判断"&gt;直接判断&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;123&lt;/span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;){ &lt;span style="color:#75715e"&gt;//obj.b ==&amp;gt;123
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;运行了&amp;#39;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//可以运行
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;){ &lt;span style="color:#75715e"&gt;//obj.b ==&amp;gt;undefined
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;运行了&amp;#39;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//没有运行
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;obj2&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;obj2&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;){ &lt;span style="color:#75715e"&gt;//obj.b ==&amp;gt;false
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;运行了&amp;#39;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//没有运行
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 不严谨,如果值为0,undefined,false,null... 也会判断为false
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="in-操作符"&gt;in 操作符&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;123&lt;/span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;a&amp;#39;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;in&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;){ &lt;span style="color:#75715e"&gt;// &amp;#39;a&amp;#39; in obj ==&amp;gt;true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;运行了&amp;#39;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//可以运行
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;b&amp;#39;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;in&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;){&lt;span style="color:#75715e"&gt;// &amp;#39;a&amp;#39; in obj ==&amp;gt;false
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;运行了&amp;#39;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//没有运行
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="利用hasownproperty"&gt;利用hasOwnProperty&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;123&lt;/span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;hasOwnProperty&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;a&amp;#39;&lt;/span&gt;)){ &lt;span style="color:#75715e"&gt;//==&amp;gt;true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;运行了&amp;#39;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//可以运行
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;hasOwnProperty&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;b&amp;#39;&lt;/span&gt;)){ &lt;span style="color:#75715e"&gt;//==&amp;gt;false
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;运行了&amp;#39;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//没有运行
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;还有好多好多,得慢慢写&lt;/p&gt;</description></item><item><title>浏览器常用的本地储存方式</title><link>https://time-friend.com/zh/archive/browser-local-storage/</link><pubDate>Fri, 29 Apr 2016 17:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/browser-local-storage/</guid><description>&lt;p&gt;日常开发中,难免会遇到一些要求浏览器储存一些数据的需求.目前常用的储存方法有:&lt;/p&gt;
&lt;h2 id="cookie"&gt;cookie&lt;/h2&gt;
&lt;p&gt;cookie设计之初,本身不是用来储存数据.而是区别http请求.
所以每一次http请求,都会带上cookie.如果cookie储存的量实在过大,肯定会造成http的性能问题.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 设置cookie(储存数据)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;setcookie&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;value&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;expired&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;domain&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;now&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Date();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;==&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;throw&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Cookie Name Must not be Null&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		}&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;value&lt;/span&gt;&lt;span style="color:#f92672"&gt;==&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#66d9ef"&gt;throw&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Cookie Value Must not be Null&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		}&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;expired&lt;/span&gt;&lt;span style="color:#f92672"&gt;==&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#a6e22e"&gt;expired&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;&lt;span style="color:#f92672"&gt;==&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;domain&lt;/span&gt;&lt;span style="color:#f92672"&gt;==&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&lt;span style="color:#a6e22e"&gt;domain&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;window.&lt;span style="color:#a6e22e"&gt;location&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;host&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;now&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;setTime&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;now&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getTime&lt;/span&gt;()&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;expired&lt;/span&gt;&lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1000&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;document.&lt;span style="color:#a6e22e"&gt;cookie&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;=&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;escape&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;value&lt;/span&gt;)&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;;expires=&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;now&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;toGMTString&lt;/span&gt;()&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;;path=&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;;domain=&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;domain&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 读取cookie(读取数据)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getcookie&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;allcookie&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;document.&lt;span style="color:#a6e22e"&gt;cookie&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;thiscookie&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;allcookie&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;match&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;=[^\\s]*&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;mycookie&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;thiscookie&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;].&lt;span style="color:#a6e22e"&gt;split&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;=&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;mycookie&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;].&lt;span style="color:#a6e22e"&gt;substring&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;mycookie&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;].&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;unescape&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="localstorage"&gt;localStorage&lt;/h2&gt;
&lt;p&gt;相对cookie的读取操作,localStorage会简单非常多.
另外localStorage每一次更新,都会触发一次onstorage事件&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;localStorage&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;xxx&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;time-friend.com&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;localStorage&lt;/span&gt;[&lt;span style="color:#e6db74"&gt;&amp;#39;xxx&amp;#39;&lt;/span&gt;]&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;time-friend.com&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;localStorage&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;setItem&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;xxx&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;time-friend.com&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//获取
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;localStorage&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;xxx&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;localStorage&lt;/span&gt;[&lt;span style="color:#e6db74"&gt;&amp;#39;xxx&amp;#39;&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;localStorage&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getItem&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;xxx&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//删除
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;localStorage&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;removeItem&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;xxx&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//清空locaStorage
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;localStorage&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;clear&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//onstorage事件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;window.&lt;span style="color:#a6e22e"&gt;addEventListener&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;storage&amp;#34;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 做一些你想做的事情
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}, &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;); 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="flashshareobject"&gt;Flash ShareObject&lt;/h2&gt;
&lt;p&gt;这种方式能能解决上面提到的cookie存储的两个弊端，而且能够跨浏览器，应该说是目前最好的本地存储方案。不过，需要在页面中插入一个Flash.
缺点：需要安装Flash插件。&lt;/p&gt;</description></item><item><title>什么是浏览器的重绘与回流</title><link>https://time-friend.com/zh/archive/what-is-browser-repaint-and-reflow/</link><pubDate>Mon, 25 Apr 2016 19:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/what-is-browser-repaint-and-reflow/</guid><description>&lt;h1 id="重绘与回流的定义"&gt;重绘与回流的定义&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;重绘：当前元素的样式(背景颜色、字体颜色等)发生改变的时候，我们只需要把改变的元素重新的渲染一下即可，重绘对浏览器的性能影响较小，所以 一般不考虑。
　　发生重绘的情形：改变容器的外观风格等，比如background：black等。改变外观，不改变布局，不影响其他的dom。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;回流：是指浏览器为了重新渲染部分或者全部的文档而重新计算文档中元素的位置和几何构造的过程。因为回流可能导致整个dom树的重新构造，所以是性能的一大杀手.一个元素的回流导致了其所有子元素以及DOM中紧随其后的祖先元素的随后的回流.
 &lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="浏览器渲染过程"&gt;浏览器渲染过程　　&lt;/h2&gt;
&lt;p&gt;渲染：就是把浏览器把HTML代码以css定义的规则显示在浏览器窗口的过程 &lt;/p&gt;
&lt;h2 id="浏览器解析html的基本过程"&gt;浏览器解析HTML的基本过程：&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;用户输入网址，浏览器向服务器发出请求，服务器返回html文件&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;浏览器载入html代码，发现标签内有一个标签引用外部css文件&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;浏览器又发出css文件的请求，服务器返回这个css文件&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;浏览器继续载入html中的部分的代码，并且css文件已经拿到手了，可以渲染页面&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;浏览器在代码中发现一个标签引用关了一张图片，向服务器发出请求。此时浏览器不会等到图片下载完，而是继续渲染后面的代码&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;服务器返回图片文件，由于图片占用了一定面积，影响了后面段落的排布，因此浏览器需要回过头来渲染这部分代码&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;浏览器发现了一个包含一行javascript代码的script标签，赶快运行它&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;javascript脚本执行了这条语句，命令浏览器隐藏代码中某个,杯具了，突然就少了一个元素，浏览器不得不重新渲染这部分代码&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;终于等到的到来，浏览器泪流满面 &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;等等，还没完，用户点了一个界面中的“换肤”按钮，javascript让浏览器换了一个标签中的css的路径&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;浏览器召集了在座的各位：&amp;ldquo;大伙需要收拾下行李，咱得重新来过&amp;rdquo;，浏览器向服务器请求了新的css文件，重新渲染页面当页面的布局发生变化时，浏览器会回过头来重新渲染，这就是页面变慢的原因。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="触发回流的操作"&gt; 触发回流的操作&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;调整窗口大小（Resizing the window）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;改变字体（Changing the font）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;增加或者移除样式表（Adding or removing a stylesheet）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;内容变化，比如用户在input框中输入文字（Content changes, such as a user typing text in an input box）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;激活 CSS 伪类，比如 :hover (IE 中为兄弟结点伪类的激活)（Activation of CSS pseudo classes such as :hover (in IE the activation of the pseudo class of a sibling)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;操作 class 属性（Manipulating the class attribute）&lt;/p&gt;</description></item><item><title>移动端网站点击出现闪动或灰色背景问题</title><link>https://time-friend.com/zh/archive/mobile-tap-highlight-issue/</link><pubDate>Wed, 20 Apr 2016 19:33:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/mobile-tap-highlight-issue/</guid><description>&lt;p&gt;移动端网站点击出现闪动或灰色背景问题&lt;/p&gt;
&lt;p&gt;只需对绑定事件添加class样式 使其触发事件时背景为透明色&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;{&lt;span style="color:#66d9ef"&gt;-webkit-&lt;/span&gt;tap-highlight-color:&lt;span style="color:#66d9ef"&gt;transparent&lt;/span&gt;;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>源码分析AngularJS中的Provider们的小小区别</title><link>https://time-friend.com/zh/archive/angularjs-provider-differences-source-analysis/</link><pubDate>Mon, 22 Feb 2016 16:14:25 +0000</pubDate><guid>https://time-friend.com/zh/archive/angularjs-provider-differences-source-analysis/</guid><description>&lt;h1 id="angularjs的provider"&gt;AngularJS的provider&lt;/h1&gt;
&lt;p&gt;Angular中有以下创建供应商(provider)的方法:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;provider()&lt;/li&gt;
&lt;li&gt;service()&lt;/li&gt;
&lt;li&gt;factory()&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="provider使用方式"&gt;Provider使用方式&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;angular&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;app&amp;#34;&lt;/span&gt;, [])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#a6e22e"&gt;provider&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;HelloAngular&amp;#34;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;$get&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;小明&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getName&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;getName&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getName&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#a6e22e"&gt;controller&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;MyCtrl&amp;#39;&lt;/span&gt;, [&lt;span style="color:#e6db74"&gt;&amp;#39;$scope&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;HelloAngular&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;$scope&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;helloAngular&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;$scope&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;gameName&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;helloAngular&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getName&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="service使用方式"&gt;Service使用方式&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;angular&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;app&amp;#34;&lt;/span&gt;, [])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#a6e22e"&gt;service&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;HelloAngular&amp;#34;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;小明&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getName&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#a6e22e"&gt;controller&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;MyCtrl&amp;#39;&lt;/span&gt;, [&lt;span style="color:#e6db74"&gt;&amp;#39;$scope&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;HelloAngular&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;$scope&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;helloAngular&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;$scope&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;gameName&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;helloAngular&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getName&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="factory使用方式"&gt;Factory使用方式&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;angular&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;app&amp;#34;&lt;/span&gt;, [])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#a6e22e"&gt;factory&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;HelloAngular&amp;#34;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;小明&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getName&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 	&lt;span style="color:#a6e22e"&gt;getName&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;getName&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#a6e22e"&gt;controller&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;MyCtrl&amp;#39;&lt;/span&gt;, [&lt;span style="color:#e6db74"&gt;&amp;#39;$scope&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;HelloAngular&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;$scope&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;helloAngular&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;$scope&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;gameName&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;helloAngular&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getName&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;实现方法各有区别,但是使用上都是一模一样的&lt;/p&gt;</description></item><item><title>Hexo的SEO优化(搜索引擎优化)</title><link>https://time-friend.com/zh/archive/hexo-seo-optimization/</link><pubDate>Tue, 19 Jan 2016 21:32:05 +0000</pubDate><guid>https://time-friend.com/zh/archive/hexo-seo-optimization/</guid><description>&lt;p&gt;今天给大家聊一聊hexo的seo也就是百度跟谷歌的一些搜索引擎优化.&lt;/p&gt;
&lt;h2 id="sitemap网站地图"&gt;sitemap网站地图&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;安装site map网站地图插件&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;npm install hexo-generator-sitemap --save
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;npm install hexo-generator-baidu-sitemap --save
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="2"&gt;
&lt;li&gt;_config.yml中增加以下配置&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;itemap:
 path: sitemap.xml
baidusitemap:
 path: baidusitemap.xml
&lt;/code&gt;&lt;/pre&gt;&lt;ol start="3"&gt;
&lt;li&gt;生成网站地图&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;hexo clean
hexo g
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="百度主动推送"&gt;百度主动推送&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;安装插件&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm install hexo-baidu-url-submit --save
&lt;/code&gt;&lt;/pre&gt;&lt;ol start="2"&gt;
&lt;li&gt;_config.yml插件配置&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;baidu_url_submit:
 count: 10 # 提交最新的链接数
 host: time-friend.com # 在百度站长平台中注册的域名,虽然官方推荐要带有 www, 但可以不带.
 token: your_token ## 请注意这是您的秘钥， 请不要发布在公众仓库里!
 path: baidu_urls.txt # 文本文档的地址,新链接会保存在此文本文档里
&lt;/code&gt;&lt;/pre&gt;&lt;ol start="3"&gt;
&lt;li&gt;_config.yml发布配置&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;deploy:
- type: git #部署类型
 repository: xxxxx #部署的仓库
 branch: master 
- type: baidu_url_submitter # 新增这一行类型
&lt;/code&gt;&lt;/pre&gt;&lt;ol start="4"&gt;
&lt;li&gt;推送且发布&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;hexo clean
hexo g
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>ES6 之Proxy</title><link>https://time-friend.com/zh/archive/es6-proxy/</link><pubDate>Fri, 31 Jul 2015 21:17:51 +0000</pubDate><guid>https://time-friend.com/zh/archive/es6-proxy/</guid><description>&lt;h3 id="proxy"&gt;Proxy&lt;/h3&gt;
&lt;p&gt;ES6新增了Proxy,那Proxy是什么呢?&lt;/p&gt;
&lt;p&gt;Proxy,翻译是代理的意思.在ES6中,Proxy可以监听对象的修改.&lt;/p&gt;
&lt;p&gt;也就是说,外界对这个对象的访问与修改,都可以通过Proxy监听,并且可以做一些别的事情.&lt;/p&gt;
&lt;p&gt;举个例子:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;proxyObj&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Proxy(&lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;,{ &lt;span style="color:#75715e"&gt;//proxyObj会继承obj
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;set&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;alert&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;我被修改了&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//修改属性
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;proxyObj&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;; &lt;span style="color:#75715e"&gt;//属性被修改后,之前设置的handler会被触发
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// 2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;就这么简单&lt;/p&gt;
&lt;!-- more --&gt;
&lt;hr&gt;
&lt;h3 id="下面是可以监听的操作"&gt;下面是可以监听的操作&lt;/h3&gt;
&lt;h4 id="1-gettarget-propkey-receiver"&gt;1. get(target, propKey, receiver)&lt;/h4&gt;
&lt;p&gt;拦截对象属性的读取，比如proxy.foo和proxy[&amp;lsquo;foo&amp;rsquo;]。&lt;/p&gt;
&lt;h4 id="2-settarget-propkey-value-receiver"&gt;2. set(target, propKey, value, receiver)&lt;/h4&gt;
&lt;p&gt;拦截对象属性的设置，比如proxy.foo = v或proxy[&amp;lsquo;foo&amp;rsquo;] = v，返回一个布尔值。&lt;/p&gt;
&lt;h4 id="3-hastarget-propkey"&gt;3. has(target, propKey)&lt;/h4&gt;
&lt;p&gt;拦截propKey in proxy的操作，以及对象的hasOwnProperty方法，返回一个布尔值。&lt;/p&gt;
&lt;h4 id="4-deletepropertytarget-propkey"&gt;4. deleteProperty(target, propKey)&lt;/h4&gt;
&lt;p&gt;拦截delete proxy[propKey]的操作，返回一个布尔值。&lt;/p&gt;
&lt;h4 id="5-ownkeystarget"&gt;5. ownKeys(target)&lt;/h4&gt;
&lt;p&gt;拦截Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy)，返回一个数组。该方法返回对象所有自身的属性，而Object.keys()仅返回对象可遍历的属性。&lt;/p&gt;
&lt;h4 id="6-getownpropertydescriptortarget-propkey"&gt;6. getOwnPropertyDescriptor(target, propKey)&lt;/h4&gt;
&lt;p&gt;拦截Object.getOwnPropertyDescriptor(proxy, propKey)，返回属性的描述对象。&lt;/p&gt;
&lt;h4 id="7-definepropertytarget-propkey-propdesc"&gt;7. defineProperty(target, propKey, propDesc)&lt;/h4&gt;
&lt;p&gt;拦截Object.defineProperty(proxy, propKey, propDesc）、Object.defineProperties(proxy, propDescs)，返回一个布尔值。&lt;/p&gt;
&lt;h4 id="8-preventextensionstarget"&gt;8. preventExtensions(target)&lt;/h4&gt;
&lt;p&gt;拦截Object.preventExtensions(proxy)，返回一个布尔值。&lt;/p&gt;</description></item><item><title>ES6 之Promise</title><link>https://time-friend.com/zh/archive/es6-promise/</link><pubDate>Tue, 28 Jul 2015 23:13:56 +0000</pubDate><guid>https://time-friend.com/zh/archive/es6-promise/</guid><description>&lt;h3 id="promise"&gt;Promise&lt;/h3&gt;
&lt;p&gt;Promise与上一章的Generator一样,也是异步编程的一种解决方案.&lt;/p&gt;
&lt;p&gt;在 jQuery,Angular都能找到相似的处理异步的方法.&lt;/p&gt;
&lt;h3 id="基本使用"&gt;基本使用&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//首先先实例化一个Promise
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;promise&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Promise(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;resolve&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;reject&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//Promise会有两个参数 resolve, reject,一个代表成功,一个代表失败
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#75715e"&gt;/* true or false */&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;resolve&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;value&lt;/span&gt;); &lt;span style="color:#75715e"&gt;//成功,会执行promise.then的第一个回调
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;reject&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;); &lt;span style="color:#75715e"&gt;//失败,会执行promise.then的第二个回调
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;promise&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;then&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;value&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//当上面函数运行resolve()的时候,会走这里
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//并且可以接收到 Promise函数里resolve传入的参数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;},&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//当上面函数运行reject()的时候,会走这里
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//并且可以接收到 Promise函数里reject传入的参数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}).&lt;span style="color:#66d9ef"&gt;catch&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//当then的两个回调函数都有报错的时候,如果加上了catch,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//可以在这里接受到报错的对象,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//且不会导致代码因为报错,停止执行
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这就是一个完整的Promise的使用方法.是不是非常的简单?&lt;/p&gt;</description></item><item><title>ES6 之Generator</title><link>https://time-friend.com/zh/archive/es6-generator/</link><pubDate>Sat, 25 Jul 2015 22:15:47 +0000</pubDate><guid>https://time-friend.com/zh/archive/es6-generator/</guid><description>&lt;h3 id="generator的基本使用"&gt;Generator的基本使用&lt;/h3&gt;
&lt;p&gt;Generator是ES6提供的一种异步解决方案.他能干什么呢?&lt;/p&gt;
&lt;p&gt;能具体解决我们什么样的问题呢?&lt;/p&gt;
&lt;p&gt;比如说,我想做一件事情,但是必须要求有两个ajax完成后才能做.&lt;/p&gt;
&lt;p&gt;比如:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;$http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;请求1&amp;#39;&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;success&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;$http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;请求2&amp;#39;&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;success&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// do something ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这样做的话,就要一层一层的嵌套,当请求更多的时候,代码会写的非常的乱.&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;现在我们有了Generator,我们该怎么做呢?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;&lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getData&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;yield&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;请求1&amp;#39;&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;success&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// do something ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;g&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;next&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;yield&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;请求2&amp;#39;&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;success&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// do something ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;g&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;next&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//最终要做的事情
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;g&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;getData&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;g&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;next&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;就这样,我们把必须要嵌套的异步操作,写成了&amp;quot;同步&amp;quot;.&lt;/p&gt;
&lt;p&gt;上面的函数,有三个关键的地方:&lt;/p&gt;
&lt;p&gt;1.function 后面多了一个 *&lt;/p&gt;
&lt;p&gt;2.函数里多了一个yield 关键字&lt;/p&gt;
&lt;p&gt;3.函数执行后,会有一个next方法;&lt;/p&gt;
&lt;p&gt;Generator的基本使用,就是在这三个关键的地方.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;关于Generator的运行过程是这样子的:&lt;/p&gt;
&lt;p&gt;1.在function后面加一个*,表示申明了一个Generator函数.&lt;/p&gt;
&lt;p&gt;2.当Generator函数运行后,会实例出一个Generator对象.
这个Generator对象下会有一个next方法.&lt;/p&gt;
&lt;p&gt;3.当我们运行next方法的时候,才能真正运行Generator函数里真正的内容.&lt;/p&gt;
&lt;p&gt;4.当执行Generator函数的时候,碰到了yield,函数会暂停一次.&lt;/p&gt;
&lt;p&gt;5.当下一次运行next方法的时候,Generator函数会从上一次暂停的地方继续执行.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="yield"&gt;yield&lt;/h3&gt;
&lt;p&gt;yield关键字与return很像,会返回相应的东西.&lt;/p&gt;
&lt;p&gt;他们的区别在于:&lt;/p&gt;
&lt;p&gt;yield是暂停函数的运行,必须要在Generator函数里使用.&lt;/p&gt;
&lt;p&gt;return是终止函数的运行,任何地方都能使用&lt;/p&gt;</description></item><item><title>ES6 之箭头函数</title><link>https://time-friend.com/zh/archive/es6-arrow-functions/</link><pubDate>Sun, 19 Jul 2015 20:45:33 +0000</pubDate><guid>https://time-friend.com/zh/archive/es6-arrow-functions/</guid><description>&lt;p&gt;在es6中可以使用箭头函数（Arrow Functions）&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;foo&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;) =&amp;gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;foo&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;hello word&amp;#34;&lt;/span&gt;); &lt;span style="color:#75715e"&gt;//hello word
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;等价于&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;foo&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;foo&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;hello word&amp;#34;&lt;/span&gt;); &lt;span style="color:#75715e"&gt;//hello word
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;!-- more --&gt;
&lt;p&gt;以上函数只有一个参数,还可以写成连括号都不需要:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;foo&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt; =&amp;gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;foo&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;hello word&amp;#34;&lt;/span&gt;); &lt;span style="color:#75715e"&gt;//hello word
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果函数没有参数,就必须要加上括号了:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;foo&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; () =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;alert&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;hello word&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;作为事件句柄&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;document.&lt;span style="color:#a6e22e"&gt;addEventListener&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;click&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;event&lt;/span&gt; =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;event&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;回调&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;$&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;button&amp;#34;&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;hover&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ()=&amp;gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//鼠标移入
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;鼠标移入&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;},
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ()=&amp;gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//鼠标移出
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;鼠标移出&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;p&gt;使用箭头函数之后,this将会继承外围作用域的this,举个例子&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;oImage&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Image&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;oImage2&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Image&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;document.&lt;span style="color:#a6e22e"&gt;getElementById&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;button&amp;#34;&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;onclick&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;() =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//没有外围作用域,所以this是undefined
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;); &lt;span style="color:#75715e"&gt;// 这里的this是undefined
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;oImage&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;https://gss0.bdstatic.com/5eR1dDebRNRTm2_p8IuM_a/res/img/richanglogo168_24.png&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;oImage2&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;https://gss0.bdstatic.com/5eR1dDebRNRTm2_p8IuM_a/res/img/richanglogo168_24.png&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//这里使用了箭头函数,this将会继承外围作用域的this,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//可是外围的this也是undefined,所以这里还是undefined
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;oImage&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;onload&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;() =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;)&lt;span style="color:#75715e"&gt;// 这里的this是undefined
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//这里没有用箭头函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;oImage2&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;onload&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;)&lt;span style="color:#75715e"&gt;// 这里的this 将会是image对象
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;换一种写法,最外层使用传统的function写法&lt;/p&gt;</description></item><item><title>ES6 之解构赋值</title><link>https://time-friend.com/zh/archive/es6-destructuring/</link><pubDate>Fri, 17 Jul 2015 23:32:16 +0000</pubDate><guid>https://time-friend.com/zh/archive/es6-destructuring/</guid><description>&lt;p&gt;学习解构赋值的时候,我想到了以前的一道题:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;a,b 两个变量，不用第三个变量来切换两个变量的值&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//20
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//10
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//20
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//10
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;也有奇淫技巧&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;][&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//20
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//10
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;!-- more --&gt;
&lt;p&gt;今天学到了解构赋值,那方法就更简单清晰了&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;]&lt;span style="color:#f92672"&gt;=&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//20
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;) &lt;span style="color:#75715e"&gt;//10
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;怎么样,是不是很神奇?&lt;/p&gt;
&lt;h3 id="数组的解构赋值"&gt;数组的解构赋值&lt;/h3&gt;
&lt;h4 id="什么是解构赋值"&gt;什么是解构赋值?&lt;/h4&gt;
&lt;p&gt;以前我们赋值变量是这样子的:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;foo1&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;foo2&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;foo3&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;foo1&lt;/span&gt;); &lt;span style="color:#75715e"&gt;//1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;foo2&lt;/span&gt;); &lt;span style="color:#75715e"&gt;//2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;foo3&lt;/span&gt;); &lt;span style="color:#75715e"&gt;//3
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在es6中我们可以这样:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; [&lt;span style="color:#a6e22e"&gt;foo1&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;foo2&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;foo3&lt;/span&gt;]&lt;span style="color:#f92672"&gt;=&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;foo1&lt;/span&gt;); &lt;span style="color:#75715e"&gt;//1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;foo2&lt;/span&gt;); &lt;span style="color:#75715e"&gt;//2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;foo3&lt;/span&gt;); &lt;span style="color:#75715e"&gt;//3
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;注意:左右两边格式一定要一样&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;p&gt;那如果我只想赋值一部分变量呢?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; [,,&lt;span style="color:#a6e22e"&gt;foo3&lt;/span&gt;]&lt;span style="color:#f92672"&gt;=&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;foo3&lt;/span&gt;); &lt;span style="color:#75715e"&gt;//3
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; [,&lt;span style="color:#a6e22e"&gt;foo2&lt;/span&gt;,]&lt;span style="color:#f92672"&gt;=&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;foo2&lt;/span&gt;); &lt;span style="color:#75715e"&gt;//2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;p&gt;如果相对应的位置没有值,比如说这样:&lt;/p&gt;</description></item><item><title>ES6 之变量那些事</title><link>https://time-friend.com/zh/archive/es6-variables/</link><pubDate>Wed, 15 Jul 2015 20:18:24 +0000</pubDate><guid>https://time-friend.com/zh/archive/es6-variables/</guid><description>&lt;p&gt;ES6 已经正式发布一个月了,接下来会分享一些学习笔记以及自己的理解.&lt;/p&gt;
&lt;h3 id="新增的关键字-let与const"&gt;新增的关键字 let与const&lt;/h3&gt;
&lt;p&gt;一直以来,javascript 都是用var来申明变量&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;foo&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;foo&lt;/span&gt;(); &lt;span style="color:#75715e"&gt;//1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;现在我们多了两个新的小伙伴:let与const&lt;/p&gt;
&lt;!-- more --&gt;
&lt;h3 id="let命令"&gt;let命令&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;foo&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;foo&lt;/span&gt;(); &lt;span style="color:#75715e"&gt;//1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这样看起来,与var没有什么区别,我们看接下来的例子&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;a&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// Error: a is not defined
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在 for函数里&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// 10
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// Error: i is not defined
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上面的例子说明了,let只在块级作用域里有效.而var在以上情况下,是作为一个全局变量存在的;&lt;/p&gt;
&lt;p&gt;我们再举一个例子:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;arr&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;arr&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;push&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;arr&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;]()) &lt;span style="color:#75715e"&gt;//3
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;arr&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;]()) &lt;span style="color:#75715e"&gt;//3
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;arr&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;]()) &lt;span style="color:#75715e"&gt;//3
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;数组里每一个function运行后,输出的i都是10;&lt;/p&gt;</description></item><item><title>ES6 之如何快速的做ES6练习</title><link>https://time-friend.com/zh/archive/es6-quick-start/</link><pubDate>Wed, 15 Jul 2015 19:02:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/es6-quick-start/</guid><description>&lt;p&gt;babel这个词,可翻译成通天塔，变乱塔.&lt;/p&gt;
&lt;p&gt;《圣经·旧约·创世记》&lt;/p&gt;
&lt;p&gt;第11章宣称，当时人类联合起来兴建希望能通往天堂的高塔；
为了阻止人类的计划，上帝让人类说不同的语言，
使人类相互之间不能沟通，计划因此失败，人类自此各散东西。&lt;/p&gt;
&lt;p&gt;这应该就是为什么我们的babel.js叫babel的原因;&lt;/p&gt;
&lt;h3 id="如何运行es6"&gt;如何运行es6&lt;/h3&gt;
&lt;h4 id="直接网上编译"&gt;直接网上编译&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://babeljs.io/repl/"&gt;Babel有一个REPL在线编译器，可以直接在线将ES6代码转为ES5代码。转换完成后,直接在网页里运行。&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id="引入browserjs"&gt;引入browser.js&lt;/h4&gt;
&lt;p&gt;browser.js是Babel提供的浏览器转换脚本,可以直接在浏览器中引入运行.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;注意:要在下面的script标签定义type为 &amp;ldquo;text/babel&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;html&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;lang&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;en&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style="color:#f92672"&gt;head&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;meta&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;charset&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;UTF-8&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;title&lt;/span&gt;&amp;gt;ES6 练习&amp;lt;/&lt;span style="color:#f92672"&gt;title&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;http://cdn.bootcss.com/babel-core/5.8.24/browser.js&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;head&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;body&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;type&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;text/babel&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//在这里,就可以运行你的es6代码了
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;/&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;body&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;html&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>自动化部署前端代码 - grunt-ftp-deploy的使用</title><link>https://time-friend.com/zh/archive/automated-deployment-frontend-code-grunt-ftp-deploy/</link><pubDate>Sun, 14 Jun 2015 23:36:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/automated-deployment-frontend-code-grunt-ftp-deploy/</guid><description>&lt;p&gt;每一次修改完代码之后,要部署到远程的服务器,我的操作步骤是:&lt;/p&gt;
&lt;p&gt;修改代码 &amp;ndash;&amp;gt; grunt build &amp;ndash;&amp;gt; 打开FileZilla &amp;ndash;&amp;gt;登录ftp服务器 &amp;ndash;&amp;gt;找到本地文件夹 &amp;ndash;&amp;gt; 找到远程服务器目标文件夹 &amp;ndash;&amp;gt;全选本地文件 &amp;ndash;&amp;gt; 上传&lt;/p&gt;
&lt;p&gt;因为部署代码,在某个时候会特别频繁.每一次都要重复上面的八个操作.表示要做点什么,改变一下.&lt;/p&gt;
&lt;p&gt;今天我们的主角:grunt-ftp-deploy&lt;/p&gt;
&lt;p&gt;如果是sftp可以使用grunt-sftp-deploy&lt;/p&gt;
&lt;p&gt;安装:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm install grunt-ftp-deploy --save-dev

or

npm install grunt-sftp-deploy --save-dev
&lt;/code&gt;&lt;/pre&gt;&lt;!-- more --&gt;
&lt;p&gt;在与Gruntfile文件同一目录,我们新建一个&amp;quot;.ftppass&amp;quot;的文件,
里面是ftp的授权信息,
内容如下:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;key1&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;username&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;username&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;password&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;password&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Gruntfile配置代码:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//ftp-deploy
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;grunt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;initConfig&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;ftp-deploy&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;build&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;auth&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;host&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;192.168.1.245&amp;#39;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;//ftp服务器的ip地址
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;port&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;21&lt;/span&gt;,&lt;span style="color:#75715e"&gt;//服务器端口
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;authKey&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;key1&amp;#39;&lt;/span&gt;&lt;span style="color:#75715e"&gt;//.ftppass文件里,key1的授权信息
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;path/to/source/folder&amp;#39;&lt;/span&gt;,&lt;span style="color:#75715e"&gt;//本地文件夹
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;dest&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;/path/to/destination/folder&amp;#39;&lt;/span&gt;,&lt;span style="color:#75715e"&gt;//服务器的目标文件夹
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;exclusions&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;&amp;#39;path/to/source/folder/**/.DS_Store&amp;#39;&lt;/span&gt;]&lt;span style="color:#75715e"&gt;//不上传的文件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;or&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//sftp-deploy
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;grunt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;initConfig&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;sftp-deploy&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;build&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;auth&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;host&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;192.168.1.245&amp;#39;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;//ftp服务器的ip地址
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;port&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;21&lt;/span&gt;,&lt;span style="color:#75715e"&gt;//服务器端口
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;authKey&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;key1&amp;#39;&lt;/span&gt;&lt;span style="color:#75715e"&gt;//.ftppass文件里,key1的授权信息
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;cache&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;false&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;path/to/source/folder&amp;#39;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;//本地文件夹
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;dest&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;/path/to/destination/folder&amp;#39;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;//服务器的目标文件夹
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;serverSep&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;/&amp;#39;&lt;/span&gt;,&lt;span style="color:#75715e"&gt;//服务器的相对路径
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;localSep&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;/&amp;#39;&lt;/span&gt;,&lt;span style="color:#75715e"&gt;//本地的相对路径
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;concurrency&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;,&lt;span style="color:#75715e"&gt;//每次上传多少个文件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;progress&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt; &lt;span style="color:#75715e"&gt;//是否显示进度条
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;加载task&lt;/p&gt;</description></item><item><title>烦人的AngularJS注解 - grunt-ng-annotate的使用</title><link>https://time-friend.com/zh/archive/annoying-angularjs-annotations-grunt-ng-annotate/</link><pubDate>Fri, 12 Jun 2015 23:15:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/annoying-angularjs-annotations-grunt-ng-annotate/</guid><description>&lt;p&gt;angular加入了依赖注入&lt;/p&gt;
&lt;p&gt;编写代码的时候,大致的写法如下&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;controller&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;tempController&amp;#39;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;$scope&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;$http&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;$state&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;$timeout&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;可是这样的代码,压缩后会造成一个问题.
函数的参数:$scope, $http, $state, $timeout会变成: a,b,c,d&lt;/p&gt;
&lt;p&gt;导致这个函数找不到需要注入的服务,因为每个参数的命名都是严格规定的.&lt;/p&gt;
&lt;p&gt;如下:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;controller&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;tempController&amp;#39;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;d&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;!-- more --&gt;
&lt;p&gt;为了解决这个问题,angular支持如下写法:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;controller&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;tempController&amp;#39;&lt;/span&gt;, [&lt;span style="color:#e6db74"&gt;&amp;#34;$scope&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;$http&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;$state&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;$timeout&amp;#34;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;$scope&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;$http&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;$state&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;$timeout&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }])
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;那么问题来了:&lt;/p&gt;
&lt;p&gt;每一次添加一个服务的时候,都需要写两遍.
每一次删除一个服务的时候,都需要删两遍.&lt;/p&gt;
&lt;p&gt;表示大大降低了变成的愉悦.&lt;/p&gt;
&lt;p&gt;那么我们怎么解决这个问题呢?&lt;/p&gt;
&lt;p&gt;今天的主角来了,那就是grunt-ng-annotate&lt;/p&gt;
&lt;p&gt;这是一个grunt的插件,当然在glup上也有.因为我的项目主要是用grunt写的.
那么这次主要讲grunt版本的ng-annotate.&lt;/p&gt;
&lt;p&gt;首先我们需要安装ng-annotate:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm install grunt-ng-annotate --save-dev
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在你的Gruntfile里运行这个插件:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;grunt.loadNpmTasks(&amp;#39;grunt-ng-annotate&amp;#39;);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;配置代码:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-JavaScript" data-lang="JavaScript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;grunt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;initConfig&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;ngAnnotate&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;dist&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;files&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;expand&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;cwd&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;lt;%= yeoman.dist %&amp;gt;&amp;#39;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;//相对路径
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;**/*Controller.js&amp;#39;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;//需要匹配的文件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;dest&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;lt;%= yeoman.dist %&amp;gt;&amp;#39;&lt;/span&gt; &lt;span style="color:#75715e"&gt;//文件输出的路径
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;js代码在函数里加入 &amp;ldquo;ngInject&amp;rdquo;:&lt;/p&gt;</description></item><item><title>AngularJS 指令模版</title><link>https://time-friend.com/zh/archive/angularjs-directive-template/</link><pubDate>Thu, 21 May 2015 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/angularjs-directive-template/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;myModule&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;directive&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;namespaceDirectiveName&amp;#39;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;factory&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;injectables&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;directiveDefinitionObject&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;restrict&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;string&lt;/span&gt;,&lt;span style="color:#75715e"&gt;//指令的使用方式，包括标签，属性，类，注释
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;priority&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;number&lt;/span&gt;,&lt;span style="color:#75715e"&gt;//指令执行的优先级
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;template&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;string&lt;/span&gt;,&lt;span style="color:#75715e"&gt;//指令使用的模板，用HTML字符串的形式表示
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;templateUrl&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;string&lt;/span&gt;,&lt;span style="color:#75715e"&gt;//从指定的url地址加载模板
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;replace&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bool&lt;/span&gt;,&lt;span style="color:#75715e"&gt;//是否用模板替换当前元素，若为false，则append在当前元素上
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;transclude&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bool&lt;/span&gt;,&lt;span style="color:#75715e"&gt;//是否将当前元素的内容转移到模板中
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;scope&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bool&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;or&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;object&lt;/span&gt;,&lt;span style="color:#75715e"&gt;//指定指令的作用域
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;controller&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;controllerConstructor&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;$scope&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;$element&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;$attrs&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;$transclude&lt;/span&gt;){...},&lt;span style="color:#75715e"&gt;//定义与其他指令进行交互的接口函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;string&lt;/span&gt;,&lt;span style="color:#75715e"&gt;//指定需要依赖的其他指令
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;link&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;postLink&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;scope&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;iElement&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;iAttrs&lt;/span&gt;) {...},&lt;span style="color:#75715e"&gt;//以编程的方式操作DOM，包括添加监听器等
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;compile&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;compile&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;tElement&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;tAttrs&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;transclude&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;pre&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;preLink&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;scope&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;iElement&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;iAttrs&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;controller&lt;/span&gt;){...},
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;post&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;postLink&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;scope&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;iElement&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;iAttrs&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;controller&lt;/span&gt;){...}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&lt;span style="color:#75715e"&gt;//编程的方式修改DOM模板的副本，可以返回链接函数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;directiveDefinitionObject&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>新的开始,心路历程</title><link>https://time-friend.com/zh/archive/new-beginning/</link><pubDate>Sun, 20 Jul 2014 00:00:00 +0000</pubDate><guid>https://time-friend.com/zh/archive/new-beginning/</guid><description>&lt;h2 id="2014-07-20"&gt;2014-07-20&lt;/h2&gt;
&lt;p&gt;毕业了,
学不会的,才叫学习!!!!
:)&lt;/p&gt;
&lt;h2 id="2018-11-20"&gt;2018-11-20&lt;/h2&gt;
&lt;p&gt;我们学习那么多的技术,只是为了让业务有更多的可能性,让自己的想象力有一块稳健的基石而不是胡思乱想.&lt;/p&gt;
&lt;h2 id="2018-12-16"&gt;2018-12-16&lt;/h2&gt;
&lt;p&gt;原来自己一直学习的动力,全部都来自对未来的焦虑.&lt;/p&gt;
&lt;h2 id="2018-12-28"&gt;2018-12-28&lt;/h2&gt;
&lt;p&gt;我的成长,看来是要跟时间赛跑了.&lt;/p&gt;
&lt;h2 id="2019-01-01"&gt;2019-01-01&lt;/h2&gt;
&lt;p&gt;今年的目标确立了,一共两点. 一个是英语,一个是体重~&lt;/p&gt;
&lt;h2 id="2019-01-14"&gt;2019-01-14&lt;/h2&gt;
&lt;p&gt;Bug 是团队很重要的一笔经验财富&lt;/p&gt;
&lt;h2 id="2019-01-25"&gt;2019-01-25&lt;/h2&gt;
&lt;p&gt;最近学习的动力减少了,博客也有点懒得更新了.
主要是短期目标又实现了一个,焦虑减少了.这种感觉也挺好的.&lt;/p&gt;
&lt;h2 id="2020-09-08"&gt;2020-09-08&lt;/h2&gt;
&lt;p&gt;2020年终于把脂肪甩掉了,一共减重将近40斤.
每天站在体重秤上,就知道今天该吃什么,吃多少.
养好生活习惯,体重也维持的不错.
但是英语持续背了两三个月单词,又停下来了.&lt;/p&gt;
&lt;h2 id="2021-03-04"&gt;2021-03-04&lt;/h2&gt;
&lt;p&gt;今天,我提了离职流程.心情极其复杂~
要离开这个自己亲手打造的前端团队.
去年一年时间压力极大的度过.虽然也得到了公司的认可.
但是好像也还是满足不了自己的成就感.
年纪越大,成就感越难满足.&lt;/p&gt;
&lt;h2 id="2021-07-19"&gt;2021-07-19&lt;/h2&gt;
&lt;p&gt;加入了一家新公司.三个月过去,还是很焦虑.
从来没有过三个月还没承担独立业务的.
选择是对的,只是这里压力很大.
以前我是一个很有想法的人,现在却变成了一个开发资源.&lt;/p&gt;
&lt;h2 id="2021-12-10"&gt;2021-12-10&lt;/h2&gt;
&lt;p&gt;年底一个新项目要成立新的 team,义无反顾的加入了.
可能是不甘心,也可能是想证明什么.&lt;/p&gt;
&lt;h2 id="2022-05-20"&gt;2022-05-20&lt;/h2&gt;
&lt;p&gt;又成为了新 team 的前端 leader.
但这次没有第一次那么兴奋了.
+1 是一个行业内很资深的人,一起合作很开心.
在执行上给了我很多空间.&lt;/p&gt;
&lt;h2 id="2025-03-21"&gt;2025-03-21&lt;/h2&gt;
&lt;p&gt;去年 3 月,准备开始一个 AI 项目.
Team 里遇到一个背景很强,但手段低劣的人.
最后吵了一架,项目不欢而散.&lt;/p&gt;
&lt;h2 id="2026-01-10"&gt;2026-01-10&lt;/h2&gt;
&lt;p&gt;AI 项目让我整个人都筋疲力尽,有了严重的焦虑症.
身体已经承受不住了,换了一个新的 team.&lt;/p&gt;
&lt;p&gt;最近一年,基本上是使用 AI 写代码了,每个月都要花掉几百块美金.
基本上知道目前的 AI 边界在哪里.
AI 并没有让开发更加轻松.&lt;/p&gt;</description></item></channel></rss>