关于javascript:如何高效地组织-npm-script

51次阅读

共计 6456 个字符,预计需要花费 17 分钟才能阅读完成。

我是山月,这是我对于 Node 进阶 的第十三篇文章,欢送关注我的博客: shfshanyue/blog 以及 Node 进阶系列

家喻户晓,一个 Javasript 我的项目的脚本类工具,能够应用 package.json 中的 scripts 字段来组织,简略来说,这就是 npm script

最典型最罕用约定俗成的一个是 npm start,用以启动我的项目:

{
  "scripts": {"start": "next"}
}

约定俗成的还有很多,如下所列

  • npm install
  • npm test
  • npm publish

约定俗成的亲儿子脚本天然和其它第三方脚本不一样,如果须要执行它,间接应用 npm 前缀即可,如 npm start,那其它脚本呢?那就须要 npm run 前缀了。而 yarn 就没这么多考究了,厚此薄彼。

$ npm run <user defined>
$ npm run-script dev

# 为了简略不便,等同于
$ npm run dev

# yarn 
$ yarn dev

以上是家喻户晓的,以下讲一讲有可能不是家喻户晓的

运行: npm run dev 与 npm start 的区别

对于一个 纯生成动态页面打包 的前端我的项目而言,它们是没有多少区别的:生产环境的部署只依赖于构建生成的资源,更不依赖 npm scripts。可见 如何部署前端我的项目。

应用 create-react-app 生成的我的项目,它的 npm script 中只有 npm start

{
  "start": "react-scripts start",
  "build": "react-scripts build",
  "test": "react-scripts test",
  "eject": "react-scripts eject"
}

应用 vuepress 生成的我的项目,它的 npm script 中只有 npm run dev

{
  "dev": "vuepress dev",
  "build": "vuepress build"
}

在一个 面向服务端 的我的项目中,如 nextnuxtnest。dev 与 start 的区别趋于显著,一个为生产环境,一个为开发环境

  • dev: 在开发环境启动我的项目,个别带有 watch 选项,监听文件变动而重启服务,此时会消耗大量的 CPU 性能,不宜放在生产环境
  • start: 在生产环境启动我的项目

nest 我的项目中进行配置

{
  "start": "nest start",
  "dev": "nest start --watch"
}

运行:Script Hooks -> 如何把新我的项目疾速跑起来

新人入职新上手我的项目,如何把它跑起来,这是所有人都会碰到的问题:所有人都是从老手开始的。

有可能你会脱口而出:npm run dev/npm start,但理论工作中,处处藏坑,往往没这么简略。

  1. 查看是否有 CI/CD,如果有跟着 CI/CD 部署的脚本跑命令
  2. 查看是否有 dockerfile,如果有跟着 dockerfile 跑命令
  3. 查看 npm scripts 中是否有 dev/start,尝试 npm run dev/npm start
  4. 查看是否有文档,如果有跟着文档走。为啥要把文档放到最初一个?起因你懂的

但即使是非常审慎,也有可能遇到以下几个叫苦不迭、节约了一下午工夫的坑:

  1. 前端有可能在 本地环境启动时须要依赖前端构建时所产生的文件 ,所以有时须要 先失常部署一遍,再试着依照本地环境启动 (即须要先 npm run build 一下,再 npm run dev/npm start)。(比方,一次咱们的我的项目 npm run dev 时须要 webpack DllPlugin 构建后的货色)
  2. 别忘了设置环境变量或者配置文件

因而,设置一个少的 script,能够很好地防止前人踩坑,更重要的是,能够防止前人骂你

{
  "scripts": {
    "start": "npm run dev",
    "config": "node assets && node config",
    "build": "webpack",
    // 设置一个 dev 的钩子,在 npm run dev 前执行,此处有可能不是必须的
    "predev": "npm run build",
    "dev": "webpack-dev-server --inline --progress"
  }
}

Hooks

在 npm script 中,对于每一个命令都有 Pre/Post 钩子,别离在命令执行前后执行

npm run <script>
pre<script>
<script>
post<script>

在工作中,这些钩子与内置的命令为我的项目提供了简便的操作形式,也提供了更平安的我的项目操作流程

  1. 装包之后,进行 husky(v5.0) 的设置
  2. 打包之前,清理指标文件件
  3. 发包之前,进行打包构建
  4. 运行之前,筹备好资源文件
{
  "scripts": {
    "postinstall": "husky install",
    "prebuild": "rimraf dist",
    "build": "webpack",
    "predev": "npm run assets",
    "dev": "webpack-dev-server --inline --progress"
  }
}

