(前端工程化01)私人管家-包管理器

字数:3883, 阅读时间:10分钟,点击阅读原文
目录:html

点击查看源网页

包管理器

在好久好久之前,那时候的前端被你们”亲切“的称为“切图仔”,那时前端的工做很是简单,仅仅只是将设计图还原,而后加上一些交互和特效。因为没有分享的平台,项目中不少本身写的东西分享出来也比较困难,代码的复用也只能是手动CV。即便用到了第三方的一些插件,好比jQuery,也只能下载后手动进行管理。前端

后来,nodejs出现了,做为一门后端语言,它的复杂程度远比前端要高得多,若是手动管理那将是一件很痛苦的事情,因此npm应运而生。vue

下面咱们简单介绍一下几个概念:node

  • 包:包便是一段能复用的代码,它能够存在开发者本地和云端,每一个包可能依赖也可能不会依赖其余包
  • 包管理器:对包进行管理的工具,能够追溯包的版本、依赖、做者等相关信息,还能够将云端的包下载到本地。

NPM

npm即Node package Manager,软件开发者可在上面分享本身的成果,包含上百万个包,并且使用它能够轻松跟踪依赖和版本。react

npm主要有三个部分组成:git

  • 网站:开发者查找包(package)的主要途径,能够经过不一样的条件进行检索,还能够管理本身或组织的帐户
  • 注册表:一个巨大的数据库,保存了每一个包(package)的相关信息
  • 命令行工具:经过命令行终端运行

NPM会在安装NodeJS的时候附带安装,具体的安装及配置请见上一篇《开发环境搭建》。github

经常使用命令

生成配置文件package.json

npm init [配置]

配置:web

  • -y(--yes) :跳过问答模式,全部配置所有选择默认配置

搜索包

npm search <包名>

注意: 搜索包须要切换到npm官方镜像源typescript

npm包的开发门槛很低,数量众多,重复的轮子也多得出奇,每次选择一个包对我这种选择强迫症来讲,不是一件容易的事情,通常咱们能够参考如下几点:shell

  • 下载量,相信别人的选择
  • 维护的活跃程度,包括最后更新时间,是否能够给做者提交issues
  • 文档,没文档就是在看天书

安装包

npm install <包名> [配置] # install 能够简写为i

配置:

  • -g (--global):将包做为全局依赖安装,通常命令行工具之类的会选择此方式
  • -S (--save):将包做为生产依赖安装,通常在生成(线上)环境使用的依赖都采用此方式,默认也是此方式
  • -D (--save-dev):将包做为开发依赖安装,通常开发环境使用的一些工具都采用此方式安装

能够在包名后面加上版本号以安装特定版本号,如npm install vue@2.16.1

卸载包

npm uninstall <包名> [配置]

配置和安装包配置同样,不一样配置表示写在不一样地方的包

更新包

npm update <包名> [配置]

配置和安装包配置同样,不一样配置表示写在不一样地方的包

发布包

npm publish [配置]

配置:

  • --tag beta: 指定标签,默认为版本号,可以使用npm publish --tag beta安装

安全检测

npm audit # 对包及其依赖进行安全监测,并生成报告
npm audit fix # 自动为易受攻击的依赖项安装兼容的更新
npm set audit false # 关闭监测机制

因为npm包的数量众多,并且不少包早已没有维护了,不免会出现一些安全问题,因此安全监测能够帮助咱们作一些排查。

注意:** 安全监测须要切换到npm官方镜像源

清除缓存

npm cache clean --force #强制清除npm缓存

NPX

npm在5.2版本内置了npx工具,也可使用npm install -g npx手动安装,主要用来在命令行调用项目内部安装的模块,避免安装一些全局模块。

  • 调用项目中安装的包

若是咱们在项目中安装了gulp,要执行gulp相关的命令,若是在项目目录下在终端直接执行的话,它会去全局的包查找,若是要避免这种状况,就只能将命令定义在package.json的scripts中,而后经过npm run的方式来执行。若是使用npx,就会避免这种状况,由于它会优先去本地项目中寻找。

npx gulp --version
  • 避免全局安装模块

通常在使用一些脚手架的时候,咱们须要在全局安装后才可以使用。若是使用npx就不须要。

npx create-react-app my-react-app

npx 将create-react-app下载到一个临时目录,使用之后再删除,避免了安装全局模块。

  • 执行远程代码
# 执行 Gist 代码
$ npx https://gist.github.com/zkat/4bc19503fe9e9309e2bfaa2c58074d32

# 执行仓库代码
$ npx github:piuccio/cowsay hello

参考资料:npx 使用教程

package.json

package.json是npm的配置文件,通常存在于项目的根目录中,记录了当前工程信息及使用的依赖包信息。

必填字段
  • name:包的名字,不能以点(.)或下划线(_)开头,不能包含中文、大写字母及非URL安全字符,长度必须小于或等于214个字符,@开头的包标识它是Scoped包。
  • version:包的当前版本,遵循 Semantic Versioning 2.0.0 语义化版本规范
