<?xml version="1.0" encoding="utf-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>放牧的风</title><link>https://grazingwind.com/</link><description>全栈之路 欢迎来到我的博客</description><item><title>vue中涉及的字符串模板与dom模板</title><link>https://grazingwind.com/post/83.html</link><description>&lt;p&gt;最近看到vue官方文档的时候，多次提及字符串模板和dom模板，对这个概念比较模糊，经查阅后记录供日后参考。&lt;/p&gt;&lt;h2&gt;1. 字符串模板&lt;/h2&gt;&lt;p&gt;字符串模板就是写在vue中的template中定义的模板，如.vue的单文件组件模板和定义组件时template属性值的模板。字符串模板不会在页面初始化参与页面的渲染，会被vue进行解析编译之后再被浏览器渲染，所以不受限于html结构和标签的命名。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;Vue.component(&amp;#39;MyComponentA&amp;#39;,&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;template:&amp;nbsp;&amp;#39;&amp;lt;div&amp;nbsp;MyId=&amp;quot;123&amp;quot;&amp;gt;&amp;lt;MyComponentB&amp;gt;hello,&amp;nbsp;world&amp;lt;/MyComponentB&amp;gt;&amp;lt;/div&amp;gt;&amp;#39;
})
&amp;lt;div&amp;nbsp;id=&amp;quot;app&amp;quot;&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MyComponentA&amp;gt;&amp;lt;/MyComponentA&amp;gt;
&amp;lt;/div&amp;gt;&lt;/pre&gt;&lt;h2&gt;2. dom模板(或者称为Html模板)&lt;/h2&gt;&lt;p&gt;dom模板就是写在html文件中，一打开就会被浏览器进行解析渲染的，所以要遵循html结构和标签的命名，否则浏览器不解析也就不能获取内容了。&lt;/p&gt;&lt;p&gt;下面的例子不会被正确渲染, 会被解析成mycomponent,但是注册的vue的组件是MyComponent，因此无法渲染。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-markup&quot;&gt;&amp;lt;!DOCTYPE&amp;gt;
&amp;lt;html&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;head&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;meta&amp;nbsp;charset=&amp;quot;utf-8&amp;quot;&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;title&amp;gt;Vue&amp;nbsp;Component&amp;lt;/title&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/head&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;body&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;nbsp;id=&amp;quot;app&amp;quot;&amp;gt;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Hello&amp;nbsp;Vue&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MyComponent&amp;gt;&amp;lt;/MyComponent&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/div&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;script&amp;nbsp;src=&amp;quot;https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;script&amp;nbsp;&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//全局注册
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Vue.component(&amp;#39;MyComponent&amp;#39;,&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;template:&amp;nbsp;&amp;#39;&amp;lt;div&amp;gt;组件类容&amp;lt;/div&amp;gt;&amp;#39;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;new&amp;nbsp;Vue&amp;nbsp;({
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;el:&amp;nbsp;&amp;#39;#app&amp;#39;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/script&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/pre&gt;&lt;p&gt;所以，下面的例子就可以正常显示了：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-markup&quot;&gt;&amp;lt;!DOCTYPE&amp;gt;
&amp;lt;html&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;head&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;meta&amp;nbsp;charset=&amp;quot;utf-8&amp;quot;&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;title&amp;gt;Vue&amp;nbsp;Component&amp;lt;/title&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/head&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;body&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;div&amp;nbsp;id=&amp;quot;app&amp;quot;&amp;gt;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Hello&amp;nbsp;Vue&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;my-component&amp;gt;&amp;lt;/my-component&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/div&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;script&amp;nbsp;src=&amp;quot;https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;script&amp;nbsp;&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//全局注册
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Vue.component(&amp;#39;my-component&amp;#39;,&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;template:&amp;nbsp;&amp;#39;&amp;lt;div&amp;gt;组件类容&amp;lt;/div&amp;gt;&amp;#39;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;new&amp;nbsp;Vue&amp;nbsp;({
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;el:&amp;nbsp;&amp;#39;#app&amp;#39;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/script&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/pre&gt;&lt;p&gt;因为html对大小写不敏感，所以在DOM模板中使用组件必须使用kebab-case命名法(短横线命名)。&lt;/p&gt;&lt;p&gt;因此,对于组件名称的命名，可参考如下实现：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-markup&quot;&gt;/*--&amp;nbsp;在单文件组件、JSX和字符串模板中&amp;nbsp;--*/
&amp;lt;MyComponent/&amp;gt;

/*--&amp;nbsp;在&amp;nbsp;DOM&amp;nbsp;模板中&amp;nbsp;--*/
&amp;lt;my-component&amp;gt;&amp;lt;/my-component&amp;gt;

/*--&amp;nbsp;在所有地方&amp;nbsp;--*/
&amp;lt;my-component&amp;gt;&amp;lt;/my-component&amp;gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Fri, 01 Apr 2022 20:17:23 +0800</pubDate></item><item><title>CentOS下文件/文件夹的压缩和解压命令用法详解</title><link>https://grazingwind.com/post/82.html</link><description>&lt;p&gt;tar功能：文件的压缩或解压&lt;/p&gt;&lt;p&gt;语法：tar 命令&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;-c 建立一个压缩文件的参数指令（create） –压缩&lt;br style=&quot;margin: 0px; padding: 0px; list-style: none; box-sizing: border-box; word-break: break-all;&quot;/&gt;-x 解开一个压缩文件的参数指令（extract） –解压&lt;br style=&quot;margin: 0px; padding: 0px; list-style: none; box-sizing: border-box; word-break: break-all;&quot;/&gt;-z 是否需要gzip压缩&lt;br style=&quot;margin: 0px; padding: 0px; list-style: none; box-sizing: border-box; word-break: break-all;&quot;/&gt;-v 显示压缩的过程（verbose）&lt;br style=&quot;margin: 0px; padding: 0px; list-style: none; box-sizing: border-box; word-break: break-all;&quot;/&gt;-f 使用档名，在f之后要立即接档名（file）&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;压缩：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;tar&amp;nbsp;-zcvf&amp;nbsp;文件名&amp;nbsp;压缩路径&lt;/pre&gt;&lt;p&gt;解压：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;tar&amp;nbsp;-zxvf&amp;nbsp;文件名&lt;/pre&gt;&lt;p&gt;示例：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;tar&amp;nbsp;-zcvf&amp;nbsp;文件名.tar.gz&amp;nbsp;要压缩文件路径&lt;/pre&gt;&lt;p&gt;解压缩&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;tar&amp;nbsp;-zxvf&amp;nbsp;要解压的文件.tar.gz&lt;/pre&gt;&lt;p&gt;这个命令是解压到当前文件夹&lt;/p&gt;&lt;p&gt;解压到指定目录中（该目录需要存在）需要添加-C参数&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;tar&amp;nbsp;-zxvf&amp;nbsp;要解压的文件.tar.gz&amp;nbsp;-C&amp;nbsp;指定目录路径&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Wed, 23 Feb 2022 15:02:27 +0800</pubDate></item><item><title>vscode中的jsconfig.json文件首行无故报错</title><link>https://grazingwind.com/post/81.html</link><description>&lt;h2&gt;问题&lt;/h2&gt;&lt;p&gt;在vscode中，我们配置完jsconfig.json文件后可能会报错。&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;分析&lt;/h2&gt;&lt;p&gt;vscode会自动进行JavaScript文件的语义检查。因为自定义的jsconfig.json文件无法覆盖vscode自带的配置，所以会报错。&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2&gt;解决方法&lt;/h2&gt;&lt;p&gt;打开配置settings.json文件，让自定义的jsconfig.js文件覆盖vscode默认选项&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;img class=&quot;ue-image&quot; src=&quot;https://grazingwind.com/zb_users/upload/2022/02/202202081644313141917656.jpg&quot; title=&quot;20220208173637.jpg&quot; alt=&quot;20220208173637.jpg&quot;/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Tue, 08 Feb 2022 17:35:29 +0800</pubDate></item><item><title>tsconfig.json配置说明</title><link>https://grazingwind.com/post/80.html</link><description>&lt;p&gt;在 TypeScript 开发中，tsconfig.json 是个不可或缺的配置文件，它是我们在 TS 项目中最常见的配置文件，那么你真的了解这个文件吗？它里面都有哪些优秀配置？如何配置一个合理的 tsconfig.json 文件？本文将全面带大家一起详细了解 tsconfig.json 的各项配置。&lt;/p&gt;&lt;p&gt;本文将从以下几个方面全面介绍 tsconfig.json 文件：&lt;/p&gt;&lt;p&gt;&amp;nbsp; &lt;img src=&quot;https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/27af569d139b4e22b4bd10c57fd210d6~tplv-k3u1fbpfcp-watermark.awebp&quot; alt=&quot;了不起的 tsconfig.json 指南.png&quot; loading=&quot;lazy&quot;/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;水平有限，欢迎各位大佬指点~~&lt;/p&gt;&lt;h2 data-id=&quot;heading-0&quot;&gt;一、tsconfig.json 简介&lt;/h2&gt;&lt;h3 data-id=&quot;heading-1&quot;&gt;1. 什么是 tsconfig.json&lt;/h3&gt;&lt;p&gt;TypeScript 使用 tsconfig.json 文件作为其配置文件，当一个目录中存在 tsconfig.json 文件，则认为该目录为 TypeScript 项目的根目录。&lt;/p&gt;&lt;p&gt;通常 tsconfig.json 文件主要包含两部分内容：指定待编译文件和定义编译选项。&lt;/p&gt;&lt;p&gt;从《&lt;a href=&quot;https://link.juejin.cn?target=http%3A%2F%2Fjson.schemastore.org%2Ftsconfig&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot; title=&quot;http://json.schemastore.org/tsconfig&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;TypeScript编译器的配置文件的JSON模式&lt;/a&gt;》可知，目前 tsconfig.json 文件有以下几个顶层属性：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot; style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;p&gt;compileOnSave&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;compilerOptions&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;exclude&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;extends&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;files&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;include&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;references&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;typeAcquisition&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;文章后面会详细介绍一些常用属性配置。&lt;/p&gt;&lt;h3 data-id=&quot;heading-2&quot;&gt;2. 为什么使用 tsconfig.json&lt;/h3&gt;&lt;p&gt;通常我们可以使用 &lt;code&gt;tsc&lt;/code&gt;&amp;nbsp;命令来编译少量 TypeScript 文件：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-powershell&quot;&gt;/*
&amp;nbsp;&amp;nbsp;参数介绍：
&amp;nbsp;&amp;nbsp;--outFile&amp;nbsp;//&amp;nbsp;编译后生成的文件名称
&amp;nbsp;&amp;nbsp;--target&amp;nbsp;&amp;nbsp;//&amp;nbsp;指定ECMAScript目标版本
&amp;nbsp;&amp;nbsp;--module&amp;nbsp;&amp;nbsp;//&amp;nbsp;指定生成哪个模块系统代码
&amp;nbsp;&amp;nbsp;index.ts&amp;nbsp;&amp;nbsp;//&amp;nbsp;源文件
*/
$&amp;nbsp;tsc&amp;nbsp;--outFile&amp;nbsp;leo.js&amp;nbsp;--target&amp;nbsp;es3&amp;nbsp;--module&amp;nbsp;amd&amp;nbsp;index.ts&lt;/pre&gt;&lt;p&gt;但如果实际开发的项目，很少是只有单个文件，当我们需要编译整个项目时，就可以使用 tsconfig.json 文件，&lt;strong&gt;将需要使用到的配置都写进 tsconfig.json 文件，这样就不用每次编译都手动输入配置，另外也方便团队协作开发。&lt;/strong&gt;&lt;/p&gt;&lt;h2 data-id=&quot;heading-3&quot;&gt;二、使用 tsconfig.json&lt;/h2&gt;&lt;p&gt;目前使用 tsconfig.json 有2种操作：&lt;/p&gt;&lt;h3 data-id=&quot;heading-4&quot;&gt;1. 初始化 tsconfig.json&lt;/h3&gt;&lt;p&gt;在初始化操作，也有 2 种方式：&lt;/p&gt;&lt;ol class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;手动在项目根目录（或其他）创建 tsconfig.json 文件并填写配置；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;通过 &lt;code&gt;tsc --init&lt;/code&gt;&amp;nbsp;初始化 tsconfig.json 文件。&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h3 data-id=&quot;heading-5&quot;&gt;2. 指定需要编译的目录&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;在不指定输入文件的情况下&lt;/strong&gt;执行 &lt;code&gt;tsc&lt;/code&gt;&amp;nbsp;命令，默认从当前目录开始编译，编译所有 &lt;code&gt;.ts&lt;/code&gt;&amp;nbsp;文件，并且从当前目录开始查找 tsconfig.json 文件，并逐级向上级目录搜索。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-powershell&quot;&gt;$&amp;nbsp;tsc&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;另外也可以为 &lt;code&gt;tsc&lt;/code&gt; 命令指定参数 &lt;code&gt;--project&lt;/code&gt; 或 &lt;code&gt;-p&lt;/code&gt; 指定需要编译的目录，该目录需要包含一个 tsconfig.json 文件，如：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-powershell&quot;&gt;/*
&amp;nbsp;&amp;nbsp;文件目录：
&amp;nbsp;&amp;nbsp;├─src/
&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;├─index.ts
&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;└─tsconfig.json
&amp;nbsp;&amp;nbsp;├─package.json
*/
$&amp;nbsp;tsc&amp;nbsp;--project&amp;nbsp;src&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;注意，tsc 的命令行选项具有优先级，会覆盖 tsconfig.json 中的同名选项。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;更多 tsc 编译选项，可查看&lt;a href=&quot;https://link.juejin.cn?target=https%3A%2F%2Fwww.tslang.cn%2Fdocs%2Fhandbook%2Fcompiler-options.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot; title=&quot;https://www.tslang.cn/docs/handbook/compiler-options.html&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;《编译选项》&lt;/a&gt;章节。&lt;/p&gt;&lt;h2 data-id=&quot;heading-6&quot;&gt;三、使用示例&lt;/h2&gt;&lt;p&gt;这个章节，我们将通过本地一个小项目 &lt;code&gt;learnTsconfig&lt;/code&gt;&amp;nbsp;来学着实现一个简单配置。&lt;/p&gt;&lt;p&gt;当前开发环境：windows / node 10.15.1 / TypeScript3.9&lt;/p&gt;&lt;h3 data-id=&quot;heading-7&quot;&gt;1. 初始化 learnTsconfig 项目&lt;/h3&gt;&lt;p&gt;执行下面命令：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-powershell&quot;&gt;$&amp;nbsp;mkdir&amp;nbsp;learnTsconfig
$&amp;nbsp;cd&amp;nbsp;.\learnTsconfig\
$&amp;nbsp;mkdir&amp;nbsp;src
$&amp;nbsp;new-item&amp;nbsp;index.ts&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;并且我们为 index.ts 文件写一些简单代码：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-typescript&quot;&gt;//&amp;nbsp;返回当前版本号
function&amp;nbsp;getVersion(version:string&amp;nbsp;=&amp;nbsp;&amp;quot;1.0.0&amp;quot;):&amp;nbsp;string{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;version;
}

console.log(getVersion(&amp;quot;1.0.1&amp;quot;))&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;我们将获得这么一个目录结构：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-powershell&quot;&gt;&amp;nbsp;&amp;nbsp;└─src/
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;└─index.ts&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3 data-id=&quot;heading-8&quot;&gt;2. 初始化 tsconfig.json 文件&lt;/h3&gt;&lt;p&gt;在 learnTsconfig 根目录执行：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-powershell&quot;&gt;$&amp;nbsp;tsc&amp;nbsp;--init&lt;/pre&gt;&lt;h3 data-id=&quot;heading-9&quot;&gt;3. 修改 tsconfig.json 文件&lt;/h3&gt;&lt;p&gt;我们设置几个常见配置项：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-typescript&quot;&gt;{
&amp;nbsp;&amp;nbsp;&amp;quot;compilerOptions&amp;quot;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;target&amp;quot;:&amp;nbsp;&amp;quot;ES5&amp;quot;,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;目标语言的版本
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;module&amp;quot;:&amp;nbsp;&amp;quot;commonjs&amp;quot;,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;指定生成代码的模板标准
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;noImplicitAny&amp;quot;:&amp;nbsp;true,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;不允许隐式的&amp;nbsp;any&amp;nbsp;类型
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;removeComments&amp;quot;:&amp;nbsp;true,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;删除注释&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;preserveConstEnums&amp;quot;:&amp;nbsp;true,&amp;nbsp;&amp;nbsp;//&amp;nbsp;保留&amp;nbsp;const&amp;nbsp;和&amp;nbsp;enum&amp;nbsp;声明
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;sourceMap&amp;quot;:&amp;nbsp;true&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;生成目标文件的sourceMap文件
&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;quot;files&amp;quot;:&amp;nbsp;[&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;指定待编译文件
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;./src/index.ts&amp;quot;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;]
}&lt;/pre&gt;&lt;p&gt;其中需要注意一点： &lt;code&gt;files&lt;/code&gt;&amp;nbsp;配置项值是一个&lt;strong&gt;数组&lt;/strong&gt;，用来指定了待编译文件，即&lt;strong&gt;入口文件&lt;/strong&gt;。&lt;br/&gt;当入口文件依赖其他文件时，不需要将被依赖文件也指定到 &lt;code&gt;files&lt;/code&gt;&amp;nbsp;中，因为&lt;strong&gt;编译器会自动将所有的依赖文件归纳为编译对象&lt;/strong&gt;，即 &lt;code&gt;index.ts&lt;/code&gt;&amp;nbsp;依赖 &lt;code&gt;user.ts&lt;/code&gt;&amp;nbsp;时，不需要在 &lt;code&gt;files&lt;/code&gt;&amp;nbsp;中指定 &lt;code&gt;user.ts&lt;/code&gt;&amp;nbsp;， &lt;code&gt;user.ts&lt;/code&gt;&amp;nbsp;会自动纳入待编译文件。&lt;/p&gt;&lt;h3 data-id=&quot;heading-10&quot;&gt;4. 执行编译&lt;/h3&gt;&lt;p&gt;配置完成后，我们可以在命令行执行 &lt;code&gt;tsc&lt;/code&gt;&amp;nbsp;命令，执行编译完成后，我们可以得到一个 &lt;code&gt;index.js&lt;/code&gt;&amp;nbsp;文件和一个 &lt;code&gt;index.js.map&lt;/code&gt;&amp;nbsp;文件，证明我们编译成功，其中 &lt;code&gt;index.js&lt;/code&gt;&amp;nbsp;文件内容如下：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-typescript&quot;&gt;function&amp;nbsp;getVersion(version)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(version&amp;nbsp;===&amp;nbsp;void&amp;nbsp;0)&amp;nbsp;{&amp;nbsp;version&amp;nbsp;=&amp;nbsp;&amp;quot;1.0.0&amp;quot;;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;version;
}
console.log(getVersion(&amp;quot;1.0.1&amp;quot;));
//#&amp;nbsp;sourceMappingURL=index.js.map&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;可以看出，tsconfig.json 中的 &lt;code&gt;removeComments&lt;/code&gt;&amp;nbsp;配置生效了，将我们添加的注释代码移除了。&lt;/p&gt;&lt;p&gt;到这一步，就完成了这个简单的示例，接下来会基于这个示例代码，讲解《七、常见配置示例》。&lt;/p&gt;&lt;h2 data-id=&quot;heading-11&quot;&gt;四、tsconfig.json 文件结构介绍&lt;/h2&gt;&lt;h3 data-id=&quot;heading-12&quot;&gt;1. 按顶层属性分类&lt;/h3&gt;&lt;p&gt;在 tsconfig.json 文件中按照&lt;strong&gt;顶层属性&lt;/strong&gt;，分为以下几类：&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/396b6737cab94abbb37cfb7e68f299ee~tplv-k3u1fbpfcp-watermark.awebp&quot; alt=&quot;tsconfig.json 文件结构（顶层属性）.png&quot; loading=&quot;lazy&quot;/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7accce7b33b44d57bb5901151a6677a8~tplv-k3u1fbpfcp-watermark.awebp&quot; alt=&quot;了不起的 tsconfig.json 指南.png&quot; loading=&quot;lazy&quot;/&gt;&lt;/p&gt;&lt;h3 data-id=&quot;heading-13&quot;&gt;2. 按功能分类&lt;/h3&gt;&lt;p&gt;&lt;img src=&quot;https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b3f1a621181a49ae8b646c9ba83280f9~tplv-k3u1fbpfcp-watermark.awebp&quot; alt=&quot;tsconfig.json 文件结构（功能）.png&quot; loading=&quot;lazy&quot;/&gt;&lt;/p&gt;&lt;h2 data-id=&quot;heading-14&quot;&gt;五、tsconfig.json 配置介绍&lt;/h2&gt;&lt;h3 data-id=&quot;heading-15&quot;&gt;1. compileOnSave&lt;/h3&gt;&lt;p&gt;&lt;code&gt;compileOnSave&lt;/code&gt;&amp;nbsp;属性作用是&lt;strong&gt;设置保存文件的时候自动编译，但需要编译器支持&lt;/strong&gt;。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-typescript&quot;&gt;{
	//&amp;nbsp;...
&amp;nbsp;&amp;nbsp;&amp;quot;compileOnSave&amp;quot;:&amp;nbsp;false,
}&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3 data-id=&quot;heading-16&quot;&gt;2.&amp;nbsp;compilerOptions&lt;/h3&gt;&lt;p&gt;&lt;code&gt;compilerOptions&lt;/code&gt;&amp;nbsp;属性作用是&lt;strong&gt;配置编译选项&lt;/strong&gt;。&lt;/p&gt;&lt;p&gt;若 &lt;code&gt;compilerOptions&lt;/code&gt; 属性被忽略，则编译器会使用默认值，可以查看&lt;a href=&quot;https://link.juejin.cn?target=https%3A%2F%2Fwww.typescriptlang.org%2Fdocs%2Fhandbook%2Fcompiler-options.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot; title=&quot;https://www.typescriptlang.org/docs/handbook/compiler-options.html&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;《官方完整的编译选项列表》&lt;/a&gt;。&lt;/p&gt;&lt;p&gt;编译选项配置非常繁杂，有很多配置，这里只列出常用的配置。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-typescript&quot;&gt;{
&amp;nbsp;&amp;nbsp;//&amp;nbsp;...
&amp;nbsp;&amp;nbsp;&amp;quot;compilerOptions&amp;quot;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;incremental&amp;quot;:&amp;nbsp;true,&amp;nbsp;//&amp;nbsp;TS编译器在第一次编译之后会生成一个存储编译信息的文件，第二次编译会在第一次的基础上进行增量编译，可以提高编译的速度
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;tsBuildInfoFile&amp;quot;:&amp;nbsp;&amp;quot;./buildFile&amp;quot;,&amp;nbsp;//&amp;nbsp;增量编译文件的存储位置
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;diagnostics&amp;quot;:&amp;nbsp;true,&amp;nbsp;//&amp;nbsp;打印诊断信息&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;target&amp;quot;:&amp;nbsp;&amp;quot;ES5&amp;quot;,&amp;nbsp;//&amp;nbsp;目标语言的版本
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;module&amp;quot;:&amp;nbsp;&amp;quot;CommonJS&amp;quot;,&amp;nbsp;//&amp;nbsp;生成代码的模板标准
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;outFile&amp;quot;:&amp;nbsp;&amp;quot;./app.js&amp;quot;,&amp;nbsp;//&amp;nbsp;将多个相互依赖的文件生成一个文件，可以用在AMD模块中，即开启时应设置&amp;quot;module&amp;quot;:&amp;nbsp;&amp;quot;AMD&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;lib&amp;quot;:&amp;nbsp;[&amp;quot;DOM&amp;quot;,&amp;nbsp;&amp;quot;ES2015&amp;quot;,&amp;nbsp;&amp;quot;ScriptHost&amp;quot;,&amp;nbsp;&amp;quot;ES2019.Array&amp;quot;],&amp;nbsp;//&amp;nbsp;TS需要引用的库，即声明文件，es5&amp;nbsp;默认引用dom、es5、scripthost,如需要使用es的高级版本特性，通常都需要配置，如es8的数组新特性需要引入&amp;quot;ES2019.Array&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;allowJS&amp;quot;:&amp;nbsp;true,&amp;nbsp;//&amp;nbsp;允许编译器编译JS，JSX文件
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;checkJs&amp;quot;:&amp;nbsp;true,&amp;nbsp;//&amp;nbsp;允许在JS文件中报错，通常与allowJS一起使用
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;outDir&amp;quot;:&amp;nbsp;&amp;quot;./dist&amp;quot;,&amp;nbsp;//&amp;nbsp;指定输出目录
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;rootDir&amp;quot;:&amp;nbsp;&amp;quot;./&amp;quot;,&amp;nbsp;//&amp;nbsp;指定输出文件目录(用于输出)，用于控制输出目录结构
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;declaration&amp;quot;:&amp;nbsp;true,&amp;nbsp;//&amp;nbsp;生成声明文件，开启后会自动生成声明文件
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;declarationDir&amp;quot;:&amp;nbsp;&amp;quot;./file&amp;quot;,&amp;nbsp;//&amp;nbsp;指定生成声明文件存放目录
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;emitDeclarationOnly&amp;quot;:&amp;nbsp;true,&amp;nbsp;//&amp;nbsp;只生成声明文件，而不会生成js文件
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;sourceMap&amp;quot;:&amp;nbsp;true,&amp;nbsp;//&amp;nbsp;生成目标文件的sourceMap文件
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;inlineSourceMap&amp;quot;:&amp;nbsp;true,&amp;nbsp;//&amp;nbsp;生成目标文件的inline&amp;nbsp;SourceMap，inline&amp;nbsp;SourceMap会包含在生成的js文件中
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;declarationMap&amp;quot;:&amp;nbsp;true,&amp;nbsp;//&amp;nbsp;为声明文件生成sourceMap
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;typeRoots&amp;quot;:&amp;nbsp;[],&amp;nbsp;//&amp;nbsp;声明文件目录，默认时node_modules/@types
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;types&amp;quot;:&amp;nbsp;[],&amp;nbsp;//&amp;nbsp;加载的声明文件包
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;removeComments&amp;quot;:true,&amp;nbsp;//&amp;nbsp;删除注释&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;noEmit&amp;quot;:&amp;nbsp;true,&amp;nbsp;//&amp;nbsp;不输出文件,即编译后不会生成任何js文件
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;noEmitOnError&amp;quot;:&amp;nbsp;true,&amp;nbsp;//&amp;nbsp;发送错误时不输出任何文件
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;noEmitHelpers&amp;quot;:&amp;nbsp;true,&amp;nbsp;//&amp;nbsp;不生成helper函数，减小体积，需要额外安装，常配合importHelpers一起使用
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;importHelpers&amp;quot;:&amp;nbsp;true,&amp;nbsp;//&amp;nbsp;通过tslib引入helper函数，文件必须是模块
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;downlevelIteration&amp;quot;:&amp;nbsp;true,&amp;nbsp;//&amp;nbsp;降级遍历器实现，如果目标源是es3/5，那么遍历器会有降级的实现
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;strict&amp;quot;:&amp;nbsp;true,&amp;nbsp;//&amp;nbsp;开启所有严格的类型检查
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;alwaysStrict&amp;quot;:&amp;nbsp;true,&amp;nbsp;//&amp;nbsp;在代码中注入&amp;#39;use&amp;nbsp;strict&amp;#39;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;noImplicitAny&amp;quot;:&amp;nbsp;true,&amp;nbsp;//&amp;nbsp;不允许隐式的any类型
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;strictNullChecks&amp;quot;:&amp;nbsp;true,&amp;nbsp;//&amp;nbsp;不允许把null、undefined赋值给其他类型的变量
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;strictFunctionTypes&amp;quot;:&amp;nbsp;true,&amp;nbsp;//&amp;nbsp;不允许函数参数双向协变
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;strictPropertyInitialization&amp;quot;:&amp;nbsp;true,&amp;nbsp;//&amp;nbsp;类的实例属性必须初始化
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;strictBindCallApply&amp;quot;:&amp;nbsp;true,&amp;nbsp;//&amp;nbsp;严格的bind/call/apply检查
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;noImplicitThis&amp;quot;:&amp;nbsp;true,&amp;nbsp;//&amp;nbsp;不允许this有隐式的any类型
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;noUnusedLocals&amp;quot;:&amp;nbsp;true,&amp;nbsp;//&amp;nbsp;检查只声明、未使用的局部变量(只提示不报错)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;noUnusedParameters&amp;quot;:&amp;nbsp;true,&amp;nbsp;//&amp;nbsp;检查未使用的函数参数(只提示不报错)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;noFallthroughCasesInSwitch&amp;quot;:&amp;nbsp;true,&amp;nbsp;//&amp;nbsp;防止switch语句贯穿(即如果没有break语句后面不会执行)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;noImplicitReturns&amp;quot;:&amp;nbsp;true,&amp;nbsp;//每个分支都会有返回值
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;esModuleInterop&amp;quot;:&amp;nbsp;true,&amp;nbsp;//&amp;nbsp;允许export=导出，由import&amp;nbsp;from&amp;nbsp;导入
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;allowUmdGlobalAccess&amp;quot;:&amp;nbsp;true,&amp;nbsp;//&amp;nbsp;允许在模块中全局变量的方式访问umd模块
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;moduleResolution&amp;quot;:&amp;nbsp;&amp;quot;node&amp;quot;,&amp;nbsp;//&amp;nbsp;模块解析策略，ts默认用node的解析策略，即相对的方式导入
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;baseUrl&amp;quot;:&amp;nbsp;&amp;quot;./&amp;quot;,&amp;nbsp;//&amp;nbsp;解析非相对模块的基地址，默认是当前目录
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;paths&amp;quot;:&amp;nbsp;{&amp;nbsp;//&amp;nbsp;路径映射，相对于baseUrl
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;如使用jq时不想使用默认版本，而需要手动指定版本，可进行如下配置
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;jquery&amp;quot;:&amp;nbsp;[&amp;quot;node_modules/jquery/dist/jquery.min.js&amp;quot;]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;rootDirs&amp;quot;:&amp;nbsp;[&amp;quot;src&amp;quot;,&amp;quot;out&amp;quot;],&amp;nbsp;//&amp;nbsp;将多个目录放在一个虚拟目录下，用于运行时，即编译后引入文件的位置可能发生变化，这也设置可以虚拟src和out在同一个目录下，不用再去改变路径也不会报错
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;listEmittedFiles&amp;quot;:&amp;nbsp;true,&amp;nbsp;//&amp;nbsp;打印输出文件
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;listFiles&amp;quot;:&amp;nbsp;true//&amp;nbsp;打印编译的文件(包括引用的声明文件)
&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3 data-id=&quot;heading-17&quot;&gt;3.&amp;nbsp;exclude&lt;/h3&gt;&lt;p&gt;&lt;code&gt;exclude&lt;/code&gt;&amp;nbsp;属性作用是&lt;strong&gt;指定编译器需要排除的文件或文件夹&lt;/strong&gt;。&lt;/p&gt;&lt;p&gt;默认排除 &lt;code&gt;node_modules&lt;/code&gt;&amp;nbsp;文件夹下文件。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-typescript&quot;&gt;{
	//&amp;nbsp;...
&amp;nbsp;&amp;nbsp;&amp;quot;exclude&amp;quot;:&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;src/lib&amp;quot;&amp;nbsp;//&amp;nbsp;排除src目录下的lib文件夹下的文件不会编译
&amp;nbsp;&amp;nbsp;]
}&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;和 &lt;code&gt;include&lt;/code&gt;&amp;nbsp;属性一样，支持 glob 通配符：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot; style=&quot;list-style-type: square;&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;code&gt;*&lt;/code&gt; 匹配0或多个字符（不包括目录分隔符）&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; 递归匹配任意子目录&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3 data-id=&quot;heading-18&quot;&gt;4.&amp;nbsp;extends&lt;/h3&gt;&lt;p&gt;&lt;code&gt;extends&lt;/code&gt;&amp;nbsp;属性作用是&lt;strong&gt;引入其他配置文件，继承配置&lt;/strong&gt;。&lt;/p&gt;&lt;p&gt;默认包含当前目录和子目录下所有 TypeScript 文件。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-typescript&quot;&gt;{
	//&amp;nbsp;...
&amp;nbsp;&amp;nbsp;//&amp;nbsp;把基础配置抽离成tsconfig.base.json文件，然后引入
	&amp;quot;extends&amp;quot;:&amp;nbsp;&amp;quot;./tsconfig.base.json&amp;quot;
}&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3 data-id=&quot;heading-19&quot;&gt;5.&amp;nbsp;files&lt;/h3&gt;&lt;p&gt;&lt;code&gt;files&lt;/code&gt;&amp;nbsp;属性作用是&lt;strong&gt;指定需要编译的单个文件列表&lt;/strong&gt;。&lt;/p&gt;&lt;p&gt;默认包含当前目录和子目录下所有 TypeScript 文件。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-typescript&quot;&gt;{
	//&amp;nbsp;...
&amp;nbsp;&amp;nbsp;&amp;quot;files&amp;quot;:&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;指定编译文件是src目录下的leo.ts文件
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;scr/leo.ts&amp;quot;
&amp;nbsp;&amp;nbsp;]
}&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3 data-id=&quot;heading-20&quot;&gt;6.&amp;nbsp;include&lt;/h3&gt;&lt;p&gt;&lt;code&gt;include&lt;/code&gt;&amp;nbsp;属性作用是&lt;strong&gt;指定编译需要编译的文件或目录&lt;/strong&gt;。&lt;/p&gt;&lt;pre&gt;{
	//&amp;nbsp;...
&amp;nbsp;&amp;nbsp;&amp;quot;include&amp;quot;:&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;&amp;quot;scr&amp;quot;&amp;nbsp;//&amp;nbsp;会编译src目录下的所有文件，包括子目录
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;&amp;quot;scr/*&amp;quot;&amp;nbsp;//&amp;nbsp;只会编译scr一级目录下的文件
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;scr/*/*&amp;quot;&amp;nbsp;//&amp;nbsp;只会编译scr二级目录下的文件
&amp;nbsp;&amp;nbsp;]
}&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3 data-id=&quot;heading-21&quot;&gt;7.&amp;nbsp;references&lt;/h3&gt;&lt;p&gt;&lt;code&gt;references&lt;/code&gt;&amp;nbsp;属性作用是&lt;strong&gt;指定工程引用依赖。&lt;/strong&gt; 在项目开发中，有时候我们为了方便将前端项目和后端&lt;code&gt;node&lt;/code&gt;项目放在同一个目录下开发，两个项目依赖同一个配置文件和通用文件，但我们希望前后端项目进行灵活的分别打包，那么我们可以进行如下配置：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-typescript&quot;&gt;{
	//&amp;nbsp;...
&amp;nbsp;&amp;nbsp;&amp;quot;references&amp;quot;:&amp;nbsp;[&amp;nbsp;//&amp;nbsp;指定依赖的工程
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;quot;path&amp;quot;:&amp;nbsp;&amp;quot;./common&amp;quot;}
&amp;nbsp;&amp;nbsp;]
}&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3 data-id=&quot;heading-22&quot;&gt;8.&amp;nbsp;typeAcquisition&lt;/h3&gt;&lt;p&gt;&lt;code&gt;typeAcquisition&lt;/code&gt;&amp;nbsp;属性作用是&lt;strong&gt;设置自动引入库类型定义文件(.d.ts)相关。&lt;/strong&gt; 包含 3 个子属性：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;code&gt;enable&lt;/code&gt;&amp;nbsp; : 布尔类型，是否开启自动引入库类型定义文件(.d.ts)，默认为 false；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code&gt;include&lt;/code&gt;&amp;nbsp; : 数组类型，允许自动引入的库名，如：[&amp;quot;jquery&amp;quot;, &amp;quot;lodash&amp;quot;]；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code&gt;exculde&lt;/code&gt;&amp;nbsp; : 数组类型，排除的库名。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre class=&quot;prism-highlight prism-language-typescript&quot;&gt;{
	//&amp;nbsp;...
&amp;nbsp;&amp;nbsp;&amp;quot;references&amp;quot;:&amp;nbsp;[&amp;nbsp;//&amp;nbsp;指定依赖的工程
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;quot;path&amp;quot;:&amp;nbsp;&amp;quot;./common&amp;quot;}
&amp;nbsp;&amp;nbsp;]
}&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2 data-id=&quot;heading-23&quot;&gt;六、常见配置示例&lt;/h2&gt;&lt;p&gt;本部分内容中，我们找了几个实际开发中比较常见的配置，当然，还有很多配置需要自己摸索哟~~&lt;/p&gt;&lt;h3 data-id=&quot;heading-24&quot;&gt;1. 移除代码中注释&lt;/h3&gt;&lt;p&gt;tsconfig.json：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-typescript&quot;&gt;{
&amp;nbsp;&amp;nbsp;&amp;quot;compilerOptions&amp;quot;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;removeComments&amp;quot;:&amp;nbsp;true,
&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;编译前：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-typescript&quot;&gt;//&amp;nbsp;返回当前版本号
function&amp;nbsp;getVersion(version:string&amp;nbsp;=&amp;nbsp;&amp;quot;1.0.0&amp;quot;):&amp;nbsp;string{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;version;
}
console.log(getVersion(&amp;quot;1.0.1&amp;quot;))&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;编译结果：&lt;/p&gt;&lt;pre&gt;function&amp;nbsp;getVersion(version)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(version&amp;nbsp;===&amp;nbsp;void&amp;nbsp;0)&amp;nbsp;{&amp;nbsp;version&amp;nbsp;=&amp;nbsp;&amp;quot;1.0.0&amp;quot;;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;version;
}
console.log(getVersion(&amp;quot;1.0.1&amp;quot;));&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3 data-id=&quot;heading-25&quot;&gt;2. 开启null、undefined检测&lt;/h3&gt;&lt;p&gt;tsconfig.json：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-typescript&quot;&gt;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;compilerOptions&amp;quot;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;strictNullChecks&amp;quot;:&amp;nbsp;true
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
}&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;修改 &lt;code&gt;index.ts&lt;/code&gt;&amp;nbsp;文件内容：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-typescript&quot;&gt;const&amp;nbsp;leo;
leo&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Pingan(&amp;#39;leo&amp;#39;,&amp;#39;hello&amp;#39;);&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;这时候编辑器也会提示错误信息，执行 &lt;code&gt;tsc&lt;/code&gt;&amp;nbsp;后，控制台报错：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-powershell&quot;&gt;src/index.ts:9:11&amp;nbsp;-&amp;nbsp;error&amp;nbsp;TS2304:&amp;nbsp;Cannot&amp;nbsp;find&amp;nbsp;name&amp;nbsp;&amp;#39;Pingan&amp;#39;.

9&amp;nbsp;leo&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Pingan(&amp;#39;leo&amp;#39;,&amp;#39;hello&amp;#39;);

Found&amp;nbsp;1&amp;nbsp;error.&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3 data-id=&quot;heading-26&quot;&gt;3. 配置复用&lt;/h3&gt;&lt;p&gt;通过&amp;nbsp;&lt;code&gt;extends&lt;/code&gt;&amp;nbsp;属性实现配置复用，即一个配置文件可以继承另一个文件的配置属性。&lt;/p&gt;&lt;p&gt;比如，建立一个基础的配置文件 &lt;code&gt;configs/base.json&lt;/code&gt; ：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-typescript&quot;&gt;{
&amp;nbsp;&amp;nbsp;&amp;quot;compilerOptions&amp;quot;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;noImplicitAny&amp;quot;:&amp;nbsp;true,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;strictNullChecks&amp;quot;:&amp;nbsp;true
&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;在&lt;code&gt;tsconfig.json&lt;/code&gt;&amp;nbsp;就可以引用这个文件的配置了：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-typescript&quot;&gt;{
&amp;nbsp;&amp;nbsp;&amp;quot;extends&amp;quot;:&amp;nbsp;&amp;quot;./configs/base&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;quot;files&amp;quot;:&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;main.ts&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;supplemental.ts&amp;quot;
&amp;nbsp;&amp;nbsp;]
}&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3 data-id=&quot;heading-27&quot;&gt;4. 生成枚举的映射代码&lt;/h3&gt;&lt;p&gt;在默认情况下，使用 &lt;code&gt;const&lt;/code&gt;&amp;nbsp;修饰符后，枚举不会生成映射代码。&lt;/p&gt;&lt;p&gt;如下，我们可以看出：使用 &lt;code&gt;const&lt;/code&gt; 修饰符后，编译器不会生成任何 &lt;code&gt;RequestMethod&lt;/code&gt; 枚举的任何映射代码，在其他地方使用时，内联每个成员的值，节省很大开销。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-typescript&quot;&gt;const&amp;nbsp;enum&amp;nbsp;RequestMethod&amp;nbsp;{
&amp;nbsp;&amp;nbsp;Get,
&amp;nbsp;&amp;nbsp;Post,
&amp;nbsp;&amp;nbsp;Put,
&amp;nbsp;&amp;nbsp;Delete
}

let&amp;nbsp;methods&amp;nbsp;=&amp;nbsp;[
&amp;nbsp;&amp;nbsp;RequestMethod.Get,
&amp;nbsp;&amp;nbsp;RequestMethod.Post
]&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;编译结果：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-typescript&quot;&gt;&amp;quot;use&amp;nbsp;strict&amp;quot;;
let&amp;nbsp;methods&amp;nbsp;=&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0&amp;nbsp;/*&amp;nbsp;Get&amp;nbsp;*/,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&amp;nbsp;/*&amp;nbsp;Post&amp;nbsp;*/
];&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;当然，我们希望生成映射代码时，也可以设置 &lt;code&gt;tsconfig.json&lt;/code&gt; 中的配置，设置 &lt;code&gt;preserveConstEnums&lt;/code&gt; 编译器选项为 &lt;code&gt;true&lt;/code&gt; ：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-typescript&quot;&gt;{
&amp;nbsp;&amp;nbsp;&amp;quot;compilerOptions&amp;quot;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;target&amp;quot;:&amp;nbsp;&amp;quot;es5&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;preserveConstEnums&amp;quot;:&amp;nbsp;true
&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;最后编译结果变成：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-typescript&quot;&gt;&amp;quot;use&amp;nbsp;strict&amp;quot;;
var&amp;nbsp;RequestMethod;
(function&amp;nbsp;(RequestMethod)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RequestMethod[RequestMethod[&amp;quot;Get&amp;quot;]&amp;nbsp;=&amp;nbsp;0]&amp;nbsp;=&amp;nbsp;&amp;quot;Get&amp;quot;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RequestMethod[RequestMethod[&amp;quot;Post&amp;quot;]&amp;nbsp;=&amp;nbsp;1]&amp;nbsp;=&amp;nbsp;&amp;quot;Post&amp;quot;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RequestMethod[RequestMethod[&amp;quot;Put&amp;quot;]&amp;nbsp;=&amp;nbsp;2]&amp;nbsp;=&amp;nbsp;&amp;quot;Put&amp;quot;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RequestMethod[RequestMethod[&amp;quot;Delete&amp;quot;]&amp;nbsp;=&amp;nbsp;3]&amp;nbsp;=&amp;nbsp;&amp;quot;Delete&amp;quot;;
})(RequestMethod&amp;nbsp;||&amp;nbsp;(RequestMethod&amp;nbsp;=&amp;nbsp;{}));
let&amp;nbsp;methods&amp;nbsp;=&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0&amp;nbsp;/*&amp;nbsp;Get&amp;nbsp;*/,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&amp;nbsp;/*&amp;nbsp;Post&amp;nbsp;*/
];&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3 data-id=&quot;heading-28&quot;&gt;5. 关闭 this 类型注解提示&lt;/h3&gt;&lt;p&gt;通过下面代码编译后会报错：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-typescript&quot;&gt;const&amp;nbsp;button&amp;nbsp;=&amp;nbsp;document.querySelector(&amp;quot;button&amp;quot;);
button?.addEventListener(&amp;quot;click&amp;quot;,&amp;nbsp;handleClick);
function&amp;nbsp;handleClick(this)&amp;nbsp;{
&amp;nbsp;console.log(&amp;quot;Clicked!&amp;quot;);
&amp;nbsp;this.removeEventListener(&amp;quot;click&amp;quot;,&amp;nbsp;handleClick);
}&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;报错内容：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-powershell&quot;&gt;src/index.ts:10:22&amp;nbsp;-&amp;nbsp;error&amp;nbsp;TS7006:&amp;nbsp;Parameter&amp;nbsp;&amp;#39;this&amp;#39;&amp;nbsp;implicitly&amp;nbsp;has&amp;nbsp;an&amp;nbsp;&amp;#39;any&amp;#39;&amp;nbsp;type.
10&amp;nbsp;function&amp;nbsp;handleClick(this)&amp;nbsp;{
Found&amp;nbsp;1&amp;nbsp;error.&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;这是因为&amp;nbsp;&lt;code&gt;this&lt;/code&gt; 隐式具有 &lt;code&gt;any&lt;/code&gt; 类型，如果没有指定类型注解，编译器会提示“&amp;quot;this&amp;quot; 隐式具有类型 &amp;quot;any&amp;quot;，因为它没有类型注释。”。&lt;/p&gt;&lt;p&gt;解决方法有2种：&lt;/p&gt;&lt;ol class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;指定 this 类型，如本代码中为 &lt;code&gt;HTMLElement&lt;/code&gt;&amp;nbsp;类型：&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;code&gt;HTMLElement&lt;/code&gt; 接口表示所有的 HTML 元素。一些HTML元素直接实现了 &lt;code&gt;HTMLElement&lt;/code&gt; 接口，其它的间接实现&lt;code&gt;HTMLElement&lt;/code&gt;接口。 关于&lt;a href=&quot;https://link.juejin.cn?target=https%3A%2F%2Fdeveloper.mozilla.org%2Fzh-CN%2Fdocs%2FWeb%2FAPI%2FHTMLElement&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot; title=&quot;https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLElement&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt; HTMLElement &lt;/a&gt;可查看详细。&lt;/p&gt;&lt;ol start=&quot;2&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;使用&amp;nbsp;&lt;code&gt;--noImplicitThis&lt;/code&gt;&amp;nbsp;配置项：&amp;nbsp;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;在 TS2.0 还增加一个新的编译选项： &lt;code&gt;--noImplicitThis&lt;/code&gt;，表示当 &lt;code&gt;this&lt;/code&gt; 表达式值为 &lt;code&gt;any&lt;/code&gt; 类型时生成一个错误信息。我们设置为 &lt;code&gt;true&lt;/code&gt;&amp;nbsp;后就能正常编译。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-typescript&quot;&gt;{
&amp;nbsp;&amp;nbsp;&amp;quot;compilerOptions&amp;quot;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;noImplicitThis&amp;quot;:&amp;nbsp;true
&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2 data-id=&quot;heading-29&quot;&gt;七、Webpack/React 中使用示例&lt;/h2&gt;&lt;h3 data-id=&quot;heading-30&quot;&gt;1. 配置编译 ES6 代码，JSX 文件&lt;/h3&gt;&lt;p&gt;创建测试项目 webpack-demo，结构如下：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-powershell&quot;&gt;webpack-demo/
&amp;nbsp;&amp;nbsp;|-&amp;nbsp;package.json
&amp;nbsp;&amp;nbsp;|-&amp;nbsp;tsconfig.json
&amp;nbsp;&amp;nbsp;|-&amp;nbsp;webpack.config.js
&amp;nbsp;&amp;nbsp;|-&amp;nbsp;/dist
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|-&amp;nbsp;bundle.js
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|-&amp;nbsp;index.html
&amp;nbsp;&amp;nbsp;|-&amp;nbsp;/src
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|-&amp;nbsp;index.js
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|-&amp;nbsp;index.ts
&amp;nbsp;&amp;nbsp;|-&amp;nbsp;/node_modules&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;安装 TypeScript 和 ts-loader：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-powershell&quot;&gt;$&amp;nbsp;npm&amp;nbsp;install&amp;nbsp;--save-dev&amp;nbsp;typescript&amp;nbsp;ts-loader&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;配置 tsconfig.json，支持 JSX，并将 TypeScript 编译为 ES5：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-typescript&quot;&gt;{
&amp;nbsp;&amp;nbsp;&amp;quot;compilerOptions&amp;quot;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;outDir&amp;quot;:&amp;nbsp;&amp;quot;./dist/&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;noImplicitAny&amp;quot;:&amp;nbsp;true,
+&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;module&amp;quot;:&amp;nbsp;&amp;quot;es6&amp;quot;,
+&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;target&amp;quot;:&amp;nbsp;&amp;quot;es5&amp;quot;,
+&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;jsx&amp;quot;:&amp;nbsp;&amp;quot;react&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;allowJs&amp;quot;:&amp;nbsp;true
&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;还需要配置 webpack.config.js，使其能够处理 TypeScript 代码，这里主要在 &lt;code&gt;rules&lt;/code&gt;&amp;nbsp;中添加 &lt;code&gt;ts-loader&lt;/code&gt;&amp;nbsp;：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-typescript&quot;&gt;const&amp;nbsp;path&amp;nbsp;=&amp;nbsp;require(&amp;#39;path&amp;#39;);

module.exports&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;entry:&amp;nbsp;&amp;#39;./src/index.ts&amp;#39;,
&amp;nbsp;&amp;nbsp;module:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rules:&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;test:&amp;nbsp;/\.tsx?$/,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;use:&amp;nbsp;&amp;#39;ts-loader&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;exclude:&amp;nbsp;/node_modules/
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]
&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;resolve:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;extensions:&amp;nbsp;[&amp;nbsp;&amp;#39;.tsx&amp;#39;,&amp;nbsp;&amp;#39;.ts&amp;#39;,&amp;nbsp;&amp;#39;.js&amp;#39;&amp;nbsp;]
&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;output:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;filename:&amp;nbsp;&amp;#39;bundle.js&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;path:&amp;nbsp;path.resolve(__dirname,&amp;nbsp;&amp;#39;dist&amp;#39;)
&amp;nbsp;&amp;nbsp;}
};&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h3 data-id=&quot;heading-31&quot;&gt;2. 配置 source map&lt;/h3&gt;&lt;p&gt;想要启用 source map，我们必须配置 TypeScript，以将内联的 source map 输出到编译后的 JavaScript 文件中。&lt;/p&gt;&lt;p&gt;只需要在 tsconfig.json 中配置 sourceMap 属性：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-typescript&quot;&gt;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;compilerOptions&amp;quot;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;outDir&amp;quot;:&amp;nbsp;&amp;quot;./dist/&amp;quot;,
+&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;sourceMap&amp;quot;:&amp;nbsp;true,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;noImplicitAny&amp;quot;:&amp;nbsp;true,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;module&amp;quot;:&amp;nbsp;&amp;quot;commonjs&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;target&amp;quot;:&amp;nbsp;&amp;quot;es5&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;jsx&amp;quot;:&amp;nbsp;&amp;quot;react&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;allowJs&amp;quot;:&amp;nbsp;true
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;}&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;然后配置&amp;nbsp;webpack.config.js 文件，让 webpack 提取 source map，并内联到最终的 bundle 中：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-typescript&quot;&gt;&amp;nbsp;&amp;nbsp;const&amp;nbsp;path&amp;nbsp;=&amp;nbsp;require(&amp;#39;path&amp;#39;);

&amp;nbsp;&amp;nbsp;module.exports&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;entry:&amp;nbsp;&amp;#39;./src/index.ts&amp;#39;,
+&amp;nbsp;&amp;nbsp;&amp;nbsp;devtool:&amp;nbsp;&amp;#39;inline-source-map&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;module:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rules:&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;test:&amp;nbsp;/\.tsx?$/,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;use:&amp;nbsp;&amp;#39;ts-loader&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;exclude:&amp;nbsp;/node_modules/
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;resolve:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;extensions:&amp;nbsp;[&amp;nbsp;&amp;#39;.tsx&amp;#39;,&amp;nbsp;&amp;#39;.ts&amp;#39;,&amp;nbsp;&amp;#39;.js&amp;#39;&amp;nbsp;]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;output:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;filename:&amp;nbsp;&amp;#39;bundle.js&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;path:&amp;nbsp;path.resolve(__dirname,&amp;nbsp;&amp;#39;dist&amp;#39;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;};&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2 data-id=&quot;heading-32&quot;&gt;八、总结&lt;/h2&gt;&lt;p&gt;本文较全面介绍了 tsconfig.json 文件的知识，从“什么是 tsconfig.js 文件”开始，一步步带领大家全面认识 tsconfig.json 文件。 文中通过一个简单 learnTsconfig 项目，让大家知道项目中如何使用 tsconfig.json 文件。在后续文章中，我们将这么多的配置项进行分类学习。最后通过几个常见配置示例，解决我们开发中遇到的几个常见问题。&lt;/p&gt;&lt;p&gt;当然，本文篇幅有限，无法针对每个属性进行深入介绍，这就需要大家在实际开发中，多去尝试和使用啦~&lt;/p&gt;&lt;h2 data-id=&quot;heading-33&quot;&gt;九、学习和参考资料&lt;/h2&gt;&lt;p&gt;1.&lt;a href=&quot;https://link.juejin.cn?target=https%3A%2F%2Fwww.typescriptlang.org%2Ftsconfig&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot; title=&quot;https://www.typescriptlang.org/tsconfig&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;《Intro to the TSConfig Reference》&lt;/a&gt;&amp;nbsp; 2.&lt;a href=&quot;https://link.juejin.cn?target=https%3A%2F%2Fwww.tslang.cn%2Fdocs%2Fhandbook%2Ftsconfig-json.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot; title=&quot;https://www.tslang.cn/docs/handbook/tsconfig-json.html&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;《tsconfig.json》&lt;/a&gt;&amp;nbsp; 3.&lt;a href=&quot;https://link.juejin.cn?target=http%3A%2F%2Fjson.schemastore.org%2Ftsconfig&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot; title=&quot;http://json.schemastore.org/tsconfig&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;《TypeScript编译器的配置文件的JSON模式》&lt;/a&gt; 4.&lt;a href=&quot;https://link.juejin.cn?target=https%3A%2F%2Fwww.jianshu.com%2Fp%2F0383bbd61a6b&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot; title=&quot;https://www.jianshu.com/p/0383bbd61a6b&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;《详解TypeScript项目中的tsconfig.json配置》&lt;/a&gt;&amp;nbsp; 5.&lt;a href=&quot;https://link.juejin.cn?target=https%3A%2F%2Fwww.typescriptlang.org%2Fdocs%2Fhandbook%2Fcompiler-options.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot; title=&quot;https://www.typescriptlang.org/docs/handbook/compiler-options.html&quot; ref=&quot;nofollow noopener noreferrer&quot;&gt;《官方完整的编译选项列表》&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;原文链接：https://juejin.cn/post/6844904178234458120&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Thu, 20 Jan 2022 14:24:04 +0800</pubDate></item><item><title>解决Chrome开启硬件加速后播放视频黑屏闪烁</title><link>https://grazingwind.com/post/79.html</link><description>&lt;p&gt;最近在使用Chrome时遇到了一个比较头疼的问题，就是开启硬件加速后，播放视频黑屏闪烁，整个眼都要被晃瞎了。&lt;br/&gt;&lt;/p&gt;&lt;p&gt;终于找到了一个解决方案，在此记录一下。&lt;/p&gt;&lt;h2&gt;硬件加速开启方法&lt;/h2&gt;&lt;p&gt;硬件加速是指，应用程序使用计算机硬件的能力，比软件实现的功能能够更有效地执行某些操作。&amp;nbsp;&lt;/p&gt;&lt;p&gt;在Chrome&amp;nbsp;浏览器中，硬件加速能够利用计算机的图形处理单元（GPU）来处理图形密集型任务，例如：播放视频、网页游戏或需要更快数学运算的任何内容。&lt;/p&gt;&lt;p&gt;硬件加速开启方法，浏览器输入&amp;nbsp;chrome://settings/system&lt;/p&gt;&lt;p&gt;&lt;img class=&quot;ue-image&quot; src=&quot;https://grazingwind.com/zb_users/upload/2021/12/202112071638847627872122.png&quot; title=&quot;20211207112650.png&quot; alt=&quot;20211207112650.png&quot;/&gt;&lt;/p&gt;&lt;h2&gt;解决方法&lt;/h2&gt;&lt;p&gt;Chrome(包括Edge Chromium和其他Chromium浏览器)地址栏输入 chrome://flags/#use-angle&lt;/p&gt;&lt;p&gt;&lt;img class=&quot;ue-image&quot; src=&quot;https://grazingwind.com/zb_users/upload/2021/12/202112071638847546425835.png&quot; title=&quot;9aQ5-joihKtT3cSkg-5t.png&quot; alt=&quot;9aQ5-joihKtT3cSkg-5t.png&quot;/&gt;&lt;/p&gt;&lt;p&gt;Windows机器建议把ANGLE调用的图形API阉割为D3D9。&lt;/p&gt;&lt;p&gt;Google Chrome的硬件渲染一言难尽，Linux平台直接把Mesa甚至DRM搞挂都屡见不鲜，然而Google的解决方案居然不是修好硬件渲染而是SwiftShader。&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Tue, 07 Dec 2021 11:24:43 +0800</pubDate></item><item><title>babel、vue编译，Prettier原理等离不开的AST技术</title><link>https://grazingwind.com/post/78.html</link><description>&lt;div&gt;&lt;div&gt;&lt;h2 data-id=&quot;heading-0&quot;&gt;概要&lt;/h2&gt;&lt;p&gt;本文将通过以下几个方面对AST进行学习&lt;/p&gt;&lt;ol class=&quot; list-paddingleft-2&quot; style=&quot;list-style-type: decimal;&quot;&gt;&lt;li&gt;&lt;p&gt;为什么要了解AST，简要说明AST在开发中的重要性&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;什么是AST，对AST有一个直观的认识&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;AST是如何生成的，分析将代码解析成AST的原理&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;AST的具体应用，通过解读babel原理、vue模板编译过程，Prettier实现原理，来分析AST在开发中的具体使用。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;AST还能做什么，结合工作，思考AST能为我们做些什么&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;h2 data-id=&quot;heading-1&quot;&gt;为什么要学习AST&lt;/h2&gt;&lt;p&gt;AST（抽象语法树）在开发过程中扮演一个非常重要的角色，但是我们却很少去直接接触它。&lt;/p&gt;&lt;p&gt;无论是代码编译（babel），打包（webpack），代码压缩，css预处理，代码校验（eslint），代码美化（pretiier），Vue中对template的编译，这些的实现都离不开AST。&lt;/p&gt;&lt;p&gt;了解学习AST，能够帮助我们更好的对上面说的这些工具原理进行理解，同时，我们可以利用它去开发一些工具，来优化我们的开发流程，提高开发效率。&lt;/p&gt;&lt;/div&gt;&lt;h2 data-id=&quot;heading-2&quot;&gt;什么是AST&lt;/h2&gt;&lt;p&gt;AST是对源代码的抽象语法结构的树状表现形式。&lt;/p&gt;&lt;p&gt;在不同的场景下，会有不同的解析器将源码解析成抽象语法树。&lt;/p&gt;&lt;p&gt;下面直观的看一下AST是什么样的&lt;/p&gt;&lt;p&gt;代码如下&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;let&amp;nbsp;answer&amp;nbsp;=&amp;nbsp;2&amp;nbsp;*&amp;nbsp;3;&lt;/pre&gt;&lt;p&gt;对应的AST语法树&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;type&amp;quot;:&amp;nbsp;&amp;quot;Program&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;body&amp;quot;:&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;type&amp;quot;:&amp;nbsp;&amp;quot;VariableDeclaration&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;declarations&amp;quot;:&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;type&amp;quot;:&amp;nbsp;&amp;quot;VariableDeclarator&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;id&amp;quot;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;type&amp;quot;:&amp;nbsp;&amp;quot;Identifier&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;name&amp;quot;:&amp;nbsp;&amp;quot;answer&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;init&amp;quot;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;type&amp;quot;:&amp;nbsp;&amp;quot;BinaryExpression&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;operator&amp;quot;:&amp;nbsp;&amp;quot;*&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;left&amp;quot;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;type&amp;quot;:&amp;nbsp;&amp;quot;Literal&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;value&amp;quot;:&amp;nbsp;2,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;raw&amp;quot;:&amp;nbsp;&amp;quot;2&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;right&amp;quot;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;type&amp;quot;:&amp;nbsp;&amp;quot;Literal&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;value&amp;quot;:&amp;nbsp;3,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;raw&amp;quot;:&amp;nbsp;&amp;quot;3&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;],
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;kind&amp;quot;:&amp;nbsp;&amp;quot;let&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;],
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;sourceType&amp;quot;:&amp;nbsp;&amp;quot;script&amp;quot;
}&lt;/pre&gt;&lt;p&gt;那么AST是如何生成的呢？&lt;span style=&quot;color: #333333; font-family: -apple-system, system-ui, &amp;quot;Segoe UI&amp;quot;, Roboto, Ubuntu, Cantarell, &amp;quot;Noto Sans&amp;quot;, sans-serif, BlinkMacSystemFont, &amp;quot;Helvetica Neue&amp;quot;, &amp;quot;PingFang SC&amp;quot;, &amp;quot;Hiragino Sans GB&amp;quot;, &amp;quot;Microsoft YaHei&amp;quot;, Arial; font-size: 15px; background-color: #FFFFFF;&quot;&gt;&lt;/span&gt;&lt;br/&gt;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;h2 data-id=&quot;heading-3&quot;&gt;AST是如何生成的&lt;/h2&gt;&lt;p&gt;AST是通过JS Parser （解析器），将js源码转化为抽象语法树，主要分为两步&lt;/p&gt;&lt;h3 data-id=&quot;heading-4&quot;&gt;1. 分词&lt;/h3&gt;&lt;p&gt;将整个的代码字符串，分割成语法单元数组（token）。
JS中的语法单元（token）指标识符（function，return），运算符，括号，数字，字符串等能解析的最小单元。主要有以下几种：&lt;/p&gt;&lt;ol class=&quot; list-paddingleft-2&quot; style=&quot;list-style-type: decimal;&quot;&gt;&lt;li&gt;&lt;p&gt;标识符&lt;br/&gt;没有被引号括起来的连续字符，可以包含字母、数字、_、$，其中数字不能作为开头。&lt;br/&gt;标识符可能是var，return，function等关键字，也可能是true，false这样的内置常量，或是一个变量。具体是哪种语义，分词阶段不区分，只要正确拆分即可。&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;字符串 对计算机而言，字符串只会参与计算和展示，具体里面细分没必要分析&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;注释 &amp;nbsp;不管是行注释还是块注释，对于计算机来说并不关心其内容，所以可以作为不可再拆分的最小单元&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;p&gt;依然拿上面的代码作为例子，分词后生成的语法单元数组如下&lt;/p&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;type&amp;quot;:&amp;nbsp;&amp;quot;Keyword&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;value&amp;quot;:&amp;nbsp;&amp;quot;var&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;range&amp;quot;:&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;type&amp;quot;:&amp;nbsp;&amp;quot;Identifier&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;value&amp;quot;:&amp;nbsp;&amp;quot;answer&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;range&amp;quot;:&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;10
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;type&amp;quot;:&amp;nbsp;&amp;quot;Punctuator&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;value&amp;quot;:&amp;nbsp;&amp;quot;=&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;range&amp;quot;:&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;11,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;12
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;type&amp;quot;:&amp;nbsp;&amp;quot;Numeric&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;value&amp;quot;:&amp;nbsp;&amp;quot;2&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;range&amp;quot;:&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;13,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;14
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;type&amp;quot;:&amp;nbsp;&amp;quot;Punctuator&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;value&amp;quot;:&amp;nbsp;&amp;quot;*&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;range&amp;quot;:&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;15,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;16
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;type&amp;quot;:&amp;nbsp;&amp;quot;Numeric&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;value&amp;quot;:&amp;nbsp;&amp;quot;3&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;range&amp;quot;:&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;17,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;18
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;type&amp;quot;:&amp;nbsp;&amp;quot;Punctuator&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;value&amp;quot;:&amp;nbsp;&amp;quot;;&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;range&amp;quot;:&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;18,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;19
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
]&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;h3 data-id=&quot;heading-5&quot;&gt;2. 语义分析&lt;/h3&gt;&lt;p&gt;语义分析的目的是将分词得到的语法单元进行一个整体的组合，分析确定语法单元之间的关系。&lt;/p&gt;&lt;p&gt;简单来说，语义分析可以理解成对语句（statement）和表达式（expression）的识别。&lt;/p&gt;&lt;ol class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;语句，一个具备边界的代码区域。相邻的两个语句之间从语法上讲互不影响。比如： &lt;code&gt;var a = 1; if(xxx){xxx}&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;表达式，指最终会有一个结果的一小段代码，它可以嵌入到另一个表达式中，且包含在表达式中。比如：&lt;code&gt;a++&lt;/code&gt;， &lt;code&gt;i &amp;gt; 0 &amp;amp;&amp;amp; i&amp;lt; 6&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;语义分析是一个递归的过程，它会将分词分析出来的数组转化成树形的表达形式。同时，会验证语法，语法如果存在错误的话，会抛出语法错误。&lt;/p&gt;&lt;h2 data-id=&quot;heading-6&quot;&gt;AST的具体应用&lt;/h2&gt;&lt;p&gt;文章一开始就说到了，babel，webpack，css预处理，eslint等都应用到了AST树，那么AST到底做了一个什么样的角色呢！？ 下面我们就来看一下。&lt;/p&gt;&lt;p&gt;首先看一下babel工作原理的实现。&lt;/p&gt;&lt;h3 data-id=&quot;heading-7&quot;&gt;babel实现原理&lt;/h3&gt;&lt;p&gt;babel是一个javascript编译器，用来将es6语法编译成es5&lt;/p&gt;&lt;p&gt;babel的工作可以分为3个阶段：&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;img class=&quot;ue-image&quot; src=&quot;https://grazingwind.com/zb_users/upload/2021/11/202111221637570058409275.png&quot; title=&quot;p1-jj.byteimg.com_tos-cn-i-t2oaga2asx_gold-user-assets_2019_12_12_16efabb5dd074189_tplv-t2oaga2asx-watermark.awebp.png&quot; alt=&quot;p1-jj.byteimg.com_tos-cn-i-t2oaga2asx_gold-user-assets_2019_12_12_16efabb5dd074189_tplv-t2oaga2asx-watermark.awebp.png&quot; width=&quot;970&quot; height=&quot;154&quot; style=&quot;width: 970px; height: 154px;&quot;/&gt;&lt;/p&gt;&lt;p&gt;第1步 解析（Parse）&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;p&gt;通过解析器babylon将代码解析成抽象语法树&lt;/p&gt;&lt;p&gt;第2步 转换（TransForm）&lt;br/&gt;通过babel-traverse plugin对抽象语法树进行深度优先遍历，遇到需要转换的，就直接在AST对象上对节点进行添加、更新及移除操作，比如遇到箭头函数，就转换成普通函数，最后得到新的AST树。&lt;/p&gt;&lt;p&gt;第3步 生成（Generate）&lt;br/&gt;通过babel-generator将AST树生成es5代码&lt;/p&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;h3 data-id=&quot;heading-8&quot;&gt;vue模板编译过程&lt;/h3&gt;&lt;p&gt;Vue 提供了 2 个版本，一个是 Runtime + Compiler ，另一个是 Runtime only 的，前者是包含编译代码的，会把编译的过程放在运行时做，后者是不包含编译代码的，需要借助 webpack 的vue-loader把模板编译render函数。不管使用哪个版本，都有一个环节，就是将模板编译成render函数。&lt;/p&gt;&lt;p&gt;下面我们分析下vue模板的编译过程，这也是vue源码实现中非常重要的一个模块。
vue模板的编译过程分为3个阶段&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;img class=&quot;ue-image&quot; src=&quot;https://grazingwind.com/zb_users/upload/2021/11/202111221637570147517337.png&quot; title=&quot;p1-jj.byteimg.com_tos-cn-i-t2oaga2asx_gold-user-assets_2019_12_12_16efabbb717ce350_tplv-t2oaga2asx-watermark.awebp.png&quot; alt=&quot;p1-jj.byteimg.com_tos-cn-i-t2oaga2asx_gold-user-assets_2019_12_12_16efabbb717ce350_tplv-t2oaga2asx-watermark.awebp.png&quot; width=&quot;978&quot; height=&quot;135&quot; style=&quot;width: 978px; height: 135px;&quot;/&gt;&lt;/p&gt;&lt;p&gt;第1步 解析（Parse）&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;const&amp;nbsp;ast&amp;nbsp;=&amp;nbsp;parse(template.trim(),&amp;nbsp;options)&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;p&gt;将模板字符串解析生成 AST,这里的解析器是vue自己实现的，解析过程中会使用正则表达式对模板顺序解析，当解析到开始标签、闭合标签、文本的时候都会有相对应的回调函数执行，来达到构造 AST 树的目的。&lt;/p&gt;&lt;p&gt;生成的AST 元素节点总共有 3 种类型，1 为普通元素， 2 为表达式，3为纯文本。下面看一个例子&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;&amp;lt;ul&amp;nbsp;:class=&amp;quot;bindCls&amp;quot;&amp;nbsp;class=&amp;quot;list&amp;quot;&amp;nbsp;v-if=&amp;quot;isShow&amp;quot;&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;li&amp;nbsp;v-for=&amp;quot;(item,index)&amp;nbsp;in&amp;nbsp;data&amp;quot;&amp;nbsp;@click=&amp;quot;clickItem(index)&amp;quot;&amp;gt;{{item}}:{{index}}&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;&lt;/pre&gt;&lt;p&gt;上面模板解析生成的AST树如下：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;ast&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;#39;type&amp;#39;:&amp;nbsp;1,
&amp;nbsp;&amp;nbsp;&amp;#39;tag&amp;#39;:&amp;nbsp;&amp;#39;ul&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;#39;attrsList&amp;#39;:&amp;nbsp;[],
&amp;nbsp;&amp;nbsp;&amp;#39;attrsMap&amp;#39;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;:class&amp;#39;:&amp;nbsp;&amp;#39;bindCls&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;class&amp;#39;:&amp;nbsp;&amp;#39;list&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;v-if&amp;#39;:&amp;nbsp;&amp;#39;isShow&amp;#39;
&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;#39;if&amp;#39;:&amp;nbsp;&amp;#39;isShow&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;#39;ifConditions&amp;#39;:&amp;nbsp;[{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;exp&amp;#39;:&amp;nbsp;&amp;#39;isShow&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;block&amp;#39;:&amp;nbsp;//&amp;nbsp;ul&amp;nbsp;ast&amp;nbsp;element
&amp;nbsp;&amp;nbsp;}],
&amp;nbsp;&amp;nbsp;&amp;#39;parent&amp;#39;:&amp;nbsp;undefined,
&amp;nbsp;&amp;nbsp;&amp;#39;plain&amp;#39;:&amp;nbsp;false,
&amp;nbsp;&amp;nbsp;&amp;#39;staticClass&amp;#39;:&amp;nbsp;&amp;#39;list&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;#39;classBinding&amp;#39;:&amp;nbsp;&amp;#39;bindCls&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;#39;children&amp;#39;:&amp;nbsp;[{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;type&amp;#39;:&amp;nbsp;1,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;tag&amp;#39;:&amp;nbsp;&amp;#39;li&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;attrsList&amp;#39;:&amp;nbsp;[{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;name&amp;#39;:&amp;nbsp;&amp;#39;@click&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;value&amp;#39;:&amp;nbsp;&amp;#39;clickItem(index)&amp;#39;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}],
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;attrsMap&amp;#39;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;@click&amp;#39;:&amp;nbsp;&amp;#39;clickItem(index)&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;v-for&amp;#39;:&amp;nbsp;&amp;#39;(item,index)&amp;nbsp;in&amp;nbsp;data&amp;#39;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;parent&amp;#39;:&amp;nbsp;//&amp;nbsp;ul&amp;nbsp;ast&amp;nbsp;element
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;plain&amp;#39;:&amp;nbsp;false,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;events&amp;#39;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;click&amp;#39;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;value&amp;#39;:&amp;nbsp;&amp;#39;clickItem(index)&amp;#39;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;hasBindings&amp;#39;:&amp;nbsp;true,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;for&amp;#39;:&amp;nbsp;&amp;#39;data&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;alias&amp;#39;:&amp;nbsp;&amp;#39;item&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;iterator1&amp;#39;:&amp;nbsp;&amp;#39;index&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;children&amp;#39;:&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;type&amp;#39;:&amp;nbsp;2,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;expression&amp;#39;:&amp;nbsp;&amp;#39;_s(item)+&amp;quot;:&amp;quot;+_s(index)&amp;#39;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;text&amp;#39;:&amp;nbsp;&amp;#39;{{item}}:{{index}}&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;tokens&amp;#39;:&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;#39;@binding&amp;#39;:&amp;#39;item&amp;#39;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;:&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;#39;@binding&amp;#39;:&amp;#39;index&amp;#39;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]
&amp;nbsp;&amp;nbsp;}]
}&lt;/pre&gt;&lt;p&gt;第2步 优化语法树（Optimize）&lt;/p&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;optimize(ast,&amp;nbsp;options)&lt;/pre&gt;&lt;div&gt;&lt;p&gt;vue模板中并不是所有数据都是响应式的，有很多数据是首次渲染后就永远不会变化的，那么这部分数据生成的 DOM 也不会变化，我们可以在patch的过程跳过对他们的比对。&lt;br/&gt;此阶段会深度遍历生成的 AST树，检测它的每一颗子树是不是静态节点，如果是静态节点则它们生成 DOM 永远不需要改变，这对运行时对模板的更新起到极大的优化作用。&lt;/p&gt;&lt;p&gt;遍历过程中，会对整个 AST 树中的每一个 AST 元素节点标记static和staticRoot（递归该节点的所有children，一旦子节点有不是static的情况，则为false，否则为true）。&lt;/p&gt;&lt;p&gt;经过该阶段，上面例子中的ast会变成&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;ast&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;#39;type&amp;#39;:&amp;nbsp;1,
&amp;nbsp;&amp;nbsp;&amp;#39;tag&amp;#39;:&amp;nbsp;&amp;#39;ul&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;#39;attrsList&amp;#39;:&amp;nbsp;[],
&amp;nbsp;&amp;nbsp;&amp;#39;attrsMap&amp;#39;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;:class&amp;#39;:&amp;nbsp;&amp;#39;bindCls&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;class&amp;#39;:&amp;nbsp;&amp;#39;list&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;v-if&amp;#39;:&amp;nbsp;&amp;#39;isShow&amp;#39;
&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;#39;if&amp;#39;:&amp;nbsp;&amp;#39;isShow&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;#39;ifConditions&amp;#39;:&amp;nbsp;[{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;exp&amp;#39;:&amp;nbsp;&amp;#39;isShow&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;block&amp;#39;:&amp;nbsp;//&amp;nbsp;ul&amp;nbsp;ast&amp;nbsp;element
&amp;nbsp;&amp;nbsp;}],
&amp;nbsp;&amp;nbsp;&amp;#39;parent&amp;#39;:&amp;nbsp;undefined,
&amp;nbsp;&amp;nbsp;&amp;#39;plain&amp;#39;:&amp;nbsp;false,
&amp;nbsp;&amp;nbsp;&amp;#39;staticClass&amp;#39;:&amp;nbsp;&amp;#39;list&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;#39;classBinding&amp;#39;:&amp;nbsp;&amp;#39;bindCls&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;#39;static&amp;#39;:&amp;nbsp;false,
&amp;nbsp;&amp;nbsp;&amp;#39;staticRoot&amp;#39;:&amp;nbsp;false,
&amp;nbsp;&amp;nbsp;&amp;#39;children&amp;#39;:&amp;nbsp;[{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;type&amp;#39;:&amp;nbsp;1,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;tag&amp;#39;:&amp;nbsp;&amp;#39;li&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;attrsList&amp;#39;:&amp;nbsp;[{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;name&amp;#39;:&amp;nbsp;&amp;#39;@click&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;value&amp;#39;:&amp;nbsp;&amp;#39;clickItem(index)&amp;#39;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}],
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;attrsMap&amp;#39;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;@click&amp;#39;:&amp;nbsp;&amp;#39;clickItem(index)&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;v-for&amp;#39;:&amp;nbsp;&amp;#39;(item,index)&amp;nbsp;in&amp;nbsp;data&amp;#39;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;parent&amp;#39;:&amp;nbsp;//&amp;nbsp;ul&amp;nbsp;ast&amp;nbsp;element
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;plain&amp;#39;:&amp;nbsp;false,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;events&amp;#39;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;click&amp;#39;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;value&amp;#39;:&amp;nbsp;&amp;#39;clickItem(index)&amp;#39;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;hasBindings&amp;#39;:&amp;nbsp;true,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;for&amp;#39;:&amp;nbsp;&amp;#39;data&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;alias&amp;#39;:&amp;nbsp;&amp;#39;item&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;iterator1&amp;#39;:&amp;nbsp;&amp;#39;index&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;static&amp;#39;:&amp;nbsp;false,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;staticRoot&amp;#39;:&amp;nbsp;false,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;children&amp;#39;:&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;type&amp;#39;:&amp;nbsp;2,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;expression&amp;#39;:&amp;nbsp;&amp;#39;_s(item)+&amp;quot;:&amp;quot;+_s(index)&amp;#39;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;text&amp;#39;:&amp;nbsp;&amp;#39;{{item}}:{{index}}&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;tokens&amp;#39;:&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;#39;@binding&amp;#39;:&amp;#39;item&amp;#39;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;:&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;#39;@binding&amp;#39;:&amp;#39;index&amp;#39;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;],
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;static&amp;#39;:&amp;nbsp;false
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]
&amp;nbsp;&amp;nbsp;}]
}&lt;/pre&gt;&lt;p&gt;第3步 生成代码&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;const&amp;nbsp;code&amp;nbsp;=&amp;nbsp;generate(ast,&amp;nbsp;options)&lt;/pre&gt;&lt;p&gt;通过generate方法，将ast生成render函数&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;with(this){
&amp;nbsp;&amp;nbsp;return&amp;nbsp;(isShow)&amp;nbsp;?
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_c(&amp;#39;ul&amp;#39;,&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;staticClass:&amp;nbsp;&amp;quot;list&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;class:&amp;nbsp;bindCls
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_l((data),&amp;nbsp;function(item,&amp;nbsp;index)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;_c(&amp;#39;li&amp;#39;,&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;on:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;click&amp;quot;:&amp;nbsp;function($event)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;clickItem(index)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[_v(_s(item)&amp;nbsp;+&amp;nbsp;&amp;quot;:&amp;quot;&amp;nbsp;+&amp;nbsp;_s(index))])
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;:&amp;nbsp;_e()
}&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;h3 data-id=&quot;heading-9&quot;&gt;Prettier实现原理&lt;/h3&gt;&lt;p&gt;通过上面对babel实现原理和vue模板的编译原理可以看出，他们的实现有很多相同之处，都是先将源码解析成AST树，然后对AST树就行处理，最后生成想要的东西。&lt;/p&gt;&lt;p&gt;Prettier的实现同样是这样，首先依然是将代码解析生成AST树，然后是对AST遍历，调整长句，整理空格，括号等，最后输出代码，这里就不赘述了。&lt;/p&gt;&lt;h3 data-id=&quot;heading-10&quot;&gt;小结&lt;/h3&gt;&lt;p&gt;我们分析了Babel原理、vue模板编译过程、Prettier原理，这里我们简单总结一下。&lt;br/&gt;如果把源码比作一个机器，那么分词过程就是将这台机器拆分成一个个零件，语义分析过程就是分析每个零件的位置以及作用，然后根据需要对零件进行加工处理，最后再组装成一个新的机器。&lt;/p&gt;&lt;h2 data-id=&quot;heading-11&quot;&gt;AST还能做什么&lt;/h2&gt;&lt;p&gt;那么工作中我们能使用AST做些什么呢？！&lt;/p&gt;&lt;p&gt;这里就要发挥想象了，看看我们日常工作中有什么需求是可以通过AST开发个工具来解决。&lt;br/&gt;比如，可以通过AST可以将代码自动转成流程图；&lt;br/&gt;或者根据自定义的注释规范，通过工具自动生成文档；&lt;br/&gt;或是通过工具自动生成骨架屏文件。&lt;/p&gt;&lt;/div&gt;&lt;br/&gt;&lt;br/&gt;原文链接：https://juejin.cn/post/6844904019505184776&lt;br/&gt;&lt;br/&gt;&lt;/div&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;/div&gt;</description><pubDate>Mon, 22 Nov 2021 16:29:31 +0800</pubDate></item><item><title>WSGI与ASGI的区别与联系</title><link>https://grazingwind.com/post/77.html</link><description>&lt;h2&gt;什么是WSGI&lt;/h2&gt;&lt;p&gt;CGI（Common Gateway Interface，通用网关接口），定义客户端与Web服务器的交流方式的一个程序，例如正常情况下客户端发送过来一个请求，根据HTTP协议Web服务器将请求的内容解析出来，经过处理会后，再将返回的内容封装好。例如服务器返回一个HTML页面，并且根据HTTP协议构建返回内容的响应格式，涉及到TCP连接、HTTP原始请求和相应格式都是由一个软件来完成，这个程序就是CGI。&lt;/p&gt;&lt;p&gt;那么WSGI（Python Web Server Gateway Interface，WSGI）Web服务器网关接口，是为Python语言定义的Web服务器和Web应用程序或框架之间的一猴子那个简单而且通用的接口，从语义上理解，WSGI为了解决Web服务器与客户端之间的通信问题而产生的。并且WSGI是基于现存的CGI标准而设计的，同样是一种程序。&lt;/p&gt;&lt;p&gt;WSGI区分为两部分，一种为服务器或网关，另一种为应用程序或应用框架，所谓的WSGI中间件同时实现了API的两方，即在WSGI服务器和WSGI应用之间起调解作用：从WSGI服务器的角度来说，中间件扮演应用程序，而从应用程序的角度来说，中间件扮演服务器。中间件具有的功能有：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot; style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;&lt;p&gt;重写环境变量后，根据目标URL，将请求消息路由到不同的应用对象。&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;进行内容后处理，例如应用样表。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;WSGI就是基于Python的以CGI为标准做一些扩展。&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;img class=&quot;ue-image&quot; src=&quot;https://grazingwind.com/zb_users/upload/2021/10/202110121634018077293151.png&quot; style=&quot;&quot; title=&quot;20200508220847789.png&quot;/&gt;&lt;/p&gt;&lt;h2&gt;什么是ASGI&lt;/h2&gt;&lt;p&gt;&lt;img class=&quot;ue-image&quot; src=&quot;https://grazingwind.com/zb_users/upload/2021/10/202110121634018078282418.jpg&quot; style=&quot;&quot; title=&quot;20200508220854536.jpg&quot;/&gt;&lt;/p&gt;&lt;p&gt;WSGI 规范自诞生以来应用广泛，在作为 Python 框架和 web 服务的选择上拥有非常好的灵活性。但，因为是针对 HTTP 风格的请求响应模型做的设计，加上越来越多不遵循这种模式的协议逐渐成为 web 编程的标准之一，比如说，WebSocket。所以需要新的改变。&lt;/p&gt;&lt;p&gt;ASGI 尝试保持在一个简单的应用接口的前提下，提供允许数据能够在任意时候、被任意应用进程发送和接受的抽象。&lt;/p&gt;&lt;p&gt;它同样描绘了一个新的，兼容 HTTP 请求响应以及 WebSocket 数据帧的序列格式。允许这些协议能通过网络或本地 socket 进行传输，以及让不同的协议被分配到不同的进程进行处理。&lt;/p&gt;&lt;h2&gt;目的&lt;/h2&gt;&lt;p&gt;介于网络协议服务和 Python 应用之间的标准接口，能够处理多种通用协议类型，包括 HTTP、HTTP2 和 WebSocket。在 WSGI 上进行拓展，并最终取代它。在设计上还是包含了 WSGI 到 ASGI 以及 ASGI 到 WSGI 的转换器，目的是为了使 HTTP 协议的编写更为容易。&lt;/p&gt;&lt;h2&gt;总览&lt;/h2&gt;&lt;p&gt;SGI 由三个不同的组件构成：协议服务、频道层（channel layer）、应用代码。频道层是这个实现中最重要的部分，它能同时对协议服务和应用提供接口。&lt;/p&gt;&lt;p&gt;一个频道层对协议服务、应用服务提供一个 send 的可调用方法，该方法接受 channel name、message dict 以及一个 receive_many 方法作为参数。receive_many 方法接受 channel name 的 list 作为参数，返回指定频道的下一条可用的消息。&lt;/p&gt;&lt;p&gt;所以，相较于在 WSGI 上，我们将协议服务直接指向应用，在 ASGI 里，我们将协议服务和应用同时指向一个频道层的实例。它的目的是让应用服务和协议服务总是运行在不同的进程或者线程中，并通过频道层进行通信。&lt;/p&gt;&lt;h2&gt;区别&lt;/h2&gt;&lt;p&gt;总体来说就是ASGI对于WSGI原有的模式的支持和WebSocket的扩展，即ASGI是WSGI的扩展。&lt;/p&gt;</description><pubDate>Tue, 12 Oct 2021 13:53:07 +0800</pubDate></item><item><title>ubuntu下screen的使用</title><link>https://grazingwind.com/post/76.html</link><description>&lt;p&gt;关掉xshell之后执行的脚本也随之停止，我们可以使用screen命令，来让保证退出ssh之后程序继续在后台跑。&lt;/p&gt;&lt;p&gt;利用SSH远程连接服务器，运行程序需要保证在此期间窗口不能关闭并且连接不能断开，否则当前窗口所运行的任务就被杀死。&lt;/p&gt;&lt;p&gt;参考GNU&amp;#39;s Screen 官网：&lt;a href=&quot;http://www.gnu.org/software/screen/&quot;&gt;GNU&amp;#39;s Screen&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;img class=&quot;ue-image&quot; src=&quot;https://grazingwind.com/zb_users/upload/2021/09/202109171631847772896090.png&quot; title=&quot;787798-20181026175145078-1516220736.png&quot; alt=&quot;787798-20181026175145078-1516220736.png&quot;/&gt;&lt;/p&gt;&lt;h2&gt;主要使用&lt;/h2&gt;&lt;p&gt;1. 安装&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;首先可以先查看是否安装screen，通过命令&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-powershell&quot;&gt;screen&amp;nbsp;-ls&lt;/pre&gt;&lt;p&gt;若出现：&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-powershell&quot;&gt;The&amp;nbsp;program&amp;nbsp;&amp;#39;screen&amp;#39;&amp;nbsp;is&amp;nbsp;currently&amp;nbsp;not&amp;nbsp;installed.&amp;nbsp;You&amp;nbsp;can&amp;nbsp;install&amp;nbsp;it&amp;nbsp;by&amp;nbsp;typing:
sudo&amp;nbsp;apt&amp;nbsp;install&amp;nbsp;screen&lt;/pre&gt;&lt;p&gt;说明尚未安装，安装提示，通过下面的命令安装screen&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-powershell&quot;&gt;sudo&amp;nbsp;apt&amp;nbsp;install&amp;nbsp;screen&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;2.&amp;nbsp;创建新建窗口&lt;br/&gt;&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot; style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;&lt;p&gt;可直接通过命令&lt;code&gt;screen&lt;/code&gt;新建一个窗口，并进入窗口。但通过这种方式新建的窗口没有名字，只有系统分配给它的一个id。当需要恢复窗口时，只能通过id号来恢复。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;通过命令&lt;code&gt;screen -S name&lt;/code&gt;，这样就可以新建一个名字为name的窗口，同样系统也会分配给它一个id，当恢复该窗口时既可以通过id号也可以通过窗口名。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;3. 分离会话&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;退出当前新建的窗口，通过快键键Ctrl+A+D实现分离，此时窗口会跳出[detached]的提示，并回到主窗口。&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;4. 恢复会话窗口&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;首先查看当前有哪些screen窗口，通过命令：&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-markdown&quot;&gt;screen&amp;nbsp;-ls&lt;/pre&gt;&lt;p&gt;将列出窗口列表。&lt;/p&gt;&lt;p&gt;&lt;img class=&quot;ue-image&quot; src=&quot;https://grazingwind.com/zb_users/upload/2021/09/202109171631847991771317.png&quot; title=&quot;787798-20181026175344791-956631152.png&quot; alt=&quot;787798-20181026175344791-956631152.png&quot;/&gt;&lt;/p&gt;&lt;p&gt;由以上可知，当前有两个窗口，其中test窗口已经被杀死，test2窗口分离。可以通过以下命令恢复test2窗口：&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-powershell&quot;&gt;screen&amp;nbsp;-r&amp;nbsp;test2&lt;/pre&gt;&lt;p&gt;或&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-powershell&quot;&gt;screen&amp;nbsp;-r&amp;nbsp;27582&lt;/pre&gt;&lt;p&gt;这样就返回了test2窗口&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;5. 通过命令杀死会话窗口：&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-powershell&quot;&gt;kill&amp;nbsp;-9&amp;nbsp;threadnum&lt;/pre&gt;&lt;p&gt;注意此处只能通过id号来杀死窗口。&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;6. 通过命令清除死去窗口&lt;br style=&quot;margin: 0px; padding: 0px;&quot;/&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-powershell&quot;&gt;screen&amp;nbsp;-wipe&lt;/pre&gt;&lt;p&gt;这个命令将自动清除所有处于dead状态的窗口&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Fri, 17 Sep 2021 11:01:59 +0800</pubDate></item><item><title>centos通过配置ssh-key实现github连接  </title><link>https://grazingwind.com/post/75.html</link><description>&lt;p&gt;最近github更新了策略，原来是用密码的方式进行代码push、pull的方法被禁掉了。&lt;/p&gt;&lt;p&gt;尝试git操作时，会有下面的提示：&lt;br/&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;remote:&amp;nbsp;Support&amp;nbsp;for&amp;nbsp;password&amp;nbsp;authentication&amp;nbsp;was&amp;nbsp;removed&amp;nbsp;on&amp;nbsp;August&amp;nbsp;13,&amp;nbsp;2021.&amp;nbsp;Please&amp;nbsp;use&amp;nbsp;a&amp;nbsp;personal&amp;nbsp;access&amp;nbsp;token&amp;nbsp;instead.
remote:&amp;nbsp;Please&amp;nbsp;see&amp;nbsp;https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/&amp;nbsp;for&amp;nbsp;more&amp;nbsp;information.&lt;/pre&gt;&lt;p&gt;所以，后面应该转向使用access&amp;nbsp;token的方式进行代码管理。&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;1、生成&lt;code&gt;ssh-key&lt;/code&gt;，填入自己的邮箱&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;ssh-keygen&amp;nbsp;-t&amp;nbsp;rsa&amp;nbsp;-C&amp;nbsp;&amp;quot;xxxxxx@126.com&amp;quot;&lt;/pre&gt;&lt;p&gt;2、进入&lt;code&gt;ssh&lt;/code&gt;目录&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;cd&amp;nbsp;~/.ssh&lt;/pre&gt;&lt;p&gt;3、查看文件&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;ls&lt;/pre&gt;&lt;p&gt;会看到列举出了有&lt;code&gt;id_rsa&lt;/code&gt;、&lt;code&gt;id_rsa.pub&lt;/code&gt;。&lt;/p&gt;&lt;p&gt;4、复制一下&lt;code&gt;id_rsa.pub&lt;/code&gt;文件内容&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;cat&amp;nbsp;id_rsa.pub&lt;/pre&gt;&lt;p&gt;5、打开&lt;code&gt;github&lt;/code&gt;中的&lt;code&gt;SSH and GPS keys&lt;/code&gt;选项，新增&lt;code&gt;SSH key&lt;/code&gt;，添加完成需要再次输入&lt;code&gt;github&lt;/code&gt;密码验证。&lt;br style=&quot;box-sizing: border-box; outline: 0px; overflow-wrap: break-word; color: rgb(77, 77, 77); font-family: -apple-system, &amp;quot;SF UI Text&amp;quot;, Arial, &amp;quot;PingFang SC&amp;quot;, &amp;quot;Hiragino Sans GB&amp;quot;, &amp;quot;Microsoft YaHei&amp;quot;, &amp;quot;WenQuanYi Micro Hei&amp;quot;, sans-serif; font-size: 16px; font-variant-ligatures: no-common-ligatures; white-space: normal; background-color: rgb(255, 255, 255);&quot;/&gt;6、在自己的终端测试一下吧，使用&amp;nbsp;&lt;code&gt;ssh -T git@github.com&lt;/code&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-bash&quot;&gt;ssh&amp;nbsp;-T&amp;nbsp;git@github.com
Hi&amp;nbsp;xxxxxx!&amp;nbsp;You&amp;#39;ve&amp;nbsp;successfully&amp;nbsp;authenticated,&amp;nbsp;but&amp;nbsp;GitHub&amp;nbsp;does&amp;nbsp;not&amp;nbsp;provide&amp;nbsp;shell&amp;nbsp;access.&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;这样就成功了~&lt;/p&gt;</description><pubDate>Fri, 27 Aug 2021 09:41:34 +0800</pubDate></item><item><title>JavaScript中undefined与null的区别</title><link>https://grazingwind.com/post/74.html</link><description>&lt;p&gt;大多数计算机语言，有且仅有一个表示&amp;quot;无&amp;quot;的值，比如，C语言的NULL，Java语言的null，Python语言的None，Ruby语言的nil。&lt;/p&gt;&lt;p&gt;有点奇怪的是，JavaScript语言居然有两个表示&amp;quot;无&amp;quot;的值：undefined和null。这是为什么？&lt;/p&gt;&lt;p&gt;&lt;img class=&quot;ue-image&quot; src=&quot;https://grazingwind.com/zb_users/upload/2021/08/202108191629337483881259.png&quot;/&gt;&lt;/p&gt;&lt;h2&gt;一、相似性&lt;/h2&gt;&lt;p&gt;在JavaScript中，将一个变量赋值为undefined或null，老实说，几乎没区别。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;a&amp;nbsp;=&amp;nbsp;undefined;
var&amp;nbsp;a&amp;nbsp;=&amp;nbsp;null;&lt;/pre&gt;&lt;p&gt;上面代码中，a变量分别被赋值为undefined和null，这两种写法几乎等价。&lt;/p&gt;&lt;p&gt;undefined和null在if语句中，都会被自动转为false，相等运算符甚至直接报告两者相等。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;if&amp;nbsp;(!undefined)&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(&amp;#39;undefined&amp;nbsp;is&amp;nbsp;false&amp;#39;);
//&amp;nbsp;undefined&amp;nbsp;is&amp;nbsp;false

if&amp;nbsp;(!null)&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;console.log(&amp;#39;null&amp;nbsp;is&amp;nbsp;false&amp;#39;);
//&amp;nbsp;null&amp;nbsp;is&amp;nbsp;false

undefined&amp;nbsp;==&amp;nbsp;null&amp;nbsp;
//&amp;nbsp;true&lt;/pre&gt;&lt;p&gt;上面代码说明，两者的行为是何等相似！&lt;/p&gt;&lt;p&gt;既然undefined和null的含义与用法都差不多，为什么要同时设置两个这样的值，这不是无端增加JavaScript的复杂度，令初学者困扰吗？Google公司开发的JavaScript语言的替代品Dart语言，就明确规定只有null，没有undefined！&lt;/p&gt;&lt;h2&gt;二、历史原因&lt;/h2&gt;&lt;p&gt;最近，我在读新书&lt;a href=&quot;http://speakingjs.com/&quot; target=&quot;_blank&quot;&gt;《Speaking JavaScript》&lt;/a&gt;时，意外发现了这个问题的答案！&lt;/p&gt;&lt;p&gt;原来，这与JavaScript的历史有关。1995年&lt;a href=&quot;https://www.ruanyifeng.com/blog/2011/06/birth_of_javascript.html&quot; target=&quot;_blank&quot;&gt;JavaScript诞生&lt;/a&gt;时，最初像Java一样，只设置了null作为表示&amp;quot;无&amp;quot;的值。&lt;/p&gt;&lt;p&gt;根据C语言的传统，null被设计成可以自动转为0。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;Number(null)
//&amp;nbsp;0

5&amp;nbsp;+&amp;nbsp;null
//&amp;nbsp;5&lt;/pre&gt;&lt;p&gt;但是，JavaScript的设计者Brendan Eich，觉得这样做还不够，有两个原因。&lt;/p&gt;&lt;p&gt;首先，null像在Java里一样，被当成一个对象。但是，JavaScript的数据类型分成原始类型（primitive）和合成类型（complex）两大类，Brendan Eich觉得表示&amp;quot;无&amp;quot;的值最好不是对象。&lt;/p&gt;&lt;p&gt;其次，JavaScript的最初版本没有包括错误处理机制，发生数据类型不匹配时，往往是自动转换类型或者默默地失败。Brendan Eich觉得，如果null自动转为0，很不容易发现错误。&lt;/p&gt;&lt;p&gt;因此，Brendan Eich又设计了一个undefined。&lt;/p&gt;&lt;h2&gt;三、最初设计&lt;/h2&gt;&lt;p&gt;JavaScript的最初版本是这样区分的：&lt;strong&gt;null是一个表示&amp;quot;无&amp;quot;的对象，转为数值时为0；undefined是一个表示&amp;quot;无&amp;quot;的原始值，转为数值时为NaN。&lt;/strong&gt;&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;Number(undefined)
//&amp;nbsp;NaN

5&amp;nbsp;+&amp;nbsp;undefined&amp;nbsp;
//&amp;nbsp;NaN&lt;/pre&gt;&lt;h2&gt;四、目前的用法&lt;/h2&gt;&lt;p&gt;但是，上面这样的区分，在实践中很快就被证明不可行。目前，null和undefined基本是同义的，只有一些细微的差别。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;null表示&amp;quot;没有对象&amp;quot;，即该处不应该有值。&lt;/strong&gt;典型用法是：&lt;/p&gt;&lt;p&gt;（1） 作为函数的参数，表示该函数的参数不是对象。&lt;/p&gt;&lt;p&gt;（2） 作为对象原型链的终点。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;Object.getPrototypeOf(Object.prototype)
//&amp;nbsp;null&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;undefined表示&amp;quot;缺少值&amp;quot;，就是此处应该有一个值，但是还没有定义。&lt;/strong&gt;典型用法是：&lt;/p&gt;&lt;p&gt;（1）变量被声明了，但没有赋值时，就等于undefined。&lt;/p&gt;&lt;p&gt;（2) 调用函数时，应该提供的参数没有提供，该参数等于undefined。&lt;/p&gt;&lt;p&gt;（3）对象没有赋值的属性，该属性的值为undefined。&lt;/p&gt;&lt;p&gt;（4）函数没有返回值时，默认返回undefined。&lt;/p&gt;&lt;pre class=&quot;prism-highlight prism-language-javascript&quot;&gt;var&amp;nbsp;i;
i&amp;nbsp;//&amp;nbsp;undefined

function&amp;nbsp;f(x){console.log(x)}
f()&amp;nbsp;//&amp;nbsp;undefined

var&amp;nbsp;o&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Object();
o.p&amp;nbsp;//&amp;nbsp;undefined

var&amp;nbsp;x&amp;nbsp;=&amp;nbsp;f();
x&amp;nbsp;//&amp;nbsp;undefined&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;本文转载自：https://www.ruanyifeng.com/blog/2014/03/undefined-vs-null.html&lt;/p&gt;</description><pubDate>Thu, 19 Aug 2021 09:32:21 +0800</pubDate></item></channel></rss>