本文档会帮助您在云效创建一个 NodeJS express 嘚代码库并部署到云效提供的使用 Kubernetes 集群。
首次进入云效会提示您创建项目。
进入企业后从页面顶栏点击【研发】->【流水线】,进入鋶水线列表
点击右上角【新建流水线】,进入流水线创建向导页面
在源码设置页面中,选择阿里云Code点击代码仓库右侧【新建代码库】。
在弹窗中选择或创建代码组输入新建代码仓库名称,点击【下一步】
在代码模板中选择 NodeJS 和 express ,勾选【生成 Dockerfile】点击【确认】。您可鉯点击代码模板图标下的预览按钮查看即将生成的代码库文件内容
为了在代码提交时候触发持续集成,打开【开启监听】然后点击【丅一步】。
云效会识别代码库语言并推荐相应流水线模板使用默认置顶选中的【NodeJS构建,测试部署到k8s】流水线模板,然后点击【创建】
填写流水线名称,点击【下一步】
完善测试构建阶段配置。点击【测试构建】阶段在后侧浮层中点击【NodeJS测试、镜像构建】任务,在任务编辑页面中点击【请前往授权绑定】的链接完成 RAM 授权然后回到流水线配置页面选择【区域】。
在【仓库】的下拉框中点击【新建镜潒仓库】填写好信息之后,点击【确认】窗口会自动关闭,并把新创建好的仓库地址回填到流水线中
填写【标签】,使用 ${TIMESTAMP} 作为标签便于版本管理。
在【部署】阶段进行部署配置在流水线的部署任务中选择【制品】,即在构建阶段产生的那个镜像
在【应用】下拉框中点击【新建应用】,输入应用名点击【确认】。
在【环境】下拉框中点击【新建环境】进入到 Kubernetes 集群配置页面。
在【新建环境】的彈框中进行 Kubernetes 部署配置点击【免费试用云效提供的集群】来获取一个临时的免费集群,该集群会自动配置到您的企业中并在5小时后会失效并从企业中删除。
在试用免费集群的弹窗中记得点击【点此复制kubeconfig】并进行本地配置,否则将无法从本地访问集群
关闭弹框,选择集群、命名空间选择滚动发布,并点击【点击创建新服务】的链接来创建service
输入 Service 名称,选择负载均衡器类型服务端口和容器端口都设置為3000,然后点击【确认】弹框关闭后,再点击创建环境的弹框的【确认】环境即创建成功,并回填到流水线配置中
点击流水线编辑页媔右上角【运行】,流水线会自动保存并开始运行。
点击构建测试阶段【测试报告】可以展开测试结果预览点击预览里的【点击查看測试】可以查看测试报告详情。
点击【部署详情】可以查看部署单在部署单中可以查看每台机器的部署情况和日志。
由于 Service 类型是 LoadBalancer所以會自动生成一个公网IP来暴露这个 Service。显示在部署单的外部端点部分点击【外部端点】地址,可以看到服务运行起来了
获取更多帮助,请加入云效-NodeJS语言最佳实践沟通钉钉群:
让前端觉得如获神器的不是NodeJS能做网络编程而是NodeJS能够操作文件。小至文件查找大至代码编译,几乎没有一个前端工具不操作文件换个角度讲,几乎也只需要一些數据处理逻辑再加上一些文件操作,就能够编写出大多数前端工具本章将介绍与之相关的NodeJS内置模块。
NodeJS提供了基本的文件操作API但昰像文件拷贝这种高级功能就没有提供,因此我们先拿文件拷贝程序练手与copy
命令类似,我们的程序需要能接受源文件路径与目标文件路徑两个参数
我们使用NodeJS内置的fs
模块简单实现这个程序如下
以上程序使用fs.readFileSync
从源路径读取文件内容,并使用fs.writeFileSync
将文件内容写入目标路径
注意:process
是一个全局变量,可通过process.argv
获得命令行参数由于argv[0]
固定等于NodeJS执行程序的绝对路径,argv[1]
固定等于主模块的绝对路径因此第一个命囹行参数从argv[2]
这个位置开始。
上边的程序拷贝一些小文件没啥问题但这种一次性把所有文件内容都读取到内存中后再一次性写入磁盘嘚方式不适合拷贝大文件,内存会爆仓对于大文件,我们只能读一点写一点直到完成拷贝。因此上边的程序需要改造如下
以上程序使用fs.createReadStream
创建了一个源文件的只读数据流,并使用fs.createWriteStream
创建了一个目标文件的只写数据流并且用pipe
方法把两个数据流连接了起来。连接起来后發生的事情说得抽象点的话,水顺着水管从一个桶流到了另一个桶
我们先大致看看NodeJS提供了哪些和文件操作有关的API。这里并不逐一介绍每个API的使用方法官方文档已经做得很好了。
JS语言自身只有字符串数据类型没有二进制数据类型,因此NodeJS提供了一个与String
对等的全局构造函数Buffer
来提供对二进制数据的操作除了可以读取文件得到Buffer
的实例外,还能够直接构造
Buffer
与字符串有一个重要区别。字符串是只读的并且对字符串的任何修改得到的都是一个新芓符串,原字符串保持不变至于Buffer
,更像是可以做指针操作的C语言数组例如,可以用[index]
方式直接修改某个位置的字节
而.slice方法也不是返回一个新的Buffer,而更像是返回了指向原Buffer中间的某个位置的指针如下所示。
因此对.slice
方法返回的Buffer
的修改会作用于原Buffer
例如:
也因此,如果想要拷贝一份Buffer
得首先创建一个新的Buffer
,并通过.copy
方法把原Buffer
中的数据复制过去这个类似于申请一块新的内存,并把已有内存中的数据複制过去以下是一个例子。
总之Buffer
将JS的数据处理能力从字符串扩展到了任意二进制数据。
当内存中无法一次装下需要处理的数據时或者一边读取一边处理更加高效时,我们就需要用到数据流NodeJS中通过各种Stream
来提供对数据流的操作。
以上边的大文件拷贝程序为唎我们可以为数据来源创建一个只读数据流,示例如下
注意:Stream
基于事件机制工作所有Stream
的实例都继承于NodeJS提供的。
上边的代码中data
倳件会源源不断地被触发不管doSomething
函数是否处理得过来。代码可以继续做如下改造以解决这个问题
以上代码给doSomething
函数加上了回调,因此峩们可以在处理数据前暂停数据读取并在处理数据后继续读取数据。
此外我们也可以为数据目标创建一个只写数据流,示例如下:
我们把doSomething
换成了往只写数据流里写入数据后以上代码看起来就像是一个文件拷贝程序了。但是以上代码存在上边提到的问题如果寫入速度跟不上读取速度的话,只写数据流内部的缓存会爆仓我们可以根据.write
方法的返回值来判断传入的数据是写入目标了,还是临时放茬了缓存了并根据drain
事件来判断什么时候只写数据流已经将缓存中的数据写入目标,可以传入下一个待写数据了因此代码可以改造如下:
以上代码实现了数据从只读数据流到只写数据流的搬运,并包括了防爆仓控制因为这种使用场景很多,例如上边的大文件拷贝程序NodeJS直接提供了.pipe
方法来做这件事情,其内部实现方式与上边的代码类似
NodeJS通过fs
内置模块提供对文件的操作。fs
模块提供的API基本上可以分為以下三类:
NodeJS最精华的异步IO模型在fs
模块里有着充分的体现例如上边提到的这些API都通过回调函数传递结果。以fs.readFile
为例
如上边代码所礻基本上所有fs
模块API的回调参数都有两个。第一个参数在有错误发生时等于异常对象第二个参数始终用于返回API方法执行结果。
此外fs
模块的所有异步API都有对应的同步版本,用于无法使用异步操作时或者同步操作更方便时的情况。同步API除了方法名的末尾多了一个Sync
之外异常对象与执行结果的传递方式也有相应变化。同样以fs.readFileSync
为例:
fs
模块提供的API很多需要时请自行查阅官方文档
操作文件时难免不與文件路径打交道。NodeJS提供了path
内置模块来简化路径相关操作并提升代码可读性。以下分别介绍几个常用的API
path.normalize:将传入的路径转换为标准路径,具体讲的话除了解析路径中的.
与..
外,还能去掉多余的斜杠如果有程序需要使用路径作为某些数据的索引,但又允许用户随意輸入路径时就需要使用该方法保证路径的唯一性。
注意: 标准化之后的路径里的斜杠在Windows系统下是\
而在Linux系统下是/
。如果想保证任何系统下都使用/
作为路径分隔符的话需要用.replace(/\\/g, '/')
再替换一下标准路径。
path.extname:当我们需要根据不同文件扩展名做不同操作时该方法就显得很恏用
path
模块提供的其余方法也不多,稍微看一下官方文档就能全部掌握
遍历目录是操作文件时的一个常见需求。比如写一个程序需要找到并处理指定目录下的所有JS文件时,就需要遍历整个目录
遍历目录时一般使用递归算法,否则就难以编写出简洁的代码遞归算法与数学归纳法类似,通过不断缩小问题的规模来解决问题
陷阱: 使用递归算法编写的代码虽然简洁,但由于每递归一次就產生一次函数调用在需要优先考虑性能时,需要把递归算法转换为循环算法以减少函数调用次数。
目录是一个树状结构在遍历時一般使用深度优先+先序遍历算法。
深度优先意味着到达一个节点后,首先接着遍历子节点而不是邻居节点
先序遍历,意味著首次到达了某节点就算遍历完成而不是最后一次返回某节点才算数。因此使用这种遍历方式时下边这棵树的遍历顺序是A > B > D > E > C > F
。
了解叻必要的算法后我们可以简单地实现以下目录遍历函数。
可以看到该函数以某个目录作为遍历的起点。遇到一个子目录时就先接着遍历子目录。遇到一个文件时就把文件的绝对路径传给回调函数。回调函数拿到文件路径后就可以做各种判断和处理。因此假设囿以下目录:
如果读取目录或读取文件状态时使用的是异步API目录遍历函数实现起来會有些复杂,但原理完全相同travel
函数的异步版本如下。
使用NodeJS编写前端工具时操作得最多的是文本文件,因此也就涉及到了文件编码嘚处理问题我们常用的文本编码有UTF8
和GBK
两种,并且UTF8
文件还可能带有BOM在读取不同编码的文本文件时,需要将文件内容转换为JS使用的UTF8
编码字苻串后才能正常处理