信息类字段
  • description:包的描述
  • keywords:关键字,值为一个字符串数组,当在搜索包时颇有用
  • license:许可证,以便让用户了解他们是在什么受权下使用此包,以及此包还有哪些附加限制。
{
  "license": "MIT",
  "license": "(MIT or GPL-3.0)",
  "license": "SEE LICENSE IN LICENSE_FILENAME.txt",
  "license": "UNLICENSED"
}
连接类字段

各类指向项目文档、issues 上报,以及代码托管网站的连接字段。

  • homepage:是包的项目主页或者文档首页。
  • bugs:问题反馈系统的 URL,或者是 email 地址之类的连接。方便用户经过该途径向包做者反馈问题。
  • repository:是包代码托管的位置。
{
  "repository": { "type": "git", "url": "https://github.com/user/repo.git" },
  "repository": "github:user/repo",
  "repository": "gitlab:user/repo",
  "repository": "bitbucket:user/repo",
  "repository": "gist:a1b2c3d4e5f"
}
项目维护类字段

项目的维护者的相关信息。

  • `author:做者信息,一我的。
{
  "author": { "name": "Your Name", "email": "you@example.com", "url": "http://your-website.com" },
  "author": "Your Name <you@example.com> (http://your-website.com)"
}
  • `contributors:贡献者信息,可能不少人。
{
  "contributors": [
    { "name": "Your Friend", "email": "friend@example.com", "url": "http://friends-website.com" }
    { "name": "Other Friend", "email": "other@example.com", "url": "http://other-website.com" }
  ],
  "contributors": [
    "Your Friend <friend@example.com> (http://friends-website.com)",
    "Other Friend <other@example.com> (http://other-website.com)"
  ]
}
文件类信息

指定包含在项目中的文件,以及项目的入口文件。

  • files:项目包含的文件,能够是单独的文件、整个文件夹,或者通配符匹配到的文件。
{
  "files": [
    "filename.js",
    "directory/",
    "glob/*.{js,json}"
  ]
}
  • main:项目的入口文件。
{
  "main": "filename.js"
}
  • bin:随着项目一块儿被安装的可执行文件,开发命令行工具会用到此项。
{
  "bin": "bin.js",
  "bin": {
    "other-command": "bin/other-command"
  }
}
  • man:项目的入口文件。

项目的入口文件。

{
  "man": "./man/doc.1",
  "man": ["./man/doc.1", "./man/doc.2"]
}
  • directories:当你的包安装时,你能够指定确切的位置来放二进制文件、man pages、文档、例子等
{
  "directories": {
    "lib": "path/to/lib/",
    "bin": "path/to/bin/",
    "man": "path/to/man/",
    "doc": "path/to/doc/",
    "example": "path/to/example/"
  }
}
  • types:指定 TypeScript 中的类型声明文件
{
  "types": "./lib/main.d.ts",
}
任务类字段

脚本是定义自动化开发相关任务的好方法,好比使用一些简单的构建过程或开发工具。 在 scripts 字段里定义的脚本,能够经过npm run xxx 命令来执行。 例如,上述 build-project 脚本能够经过 npm run build-project 调用,并执行 node build-project.js

{
  "scripts": {
    "build-project": "node build-project.js"
  }
}

有一些特殊的脚本名称。 若是定义了 preinstall 脚本,它会在包安装前被调用。 出于兼容性考虑,installpostinstallprepublish 脚本会在包完成安装后被调用。

特定的 scripts
  • prepublish: 在打包并发布包以前运行,以及在没有任何参数的本地 npm 安装以前运行。
  • prepare: 在打包和发布包以前运行,在没有任何参数的本地 npm install 上运行,以及安装 git 依赖项时。 这是在 preublish 以后运行,可是在 preublishOnly 以前运行。
  • prepublishOnly: 在包准备和打包以前运行,仅限于npm发布。
  • prepack: 在打包 tarball 以前运行(在 npm packnpm publish,以及安装 git 依赖项时)
  • postpack: 在生成 tarball 以后运行并移动到其最终目标。
  • publish, postpublish: 在包发布后运行。
  • preinstall: 在安装软件包以前运行。
  • install, postinstall: 安装包后运行。
  • preuninstall, uninstall: 在卸载软件包以前运行。
  • postuninstall: 在卸载软件包以后运行。
  • preversion: 在改变包版本以前运行。
  • version: 改变包版本后运行,但提交以前。
  • postversion: 改变包版本后运行,而后提交。
  • pretest, test, posttest: 由 npm test 命令运行。
  • prestop, stop, poststop: 由 npm stop 命令运行。
  • prestart, start, poststart: 由 npm start 命令运行。
  • prerestart, restart, postrestart: 由 npm restart 命令运行。 注意:若是没有提供重启脚本,npm restart 将运行 stopstart 脚本。
  • preshrinkwrap, shrinkwrap, postshrinkwrap: 由 npm shrinkwrap 命令运行。
依赖描述类字段