构建

构建打包,基本上所有的我的项目都含有这个命令,并且默认为 npm run build

在 CI 或前端托管平台 Vercel/Netlify 中,对于部署前端我的项目,最重要的一步就是打包。然而有些我的项目有可能不须要打包,此时能够应用 if-present 参数,代表如果存在该 script,则执行,否则跳过


$ npm run --if-present build
{
  "scripts": {"build": "next build"}
}

测试: Script 后缀

对于实现一件极为简单的事件,能够应用前缀进行分组组织 npm script,比方测试。

  • npm run test: 应用 mocha 进行单元测试
  • npm run test:coverage: 应用 nyc 查看单元测试覆盖率
  • npm run test:e2e: 应用 cypress 进行 UI 自动化测试
{
  "test": "mocha",
  "test:coverage": "nyc npm test",
  "test:e2e": "npm run cy:run --",
  "cy:run": "cypress run --config-file cypress/config.json",
  "cy:open": "cypress open --config-file cypress/config.json"
}

对于测试而言,mochanyc 联合能够很好地进行单元测试,并提供覆盖率报告。

对于前端 e2e 测试而言,cypresspuppeteer 无疑是最风行的框架。

那如何对 Vue/React 组件进行更好地测试及文档呢?

组件测试:

storybook 能够更好地对 React/Vue 组件进行调试、测试并造成帮忙文档。开发根底组件库时,能够配置 npm run storybook 进行更好的测试

$ npm run storybook
{
  "scripts": {
    "storybook": "start-storybook -p 9001 -c .storybook",
    "storybook:build": "build-storybook -c .storybook -o .out",
    "prepublishOnly": "npm run build"
  }
}

格式化: Prettier

Prettier 是一款反对多种编程语言,如 html、css、js、graphql、markdown 等并且可与编辑器 (vscode) 深度集成的代码格式化工具。

在 npm script 中配置代码格式化如下所示:对 jscssjsonmarkdown 进行格式化

{
  "scripts": {
    // 配置文件: .prettierrc
    // 格式化: --write
    // 文件: *.js
    "prettier": "prettier --config .prettierrc --write {.,components,lib,pages}/*.{js,css,json,md}",
  }
}

.prettierrcprettier 的配置文件,个别是比较简单的配置,可供配置的 Prettier Options 也没有很多。

{
  "singleQuote": true,
  "printWidth": 100,
  "semi": false,
  "arrowParens": "avoid"
}

Lint: 代码格式化及质量检查

那 Prettier 与 ESLint/StyleLint/TSLint 有什么区别?

Prettier 仅仅作代码的格式化,如空格、是否增加分号之类。而 ESLint 之类对代码格式化外,还对代码进行 质量检查,如 no-unused-vars, no-implicit-globals 等规定。

JS 与 TS 的质量检查,还是要看 eslint。

{
  "scripts": {
    "lint": "eslint .",
    "lint:fix": "eslint . --fix"
  }
}

除了 eslint 之外,还能够对 markdown、gitcommit 进行格式化

  • markdownlint
  • commitlint

Git: 你好,代码不合格,这里禁止提交

你的代码不合格,为了防止你被别人吐槽,这里不容许提交。这时候 Git Hooks 就派上了用场。

Git Hooks 中的 precommit hook 会在代码提交之前执行脚本,如果脚本不通过 (Exit Code 不是 0),则禁止提交。

husky 与 lint-staged 是 Git Hooks 的最佳搭配。

{
  "scripts": {
    "lint": "eslint .",
    "prettier": "prettier --config .prettierrc --write {.,components,lib,pages}/*.{js,css,json,md}",
  },
  "husky": {
    "hooks": {"pre-commit": "lint-staged"}
  },
  "lint-staged": {
    "*.js": ["npm run lint"],
    "*.{js,css,json,md}": ["npm run prettier"]
  }
}

Outdated: 你的依赖已过期

当一个库过期了会怎么样?

  • 找不到文档,无处下手
  • 常常有 Bug 由过期库引起,很难修复
  • 存在平安危险

没有人会喜爱过期的库。

应用 npm outdated 能够发现 package.json 中依赖的过期库

