我搜寻了很多驯服JAVAScript的工具,结果发现了它
3主流,2晦涩,1在上升
> Photo by Anna Elfimova on Unsplash
我已经使用静态类型语言进行编码多年,从Assembler开始,通过Visual Basic和C#迁移到C,但是当我迁移到JavaScript时,对软件的所有理解都发生了变化。
当我决定第一次尝试JavaScript时,我使用Sublime Text进行了编码,这全都与文本编辑,多光标,微插件有关,并且与Visual Studio相比,它的运行速度极快。 我不必等待IntelliSense或编译器,我键入,保存并准备好运行代码了,瞧!
脚本语言的速度非常快,但也发生了一点变化:每小时我的手指可能输入的错误数量激增。
我喜欢C#,也喜欢IDE,Intellisense,自动完成功能,并且诚实地使用了"面向编译器的开发"。 我只是通过阅读出现错误时编译器和Intellisense指出的内容来学习的。
正如您现在可能想到的那样,我很快就从静态类型化和编译型语言中获得了JavaScript的优势:语法很怪异,没有任何东西可以缓存我的错误,当时的范围很混乱,库缺乏自动发现能力(没有Intellisense), 承诺不存在,并且框架没有像今天那样被采用。
在我最初使用JavaScript多年后,虽然主要使用C#,但是我找到了一份可以全职使用AngularJS的工作。 我感到AngularJS使项目更加结构化,并为JavaScript带来了编程中常见的"良好实践"。
在2年的时间里,该项目使我吸取了许多关于JavaScript的经验,但是我仍然觉得没有什么能像我预期的那样顺利进行。
我觉得JavaScript难以驯服:运行时异常仍然是一种规范,我的大多数代码在大多数时间都重复了,可读性仍然是一个问题,表达意图不仅是挑战,而且是奢侈,我过去编程中的知识很少 经验似乎在JavaScript中效果很好,而最糟糕的部分是:我仍然觉得自己是一个糟糕的JavaScript程序员。
在尝试将我的面向对象程序设计知识以及其他从C#到JavaScript的优秀知识应用于我时,我一直关注着一切如何转变,这花了我一段时间,但直到最后,我决定改变思路。
我进入了一个新的状态,我的前提是:将面向对象的编程原理和设计模式应用于JavaScript是浪费时间,JavaScript并非完全为此目的而设计,我将尽我所能来做事情 忘了OOP。
我开始积累自己的一套良好实践,一段时间后,我开始觉得自己对JavaScript有所了解。 最后,我开始减少代码编写,减少错误,做出有用的抽象,一切开始看起来不错,与此同时,我遇到了有关……函数式编程的文字。
吞噬了关于函数式编程的所有知识之后,我设法将我的每一个良好的JavaScript做法都映射到一个函数式编程概念,但是函数式编程不仅囊括了我的全部经验,而且这超出了我最疯狂的梦想。
我开始应用并展示每个概念的每一个提交,菜鸟的错误,我的团队完全不了解我们已经使用OOP近两年了,使用AngularJS,在项目结束时转移范例肯定会死, 我更正并继续使用OOP。 幸运的是,该项目结束了,我可以进入一个新的职位,这个新职位使团队拥有更多的函数式编程经验。
在工作之间,我练习了函数式编程,并试图发现如何使用每个可用的库。 我终于感觉到对JavaScript的控制了,要获得对JavaScript的控制,我不得不放弃它。
在学习了函数式编程的一些基础知识之后,我决定尝试使用比AngularJS更适合FP的其他框架(此时Angular 2已经存在了)。
我开始使用现代框架,遇到了React和Elm,我爱Elm! 那TypeScript呢? 尽管我完全放弃了windows,但我不敢相信我很高兴再次使用Microsoft工具。 这是我所需要的全部时间。
回想起来,以自己的方式尝试之后,我绝对可以确定,我对JavaScript的不良表现的很大一部分是我自己对工具的缺乏了解,而这些工具与我对软件的自然思考方式更为相关,因此我感觉自己像 在使用公司的技术堆栈时从水中捞出。
在给我当前的工具链之前,有一条建议:没有限制地自己练习要掌握的语言,然后再找到与您的喜好相匹配的工作,否则,您可能会感到痛苦,因为 您将为自己使用错误的工具,因此永远无法发挥自己的潜力。
您肯定知道其中一些工具,但是为了完整起见,我将尝试对所有这些工具进行简要说明。
> Banner from TypeScript home page
在他们自己的主页上:
TypeScript是JavaScript的类型化超集,可编译为纯JavaScript。
是什么让我在每个项目中都使用TypeScript?
在编译时发现错误是一件好事,这需要几秒钟吗? 值得。 愚蠢的错误,莫名其妙的运行时错误,显示得太迟的错误的无奈使我对这个职业的热爱减少了,但是TypeScript再次带来了欢乐。
表现力和顺从性,意图和统一性,设计和力量,类型需要时间来掌握,但是孩子们,他们值得。 每一个 单。 时间。 我非常想念类型。 TypeScript和函数型都兼容面向对象的类型。
当您有类型时,很多对话消失了,您为试图理解和使用代码的人们节省了很多时间,无需阅读手册就可以发现整个库的使用,并且可以确保一切都会 由于类型约束而应该使用。
TypeScript中的类型还有很长的路要走,但是今天的类型系统已经为前端带来了如此强大的功能。 没有类型系统感觉就像试图步行超越赛车。 它给人以JavaScript错过的工程感,我使用类型来设计和强制正确使用接口,并且每天花我安全的时间编写类型(好吧,这主要是我的看法)。
有了TypeScript,我每小时的错误以及因此而感到沮丧的机会大大减少了,仅此部分就值得了。
该版本的TypeScript也越来越好,它迅速采用了新的ECMAScript功能。
因此,是的,我放弃了使用纯原始JavaScript编写代码的方式,这对我的理智有危害。 TypeScript具有JavaScript的所有优点以及许多使JavaScript实际可行的机制。
> Banner from @code Twitter
这不是IDE,而是文本编辑器,是其主页上最好的文本前端编辑器:
代码编辑。 重新定义。 自由。 建立在开源上。 无处不在。
为什么选择VSCode?
这句话是正确的,我已经在需要使用的每个操作系统上可靠地使用了VSCode,它速度很快,并且在所有地方都有很多优点,无需担心平台支持。
Yeeeesss。 它可以使用JavaScript创造奇迹,但是使用TypeScript,它就像上帝一样,快速,可靠,并在编译前发现错误! 我认为这是VSCode的最佳功能之一,就像有另一双眼睛一样。
当时,每个插件的Sublime都很慢,并且缺少IntelliSense,VSCode很快,并且在发布之前一直保持增长,老实说,这么好的软件是免费的。
一切都按预期进行,具有我能想到的所有功能,而那些不应该成为核心的人是扩展,说实话掌握它是值得的。
总之,一个描述我的VSCode代码经验的短语:我没有任何抱怨。
> Banner from Xpgraph blog post
从他们的主页:
一个用于构建用户界面的JavaScript库
如前所述,我从AngularJS开始,这是前端包含完整电池的框架,但是迁移到React对我来说是不可避免的,这就是为什么:
是的,不是框架,那是我最喜欢的东西之一,我通常编写小型程序,不需要大量的框架,只需要一点帮助我就可以构建小型UI。
最好的卖点是,React接受了函数式编程,与我对JavaScript的新认识保持一致。
React做出了简洁的努力,我对此表示赞赏。 React用最少的语法表达了复杂的概念,诸如useState和High Order Components之类的例子是使用正确的抽象要比使用一堆可能最终使用错误的工具要好得多的例子。
我不使用Svelte或Vue的原因是我不喜欢模板,而我喜欢类型。 在模板文件中,您没有TypeScript,也没有JavaScript,但有模板脚本式的临时标记,可以帮助您处理各种类型的未键入内容。
我真的很喜欢React的本质。 意思是我使用css而不是CSS,而不是html + JS,而在TypeScript中使用TSX,所有CSS,HTML和JS,并且我喜欢它,所有内容都具有IntelliSense,编译错误,类型,没有上下文切换 。
如我所见,小型组件是CSS + HTML + JS的混合物,将它们全部合并到TypeScript中对我有利。
更好的一面呢? 它的性能卓越,并且在每个新版本中都在不断改进,将更多的JSS转换为静态CSS,对更多的TSX进行了优化等,因此您可以进行惯用的编程,并且随着时间的推移,编译器可以改善输出。
在我所服务的公司中,我们使用小型程序而不是低级的东西来编写高级概念,我相信公司大部分时间都不会付钱给程序员来优化任何东西,他们想要快速可用且可靠的软件。
> Photo by Paxson Woelber on Unsplash
现在让我们变得奇怪,我不希望您从他们的主页了解这一点:
JavaScript程序员的实用功能库。
我可以花几个小时写有关Ramda的文章,我将尝试总结为什么在100%的项目中使用Ramda的最畅销点:
如此多的人曾经或曾经将Lodash用作实用腰带,但是Lodash对我来说是一个大问题,所有争论都是落后的。 如果考虑可组合软件,您很快就会意识到,如果要组合两个Lodash函数,则需要一个中间的"辅助"变量。 我宁愿不这样。
另一方面,Ramda在设计时考虑了成分,在咖喱和烟斗的帮助下,精心打造了均匀的界面。
上面我一直抱怨重复代码,大多数代码都是小型实用程序函数,如果我启动另一个项目后必须设法将所有文件夹都包含在其中,那么我不得不再次编写它们,因此我一直在寻找一个重复的代码。 好的实用程序库。
现在,我几乎没有考虑过抽象函数以使其具有更高的可重用性,因为所有通用的可重用函数都在Ramda中,并且具有非常强大的功能优先接口。
公用事业带应包含纯粹的功能,这意味着这些功能必须:无副作用,并将数据视为不可变的。 这些东西与实用程序库不一致,哎呀,甚至在JavaScript内置Array函数中也不一致,不相信我吗? 看这个:
您是否可以估计发现naiveArray行为所需的时间,如果您依靠它在应用sort之后保持不变的话? 好的,抱歉,我不想引起您的癫痫发作。
我在代码的每一段中都非常珍视这些东西,因此Ramda将其内置在每个函数中的事实真是令人惊讶。
转换器的实用描述:
转换器消除了组合多个阵列功能的性能损失。
我认为图像胜于文字,转换器难以理解:
> https://jsperf.com/native-vs-ramad-vs-lodash-vs-immutable
Ramda充满了换能器功能,这意味着性能非常好,您可以堆叠多个filter,map和21个其他功能,它将仅迭代数组并应用一次功能,而不是N次。
Ramda很棒,但是所有的好东西都是有代价的……如果您正在考虑使用TypeScript。
Ramda类型的类型,类型推论和类型解析的复杂性贯穿整个屋顶。 最重要的是,主要贡献者根本对TypeScript不感兴趣。
他们似乎是一群了不起的开发人员,他们在不需要TypeScript的情况下就驯服了JavaScript,并且对将此惊人的库移植到TypeScript的兴趣为零。
那么它如何与TypeScript一起使用呢? 值得庆幸的是,其他开发人员承担了为库提供类型的任务,并且他们精通TypeScript类型系统(我很理解这些签名),但是似乎在每个发行版中都可以更好地工作。
要提供准确而可推断的TypeScript类型,这是一个艰巨的挑战,因为它们对JavaScript高级类型功能的要求如此之高,但是它们却无法实现,现在大多数功能可以在TypeScript中无缝使用,但是 最高级的需要一些帮助来确定类型的结果。
尽管如此,Ramda仍然是我乐于使用的最精良的实用程序库之一,在我驯服JavaScript的过程中,它让我非常感动。 谢谢,拉姆达
只要我们留在JavaScript领域,Ramda就是一个了不起的解决方案,但是当我完全采用TypeScript时,它变得……笨拙地使用了,类型推断并不是那么好,所以我搜索了其他考虑到TypeScript的解决方案,或者 更好的是用TypeScript编写的。
幸运的是,我从他们的主页中找到了图书馆奇迹fp-ts:
TypeScript中的类型化函数式编程
fp-ts为开发人员提供了流行的模式以及来自TypeScript中类型化功能语言的可靠抽象。
老实说,fp-ts是一个杰作,它为TypeScript带来了很多好处,并且以一种不引人注目的方式,它的类型也是完全惯用的。
为什么我在100%的项目中使用fp-ts?
由于类型分析的从左到右的性质,我故意避免谈论Ramda的管道,因为fp-ts版本对于TypeScript和IntelliSense更是惯用的。
这是没有管道的代码:
在main中,我需要使用中介变量来分配中介结果,在main2中,要从右到左读取执行顺序是很尴尬的。
这是Ramda管道的代码:
使用管道,我们不需要中间变量,不需要所有数据流,但是,在大多数情况下,TypeScript在使用Ramda管道时会产生错误,因为输入值位于最后,因此无法推断出第一个函数的输入是什么, 依此类推,因为TypeScript从左到右进行推断,并且Ramda的管道可以正常工作,所以推断应该同时从左到右和从右至左进行,因此Ramda的管道类似于类型推断系统中的一个共同特征。 功能语言,例如Haskell,OCalm和F#,但不是TypeScript中的语言,尽管JavaScript根本没有问题。
现在看一下fp-ts版本的管道:
区别在于fp-ts将管道的输入放在首位,从而使TypeScript推论变得愉快。 在JavaScript领域,Ramdas的方法是100%有效的惯用代码,但是TypeScript缺少从右到左的推断使其"无效"或通常很难使用,因此我通常倾向于使用fp-ts版本的管道,而不是 拉姆达的。
我很自豪地宣布,我再也很少遇到未定义和null错误,因为最后,我有了Option的惯用且完全受支持的实现。
Option基本上是表示可能存在或不存在值的数据的包装器。
另一方面,允许轻松地分叉代码,事情可以向左或向右移动。
让我举一个例子:
哦,这真是一个不错的代码。 这么小的代码没有错。
除了,一切。 但是我们并不是那么愚蠢,我们可以改善,抛出一些if并尝试…捕获表达式,然后就一切就绪了。
现在可以了。 在该示例中,我向您展示JavaScript和TypeScript都无法指导您检查这种情况,也许带有–strictNullChecks的TypeScript会有所帮助,但是函数返回类型不能表示错误,但这不是全部,分支都被弄乱了 向上,我返回了早期错误和晚期错误,并且在中间成功了吗? 现在来看这个:
如您在本例中看到的,Option和Either都迫使我们以显式方式处理分支,没有"遗漏分支",我们可以用Either的左分支表示Errors,而我们只在最后返回。
如果预计会出现"错误",为什么要使用try … catch? 这是预期的行为,try … catch习惯于"出乎意料的错误",但是对于预期的逻辑分支,无论是完美的抽象,事情都可以向左(错误)或向右(成功)。
这些数据结构可帮助我们构造更高级的数据流模式(如Rail Way编程),如果您不知道我在说什么,请查看此页面:https:
//fsharpforfunandprofit.com/rop/。
最后但并非最不重要的一点是,我将提到TaskEither,任务基本上是Promise的包装器,但具有更为单调的界面,这个奇怪的词是什么意思? 这意味着它更适合标准接口,而不是像Promise这样的古怪实例方法,可以使用完善的map,chain,ap,fold等。
好的,如果您还不熟悉函数式编程,那么在代码库中当然不能很好地建立ap和fold,但是一旦找到,您会注意到函数的统一性,无论封装数据如何,都意味着相同 结构,无论您要映射的是数组,对象,选项,Either还是TaskEither,映射都意味着相同,它对每个数据结构都有详细说明,但是map在所有情况下都是map, 统一,无需学习(在函数式编程中)经过充分研究的转换的另一种重新实现。
这些只是使您的代码真正表达意图,更简洁并最终更可靠的功能数据结构中的3个。
让我介绍XState作为应该已经取代Redux的库。 从他们的主页:
现代网络的JavaScript和TypeScript有限状态机和状态图。
很长时间以来,我的Redux商店都缺少一些东西,我试图制作一些小的中间件来帮助我驯服Redux,但是感觉……不完整。 直到我中奖并找到XState。
为什么我在100%的React项目中使用XState?
我的问题是Redux只是问题的一半,而没有注意到我在每个React组件中都制作了小型状态机,并在扩展状态(或无限状态)中使用Redux,一旦我发现XState,我所有的设计问题都遇到了一个有价值的竞争者。
应该显示一个按钮吗? 已启用? 显示文字A或B? 所有这些"域"规范都不超过几个有限的事先指定的状态; 如果您明确地编写了这样的状态,则读取和升级组件将成为一件乐事。
使用AngularJS和模板,我的状态由一堆无法读取的交织在一起的变量组成,使用React和Redux,所有数据都放在一个地方,但是状态没有以任何方式表示,是对数据的解释,但是 使用XState我的状态实际上是明确的。 看看这台机器:
如果您是像我这样的图形人物,则可以尝试使用XState可视化工具:
我需要向您解释这台机器的行为吗? 不,我不知道 在那里,肉眼看不到,没有奇怪的曼波大猫。
我们推出了三本新出版物! 通过关注它们来表达对我们新出版物的热爱:普通英语的AI,普通英语的UX,普通英语的Python –谢谢并继续学习!
我们也一直对帮助推广高质量的内容感兴趣。 如果您有要提交给我们任何出版物的文章,请使用您的中等用户名给我们发送电子邮件至submittings@plainenglish.io,我们将使您成为作家。 另外,请告诉我们您要添加到哪个出版物。
(本文翻译自Edgar Rodríguez的文章《The 6 tools that changed JavaScript for me》,参考:
https://medium.com/javascript-in-plain-english/the-6tools-that-changed-javascript-for-me-3ee1faf40585)