npm 是 JavaScript世界的包管理工具,并且是 Node.js平台的默认包管理工具。通过 npm可以安装、共享、分发代码,管理项目依赖关系。本篇文章带大家了解一下npm的原理,希望对大家有所帮助!
npm据称成为世界最大的包管理器?原因真的只是用户友好?
用来初始化一个简单的package.json文件。package.json文件用来定义一个package的描述文件。
1、npm init
的执行的默认行为
执行npm init --yes
,全部使用默认的值。
2、 自定义npm init
行为
npm init
命令的原理是:调用脚本,输出一个初始化的package.json文件。
获取用户输入使用prompt()方法。
npm的核心功能:依赖管理。执行npm i
从package.json中dependencies和devDependencies将依赖包安装到当前目录的node_modules文件夹中。
2.1、package定义
npm i
就可以安装一个包。通常package就是我们需要安装的包名,默认配置下npm会从默认的源(Registry)中查找该包名的对应的包地址,并且下载安装。 还可以是一个指向有效包名的http url/git url/文件夹路径。
package的准确定义,符合以下a)到g)其中一个条件,他就是一个package:
package的准确定义
2.2、安装本地包/远程git仓库包
共享依赖包,并非非要把包发布到npm源上才能使用。
1)、场景1:本地模块引用
开发中避免不了模块之间调用,开发中,我们把频繁调用的配置模块放在根目录,然后如果有很多层级目录,后来引用
const config = require(''../../../../..config)
这样的路径引用不利于代码重构。这时候我们需要考虑把这个模块分离出来供其他模块共享。比如config.js可以封装成一个package放到node_modules目录下。
不需要手动拷贝或者创建软连接到node_modules目录,npm 有自己的解决方案:
方案:
1、新增config文件夹,将config.js移入文件夹,名字修改为index.js,创建package.json定义config包
{ "name": "config", "main": "index.js", "version": "0.1.0" }
2、在项目的package.json新增依赖项,然后执行npm i。
{ "dependencies": { "config":"file: ./config" } }
查看 node_modules 目录我们会发现多出来一个名为 config,指向上层 config/ 文件夹的软链接。这是因为 npm 识别 file: 协议的url,得知这个包需要直接从文件系统中获取,会自动创建软链接到 node_modules 中,完成“安装”过程。
2)、场景2:私有git共享package
团队内会有一些代码/公用库需要在团队内不同项目间共享,但可能由于包含了敏感内容。
我们可以简单的将被依赖的包托管到私有的git仓库中,然后将git url保存到dependencies中。npm会直接调用系统的git命令从git仓库拉取包的内容到node_modules中。
npm支持的git url格式:
<protocol>://[<user>[:<password>]@]<hostname>[:<port>][:][/]<path>[#<commit-ish> | #semver:<semver>]
git 路径后可以使用 # 指定特定的 git branch/commit/tag, 也可以 #semver: 指定特定的 semver range.
比如:
git+ssh://git@github.com:npm/npm.git#v1.0.27 git+ssh://git@github.com:npm/npm#semver:^5.0 git+https://isaacs@github.com/npm/npm.git git://github.com/npm/npm.git#v1.0.27
3)、场景3:开源package问题修复
此时我们可以手动进入 node_modules 目录下修改相应的包内容,也许修改了一行代码就修复了问题。但是这种做法非常不明智!
方案:
fork原作者的git库,在自己的repo修复问题,然后将dependencies中的相应依赖改为自己修复后版本的git url就可以解决问题。
npm i执行完毕,node_modules中看到所有的依赖包。开发人员无关注node_modules文件夹的结构细节,关注业务代码中引用依赖包。
理解node_modules结构帮助我们更好理解npm如何工作。npm2到npm5变化和改进。
3.1 npm2
npm2在安装依赖包,采用的是简单的递归安装方法。每一个包都有自己的依赖包,每一个包的依赖都安装在自己的node_modules中,依赖关系层层递进,构成整个依赖树,这个依赖树与文件系统中的文件结构树一一对应。
最方便的依赖树的方式在根目录下执行npm ls
。
优点:
层级结构明显,便于傻瓜式管理。
缺点:
Pour les projets complexes, la structure des répertoires peut être trop profonde et le chemin du fichier profond est trop long, ce qui fait que le chemin du fichier dans le système de fichiers de la fenêtre ne peut pas dépasser 260 caractères.
Certains packages qui dépendent de plusieurs packages sont installés de manière répétée à de nombreux endroits, provoquant beaucoup de redondance.
3.2 npm3
Le répertoire node_modules de npm3 a été modifié pour une structure hiérarchique plus plate. npm3 parcourt toute l'arborescence des dépendances pendant l'installation et calcule la méthode d'installation de dossier la plus raisonnable. Tous les packages dépendants à plusieurs reprises peuvent être réinstallés.
Pour npm, les packages portant le même nom et des versions différentes sont deux packages indépendants. L'arborescence des dépendances de
npm3 ne correspond plus à la hiérarchie des dossiers un à un.
3.3 npm5
Suivez la méthode d'installation du package de dépendances plates de npm3. Le plus gros changement est l'ajout du fichier package-lock.json.
Fonction Package-lock.json : verrouillez la structure d'installation des dépendances et constatez que la structure hiérarchique des fichiers du répertoire node_modules correspond à la structure json un à un.
npm5 générera le fichier package-lock.json par défaut après avoir exécuté npm i et le soumettra à la base de code git/svn.
Pour mettre à niveau, n'utilisez pas la version 5.0.
Remarque : dans npm 5.0, si le fichier package-lock existe déjà, si vous ajoutez manuellement une dépendance au fichier package.json puis exécutez npm install, la nouvelle dépendance ne sera pas installée dans node_modules, package-lock.json ne sera pas mis à jour en conséquence.
Présente les connaissances liées à la gestion des mises à niveau des packages de dépendances.
4.1 Version sémantique semver
Une fonctionnalité importante de la gestion des dépendances npm adopte la spécification de version sémantique (semver) comme solution de gestion de versions.
Le numéro de version sémantique doit contenir trois chiffres, le format est : major.minor.patch. Cela signifie : numéro de version majeure. Numéro de version mineure.
Nous devons utiliser la convention Semver dans les dépendances pour spécifier le numéro de version ou la plage du package de dépendances requis.
Les règles couramment utilisées sont les suivantes :
version sémantique semver
1. Deux règles sont reliées par un espace pour représenter la logique "ET", qui est l'intersection des deux règles.
Par exemple, >=2.3.1 <=2.8.0 peut être interprété comme : >=2.3.1 et <=2.8.0
2. Deux règles sont connectées avec || pour exprimer la logique "OU", qui est l'union des deux règles.
tel que ^2 >=2.3.1 || ^3 >3.2
3 Une manière plus intuitive d'exprimer la plage de numéros de version
4. Ajouter après MAJOR.MINOR.PATCH - suivi d'une étiquette séparée par des points. En tant qu'étiquette de version préliminaire, elle est généralement considérée comme instable et n'est pas. recommandé pour la version de production utilisée.
4.2 Mise à niveau de la version des dépendances
Après l'installation d'un package de dépendances, une nouvelle version est publiée Comment utiliser npm pour mettre à niveau la version ?
Conclusion de l'utilisation de npm3 :
Conclusion de l'utilisation de npm5 :
4.3 Meilleure pratique
Le nœud que j'utilise couramment est 8.11.x et npm est 5.6. 0.
升级依赖包:
降级依赖包:
删除依赖包:
5.1 基本使用
npm scripts是npm的一个重要的特性。在package.json中scripts字段定义一个脚本。
比如:
{ "scripts": { "echo": "echo HELLO WORLD" } }
我们可以通过npm run echo 命令执行这段脚本,就像shell中执行echo HELLO WOLRD,终端是可以看到输出的。
总结如下:
5.2 node_modules/.bin目录
保存了依赖目录中所安装的可供调用的命令行包。本质是一个可执行文件到指定文件源的映射。
例如 webpack 就属于一个命令行包。如果我们在安装 webpack 时添加 --global 参数,就可以在终端直接输入 webpack 进行调用。
上一节所说,npm run 命令在执行时会把 ./node_modules/.bin 加入到 PATH 中,使我们可直接调用所有提供了命令行调用接口的依赖包。所以这里就引出了一个最佳实践:
•将项目依赖的命令行工具安装到项目依赖文件夹中,然后通过 npm scripts 调用;而非全局安装
于是 npm 从5.2 开始自带了一个新的工具 npx.
5.3 npx
npx 的使用很简单,就是执行 npx 即可,这里的 默认就是 ./node_modules 目录中安装的可执行脚本名。例如上面本地安装好的 webpack 包,我们可以直接使用 npx webpack 执行即可。
5.4 用法
1、传入参数
"scripts": { "serve": "vue-cli-service serve", "serve1": "vue-cli-service --serve1", "serve2": "vue-cli-service -serve2", "serve3": "vue-cli-service serve --mode=dev --mobile -config build/example.js" }
除了第一个可执行的命令,以空格分割的任何字符串都是参数,并且都能通过process.argv属性访问。
比如执行npm run serve3命令,process.argv的具体内容为:
[ '/usr/local/Cellar/node/7.7.1_1/bin/node', '/Users/mac/Vue-projects/hao-cli/node_modules/.bin/vue-cli-service', 'serve', '--mode=dev', '--mobile', '-config', 'build/example.js' ]
2、多命令运行 在启动时可能需要同时执行多个任务,多个任务的执行顺序决定了项目的表现。
1)串行执行
串行执行,要求前一个任务执行成功之后才能执行下一个任务。使用 && 服务来连接。
npm run scipt1 && npm run script2
串行执行命令,只要一个命令执行失败,整个脚本会中止的。
2)并行执行
并行执行,就是多个命令同时平行执行,使用 & 符号来连接。
npm run script1 & npm run script2
3、env 环境变量 在执行npm run脚本时,npm会设置一些特殊的env环境变量。其中package.json中的所有字段,都会被设置为以npm_package_ 开头的环境变量。
4、指令钩子 在执行npm scripts命令(无论是自定义还是内置)时,都经历了pre和post两个钩子,在这两个钩子中可以定义某个命令执行前后的命令。比如在执行npm run serve命令时,会依次执行npm run preserve、npm run serve、npm run postserve,所以可以在这两个钩子中自定义一些动作:
"scripts": { "preserve": "xxxxx", "serve": "cross-env NODE_ENV=production webpack", "postserve": "xxxxxx" }
5、常用脚本示例
// 删除目录 "clean": "rimraf dist/*", // 本地搭建一个http服务 "server": "http-server -p 9090 dist/", // 打开浏览器 "open:dev": "opener http://localhost:9090", // 实时刷新 "livereload": "live-reload --port 9091 dist/", // 构建 HTML 文件 "build:html": "jade index.jade > dist/index.html", // 只要 CSS 文件有变动,就重新执行构建 "watch:css": "watch 'npm run build:css' assets/styles/", // 只要 HTML 文件有变动,就重新执行构建 "watch:html": "watch 'npm run build:html' assets/html", // 部署到 Amazon S3 "deploy:prod": "s3-cli sync ./dist/ s3://example-com/prod-site/", // 构建 favicon "build:favicon": "node scripts/favicon.js",
6.1 npm config
6.2 npmrc文件
可以通过删除npm config命令修改配置,还可以通过npmrc文件直接修改配置。
npmrc文件优先级由高到低,包括:
比如:我们在公司内网下需要代理才能访问默认源:https://registry.npmjs.org源;或者访问内网的registry,就可以在工作项目下新增.npmrc文件并提交代码库。
示例配置:
proxy = http://proxy.example.com/ https-proxy = http://proxy.example.com/ registry = http://registry.example.com/
这种在工程内配置文件的优先级最高,作用域在这个项目下,可以很好的隔离公司项目和学习研究的项目两种不同环境。
将这个功能与 ~/.npm-init.js 配置相结合,可以将特定配置的 .npmrc 跟 .gitignore, README 之类文件一起做到 npm init 脚手架中,进一步减少手动配置。
6.3 node版本约束
一个团队中共享了相同的代码,但是每个人开发机器不一致,使用的node版本也不一致,服务端可能与开发环境不一致。
{ "engines": {"node": ">=7.6.0"} }
[1] node查阅兼容表格: https://node.green/
更多node相关知识,请访问:nodejs 教程!
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!