$ npm outdated
Package                            Current  Wanted  Latest  Location                                        Depended by
@vuepress/plugin-google-analytics    1.7.1   1.8.2   1.8.2  node_modules/@vuepress/plugin-google-analytics  blog
axios                               0.21.0  0.21.1  0.21.1  node_modules/axios                              blog
dayjs                                1.9.6  1.10.4  1.10.4  node_modules/dayjs                              blog
graphql                             15.4.0  15.5.0  15.5.0  node_modules/graphql                            blog
koa                                 2.13.0  2.13.1  2.13.1  node_modules/koa                                blog
npm-check-updates                   10.2.2  10.3.1  11.3.0  node_modules/npm-check-updates                  blog
vuepress                             1.7.1   1.8.2   1.8.2  node_modules/vuepress                           blog

然而 npm outdated 并不好用,比方如何一键降级?就像利用商店降级所有手机软件一样。

node-check-updates 是加强版的 npm outdated,它最简略的性能是一键降级,细化性能是降级策略与平安降级。ncu 是它的二进制命令

$ ncu
Checking package.json
[====================] 5/5 100%

express           4.12.x  →   4.13.x
multer            ^0.1.8  →   ^1.0.1
react-bootstrap  ^0.22.6  →  ^0.24.0
react-a11y        ^0.1.1  →   ^0.2.6
webpack          ~1.9.10  →  ~1.10.5

Run ncu -u to upgrade package.json

应用 ncu --doctor,在降级每一个依赖时会对我的项目进行测试,如果测试通过则装置依赖胜利,否则回退到原先版本

$ ncu --doctor -u
npm install
npm run test
ncu -u
npm install
npm run test
Failing tests found:
/projects/myproject/test.js:13
  throw new Error('Test failed!')
  ^
Now let's identify the culprit, shall we?
Restoring package.json
Restoring package-lock.json
npm install
npm install --no-save react@16.0.0
npm run test
  ✓ react 15.0.0 → 16.0.0
npm install --no-save react-redux@7.0.0
npm run test
  ✗ react-redux 6.0.0 → 7.0.0
Saving partially upgraded package.json

在 npm script 中进行配置 ncu:

{
  "scripts": {"ncu": "ncu"}
}

Audit: 你的依赖存在平安危险

当某一个 package 存在平安危险时,这时候就要小心了,毕竟谁也不想本人的网站被攻打。惟一的解决办法就是 package 降级版本。就像 Github 的机器人这样:

那应用 ncu 把所有依赖包降级到最新还会有平安危险吗?

会有,因为 ncu 只会把 package.json 中的依赖降级到最新,而不会把 lock file 中的依赖降级到最新。

npm audit 能够发现我的项目中的危险库,并应用 npm audit fix 进行修复。

然而美中不足,npm audit 的精准度没有 yarn audit 高。

再美中不足,yarn audit 并不反对 yarn audit fix 主动修复

$ npm audit

$ npm audit fix

snyk 是一个查看包危险的一个服务,他提供了命令行工具检测危险,能够应用它代替 npm audit。他也有缺点,依赖一个服务,能够依据容器自建或者应用 SASS。

{
  "scripts": {
    "audit": "snyk test",
    "audit:fix": "snyk protect"
  }
}

Size: 管制你的 bundle 大小

size limit 与 bundle size 都是能够管制 bundle 体积的两个工具,不过 size-limit 对启动工夫也有更强的反对。

{
  "scripts": {
    "size": "size-limit",
    "analyze": "size-limit --why"
  },
  "size-limit": [
    {
      "path": "dist/promise-utils.cjs.production.min.js",
      "limit": "10 KB"
    },
    {
      "path": "dist/promise-utils.esm.js",
      "limit": "10 KB"
    }
  ]
}

总结

在工作中高效应用 npm script,能够极高效率与代码品质,本文中波及到的 package 如下所示

  • husky
  • mocha
  • nyc
  • cypress
  • puppeteer
  • storybook
  • prettier
  • eslint
  • markdownlint
  • @commitlint/cli
  • lint-staged
  • husky
  • npm-check-updates
  • lerna
  • size-limit
  • bundle-size

你能够在 npm devtool 中找到更多乏味有用的库

对于山月

我是山月,欢送关注我的博客: shfshanyue/blog,内含我在理论工作中碰到的问题、对于业务的思考及在全栈方向上的学习

  • 有可能你并不需要服务器
  • 前端工程化系列
  • Node 进阶系列

社交:

Github 知乎 掘金 博客

我的项目:

next app 我的面试 诗词集
开发者工具箱 npm 在线执行 前端周刊

正文完
 0