本文转载自微信公众号《全栈成长之路》,作者单月星。转载本文请联系全栈成长之路公众号。折腾了两天,终于把这篇文章写完了。有兴趣的可以加我的微信好友山月94进行交流。这篇文章也可以在山月的博客上找到。文字众所周知。可以使用package.json中的脚本字段来组织Javasript项目的脚本工具。简而言之,这是npm脚本。最典型和常用的约定是npmstart,它用于启动项目:{"scripts":{"start":"next"}}有很多快速约定,如下所示npminstallnpmtestnpmpublish。..亲儿子脚本同意快,自然和其他第三方脚本不一样。如果需要执行,可以直接使用npm前缀,比如npmstart。其他脚本呢?然后你需要npmrun前缀。但是yarn并没有那么讲究,一视同仁。$npmrun$npmrun-scriptdev#为了简单方便,等价于$npmrundev#yarn$yarndev上面的大家都知道,下面的讲的可能不是很熟悉:npmrundev和npm的区别start是针对一个“纯就生成静态页面打包的前端项目”而言的,它们之间没有太大的区别:生产环境的部署只依赖于build生成的资源,并不依赖于npm脚本。请参阅如何部署前端项目[1]。对于使用create-react-app生成的项目,其npm脚本只有npmstart{"start":"react-scriptsstart","build":"react-scriptsbuild","test":"react-scriptstest","eject":"react-scriptseject"}使用的是vuepress生成的工程,其npm脚本只有npmrundev{"dev":"vuepressdev","build":"vuepressbuild"}在一个“面向服务器”的工程中它们,例如next、nuxt和nest。dev和start之间的区别往往很明显。一个用于生产环境,另一个用于开发环境。生产环境启动:在生产环境启动项目,在nest项目中配置{"start":"neststart","dev":"neststart--watch"}运行:ScriptHooks->Howtorun新项目快新手进入一个新项目,如何跑起来是每个人都会遇到的问题:每个人都是从新手开始。有可能你会脱口而出:npmrundev/npmstart,但在实际工作中,处处都是陷阱,而且往往没有那么简单。查看是否有CI/CD,如果有CI/CD部署的脚本,运行命令查看是否有dockerfile,如果有运行dockerfile的命令,查看npmscripts中是否有dev/start,试试npmrundev/npmstart看看有没有文档,如果按照文档。为什么把文件放在最后?道理你懂的,但即使你很谨慎,也可能会遇到下面这些浪费一个下午抱怨的坑:前端在本地环境启动时可能需要依赖前端构建时生成的文件”,所以有时候需要“先正常部署,再根据本地环境尝试启动(即需要先npmrunbuild,再npmrundev/npmstart)”。(例如,一旦我们的项目npmrundev需要webpackDllPlugin构建的东西)不要忘记设置环境变量或配置文件。所以设置一个小脚本可以防止后人踩坑,更重要的是可以避免后人骂你{"scripts":{"start":"npmrundev","config":"nodeassets&&nodeconfig","build":"webpack",//设置一个devhook,在npmrundev之前执行,这里可能不需要"predev":"npmrunbuild","dev":"webpack-dev-server--inline--progress"}}Hooks在npmscript中,每个命令都有Pre/Posthooks,分别在命令执行前后执行npmrun。在工作过程中,这些hooks和内置命令为项目提供了简单的操作方法,也提供了更安全的项目操作过程打包后,打包前设置husky(v5.0),清理目标文件,打包前,building并运行,准备资源文件-dev-server--inline--progress"}}构建打包,基本上所有项目都包含这个命令,默认为npmrUnbuild在CI或前端托管平台Vercel/Netlify中,部署前端项目最重要的一步就是打包。但是,有些项目可能不需要打包。这时候可以使用if-present参数,意思是如果脚本存在就执行,否则跳过$npmrun--if-presentbuild{"scripts":{"build":"nextbuild"}}测试:脚本后缀要完成一个很复杂的事情,可以使用前缀来对npm脚本进行分组和组织,比如测试。npmruntest:使用mocha[2]进行单元测试npmruntest:coverage:使用nyc[3]查看单元测试覆盖率npmruntest:e2e:使用cypress[4]进行UI自动化测试{"test":"mocha","test:coverage":"nycnpmtest","test:e2e":"npmruncy:run--","cy:run":"cypressrun--config-filecypress/config.json","cy:open":"cypressopen--config-filecypress/config.json"}测试方面,mocha和nyc的结合可以很好的进行单元测试,并提供覆盖率报告。对于前端端到端测试,cypress和puppeteer无疑是最流行的框架。那么如何更好地测试和记录Vue/React组件呢?组件测试:storybook[5]可以更好的对React/Vue组件进行调试、测试和形成帮助文档。在开发基础组件库时,可以配置npmrunstorybook来更好的测试$npmrunstorybook{"scripts":{"storybook":"start-storybook-p9001-c.storybook","storybook:build":"build-storybook-c.storybook-o.out","prepublishOnly":"npmrunbuild"}}故事书格式化的使用方法:PrettierPrettier[6]是一个支持多种编程语言的程序,比如html,css,js,graphql,markdown,etc.和一个可以和编辑器(vscode)深度集成的代码格式化工具。支持多种编程语言。在npmscript中配置代码格式如下:Formatjs,css,json,markdown{"scripts":{//配置文件:.prettierrc//格式:--write//file:*.js"prettier":"prettier--config.prettierrc--write{.,components,lib,pages}/*.{js,css,json,md}",}}.prettierrc是prettier的配置文件,一般都是比较简单的配置,数量不多PrettierOptions[7]可用于配置。{"singleQuote":true,"printWidth":100,"semi":false,"arrowParens":"avoid"}Lint:代码格式化和质量检查。Prettier和ESLint/StyleLint/TSLint有什么区别?Prettier只是针对Code的格式化,比如空格,是否加分号等。除了格式化代码,ESLint还会对代码进行“质量检查”,比如no-unused-vars、no-implicit-globals等规则。JS和TS的质量检测仍然依赖于eslint[8]。{"scripts":{"lint":"eslint.","lint:fix":"eslint.--fix"}}除了eslint,还可以格式化markdown和gitcommitmarkdownlint[9]commitlint[10]Git:你好,代码不合格。禁止在这里提交您不合格的代码。为了不让你被别人投诉,这里不让你投稿。这就是GitHooks派上用场的地方。GitHooks中的precommithook会在提交代码之前执行脚本,如果脚本失败(ExitCode不为0),则禁止提交。husky[11]和lint-staged[12]是GitHooks的最佳搭配。{"scripts":{"lint":"eslint.","prettier":"prettier--config.prettierrc--write{.,components,lib,pages}/*.{js,css,json,md}",},"husky":{"hooks":{"pre-commit":"lint-staged"}},"lint-staged":{"*.js":["npmrunlint"],"*.{js,css,json,md}":["npmrunprettier"]}}过时:您的依赖项已过时。当图书馆过时时会发生什么?找不到文档,无处可去。错误通常是由过时的库引起的。难以修复是一种安全风险没有人喜欢过时的库。使用npmoutdated在package.json$npmoutdatedPackageCurrentWantedLatestLocationDependedby@vuepress/plugin-google-analytics1.7.11.8.21.8.2node_modules/@vuepress/plugin-google-analyticsblogaxios0.21.00.21.10.21js.1ax.logbmodules/中查找依赖的过期库node9modules.10.41.10.4node_modules/dayjsbloggraphql15.4.015.5.015.5.0node_modules/graphqlblogkoa2.13.02.13.12.13.1node_modules/koablognpm-check-updates10.2.210.3.111.3.0node_modules/npm-1check-module18.5.5.0node_modules/npm-1check-module1.8.13.1node_modules/koablognpm-check-updates10.2.210.3.111.3.0node_modules/npm-1check-1vue1.node-updates18.5.0node_modules/npm-1check-1vue1.node-updatesblog2.13.02.13.12.13.1节点模块/vuepress但npm过时了不好用。比如如何一键升级?就像应用商店升级所有的手机软件一样。node-check-updates是npm过时的增强版本。其最简单的功能是一键升级,详细的功能是升级策略和安全升级。ncu是它的二进制命令$ncuCheckingpackage.json[=====================]5/5100%express4.12.x→4.13.xmulter^0.1.8→^1.0.1react-bootstrap^0.22.6→^0.24.0react-a11y^0.1.1→^0.2.6webpack~1.9.10→~1.10.5Runncu-utoupgradepackage.json使用ncu--doctor升级各个依赖项目测试通过后将进行测试。如果测试通过,则说明安装依赖成功。否则,它将回退到原始版本。找出罪魁祸首,好吗?Restoringpackage.jsonRestoringpackage-lock.jsonnpminstallnpminstall--no-savereact@16.0.0npmruntest?react15.0.0→16.0.0npminstall--no-savereact-redux@7.0.0npmruntest?react-radux6.0.0→7.0.0Savingpartiallyupgjson已配置在npmscriptncu:{"scripts":{"ncu":"ncu"}}Audit:Yourdependencieshavesecurityrisks当某个包存在安全风险时,这时候你要小心了,毕竟我也不是谁不想我的网站被攻击。唯一的解决办法是升级包版本。就像Github的机器人:Github机器人风险提示和提交PR。使用ncu将所有依赖包升级到最新有安全隐患吗?是的,因为ncu只会将package.json中的依赖升级到最新,而不会将lock文件中的依赖更新到最新。npmaudit可以发现项目中有风险的库,并使用npmauditfix修复它们。不过也有美中不足的地方,npmaudit的准确率没有yarnaudit高。不管怎么美中不足,yarnaudit都不支持yarnauditfix的自动修复。$npmaudit$npmauditfixsnyk是一项检查包风险的服务。它提供了一个命令行工具来检测风险,可以用来代替npmaudit。它也有缺陷,依赖一个服务,可以根据容器来构建,也可以使用SASS。{"scripts":{"audit":"snyktest","audit:fix":"snykprotect"}}Size:Controlyourbundlesizesizelimit[13]和bundlesize[14]可以控制bundlevolume两个工具,但size-limit对启动时间也有更强的支持。{"scripts":{"size":"size-limit","analyze":"size-limit--why"},"size-limit":[{"path":"dist/promise-utils.cjs.production.min.js","limit":"10KB"},{"path":"dist/promise-utils.esm.js","limit":"10KB"}]}工作中高效使用总结npmscript可以达到极高的效率和代码质量。本文涉及的包如下:husky[15]mocha[16]nyc[17]cypress[18]puppeteer[19]storybook[20]prettier[21]eslint[22]markdownlint[23]@commitlint/cli[24]lint-staged[25]husky[26]npm-check-updates[27]lerna[28]size-limit[29]bundle-size[30]你可以在npmdevtool[31]中找到更多有趣有用的库】参考[1]如何部署前端项目:https://shanyue.tech/frontend-engineering/docker.html[2]mocha:https://npm.devtool。tech/mocha[3]nyc:https://npm.devtool.tech/nyc[4]cypress:https://npm.devtool.tech/cypress[5]storybook:https://storybook.js.org/[6]更漂亮:https://npm.devtool.tech/prettierr[7]更漂亮的选项:https://prettier.io/docs/en/options.html#parser[8]eslint:https://npm.devtool.tech/eslint[9]markdownlint:https://npm.devtool.tech/markdownlint[10]commitlint:https://www.npmjs.com/package/@commitlint/cli[11]husky:https://npm.devtool.tech/husky[12]lint-staged:https://github.com/okonet/lint-staged[13]大小限制:https://github.com/ai/size-limit/[14]包大小:https://github.com/siddharthkp/bundlesize[15]husky:https://npm.devtool.tech/husky[16]mocha:https://npm.devtool.tech/mocha[17]nyc:https://npm.devtool.tech/nyc[18]cypress:https://npm.devtool.tech/cypress[19]puppeteer:https://npm.devtool.tech/puppeteer[20]storybook:https://npm.devtool.tech/storybook[21]prettier:https://npm.devtool.tech/prettier[22]eslint:https://npm.devtool.tech/eslint[23]markdownlint:https://npm.devtool.tech/markdownlint[24]@commitlint/cli:https://npm.devtool.tech/@commitlint/cli[25]lint-staged:https://npm.devtool.tech/lint-staged[26]husky:https://npm.devtool。tech/husky[27]npm-check-updates:https://npm.devtool.tech/npm-check-updates[28]lerna:https://npm.devtool.tech/lerna[29]大小限制:https://npm.devtool.tech/size-limit[30]bundle-size:https://npm.devtool.tech/bundle-size[31]npmdevtool:https://npm.devtool.tech