记录了当前工程或者包的其余依赖,他们的版本遵循以下规则:

  • 补丁发布:1.01.0.x~1.0.4
  • 次要版本:11.x^1.0.4
  • 主要版本:*x
  • dependencies:这些是你的包的开发版和发布版都须要的依赖,使用npm i xxx -S安装。
{
  "dependencies": {
    "package-1": "^3.1.4",
    "package-2": "file:./path/to/dir"
  }
}
你能够指定一个确切的版本、一个最小的版本 (好比 >=) 或者一个版本范围 (好比 >= ... <)。
包也能够指向本地的一个目录文件夹。
  • devDependencies:这些是只在你的包开发期间须要,可是生产环境不会被安装的包,使用npm i xxx -D安装。

这些是只在你的包开发期间须要,可是生产环境不会被安装的包。

{
  "devDependencies": {
    "package-2": "^0.4.2"
  }
}

咱们再安装包的时候最好按照使用环境来安装,不要不分环境随便安装,不然在某些状况下打包会出现问题。

参考资料: package.json 说明文档

package-lock.json

原则上,包的发布须要严格遵循 语义版本控制 规则,可是这并非一个强制的规则,因此,大多人开发的时候经验会出现一样的 package.json 文件,但安装了不一样版本的包,这可能致使出现一些兼容错误,因此npm在安装时就会生成lock来锁定版本。

查找规则

npm包在使用时遵循以下查找规则:

  1. 在当前目录下查找node_modules目录;若是没有则向上一层目录查找,若是也没有则继续向上层目录查找直到根目录; 若是都没有则报错
  2. 进入node_modules中查找模块名目录;若是没有则报错
  3. 进入模块名目录查找 package.json 文件中的 main 配置项,导入该配置项指定的文件
  4. 若是模块名目录中没有 package.json文件,或package.json文件中没有 main 配置项,则加载 index.js 文件

Yarn

Yarn 是一个由 Facebook,Google,Exponent 和 Tilde 构建的新的 JavaScript 包管理器。正如官方公告所写,它的目标就是解决这些团队使用 npm 的时候所遇到的几个问题,即:

  • 安装包不够快速和稳定
  • 存在安全隐患,由于 npm 容许包在安装的时候运行代码

它并非想要彻底替代 npm。Yarn 仅仅是一个可以从 npm 仓库获取到模块的新的 CLI 客户端。

更清晰的输出

yarn的输出很清晰,使用了emoji,看起来也更加漂亮。

“yarn install” 命令的输出

并行安装

在安装多个包时,npm会按包顺序执行,也就是只有当一个包所有安装完成后,才会安装下一个。Yarn 则是并行执行任务,提升了性能。

yarn和npm的命令对比

  • 有区别的命令
Npm Yarn 功能描述
npm install(npm i) yarn install(yarn) 根据 package.json 安装全部依赖
npm i –save [package] yarn add [package] 添加依赖包
npm i –save-dev [package] yarn add [package] –dev 添加依赖包至 devDependencies
npm i -g [package] yarn global add [package] 进行全局安装依赖包
npm update –save yarn upgrade [package] 升级依赖包
npm uninstall [package] yarn remove [package] 移除依赖包
  • 相同操做的命令
Npm Yarn 功能描述
npm run yarn run 运行 package.json 中预约义的脚本
npm config list yarn config list 查看配置信息
npm config set registry 仓库地址 yarn config set registry 仓库地址 更换仓库地址
npm init yarn init 互动式建立/更新 package.json 文件
npm list yarn list 查看当前目录下已安装的node包
npm login yarn login 保存你的用户名、邮箱
npm logout yarn logout 删除你的用户名、邮箱
npm outdated yarn outdated 检查过期的依赖包
npm link yarn link 开发时连接依赖包,以便在其余项目中使用
npm unlink yarn unlink 取消连接依赖包
npm publish yarn publish 将包发布到 npm
npm test yarn test 测试 = yarn run test
npm bin yarn bin 显示 bin 文件所在的安装目录
yarn info yarn info 显示一个包的信息

yarn的命令跟npm的命令差别不大,若是使用过npm,那么过渡到yarn也很简单。npm自己也在不断优化,继续使用也没有关系。

参考资料:Npm vs Yarn 之备忘详单

将来

如今npm包仍是有不少没法回避的问题,最初node_modules下面每一个依赖包的依赖放在本身的目录下面,相同的依赖没法复用,不论是安装仍是删除都很是低效,并且在windows上常常会出现由于超过最大嵌套层级而没法删除的状况,不过好在后来官方调整了架构,改成平铺的结构,解决了这些问题。

不过现阶段npm的包管理仍是很混乱,咱们常常会看到下面这张图:

img

  • npm如今有不少重复的包,不少不维护的包,这给使用者形成了困扰
  • npm依赖繁多,好比我就仅仅想开发一个react的demo,结果发现要安装上千个包

npm官方应该也意识到了,因此它们正在开发下一代包管理工具Tink,相信不久的未来就会和咱们见面,是否是很期待呢?

相关文章
相关标签/搜索