使用Visual Studio Code编写和激活ABAP代码 (上)

猪年春节后的第一篇,Jerry祝各位猪年大吉!2019年的六分之一马上就快过完了,不知道大家在新的一年是否给自己定了新的小目标呢?这里Jerry先预祝大家到2019年年底的时候,在年初制定的小目标都能实现。2018年4月之前,Jerry一半时间为SAP S4CRM团队工作,剩下的一半时间为SAP C4C团队工作,所以那段时间大家能发现,Jerry公众号的文章主要是围绕着这两个SAP产品来写的。4月之后,Jerry换组,到了新的部门,工作内容也发生了变化,不再专注于某个特定的SAP产品,而是项目需要我熟悉什么产品,我就得熟悉什么产品,所以之后我的公众号文章,主题也逐渐多种多样起来。言归正传,Jerry之前的文章 那些年我用过的SAP IDE 曾经介绍过除了SAPGUI之外的其他ABAP开发工具和ABAP代码浏览工具。得益于Netweaver职责清晰的三层架构,提供了ABAP开发环境和运行环境的应用服务器层(下图中间的Application server layer)作为ABAP应用的核心, 其上可以灵活适配不同的展现层(Presentation layer), 比如WebIDE, Eclipse,和今天要介绍的Visual Studio Code。上图中应用服务器层的底层是数据库服务器层,Netweaver也支持多种主流数据库提供商的服务。例如下图是Jerry使用的一个Netweaver系统,支持包括SAP HANA在内的十种数据库管理系统(DBMS)。我们简单回顾下之前Jerry介绍过的不同的ABAP开发工具。首先是ABAP Development Tool(简称ADT), 对ABAP程序提供增删查改和激活操作的函数,通过位于路径sap/bc/下面的SICF服务节点adt暴露给外部消费者。ABAP Development Tool的Java端实现就是Eclipse的一个扩展,使用JCO(Java Connector)连接ABAP后台的adt服务,实现对ABAP程序的操作。关于ABAP Development Tool的细节,Jerry以前已经做过详细介绍,这里不再赘述,可以参考我这些文章:不喜欢SAP GUI?那试试用Eclipse进行ABAP开发吧Jerry在SAP Community上写给老外看的文章:https://blogs.sap.com/2014/08…而在浏览器里编写ABAP,即通常意义上的ABAP WebIDE,实现方式有两种。一种是通过传统的ITS(Internet Trasaction Server),通过这种方式在浏览器里显示的ABAP代码缺乏语法高亮:Jerry写过的相关博客:Open your SAP GUI transaction in Fiori launchpadhttps://blogs.sap.com/2016/12…How is old SAP GUI transaction embedded into Fiori launchpadhttps://blogs.sap.com/2016/12…另一种技术就是S/4HANA某些应用,比如Custom Logic采用的,支持语法高亮。当然这个语法高亮的支持不是天上掉下来的,详细实现参考我的博客:How ABAP syntax highlight is implemented in WebIDE launched via browserhttps://blogs.sap.com/2018/03…再回到今天聊的Visual Studio Code。SAP成都研究院很多前端开发的同事都向我推荐过这个IDE。Jerry试用过之后,印象最深的就是它那超快的启动速度,一流的扩展性和繁荣的生态圈。其扩展应用的丰富程度不亚于Sublime Text和Eclipse这些老牌开发工具。和SAP自研的ABAP Development Tool思路一样,本文介绍的Visual Studio Code扩展应用,ABAP Remote File System,也是通过另一种编程语言TypeScript去远程消费ABAP后台程序的增删查改服务。该扩展应用的作者叫Marcello,一位居住在伦敦的程序猿(Jerry想起了西甲皇家马德里足球队昔日的队宠)。这个Visual Studio Code的扩展是开源的,github仓库地址:https://github.com/marcellour…安装和配置的步骤在仓库的readme里有详细说明,最简单的方式就是在Visual Studio Code里直接用abap作为关键字搜索Market place,然后点Install安装。这个扩展的配置文件settings.json的内容可以参考下图:配置完成后,在Visual Studio Code的命令栏里能看到连接ABAP系统的指令和settings.json里配置的两条记录,任选一个后登入系统,显示该系统下的ABAP程序资源。操作它们的方式和基于Eclipse的ABAP Development Tool大同小异。当然也有一些Visual Studio Code提供的特色功能,比如下图这种类Google的即时搜索。这个扩展本身是不提供ABAP代码语法高亮的,需要安装另一个来自Lars Hvam贡献的语法高亮扩展。安装完毕后,ABAP的语法高亮也能顺利在Visual Studio Code里工作了。下面这张动图来自Marcello,演示了通过Visual Studio Code的这个扩展实现ABAP代码的基本编辑。作者在他的readme也明确注明,这个扩展还处于Beta测试阶段,使用者需自己承担风险。在Jerry看来,Visual Studio Code的这个扩展,如果用来做ABAP开发的话,功能还相对局限,但是如果对SAPGUI或者ABAP Development Tool产生了审美疲劳,想换一种工具来阅读ABAP源代码,那么它和下图的Sublime Text一样,都是不错的选择。将来如果Jerry有空,会在这篇文章的下半部分简单介绍下这个扩展的TypeScript实现细节。另外,今年Jerry也会争取能分享一些SAP云平台上ABAP编程环境的相关内容,敬请期待。感谢阅读。更多阅读动手使用ABAP Channel开发一些小工具,提升日常工作效率聊聊C语言和ABAPABAP vs Java, 蛙泳 vs 自由泳300行ABAP代码实现一个最简单的区块链原型Jerry的ABAP原创技术文章合集ABAP开发人员未来应该学些什么Jerry的ABAP, Java和JavaScript乱炖我用ABAP做过的那些无聊的事情不喜欢SAP GUI?那试试用Eclipse进行ABAP开发吧那些年我用过的SAP IDE要获取更多Jerry的原创文章,请关注公众号"汪子熙": ...

February 24, 2019 · 1 min · jiezi

haskell vscode下的环境搭配(包含各种坑的解决办法)

