当前位置: 首页 > 科技观察

npmscript的操作大家可能没见过

时间:2023-03-12 18:56:14 科技观察

作为前端开发,npmscript基本天天用,但是很多同学可能只停留在运行层面,并没有深入了解。今天我将介绍一些不同的npm脚本操作。希望对大家有所帮助。什么是npm脚本?其实我们每天都在使用npmscript,也就是我们package.json文件的scripts属性中的语句。比如我们常用的npmrundev、npmrunserve、npmstart等都是npm脚本。运行单个命令首先我们在package.json文件中新建一个测试脚本,内容是输出hellorandy:然后我们运行npmruntest,控制台可以看到:至此我们的第一个npm脚本已经运行成功。运行多个命令在实际开发过程中,可能会同时启动多个命令。比如我们前后端一起启动。运行多条命令会涉及到串行和并行的问题,下面笔者将分别进行说明。串行的实现方法也比较简单,用&&符号将多个npm脚本依次串起来即可。"scripts":{"frotend":"echo\"前端服务启动\"","server":"echo\"后端服务启动\"","all1":"npmrunfrotend&&npmrunserver",},运行结果如下:需要注意的是,在串行执行过程中,如果前面的命令失败,后面的所有命令都会被终止。并行有时为了提高效率,我们希望多个命令并行执行,只需使用&符号将多个npm脚本依次串起来即可。"scripts":{"frotend":"echo\"前端服务启动\"","server":"echo\"后端服务启动\"","all2":"npmrunfrotend&npmrunserver",},运行结果如下:其实除了使用&&和&,我们还有更优雅的方式,可以使用npm-run-all或者并发。更好的方法1npm-run-all首先我们安装:npminpm-run-all-D然后添加我们的npm-run-all命令:"scripts":{"frotend":"echo\"front-endservice它是started\"","server":"echo\"后端服务启动\"","all3":"npm-run-allfrotendserver",},运行结果如下:以上是串行执行,当然我们也可以并行执行,只要加上--parallel:"scripts":{"frotend":"echo\"前端服务启动\"","server":"echo\"即可后端服务启动\"","all4":"npm-run-all--parallelfrotendserver",},运行结果如下:npm-run-all有很多用法,这里只是介绍一下有兴趣的同学可以查看文档自行学习。更好的方式2concurrently首先我们安装:npmiconcurrently-D然后添加我们的concurrent命令:"scripts":{"frotend":"echo\"前端服务启动\"","server":"echo\"后台服务启动\"","all5":"concurrently\"npmrunfrotend\"\"npmrunserver\""},运行结果如下:concurrently有很多用法,这里只是一个介绍,谢谢有兴趣的同学可以查看文档自行学习。我们都知道给npm脚本传递参数eslint是前端开发代码检测的重要工具。我们经常会配置两个脚本,一个用于错误检测,一个用于简单的错误修复。"lint":"eslintjs/*.js","lint:fix":"eslintjs/*.js--fix"作者的js文件夹下有这样一个js文件,是空间问题。我们运行npmrunlint,可以看到如下错误:空格等简单的问题,eslint可以自动修复,运行npmrunlint:fix可以看到,空间问题自动修复了:其实经过学习npm脚本和传参,一条命令搞定。npm脚本使用--传递参数。我们只需要在package.json中配置一条命令:"lint":"eslintjs/*.js",当我们需要修复它的时候,我们通过传递参数来处理。可以看到空间问题也自动修复了。其实就是运行eslintjs/*.js--fix:参数的方式可以大大减少我们脚本的数量,让脚本更加灵活,尤其是一些需要传递各种参数的脚本。npmscript日志当运行npmscript出现问题时,你需要能够调试它。我们可以通过查看日志来分析问题。日志级别可以通过参数控制。默认的日志输出级别是在不添加任何日志控制参数的情况下得到的输出。它可能是你最常用的,你可以看到执行的命令和命令执行的结果。比如笔者上面的例子:显示更少的日志如果需要显示更少的日志,我们只需要在运行脚本的时候通过--loglevelsilent或者--silent或者更简单的-s来控制即可。比如上面笔者的例子:只会输出结果,很简单。显示更多的日志如果需要显示更多的日志,我们只需要在运行脚本的时候通过--loglevelverbose或者--verbose或者更简单的-d来控制即可。比如上面作者的例子:可以看到,输出了很多信息。npmscripthook为了方便开发者自定义,npmscript的设计者为命令的执行加入了类似生命周期的机制,具体来说就是pre和posthook脚本。当某些操作需要在之前进行检查并且某些操作需要清理时,此功能非常有用。比如运行npmruntest时,分为三个阶段:检查scripts对象中是否有pretest命令,如果有则先执行该命令;检查是否有测试命令,有则运行测试命令,没有则报错;查看是否有posttest命令,如果有则执行posttest命令;还是上面代码检查的例子,我们创建三个命令:"lint":"eslintjs/*.js","prelint":"eslintjs/*.js--fix","postlint":"echo\"eslint执行完成\""我们在每次lint前自动进行代码修复,执行完lint后输出eslint执行完成。我们来看看效果:我们只执行了npmrunlint,它却执行了三个命令:npmrunprelint、npmrunlint、npmrunpostlint。npmscript变量npmscript可以使用预定义变量和自定义变量。预定义变量预定义变量其实就是解析整个package.json文件,获取各个字段和值。您可以通过运行npmrunenv获得完整的变量列表。这个列表很长。这里我使用npmrunenv|grepnpm_package|sort得到一些排序好的预定义变量:作者的文件如下:变量的使用如下shell中的语法,在npm脚本中只要在你要引用的变量前面加上$符号即可。"var1":"echo$npm_package_author_name"执行npmrunvar1,运行结果如下:自定义变量除了预定义的变量,我们还可以在package.json中添加自定义变量,在npm脚本中使用这些变量。需要在package.json的config字段中配置自定义变量。{"config":{"say":"hellorandy"},}使用和预定义变量一样,只是在变量前面加上$符号。"var2":"echo$npm_package_config_say"执行npmrunvar2,运行结果如下:注意$npm_package_name在Linux和Mac下可以直接使用,但在Windows下必须使用%npm_package_name%。npm脚本跨平台兼容性如前所述,Linux、Mac和Windows引用变量的方式不同。可能有同学处理过npmscripts的跨平台兼容问题,比如粗略的写了两个平台各一个的npmscript,如下:{"name":"test","scripts":{"bash-script":"echoHello$npm_package_name","win-script":"echoHello%npm_package_name%"}}那么有没有更好的方法来实现这个呢?cross-varcross-var用于解决跨平台变量的使用问题。首先我们安装cross-var:npmicross-var-D然后修改我们的命令:"var3":"cross-varecho%npm_package_config_say%","var4":"cross-varecho$npm_package_config_say"让我们看看运行结果:作者是mac,可以看到用windows引用变量也能正常运行。这就是cross-var的魅力所在。可能有的写手会说变量用的不多,但是环境变量用的多。有没有办法跨平台使用环境变量?cross-envcross-env用于解决跨平台环境变量问题。首先我们安装cross-env:npmicross-env-D然后我们在设置环境变量的时候加上cross-env。"env1":"cross-envNODE_ENV=staging"这个环境变量也可以跨平台使用。npmscriptcommandlist对于一个新项目,如果我们想知道它有哪些脚本,我们通常会找到package.json文件,然后查看它的scripts字段。事实上,还有更简单的方法。直接在项目目录下执行npmrun,可以列出scripts对象中定义的所有命令。是不是很酷。运行npmrunxxx时发生了什么当npmrunxxx时,首先到项目的package.json文件中找到scripts中对应的xxx,然后执行xxx命令,例如启动vue项目时npmrunserve,实际上面就是执行vue-cli-service服务命令。为什么不直接执行vue-cli-serviceserve而是执行npmrunserve呢?因为直接执行vue-cli-serviceserve,会报错,因为操作系统中没有命令vue-cli-service。既然操作系统中不存在vue-cli-service这个命令,为什么执行npmrunserve就相当于执行了vue-cli-serviceserve呢?为什么这样就成功了,而且不报命令不存在呢?那错误呢?这就需要了解npmrunxxx是如何搜索命令的:npm运行npmrunxxx时,会先在当前目录下的node_modules/.bin中搜索要执行的程序,如果找到就运行。如果没有找到,会从全局node_modules/.bin中查找,npmi-gxxx会安装到全局目录下。如果还是找不到全局目录,再从路径环境变量中寻找其他同名的可执行程序。如果再次找不到,就会报错。因为我们在安装依赖的时候,是通过npmixxx来执行的,比如npmi@vue/cli-service,npm安装这个依赖的时候,会在node_modules/.bin/目录下创建vue-cli-service命名为几个可执行文件。所以在使用npmrunserve执行vue-cli-serviceserve时,npm会在./node_modules/.bin中找到vue-cli-service文件,并作为脚本执行,相当于执行./node_modules/.bin/vue-cli-服务服务。有时候我们可以全局安装,比如npmi-g@vue/cli-service,这样他会在全局的node_modules/.bin中创建一个可执行程序,这样我们就可以在电脑的任意目录下运行相应的命令。好了,谢谢大家的耐心观看,今天的npmscript就到这里了。