当前位置: 首页 > 后端技术 > Node.js

npmscripts使用指南

时间:2023-04-03 11:36:35 Node.js

1.什么是npmscript?npm允许使用package.json文件中的脚本字段定义脚本命令。{//..."scripts":{"build":"nodebuild.js"}}上面的代码是package.json文件的一个片段,里面的scripts字段是一个对象。它的每一个属性都对应一个脚本。例如build命令对应的脚本是nodebuild.js。在命令行中使用npmrun命令来执行这个脚本。$npmrunbuild#相当于像$nodebuild.js一样执行package.json中定义的脚本,称为npm脚本。它有很多优点。项目的相关脚本可以集中在一个地方。不同项目的脚本命令只要功能相同,就可以有相同的对外接口。用户不需要知道如何测试你的项目,只需运行npmruntest即可。您可以利用npm提供的许多辅助函数。查看当前项目的所有npmscript命令,可以使用不带任何参数的npmrun命令。$npmrun2.原理npmscript的原理很简单。每当执行npmrun时,都会自动创建一个新的shell,并在这个shell中执行指定的脚本命令。因此,只要是能被Shell(一般是Bash)运行的命令,都可以写在npm脚本中。比较特别的是,npmrun创建的新shell会将当前目录的node_modules/.bin子目录添加到PATH变量中,执行完成后,PATH变量会恢复到原来的状态。也就是说,当前目录的node_modules/.bin子目录下的所有脚本都可以直接用脚本名调用,不需要加路径。比如当前项目的依赖中有mocha,直接写mochatest即可。“测试”:“摩卡测试”而不是以下内容。"test":"./node_modules/.bin/mochatest"由于npm脚本的唯一要求是可以在shell中执行,所以不一定是Node脚本,可以写任何可执行文件在里面。npm脚本的退出代码,也遵守shell脚本规则。如果退出代码不为0,则npm认为脚本失败。3、通配符由于npmscripts是Shell脚本,所以可以使用Shell通配符。"lint":"jshint*.js""lint":"jshint**/*.js"上面代码中,*表示任意文件名,**表示任意一级子目录。如果要将通配符传递到原始命令以防止它们被shell转义,请转义星号。"test":"taptest/\*.js"4.传递参数给npm脚本传递参数,用--表示。"lint":"jshint**.js"将参数传递给上面的npmrunlint命令,必须这样写。$npmrunlint----reportercheckstyle>checkstyle.xml您还可以在package.json中打包另一个命令。"lint":"jshint**.js","lint:checkstyle":"npmrunlint----reportercheckstyle>checkstyle.xml"5.执行顺序如果npm脚本中需要执行多个任务,则需要指定它们执行的顺序。如果是并行执行(即同时并行执行),可以使用&符号。$npmrunscript1.js&npmrunscript2.js如果是二次执行(即只有上一个任务成功才会执行下一个任务),可以使用&&符号。$npmrunscript1.js&&npmrunscript2.js这两个符号是Bash的函数。此外,还可以使用node的任务管理模块:script-runner、npm-run-all、redrun。6.默认值一般情况下,npm脚本都是由用户提供的。但是,npm为这两个脚本提供了默认值。也就是说,这两个脚本可以不定义,直接使用。"start":"nodeserver.js","install":"node-gyprebuild"上面代码中,npmrunstart默认值为nodeserver.js,前提是根目录下存在脚本server.js项目目录;npmruninstall默认值为node-gyprebuild,前提是项目根目录下有binding.gyp文件。7.钩子npm脚本有两个钩子,pre和post。例如,构建脚本命令的挂钩是预构建和后构建。"prebuild":"echoIrunbeforethebuildscript","build":"cross-envNODE_ENV=productionwebpack","postbuild":"echoIrunafterthebuildscript"当用户执行npmrunbuild时,它会按照下面的顺序自动执行。npmrunprebuild&&npmrunbuild&&npmrunpostbuild因此,可以在这两个钩子中做一些准备工作和清理工作。下面是一个例子。"clean":"rimraf./dist&&mkdirdist","prebuild":"npmrunclean","build":"cross-envNODE_ENV=productionwebpack"npm默认提供以下钩子。prepublish,postpublishpreinstall,postinstallpreuninstall,postuninstallpreversion,postversionpretest,posttestprestop,poststopprestart,poststartprerestart,postrestart自定义脚本命令也可以添加前后挂钩。例如,脚本命令myscript也有premyscript和postmyscript钩子。但是双pre和post是无效的,比如prepretest和postposttest都是无效的。npm提供了一个npm_lifecycle_event变量,返回当前运行脚本的名称,如pretest、test、posttest等。因此,您可以使用该变量在同一个脚本文件中为不同的npmscripts命令编写代码。请看下面的例子。constTARGET=process.env.npm_lifecycle_event;if(TARGET==='test'){console.log(`运行测试任务!`);}if(TARGET==='pretest'){console.log(`运行预测试任务!`);}if(TARGET==='posttest'){console.log(`运行预测试任务!`);}请注意,prepublish挂钩不仅会在npmpublish命令之前运行,而且也在npminstall(没有任何参数)命令之前运行。这种行为很容易让用户感到困惑,因此npm4引入了一个新的hookprepare,它的行为等同于prepublish,从npm5开始,prepublish只会在npmpublish命令之前运行。8.简写形式四种常用的npm脚本都有简写形式。npmstart是npmrunstart的缩写npmstop是npmrunstop的缩写npmtest是npmruntest的缩写npmrestart是npmrunstop的缩写&&npmrunrestart&&npmrunstartnpmstart,npmstopandnpmrestart比较容易理解,而且npmrestart是一个复合命令,实际上执行了三个脚本命令:stop、restart、start。具体执行顺序如下。prerestartprestopstoppoststoprestartprestartpoststartpostrestart9。变量npmscripts有一个很强大的功能,就是可以使用npm的内部变量。首先,通过npm_package_前缀,npm脚本可以获取到package.json中的字段。比如下面是一个package.json。{"name":"foo","version":"1.2.5","scripts":{"view":"nodeview.js"}}然后,变量npm_package_name返回foo,变量npm_package_version返回1.2。5.//view.jsconsole.log(process.env.npm_package_name);//fooconsole.log(process.env.npm_package_version);//1.2.5在上面的代码中,我们通过环境变量process.env对象来获取包。json的字段值。如果是Bash脚本,可以使用$npm_package_name和$npm_package_version来获取这两个值。npm_package_前缀还支持嵌套的package.json字段。"repository":{"type":"git","url":"xxx"},scripts:{"view":"echo$npm_package_repository_type"}上面代码中可以获取到repository字段的type属性通过npm_package_repository_type。这是另一个例子。"scripts":{"install":"foo.js"}在上面的代码中,npm_package_scripts_install变量的值等于foo.js。那么npm脚本也可以通过npm_config_前缀获取npm配置变量,即npmconfiggetxxx命令返回的值。例如可以通过npm_config_tag获取当前模块的releasetag。"view":"echo$npm_config_tag",注意package.json中的config对象可以被环境变量覆盖。{"name":"foo","config":{"port":"8080"},"scripts":{"start":"nodeserver.js"}}在上面的代码中,npm_package_config_port变量返回8080.可以使用以下方法覆盖此值。$npmconfigsetfoo:port80最后,env命令可以列出所有的环境变量。"env":"env"10.常用脚本示例//删除目录"clean":"rimrafdist/*",//在本地构建HTTP服务"serve":"http-server-p9090dist/",//打开浏览器"open:dev":"openerhttp://localhost:9090",//实时刷新"livereload":"live-reload--port9091dist/",//构建HTML文件"build:html":"jadeindex.jade>dist/index.html",//只要css文件有变化,重新执行build"watch:css":"watch'npmrunbuild:css'assets/styles/",//只要HTML文件发生变化,重新执行构建"watch:html":"watch'npmrunbuild:html'assets/html",//部署到AmazonS3"deploy:prod":"s3-clisync./dist/s3://example-com/prod-site/",//构建favicon"build:favicon":"nodescripts/favicon.js",十一、参考链接如何使用npm作为构建工具,作者KeithCirkel很棒的npm脚本,作者RyanZimmerman