这可能是最傻瓜化的在vscode下的haskell配置介绍文章为什么要写这篇文章?在自己写搭建环境的过程中,搜了一些博文,有些真的及其不服责任和敷衍,草草几句话就带过,但是在google上排名还很高,带着一种鄙视这些文章的态度,于是写下这篇文章,希望给后面的人有帮助安装haskell我的平台:deepin-15.8,基于debian8,(ubuntu等应该这里是一份haskell的学习指南,粗略介绍了安装,资源等一些东西根据上面链接的内容,我们可以得知:不推荐使用Haskell-platform直接安装也不太推荐使用cabel更推荐使用stack安装官网安装文档安装For many Un*x operating systems, all you need to do is run://对于unix类系统curl -sSL https://get.haskellstack.org/ | shor:wget -qO- https://get.haskellstack.org/ | sh(对于windows系统)On Windows, you can download and install the Windows 64-bit Installer.创建你的project:stack new my-projectcd my-projectstack setupstack buildstack exec my-project-exeThe stack new command will create a new directory containing all the needed files to start a project correctly.The stack setup will download the compiler if necessary in an isolated location (default /.stack) that won’t interfere with any system-level installations. (For information on installation paths, please use the stack path command.).The stack build command will build the minimal project.stack exec my-project-exe will execute the command.If you just want to install an executable using stack, then all you have to do is stack install <package-name>.注意,linux系统最好将/.local/bin加入PATH中换源毕竟源在国外,所以我们首先必须要进行换源,幸好清华大学开源网站镜像站有提供,更具体一点可以看Stackage 镜像使用说明,这里记录下vim ~/.stack/config.yaml# addpackage-indices:- name: Tsinghua download-prefix: https://mirrors.tuna.tsinghua.edu.cn/hackage/package/ http: https://mirrors.tuna.tsinghua.edu.cn/hackage/00-index.tar.gzsetup-info: “http://mirrors.tuna.tsinghua.edu.cn/stackage/stack-setup.yaml"urls: latest-snapshot: http://mirrors.tuna.tsinghua.edu.cn/stackage/snapshots.json lts-build-plans: http://mirrors.tuna.tsinghua.edu.cn/stackage/lts-haskell/ nightly-build-plans: http://mirrors.tuna.tsinghua.edu.cn/stackage/stackage-nightly/# 开始使用stack,这个命令需要稍稍等待stack setup# 安装完成之后stack ghci# 会出现以下输出Configuring GHCi with the following packages:GHCi, version 8.0.1: http://www.haskell.org/ghc/ :? for helpLoaded GHCi configuration from /private/var/folders/0s/j3c0tlx10z9_x9wzhl14xmgh0000gn/T/ghci11066/ghci-scriptPrelude>搭建vscode打开vscode,下载extension,这里我推荐这四个插件:Haskell Syntax Highlighting、Haskell ghc-mod 、haskell-linter、Haskelly,其中第四个插件离不开stack。 要想使用以上插件,必须安装以下几个包:# for Haskell ghc-mod stack install ghc-mod# for haskell-linterstack install hlint# for Haskellystack install interostack install QuickCheckstack install stack-run安装时可能出现问题ghc-mod安装时如果报错stackoverflow上的解决办法我采用了stack install ghc-mod –resolver lts-8.24去解决stack-run安装报错github issueI found a workaround.Create a file: ~/.stack/global-project/stack-cabal-1.24.yamlflags: {}extra-package-dbs: []packages: []extra-deps: []resolver: lts-8.24Basically it’s using an old stack lts that was from around the time the last update to stack-run was >made.Then just run this:stack –stack-yaml ~/.stack/global-project/stack-cabal-1.24.yaml install stack-runand it should work (did for me, at least)intero安装报错stack install intero –resolver lts-8.24去解决vscode 插件配置然后打开vscode的配置文件,加上ghc-mod和hlint的路径,如下:“haskell.ghcMod.executablePath”: “/home/.local/bin/ghc-mod”,“haskell.hlint.executablePath”: “/home/.local/bin/hlint” ...

February 23, 2019 · 2 min · jiezi

弹性布局(display:flex;)

一、Flex布局-前言Flex是Flexible Box的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性,旨在提供一个更有效地布局、对齐方式,并且能够使容器中的子元素大小未知或动态变化情况下仍然能够分配好子元素之间的空间。Flex 布局的主要思想是使父容器能够调节子元素的宽度/高度(和排列顺序),从而能够最好地填充可用空间(主要是为了适应所有类型的显示设备和屏幕尺寸)。flex布容器能够放大子元素使之尽可能填充可用空间,也可以收缩子元素使之不溢出。最重要的是,flexbox布局与方向无关,不同于常规布局(基于垂直的块(block)和基于水平的内联(inline))。 虽然传统布局适用于页面,但它们对于大型或复杂的应用程序布局来说缺乏灵活性(特别是在改变方向,调整大小,拉伸,收缩等方面)。注:Flexbox布局最适合应用程序的组件和小规模布局,而 Gird 布局则适用于较大规模的布局。设为Flex布局以后,子元素的float、clear和vertical-align属性将失效。二、 基本概念采用 Flex 布局的元素,称为 Flex 容器(flex container),简称"容器"。它的所有子元素自动成为容器成员,称为 Flex 项目(flex item),简称"项目"。三、容器的属性display:flex;flex-directionjustify-contentspace-around 和 space-between 这两个值的区别不能很直观的理解。space-between 是两端对齐,使每个矩形子元素(flex项)之间的间隔是相等的,但两端的矩形子元素(flex项)不会和容器之间产生间隔。space-around 则会在每个矩形子元素(flex项)的两边产生一个相同大小的间隔,也就是说两端的矩形子元素(flex项)和容器之间的间隔大小正好是两个矩形子元素(flex项)之间间隔大小的一半(每个矩形子元素产生的间隔不会重叠,所以间隔变成两倍)。align-items(注意 对于 align-items: stretch 来说,必须将每一个矩形子元素(flex项)的高度设置为 auto,否则 height 属性将会覆盖该 stretch)对于 align-items: baseline 来说,要注意如果去掉段落标签或者没内容,矩形子元素(flex项)就会按照每个矩形的底部对齐,如下图所示:为了更好地演示主轴和交叉轴的区别,让我们结合 justify-content和align-items,看看在 flex-direction 两个不同属性值的作用下,轴心有什么不同:四、项目的属性以下6个属性设置在项目上orderflex-growflex-shrinkflex-basisflexalign-self4.1 orderorder属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。.item { order: <integer>;}4.2 flex-grow(拉伸)首先,让我们将所有的矩形子元素(flex项)设置为相同的width,120px:现在,涉及到名为 flex-grow 的属性,其默认值为 0 。这意味着矩形子元素(flex项)不允许自动占据容器中剩余的空间。这意味着什么呢?好吧,让我们尝试把为每个矩形子元素(flex项)的flex-grow设置为1:所有矩形子元素(flex项)共同占据了整个容器的宽度,它们之间的间隔也都是均匀分布。flex-grow 值覆盖了 width 值。然而,关于 flex-grow 令人困惑的是其值实际上意味着什么呢?flex-grow: 1是什么意思呢?嗯,如果设置每个矩形子元素(flex项)的 flex-grow 属性值为 999 ,让我们来看一下效果:正如你所看到的,完全一样。这是因为 flex-grow 不是绝对值 – 它是一个相对值。对于每个矩形子元素(flex项) 来说,重要的不是其 flex-grow 值有多大,而是这个值与其他矩形子元素(flex项) 的 flex-grow 值相比较,相对值有多大。如果我们将每个矩形子元素(flex项) 设置为flex-grow: 1,然后调整第 3 个矩形子元素的flex-grow值,那么我们可以看到改变,如图:要真正理解这里到底发生了什么,让我们快速过一边简单的数学知识。每个矩形子元素(flex项)的 flex-grow 初始值都是 1。如果我们将每个矩形子元素(flex项)的 flex-grow 相加起来,总和为 6。因此容器的总宽度被平均分成了 6 份。每个矩形子元素(flex项)增长到填充容器可用空间的1/6。当我们将第 3 个矩形子元素的 flex-grow 设置为 2 时,容器现在被分成了 7 等份,因为所有 flex-grow 属性是:1 + 1 + 2 + 1 + 1 + 1。第 3 个矩形子元素占了整个容器空间的 2/7,其他的占了 1/7。同理,当设置第 3 个矩形子元素的 flex-grow: 3 的时候,整个容器宽度被分成了 8 等份(1 + 1 + 3 + 1 + 1 + 1),第 3 个矩形子元素占了 3/8,其他的占了 1/8。以此类推。flex-grow 只和比例相关,如果我们设置第 3 个矩形子元素 flex-grow: 12,其余每个方块的 flex-grow: 4;跟第三个设置成 3,其他的设置成 1 得到同样的效果,见下图:重要的是每个矩形子元素的 flex-grow 与其他矩形子元素成比例的。最后一点,请记住,就像 flex-basis 一样,flex-grow 只适用于主轴(main axis)。我们的矩形子元素只会影响宽度,除非我们将 flex-direction设置为column。4.3 flex-shrink(收缩)flex-shrink 正好和 flex-grow 相反,它是决定矩形子元素允许收缩多少的。它的主要用途是指定哪些 flex项 要缩小,哪些 flex项 不要缩小。默认情况下,每个矩形子元素(flex项)都为 1 – 这意味着每个矩形子元素将随着容器收缩而收缩。让我们看看实际情况。 在下面的 GIF 中,每个矩形子元素(flex项)的 flex-grow 为1,所以他们填充满了整个容器,并且flex-shrink 为 1,所以他们被允许收缩。现在让我们将第 3 个矩形子元素的 flex-shrink 设置为 0 。它是禁止收缩,所以它会随着容器拉伸而拉伸,但是当容器收缩的时候,当其宽度收缩至设置的120px时,它不再允许收缩。flex-shrink 的默认值是 1 – 这意味着你的元素默认允许收缩,除非你告诉他们不允许收缩!同样, flex-shrink 约为比例。如果一个矩形子元素的 flex-shrink 为 6,并且其余flex-shrink 为 2,那么这个矩形子元素随着容器空间的收缩,将以 3 倍于其他矩形子元素的速度缩小。注意这里的措辞:3x(3倍)flex-shrink的矩形子元素将缩小 3倍。这并不是收缩1/3的宽度。稍后,我们将深入了解元素是如何收缩和拉伸的。但首先,让我们了解最后一个属性,把这些东西都串起来。4.4 flex-basisflex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。4.5 flexflex 是 flex-grow,flex-shrink 和 flex-basis 的缩写 – 所有这些都放在一起。它的默认值是0(grow),1(shrink)和 auto(basis)。4.5 align-selfalign-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。.item { align-self: auto | flex-start | flex-end | center | baseline | stretch;} ...

February 21, 2019 · 1 min · jiezi

如何让文本只显示两行——块级文字省略

在页面显示中我们经常会需要进行省略,比如简介里面的省略,比如固定div中字数超过限制之后的省略。我们可以用css轻松做到。单行文字的省略单行文字省略比较简单。关键代码如下:<style> .single { width: 280px; text-overflow: ellipsis; /* 文本溢出时显示省略号来代表被修剪的文本 / white-space: nowrap; / 段落中的文本不进行换行 / overflow: hidden; / 溢出部分隐藏 / border:1px solid red; }</style><body> <p class=“single”>春天,又称春季,是四季中的第一个季节,指立春至立夏期间,含节气有立春、雨水、惊蛰、春分、清明、谷雨</p></body>最终的效果是:当一行中的文本不固定的时候,可以设置一个max-width,当超过这个最大宽度,就进行省略,其他的时候不省略。常见应用如:历史搜索记录里面的记录显示。多行文字的省略多行文字的省略可以用css来做,也可以用js来做。先来看看css的做法。css:多行文字的省略主要用到-webkit-line-clamp属性,主要用来限制在一个块元素显示的文本的行数。但是这个属性不规范,要实现该效果,必须结合其他外来的WebKit属性。来看具体实现:<style> /让文字只显示2行/ .main-agency { width: 280px; overflow: hidden; text-overflow: ellipsis; / 文本溢出时显示省略号来代表被修剪的文本 / display: -webkit-box; / 必须结合的属性 ,将对象作为弹性伸缩盒子模型显示 / -webkit-box-orient: vertical; / 必须结合的属性 ,设置或检索伸缩盒对象的子元素的排列方式 / -webkit-line-clamp: 2; / 文本需要显示多少行 */ }</style><body> <div class=“main-agency”>feeeeeeeeeeee菲菲姐而非减肥法金额菲艾斯阿金费分解分解发黑发黄三板斧非法即使对方是反黑反腐的胜利会计法撒开了分解机菲菲姐宽带连接覅记得发分解飞机佛山飞机奥利弗降低房价大幅eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee</div></body>最终显示的效果如下:这个省略的效果也可以用js来做:js:<script>function subEllipsis(content) { content = content.length>24 ? content.substring(0,23)+’…’ : content}</script>js的做法适用于最多适配多少个字符的情况,但是如果想控制显示几行的话,css的方式显然更加方便。

February 19, 2019 · 1 min · jiezi

React

网页总是一个链接着另一个的,React一大优势在于每次链接到另一个页面上去的时候,不需要向传统页面一样,得销毁所有代码,重新渲染新页面的代码,而只在一个页面上展现新的内容——单页页面。React另一个优势是,以往的单页页面你需要考虑哪个元素要被删除、哪个元素的行为要被修改,而我们只需要告诉React我们想要的最终页面的效果,React会自动帮我们处理页面上的元素,做删除、修改等操作。而我只知道React有自己的虚拟DOM,它会对比虚拟DOM和真实DOM的差别,然后在适当的时机更新页面。至于它怎么对比的?怎么知道差别的?怎么进行修改的?我不知道,不过,对于我们,谁在乎呢?必须首先知道的关于React的术语JSX语法:React特有语法,用来搭建虚拟DOM组件(Component):一个个代码块,用来封装各种功能,可以类比于函数(function)props&status:组件的所有静态属性 & 所有动态属性引入React想要使用React,你需要先引入:<script src=“https://unpkg.com/react@16/umd/react.development.js" crossorigin></script><script src=“https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin</script><script src=“https://unpkg.com/babel-standalone@6/babel.min.js"></script>上面两个<script>引入了React的核心库,最后一句<script>引入jsx语法编译器,因为浏览器不懂jsx只知道javascript,所以,引入编译器转换为浏览器能懂的javascript语言请参考React官方文档以获取最新版本React的引入:https://reactjs.org/docs/add-…初步使用React并没有什么特别的技巧,先看代码,再做解释:<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <title>React First Try</title> <script src=“https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <script src=“https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> <script src=“https://unpkg.com/babel-standalone@6/babel.min.js"></script></head><body> <div id=“container”></div> <script type=“text/babel”> var container = document.querySelector("#container”); ReactDOM.render( <div> <p>Batman</p> <p>catwoman</p> </div>, container ); </script></body></html>解释:首先引入了三个<script>新建一个元素<div id=“container”></div>我们必须在一个<scripr type=“text/babel”>中使用React,请注意<script>的type像一般的javascript语法一样,我们先获取页面元素var container = document.querySelector("#container”);修改虚拟DOM,并渲染真实DOM其中,ReactDOM.render();就是在渲染,其含义是将第一个参数渲染到第二个参数下。而第一个参数<div>…</div>就是新的虚拟DOM的内容,可更改为我们想要的真实DOM结构。ReactDOM.render( <div> <p>Batman</p> <p>catwoman</p> </div>, container);效果、页面结构我们看到,页面中已经添加了包含两个<p>元素的<div>。React.render()函数的第一个参数只能是一个标签,不能是并列的两个标签。不过一个标签里的子标签可以随便的添加,所以最好的方法就是,在外面添加一个<div></div>使用组件(Component)上面的方法是直接将你想要的写在React.render()里,通常的做法是引用组件定义一个组件class 组件名 extends React.Component( //your code);组件里可以添加很多功能,比如想要添加一个按钮,你只需直接写你想要的DOM结构,而不需要使用javascript语法:createElement()、appendChild()等class 组件名 extends React.Component( render(){ return (<button>Batman</button>); });在组件里写好你想要的东西,使用React.render()进行渲染React.render( <组件名/>, 想要渲染的位置)完整代码可以如下<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <title>React First Try</title> <script src=“https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <script src=“https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> <script src=“https://unpkg.com/babel-standalone@6/babel.min.js"></script></head><body> <div id=“container”></div> <script type=“text/babel”> var container = document.querySelector("#container”); class Myname extends React.Component{ render(){ return (<button>Batman</button>); } }; ReactDOM.render( <Myname/>, container ); </script></body></html>效果、页面结构我们看到,页面上出现了我们想要的按钮,页面结构里也成功添加了<button>标签。注意!!!组件名首字母必须大写!!!引用组件注意代码<组件名/>,一个符号都不能错的!!!使用propsprops用来获取组件的静态属性,可以先看下面的一个小例子:<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <title>React First Try</title> <script src=“https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <script src=“https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> <script src=“https://unpkg.com/babel-standalone@6/babel.min.js"></script></head><body> <div id=“container”></div> <script type=“text/babel”> var container = document.querySelector("#container”); class Myname extends React.Component{ render(){ return (<button type={this.props.buttontype}>{this.props.children}</button>); } }; ReactDOM.render( <Myname buttontype=“submit”>Batman</Myname> , container ); </script></body></html>不必惊慌,修改的地方只有组件的render()和实际渲染的render()两个函数。第一个render()添加了<button>的type属性,该属性值指向{this.props.buttontype},意思是该组件名为buttontype的静态属性。这个render()还将<button>的显示文字指向{this.props.children},意思是该组件的子元素这个静态属性第二个render()函数添加了<Myname>的静态属性buttontype,和一个text类型的子元素Batman结论就是:在渲染真实DOM的时候,会创建一个<button></button>标签,它的type属性值为submit,文字显示为Batman效果、页面结构,哈哈哈,没啥区别,没区别就对了:props的传递性props只能从父元素向下传递给子元素:当有多个属性你想传递的时候,你的代码可能就会是这样的,会重复很多遍{this.props.propsName}:<script>class Me extends React.Component{ render(){ return ( <div> <p>{this.props.props1}</p> <p>{this.props.props2}</p> <p>{this.props.props3}</p> </div> ); }};class Father extends React.Component{ render(){ return ( <Me props1={this.props.props1} props2={this.props.props2} props3={this.props.props3}/> ); }};ReactDOM.render( <Father props1=“a” props2=“b” props3=“c”/>,container);</script>如果你不想重复很多遍繁琐的{this.props.propsName},那你可以使用扩展运算符…表示取到所有的静态属性并且都使等于{this.props.propsName},所以我们的代码可以稍作简化:<script>class Me extends React.Component{ render(){ return ( <div> <p>{this.props.props1}</p> <p>{this.props.props2}</p> <p>{this.props.props3}</p> </div> ); }};class Father extends React.Component{ render(){ return ( <Me {…props}/> //????????使用扩展运算符进行简化{…props} ); }};ReactDOM.render( <Father props1=“a” props2=“b” props3=“c”/>,container);</script>React操作CSS此方法可以使你在<script>里更改、渲染CSS。不过使用React的JSX语法会和CSS语法有一点点不同,就一点点┑( ̄  ̄)┍因为刚开始接触,代码不难,所以直接先看示例代码吧;<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <title>React First Try</title> <script src=“https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <script src=“https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> <script src=“https://unpkg.com/babel-standalone@6/babel.min.js"></script></head><body> <div id=“container”></div> <script type=“text/babel”> var container = document.querySelector("#container”); class Mycss extends React.Component{ render(){ var letterColor = { padding: 10, margin: 10, backgroundColor: this.props.thiscolor, color: “#333”, display: “inline-block”, fontFamily: “monospace”, fontSize: 32, textAlign: “center”, }; return (<div style={letterColor}>{this.props.children}</div>); } }; ReactDOM.render( <div> <Mycss thiscolor="#58B3FF”>B</Mycss> <Mycss thiscolor="#FF605F”>a</Mycss> <Mycss thiscolor="#FFD52E”>t</Mycss> <Mycss thiscolor="#49DD8E”>m</Mycss> <Mycss thiscolor="#AE99FF”>a</Mycss> <Mycss thiscolor="#FF6633”>n</Mycss> </div> , container ); </script></body></html>哇!!代码怎么看上去又有这么多的改动啊!!别慌张别慌张!其实和上一小节一样,只改动了一些内容在组件的render()和真实渲染的render()两个函数里组件render()里首先定义了一个虚拟CSS类,看上去符合CSS语法,但其实呢,他是一个JSX语法,仔细看,它就是一个用JSX语法写的神似CSS的对象。其中的一些区别如下:它不应该有px,px这种东西JSX会自动补充它不应该有分号;来表示这个属性结束了,请使用逗号,它应该把除了纯数字外的所有属性值都加上引号"“它应该使用驼峰命名法来表示CSS中使用连接号-的属性名:backgroundColor所以,在遵循了所有使用JSX语法描述CSS状态的规则之后,你就可以成功的定义一个虚拟CSS。接着,在组件的render()里调用它,像这样<div style={letterColor}>,style={虚拟CSS名}。在这里另一个知识点是,在定义虚拟CSS的backgroundColor时,它的参数值是一个变量this.props.thiscolor,同上一小节一样,在真实渲染render()的第一个参数里定义这个静态变量<Mycss thiscolor="#58B3FF”>。这样,就成功在CSS(虚拟的)里调用了其它地方的变量来确定属性值。效果、页面结构:值得注意的是,React处理的CSS是通过内联方式(标签中插入style属性)实现的小结这个时候,我们需要做一个小例子,来巩固下关于组件、CSS引入、props的概念我们想要实现的效果我们想要实现的效果就是,当你输入颜色代码,上面就能正确的展示颜色:分离组件在React的世界,一切都是组件,页面上所有的内容都是由一个个组件搭建起来的。你可以将结构划分为很小的组件,这样实现的功能就很详细。你也可以将结构划分为稍大的组件,功能就更集中。所以,像我们这样的小应用,下面的组件划分方法就足以满足要求:编写程序在分析完结构需要分成多少组件之后,可以开始构造代码首先,我们编写组件框架。其中每一个class就代表了我们分成的组件。在这里class ColorName表示文字部分,class Color表示颜色显示区,class Board表示用来承载这个应用的底板。每个组件都有一个render()函数用来之后渲染组件到DOM上。<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <title>Color</title> <script src=“https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <script src=“https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> <script src=“https://unpkg.com/babel-standalone@6/babel.min.js"></script></head><body> <div id=“container”></div> <script type=“text/babel”> var container = document.querySelector("#container”); class ColorName extends React.Component{ render(){ } }; class Color extends React.Component{ render(){ } }; class Board extends React.Component{ render(){ } }; ReactDOM.render( <Board/>,container ); </script></body></html>上述步骤等于搭完了骨架,我们需要填充肌肉。写下,最终需要每个组件分别返回什么标签:ColorName组件返回一个<p>标签,用以展现颜色的色号Color组件返回一个<div>标签,用来显示颜色Board组件返回一个<div>标签,并且把上两个组件包在一起<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <title>Color</title> <script src=“https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <script src=“https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> <script src=“https://unpkg.com/babel-standalone@6/babel.min.js"></script></head><body> <div id=“container”></div> <script type=“text/babel”> var container = document.querySelector("#container”); class ColorName extends React.Component{ render(){ return (<p>{this.props.colorName}</p>); } }; class Color extends React.Component{ render(){ return (<div id=“color”></div>); } }; class Board extends React.Component{ render(){ return ( <div> <Color colorName = {this.props.colorName}/> <ColorName colorName = {this.props.colorName}/> </div> ); } }; ReactDOM.render( <Board colorName="#f7a87d”/>,container ); </script></body></html>接下来我们只需要添加你想要的CSS就OK了,不过在添加CSS之前,我想对上一步骤简单解释:我们在渲染真实DOM时定义了一个静态属性colorName="#f7a87d”,经由组件Board传入组件ColorName、Color。最后通过每个组件各自的render()函数的return渲染在页面上。最后我们需要添加一些CSS帮页面穿点衣服,其中对CSS的引入使用了两种方法,使用React引入和引入外部CSS文件:<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <title>Color</title> <script src=“https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <script src=“https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> <script src=“https://unpkg.com/babel-standalone@6/babel.min.js"></script> <style> #board{ width: 300px; height: 400px; /* border: 1px solid red; */ border-radius: 3%; box-shadow: 3px 5px 7px 1px rgba(128,128,128,1); } #color{ height: 80%; border-radius: 3%; box-shadow: 1px 1px 6px 1px rgba(128,128,128,1); } </style></head><body> <div id=“container”></div> <script type=“text/babel”> var container = document.querySelector("#container”); class ColorName extends React.Component{ render(){ var ColorNameStyle = { fontSize: “2.5em”, fontFamily: “sans-serif”, fontWeight: “bold”, textAlign: “center”, margin: 17, }; return (<p style={ColorNameStyle}>{this.props.colorName}</p>); } }; class Color extends React.Component{ render(){ var colorStyle = { backgroundColor: this.props.colorName, }; return (<div style={colorStyle} id=“color”></div>); } }; class Board extends React.Component{ render(){ return ( <div id=“board”> <Color colorName = {this.props.colorName}/> <ColorName colorName = {this.props.colorName}/> </div> ); } }; ReactDOM.render( <Board colorName="#f7a87d”/>,container ); </script></body></html>使用state以上的各个步骤可以创建一个基本的静态页面,如果想要创建一个有点动态,看上不是死气沉沉的页面,那就一定需要state。正如之前提到的,props包含了所有的静态属性,state则包含了所有用于动态展示的属性。这时,我们需要一个例子我们的目标分离组件外面一个黑的长方形边框;内部一个黑色的底板;#5dffff的动态数字;三行文字编写代码编写代码框架:Times类表示变化的数字;Words表示三行灰色的文字;BlackBoard表示黑色的底板;Board表示最外面一圈黑边框<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <meta name=“viewport” content=“width=device-width, initial-scale=1.0”> <meta http-equiv=“X-UA-Compatible” content=“ie=edge”> <title>Lightning</title> <script src=“https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <script src=“https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> <script src=“https://unpkg.com/babel-standalone@6/babel.min.js"></script></head><body> <div id=“container”></div> <script type=“text/babel”> var container = document.querySelector("#container”); class Times extends React.Component{ render(){ return (); } }; class Words extends React.Component{ render(){ return (); } }; class BlackBoard extends React.Component{ render(){ return (); } }; class Board extends React.Component{ render(){ return (); } }; ReactDOM.render( <Board/> ,container ); </script></body></html>然后我们需要添上返回的内容,我们就只看React的内容<script type=“text/babel”> var container = document.querySelector("#container”); class Times extends React.Component{ render(){ return (<h1>Strike Times</h1>); } }; class Words extends React.Component{ render(){ return ( <div> <p>lightning strike</p> <p>worldwide</p> <p>(since you loaded this outstanding)</p> </div> ); } }; class BlackBoard extends React.Component{ render(){ return ( <div> <Times/> <Words/> </div> ); } }; class Board extends React.Component{ render(){ return ( <div> <BlackBoard/> </div> ); } }; ReactDOM.render( <Board/> ,container );</script>将Strike Times变成动态,我们只需改变Times类:首先需要定义state:必须在constructor内定义this.state={}constructor(props){ super(props); this.state = { strike: 0, };}使用生命周期钩子,componentDidMount钩子里的内容会在页面渲染完成后被调用.在本例中,页面渲染完成后会调用一个计时器setInterval(),计时器中调用的函数请使用箭头函数,这样被调用的函数里的this才会被正确的指向当前类,其它调用方法会指向windowcomponentDidMount() { setInterval(() => this.addNumber(),1000);}定义你想调用的函数注意!!!如果你想修改state中的值,请必须使用this.setState()来修改!!addNumber(){ this.setState({ strike: this.state.strike + 100, });}最后,设定返回值,显示的内容为state中的strike值render(){ return (<h1>{this.state.strike}</h1>);}加上点样式<script type=“text/babel”> var container = document.querySelector("#container”); class Times extends React.Component{ constructor(props){ super(props); this.state = { strike: 0, }; } componentDidMount() { setInterval(() => this.addNumber(),1000); } addNumber(){ this.setState({ strike: this.state.strike + 100, }); } render(){ var strikeStyle = { margin: 0, padding: “55px”, color: “#5dffff”, fontSize: “60px”, } return (<h1 style={strikeStyle}>{this.state.strike}</h1>); } }; class Words extends React.Component{ render(){ var words = { fontFamily: “sans-serif”, margin: 0, padding: 0, }; var wordStyle = { wordNormal: { …words, color: “#999999”, fontSize: 33, }, wordBig: { …words, color: “#999999”, fontSize: 50, }, wordSmall: { …words, color: “#4d4d4d”, }, } return ( <div> <p style = {wordStyle.wordNormal}>lightning strike</p> <p style = {wordStyle.wordBig}>worldwide</p> <p style = {wordStyle.wordSmall}>(since you loaded this outstanding)</p> </div> ); } }; class BlackBoard extends React.Component{ render(){ return ( <div style = {this.props.style}> <Times/> <Words/> </div> ); } }; class Board extends React.Component{ render(){ var boardStyle = { board: { width: 300, height: 400, padding: 13, backgroundColor: “white”, border: “2px solid black”, }, blackboard: { height: “100%”, backgroundColor: “black”, borderRadius: “7%”, textAlign: “center”, lineHeight: “50px”, } }; return ( <div style={boardStyle.board}> <BlackBoard style = {boardStyle.blackboard}/> </div> ); } }; ReactDOM.render( <Board/> ,container );</script>使用JSX即使我们在之前的文章中已经开始使用了JSX这种React特别的语法,但是,我们还是应该为它专门开辟一个新的章节,因为,JSX、组件、组件生命周期是React的三大奠基核心(哈哈哈,当然是我的个人见解)。说到JSX,令人印象深刻的就是各种在js里添加html标签和出现在各个地方的{}在js里添加html标签在提倡 css样式、js行为、html标签 分离的时代,这样的设计别出心裁。主要是因为React的基础设施不是传统的html标签,而是各个组件。一个组件里包含了构成页面某一部分所需要的所有的 css样式、js行为、html标签 。 所以,遵循这样的思路,在js里添加html标签没什么稀奇的。像这样:var myname = <h1>Batman</h1>;function functionName(){ // your codes return <h1>Batman</h1>;}const me = ( <div> <h1>Batman</h1> <h2>hello gotham</h2> </div>);注意!!!JSX不能够将 多个html标签 直接赋给一个变量或者直接返回,需要将 多个html标签 包括在一个父元素中,就像上例第三个例子一样。{}在js里添加html标签对我们来说已经见怪不怪了,大括号{}的使用才是精髓。哈哈哈~~{}用于在React中的各个地方引用各种合理的JS表达式(valid JavaScript expression)。大括号里可以是变量user.username、表达式2+2、函数调用functionName(user)等。像这样:const name = ‘Josh Perez’;const element = <h1>Hello, {name}</h1>;const element = <img src={user.avatarUrl}></img>;const element = <h1>2+2={2+2}</h1>;function formatName(user) { return user.firstName + ’ ’ + user.lastName;}const user = { firstName: ‘Harper’, lastName: ‘Perez’};const element = ( <h1> Hello, {formatName(user)}! </h1>);ReactDOM.render( element, document.getElementById(‘root’));另外,还有双括号{{}}的写法,这种表达方式用于在JSX里内联样式。{{}}内的内容:对象的写法,将css里的;变成,属性名使用驼峰写法,css里-后面的第一个字母大写只会生效最后一个style,下例中只会生效style={gothamStyle}var myName = <h1 style={{color:“black”}} style={{fontSize:“25px”}} style={gothamStyle}>Batman</h1>;像这样:const myName = <h1 style={{color:“black”,fontSize:“25px”}}>Batman</h1>;关于更多React中操作CSS,你还可以浏览这篇文章:https://www.jianshu.com/p/850…JSX的优势防止XSS (cross-site-scripting)攻击。因为所有内容在被React渲染到页面上前都会先转成字符串小巧灵活。JSX本质就是Javascript,所以,JSX可以被放在任何一个地方。再加上JSX里的内容非常丰富。结合React的设计思想,JSX非常好用。当然JSX还可以撰写css内容,详细可以参见之前章节:React操作CSS使用JSX的一个例子只要使用React搭建网站必然需要用到JSX,额,虽然官方是这样表示的:Well我们还是快速的过一遍这个例子我们要实现的目标几个圆圈过1秒就变颜色,颜色随机从颜色库里选取完整代码其实很简单,Circle组件负责改变颜色的行为,CreateCircle组件负责定义样式并渲染这些圆圈。然后因为一直是动态的,所以,使用Circle组件的state,每个一段时间setInterval都会调用changeColor函数,来改变state里的内容,改变之后React会重新渲染页面被改动的部分。值得注意的是,在这个例子中,JSX被运用在任何一个位置,可以被压到数组中去colorarray.push(<CreateCircle bgColor={colors[random]} key={i}/>)被渲染render(){ return (<div>{this.state.colorArray}</div>);};撰写、引用cssclass CreateCircle extends React.Component{ render(){ var circleStyle = { padding: 10, margin: 20, display: “inline-block”, backgroundColor: this.props.bgColor, borderRadius: “50%”, width: 100, height: 100, }; return (<div style={circleStyle}></div>); }};注意!!!在React中使用key={}属性来唯一标识一个组件<CreateCircle key={i}/>完整代码:<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <meta name=“viewport” content=“width=device-width, initial-scale=1.0”> <meta http-equiv=“X-UA-Compatible” content=“ie=edge”> <title>Lightning</title> <script src=“https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <script src=“https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> <script src=“https://unpkg.com/babel-standalone@6/babel.min.js"></script></head><body> <div id=“container”></div> <script type=“text/babel”> var container = document.getElementById(“container”); var colors = ["#393E41”,"#E94F37”,"#1C89BF”,"#A1D363”,"#85FFC7”,"#297373”,"#FF8552”,"#A40E4C”]; class Circle extends React.Component{ constructor(props){ super(props); this.state = { colorArray: [], }; }; changeColor(){ var colorarray = []; this.setState({ colorArray: [], }); for(var i=0;i < colors.length;i++){ var random = Math.floor(Math.random()*colors.length); colorarray.push(<CreateCircle bgColor={colors[random]} key={i}/>) this.setState({ colorArray: colorarray, }); } }; componentDidMount(){ setInterval(() => this.changeColor(),1000); }; render(){ return (<div>{this.state.colorArray}</div>); }; }; class CreateCircle extends React.Component{ render(){ var circleStyle = { padding: 10, margin: 20, display: “inline-block”, backgroundColor: this.props.bgColor, borderRadius: “50%”, width: 100, height: 100, }; return (<div style={circleStyle}></div>); } }; ReactDOM.render( <Circle/> ,container ) </script></body></html>React中的事件事件的意义不用多说,事件是页面与用户交互的唯一途径,人机交互大部分还是通过鼠标和键盘吧,当然还有像手写板、麦克风、摄像头等设备,但截至今日前端貌似没有什么权限,不然安全性就太差了。在React中,事件的绑定大致和原生网页相似,大概也就是命名方式不同和this的指向不同这两点区别。可以参考:https://reactjs.org/docs/hand…在React中绑定事件直接绑定class Button extends React.Component{ render(){ return (<button onClick=“console.log(‘Hello gotham’)">Click me!</button>) }}WHAT??这不是和原生的一模一样吗?是呀,只是在命名上采用的是React喜爱的驼峰Camel-Case命名法,原生的都是小写。但这种方法多老式。间接绑定class Button extends React.Component{ consoleLog(){ console.log(“Hello gotham”); } render(){ return (<button onClick={this.consoleLog}>Click me!</button>) }}将函数拿到外面去,然后在元素的事件上绑定这个函数,绑定的时候使用JSX的{}并且一定加上this,表示绑定的是这个组件里的函数。超级间接绑定class Inner extends React.Component{ render(){ return (<button onClick={this.props.clickHandler}>Click me!</button>) }}class Outer extends React.Component{ consoleLog(){ console.log(“Hello gotham”); } render(){ return (<Inner clickHandler={this.consoleLog}/>) }}哈哈哈,这是什么鬼?就是利用了React的props,把函数绑定在一个props上,本例中是clickHandler,然后渲染了新组件,在新组件中,可以使用this.props来调用这个函数。简单来说就是,将函数从父组件通过props传递到了子组件。this的指向在React中,绝大部分的this都指向组件本身。但是,在自定义的函数中,this是没有指向的,所以会有this is undefined的报错,尤其是自定义的函数需要引用函数外组件内的其它资源的时候。像下面这样写是会报错的:我们想要点击Hello gotham按钮调用greeting函数,greeting函数会调用gotham函数打印Hello gotham字样。但是,greeting函数里的this没有指向,所以会出现上面的报错。class Welcome extends React.Component{ gotham(){ console.log(“Hello gotham”); } greeting(){ this.gotham(); } render(){ return (<button onClick={this.greeting}>Hello gotham<button/>) }}所以,如果想要在自定义函数中调用同组件其它资源,你有下面3中方法来绑定this:constructor中绑定class Welcome extends React.Component{ constructor(props){ super(props); this.greeting = this.greeting.bind(this); ????这句是绑定 } gotham(){ console.log(“Hello gotham”); } greeting(){ this.gotham(); } render(){ return (<button onClick={this.greeting}>Hello gotham<button/>) }}内联式绑定class Welcome extends React.Component{ gotham(){ console.log(“Hello gotham”); } greeting(){ this.gotham(); } render(){ ????????????????????????这里是绑定 return (<button onClick={this.greeting.bind(this)}>Hello gotham<button/>) }}内联式箭头函数绑定class Welcome extends React.Component{ gotham(){ console.log(“Hello gotham”); } greeting(){ this.gotham(); } render(){ ????????????????????????????????????????????????这里是绑定 return (<button onClick={(e) => this.greeting(e)}>Hello gotham<button/>) }}关于绑定this还可以参考:https://www.jianshu.com/p/95a…合成事件SyntheticEventReact中的合成事件可以对应为通常函数中的事件对象eventfunction gotham(event){ // your codes}e…这个功能有点多,你可以自己打印出来看看呀,或者看看官方文档:https://reactjs.org/docs/even…这里只贴出来关于鼠标和键盘事件:鼠标事件boolean altKeyboolean ctrlKeyboolean shiftKeyboolean metaKeynumber buttonnumber buttonsnumber clientXnumber clientYboolean getModifierState(key)number pageXnumber pageYDOMEventTarget relatedTargetnumber screenXnumber screenY适用于如下事件:onClick onContextMenu onDoubleClick onDrag onDragEnd onDragEnter onDragExit onDragLeave onDragOver onDragStart onDrop onMouseDown onMouseEnter onMouseLeave onMouseMove onMouseOut onMouseOver onMouseUp键盘事件boolean altKeynumber charCodeboolean ctrlKeyboolean getModifierState(key)string keynumber keyCodestring localenumber locationboolean metaKeyboolean repeatboolean shiftKeynumber which适用于如下事件:onKeyDown onKeyPress onKeyUp关于事件的小例子我们的目标点击加号按钮数字加1,按住shift点击加号,数字加10实现思路分割组件。底板、数字、按钮点击按钮数字变化,所以,将资料存放于数字组件,并且通过数字组件调用按钮键盘事件的合成事件中,能够监听shift键是否被按下抛开样式的完整代码其它的无关紧要,注意Show组件内的increase函数,我们可以看到合成事件e.shiftKey和{this.increase.bind(this)}的使用<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <title>react-event</title> <script src=“https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <script src=“https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> <script src=“https://unpkg.com/babel-standalone@6/babel.min.js"></script></head><body> <div id=“container”></div> <script type=“text/babel”> var container = document.querySelector("#container”); class Button extends React.Component{ render(){ return (<button onClick={this.props.clickHandler}>+</button>) } } class Show extends React.Component{ constructor(props){ super(props); this.state = { number: 0, }; } increase(e){ var num = this.state.number; if(e.shiftKey){ num += 10; }else{ num += 1; } this.setState({ number: num, }); } render(){ return ( <div> <p>{this.state.number}</p> <Button clickHandler={this.increase.bind(this)}/> </div> ) } } class Board extends React.Component{ render(){ return ( <div> <Show/> </div> ); } }; ReactDOM.render( <Board/>, container ) </script></body></html>组件的生命周期LifecycleReact创造出来组件,同时也给组件配上了生命周期,用来更好的控制组件,这也是React的一大优势。组建的生命周期可以参考这个:https://reactjs.org/docs/reac…。往下多翻翻~~这个参考资料也非常棒:https://www.w3cplus.com/react…常用生命周期componentDidMount()componentDidUpdate()componentWillUnmount()不常用且慎用的生命周期shouldComponentUpdate()static getDerivedStateFromProps()getSnapshotBeforeUpdate()static getDerivedStateFromError()componentDidCatch()消失的生命周期消失的生命周期不理他。React Router官方文档:https://reacttraining.com/rea…github:https://github.com/ReactTrain…React Router就把他看作是一个插件吧,中文名:React路由。 ...

February 17, 2019 · 7 min · jiezi

vscode插件开发实践与demo源码

vscode插件开发实践与demo源码写在前面工欲善其事必先利其器。vscode作为优秀的开发工具,给我的日常开发工作提供了极大的便利。其拓展机制更是如此。但是,最近在做年度专业线任务时,有需要用到漂亮的行尾注释对齐,搜索后发现vscode官方插件市场没有我想要的。于是便想着自己来开发这么个东西,一方面方便后边自己使用,一方面也能学习下vscode的插件开发、发布方法,另一方面要是发布后对其他人有所帮助就更好了。本文主要内容这篇文章是在我完成插件开发、发布后写的,记录下方法。主要包含两个方面的内容:vscode插件开发、发布主要流程vscode插件demo源码参考https://github.com/gitshan/vscode-extension-comment-alignervscode插件开发、发布主要流程插件开发前的准备:vscode、nodejs、vscode插件生产工具、git、微软账号插件开发:插件构思、官方文档查阅插件发布:打包、上传、插件市场操作插件维护:更新迭代后打包、上传、插件市场操作插件开发前的准备:vscode、nodejs、git、微软账号,这个的准备无需多说。vscode插件生产工具:官方推荐使用Yeoman 和 VS Code Extension Generator。用如下命令安装:npm install -g yo generator-code至此开发所需的准备已做好。插件开发使用生产工具初始化代码执行如下指令yo code结果如下:$ yo code —– ╭──────────────────────────╮ | | │ Welcome to the Visual │ |–(o)–| │ Studio Code Extension │ ---------´ │ generator! │ ( _´U_ ) ╰──────────────────────────╯ /A\ / | ~ | ’..’_ ´ |° ´ Y? What type of extension do you want to create? (Use arrow keys)> New Extension (TypeScript) New Extension (JavaScript) New Color Theme New Language Support New Code Snippets New Keymap New Extension Pack(Move up and down to reveal more choices)在os系统上通过上下键来选择要创建的类型,在win上输入1、2、3后按回车来选择。其余步骤根据提示即可。得到如下结构目录结构:├── .vscode // 资源配置文件├── CHANGELOG.md // 更改记录文件,会展示到vscode插件市场├── extension.js // 拓展源代码文件├── jsconfig.json├── package.json // 资源配置文件├── README.md // 插件介绍文件,会展示到vscode插件市场├── test // 测试文件└── vsc-extension-quickstart.mdps:其余项目类型的文档目录可能会有所差别,以生成的文件目录为准。在js拓展项目下,最重要的就是extension.js和package.json。插件构思灵感来源于生活、工作,这个想到了就可以去做。比如我这个行尾注释对齐(上面的目录注释就是用的我刚开发好的插件)。关于comment-aligner的具体思路就不写在这里了,感兴趣的可以去下载源码看看,里边包含了完整的注释。逻辑十分简单。查阅文档开发这里不得不说一下官方文档不太好看,至少不是那么友好。传送门https://code.visualstudio.com/api/references/vscode-api。英文实在吃力的可以使用chrome的一键翻译,翻译的还算准确的。对于基本的应用主要查看window相关的就足够了,结合yo code生成的基本代码可以实现简单的功能。插件发布安装打包、发布工具npm install -g vsce创建发布人在插件市场官网创建发布人完善package.jsonpackage.json中有vscode的自定义配置,在执行打包命令时vscode会自检,如果配置错误或者遗漏会有提示信息。较完整的信息如下(下方是我发布的comment aligner的package.json文件):{ “name”: “comment-aligner”, “displayName”: “comment aligner”, “description”: “A tool for aligning the inline trailing comment”, “version”: “1.0.1”, “publisher”: “huangbaoshan”, // 发布人,在插件市场官网创建的发布人id “icon”: “icon/icon.png”, // 插件图标,用于在插件市场展示的icon;可以放到同级目录内,打包会带入 “repository”: { “type”: “git”, “url”:“https://github.com/gitshan/vscode-extension-comment-aligner.git" }, “engines”: { “vscode”: “^1.30.0” // vscode版本号 }, “categories”: [ “Other” // vscode插件类别,会在插件市场的对应类别中展示 ], “activationEvents”: [ “onCommand:extension.commentaligner” ], “main”: “./extension.js”, “contributes”: { “commands”: [{ “command”: “extension.commentaligner”, // 插件注册的类名 “title”: “Comment Aligner” // 插件在命令面包的展示名称 }] }, “scripts”: { “postinstall”: “node ./node_modules/vscode/bin/install”, “test”: “node ./node_modules/vscode/bin/test” }, “devDependencies”: { “typescript”: “^3.1.4”, “vscode”: “^1.1.25”, “eslint”: “^4.11.0”, “@types/node”: “^8.10.25”, “@types/mocha”: “^2.2.42” }}打包执行如下命令:vsce package在根目录得到:comment-aligner-1.0.1.vsix文件发布方法一:用vsce的vsce publish工具来发布,但是需要在官网配置Personal Access Token较为繁琐。可参考官方教程方法二:在官网直接上传发布上传后点击确定即可发布成功。发布检查在插件市场官网看状态在插件市场官网搜索在vscode插件页搜索以上均表示已发布成功。插件维护在发现bug和新功能开发完成后,需要更新插件,只需要将新生产的.vsix包上传到官网即可。最后希望有用,谢谢大家。 ...

February 13, 2019 · 1 min · jiezi

VSCode 小鸡汤 第01期 - REST Client 简单好用的接口测试辅助工具

介绍今天给大家介绍一个后端开发辅助的好工具 —— REST Client,插件如其名这就是一个 REST 的客户端插件,把我们的 VSCode 转化为一个 REST 接口测试的利器我们一般都会用 PostMan 来完成接口测试的工作,因为用起来十分简单快捷,但是一直以来我也在寻找更好的方案,一个不用切换窗口多开一个 app 的方案 —— 终于在使用 VSCode 一段时版本间,我找到了 REST Client 插件,初看 REST Client 插件的时候,会觉得他十分的简陋,但是在使用一段时间后会发现在 REST Client 插件中已经有完成接口测试所需的所有东西优势基于 HTTP 语言,HTTP 语言是一门非常简单的语言,使用 HTTP 语言可以轻松的描述请求纯文本记录,不同于 PostMan 保存在云端,或是 Paw 那样保存二进制文件,并且纯文本可以使用 git 追踪内容的变化无需切换窗口,测试,调试,代码编辑都在一个 VSCode 中完成劣势操作和使用不像 PostMan 之类的图形化工具那么直观不支持请求前后对数据进行操作的脚本,不过这个已经在作者的开发计划中很多时候我们只是需要写完代码后手边有一个小工具可以轻松愉快的看一眼接口是否正常,那么 REST Client 就是我们的首选了使用介绍安装和入门插件的安装非常简单,搜索 restclient 即可安装安装完成后,可以在命令菜单中找到 REST Client 相关的功能简单请求我们先从发送最简单的请求开始首先需要新建一个 http 文件,创建文件时后缀为 http 即可,例如 test.http之后输入下面的内容:GET http://localhost:8000/api/v1/public/echo?msg=1345asdf HTTP/1.1echo 是一个测试服务,他会返回你传入的 msg 的内容,输入完上面的这时候请求上面会显示一个 “Send Request” 按钮,点击即可发送请求,请求完成后,插件会分割当前窗口将新的结果打开在右侧的窗口中,下图中显示了请求的所有相关信息HTTP 语言基础语言入门HTTP 是一个非常简单的语言,入门仅需几分钟最基本的 HTTP 语言语法入门可以参看上面的内容,配合 VSCode 的自动提示功能,用起来简直不要太快也不用担心是否记得 header 里面那些选项,想不起来的时候 Ctrl + 空格 调出自动提示即可要注意的地方请求文本最后面需要有一个空行,或者一个 # 开头的行,建议空行,这样多个请求看起来会非常好看如果需要把 form 类型的参数拆分为多行,那么第二个参数开始必须以 & 开始(如图)GET 请求也可以将参数拆分多行,每行开头必须以 ? 或者 & 开始发送文件一般来说,我们使用 multipart/form-data 请求方式来完成如图配置,REST Client 就会将文件内容填充到相应的区域完成发送保存请求结果对于返回图片的接口在 VSCode 中是可以直接预览的,如果是 Excel 之类的二进制文件,那么这里可能会显示乱码(二进制文件)选中相应结果页,右上角提供了保存结果的按钮查看请求历史使用 Ctrl + Alt + H(macOS 使用 Cmd + option + H)查看请求历史使用变量变量的好处,在开发过程中我们都知道,在 HTTP 语言中同样可以使用变量来帮助我们组织请求代码自定义变量我们可以在 http 文件中直接定义变量,使用 @ 符号开头,以 {{variable name}} 的格式来使用@host = http://localhost:8000@token = adsfasdfasdfadsfasdfasdfas### testGET {{host}}/api/v1/public/echo HTTP/1.1 ?msg=1345asdf &bundle_id=demo &test=1 &token={{token}}### test requestPOST {{host}}/api/v1/public/echo HTTP/1.1Content-Type: application/x-www-form-urlencodedUser-Agent: iPhonetest=1&bundle_id=demo&msg=123123&token={{token}}这样在测试验证不同环境接口正确性的场合,我们可以很方便的在不同服务器之间切换,或是所有接口都使用同一个参数的时候非常方便例如上面的 token 应该是大部分接口都会使用到的环境变量除了使用自定义变量以外还可以对当前的项目或是创建编辑器全局的环境变量"rest-client.environmentVariables": { “$shared”: { “version”: “v1” }, “local”: { “version”: “v2”, “host”: “http://localhost:8000”, “token”: “tokentokentokentoken1” }, “prod”: { “host”: “http://api.xxxxxx.com”, “token”: “tokentokentoken2” }}上面 $shared 中的变量表示在所有环境设置中都可以使用的设置后可通过 Ctrl + Alt + E(Cmd + option + E)切换环境系统变量REST Client 提供了一些自带的系统变量,方便我们直接使用(这里由于我没有使用过 Azure 所以跳过了 Azure 相关的变量,大家可以参考文档使用){{$guid}}: 生成一个 UUID{{$randomInt min max}}: 生成随机整数{{$timestamp [offset option]}}: 生成时间戳,可以使用类似 {{$timestamp -3 d}} 生成3天前的时间戳,或是使用 {{$timestamp 2 h}} 这样的形式生成2小时后的时间戳{{$datetime rfc1123|iso8601 [offset option]}}: 生成日期字符串VSCode 提供的辅助功能VSCode 对我们使用 HTTP 语言提供了包括自动提示,Outline 代码导航功能,方便我们编写接口测试代码自动提示Outline 以及代码导航验证和证书Basic AuthBasic Auth 可以使用已经 Base64 后的 username:password,也可以直接填入 username 和 password,也就是下面两种形式都是可以的使用 Base64 的结果POST {{host}}/api/v1/public/echo HTTP/1.1Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=使用 username 和 passwordPOST {{host}}/api/v1/public/echo HTTP/1.1Authorization: Basic username passwordDigest AuthDigest Auth 直接填入 username 和 password 即可POST {{host}}/api/v1/public/echo HTTP/1.1Authorization: Digest username passwordSSL 证书ssl 证书在设置文件中对特定域名指定证书路径后,就可以自动生效了"rest-client.certificates": { “localhost:8081”: { “cert”: “/Users/demo/Certificates/client.crt”, “key”: “/Users/demo/Keys/client.key” }, “example.com”: { “cert”: “/Users/demo/Certificates/client.crt”, “key”: “/Users/demo/Keys/client.key” }}每个 host 我们可以设置下面的内容:cert: x509 证书路径key: 私钥路径pfx: PKCS #12 或者 PFX 证书路径passphrase: 证书密码(需要时设置)代码生成曾经使用 Postman 的时候,Postman 的代码生成功能为我提供了非常多的方便,REST Client 中提供了同样的功能选中一个请求后,点击右键选择 Copy Request As cURL 可以把当前的请求复制成 curl 的命令,也可以使用 Ctrl + Alt + C(macOS 下Cmd + Option + C)呼出代码生成菜单,选择需要生成的语言选择语言后选择具体代码调用的方式,比如 python 可以使用 http.client 库或者 Requests 库来发送请求命名请求之前我们发送的所有请求都是匿名请求,匿名请求和命名请求的区别就是在一个 http 文件内,可以引用命名请求的请求信息和响应信息,在请求之间有依赖关系时这个功能非常有用,例如每次登录成功后其他请求都需要更新登录返回的 token,命名请求可以用过 JSONPath 或者 XPath 获取响应数据在响应中也会显示使用到当前命名请求的变量值的更新一些有用的设置设置响应显示内容在 REST Client 设置中的 “Preview Option” 可以设置请求响应显示什么内容,总共有四种,full,body,header,exchang我们分别来看下四种结果显示什么内容full:Header + Bodybody:只显示 Bodyheader:只显示 Headerexchange:显示请求 + Header + Body其他常用的设置选项rest-client.timeoutinmilliseconds: 设置请求超时,单位毫秒rest-client.showResponseInDifferentTab: 每个响应请求创建一个新的 tab,为 false 时,每次请求会覆盖上一次的请求结果,设置为 true 时每次请求都会打开一个新的 tab,方便对比多次请求结果rest-client.previewColumn: 请求结果显示,current 表示显示在当前的编辑器分组 beside 表示显示在侧面编辑器分组(这个侧面根据编辑器的 workbench.editor.openSideBySideDirection 选项会显示在右面或是下面代理:使用http.proxy 和 http.proxyStrictSSL最后其实 Postman 和 Paw 都提供更为强力的辅助工具,这里使用 REST Client 单纯觉得 Postman 和 Paw 大部分功能我其实都用不到,因为仅仅验证接口是否正常,业务是否能跑通,所以一直在寻找一个简单的工具,REST Client 刚好满足了我所有的需求这里附上 REST Client 项目地址,里面也有对应的文档 https://github.com/Huachao/vscode-restclient最后欢迎大家订阅我的微信公众号 Little Code公众号主要发一些开发相关的技术文章谈谈自己对技术的理解,经验也许会谈谈人生的感悟本人不是很高产,但是力求保证质量和原创 ...

February 2, 2019 · 2 min · jiezi

关于git的仓库同步指南

关于git的仓库同步指南前言我们都知道,GitHub是一个方便多人协作的托管平台.如何将本地local仓库、个人远程origin仓库(GitHub上的仓库)和远程upstream仓库(在GitHub上fork别人的仓库)进行同步是多人协作的前提.那么我们就来看一下,过程该如何进行情景描述前提:A与B两人协作管理同一个upstream远程仓库,且本次操作A、B同时fork.场景一:现实中我们经常出现这种问题:A fork了远程upstream仓库,几天之后upstream仓库更新了新的版本,此时A的个人仓库与origin仓库已经落后,如果这个时候A 在落后的版本上继续commit,就会频频出错,那么A就需要更新本地仓库,在最新的基础上再操作.场景二:A在最新的版本上进行了自己的修改,并且已经push到upstream仓库,此时upstream版本已被A更新. B想要同步A的此次更新需要fetch远程upstream仓库(此时local 已更新),再将local 仓库push到本地origin仓库.完成同步的操作.图形详解实际操作场景一解决方法获取代码库1 、 fork别人的仓库到自己的GitHub2、将fork到的仓库clone到本地local同步更新代码因为fork并不能将所有东西都复制过来,这个操作只是获取到了路径,所以此时local仓库和upstream远程仓库并不同步,想要同步需先fetch(见操作3)3、使A local仓库和远程upstream仓库的master分支同步$ git fetch upstream$ git rebase upstream/master4、A在本地对代码进行修改之后,在SmartGit进行commit提交操作,然后push到自己的origin仓库$ git push origin master5、去GitHub提pr到此就已经完成了所有操作,如果原作者同意你的pr申请,你就成功的对upstream的代码进行了修改场景二解决方法6、B想要更新到upstream仓库的最新版本,就必须在终端进行fetch,rebase等操作(同上3)7、B的local仓库已同步,需要将最新版本push到B自己的origin仓库,使origin仓库更新结语好啦,到这里我们就能清楚的理解仓库同步的重要性以及如何同步各个仓库了.感谢阅读,下期再会. 原创作者:田晨晨、赵笑漫 日 期:2019年1月31日

January 31, 2019 · 1 min · jiezi

如何在WSL下使用VS Code

自微软开始宣布拥抱开源以来,我认为微软发布的最棒的两大功能是:Visual Studio Code(VS Code)和Windows子系统Linux(WSL),有了这两者的结合,它为软件开发人员开辟了一条新的编写代码的途径。WSL使开发人员能够在Windows 10上运行Linux环境,而无需付出更多使用虚拟机时的开销。使用WSL,我们可以从Windows应用商店上安装大多数Linux正式版,我们甚至还能在其GUI上运行Bash shell脚本和Linux应用程序。本文提供了详细的WSL配置分步说明,便于我们能够通过WSL在Linux上运行VS Code。虽然本文的标题是《 在WSL下使用VS Code》,但也同样适用于其他GUI应用程序。本文中使用的软件包括:Windows 10 1809Ubuntu 18.04Visual Studio Code 1.30.2MebaXTerm 11.1本文目录:启用WSL安装Linux下载并安装MobaXterm启动MobaXterm并打开X Server在已安装的Linux上安装X Client启动VS Code除了Windows 10和VS Code之外,我们还需要X Server和X Client来使VS Code与WSL协同工作。在Linux的世界中, X Window System扮演着为构建GUI环境必要的基本框架角色。 X Window System使用客户端 - 服务器模型,已实现与远程计算机以图形界面连接。 因此,要使用我们的本地计算机(例如笔记本电脑)连接到远程Linux计算机,我们需要:在远程Linux机器上运行X Client应用程序在本地计算机上运行X Server应用程序远程X客户端与本地X服务器建立连接并提供该应用程序的图形界面。所以使用此技术,就可以使用WSL运行VS Code。X Server为我们提供了我们要运行的图形环境,由于WSL的Bash不支持X Server,因此通过选型在这里我选择了配置更为简单的MobaXterm。打开WSL功能在我们安装Linux发行版之前,我们需要启用WSL。 为此,首先在搜索栏上输入“打开或关闭Windows功能”。然后在打开的窗口勾选 “WSL”单击“确定”按钮后,我们可能需要重启机器。现在,我们在Windows 10上启用了WSL。(有关WSL的更多详细信息,请访问https://docs.microsoft.com/en…)安装Linux(Ubuntu)如果启用了WSL功能,那么我们就可以将Linux安装到Windows 10上了。在Windows应用商店搜索Ubuntu。安装完成后启动启动Ubuntu后,请按照说明创建用户帐户。Ubuntu全部配置完成后,我们继续安装MobaXterm安装并设置MobaXterm首选我们从官网下载MobaXterm,他们官网提供了绿色版和安装版两种版本。选哪个看个人喜好,实际使用上区别不大,我这里使用的是绿色版。解压完成后启动程序,点击启动X Server(如下图)而后,X Server就启动了。配置X Client如开头所述,X Client是我们想要远程访问的应用程序。在本文里,这个应用程序是VS Code。 为此,请按照以下步骤操作:启动命令提示符在命令提示符下,键入bash以进入Ubuntu bash。输入命令 $ export DISPLAY=localhost:0.0. 我们也可以在 ~/.bashrc添加这个命令, 这样我们每次登录时就都不需要再重复这样的工作了<g class=“gr_ gr_9 gr-alert gr_tiny gr_gramm gr_inline_cards gr_run_anim Grammar multiReplace” id=“9” data-gr-id=“9”>in.export DISPLAY=localhost:0.0 告诉X Client应用程序的具体IP信息,因为我们在本机执行该命令,所以使用的是localhost,如果你使用的是远程计算机,请改掉localhost部分安装VS Code现在,我们可以下载VS Code并安装到Ubuntu上。在这我们使用Firefox下VS Code,这能再之后减少很多麻烦。命令如下:$ sudo apt update$ sudo apt install firefox启动Firefox以下载VS Code下载的VS Code Debian软件包应该位于 ~/Download.目录内$ cd ~/Download$ sudo dpkg -i code_1.30.2-1546901646_amd64.deb注:如果因为一些依赖问题而导致安装失败,请先安装依赖库,如下:$ sudo dpkg -i code_1.30.2-1546901646_amd64.debSelecting previously unselected package code.(Reading database … 42604 files and directories currently installed.)Preparing to unpack code_1.30.2-1546901646_amd64.deb …Unpacking code (1.30.2-1546901646) …dpkg: dependency problems prevent configuration of code: code depends on libnotify4; however: Package libnotify4 is not installed. code depends on libnss3 (>= 2:3.26); however: Package libnss3 is not installed. code depends on libxkbfile1; however: Package libxkbfile1 is not installed. code depends on libgconf-2-4; however: Package libgconf-2-4 is not installed. code depends on libsecret-1-0; however: Package libsecret-1-0 is not installed. code depends on libxss1; however: Package libxss1 is not installed. dpkg: error processing package code (–install): dependency problems - leaving unconfiguredProcessing triggers for mime-support (3.60ubuntu1) …Errors were encountered while processing: code安装依赖库sudo apt install libnotify4 libnss3 libxkbfile1 libgconf-2-4 libsecret-1-0 libgtk-3-0 libxss1如果出现如下错误,请尝试sudo apt -fix-broken install命令重新安装Reading package lists… DoneBuilding dependency treeReading state information… Donelibgtk-3-0 is already the newest version (3.22.30-1ubuntu1).libgtk-3-0 set to manually installed.You might want to run ‘apt –fix-broken install’ to correct these.The following packages have unmet dependencies: libgconf-2-4 : Depends: gconf2-common (= 3.2.6-4ubuntu1) but it is not going to be installed Recommends: gconf-service but it is not going to be installed libnss3 : Depends: libnspr4 (>= 2:4.12) but it is not going to be installed libsecret-1-0 : Depends: libsecret-common but it is not going to be installedE: Unmet dependencies. Try ‘apt –fix-broken install’ with no packages (or specify a solution).安装完成后,启动VS Code。$ code注意:一旦我们启动了VS Code,我们可能会无法移动或调整VS Code的窗口。这是因为自VS Code 1.30以来默认启用了Linux上的自定义磁贴和菜单栏。 为了能够避免这一问题,我们需要将设置更改为native。首先,打开VS Code设置。[文件 - >首选项 - >设置]其次,在搜索栏上键入title bar,然后选择native。重启VS Code,现在我们应该已经可以移动和调整VS Code窗口和大小了。结论使用WSL和X Server,我们可以在Windows 10上安装Linux并使用图形界面运行Linux上的应用程序。 但是,这时候可能有人会问,我们为什么要这样做? 为什么不直接在Windows上使用VirtualBox或VMware等虚拟机或者使用其他Linux机器?当然,大多数情况下这些方式没有问题,但在某些个别情况下,这样的方式并不适用。 例如:没有强大的工作站,运行虚拟机会导致机器很慢。没有预算购买另一台机器来运行Linux。由于网络的延迟,在云上运行带有图形界面的应用程序可能会很慢。WSL提供了一种简单而廉价的解决方案,我们可以在我们更熟悉的Windows 10环境中运行Linux和Linux应用程序。本文是由葡萄城技术开发团队发布,转载请注明出处:葡萄城官网了解葡萄城开发工具了解葡萄城开发者解决方案 ...

January 30, 2019 · 2 min · jiezi

我的VS CODE

在日常开发中,我使用的编辑器是 VS CODE。不仅界面简洁好看,而且插件丰富,是前端开发的首选工具之一。这些插件和工具的目的是为了提高我们的开发效率,下面就我日常开发切身使用到和感受到有帮助的插件和方法做个总结。VS CODE 常用的个人在用的插件Chinese (Simplified) Language Pack for Visual Studio Code为 vscode 提供中文界面EditorCofig for VS Code给 VS Code 项目应用全局的.editorconfig 设置,包括 Tab 空格数量,文件结尾符号等Gitconfig Syntab为.gitconfig, .gitattributes, .gitmodules 提供语法高亮Mocha sidebarmacha 测试框架的 VS Code 支持Path Intellisense对.js 文件提供路径感知,提示功能。如何在.vue 文件中提供路径感知只设置在工作区设置的话,只对当前工作区有效。TODO HightlightTODO highlight.Vetur对.vue 文件提供语法高亮和自动补全vscode wxml对小程序.wxml 文件提供补全和语法高亮vscode weapp api只需要键入wx就会有微信api的提示使用 jsconfig.json 做路径感知当我们在项目中集成 webpack 的时候,经常会使用 webpack alias。在 VS Code 中,支持 alias,需要使用jsconfig.json。很可惜,这个方法在.vue 文件中不支持,目前没有找到解决方案。不过我们可以使用上面的path intellisense插件来做路径提示。如何使用 jsconfig.json 让 vscod 对 js 文件提供路径感知{ “compilerOptions”: { “target”: “es2017”, “allowSyntheticDefaultImports”: false, “baseUrl”: “./”, “paths”: { “@/”: [ “src/apps/” ], “app/”: [ “src/apps/” ], “Components/”: [ “src/components/” ], “services/”: [ “src/services/” ], “style/”: [ “src/style/” ] } }, “exclude”: [ “node_modules”, “dist”, “.nyc_output”, “build”, “coverage” ]}解决 path intellisense 插件对‘/’的不支持我们在 vscode 中设置 path intellisense 对’/‘的支持"path-intellisense.mappings": { “/”: “${workspaceRoot}”, “@”: “${workspaceRoot}/src”}其中/ 和 vscode 本身的路径提示冲突,在这种情况下只会基于当前文件盘为根目录,需要关闭 vscode 本身对 js 代码 import 的智能提示(version 1.30.2){ “javascript.suggest.paths”: false} ...

January 28, 2019 · 1 min · jiezi

Visual Studio Code使用中CPU占用率异常暴增过高原因

今天要说的是一个困扰我好几个月的问题,Visual Studio Code(下文简称VSCode)在使用中突然增高,风扇开始狂转,温度骤增,影响心情的故障原因。其实,无论是Windows还是OSX,很多人可能或多或少都遇到过VSCode突然就不好使了,我就遇到过好多次疑难杂症,折腾很久才弄出来,比如下面三点:tab键突然就不好使了,卡顿很久或者压根无法缩进,并且sidebar的git那块功能彻底失效!写Markdown文档的时候,tab键的缩进只能向右,不能收回。。。这真是奇葩。使用中莫名其妙的风扇就响了起来,看看进程和温度,CPU满载执行,完全不知道怎么回事,这也是本次要专门提到的问题。系统使用环境及VSCode状态检测我使用的是黑苹果,当然这个与CPU占用率增高并无关系,通过code –status查看一些基本信息如下:P750TM:~ whidy$ code –statusVersion: Code 1.30.2 (61122f88f0bf01e2ac16bdb9e1bc4571755f5bd8, 2019-01-07T22:48:31.260Z)OS Version: Darwin x64 17.7.0CPUs: Intel(R) Core(TM) i5-8600K CPU @ 3.60GHz (6 x 3600)Memory (System): 16.00GB (5.22GB free)Load (avg): 2, 2, 2VM: 0%Screen Reader: noProcess Argv: –inspect-extensions=9993GPU Status: 2d_canvas: enabled checker_imaging: disabled_off flash_3d: enabled flash_stage3d: enabled flash_stage3d_baseline: enabled gpu_compositing: enabled multiple_raster_threads: enabled_on native_gpu_memory_buffers: enabled rasterization: unavailable_software video_decode: enabled video_encode: enabled webgl: enabled webgl2: enabledCPU % Mem MB PID Process 0 98 1775 code main 0 49 1776 gpu-process 0 229 1777 window (settings.json — mpa-stat-sdk) 0 0 1780 /bin/bash -l 0 115 1783 extensionHost 0 82 1787 /Applications/Visual Studio Code.app/Contents/Frameworks/Code Helper.app/Contents/MacOS/Code Helper –nolazy –inspect=10785 /Applications/Visual Studio Code.app/Contents/Resources/app/extensions/json-language-features/server/dist/jsonServerMain –node-ipc –clientProcessId=1783 0 49 1784 watcherService 0 49 1789 searchService 0 33 1785 utility 0 82 1817 shared-process 0 311 1830 window (ald-stat.js — one-plus-sport) 0 49 1831 watcherService 0 98 1832 extensionHost 4 66 1870 electron_node eslintServer.js 0 131 1871 electron_node tsserver.js 0 66 1879 electron_node typingsInstaller.js typesMap.js 0 49 1835 searchServiceWorkspace Stats: | Window (ald-stat.js — one-plus-sport)| Window (settings.json — mpa-stat-sdk)| Folder (one-plus-sport): 273 files| File types: js(75) json(58) wxss(57) wxml(56) png(21) md(2)| gitignore(1) xlsx(1) jpg(1) zip(1)| Conf files:| Folder (mpa-stat-sdk): 21 files| File types: js(13) md(3) json(2) zip(2) gitignore(1)| Conf files: gulp.js(1) package.json(1)故障现象先来看看正常情况下和非正常情况的运行情况对比图:上图为正常情况下的截图上图为异常情况下的截图这个问题真的令我很苦恼,我这两张截图期间绝对没有做任何可能会产生高计算需求的工作,但是正常的操作怎么会出现这种情况呢。故障分析及解决于是进行了大量的搜索,百度就不用看了,屎一样的结果:前5篇内容完全一致,结论:“search.followSymlinks”:true,在我这一点用也没用。顺便吐槽,我完全不理解,在中国尤其是CSDN,为什么一个简单的小问题,一大堆人转载,完全一样的内容,如果真的是神一般的技巧,敢不敢多写一点,为什么这样能解决问题,出现故障的原因呢,无脑抄袭就算了,做笔记请使用自己的笔记本,比如有道云笔记,印象笔记不好吗,难道没人知道你是抄的?简直浪费搜索时间!垃圾!吐槽完毕,该用google了,实际上,我一开始就没用百度,只是写这篇文章,担心有人遇到过这样的问题,写过相同的解决方案,说我是抄来的。就索性百度搜一下。用谷歌自然用英文,虽然我英语很渣,但是谷歌懂我。只需要几个关键词:无论是微软官方的issue查,还是stackoverflow查,总能有很大的收获,但是,我这个问题比较特殊,我尝试过最基本的两种处理办法:屏蔽所有插件测试重置自定义的settings.json文件然而都不好使。可怜我英文也不是特别好,有可能有些有用的信息被我忽略掉了。这里补充一下,其实大部分原因,可以通过官方提供的自排除方案来检查Performance Issues,我很推荐遇到CPU占用率过高的情况下先看看这篇文章。不过也不是全无收获,至少开头提到的三个问题,前两个查出来了。第一个问题是插件Auto Rename Tag造成的,这个至少在一年前是非常流行的,我自己也觉得很好用,就一直装了,完全想不到这个简单的功能居然会造成VSCode某些功能异常,去插件主页看看,作者也不更新维护了,插件评价页面全是一星,可见目前已经是垃圾插件了查看评论,不过过年很多无脑转载的还在推荐这个插件,所以为了避免大家入坑,建议不要使用Auto Rename Tag。第二个问题也是插件问题,就是Markdown All in One这个插件导致缩进功能不好使,原因我也不知道,其实这个问题并不严重,有强烈依赖改插件的朋友还是可以继续使用,我也很推荐这个插件写markdow,有些还是挺便捷的,不过我是删了哈哈哈,看个人意愿了~好了第三个问题才是最重要的,我反复观察了很久,做了大量测试和查阅文档,终于得出结论:当且仅当VSCode的窗口大于1个的时候,才会出现该现象出现异常经常出现在切换不同窗口之后发生我发现切换窗口后出现异常就搜索关键词two/multi vscode switch cause a high cpu useage终于找到了一丝丝线索,仔细阅读了下面几篇:Switching between VSCode windows with any custom app switcher causes high CPU usageapplication processes consume 200% CPU combinedExtreme CPU usage when multiple windows are openRenderer high CPU on OSX with custom window switchers我终于,发现了一个问题,我切换VSCode的窗口的方式有问题!!!我是用了罗技鼠标的快捷键功能导致,如图:啊,我的天啊!我反复尝试,在多个窗口,直接用键盘的Cmd + 来切换内部应用窗口,妥妥的一点毛病都没有。结论很多情况下VSCode功能异常都是插件引起的,尝试关闭所有插件来检查,建议阅读Performance Issues。其次是**第三方Switcher应用切换VSCode窗口会造成异常!比如常用的鼠标功能键!啊,坑了我好多个月,反复重装VSCode和系统都没法解决的毛病终于解决了。。。以后只能用Cmd + 来切换了 ...

January 28, 2019 · 2 min · jiezi

在 React-CRA 应用中配合 VSCode 使用 ESLint 实践前端代码规范

更新时间:2019-01-22React.js create-react-app 项目 + VSCode 编辑器 + ESLint 代码检查工具 + Airbnb 编码规范前言为什么要使用 ESLint在项目开发过程中,编写符合团队编码规范的代码是尤为重要的,程序首先是给人看的,其次才是给机器去执行。我们在开发工作中,代码维护会占很大的比重,很多时候我们还需要阅读他人的代码,如果没有一个统一的编码规范,将会给我们的工作带来很大的困扰。因此,我们期望在开发过程中遵循统一的编码规范,以实现避免基本语法错误、代码格式化、规避一些不推荐的用法等目的,最大程度的保证代码的可读性和正确性。通常每个团队都会制定适合自己的编码规范和代码风格,但是仅仅制定规范是不够的,还需要借助代码检查工具来强制推行团队的编码规范,比如 ESLint 代码检查工具。本文会介绍一种 ESLint 的配置方案,但本文关于 ESLint 的配置是基于一定的开发环境的,偏重于实际应用,并非 ESLint 本身的介绍。这里对 ESLint 的配置基于以下环境:React.js create-react-app 脚手架项目使用 VSCode 编辑器基于 Airbnb 编码规范相关链接ESLint 代码检查工具ESLint 中文 是一个开源的 JavaScript 代码检查工具,由 Nicholas C. Zakas 于2013年6月创建。JavaScript 是一个动态的弱类型语言,在开发中比较容易出错。因为没有编译程序,为了寻找 JavaScript 代码错误通常需要在执行过程中不断调试。像 ESLint 这样的可以让程序员在编码的过程中发现问题而不是在执行的过程中。ESLint 的初衷是为了让程序员可以创建自己的检测规则。ESLint 的所有规则都被设计成可插入的。ESLint 的默认规则与其他的插件并没有什么区别,规则本身和测试可以依赖于同样的模式。为了便于人们使用,ESLint 内置了一些规则,当然,你可以在使用过程中自定义规则。Create-React-App 应用Create React App 是 React 官方支持的创建单页面 React 应用的方式,通过 create-react-app 脚手架命令可以快速创建一个 React 应用,免去了我们自己配置 webpack 的麻烦,我们这次 ESLint 的配置方案就是基于 create-react-app 项目的。VSCode 编辑器VSCode 是微软的良心之作,是一个轻量且强大的代码编辑器,支持 Windows 和 Linux。内置 JavaScript、TypeScript 和 Node.js 支持,而且拥有丰富的插件生态系统,还可以通过安装插件来支持 C++、C#、Python、PHP 等其他语言,堪称开发的利器。插件扩展:Extensions for the Visual Studio family of products。Airbnb 编码规范Airbnb JavaScript Style Guide 是独角兽公司 Airbnb 内部的 JavaScript 编码规范,该项目是 Github 上很受欢迎的一个开源项目,在前端开发中使用广泛,本文的 ESLint 配置规则就是以Airbnb JavaScript 编码规范(2.0) 和 Airbnb React/JSX 编码规范 作为基础的。具体配置方法在 VSCode 中安装 ESLint 扩展在 VSCode 扩展面板搜索 ESLint,找到安装最多的那个安装即可,安装完成之后需要 重新加载 以激活扩展,但想要让扩展进行工作,我们还需要进行 ESLint 的安装配置。创建 CRA 项目我们的配置方案是基于 CRA 脚手架项目进行测试的,因此我们要先创建一个 CRA 项目,具体方法详见官方文档:Create React App。创建的 CRA 项目文件组织结构如下: my-app ├── README.md ├── node_modules ├── package.json ├── .gitignore ├── public │ ├── favicon.ico │ ├── index.html │ └── manifest.json └── src ├── App.css ├── App.js ├── App.test.js ├── index.css ├── index.js ├── logo.svg └── serviceWorker.js安装 ESLintESLint 可以选择进行本地安装: npm install eslint –save-dev也可以进行全局安装: npm install -g eslint一般推荐进行全局安装,使其可以作用于我们所有的项目。具体请参见 eslint-npm 文档。创建 ESLint 配置文件ESLint 安装完成之后,我们需要创建一个配置文件,为了详细演示 ESLint 是如何在实际项目中工作的,我们接下来的操作都在我们上面已经创建的 CRA 脚手架项目中进行,且先不考虑 Airbnb 编码规范的使用,而是先创建一个较为常见的自定义代码风格。我们在创建的 my-app 项目下执行 cmd 命令 eslint –init,根据提示我们选择通过 Answer questions about your style 的方式创建一份自定义的代码规范,下图是一个示例,具体可根据项目需要进行配置:这样我们就已经创建了一个自定义的 ESLint 配置文件,可以看到在 my-app 项目中生成了一个名为 .eslintrc.js 的文件,其中的规则就是根据我们上图中的选择进行设定的,具体内容如下: /* .eslintrc.js / module.exports = { “env”: { “browser”: true, “commonjs”: true, “es6”: true }, “extends”: “eslint:recommended”, “parserOptions”: { “ecmaFeatures”: { “jsx”: true }, “ecmaVersion”: 2018, “sourceType”: “module” }, “plugins”: [ “react” ], “rules”: { “indent”: [ “error”, 4 ], “linebreak-style”: [ “error”, “windows” ], “quotes”: [ “error”, “single” ], “semi”: [ “error”, “always” ] } };至此,我们在 VSCode 中打开 my-app 项目,可以发现 ESLint 扩展已经可以正常工作了,ESLint 会自动检测语法错误,并高亮显示,同时在 VSCode 编辑器的问题窗口会输出相应的错误信息。设置 autoFixOnSave经过以上步骤操作之后,ESLint 扩展已经正常工作了,并且可以根据错误提示手动修复检测到的错误,但是这样显然是低效和繁琐的,这个时候就需要配置 ESLint 扩展插件的自动修复功能了。在 VSCode 中依次点击 文件–>首选项–>设置,打开 settings.json 文件,在设置中搜索 eslint,会发现 ESLint 扩展插件的自动修复功能是关闭的,我们在右侧的用户设置中对此项进行修改,将其设置为:“eslint.autoFixOnSave”: true,,这样 ESLint 扩展插件的自动修复功能就打开了。此时,我们再次打开错误页面,执行保存(Ctrl+s)操作,就会发现 eslint 的错误可以自动修复了,如果当前页面错误较多的话,可能需要多次执行 Ctrl+s。使用 Airbnb 编码规范上面我们已经使 ESLint 在我们的项目中正常工作了,但使用的代码风格是我们自定义的,有时候我们希望使用一些大厂的比较成熟的代码规范,比如 Airbnb JavaScript Style,接下来我们就将自定义的 ESLint 配置改为使用 Airbnb 编码规范配置。首先,我们需要安装 2 个 npm 依赖包:babel-eslint,增强语法识别能力babel-eslint allows you to lint ALL valid Babel code with the fantastic ESLint.$ npm i babel-eslinteslint-config-airbnb,Airbnb 提供的支持 ECMAScript 6+ 和 React 的 ESLint rules,包括 eslint eslint-plugin-import eslint-plugin-react 以及 eslint-plugin-jsx-a11y。Our default export contains all of our ESLint rules, including ECMAScript 6+ and React. It requires eslint, eslint-plugin-import, eslint-plugin-react, and eslint-plugin-jsx-a11y. If you don’t need React, see eslint-config-airbnb-base.// If using npm 5+, use this shortcut$ npx install-peerdeps –dev eslint-config-airbnb然后我们要修改 .eslintrc.js 文件,以使用我们安装的 Airbnb 编码规范,修改后内容如下: / .eslintrc.js / module.exports = { “env”: { “browser”: true, “commonjs”: true, “es6”: true }, “extends”: “airbnb”, // 使用 eslint-config-airbnb “parser”: “babel-eslint”, // 增强语法识别能力 “parserOptions”: { “ecmaFeatures”: { “jsx”: true }, “ecmaVersion”: 2017, “sourceType”: “module” }, “rules”: { // 这里可以根据需要对 airbnb 的规则进行修改,此处仅为示例 “linebreak-style”: 0, “prefer-destructuring”: 0, “prefer-const”: 0, “one-var”: 0, “comma-dangle”: [’error’, { arrays: ‘only-multiline’, objects: ‘always-multiline’, imports: ‘only-multiline’, exports: ‘only-multiline’, functions: ‘ignore’, }], “no-console”: 1, “import/prefer-default-export”: 0, “import/no-extraneous-dependencies”: [2, {‘devDependencies’: true}], “react/prop-types”: 1, “react/forbid-prop-types”: 0, “react/jsx-filename-extension”: [2, {extensions: [’.js’, ‘.jsx’, ‘.tsx’]}], “jsx-a11y/anchor-is-valid”: 0, // VSCode 的 ESLint 扩展插件暂时无法正确修复这条规则带来的错误 “react/jsx-one-expression-per-line”: 0, } };至此,我们完成了在 React-CRA 应用中配合 VSCode 使用 ESLint 的全部配置。错误信息在修改 .eslintrc.js 文件以使用Airbnb 编码规范(eslint-config-airbnb)的过程中,发现 VSCode 的 ESLint 扩展插件对其中的有些规则不能正确的自动修复,比如: // One JSX Element Per Line // https://github.com/yannickcr/eslint-plugin-react/blob/843d71a432baf0f01f598d7cf1eea75ad6896e4b/docs/rules/jsx-one-expression-per-line.md ‘react/jsx-one-expression-per-line’: [’error’, { allow: ‘single-child’ }],查阅 eslint-config-airbnb 的文档发现,eslint-config-airbnb v17.1.0 版本修改了上面这条规则,具体可以参见:re-enabling jsx-one-expression-per-line allowing single children 以及 One JSX Element Per Line (react/jsx-one-expression-per-line)。当前版本的 VSCode 的 ESLint 扩展插件无法正确修复这条规则带来的错误,由于暂时找不到其他解决方法,这里就先将这条规则关闭。由此可见,随着 VSCode 或 ESLint 相关的插件和依赖包版本的变动,配置也会发生一些不可预期的变化,这里将用来测试的 CRA 脚手架项目的 package.json 文件内容附录如下; / package.json */ { “name”: “my-app”, “version”: “0.1.0”, “private”: true, “dependencies”: { “babel-eslint”: “^10.0.1”, “react”: “^16.7.0”, “react-dom”: “^16.7.0”, “react-scripts”: “2.1.3” }, “scripts”: { “start”: “react-scripts start”, “build”: “react-scripts build”, “test”: “react-scripts test”, “eject”: “react-scripts eject” }, “eslintConfig”: { “extends”: “react-app” }, “browserslist”: [ “>0.2%”, “not dead”, “not ie <= 11”, “not op_mini all” ], “devDependencies”: { “eslint”: “^5.3.0”, “eslint-config-airbnb”: “^17.1.0”, “eslint-plugin-import”: “^2.14.0”, “eslint-plugin-jsx-a11y”: “^6.1.1”, “eslint-plugin-react”: “^7.11.0” } } ...

January 23, 2019 · 3 min · jiezi

mac vscode 调试配置

安装Go语言调试工具dlv前提需要安装Xcode命令行工具。运行以下命令安装:xcode-select –installdlv安装go install github.com/derekparker/delve/cmd/dlv配置配置settings.json中的GOROOT和GOPATH点击VS Code,点击最顶部栏的Code选项,选中Preferences,点击Settings,选中Extensions,点击Go configuration,在点击Edit in settings.json,打开settings.json文件,可以通过搜索go.go查到,settings.json 文件里面默认的go.gopath和go.goroot都是null,需要自己设置,设置完gopath和goroot后按command+s保存文件。配置launch.json{ “version”: “0.2.0”, “configurations”: [ { “name”: “te”, “type”: “go”, “request”: “launch”, “mode”: “debug”, “remotePath”: “”, “port”: 23456, “host”: “127.0.0.1”, “program”: “/Users/reyun/go/src/test/build.go”, “args”: [], “showLog”: true, “trace”: true } ]}

January 23, 2019 · 1 min · jiezi

ubuntu下vscode调试开发踩过的坑

最近刚过安装了中文版的ubuntu18.04.1,安装完之后想在ubuntu上安装vscode做c/c++的开发调试,踩了不少坑,在此记录一下,希望大家在这条路上不要再踩同样的坑。1.安装vscode 安装vscode很简单,只需要一个命令即可搞定: $ sudo apt-get install visual-studio-code 注:如果需要卸载,可使用 $ sudo apt-get remove code安装成功后,会在菜单栏上出现vscode的标签,如果没有,则可以在terminal中使用命令./code打开vscode2.vscode使用过程的遇到的坑 安装完vscode后,用vscode打开代码工程目录,并根据提示安装c/c++插件后,发现鼠标无法跟踪函数和成员变量的定义,即control+鼠标单击(或鼠标右键)->Go to Definition时,提示no definition found for 。被这个莫名其妙的问题搞得一头雾水,百思不得其解。之前ubuntu16.04.4一直用的好好的,为什么到了18.04.1就找不到函数定义了。 后来仔细看提示才发现,代码路径里面的文件夹名称桌面是中文名(代码放在桌面目录下),会不会是因为这个问题才导致vscode无法跟踪函数定义呢?于是将ubuntu系统切成英文系统,切换方法如下: 1.打开系统菜单中的设置-》Region & Language 将language/语言 从中文改为English(United States) 将Formats/格式 从中国改为United States 然后重启系统 2.重启之后发现home目录下除了中文的桌面目录之外,还多了一个Desktop目录,于是将中文桌面目录下的所有文件夹剪切到Desktop目录下,并检查工程代码目录下是否还有其他中文字符,有的话继续改成英文。 3.使用vscode打开工程文件夹目录,然后再control+鼠标单击-》Go to Definition跟踪函数定义,函数已经自动跳转到函数的定义页面。问题成功解决。3.vscode调试linux下的c/c++工程3.1准备源码 准备源码main.cpp,代码如下:#include <stdio.h>int main(){ printf(“vscode test debug\n”); int a = 3; int b = 2; int c = ab; printf(“a+b=%d\n”,c); getchar(); return 0;}3.2 vscode调用makefile编译源码 为3.1的测试代码准备一个makefile文件,内容如下:TARGETNAME = buildall:$(TARGETNAME)main.o:main.cpp g++ -g -O0 -Wall -fPIC -c $^$(TARGETNAME):main.o g++ -o $@ $^.PHONY:cleanclean: rm -f $(TARGETNAME) main.o $ g++ -g -c test.cpp$ g++ -o test test.o 在terminal中make会生成build可执行文件3.3 创建vscode调试配置文件 使用vscode打开test.cpp所在的文件夹目录,按F5,弹出选择调试环境对话框(Select Environment),从对话框的下拉菜单中选择C++(GDB/LLDB),如下图所示: 选择后C++(GDB/LLDB)程序自动生成launch.json文件,如下所示:{ // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 “version”: “0.2.0”, “configurations”: [ { “name”: “(gdb) Launch”, “type”: “cppdbg”, “request”: “launch”, “program”: “enter program name, for example ${workspaceFolder}/a.out”, “args”: [], “stopAtEntry”: false, “cwd”: “${workspaceFolder}”, “environment”: [], “externalConsole”: true, “MIMode”: “gdb”, “setupCommands”: [ { “description”: “Enable pretty-printing for gdb”, “text”: “-enable-pretty-printing”, “ignoreFailures”: true } ] } ]}1)、将"program": “enter program name, for example ${workspaceFolder}/a.out”,改为:“program”: “${workspaceFolder}/test”,2)、将"externalConsole": true,改为:“externalConsole”: false,3)、如果存在程序启动参数,则将"args": [],改为:“args”: [“arg1”,“arg2”, “arg3”],3.4 使用vscode编译makefile工程 进入.vscode目录(隐藏文件),创建tasks.json文件。内容如下所示:{ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format “version”: “2.0.0”, “tasks”: [ { “label”: “build”, “type”: “shell”, “command”: “make”, //“args”:["-g", “${workspaceRoot}/main.cpp”,"-o",“build”], “problemMatcher”: [ “$gcc” ] } ]} 保存后按ctrl+shift+B进行编译。编译成功后会在当前目录下生成名为build的可执行文件。然后在代码中设置断点,按F5即可进行调试代码。3.5 使用vscode编译源码 进入.vscode目录(隐藏文件),创建tasks.json文件。内容如下所示:{ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format “version”: “2.0.0”, “tasks”: [ { “label”: “build”, “type”: “shell”, “command”: “g++”, “args”:["-g", “${workspaceRoot}/main.cpp”,"-o",“build”], “problemMatcher”: [ “$gcc” ] } ]} 保存后按ctrl+shift+B进行编译,编译成功后即可进行调试。3.6 调试 用vscode打开源码,使用F9在需要调试的地方设置断点,按F5运行程序,便可以开始linux下程序的调试,调试方法与windows的vs开发环境几乎完全一样。4.总结一下踩坑的经验教训1、vscode的代码路径不能有中文,否则会出现无法跟踪代码定义的问题;2、“externalConsole”: 应该为false,否则无法进入调试;fu3、args为一个数组,而不是一个字符串4、tasks.json的label为编译目标程序名称,必须与launch.json的"program": " ${workspaceFolder}/$(programname)",中的$(programname)相同,否则调试将出问题。5、“command”: “g++“为使用g++编译,对于c++源码,“gcc"为使用gcc编译,对应c源码,“make"对应makefile文件编译,源码工程目录下必须有对应makefile工程 ...

January 22, 2019 · 2 min · jiezi

ggit项目开发记录-- git gui程序(一)

ggit开发记录– git gui npm 工具(一)缘由:git-gui-tool 这是1.0版本 coffescript 实现,由于在临近期末考试,时间仓促, 开发的较为粗糙(说直白点就是压根不能用)。所以,决定利用寒假重写。项目计划:不再使用cs, 使用原生js, 对操作逻辑和ui风格重新设计。jquery, scss打辅助。申明:第一次写文章写的不好, 请多多关照, 有不好的地方直接怼,谢谢。项目完全手写代码,包含css等, 转载注明出处,谢谢。效果图未完待续…..

January 19, 2019 · 1 min · jiezi

宇宙最强vscode教程(基础篇)

本文主要介绍vscode在工作中常用的快捷键及插件,与工作无关的内容不谈,复杂的内容不谈,看完之后并用于实践绝对能提高工作效率阅读之前需要你有一定的vscode使用经验,至少要知道插件怎么安装本文的快捷键是基于mac的,win下只需要把cmd键在换成为ctrl。win下区别和mac只会有部分区别,如果你在win下按了快捷键没有反应,不要气馁,百度一下原因温馨提醒:快捷键需要持续练习直到成为肌肉记忆[TOC]注意:在看文章之前记住记住打开命令面板的快捷键Cmd+shift+P(win下是Ctrl+shift+p)一、代码编辑windows下的快捷键放在括号里光标的移动基础移动到行首 Cmd+左方向键 (win Home)移动到行尾 Cmd+右方向键 (win End)移动到文档的开头和末尾 Cmd+上下方向键 (win Ctrl+Home/End)在花括号{}左边右边之间跳转 Cmd+Shift+ (win Ctrl+Shift+)进阶回到上一个光标的位置,Cmd+U(win Ctrl+U) 非常有用,有时候vue文件,你改了html,需要去下面改js,改完js又需要回去,这时候Cmd+U直接回在不同的文件之间回到上一个光标的位置 Control+- (win 没测试,不知道),你改了a文件,改了b文件之后想回到a文件继续编辑,mac使用controls+-文本选择你只需要多按一个shift键就可以在光标移动的时候选中文本选中单词 Cmd+D 下面要讲的多光标也会讲到Cmd+D对于代码块的选择没有快捷键,可以使用cmd+shift+p打开命令面板,输入选择括号所有内容,待会说下如何添加快捷键删除你可以选中了代码之后再删除,再按Backpack(是backpack吗)或者delete删除,但是那样做太low了所以,最Geek的删除方式是Cmd+Shift+K (win Ctrl+Shift+K),想删多少删多少,当前你可以使用ctrl+x剪切,效果一样的代码移动Option+上下方向键(win Alt+上下)代码移动的同时按住shift就可以实现代码复制 Option+Shift+上下添加注释注释有两种形式,单行注释和块注释(在js中,单行注释//,块注释/**/)单行注释 Cmd+/ (win Ctrl +/)块注释 Option+Shift+A注意:不同语言使用的注释不同二、代码格式代码格式化对整个文档进行格式化:Option+Shift+F (win Alt+Shift+F),vscode会根据你使用的语言,使用不同的插件进行格式化,记得要下载相应格式化的插件对选中代码进行格式化: Cmd+K Cmk+F win(Ctrl+K Ctrl+F)代码缩进真个文档进行缩进调节,使用Cmd+Shift+P打开命令面板,输入缩进,然后选择相应的命令选中代码缩进调节:Cmd+] Cmd+[ 分别是减小和增加缩进(win 下不知道,自行百度)三、一些小技巧调整字符的大小写,选中,然后在命令面板输入转化为大写或者转化为小写合并代码行,多行代码合并为一行,Cmd+J(win下未绑定) 行排序,将代码行按照字母顺序进行排序,无快捷键,调出命令面板,输入按升序排序或者按降序排序四、多光标特性使用鼠标:按住Option(win Alt),然后用鼠标点,鼠标点在哪里哪里就会出现一个光标注意:有的mac电脑上是按住Cmd,然后用鼠标点才可以快捷命令Cmd+D (win Ctrl+D) 第一次按下时,它会选中光标附近的单词;第二次按下时,它会找到这个单词第二次出现的位置,创建一个新的光标,并且选中它。(注:cmd-k cmd-d 跳过当前的选择)Option+Shift+i (win Alt+Shift+i) 首先你要选中多行代码,然后按Option+Shift+i,这样做的结果是:每一行后面都会多出来一个光标撤销多光标使用Esc 撤销多光标鼠标点一下撤销五、快速跳转(文件、行、符号)快速打开文件Cmd+P (win Ctrl+P)输入你要打开的文件名,回车打开这里有个小技巧,选中你要打开的文件后,按Cmd+Enter,就会在一个新的编辑器窗口打开(窗口管理,见下文)在tab不同的文件间切换,cmd+shift+[]行跳转加入浏览器报了个错,错误在53行,如何快速跳转到53行Ctrl+g 输入行号如果你想跳转到某个文件的某一行,你只需要先按下 “Cmd + P”,输入文件名,然后在这之后加上 “:”和指定行号即可。符号跳转符号可以是文件名、函数名,可以是css的类名Cmd+Shift+O(win Ctrl+Shift+o) 输入你要跳转的符号,回车进行跳转win下输入Ctrl+T,可以在不同文件的符号间进行搜索跳转定义(definition)和实现(implementation)处f12跳到函数的定义处Cmd+f12(win Ctrl+f12)跳转到函数的实现处引用跳转很多时候,除了要知道一个函数或者类的定义和实现以外,你可能还希望知道它们被谁引用了,以及在哪里被引用了。这时你只需要将光标移动到函数或者类上面,然后按下 Shift + F12,VS Code 就会打开一个引用列表和一个内嵌的编辑器。在这个引用列表里,你选中某个引用,VS Code 就会把这个引用附近的代码展示在这个内嵌的编辑器里。六、代码重构当我们想修改一个函数或者变量的名字时候,我们只需把光标放到函数或者变量名上,然后按下 F2,这样这个函数或者变量出现的地方就都会被修改。下一篇会讲一些高级的应用

January 19, 2019 · 1 min · jiezi

有哪些鲜为人知,但是很有意思的网站?

扩展阅读有哪些鲜为人知,但是很有意思的网站?一份攻城狮笔记每天搜集 Github 上优秀的项目一些有趣的民间故事超好用的谷歌浏览器、Sublime Text、Phpstorm、油猴插件合集工具类看图识花(上传图片识别花的种类):http://stu.iplant.cn/webGridzzly(在线制作自己的网格纸):http://www.gridzzly.com/在线电子书转换器(电子书格式在线转换):http://cn.epubee.com/字体转换器(字体在线转换):http://www.akuziti.com/证件照换底色(一键换底色):https://www.bgconverter.com/OPEN GPS(高精度 IP 定位):https://www.opengps.cn/Default.aspxWindy(在线气象观测):https://www.windy.com/RAMMB(全球实时卫星云图):http://rammb-slider.cira.colostate.eduASD 商品历史价格查询(商品价格曲线):http://asd-price.com/铁路信息查询(全国铁路车站车次信息查询):https://moerail.ml/DesignCap(免费海报在线制作):https://www.designcap.com/app/在线工具箱(各种实用工具聚合):http://tool.mkblog.cn/在线工具箱(各种实用工具聚合):http://www.nicetool.net/长链接生成器:长链接生成器 v2.2图片/视频工具Photopea(网页版 PS):https://www.photopea.com/PHOTOMOSH(给图片视频加特效):https://photomosh.com/Algorithmia(AI 给黑白照片上色):https://demos.algorithmia.com/colorize-photos/Remove.bg(在线一键抠图):https://www.remove.bg/Nod to the Rhythm(让你的照片张嘴唱歌):http://nodtotherhythm.com/makeGfycat(在线制作并托管高清 GIF):https://gfycat.com/应景图(GIF 图片添加字幕水印):http://www.yingjingtu.com/index极速瘦图(图片压缩):http://www.jsysuo.com/Picdiet(图片压缩):https://www.picdiet.com/zh-cnTinyPNG(图片压缩):https://tinypng.com/Squoosh(图片压缩):https://squoosh.app/Needs More JPEG(图片超级压缩):http://needsmorejpeg.com/Waifu2x(图片在线无损放大):http://waifu2x.udp.jp/Bigjpg(图片放大):http://bigjpg.com/ILOVEIMG(在线图片编辑器):https://www.iloveimg.com视频解析网(微博,秒拍,快手,抖音):https://www.parsevideo.com/IT/AI/工具类王斌给您对对联(AI 在线对对联):https://ai.binwang.me/couplet/玄派网 (武侠生成器):http://www.xuanpai.com/Grabient(CSS 代码渐变颜色生成工具):https://www.grabient.com/多彩的颜色(图片色彩分析):https://woshizja.github.io/colorful-color/Emoji 短网址(把网址变成 Emoji 表情):https://e.mezw.com/表情符号生成器(Emoji 表情自定义创建生成):https://phlntn.com/emojibuilder/万象智能鉴黄系统(图片分析):https://cloud.tencent.com/act/event/ci_demo给小动物加光剑(趣味加工):https://giphy.com/search/lightsaber-catsLyrebird(克隆自己的声音,需登录):https://lyrebird.ai/signupWindows93(网页版 windows93 系统):http://www.windows93.net/百度镜子(百度的镜子网站):https://baidujingzi.com/bilibili 镜子(bilibili 的镜子网站)http://www.ilidilid.com/ertdfgcvb(代码特效展示):https://ertdfgcvb.xyz/Silk(互动生成艺术画):http://weavesilk.com/ASCIIFlow Infinity(可视化字符图像绘制):http://asciiflow.com/我知道你下载了什么(BT 下载内容监测):https://iknowwhatyoudownload.com/en/peer/Foxmiguel(游戏直播聚合站):http://www.foxmiguel.com/逗比拯救世界(表情包分享):http://www.bee-ji.com/装逼大全(表情包制作):https://www.zhuangbi.info/音乐/影视类穿帮网(影视剧穿帮镜头赏析):http://www.bug.cn/The Movie title stills collection(电影标题剧照集):http://annyas.com/screenshots/音乐搜索器(音乐聚合搜索下载生成外链):http://tool.mkblog.cn/music/资源帝(在线音乐聚合)http://music.ziyuandi.cn/SUKIER(冷门歌曲推荐):http://www.sukier.com/中国摇滚(中国摇滚年代史):http://www.yaogun.com/Youtube 字幕下载(字幕下载):http://downsub.com/胖鸟电影(最新影视剧蓝光下载站):http://www.pniao.com/爱追剧(电视剧电影追剧下载):http://www.aizhuiju.com/Mov电影天堂(小体积影视剧下载):https://www.dygod.net/高清 MP4ba(最新影视剧下载:复活了):http://www.mp4ba.com/RARBG(美国影视 BT 站):https://rarbgprx.org/torrents.php动漫花园资源网(动漫作品 BT 下载站):https://share.dmhy.org/爱恋动漫(动漫作品 BT 下载站):http://www.kisssub.org/迷你 MP4(最新影视剧下载):http://www.minimp4.com二次元/动漫类萌娘百科:https://zh.moegirl.org/Mainpage神奇宝贝百科:http://wiki.52poke.com/小鸡词典(互联网流行词汇百科网站):https://jikipedia.com/AnimeShot (把动画字幕用于吐槽生活):https://as2.bitinn.net/萌兔本地漫画阅读器(漫画本子在线阅读):http://wusagi.pw/猫耳 FM(二次元声站):https://www.missevan.com/Bilibili 工具箱(弹幕内容查用户名):https://biliquery.typcn.com/PaintsChainer(AI 为你的画自动上色):AI 涂色绘画文艺类时间胶囊(封存自己的记忆):http://p.timepill.net/时光邮局(给未来的自己写一封信):https://www.hi2future.com/I Remember(我记得,一个记忆碎片网站,头脑特工队):http://i-remember.fr/en/海の見える駅(能看见海的车站):https://seaside-station.com/网盘/搜索类快速创建收件夹(百度网盘匿名收件箱):http://xzc.cn/Firefox Send(临时网盘):https://send.firefox.com/Ecosia(搜索引擎,搜索使用的广告收入用于种植树木):https://www.ecosia.org/爱搜资源(百度网盘密码破解分享):https://www.aisouziyuan.com/鸠摩搜书(电子书搜索下载):https://www.jiumodiary.com/GIPHY(GIF 动图搜索网站):https://giphy.com/Similar Site Search(相似网站搜索):https://www.similarsitesearch.com/cn/文学/百科类武侠世界(歪果仁翻译中国小说):https://www.wuxiaworld.com/维基大典(国学百科):維基大典Gallerix(世界名画档案馆):https://gallerix.ru/Internet Archive(互联网档案博物馆):https://archive.org/世界护照大全(领略全球护照风采):https://www.passportindex.org/cn/中国海报(中国历年海报存档):https://chineseposters.net/美丽的化学(化学之美):https://www.beautifulchemistry.net/乡音苑(中国方言活地图):http://phonemica.net/湿在人为(两性博客):http://www.idashi.org/汉典(汉字典书):http://www.zdic.net/书格(传统书籍):https://shuge.org/古诗文网(中国传统古诗文):https://www.gushiwen.org/中少快乐阅读平台(怀旧少儿老杂志):少年儿童杂志全集实用/行政类国家邮政局申诉网站(快递问题投诉专用):http://sswz.spb.gov.cn/无人认领尸体在线查询(慎入):http://www.gzbz.com.cn/dead_men/index.asp药物临床试验登记与信息公示平台(人体实验):http://www.chinadrugtrials.org.cn/德州大学电子图书馆(人体骨骼 X 光标本):http://www.digimorph.org/index.phtml趣味/无聊类Spray.training(FPS 游戏压枪训练工具):http://spray.training/一键六学(网络梗生成器):http://bog.ac/tool/6/#今天中午吃什么?(世纪难题):https://www.zwcsm.com/你好污啊(撩妹金句):https://www.nihaowua.com/Clash(用歌声说出你想说的话,想起了《大黄蜂》):https://clash.me/Windows Update Prank(假装 Windows 升级界面):http://fakeupdate.net/字符跳跃(让你的网址动起来):http://glench.com/hash/#CLICKhappy happy hardcore(治愈小表情):https://happyhappyhardcore.com/经典 DVD(无聊网站):http://itneverhitsthecorner.com/Neave.TV(稀奇古怪的电视频道):https://neave.tv/无聊网站大全(点击进入随机无聊站):https://theuselessweb.com/声音/太空类雨季情绪(下雨的声音):https://rainymood.com/VirtOcean(海洋的声音):http://virtocean.com/Purrli(猫打呼噜的声音):https://purrli.com/这里有猫(Purrli 中文版):https://m.niucodata.com/cat/cat.php?from=wbMeteor showers(太空视角观看流星雨):https://www.meteorshowers.org/怀旧类秘密花园(中文网站考古):http://www.yini.org/Inspirograph(怀旧在线万花尺):https://nathanfriend.io/inspirograph/日本传统色(古典传统配色):http://nipponcolors.com/中国色(日本传统色的中文版):http://zhongguose.com/四大名著小说(名著地图):http://www.sdmz.net/水浒 108 将形象大全(怀旧图片):http://ls.ganquancun.com/shuihuzhuan108/游戏/测试类Am I pretty or ugly?(在线颜值分析):https://www.prettyscale.com/MyAccent(测试你的口音是英式还是美式):口音测试扫雷(网页版扫雷游戏):https://www.saolei.org/信任的进化(人性小游戏):https://www.sekai.co/trust/太鼓达人(日本经典音乐游戏网页版):https://taiko.bui.pm/一画换一画(互动绘画):http://www.sketchswap.com/Lines FRVR(划线小游戏):https://lines.frvr.com/Bad News(虚假新闻是怎样炼成的):https://getbadnews.com/#playLINE RIDER(Flash 小游戏):https://www.linerider.com/QWOP(经典小游戏):http://www.foddy.net/Athletics.htmlMikutap(鼠标音乐游戏):https://aidn.jp/mikutap/Mikutap(鼠标音乐游戏中文版):https://static.hfi.me/mikutap/it’s a(door)able(解锁小游戏):https://ncase.me/door/ScribblerToo(蜘蛛画画)Scribbler TooTexter(字符画):http://tholman.com/texter/Finding Home(音乐解压游戏):http://findingho.me/魔术键盘(解压网站):http://magickeyboard.io/Emojis & Earth Porn(寻找不动的表情):http://emojisandearthporn.com/Staggering Beauty(精神污染):http://www.staggeringbeauty.com/Pica Pic(复古手持游戏合集):http://www.pica-pic.com/在线 DOS 游戏(中文怀旧游戏):https://dos.zczc.cz/中文家用游戏博物馆(中文怀旧游戏):http://www.famicn.com/老男人游戏网(模拟器 ROM 下载网站):http://www.oldmanemu.net/Neave Interactive(互动小游戏合集):https://neave.com/Bestgames(在线小游戏网站):http://www.bestgames.com/IGCD(互联网游戏汽车数据库):http://www.igcd.net/网站之最第一个网站(世界上第一个网站):http://info.cern.ch/水滴(世界上最小的网站):http://www.guimp.com/世界最高(世界上最高的网站):https://worlds-highest-website.com/世界最长(世界上最长,增长最快的网站):http://www.worldslongestwebsite.com/世界之邮(世界上最长的邮箱):世界上最长的邮箱特别推荐福利吧(分享你的福利吧):http://fulibus.net/龙轩导航(可能是最好用的导航网站):http://ilxdh.com/抽屉新热榜(不正经的资讯社区):https://dig.chouti.com有趣网址之家(趣味小站集锦):https://youquhome.com/原文地址有哪些鲜为人知,但是很有意思的网站? ...

January 15, 2019 · 1 min · jiezi

在VS Code中使用Git进行版本管理及文件上传到Github

GitHub是一个面向开源及私有软件项目的托管平台,只支持git作为唯一的版本库格式进行托管,相信每一个学习前端的人对git和GitHub都不陌生,但是对于刚刚接触前端的人来说,看到这些会觉得很陌生,我刚刚接触的时候就是这样。我在这里详细的说明一下git和GitHub的一些基本使用方法。在进行git命令前我们需要安装git.exe,这个直接到网上搜一下,下载安装就可以了。1.首先,我们需要注册GitHub账号,然后登陆。2.进入GitHub后,我们需要新建一个库,点击New repository,进入之后页面如下在Repository name中对自己的库进行命名,Description处为对此库的描述,可以填也可以不填。3.下面的Public表示公共,Private表示私人,但是选择Private是要花钱的,可能需要绑定银行卡等操作,如果你的代码不需要保密,在这里我们选择Public即可。4.下图中蓝色线画的可以选择也可以不选择,在这里我们选择上,会自动生成一个README文件。5.打开在桌面或其他位置新建一个文件夹,打开VS Code,用VS Code打开刚才建的文件夹,新建自己想要建的文件并保存。6.在VS Code菜单栏中点击终端,并选择新建终端。7.在终端中输入git init对终端中的文件夹进行初始化。8.输入git status查看文件夹中文件的状态。发现文件夹中有两个文件,文件名称为红色。9.输入git add first.html second.wxml将文件夹的文件添加到库中。再次输入git status查看文件的状态这时发现文件名的颜色为绿色,说明已经将文件添加到了库中。10.输入git commit -m ‘second’,此处引号内的名称可以为任意。11.由于第一次使用git,在上一步中会报错,这时我们只需输入git config –global user.name ‘GitHub账户名’运行后再输入git config –global user.email ‘注册GitHub时的邮箱’即可。12.再次输入git status查看文件状态,发现工作树为空,则说明上述操作成功。13.输入git branch查看目前文件所在的分支为master14.以上为git的一些基本操作,下面讲述如何将文件远程提交到GitHub,打开自己刚刚在GitHub上新建的库,点击Clone or download,再点击右侧带箭头的文件图标,将地址复制下来。15.在VS Code中继续输入git remote add origin https://github.com/yhlp/display.git,最后的地址为刚刚在GitHub上复制的地址。16.输入git push -u origin master,运行后我们会发现报错这是因为没有将库中的README.md文件下载下来,这时我们只需输入git pull –rebase origin master,执行结束后我们会发现左侧文件夹中多了一个文件这时我们再执行git push -u origin master,执行结束后文件就已经成功提交到GitHub。到GitHub上查看,发现文件已经成功提交。17.以上为git的一些基本操作及将代码远程提交到GitHub的操作,上述代码也可以在安装好的git bash中进行,Windows系统安装好git.exe后,只需在桌面空白处右键便能看到git bash。

January 13, 2019 · 1 min · jiezi

HTTPS如何确保Web安全

前言:全网HTTPS势在必行HTTPS(全称:HyperText Transfer Protocol over Secure Socket Layer),是为了保证客户端与服务器之间数据传输的安全。 近两年,Google、Baidu、Facebook 等这样的互联网巨头,不谋而合地开始大力推行 HTTPS, 国内外的大型互联网公司很多也都已经启用了全站 HTTPS,这也是未来互联网发展的趋势,作为前端工程师,了解HTTPS的原理也是必修课之一。2019年离全网使用HTTPS已经不远了,列举几个各大互联网公司为鼓励使用HTTPS而提出的要求:1.Google的搜索引擎算法,让采用 HTTPS 的网站在搜索中排名更靠前;2.苹果要求App Store中的所有应用都必须使用 HTTPS 加密连接;3.微信小程序也要求必须使用 HTTPS 协议;4.新一代的 HTTP/2 协议的支持需以 HTTPS 为基础;5.新版本chrome已将HTTP协议网站标记不安全隐患:为什么要给HTTP加S?HTTP协议从诞生至今已经具有相当优秀和方便的一面,然而HTTP并非只有好的一面,事物皆具两面性,它的不足之处也是很明显:通信使用明文传输,内容可能会被窃听不验证通信方的身份,因此有可能遭遇伪装无法证明报文的完整性,所以有可能已经遭到篡改除此之外,HTTP本身还有很多缺点。而且,还有像某些特定的Web服务器和特定的Web浏览器在实际应用中存在的不足(也可以说成是脆弱性或安全漏洞),另外,用Java和PHP等编程语言开发的Web应用也可能存在安全漏洞。1. 通信使用明文可能会被窃听由于HTTP本身不具备加密的功能,所以也无法做到对通信整体(使用HTTP协议通信的请求和响应的内容)进行加密。所以,HTTP报文使用明文方式发送。如果要问为什么通信时不加密是一个缺点,这是因为,按TCP/IP协议族的工作机制,通信内容在所有的通信线路上都有可能遭到窥视。所谓互联网,是由能连通到全世界的网络组成,无论世界哪个角落的服务器在和客户端通信时,在此通信线路上的某些网络设备、光缆、计算机等都不可能是个人的私有物,所以不排除某个环节中会遭到恶意窥视行为。即使已经过加密处理的通信,也会被窥视到通信内容,这点和未加密的通信是相同的。只是说如果通信经过加密,就有可能让人无法破解报文信息的含义,但加密处理后的报文信息本身还是会被看到。窃听相同段上的通信并非难事。只需要收集在互联网上流动的数据包就行。对于收集来的数据包的解析工作,可以交给那些抓包或嗅探工具。2. 不验证通信方的身份就可能遭到伪装HTTP协议中的请求和相应不会对通信方进行确认。也就是说存在“服务器是否就是发送请求中URI真正指定的主机,返回的响应是否真的返回到实际提出请求的客户端”等类似问题。在HTTP协议通信时,由于不存在确认通信方的处理步骤,任何人都可以发送请求,同时,服务器只要接收到请求,只要发送端的IP地址和端口号没有被Web服务器设定限制访问,不管对方是谁都会返回一个响应,因此会存在以下各种隐患:无法确定请求发送至目标的Web服务器是否是按真实意图返回响应的那台服务器,有可能是已伪装的Web服务器。无法确定响应返回到的客户端是否是按真实意图接收响应的那个客户端,有可能是已伪装的客户端。无法确定正在通信的对方是否具备访问权限。因为某些Web服务器上保存着重要的信息,指向发给特定用户通信的权限。无法判定请求是来自何方、出自谁手。及时是无意义的请求也会照单全收。无法阻止海量请求下的DoS攻击(Denial of Service,拒绝服务攻击)。3. 无法证明报文的完整性,可能已遭到篡改所谓完整性是指信息的准确度。若无法证明其完整性,通常也就意味着无法判断信息是否准确。因此,在请求或响应送出之后知道对方接收之前的这段时间内,即使请求或相应的内容遭到篡改,也没有办法获悉。换句话说,没有任何办法确认,发出的请求、响应和接收到的请求、响应是前后相同的。文件内容在传输中可能已经被村改为其他内容,像这样,请求或响应在传输途中遭攻击者拦截并篡改内容的攻击成为中间人攻击(Man-in-the-Middle attack,MITM)。解决:HTTP + 加密 + 认证 + 完整性保护 = HTTPS上面提了那么多HTTP的缺点自然在HTTPS中我们得解决它,下面我们来看看HTTPS是如何保证我们数据传输安全的。1. HTTPS其实是身披SSL外壳的HTTPHTTPS并非是应用层的一种新协议。知识HTTP通信接口部分用SSL(Secure Socket Layer,安全套阶层)和TLS(Transport Layer Security,安全传输层协议)协议代替而已。通常,HTTP直接和TCP通信。当使用SSL时,则变成先和SSL通信,再由SSL和TCP通信了。简单来说,与SSL组合使用的HTTP被称为HTTPS(HTTP Secure,超文本传输安全协议)或HTTP over SSL。采用了SSL后,HTTP就拥有了HTTPS的加密、证书和完整性保护这些功能。SSL是独立于HTTP的协议,所以不光是HTTP协议,其它运行在应用层的SMTP和Telnet等协议均可配合SSL协议使用。可以说SSL是当今世界上应用最为广泛的网络安全技术。HTTPS的加密原理近代的加密算法中加密算法是公开的,而密钥是保密的。通过这种方式来保持加密方法的安全性。加密和解密要用到密钥,如果没有密钥就没有办法对密码解密。换句话来说,任何人只要持有密钥就能够对密文进行解密。HTTPS在加密过程中使用了非对称加密技术和对称加密技术。对称加密算法采用单钥密码系统的加密方式,同一个密钥可以同时做信息的加密和解密,这种加密的方法称为对称加密,也称为单密钥加密。下面会把对称加密算法称为共享密钥加密算法。假如现在,SSL在通信过程中,使用了对称加密算法,也就是说客户端和服务器同时共享一个密钥。于是,以共享密钥的方式加密,必须将密钥发给对方。这个时候,假如通信过程被监听,密钥被攻击者获取了,那么这个时候也就失去了加密的意义了。那么,有没有办法解决这个问题呢?答案是肯定的,也就是使用两把密钥。下面先看使用两把密钥的非对称加密算法。非对称加密算法与对称加密算法相反,非对称加密算法需要两个密钥来进行加密和解密,这两个密钥是配对的,分别是公开密钥(公钥)和私有密钥(私钥)。一般情况下,公钥是可以被公开的,它主要用来加密明文。而相应的,私钥不能被公开,用来解密公钥加密的密文。值得注意的是:公钥加密后的密文只能通过对应的私钥来解密,而私钥加密的密文却可以通过对应的公钥来解密。以上,公钥加密私钥解密用来加密,私钥加密公钥解密用来签名。相关用途后面会讲到。下面会把非对称加密算法称为公开密钥加密算法。于是现在,假设现在由服务器来生成一对公钥和密钥。当客户端第一次发请求和服务器协商的时候,服务器就生成了一对公钥和私钥。紧接着,服务器把公钥发给客户端(明文,不需要做任何加密),客户端接收后,随机生成一个密钥,使用服务器发过来的公钥进行加密。再接着,客户端把使用公钥加密的密钥发给服务器,服务器接收到了以后,用配对的私钥进行解密,就得到了客户端随机生成的那个密钥。这个时候,客户端和服务端所持的密钥都是相同的。此时,交换密钥环节就完成了。于是通信开始时就可进行上面所述的共享密钥加密方式来进行加密。同时使用可能,有小伙伴就会问,为什么要大费周章使用非对称加密的方式,然后再得到相同的密钥,进行共享密钥加密的通信呢?由于公开密钥加密处理起来比共享密钥加密方式更为复杂,因此在通信的时候使用公开密钥加密的方式,效率很低。于是,我们需要使用非对称加密的方式来保证密钥共享的过程中密钥的安全性,而后在通信的过程中使用对称加密算法,这是最合理的设计方式,在保证安全性的同时又保证了性能。所以,HTTPS采用共享密钥加密和公开密钥加密两者并用的混合加密机制。在交换密钥使用环节使用公开密钥加密方式,之后建立的通信交换报文阶段则使用共享密钥加密方式。以上,大概就是使用对称加密和非对称加密的过程。看似过程很完美,其实还存在着一个问题,就是:如何保证服务器传过来的公开密钥的正确性。换句话说,就是保证它不被拦截篡改。使用证书保证公钥的正确性假如现在正准备和某台服务器建立公开密钥加密方式下的通信,如何证明客户端收到的公开密钥就是原本预想的那台服务器发行的公开密钥呢?或许,在公开密钥传输的过程中,真正的公开密钥可能已经被攻击者替换掉了。为了解决这个问题,可以使用由数字证书机构和其相关颁发的公开密钥证书。下面阐述一下数字证书认证机构(简称CA)的业务流程:首先,服务器的运营人员向数字证书机构提出公开密钥的申请。数字证书认证机构在判明提出申请者的身份之后,会对已申请的公开密钥做数字签名,然后分配这个已签名的公开密钥,并将该公开密钥放入公钥证书后绑定在一起。我们用白话文来翻译一下上面这段话:首先,CA会向申请者颁发一个证书,这个证书里面的内容有:签发者、证书用途、服务器申请的时候附带的公钥、服务器的加密算法、使用的HASH算法、证书到期的时间等等。紧接着,把上面所提到的内容,做一次HASH求值,得到一个HASH值。再接着,用CA的私钥进行加密,这样就完成了数字签名。而用CA的私钥加密后,就生成了类似人体指纹的签名,任何篡改证书的尝试,都会被数字签名发现。最后,把数字签名,附在数字证书的末尾,传输回来给服务器。接下来,服务器会把这份由数字证书认证机构颁发的公钥证书发给客户端。这个时候,客户端可以使用数字证书机构的公开密钥对其进行验证。一旦验证成功,客户端便能够确定这个公开密钥是可信的。我们再用白话文来翻译一下:客户端拿到这个数字证书以后,用CA私钥对应的公钥,可以解密数字证书末尾的数字签名,得到原始的HASH值。紧接着,客户端按照证书中的HASH算法,对证书的内容求HASH值。如果通过CA公钥解密的HASH和通过计算求得的HASH值相同,那么认证通过,否则失败。如果认证通过,就可以取得服务器的公开密钥。那客户端上面的CA公钥是从哪里来的呢?多数浏览器开发商发布版本时,会事先在内部植入常用认证机关的公开密钥。这样,就方便客户端对于数字证书真实性的验证。其具体过程是这样子的(图中简化了数字签名的过程):这里其实就用到了非对称加密算法,只不过现在这个加密算法用来签名而不是加密。使用私钥加密,公钥解密,用于公钥的持有者验证通过私钥加密的内容是否被篡改,但是不用来保证内容是否被他人获得。而使用公钥加密,私钥解密,则是相反的,它不保证信息被他人截获篡改,但是保证信息无法被中间人获得。客户端证书HTTPS中不仅可以使用服务器证书,还可以使用客户端证书。以客户端证书进行客户端认证,它的作用与服务器证书是相同的。由于客户端获取证书需要用户自行安装客户端证书,同时也面临着费用的问题。因此,现状是,安全性极高的认证机构可办法客户端证书但是仅用于特殊用途的业务。比如那些可支撑客户端证书支出费用的业务。例如,银行的网上银行就采用了客户端证书。在登录网银时不仅要求用户确认输入ID和密码,还会要求用户的客户端证书,以确认用户是否从特定的终端访问网银。HTTPS的安全通信机制为了更好的理解HTTPS,小肆给大家画了下图来一起观察一下HTTPS的通信步骤:步骤1:客户端通过发送Client Hello报文开始SSL通信。报文中包含客户端支持的SSL的指定版本、加密组件列表(所使用的加密算法及密钥长度等)。步骤2:服务器可进行SSL通信时,会以Server Hello报文作为应答。和客户端一样,在报文中包含SSL版本以及加密组件。服务器的加密组件内容是从接收到的客户端加密组件内筛选出来的。步骤3:之后服务器发送Certificate报文。报文中包含公开密钥证书。步骤4:最后服务器发送Server Hello Done报文通知客户端,最初阶段的SSL握手协商部分结束。步骤5:SSL第一次握手结束之后,客户端以Client Key Exchange报文最为回应。报文中包含通信加密中使用的一种被称为Pre-master secret的随机密码串。该报文已用步骤3中的公开密钥进行加密。步骤6:接着客户端继续发送Change Cipher Spec报文。该报文会提示服务器,在此报文之后的通信会采用Pre-master secret密钥加密。步骤7:客户端发送Finished报文。该报文包含连接至今全部报文的整体效验值。这次握手协商是否能够成功,要以服务器是否能够正确解密该报文作为判定标准。步骤8:服务器同样发送Change Cipher Spec报文。步骤9:服务器同样发送Finished报文。步骤10:服务器和客户端的Finished报文交换完毕之后,SSL连接就算建立完成,当然,通信会受到SSL的保护。从此处开始进行应用层协议的通信,即发送HTTP请求。步骤11:应用层协议通信,即发送HTTP响应。步骤12:最后由客户端断开连接。断开连接时,发送close_notify报文。上图做了一些省略,这步之后再发送TCP FIN报文来关闭与TCP的通信。在以上流程中,应用层发送数据时会附加一种叫做MAC(Message Authentication Code)的报文摘要。MAC能够查知报文是否遭到篡改,从而保护报文的完整性。那现在有一个问题,整个过程中产生的三个随机数有什么用呢?还有,后面进行HTTP通信的时候,是用哪一个密钥进行加密,还有怎么保证报文的完整性。看下面这张图。对于客户端:当其生成了Pre-master secret之后,会结合原来的A、B随机数,用DH算法计算出一个master secret,紧接着根据这个master secret推导出hash secret和session secret。对于服务端:当其解密获得了Pre-master secret之后,会结合原来的A、B随机数,用DH算法计算出一个master secret,紧接着根据这个master secret推导出hash secret和session secret。在客户端和服务端的master secret是依据三个随机数推导出来的,它是不会在网络上传输的,只有双方知道,不会有第三者知道。同时,客户端推导出来的session secret和hash secret与服务端也是完全一样的。那么现在双方如果开始使用对称算法加密来进行通讯,使用哪个作为共享的密钥呢?过程是这样子的:双方使用对称加密算法进行加密,用hash secret对HTTP报文做一次运算生成一个MAC,附在HTTP报文的后面,然后用session-secret加密所有数据(HTTP+MAC),然后发送。接收方则先用session-secret解密数据,然后得到HTTP+MAC,再用相同的算法计算出自己的MAC,如果两个MAC相等,证明数据没有被篡改。至此,整个过程介绍完毕。技术放肆聊公众号,每日干货,最前沿的技术知识,扫描下方二维码关注: ...

January 11, 2019 · 1 min · jiezi

学会它,能让你工作学习效率提升10倍!

从小老师就教育小肆,要多记笔记,说好记性不如烂笔头,但记过的笔记却很快就忘了,甚至回头再看都不知道当时记得什么,一直期望能有个比记笔记更好的方法来学习,直到我遇见了它–思维导图。什么是思维导图?人脑不是按照工具条和菜单的方式进行思维的,它像所有自然生物一样进行着有机思维–像神经系统或树枝。要进行良好思维,人脑就需要能反应这一自然有机思维的工具。思维导图正是这一工具,它是从线性(一维)到横向(二维),再到发散性或者多维思考迈进所必不可少的下一个主要步骤。思维导图是用图标表现的发散性思维。发散性思维过程也就是大脑思考和产生想法的过程。通过捕捉和表达发散性思维,思维导图将大脑内部的过程进行了外部呈现。为什么要使用思维导图?传统笔记的劣势传统记笔记一般用的是列表或是数字编号方式进行章节排序。比如介绍都是以第一是什么,第二块是什么内容,第二点下方又有几个小的章节,第三部分有分为了哪几个章节,大致常见的笔记类似多是这种方式进行记录。这种结构也称之为线性笔记。线性笔记结构如下图所示:记笔记的人有可能在没有预览的情况下不加选择的记录信息,这样会丧失总体焦点和意图。记笔记的人只顾忙着把“一切”都卸载至上,没有时间对主题进行批判性分析和欣赏。详尽的笔记会分散注意力,使听者错过真正正在讲的内容(这就像在不阅读文章的情况下打印一篇数千字的文章一样。)笔记的量有可能变得非常大,结果使记笔记的人不愿意回过头去参考他,或者根本看不懂,不得不重新再来。思维导图的好处它们能投让你一直对全部知识“图景”了然于胸,因而可以让你对那一学科的全部知识有一个更加平衡和更加全面的理解。它们比线性笔记少占许多篇幅。10~1000页的课文可以总结到一张大幅的思维导图里面。使用一副思维导图,节约一棵大树!它们使你的大脑有一个焦点和结构,你可以在里面把任何学科的知识综合起来。它们会增强大脑对于知识的“渴求”。它们可以让你把自己的思想和想法与书籍、讲座中表达出来的思想联系起来。它们复习起来的效果和效率都好得多,高得多。它们会强化你对一些书籍、讲座和报告的记忆及理解,使你能够在任何学习课程中出类拔萃。做个对比通过上面两张对比图:第一张是传统的线性笔记结构,采用数字加序列编号,第二章是做成自驾游思维导图。明显会发现:通过思维导图形式会比传统线性笔记来的更为直观通过思维导图形式的笔记,我们可以一眼看出哪些是重要知识点,哪些是并不重要,同时清晰了解各个知识点之间的关联。思维导图采用发散性结构,不同分支下方内容相互不会干扰。整个知识点的关系与脉络就能清晰呈现出来。思维导图与线性笔记关系还有一点也要注意的是:不是说做了思维导图就不需要再做线性笔记,这个是一个错误的观点。思维导图是对线性笔记的内容的提炼与概括。思维导图上记录的是一些关键词,如果我们某个知识点遗忘了,单单通过思维导图里的关键词是很难回想起来。所以制作线性笔记也是不可或缺,思维导图只是对线性笔记的一种补充。可以理解为详细版的笔记大纲目录。如何绘制思维导图?思维导图的基本构成元素思维导图七个原则制作思维导图时,我们应该先了解思维导图的构成要素。然后再按思维导图七个基本原则提升导图整体质量。首先要清楚一点:提出这些原则并不是让你墨守成规,一成不变。制定原则的目的是将一些实际过程中得出来,能行之有效的促进大脑思维活跃因素的一个总结。你可以根据实际需求做适当调整,不要盲目遵循。1.在中心主题位置添加图像添加图像可以使整张思维导图色彩更鲜艳、可阅读性强,同时起到强调中心主题的目的。在中心主题上用色尽量丰富一些,最好是三种色彩以上。2.不同分支主题的选用不同的颜色从中心主题延伸出来的线条叫做分支主题,为了更好的对思维导图内容进行区分,不同分支主题要选用不同的颜色。还要注意的是同一分支主题下,线条颜色需保持一致。过多的颜色,反而容易混淆。有可能的话,最好在分支主题上也增加图像。3.控制线条粗细的变化我们可以通过线条的粗细来体现内容的重要程度。离中心主题中心主题层次关系越近的,线条就越粗,内容也越重要。这就是说,画线条时为了突出层级关系,线条越往外越细。如果是同一层级的话,线条粗细要保持一致。4.线条选用曲线通过对人类大脑的研究,曲线会比直线更能促进大脑联想。绘制曲线线条时,要柔和自然一些,这样整张思维导图看起来更舒适。5.每条线上只有一个关键词一条线上只能出现一个关键词,不要写成自己话,更不是将一整段内容炒录。内容应该是经过提炼浓缩的关键点。6.主题之间要有合理的间隔合理有序的主题间隔,更利于体现整张思维导图的条理性,同时阅读也更舒适,是我们做出高质量思维导图很重要的因素。7.要先理清各个知识点我们在绘制思维导图之前,要对绘制的知识点要很清晰,最好事先写一份草稿。因为手绘时再去增加或是删减内容可能会毁掉整张思维导图。思维导图十大要诀1.使用正确的纸笔确保使用横向格式的白纸——横向页面比竖向页面能容纳更多信息,而且能与广阔的外围视野相匹配。根据思维导图任务选取一张大小合适的纸(开始的时候最好选大的!),并确保手头有许多彩笔和荧光笔。2.跟随大脑给中央图像添加分支 中央图像会引发大脑产生相关联想。请遵循大脑给出的层级。不要太想在一开始就建立一个良好的结构。通常情况下,好结构按照大脑的自由联想就可以自然形成。你可以在分支之间自由移动,也可随时回到前一个分支添加新内容。3.进行区分 主枝干包含你的基本分类概念,因此需要特别强调。用大写字母书写它们。对于次级枝干上的文字,可以用大写,也可以用小写。4.使用关键词和图片 枝干上只添加可以在以后帮你回想观点的内容一个词或一幅图足矣。要最大限度地发挥左右半脑的协同作用,很重要的一点就是让所有分支、文字和图片形成一个有机整体。文字有多长,枝干就多长。5.建立联系 不时地鸟瞰一下你的思维导图。寻找思维导图内部内容的关系。用连线、图像、箭头、代码或者颜色将这些关系表现出来。有时,相同的文字或概念会出现在导图的不同分支上。这并非不必要的重复;正是发现新主题的思维导图带着你的思维在这个主题穿行。强调突出这些重要发现是很有帮助的。这可能引发范式转变!6.享受乐趣 放松你的大脑(比如,放一点音乐),不要太“用力”思考。让你的思维自由联想,把你的想法以个性化、生动化的形式写在纸上。乐趣是进行有效信息管理的关键因素。竭尽所能地利用一切让思维导图的制作过程充满乐趣(音乐、绘画、色彩)。7.复制周围的图像 只要有可能,应该尽量复制其他一些好的思维导图、图像和艺术作品。这是因为,你的大脑天生就会通过复制并根据复制的东西再创造新图像或新概念的方法来学习。你的网状组织激发系统(这是大脑中一个复杂的“编组站”)会自动地寻找那些能改善你的思维导图技巧的信息。8.让自己做个荒诞的人 应该把所有“荒诞”或者“愚盒”的想法都记录下来,特别是在制作思维导图的起步阶段,还要让别的思想也能从中流溢而出。这是因为所谓荒诞或者愚意的想法通常都是一些包含了重大突破口和新范式的东西。而且,根据它们的定义,也都是远远超出常规的东西。9.准备好工作空间或者工作环境 跟你所使用的材料一样,你的工作环境可以唤起你消极、中性或者积极的反应。因此,工作环境应该尽量舒适,让人心情愉快以便让思维进入良好的状态。尽可能使用自然光,自然光对人眼有放松作用。确保有足够的新鲜空气一一大脑最主要的食物之一是氧气。确保房间温度适宜,温度太低或太高都会分散你的工作精力。恰当地布置房间,确保使用质量最好的椅子和书桌,其设计应尽量使你保持轻松舒适的笔直姿势。好的姿势会增加大脑供血,改进感知力并加强精神和身体的耐力。此外,设计良好、吸引人的家具会使你产生使用工作空间的欲望。 为什么要制造良好的周边环境呢?因为学习经常与惩罚联系在一起,许多人下意识地就把自己学习或工作的地方设计成一个囚室的样子。要把自己的地方布置成一个不断想去的地方,哪怕你脑海中没有什么明确的学习任务。在墙上挂几张好看的画,铺上一块好的地毯一这些小改变都会使你的工作空间变成一个受欢迎并且吸引人的好地方。10.让它难忘 大脑有追逐美的自然倾向。因此,思维导图越是引人注目色彩丰富,你能记住的东西就越多。因此,花点时间给分支和图像上色,并给整幅图增加一些层次和添加一些装饰。思维导图可以用来做什么?有哪些用途?第一:制作读书笔记这也是思维导图用途最广的一块。可以将我们对书的理解转换成思维导图形式,通过制作成思维导图可以调动大脑主动思考,并将对书的见解有效进行记录,以后想要回顾书的内容,只需翻阅之前制作的思维导图,就能回忆起之前读书时的心境。第二:管理待办事项可以将日常要做的事情按时间或是按待办事项的紧急程度进行排序,并将内容制作成思维导图。能帮你从混乱不清的状态之中摆脱出来,并借助思维导图理清需要待办事项。这里任何事情都可以记录,但要能体现重要程度之分,有效避免一些重要事件的遗忘。第三:指定项目计划这里参照实际情况,可以制定一套详细的月度计划或是季度计划。通过合理的计划有助于我们项目的完成。如果某些任务有了新进展,还可以在思维导图里直接做项目跟进以及说明注释。个人也可以以周为单位,安排学习与复习时间。这些内容都可以通过思维导图来完成。还有很多管理的知识,可以参考思维导图方法论写的专题文章。第四:记录会议纲要我们同样可以将思维导图应用会议管理,开完某个会议,将今天主要议题以及会上达成的共识与结论进行整理之后。再以思维导图的形式发送给与会人员,清晰明了会议纲要以及具体执行的项目要求。在公司中对提升会议效率有很大益处。应用到得心应手之后,可以大大缩短会议时间。第五:整理旅行清单如果你是一位爱好旅行的朋友,我们还可以通过思维导图整理出行前的物品管理,清楚知道需要带些什么,有哪些东西还没买需要订购的。采用思维导图的发散性结构可以清晰管理清单的方方面面,做到万无一失。第六:自我管理可以将思维导图应用到我们自身的管理。比如可以分为这几个分支主题:自律性、学习效率、执行力、时间管理、知识管理等等这些点进行自我分析。并对不足填入对应的解决方案,并转为计划督促自己改进。通过不断重复提醒,能力也会渐渐提高。第七:时间管理时间管理的好坏对一个人学习效率影响巨大。这点也不用多说,大家应该都深有体会。思维导图其实是给提供了一直时间管理的方法,你可以结合之前我们说到的时间四象限法。进行时间管理可以结合项目管理常用的工具,同时应用思维导图中的甘特图功能,就能随时随地了解时间与项目的节点。思维导图的应用场景还非常多,是一种通用型技能,几乎每个领域都可以使用,远远不止上面的七个用途。大家最好结合自己的实际情况,思考自己所在领域哪些地方用运用思维导图来做提升。常用制作思维导图的软件MindManageriMindmapXMind除了上述3款,还有百度脑图、Freemind、MindMaster、亿图图示等等,小肆就不一一介绍了。

January 11, 2019 · 1 min · jiezi

玩转控制台,看看那些你不知道的Console用法

前言作为前端工程师,我们每天都离不开用控制台调试代码,console.log也成了我们最常用的命令,那除了用console.log,还有许多console的方法可以使用,熟练掌握它们,可以让我们在控制台看到的信息更美观准确,也会大大提高我们的开发效率哦,下面就跟小肆一起来看看吧.Chrome的控制台大部分常用浏览器都有各自的控制台,不过小肆用着最习惯的还是Chrome的控制台,打开chrome,win系统按F12,mac系统按command+option+J就可以呼出控制台了,切换到Console标签就能看到如下信息:我们可以看到,baidu还在控制台给我们留了个小彩蛋,我想这个彩蛋也是为我们程序员同学留的吧。让我们先学第一个命令清除控制台来开始吧。清除控制台在chorme下清除控制台的方法有很多:输入console.clear()命令或clear()命令使用快捷键 Control + J 或 Command + K点击控制台左上角第二个图标 ????显示信息的命令console.log(‘技术放肆聊’) // 输出普通信息console.info(‘技术放肆聊’) // 输出提示信息console.warn(‘技术放肆聊’) // 输出警告信息console.error(‘技术放肆聊’) // 输出错误信息console.debug(‘技术放肆聊’) // 输出调试信息console.log、console.info、console.debug这三个命令可以理解为一个,我们只需要用console.log就行,并且chrome还不支持console.debug命令。console.warn命令输出警告信息,信息前带有黄色警告符号。console.error输出错误信息,信息前带有红色错误符号,表示出错,同时会显示错误发生的堆栈。上段代码在chrome控制台输出效果如下:在safari输出效果如下:占位符console上述的命令支持printf的占位符格式,支持的占位符有:字符(%s)、整数(%d或%i)、浮点数(%f)和对象(%o):占位符作用%s字符串%d or %i整数%f浮点数%o可展开的DOM%O列出DOM的属性%c根据提供的css样式格式化字符串//字符(%s)console.log("%s",“技术放肆聊”);//整数(%d或%i)console.log("%d年%d月%d日",2019,1,6); //浮点数(%f)console.log(“PI=%f”,3.1415926);显示效果如下:%o、%O 都是用来输出 Object 对象的,对普通的 Object 对象,两者没区别,但是打印dom节点时就不一样了:%c 占位符是最常用的。使用 %c 占位符时,对应的后面的参数必须是 CSS 语句,用来对输出内容进行 CSS 渲染。常见的输出方式有两种:文字样式、图片输出。信息分组console.group()用于将显示的信息分组,可以把信息进行折叠和展开。console.groupEnd()结束内联分组将对象以树状结构展现console.dir()可以显示一个对象所有的属性和方法.显示某个节点的内容console.dirxml()用来显示网页的某个节点(node)所包含的html/xml代码判断变量是否是真console.assert()用来判断一个表达式或变量是否为真,此方法接受两个参数,第一个参数是表达式,第二个参数是字符串。只有当第一个参数为false,才会输出第二个参数,否则不会有任何结果。计时功能console.time()和console.timeEnd(),用来显示代码的运行时间console.time(“控制台计时器”);for(var i = 0; i < 10000; i++){ for(var j = 0; j < 10000; j++){} }console.timeEnd(“控制台计时器”);性能分析performance profileconsole.profile()和console.proileEnd()用来分析程序各个部分的运行时间,找出瓶颈所在。function All(){ for(var i = 0; i < 10; i++){ funcA(100); } funcB(1000);}function funcA(count){ for(var i = 0; i < count; i++){};}function funcB(count){ for(var i = 0; i < count; i++){};}console.profile(“性能分析器”);All();console.profileEnd();详细的信息在chrome控制台里的"profile"选项里查看console.count()统计代码被执行的次数function myFunction(){ console.count(“myFunction 被执行的次数”);}myFunction(); //myFunction 被执行的次数: 1myFunction(); //myFunction 被执行的次数: 2myFunction(); //myFunction 被执行的次数: 3console.table表格显示方法总结合理的利用console的各种方法,会使我们的调试过程更加愉悦,今天的分享就到这里了,记得右下角点好看呦!技术放肆聊公众号,每日干货,最前沿的技术知识,扫描下方二维码关注: ...

January 11, 2019 · 1 min · jiezi

vscode 同时编辑多处文字

在使用vscode进行代码编写时,用时候需要替换相同的内容,使用替换或者批量替换,不是太慢就是太快,在要替换的内容不是太多的情况,选中要替换的内容,使用Ctrl+Shift+L,这时所有相同内容都进入编辑状态,可以同时编辑啦。

January 11, 2019 · 1 min · jiezi

Flutter 环境搭建以及创建第一个APP遇到的坑

win10 64位 安装Flutter一、Flutter官方为中国开发者搭建了临时镜像,大家可以将如下环境变量加入到用户环境变量中:export PUB_HOSTED_URL=https://pub.flutter-io.cnexport FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn二、获取Flutter SDK://git 拉取flutter sdkgit clone -b dev https://github.com/flutter/flutter.git//配置path 变量(clone项目下的bin文件地址)export PATH="$PWD/flutter/bin:$PATH"cd ./flutter//安装下载依赖flutter doctor//会有错吴如下[-] Android toolchain - develop for Android devices• Android SDK at D:\Android\sdk✗ Android SDK is missing command line tools; download from https://goo.gl/XxQghQ• Try re-installing or updating your Android SDK, visit https://flutter.io/setup/#android-setup for detailed instructions.三、上面报错原因是没有下载安装Android sdk,Android设置。1、下载android studio2、安装3、安装过程中会遇到downloading components慢的问题 [解决方法][1]4、配置好了镜像后 注释掉disable.android.first.run=true 再启动android studio downloading components就会下载好了5、[设置android studio 模拟器][2]6、配置环境变量 android sdk export ANDROID_HOME 例如SDK装在D:\androidSDK中7、解决第二步 报错 android studio 安装flutter和dart插件四、vscode编辑器配置1、安装flutter和dart插件2、调用 View>Command Palette…3、输入 ‘doctor’, 然后选择 ‘Flutter: Run Flutter Doctor’ action没问题就执行如下:4、调用 View>Command Palette…5、输入 ‘flutter’, 然后选择 ‘Flutter: New Project’ action6、新建项目后F5,这里会报错,问题是之前用镜像下载sdk的问题 要删除之前的代理 android sdk路径的gradle.properties 删除代理7、再按f5就ok了 ...

January 9, 2019 · 1 min · jiezi

使用 VSCode 调试 Koa 或者 Express 项目

前言平常调试 node 打 log 打习惯了,突然发现一个问题就是打印对象的时候,尤其这个对象里面有很多属性的时候,在终端上得一直往上拉才能看到,因此打算使用 vscode 来打断点调试程序。安装这里的例子是使用 koa ,express 类似。我是使用阿里巴巴的飞冰快速搭建一个后台和前台的项目。下载飞冰打开飞冰,使用ICE Design Pro模板并点击 添加koa2,如下自动安装完成后,使用 vscode 打开项目:打开终端,运行npm run client 这个时候前端项目就运行起来了。稍微修改一下前端的代码,因为这个模板默认是使用前端直接返回数据,而不去请求接口,打开client/pages/UserLogin/actions.js,将 import {login} from ‘../../api/user’;改为 import {login} from ‘../../api/index’;就可以了。最后打开页面,地址终端里面有说明。编写launch.jsonVsCode左侧第四个按钮是调试按钮,默认是『没有配置』。点击右侧的齿轮状图标,选择Node.js 会在项目根目录下创建 .vscode 的文件夹及 launch.json 文件。launch.json 内容如下:{ // 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。 // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 “version”: “0.2.0”, “configurations”: [ { “type”: “node”, “request”: “launch”, “name”: “启动程序”, “program”: “${workspaceFolder}/server/index.js” } ]}默认会访问server下的 index.js 文件,但是这个项目的入口文件是 app.js,因此需要将index.js改为app.js。在launch.json中会使用到一些预定变量,这里说明一下:${workspaceRoot}:VSCode中打开文件夹的路径${workspaceRootFolderName}:VSCode中打开文件夹的路径, 但不包含"/"${file}:当前打开的文件${fileBasename}: 当前打开文件的文件名, 不含扩展名${fileDirname}: 当前打开文件的目录名${fileExtname} 当前打开文件的扩展名${cwd}:当前执行目录当我们在单步调试程序的时候,会进入node_modules里面,通常情况下我们并不需要去关心里面的逻辑实现,只关心项目本身的代码。在这个时候,我们就需要使用skipFiles:{ // 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。 // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 “version”: “0.2.0”, “configurations”: [{ “type”: “node”, “request”: “launch”, “name”: “启动程序”, “program”: “${workspaceFolder}/server/index.js”, “skipFiles”: [ “${workspaceRoot}/node_modules//*.js”, “<node_internals>//.js” ] }]}我们还想要自动重启的功能,安装 nodemon 或者 node-dev:// 任选其一npm i nodemon -gnpm i node-dev -g修改lanuch.json:{ // 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。 // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 “version”: “0.2.0”, “configurations”: [{ “type”: “node”, “request”: “launch”, “name”: “启动程序”, “program”: “${workspaceFolder}/server/index.js”, “runtimeExecutable”: “nodemon”, // 或者 node-dev “restart”: true, “console”: “integratedTerminal”, “skipFiles”: [ “${workspaceRoot}/node_modules/**/.js”, “<node_internals>/**/*.js” ] }]}这里新增了三个字段,分别是:runtimeExecutable:用什么命令执行 app.js,这里设置为 nodemon,默认是 noderestart:在终止 Node.js 后重启会话console:启动调试目标的位置,这里选择在 vscode 的集成终端输出信息调试这里在 server/controller/user.js 的 login 打了个断点:启动调试,如下:vscode 集成终端打印如下:在前端页面点击登录,会跳到这里:我们就能看到变量的信息啦????(注意:如果此时终止了调试,nodemon 还是会运行,得在集成终端终止) ...

December 31, 2018 · 1 min · jiezi

vscode launch.json 常用配置

{// Use IntelliSense to learn about possible attributes.// Hover to view descriptions of existing attributes.// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387"version": “0.2.0”,“configurations”: [ { “type”: “chrome”, “request”: “launch”, “name”: “Launch Chrome against localhost”, “url”: “${file}”, “sourceMaps”: true, “webRoot”: “${workspaceRoot}” }, { “name”: “nodeLauch”, //单独调试js,即可以直接运行js “type”: “node”, “request”: “launch”, “program”: “${file}”, //这个配置成你要调试的文件、${file}当前打开的文件 “stopOnEntry”: false, “args”: [], “cwd”: “${workspaceRoot}”, “runtimeExecutable”: null, “runtimeArgs”: [ “–nolazy” ], “env”: { “NODE_ENV”: “development” }, “console”: “internalConsole”, “preLaunchTask”: “”, “sourceMaps”: false }]} ...

December 28, 2018 · 1 min · jiezi

VS Code插件开发介绍(二)

一、前言在上一篇文章里,我简要介绍了 VSCode 插件开发的基本流程,同时讲解了如何获取文件夹绝对路径和用户输入的方法。最近又开发了一个新的插件,主要用途是替换当前编辑文件的内容。google 了一圈,发现介绍这方面的文章很少,特此记录一下,希望对有类似需求的人有一些帮助。二、需求需求很简单,我需要将下面文件的内容:export default { add_member# manage_member_card# member_setting# search_member# edit_member# delete_member# assign_consultant# add_member_tag# import_member# modify_member_point#};替换为:export default { add_member: ‘ce0’, manage_member_card: ‘ce1’, member_setting: ‘ce2’, search_member: ‘ce3’, edit_member: ‘ce4’, delete_member: ‘ce5’, assign_consultant: ‘ce6’, add_member_tag: ‘ce7’, import_member: ‘ce8’, modify_member_point: ‘ce9’,};可以理解为一个简单的自动化编号工具。其中要解决的问题主要有下面三个:获取当前文件路径读取文件内容写文件内容下面介绍如何实现。三、实现开始以为 VSCode 有现成的 API 可以取到当前文件内容,但找了一圈搜不到,只能通过迂回的方式实现。第一步,获取当前文件的路径:const currentlyOpenTabfilePath = vscode.window.activeTextEditor.document.fileName;第二步,读取文件内容,并拆分为数组const fs = require(‘fs’);const fileContentArr = fs.readFileSync(currentlyOpenTabfilePath, ‘utf8’).split(/\r?\n/);第三步,写文件。由于没法逐行替换文件内容,只能现将原来的文件清空,再一行一行添加回去。fs.truncateSync(currentlyOpenTabfilePath);fileContentArr.forEach( (line, index) => { let content = line; if (line.slice(-1) == ‘#’) { content = xxxxx; } fs.appendFileSync(currentlyOpenTabfilePath, content + ((index == contentLength - 1) ? ’’ : ‘\n’));})四、总结其实这个需求实现起来还是蛮简单的,主要是要根据 VSCode 的特点将思路理顺,再一步步实现。如果有更好的实现方式,请务必留言给我 ...

December 27, 2018 · 1 min · jiezi

mobx遇到的问题

使用mobx的react项目图片有提示,编译失败,告诉问题所在,老兄,语法错误了。把第二行报错翻译一遍其实就定位问题了。但是我经常比较急,总喜欢一眼带过,一眼解决,解决不了就不去看了。翻译:个人版:对于实验性语法“decorator-legacy”的支持,目前不能使用。谷歌版:目前尚未启用对实验语法’decorators-legacy’的支持有道版:目前尚未启用对实验语法“decorators-legacy”的支持很明显,答案出来了,我使用的编辑器VScode,没有开启这个实验性语法。我自己不怎么滴,去编辑器的设置去配置了,发现已经设置为true"javascript.implicitProjectConfig.experimentalDecorators": true退出编辑器,重新启动项目,发现还是有上图的报错。看来跟编辑器无关了,我的思维得转换一下,去谷歌了。是的,有一堆。但是直接去babel的github上的issue搜索,有几个,然后脑子一转,mobx官网肯定有教人安装的。结果真的有。地址安装修饰器decorator

December 27, 2018 · 1 min · jiezi

编辑器VSCode使用心得

工欲善其事必先利其器,趁手的工具会使我们开发事半功倍。市面上的编辑器我用过许多,编辑器使用经历Notepad++,(开源)这个应该是最轻量级的吧,查看代码还好,编辑代码就算了官网地址:https://notepad-plus-plus.org/Brackets,(开源)这个也不错,github-star:30k了,上次发布版本是6月18号,我当时弃用的原因是因为对vue支持不太友好官网:http://brackets.io/Atom ,(开源)github-star:47.4k,github官方出品官网地址:https://atom.ioWebStorm,(收费),这是一款很强大的编辑器,基本上就是零配置,功能丰富,缺点也很明显,启动慢,并且付费,没有中文版,中文需要汉化,不知道官方现在有没有中文包,好久没关注了官网地址:https://www.jetbrains.com/webstorm/Sublime Text:(收费),这也是一款算是比较轻量级的编辑器,功能需要自己安装扩展插件来完善,我用了好长一段时间官网地址:http://www.sublimetext.com/HBuilder:(免费),在国产编辑器中算是不错的,支持的功能也很多,当时用它来开发app,当时很想支持一下国产,但是当项目越来越大时,会很卡,超级卡,如果几个项目同时启动,估计就会挂掉了官网地址:http://www.dcloud.io/vscodevscode是我今天要重点介绍的一款编辑器,微软开源,github-star:66k官网地址:https://code.visualstudio.com/大概是从去年年初的时候接触到vscode,一直使用到今天,我并没有否定上面所列举的那些编辑器,只是vscode更适合我,每个编辑器都有自己的优点、卖点。没有最好的兵器,只有最趁手的兵器。vscode有一个很好的卖点,就是它支持中文,这是广大开发者的福利vscode和很多编辑器一样通过扩展插件来完善自己的功能vscode常用插件介绍安装插件我有个重要的参考指标,就是下载量下载量越是受欢迎成都一个参考指标,通常情况下1M以下的下载量我都会慎重考虑,⚠️:插件不是装的越多越好,有的插件间会有冲突,插件装的太多,会让编辑器变得卡顿,也就是说,在最好用,最受欢迎的插件里面挑选你最需要的vscode内部集成了git,如果你的团队也是使用git,那么我想vscode一定是你的首选GitLens — Git supercharged截止目前下载量:11M介绍GitLens增强了构建在vscode代码中的Git功能。它帮助您通过Git blame注释和代码镜头直观地看到代码作者,无缝地导航和探索Git存储库,通过强大的比较命令获得有价值的见解,等等。装上以后,是这个样子,每一行 code 的作者、提交时间、commit log 等信息,一目了然。安装成功后,会出现这个图标如果开发是vscode+git,这个插件强烈推荐,一眼就能看到是谁改了你的代码????Git History截止目前下载量:4.2M介绍:查看和搜索git日志以及图形和详细信息。查看文件的前一个副本。查看和搜索历史查看一个或所有分支的历史(git日志)查看文件的历史记录查看文件中某一行的历史(Git fault)。查看作者的历史比较:比较分支比较有跨提交比较文件其他特点:Github化身挑选提交重新提交从提交创建分支树状视图中的视图提交信息(所有更改的快照)合并和变基更多功能需要自己挖掘Auto Close Tag截止目前下载量:2.2M自动添加HTML/XML关闭标签,写前一半标签,后面一半自动补全Auto Rename Tag截止目前下载量:1.1M自动重命名成对的HTML/XML标记修改了html标签的一半(前面或后面),另一半自动修改,(注意输入法要在英文模式下)Beautify截止目前下载量:6.7M代码中美化javascript、JSON、CSS、Sass和HTML。这个都会安装吧,代码美化Bracket Pair Colorizer截止目前下载量:3.1M这个扩展允许用颜色来标识匹配的括号。用户可以定义要匹配的字符和要使用的颜色。成对的括号(大括号,小括号)颜色相同,这在代码多层括号嵌套时显得尤为重要。ESLint截止目前下载量:15M这个不需要介绍了吧,代码格式校验,支持自定义配置,错误是红色的波浪线,警告是绿色的JavaScript (ES6) code snippets截止目前下载量:2.9M用于vscode编辑器的ES6语法中的JavaScript代码片段(同时支持JavaScript和TypeScript)。这个功能我经常用js里敲clg,然后回车=> console.log(object);在调试的时候很方便实用One Dark Pro截止目前下载量:7.8M编辑器颜色主题,一直是我喜欢的风格,Material Icon Theme截止目前下载量:4.8M很漂亮的图标库,用于编辑器左侧树状菜单文件和文件夹图标显示Vetur截止目前下载量:7.1Mvue项目必装插件,用于vue代码高亮格式化等Bookmarks截止目前下载量:1.3M当代码行数很大的时候,为代码添加书签,再也不怕迷路了,如果忘记了快捷键,可以在代码中右击鼠标使用简单Project Manager截止目前下载量:2.2M如果本地项目很多的话,可以用这个插件管理项目,可以快速切换项目,并且每次只打开一个项目,多项目并行开发的最佳选择关于vscode的插件就介绍那么多了自定义代码片段在命令面板中输入Configure User Snippets选择你要编辑的代码片段,我们一vue来举例选择vue.json进行编辑下面是我的配置{ // Place your snippets for vue here. Each snippet is defined under a snippet name and has a prefix, body and // description. The prefix is what is used to trigger the snippet and the body will be expanded and inserted. Possible variables are: // $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. Placeholders with the // same ids are connected. // Example: // “Print to console”: { // “prefix”: “log”, // “body”: [ // “console.log(’$1’);”, // “$2” // ], // “description”: “Log output to console” // } “Print to console”: { “prefix”: “vue”, “body”: [ “<template>”, " <div>", " </div>", “</template>\n”, “<script>”, “export default {”, " components: {},", " data() {", " return {};", " },", " created() {},", " methods: {}", “};”, “</script>\n”, “<style lang="scss" scoped>”, “</style>”, “$2” ], “description”: “Log output to console” }}格式都是支持自定义的,保存后新建一个vue文件,编辑器中输入vue然后回车 方便吧????关于vscode的一些小建议vscode支持命令行,可以通过命令行按照依赖包,类似于:npm install 但是不建议在命令行中启动项目,类似于:npm start 为什么?当你重启编辑器的时候,服务也会跟着重启,你会说了,我为什么要重启编辑器呢? 我遇到过以下几种情况,编辑器会重载的编辑器很卡,代码格式化失效编辑器很卡,代码提示没了编辑器莫名其妙的变成英文的,虽然不影响使用,但是看着别扭编辑器升级,自动重启按装或者卸载了插件,启用或者禁用了插件,需要重新加载以上这些情况都会重启编辑器,导致在编辑器内启动的命令行工具跟着重启,所以不建议在命令行内启动项目服务(只是个人建议)关于vscode的心得就介绍那么多,希望能对你有所帮助。原文链接 ...

December 21, 2018 · 1 min · jiezi

更友好的管理VSCODE代码片断

写在前面对于我这种严格依赖 VSCODE 的人来说,会更努力的寻找释放生产力的方式,而代码片断是我日常最常用的功能之一。从官网的 Creating your own snippets 可以非常容易的构建自己代码片断库。然而维护一个需要保持特定代码格式的JSON文件是一件非常困难的事,特别是对于像我这种三天头可能就产生一个新的片断来说是一种噩梦。Markdown我想99%的程序员都离不开 Markdown,如果说将一个 Markdown 文件内容直接转换成一个代码片断应该来说是很优雅的形式,例如:这是一个按钮```html (注意 ` 应该是英文)<button type="${1|text,tel,email|}">$0</button>```与之相对应的智能提醒像这样:维护一些 Markdown 文件比维护一个JSON文件更酸爽。vscode-snippet-generatorvscode-snippet-generator 可以快速做到这一点,而且非常简单。快速入门克隆一个管理 Markdown 文件的模板项目:git clone –depth 1 https://github.com/cipchk/vscode-snippet-generator-tpl.git在项目 src 目录下创建一个 button.md,内容为上述。生成一个 VSCODE 插件安装包:npm run release然后将这个 VSCODE 插件分享给团队其他成员,仅此而已。cipchk-vscode 是我个人一个代码片断库,也是使用 vscode-snippet-generator 构建。市场如果你希望给你的开源项目提供一些片断,只需要将 package.json 相关信息变更为自己项目名称即可,最后可以将生成插件提交给VSCODE市场。参数vscode-snippet-generator 是一个命令行工具,它提供一些若干参数,这些参数你可以在命令行中指定,或在根目录创建一个名为 snippet-config.json 配置信息。sourceRoot 指定 Markdown 文件根目录,默认:srcoutFile 指定 JSON 输出路径,默认:./snippets.jsonprefix 指定前缀separator 指定多层级目前间用什么分隔符,默认:-每一个代码片断触发是由 prefix 决定,而生成 prefix 的规则默认是根据目录及文件名结构,例如:src button type.md => button-type,若有前缀:as-button-type full.md => button-full,若有前缀:as-button-full当然如果你愿意也可以通过一段 YAML 语法的头部文本来标记源文件,例如:—prefix: buttondescription: 按钮scope: typescript,html—更多风格示例,请参考 examples 目录。(完)

December 9, 2018 · 1 min · jiezi

VSCode插件开发梳理

纸上得来终觉浅,深知此事要躬行,因此来体验一下VSCode的插件开发,网上有很多小伙伴的文章给了很大帮助,本文的代码是直接使用网上的内容,特此整理出来给后来学习的伙伴们参考https://www.cnblogs.com/lianm…http://www.cnblogs.com/Leo_wl…搭建环境首先Nodejs和VSCode需要提前安装好,这里对这块的安装不再赘述。接下来安装yo 这是vscode团队为插件开发提供的工具npm install -g yo generator-code安装成功后,通过yo code生成插件开发项目,这里官方推荐使用typescript,当然我们更熟悉javascript,其余的根据情况默认即可一路生成后,通过VSCode打开(File->Open Folder)刚生成的插件项目,在这一堆文件中,我们只关心两个重点,extension.js 是插件的入口文件,package.json包含插件的配置信息准备完成后,为了先验证下插件项目正常OK,在VSCode中F5运行(或Debug->start)如果你可以看到VSCode又启动了一个窗口运行插件项目,shift+ctrl+p 输入Hello World如果在右下角能看到Hello World的提示信息就OK 了如果在编辑插件时内容做了变更,在运行的窗口只需通过Ctrl+r 即可刷新,无需关闭重新运行插件内容这里就开始写插件具体的内容了,发挥创造想象力的时候到了,但是一开始无从下手,可以参考下官网的文档,写的很是详细,虽然是英文的但是直接翻译读起来也没特别怪官方入门示例一:https://code.visualstudio.com…这里的插件内容是根据官网示例二的Markdown字数统计做了修改后的内容,可以统计任意文件中所编写的字符数量新建wordCounter.jsclass WordCounter { constructor(_vscode) { //构造函数,传入vscode对象 this.vscode = _vscode; this.init(); } init() { //初始化 var vscode = this.vscode; var StatusBarAlignment = vscode.StatusBarAlignment; var window = this.vscode.window; //statusBar,是需要手动释放的 this.statusBar = window.createStatusBarItem(StatusBarAlignment.Left); //跟注册事件相配合的数组,事件的注册,也是需要释放的 var disposable = []; //事件在注册的时候,会自动填充一个回调的dispose到数组 window.onDidChangeTextEditorSelection(this.updateText, this, disposable); //保存需要释放的资源 this.disposable = vscode.Disposable.from(disposable); this.updateText(); this.statusBar.show(); } updateText() { //现在快凌晨两点,偷个懒早点睡,临时改成字符数量了。 var window = this.vscode.window; this.editor = window.activeTextEditor; var content = this.editor.document.getText(); var len = content.replace(/[\r\n\s]+/g, ‘’).length; this.statusBar.text = 啦啦啦...已经敲了${len}个字符了; } dispose() { //实现dispose方法 this.disposable.dispose(); this.statusBar.dispose(); }} module.exports = WordCounter;修改extension.js// vscode这个包,包含了里面所有的apiconst vscode = require(‘vscode’);// 在插件被激活的时候,这个方法会被调用function activate(context) { var WordCounter = require(’./wordCounter’); var counter = new WordCounter(vscode); //需要释放的资源都在这里依次push到这个数组里面 context.subscriptions.push(counter);}exports.activate = activate;// this method is called when your extension is deactivatedfunction deactivate() {}exports.deactivate = deactivate;修改package.json{ “name”: “wordcount”, “displayName”: “WordCount”, “description”: “wordcount”, “version”: “0.0.1”, “engines”: { “vscode”: “^1.29.0” }, “categories”: [ “Other” ], “activationEvents”: [ “*” ], “main”: “./extension”, “contributes”: { “commands”: [ { “command”: “extension.sayHello”, “title”: “Hello World” } ] }, “scripts”: { “postinstall”: “node ./node_modules/vscode/bin/install”, “test”: “node ./node_modules/vscode/bin/test” }, “devDependencies”: { “typescript”: “^3.1.4”, “vscode”: “^1.1.25”, “eslint”: “^4.11.0”, “@types/node”: “^8.10.25”, “@types/mocha”: “^2.2.42” }}然后就shift+ctrl+p进入到插件运行环境下测试就可以在状态栏中的字符数量提示了本地使用插件插件编写好了之后,如何正常在VSCode开发过程中使用,这块直接把开发的插件项目拷贝到VSCode存放安装插件的目录下C:\Users\your name.vscode\extensions插件项目拷贝进去后,重启VSCode,然后随意打开一个新的项目,在状态栏也可以看到字符统计的这个功能了插件发布官方插件发布流程:https://code.visualstudio.com… ...

December 6, 2018 · 1 min · jiezi

我编写 33 个 VSCode 扩展的原因以及管理扩展的经验

简评:使用工具的同时自己创造一些工具或扩展,是一件很棒的事情。以下“我”指原作者 Fabio大家好,我叫 Fabio,是一位自学成才的开发人员,热衷于开源和授权。我也喜欢自己制作工具,自然而然地。我为常用的 VSCode 程序编写了很多扩展。在开发和管理 VSCode 扩展以及谈论我创造的所有扩展的同时,我想与大家再分享一些我的工作流程。在这里我将介绍我创造的许多工具和扩展,因此无论你是要开始开发扩展,还是想要找到很酷的新扩展,或者只是需要管理很多存储库,本文保证会有你感兴趣的内容。编写一个扩展我喜欢生产力和自动化,所以我开始新项目的方式非常精简。工具我编写了一个名为 template 的开源项目,它可以基于模板快速创建新项目,非常简单:它需要一个文件夹作为输入(“模板”)。它用 handlebars 处理所有文件,要求你为模板中找到的占位符提供值(即{{name}})。它输出一个替换了所有占位符的新文件夹。我了解过 yeoman,但它对于我的使用情况来说似乎太复杂了。我用过 khaos,但是它不再维护,并且它不会自动更新模板,总不能在每次我想用的时候都手动更新,所以我没有使用它。模板接下来我使用我的 template-vscode-extension 模板启动一个新的 VSCode 扩展。现在我有一个工作的 Hello-World-ish 扩展。该模板包含许多我经常使用的辅助函数:它支持从.vscode文件夹加载自定义配置文件 ,可以自动注册命令,还可以根据活动文件推断当前根等。如果我能回到过去,可能会把所有这些辅助函数放到一个独立的vscode-utils包中,而不是在所有扩展中复制它们,不幸的是一开始我不知道将进行 10 次扩展,现在去更新它们将需要相当多的时间。如果你在考虑编写 VSCode 扩展,或许会想以我的扩展为基础,我建议你制作自己的模板。文档我在开发扩展时总是打开 VSCode 的文档。虽然文档很长,要找到你需要的 API 并不是那么简单明了,但是只要快速阅读一下很快你就会熟悉起来。总的来说,我对能找到的 API 相当满意。扩展不管你信不信,我所做的一些扩展实际上对我开发其他扩展有一定帮助,稍后会对此进行进一步的讨论。我的扩展正如我所说的,我喜欢生产力,所以我的大部分扩展都与生产力相关的。我尽量不要过多地重复发明轮子,确保功能在扩展之间良好分离,彼此之间良好配合。无论好坏,我发现扩展很有趣,并且不乏可以自动化的东西,这就是为什么在第 1 个扩展之后我又做了第 2 个,第 3 个……和第 33 个!点击以下每个扩展程序的超链可以进入原页面,获取到更多详细信息和屏幕截图。用来编写扩展程序的扩展2、Debug Launcher:无需定义任何任务或启动配置即可从终端开始调试。我不想用重复的启动配置和任务来混乱我的存储库。VSCode 真的应该直接支持从终端启动调试器,对此我提了一个 issue。从终端启动调试器2、StatusBar Debugger:将调试器添加到状态栏,比默认浮动调试器干扰更少。默认工具栏的使用体验很糟糕(相关 issue),如果 VSCode 能公开调试状态,那这个扩展可能会好得多。3、Install .VSIX:直接从资源管理器安装扩展,右键单击即可。因为现在安装 .vsix 的体验也很糟糕(相关 issue)。4、Bump:压缩项目的版本并更新更改日志。有意见但可配置。每个可敬的扩展都需要一个更新日志,但这并不意味着你必须手动编写一个。这个扩展是我的最爱之一,我可能会制作一个CLI版本,希望将来它也可以为我制作 GitHub 版本。5、Optimize Images:使用你最喜欢的应用程序优化项目中的一个或所有图像。只需一个命令即可完成。管理项目6、Projects+:管理项目的扩展。功能丰富,可自定义,自动查找你的项目。Project Manager 是这种类型中最常用的扩展,但我有 100 多个存储库,包括一个无限可嵌套的组,我需要正确的工具来管理它们。Projects+ 可定制的快速选择Projects+ 可定制的快速选择管理待办事项7、Todo +:轻松管理待办事项列表。功能强大,易于使用和可定制。如果你不需要对TODO文件进行语法高亮,可能只想要内置的基本高亮显示,那么可以查看 Todo Tree。Todo + 语法高亮和项目级统计8、Highlight:基于正则表达式的高级文本高亮显示。适用于待机,注释等。大多数人只是使用 TODO Highlight,但我的方式更通用,更强大,也可能更快。9、Markdown Todo:轻松管理 markdown 文件中的待办事项列表。没什么特别的,但是它可以让一些 Todo + 的快捷方式基本上可以在 Markdown 文件中使用。10、Projects + Todo +:鸟瞰你的项目,将所有的 ToDo 文件聚合为一个。如果你使用 Projects + 来管理项目,且使用 Todo + 来管理待办事项,那么现在可以将所有(或部分)项目中的所有待办事项汇总到一个文件中。在…中打开…在不同的应用程序/网站之间快速切换对我来说很重要,这就是我做了很多Open in…扩展的原因。11、Open in Application:在默认的应用程序或你想要的应用程序中打开任意文件。广义Open in…扩展。12、Open in Browsers:添加一些命令,用于在任何你喜欢的浏览器中打开当前文件或项目,甚至可以同时在所有浏览器中打开。13、Open in Code:轻松地在代码和代码内部之间切换。14、Open in Finder:添加一些命令用以在 Finder 中打开当前文件或项目。15、Open in GitHub:在 github.com 中打开当前项目或文件。还有很多其他的扩展可以实现这个功能,但是当我试用时,发现它们非常臃肿,有很多我不需要或不起作用的东西。16、Open in GitTower:添加一个在 GitTower 中打开当前项目的命令。17、 Open in Marketplace:添加用于在 Marketplace 中打开当前项目的命令。18、Open in node_modules:在 node_modules 中打开当前选择或任意字符串。当你想深入了解你正在使用的模块时很有用。19、Open in NPM:在 npmjs.com 中打开当前选择、项目或任意字符串。有助于快速查看自述文件。20、Open in Ship:添加用于在 Ship 中打开当前项目的命令。不幸的是,Ship 已被弃用,它不再起作用了。我现在在 Noty 中有一个专门的标签来管理即将发生的问题。21、Open in Terminal:添加一些命令以在终端中打开当前项目。22、Open in Transmit:添加一些命令用以在 transmit 中打开当前文件或项目。 其他 23、Browser Refresh:从代码中使用 ⌘R 刷新浏览器。无需将焦点切换到它。当你无法使用热重载,并且不希望浏览器在不需要时同步刷新页面,它会非常有用。24、Commands:从状态栏触发任意命令。支持传递参数!通过命令定义的自定义命令25、Diff:Diff 2 可以轻松打开文件。因为运行code — diff path1 path2太慢了。26、Git File History::查看或区分当前文件的历史版本。其他类似的扩展不好用。27、GitHub Notifications:一个安全,可自定义的状态栏图标,提醒你有关 GitHub 上的通知。28、Monokai Night Theme:完整,黑暗和简约的 Monokai 风格主题。我试用过的主题没有一个好用,所以我不得不做出自己的主题。Monokai Night Theme29、No [Unsupported]:从标题栏中删除 “[Unsupported]” 的扩展名。现在不推荐使用,我建议使用 Fix VSCode Checksums。相关讨论见 issue 1 和issue 2。30、Open Multiple Files:同时打开文件夹中的所有文件,可选择用 glob 过滤。31、Search — Open All Results:用一个命令同时打开所有搜索结果。32、Terminals Manager:一次性设置多个终端或仅运行某些命令的扩展。这实际上是我做的第一个扩展。33、Transmit:添加一些命令用以与 Transmit 进行交互。介绍这些花了不少时间,讲一个有趣的小事:我想我的账户上发布的扩展最多,紧随微软之后,至少我还没有发现有人发布了比我更多的扩展(写完本文后发现 Greg 比我多做了 2 次扩展,我得加油了)管理扩展管理多个存储库可能是一个挑战,以下是我的工作方式。重复提交迟早你会想要更改所有存储库中的某些内容,这意味着需要在多个存储库中进行基本相同的提交,无聊而浪费时间。为了实现这类任务的自动化,我制作了 autogit,它是一个跨多个存储库执行命令的工具。通过 autogit 执行 shell 命令的示例我一直在寻找它的用途,最近我用它对我所有扩展的存储库进行了以下更改:捆绑webpack:我发现启动时间提高了约 80%。忽略package-lock.json:这只是我提交历史中的垃圾信息,阅读本 issue参考 Sindre Sorhus 关于忽略 package-lock.json 的见解。更新tsconfig.json以输出最新的代码:我使用了相当多的异步函数,但当目标版本为<=es5时,异步函数被转换为慢速代码,并且由于 VSCode 与 Node.js 的现代版本一起发布,所以不需要这样做。删除了 TSLint:我关注到我基本上忽略了它的输出,所以我删除了对 linting 的支持。在 readme 中使用高分辨率 logo:在 readme 中使用高分辨率 logo 而不是之前使用的128x128 的 logo,遗憾的是我没有特别好的 logo,这是另一个故事了 :)可以看到 autogit 如何在 33 个存储库中快速地执行这 5 项更改。使用 GitHub 同步描述和关键字这是一个不必做的事情,但是如果有一个工具能为你做这件事,那就太好了。幸运的是,autogit 和 autogit-command-github-sync 命令也能做到这一点:通过 autogit 同步我还制作了autogit-command-github-publish,用于自动创建 GitHub 存储库。报告在做了最初几次扩展后不久,我开始对了解他们获得了多少新下载感兴趣。你可以在一个页面中查看所有扩展程序,例如,您可以在此处找到我的扩展程序,但如果你不记得上次检查时扩展程序的下载次数,则无法知道新增了多少。这是我制作 rssa 的原因,这个工具可以告诉你什么时候会发生变化。你可以用它来监控几乎所有可用 URL 访问的内容。自定义 rssa 输出如果有图表那就更棒了,虽然我还没有发布这个工具,但是利用 rssa 的历史我们可以生成图表,下面是 Todo+ 的下载次数的图表:Todo +下载需要注意的是,有时候下载量会急剧增加,当发布新的更新时,就会出现这种情况,因为更新被视为下载????,任何人都可以通过推送许多次更新来拥有具有一百万次下载的扩展,这是应用市场的一个问题。谢谢很开心你看到了最后!谢谢你的阅读,希望你在这里找到了有用的内容。在评论聊一聊你是如何开发 VSCode 扩展的,以及你使用了什么扩展吧! ...

November 26, 2018 · 2 min · jiezi

智能微服务的设计与开发(node.js)

设计目标基于koa2、关系数据库(暂时只支持mysql)建立的智能微服务快速开发框架,将同时支持graphql与rest标准,使用typescript语言编写,力求安全、高效。 相关开源项目(gels – 凝胶),希冀该项目能成为联结设计、开发,前端、后端的“强力胶水”,成为微服务快速开发的有力框架。 项目地址:https://github.com/zhoutk/gels设计思路中小型企业,更多的是注重快速开发、功能迭代。关系数据库为我们提供了很多有用的支持,我试图把数据库设计与程序开发有机的结合起来,让前端送到后端的json对象自动映射成为标准的SQL查询语句。我的这种ORM方式,服务端不需要写一行代码,只需完成关系数据库的设计,就能为前端提供标准服务接口。 我设计了一套数据库访问标准接口,在实践中已经得到很好的运用。我已经在es6, typescript, java, python & go中实现;下一步是对数据库支持的扩展,准备支持流行的关系数据库(Mssql, sqlite3, prostgres等),有选择支持一些nosql,比如:mongo。数据库接口设计事务元素接口,sql参数用于手动书写sql语句,id会作为最后一个参数被送入参数数组。export default interface TransElement { table: string; method: string; params: object | Array<any>; sql?: string; id?: string | number;}数据库操作接口,包括基本CURD,两个执行手写sql接口,一个批量插入与更新二合一接口,一个事务操作接口。实践证明,下面八个接口,在绝大部分情况下已经足够。export default interface IDao { select(tablename: string, params: object, fields?: Array<string>): Promise<any>; insert(tablename: string, params: object): Promise<any>; update(tablename: string, params: object, id: string|number): Promise<any>; delete(tablename: string, id: string|number): Promise<any>; querySql(sql: string, values: Array<any>, params: object, fields?: Array<string>): Promise<any>; execSql(sql: string, values: Array<any>): Promise<any>; insertBatch(tablename: string, elements: Array<any>): Promise<any>; transGo(elements: Array<TransElement>, isAsync?: boolean): Promise<any>;}BaseDao,为业务层提供标准数据库访问的基类,是自动提供标准rest微服务的关键import IDao from ‘./idao’let dialect = G.CONFIGS.db_dialect //依赖注入let Dao = require(./${dialect}Dao).default export default class BaseDao { private table: string static dao: IDao //以组合的模式,解耦业务层与数据库访问层 constructor(table?: string) { this.table = table || ’’ if (!BaseDao.dao) { BaseDao.dao = new Dao() } } async retrieve(params = {}, fields = [], session = {userid: ‘’}): Promise<any> { let rs try { rs = await BaseDao.dao.select(this.table, params, fields) } catch (err) { err.message = data query fail: ${err.message} return err } return rs } async create(params = {}, fields = [], session = {userid: ‘’}): Promise<any> { let rs try { rs = await BaseDao.dao.insert(this.table, params) } catch (err) { err.message = data insert fail: ${err.message} return err } let { affectedRows } = rs return G.jsResponse(200, ‘data insert success.’, { affectedRows, id: rs.insertId }) } async update(params, fields = [], session = { userid: ’’ }): Promise<any> { params = params || {} const { id, …restParams } = params let rs try { rs = await BaseDao.dao.update(this.table, restParams, id) } catch (err) { err.message = data update fail: ${err.message} return err } let { affectedRows } = rs return G.jsResponse(200, ‘data update success.’, { affectedRows, id }) } async delete(params = {}, fields = [], session = {userid: ‘’}): Promise<any> { let id = params[‘id’] let rs try { rs = await BaseDao.dao.delete(this.table, id) } catch (err) { err.message = data delete fail: ${err.message} return err } let {affectedRows} = rs return G.jsResponse(200, ‘data delete success.’, { affectedRows, id }) }}默认路由/op/:command,只支持POST请求,不鉴权,提供登录等特定服务支持login,登录接口;输入参数{username, password};登录成功返回参数:{status:200, token}/rs/:table[/:id],支持四种restful请求,GET, POST, PUT, DELELTE,除GET外,其它请求检测是否授权中间件globalError,全局错误处理中间件router,路由中间件logger,日志,集成log4js,输出系统日志session,使用jsonwebtoken,实现鉴权;同时,为通过的鉴权的用户生成对应的session用户登录成功后得到的token,在以后的ajax调用时,需要在header头中加入token keyrestful_api数据表库设计完成后,会自动提供如下形式的标准restful api,多表关系可用关系数据库的视图来完成。[GET] /rs/users[?key=value&…], 列表查询,支持各种智能查询[GET] /rs/users/{id}, 单条查询[POST] /rs/users, 新增记录[PUT] /rs/users/{id}, 修改记录[DELETE] /rs/users/{id}, 删除记录智能查询查询保留字:fields, page, size, sort, search, lks, ins, ors, count, sum, groupfields, 定义查询结果字段,支持数组和逗号分隔字符串两种形式查询示例: /rs/users?username=white&age=22&fields=[“username”,“age”]生成sql: SELECT username,age FROM users WHERE username = ? and age = ?page, 分页参数,第几页size, 分页参数,每页行数sort, 查询结果排序参数查询示例: /rs/users?page=1&size=10&sort=age desc生成sql: SELECT * FROM users ORDER BY age desc LIMIT 0,10search, 模糊查询切换参数,不提供时为精确匹配查询示例: /rs/users?username=i&password=1&search生成sql: SELECT * FROM users WHERE username like ? and password like ?ins, 数据库表单字段in查询,一字段对多个值,例:查询示例: /rs/users?ins=[“age”,11,22,26]生成sql: SELECT * FROM users WHERE age in ( ? )ors, 数据库表多字段精确查询,or连接,多个字段对多个值,支持null值查询,例:查询示例: /rs/users?ors=[“age”,1,“age”,22,“password”,null]生成sql: SELECT * FROM users WHERE ( age = ? or age = ? or password is null )lks, 数据库表多字段模糊查询,or连接,多个字段对多个值,支持null值查询,例:查询示例: /rs/users?lks=[“username”,“i”,“password”,null]生成sql: SELECT * FROM users WHERE ( username like ? or password is null )count, 数据库查询函数count,行统计,例:查询示例: /rs/users?count=[“1”,“total”]&fields=[“username”]生成sql: SELECT username,count(1) as total FROM userssum, 数据库查询函数sum,字段求和,例:查询示例: /rs/users?sum=[“age”,“ageSum”]&fields=[“username”]生成sql: SELECT username,sum(age) as ageSum FROM usersgroup, 数据库分组函数group,例:查询示例: /rs/users?group=age&count=["",“total”]&fields=[“age”]生成sql: SELECT age,count() as total FROM users GROUP BY age不等操作符查询支持支持的不等操作符有:>, >=, <, <=, <>, =;逗号符为分隔符,一个字段支持一或二个操作。 特殊处:使用"=“可以使某个字段跳过search影响,让模糊匹配与精确匹配同时出现在一个查询语句中一个字段一个操作,示例:查询示例: /rs/users?age=>,10生成sql: SELECT * FROM users WHERE age> ?一个字段二个操作,示例:查询示例: /rs/users?age=>,10,<=,35生成sql: SELECT * FROM users WHERE age> ? and age<= ?使用”=“去除字段的search影响,示例:查询示例: /rs/users?age==,22&username=i&search生成sql: SELECT * FROM users WHERE age= ? and username like ?高级操作新增一条记录url [POST]/rs/usersheader Content-Type: application/json token: eyJhbGciOiJIUzI1NiIsInR…输入参数 { “username”:“bill”, “password”:“abcd”, “age”:46, “power”: “["admin","data"]” }返回参数 { “affectedRows”: 1, “id”: 7, “status”: 200, “message”: “data insert success.” }execSql执行手写sql语句,供后端内部调用使用示例 await new BaseDao().execSql(“update users set username = ?, age = ? where id = ? “, [“gels”,“99”,“6”])返回参数 { “affectedRows”: 1, “status”: 200, “message”: “data execSql success.” }insertBatch批量插入与更新二合一接口,供后端内部调用使用示例 let params = [ { “username”:“bill2”, “password”:“523”, “age”:4 }, { “username”:“bill3”, “password”:“4”, “age”:44 }, { “username”:“bill6”, “password”:“46”, “age”:46 } ] await new BaseDao().insertBatch(‘users’, params)返回参数 { “affectedRows”: 3, “status”: 200, “message”: “data batch success.” }tranGo事务处理接口,供后端内部调用使用示例 let trs = [ { table: ‘users’, method: ‘Insert’, params: { username: ‘zhou1’, password: ‘1’, age: 1 } }, { table: ‘users’, method: ‘Insert’, params: { username: ‘zhou2’, password: ‘2’, age: 2 } }, { table: ‘users’, method: ‘Insert’, params: { username: ‘zhou3’, password: ‘3’, age: 3 } } ] await new BaseDao().transGo(trs, true) //true,异步执行;false,同步执行返回参数 { “affectedRows”: 3, “status”: 200, “message”: “data trans success.” }安装运行运行数据脚本SET NAMES utf8;SET FOREIGN_KEY_CHECKS = 0;– —————————— Table structure for users– —————————-DROP TABLE IF EXISTS users;CREATE TABLE users (id int(11) NOT NULL AUTO_INCREMENT,username varchar(255) DEFAULT NULL,password varchar(255) DEFAULT NULL,age int(11) DEFAULT NULL,power json DEFAULT NULL,PRIMARY KEY (id)) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4;– —————————— Records of users– —————————-BEGIN;INSERT INTO users VALUES (‘1’, ‘white’, ‘123’, ‘22’, null), (‘2’, ‘john’, ‘456i’, ‘25’, null), (‘3’, ‘marry’, null, ‘22’, null), (‘4’, ‘bill’, ‘123’, ‘11’, null), (‘5’, ‘alice’, ‘122’, ‘16’, null), (‘6’, ‘zhoutk’, ‘123456’, ‘26’, null);COMMIT;SET FOREIGN_KEY_CHECKS = 1;配置文件示例,./src/config/configs.tsexport default { inits: { directory: { run: false, dirs: [‘public/upload’, ‘public/temp’] } }, port: 5000, db_dialect: ‘mysql’, dbconfig: { db_host: ’localhost’, db_port: 3306, db_name: ‘strest’, db_user: ‘root’, db_pass: ‘123456’, db_char: ‘utf8mb4’, db_conn: 10, }, jwt: { secret: ‘zh-tf2Gp4SFU>a4bh_$3#46d0e85W10aGMkE5xKQ’, expires_max: 36000 //10小时,单位:秒 },}在终端(Terminal)中依次运行如下命令git clone https://github.com/zhoutk/gelscd gelsnpm i -g yarnyarn global install typescript tslint nodemonyarn installtsc -w //或 command + shift + B,选 tsc:监视yarn start //或 node ./dist/index.js项目结构├── package.json├── src //源代码目录│ ├── app.ts //koa配置及启动│ ├── common //通用函数或元素目录│ │ ├── globUtils.ts │ ├── config //配置文件目录│ │ ├── configs.ts│ ├── db //数据封装目录│ │ ├── baseDao.ts│ ├── globals.d.ts //全局声明定义文件│ ├── index.ts //运行入口│ ├── inits //启动初始化配置目录│ │ ├── global.ts│ │ ├── index.ts│ │ ├── initDirectory.ts│ ├── middlewares //中间件目录│ │ ├── globalError.ts│ │ ├── logger.ts│ │ ├── router│ │ └── session.ts│ └── routers //路由配置目录│ ├── index.ts│ └── router_rs.ts├── tsconfig.json└── tslint.json相关资源地址凝胶(gels)项目: https://github.com/zhoutk/gels视频讲座资料: https://github.com/zhoutk/sifou个人博客: https://github.com/zhoutk/blog相关视频课程运用typescript进行node.js后端开发精要 这是视频2的先导课免费入口,数量有限,先到先得nodejs实战之智能微服务快速开发框架 视频2亮点:成熟项目经验,经过总结、提炼、精简、重构,带领大家一步步实现一个智能微服务框架,这是一个完整的实用项目从无到有的实现过程。课程内容与结构经过精心准备,设计合理、节奏紧凑、内容翔实。真实再现了思考、编码、调试、除 错的整个开发过程。购置了新的录屏软件和录音设备,去除了上个视频中的杂音,清晰度更高,视频比较长,有三个小时。 ...

November 16, 2018 · 5 min · jiezi

VsCode 添加文件头部注释和函数注释[koroFileHeader]

以前发过这个插件,这回版本升级了一下,修复了以前默认配置项不能删除,顺序不能移动的问题,并且新增了光标处添加函数注释的功能,也重写了一遍readme,所以再推广一下这个插件,下一步计划是支持其他语言的注释。以下是readme正文。koroFileHeader一个读取用户自定义模板,通过快捷键添加文件头部注释、在光标处添加函数注释的VsCode插件language简体中文 | English项目地址:传送门简介文件头部添加注释:在文件开头添加注释,记录文件信息读取用户设置,生成注释模板保存文件的时候,自动更新最后的编辑时间和编辑人快捷键:window:ctrl+alt+i,mac:ctrl+cmd+i在光标处添加函数注释:在光标处自动生成一个注释模板,下方有栗子支持用户自定义文件注释模板快捷键:window:ctrl+alt+t,mac:ctrl+cmd+t安装在 Vscode 扩展商店中搜索koroFileHeader,点击安装即可。使用文件头部注释:在当前编辑文件中使用快捷键:window:ctrl+alt+t/mac:ctrl+cmd+t,即可生成文件头部注释。函数注释:将光标放在函数行或者将光标放在函数上方的空白行使用快捷键window:ctrl+alt+t,mac:ctrl+cmd+t,即可生成函数注释。事实上,函数注释在文件的任意位置都可生成,这里需要自己控制。注释模板的设置默认配置:在用户首选项中搜索fileheader,默认配置为: “fileheader.customMade”: {} // 头部注释 “fileheader.cursorMode”: {} // 函数注释 用户未设置的情况下,头部注释和函数注释模板为:自定义模板:在用户设置中,搜索fileheader复制默认配置+修改配置,重启生效如上设置,生成注释:// 文件头部注释/* * @Description: * @version: * @Company: BAT * @Author: OBKoro1 * @Date: 2018-10-15 20:59:57 * @LastEditors: OBKoro1 * @LastEditTime: 2018-10-15 20:59:57 / // 函数注释 /* * @name: * @test: test font * @msg: * @param {type} * @return: */自动更新最后编辑时间、编辑人:要开启这个功能,需要在首选项设置中填写对应的属性: “fileheader.customMade”: { “Date”: “Do not edit”, // 文件创建时间(不变) “LastEditors”: “OBKoro1”, // 文件最后编辑者 “LastEditTime”: “Do not edit” // 文件最后编辑时间 } // 不填写对应属性即关闭对应功能自动更新编辑时间示例:最后如果觉得还不错的话,就给个 Star ⭐️ 鼓励一下我吧~博客、前端积累文档、公众号、GitHub ...

October 17, 2018 · 1 min · jiezi

新一代流式计算框架在金融行业的应用

大数据时代,数据计算已经渗透到了各行各业。业务沉淀数据,数据计算产生新的业务价值,数据计算正不断地用这种方式推动业务向前发展。大数据的计算模式主要分为批量计算(batch computing)、流式计算(stream computing)等,分别适用于不同的大数据应用场景。对于先存储后计算,实时性要求不高,同时数据规模大、计算模型复杂的应用场景,更适合使用批量计算。对于无需先存储,可以直接进行数据计算,实时性要求严格,但单次计算涉及数据量相对较小的应用场景,流式计算具有明显优势。与传统批量计算相比,流式计算的特点主要有以下几方面: 无边界:数据到达、处理和向后传递均是持续不断的。 瞬时性和有限持久性:通常情况下,原始数据单遍扫描,只有计算结果和部分中间数据在有限时间内被保存和向后传递。 价值的时间偏倚性:随着时间的流逝,数据中所蕴含的知识价值往往也在衰减,即流中数据项的重要程度是不同的,最近到达的数据往往比早先到达的数据更有价值。金融行业是一种典型的流式计算应用领域,涵盖了包括用户行为分析、实时营销、个性化推荐、实时风控、实时反欺诈等多个计算场景。以实时金融风控场景为例,需要流式计算系统实时分析海量的用户行为数据,根据既定的规则计算出相应的指标,并与风险模型进行匹配,第一时间判断风险等级、发现异常事件,并作出相应的风险控制措施,自动告警通知、改变业务流程。流式计算框架的技术选型目前主流的流式计算框架有Storm、Spark Streaming、Flink三种,其基本原理如下: Apache Storm:以单事件来处理数据流(所有记录一个接一个处理),延迟性低(毫秒级),但消息保障能力弱,消息传输可能重复但不会丢失;Storm在运行中可分为spout与bolt两个组件,Spout是Stream的消息产生源,Bolt类接收由Spout或者其他上游Bolt类发来的消息,对其进行处理,以实现业务逻辑。Storm运行的应用程序叫做拓扑(Topology),拓扑中定义了Spout和Bolt的组合关系。 Apache Spark Streaming:属于Spark API的扩展,以设定的时间间隔(如几秒种)处理一段段的批处理作业(即“微批处理”)。这种框架的延迟性较高(秒级),但能够保证消息传输既不会丢失也不会重复;spark程序是使用一个spark应用实例一次性对一批历史数据进行处理,spark streaming是将持续不断输入的数据流转换成多个batch分片,使用一批spark应用实例进行处理。 Apache Flink:针对流数据+批数据的计算框架。把批数据看作流数据的一种特例,延迟性较低(毫秒级),且能够保证消息传输不丢失不重复。Flink创造性的统一了流处理和批处理,作为流处理看待时输入数据流是无界的,而批处理被作为一种特殊的流处理,只是它的输入数据流被定义为有界的。Flink程序由Stream和Transformation这两个基本构建块组成,其中Stream是一个中间结果数据,而Transformation是一个操作,它对一个或多个输入Stream进行计算处理,输出一个或多个结果Stream。三种实时计算框架的对比如下:从上述指标对比可以看出,Flink作为流式处理框架中的新兴之秀,兼具了storm的低延迟和spark的高吞吐、高消息保障特性。随着框架成熟度和社区活跃度越来越高,目前Flink已在国内外各大企业中有很多成功应用,很多企业纷纷将原有基于storm、spark streaming框架的流式计算系统转投为基于Flink,Flink成为当下流式计算框架的首选。]6流式计算在金融行业的应用架构顶象技术目前已为多个银行及互联网金融客户设计并搭建了基于Flink流式计算框架的一站式实时计算平台,满足金融客户实时风控、实时反欺诈等多个场景下的计算需求。金融行业的数据具有来源广泛、实时性要求高、吞吐量大、计算模型复杂等特性,顶象技术基于Flink引擎,进行了大量的功能及可用性设计,设计了一套可支持风控、反欺诈,流式计算和同步计算的一站式实时计算平台,满足金融行业实时风控、实时反欺诈等多个场景下的计算需求。顶象一站式实时计算平台的概要架构和特点: 多数据源支持:支持从多种类型的消息中间件中获取消息流,以及从关系数据库或NoSql数据库中抽取全量/增量数据,并提供服务接口供其他系统实时推送数据。保证了计算数据的完整性和多样性。 统一的异步/同步计算服务:基于Flink的流式计算仅能满足客户的实时异步计算需求,而无法满足需要实时返回计算结果的计算场景。因此,顶象一站式实时计算平台包含了高性能的同步计算框架,可满足同步返回计算结果的应用场景。该框架与异步流式计算框架结合,提供统一的计算服务,完美覆盖所有实时计算需求。 可视化的计算配置和实时分析:为提高系统的易用性,使没有编程经验的业务人员也可通过流式计算快速实现业务目标,平台提供了可视化计算规则配置引擎,可针对各类应用场景,定义相应的计算规则。如针对风控场景,可定义各类风控事件的指标计算规则。同时,平台提供实时在线分析功能,业务人员在线选择数据源,设置报表统计规则,自动生成并实时刷新各种维度的图表,达到了数据的实时可视化分析。目前,顶象技术的一站式实时计算平台已在多个知名银行及互联网金融企业中部署上线,结合顶象实时决策引擎,实现了毫秒级风控指标计算与风控预警,同时为行内其他系统提供了统一实时数据计算服务,达到了很好的应用效果。金融机构在应用大数据的过程中,不仅需要看到其对于海量数据的存储、查询和分析类场景的需要,更需要探索如何运用多种大数据技术范式为业务提供解决方案。在应用较多的领域如用户画像、精准营销、实时反欺诈等领域,实时流计算的运用已经成为事实标准,未来在量化交易、风险检测、实时机器学习、实时决策引擎、设备异常分析等领域,相信还有更多用武之地。

October 12, 2018 · 1 min · jiezi

VS Code插件开发介绍

前言前段时间做了一个基于命令行的效率工具,可以自动生成组件的模板代码。自己用起来还觉得挺好,但在组内案例几次后大家都不愿意用,究其原因还是命令行工具使用起来门槛有点高,不方便。由于组内已经统一使用VS Code进行开发了,于是决定研究下VS Code的插件开发,让效率工具更方便的用起来。准备工作为了降低开发门槛,微软做了一个Yeoman代码生成命令,可以很方便的生成插件开发需要的模板代码,可以通过以下命令安装:// 安装npm install -g yo generator-code// 使用yo code运行完以上命令后会出现下面的操作界面,填入需要的信息即可。运行示例代码代码生成后,可以按F5开始调试插件,此时VS Code会新建一个实例并进入插件开发模式,开发中的插件可以在这个新的实例中使用。模版代码会生成一个名为Hello World的命令,按下⇧⌘P调出命令输入窗口,然后输入’Hello World’运行命令。如果找不到命令,重启下VS Code再重新运行。修改代码插件的入口代码在extension.js这个文件中,主要是修改avtivate函数:export function activate(context) { // Use the console to output diagnostic information (console.log) and errors (console.error) // This line of code will only be executed once when your extension is activated console.log(‘Congratulations, your extension “my-first-extension” is now active!’); // The command has been defined in the package.json file // Now provide the implementation of the command with registerCommand // The commandId parameter must match the command field in package.json let disposable = vscode.commands.registerCommand(’extension.sayHello’, () => { // The code you place here will be executed every time your command is executed // Display a message box to the user vscode.window.showInformationMessage(‘Hello World!’); }); context.subscriptions.push(disposable);}我插件的功能是用户通过右键点击导航栏,获取选中文件夹的绝对路径,然后提示用户输入新组件的名字,然后自动帮用户生成组件的模板代码。开发的关键点是如何获取文件夹绝对路径和获取用户输入的组件名。尤其是获取路径,找了很久才找到,官网的文档只字未提。先看代码:function activate(context) { console.log(‘Congratulations, your extension “react-template” is now active!’); // 注册一个名为createFunctionalComponent的命令 const fc = vscode.commands.registerCommand(’extension.createFunctionalComponent’, function (param) { // 文件夹绝对路径 const folderPath = param.fsPath; const options = { prompt: “请输入组件名: “, placeHolder: “组件名” } // 调出系统输入框获取组件名 vscode.window.showInputBox(options).then(value => { if (!value) return; const componentName = value; const fullPath = ${folderPath}/${componentName}; // 生成模板代码,不是本文的重点,先忽略 generateComponent(componentName, fullPath, ComponentType.FUNCTIONAL_COMP); }); }); context.subscriptions.push(pc);}代码很简单,就不做讲解了。为了显示Create Functional Component这个菜单项,我们需要修改package.json文件的contributes字段。activationEvents字段也要相应的改下。同时为了给插件配一个图标,要加一个icon字段: “icon”: “images/icon.png”, “activationEvents”: [ “onCommand:extension.createFunctionalComponent” ], “contributes”: { “commands”: [ { “command”: “extension.createFunctionalComponent”, “title”: “Create Functional Component” } ], “menus”: { “explorer/context”: [ { “command”: “extension.createFunctionalComponent”, “group”: “1_modification” } ] } },详细的contributes配置可以看这里。配置好menus之后,registerCommand的第二个函数参数就能取到文件或文件夹的绝对路径了。发布插件插件开发完后就可以发布了,需要安装vsce npm install -g vsce安装完后,需要去Azure DevOps注册并生成一个access token。详细的流程可以看这里。生成toke的时候有两个地方需要注意下:token生成后就可以登录和发布了。如果有任何的修改,要注意修改package.json里面版本号才能发布成功。发布成功后,很快就能在VS Code的插件市场搜到了。总结本文介绍了VS Code插件开发的基本流程,实现了一个简单的插件。本文只涉及到VS Code插件系统的冰山一角,更多的高级功能以后接触到的时候再作介绍。如果想再作进一步的了解,可以从这里开始。 ...

October 11, 2018 · 2 min · jiezi

如何文明提交代码

程序员最烦的几件事:写测试,变量命名,还有填代码提交信息(commit message)。翻几个开源项目遍马上可以回味那作文凑字数的青春时光。其实 commit message 的作用远不止如此,经过简单的配置便可无痛成为代码提交的文明公民。Commit Message 的作用最起码的一点,项目的提交历史是其他人(包括未来的自己)了解项目的一个重要途径。好的提交历史可以方便其他人参与进来,也可以方便自己快速定位问题。此外,提交信息还可以用来触发 CI 构建,自动生成 CHANGELOG ,版本自动语义化提升…… 只需要一点点配置就可以干这么多,真是懒人必备。选择风格跟 Code Style 一样,Commit Message 也有各种风格。如果没什么特殊癖好推荐用基于 Angular ,后独立开来的 Conventional Commits 风格。它也基本是各个工具的默认配置,所以搭配起来不需要折腾。才不要又记什么规则虽然规则不多,但不一定能随时记住,特别是对新人,必须要有友好的方式提交。commitizen 是一个很好的选择,通过命令行回答几个问题即可填完信息,减轻了记忆负担。它是一个通用的工具,通过插件方式支持各种风格。我们选择 Conventional 需要安装cz-conventional-changelog 。npm install –save-dev commitizen cz-conventional-changelog然后配置 package.json 就可以通过 npm run commit 提交。{ “scripts”: { “commit”: “git-cz” }}另外 VSCode 用户也可以用 vscode-commitizen ,通过 ctrl+shift+p 或 command+shift+p 提交。Lint 一 Lint 万无一失没错,Commit Message 也有 Linter ,可对 Commit Message 进行检验,杜绝打字手残和浑水摸鱼。这里用 commitlint 配合 husky 实现自动检测。commitlint 也是通用的工具,需要同时安装风格配置。 husky 可以方便使用 git hooks ,在 commit 时触发 commitlint 。npm install –save-dev @commitlint/cli @commitlint/config-conventional husky项目根新建 commitlint.config.jsmodule.exports = { extends: [’@commitlint/config-conventional’]}配置 package.json{ “husky”: { “hooks”: { “commit-msg”: “commitlint -E HUSKY_GIT_PARAMS” } },}自动更新最后安装 standard-version 实现自动生成 CHANGELOG 和版本自动语义化提升。npm install –save-dev standard-version配置 package.json{ “scripts”: { “release”: “standard-version” }}第一次发布时可以用以下命令重置npm run release – –first-release以后直接 npm run release 即可。也可以手动指定版本:# npm run scriptnpm run release – –release-as minor# Ornpm run release – –release-as 1.1.0小红花贴起来在 README 中加入小徽章可方便其他人了解风格。完整配置安装npm install –save-dev commitizen cz-conventional-changelog @commitlint/cli @commitlint/config-conventional husky standard-version配置 package.json{ “scripts”: { “commit”: “git-cz”, “release”: “standard-version” }, “husky”: { “hooks”: { “commit-msg”: “commitlint -E HUSKY_GIT_PARAMS” } },}项目根新建 commitlint.config.jsmodule.exports = { extends: [’@commitlint/config-conventional’]}【完】 ...

September 25, 2018 · 1 min · jiezi

最漂亮的编程主题

题目写的有点大,但确实是我近期最喜欢的主题和字体(没有之一),来自一位前端妹子的推荐。因为它太好看了,所以一定要大用特用,不但要用在VSCode上,并且还要用在vi上,所有一切能用的地方。颜色主题——One Dark颜色主题的名称基干是One Dark,应该最早是从Atom发展出来的,所以叫Atom One Dark,后来产生了变种如One Dark Pro,One Dark Pro Vivid等等,我在VSCode里选择的是One Dark Pro。在VSCode里安装安装方法很简单,直接在插件标签里输入one dark搜索就可以安装了。安装好之后怎么启用呢?在左上角菜单的首选项里找到颜色主题,就可以启用了。在vi里安装这么漂亮的主题,不用来装在vi里就可惜了。我们得做三件事:第一,在目录下建一个子目录.vim,然后在.vim目录下再建一个子目录colors,然后在colors目录下建一个文件onedark.vim,把这个文件的内容拷进去。第二,在.vim目录下再建一个子目录autoload,然后在autoload下建一个文件onedark.vim,然后把这个文件的内容拷进去。第三,在目录下建一个文件.vimrc,把下面的内容拷进去:if (empty($TMUX)) if (has(“nvim”)) let $NVIM_TUI_ENABLE_TRUE_COLOR=1 endif if (has(“termguicolors”)) set termguicolors endifendifsyntax oncolorscheme onedarkfiletype indent onset smartindentset expandtabset shiftwidth=4set pastePS. 如果你的vi不等于vim,你还需要在~/.config/fish/config.fish里写上alias vi=vim,这样你的vi就等于vim了。Fira Code字体是不是已经足够漂亮了呢?也不尽然,当当当当,我们的大杀器出场!Fira Code,这可是在github上高达27,000多颗星的字体啊,字体星数仅次于著名的Font Awesome,我简直爱死他的这个&符号了。不同于颜色主题需要在两端安装,这个Fira Code字体只需要在Mac上安装就好了,因为Terminal只能使用客户端字体,所以不需要在服务器安装,只要把字体安装好之后,在iTerm里设置一下字体就好了。安装还是用我们最爱的brew来安装:brew tap caskroom/fontsbrew cask install font-fira-code在VSCode中设置字体在settings.json中添加以下两行:“editor.fontFamily”: “‘Fira Code’”,“editor.fontLigatures”: true,结合上面安装的颜色主题,现在的VSCode是不是看起来好漂亮了呢?还带连字符的,还有那个箭头函数,是不是好吓人?在iTerm中设置字体由于vi是在iTerm中运行的,所以我们只能通过为iTerm设置字体来间接影响到vi:现在,再通过ssh打开我们的vi编辑器,是不是也看到了漂亮的字体?虽然看上去远没有VSCode那么炫酷,但也足以在服务端爽心悦目了。祝你每天编程好心情!

September 24, 2018 · 1 min · jiezi