Heim >Web-Frontend >js-Tutorial >Dieser Artikel hilft Ihnen, die Prinzipien von npm zu verstehen
npm ist das Paketverwaltungstool der JavaScript-Welt und das Standardpaketverwaltungstool für die Node.js-Plattform. Über npm können Sie Code installieren, freigeben, verteilen und Projektabhängigkeiten verwalten. Dieser Artikel wird Ihnen helfen, die Prinzipien von npm zu verstehen. Ich hoffe, er wird Ihnen hilfreich sein!
npm soll der größte Paketmanager der Welt sein? Der Grund ist wirklich nur benutzerfreundlich?
wird zum Initialisieren eines einfachen Pakets verwendet.json Datei. Die Datei package.json wird zum Definieren einer Paketbeschreibungsdatei verwendet.
1. Das Standardverhalten der npm init
-Ausführungnpm 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
npm init --yes
, und alle Standardwerte werden verwendet. 2. Passen Sie das Verhalten von npm init
an. npm init
ist: Rufen Sie das Skript auf und geben Sie eine initialisierte package.json-Datei aus. Erhalten Sie Benutzereingaben mit der Methode prompt(). 2. Installation von Abhängigkeitspaketen
🎜🎜Die Kernfunktion von npm: Abhängigkeitsmanagement. Führen Sienpm i
aus, um Abhängigkeitspakete von dependencies und devDependencies in package.json im Ordner „node_modules“ im aktuellen Verzeichnis zu installieren. 🎜🎜🎜2.1, Paketdefinition🎜🎜🎜npm i
kann ein Paket installieren. Normalerweise ist „Paket“ der Name des Pakets, das wir installieren müssen. In der Standardkonfiguration findet npm die entsprechende Paketadresse des Paketnamens aus der Standardquelle (Registrierung) und lädt sie herunter und installiert sie. Kann auch ein http-URL/Git-URL/Ordnerpfad sein, der auf einen gültigen Paketnamen verweist. 🎜🎜Die genaue Definition eines Pakets erfüllt eine der folgenden Bedingungen a) bis g), es handelt sich um ein Paket: 🎜🎜
Die genaue Definition des Pakets 🎜🎜🎜2.2. Lokale Pakete/Remote-Git-Warehouse-Pakete installieren 🎜🎜🎜Freigegebene Abhängigkeitspakete müssen nicht in der npm-Quelle veröffentlicht werden, um sie zu verwenden. 🎜🎜1), Szenario 1: Lokale Modulreferenz 🎜🎜 Aufrufe zwischen Modulen können während der Entwicklung nicht vermieden werden. Während der Entwicklung legen wir häufig aufgerufene Konfigurationsmodule im Stammverzeichnis ab und verweisen dann, wenn es viele hierarchische Verzeichnisse gibt, später auf 🎜
{ "scripts": { "echo": "echo HELLO WORLD" } }🎜 Solche Pfadverweise sind für die Code-Umgestaltung nicht förderlich. Zu diesem Zeitpunkt müssen wir darüber nachdenken, dieses Modul zu trennen, damit es von anderen Modulen gemeinsam genutzt werden kann. Beispielsweise kann config.js in ein Paket gekapselt und im Verzeichnis node_modules abgelegt werden. 🎜🎜Es ist nicht erforderlich, das Verzeichnis „node_modules“ manuell zu kopieren oder eine Soft-Verbindung herzustellen. npm verfügt über eine eigene Lösung: 🎜🎜 Lösung: 🎜🎜1. Fügen Sie einen neuen Konfigurationsordner hinzu, verschieben Sie config.js in den Ordner und ändern Sie die Datei Name zu index.js. Erstellen Sie package.json, um das Konfigurationspaket zu definieren🎜
"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" }🎜2. Fügen Sie Abhängigkeiten in package.json des Projekts hinzu und führen Sie dann npm i aus. 🎜
[ '/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' ]🎜Wenn wir uns das Verzeichnis node_modules ansehen, finden wir einen zusätzlichen Softlink namens config, der auf den oberen Ordner config/ verweist. Dies liegt daran, dass npm die URL des Dateiprotokolls erkennt und erfährt, dass dieses Paket direkt aus dem Dateisystem abgerufen werden muss. Es erstellt automatisch einen Softlink zu node_modules, um den „Installationsvorgang“ abzuschließen. 🎜🎜2), Szenario 2: Privates gemeinsam genutztes Git-Paket 🎜🎜Es wird einige Code-/öffentliche Bibliotheken im Team geben, die zwischen verschiedenen Projekten im Team gemeinsam genutzt werden müssen, aber sie können sensible Inhalte enthalten. 🎜🎜Wir können die abhängigen Pakete einfach in einem privaten Git-Repository hosten und dann die Git-URL in den Abhängigkeiten speichern. npm ruft direkt den Git-Befehl des Systems auf, um den Inhalt des Pakets aus dem Git-Warehouse in node_modules abzurufen. 🎜🎜Das von npm unterstützte Git-URL-Format: 🎜
npm run scipt1 && npm run script2🎜Sie können # nach dem Git-Pfad verwenden, um einen bestimmten Git-Zweig/Commit/Tag anzugeben, oder #semver:, um einen bestimmten Semver-Bereich anzugeben.🎜🎜Zum Beispiel: 🎜
npm run script1 & npm run script2🎜3), Szenario 3: Reparatur von Open-Source-Paketproblemen🎜🎜Zu diesem Zeitpunkt können wir das Verzeichnis node_modules manuell eingeben, um den entsprechenden Paketinhalt zu ändern. Möglicherweise wird das Problem durch Ändern einer Codezeile behoben. Aber dieser Ansatz ist sehr unklug! 🎜🎜 Lösung: 🎜🎜Forken Sie die Git-Bibliothek des Originalautors, beheben Sie das Problem in Ihrem eigenen Repo und ändern Sie dann die entsprechenden Abhängigkeiten in Ihre eigene reparierte Version der Git-URL, um das Problem zu lösen. 🎜🎜🎜3. So funktioniert die npm-Installation 🎜🎜🎜npm i wird ausgeführt und alle abhängigen Pakete werden in node_modules angezeigt. Entwickler achten nicht auf die strukturellen Details des Ordners node_modules, sondern konzentrieren sich auf die referenzierten Abhängigkeitspakete im Geschäftscode. 🎜🎜Das Verständnis der node_modules-Struktur hilft uns, besser zu verstehen, wie npm funktioniert. Änderungen und Verbesserungen von npm2 bis npm5. 🎜🎜🎜3.1 npm2🎜🎜🎜npm2 verwendet bei der Installation von Abhängigkeitspaketen eine einfache rekursive Installationsmethode. Jedes Paket verfügt über ein eigenes Abhängigkeitspaket, und die Abhängigkeiten jedes Pakets werden in seinen eigenen node_modules installiert. Die Abhängigkeitsbeziehungen bilden Schicht für Schicht den gesamten Abhängigkeitsbaum. Dieser Abhängigkeitsbaum entspricht eins zu eins dem Dateistrukturbaum das Dateisystem. 🎜🎜Der bequemste Weg zum Abhängigkeitsbaum besteht darin,
npm ls
im Stammverzeichnis auszuführen. 🎜🎜Vorteile: 🎜🎜🎜🎜Offensichtliche hierarchische Struktur, einfach für dummes Management. 🎜🎜🎜🎜Nachteile:🎜
Bei komplexen Projekten ist die Verzeichnisstruktur möglicherweise zu tief und der tiefe Dateipfad ist zu lang, was dazu führt, dass der Dateipfad im Fensterdateisystem nicht länger als 260 Zeichen sein darf.
Einige Pakete, die von mehreren Paketen abhängig sind, werden an vielen Stellen wiederholt installiert, was zu großer Redundanz führt.
3.2 npm3
Das Verzeichnis node_modules von npm3 wurde in eine flachere hierarchische Struktur geändert. npm3 durchläuft während der Installation den gesamten Abhängigkeitsbaum und berechnet die sinnvollste Ordnerinstallationsmethode. Alle Pakete, die wiederholt abhängig sind, können neu installiert werden.
Für npm sind Pakete mit demselben Namen und unterschiedlichen Versionen zwei unabhängige Pakete. Die Abhängigkeitsbaumstruktur von
npm3 entspricht nicht mehr eins zu eins der Ordnerhierarchie.
3.3 npm5
Folgen Sie der Installationsmethode für flache Abhängigkeitspakete von npm3. Die größte Änderung ist die Hinzufügung der Datei package-lock.json.
Package-lock.json-Funktion: Sperren Sie die Abhängigkeitsinstallationsstruktur und stellen Sie fest, dass die Dateihierarchiestruktur des Verzeichnisses node_modules eins zu eins der JSON-Struktur entspricht.
npm5 generiert nach der Ausführung von npm i standardmäßig die Datei package-lock.json und übermittelt sie an die Git/SVN-Codebasis.
Verwenden Sie zum Upgrade nicht Version 5.0.
Hinweis: Wenn in npm 5.0 die Paketsperrdatei bereits vorhanden ist und Sie manuell eine Abhängigkeit zur Datei package.json hinzufügen und dann npm install ausführen, wird die neue Abhängigkeit nicht in node_modules, package-lock.json installiert wird nicht entsprechend aktualisiert.
Führt in die Kenntnisse im Zusammenhang mit der Abhängigkeitspaket-Upgrade-Verwaltung ein.
4.1 Semver der semantischen Version
Ein wichtiges Merkmal des npm-Abhängigkeitsmanagements ist die Verwendung der Spezifikation der semantischen Version (Semver) als Versionsverwaltungslösung.
Die semantische Versionsnummer muss drei Zahlen enthalten, das Format ist: Major.Minor.Patch. Es bedeutet: Hauptversionsnummer.
Wir müssen die Semver-Konvention in Abhängigkeiten verwenden, um die Versionsnummer oder den Versionsbereich des erforderlichen Abhängigkeitspakets anzugeben.
Üblicherweise verwendete Regeln sind wie folgt:
Semver-Semantikversion
1 Zwei beliebige Regeln werden mit einem Leerzeichen verbunden, um die „UND“-Logik darzustellen, die den Schnittpunkt der beiden Regeln darstellt.
Zum Beispiel kann >=2.3.1 =2.3.1 und
2 Alle zwei Regeln werden mit || verbunden, um die „ODER“-Logik auszudrücken, die die Vereinigung der beiden Regeln darstellt.
wie ^2 >=2.3.1 || ^3 >3.2
3 Eine intuitivere Möglichkeit, den Versionsnummernbereich auszudrücken
4. Nach MAJOR.MINOR.PATCH anhängen – gefolgt von durch Punkte getrennten Tags. Als Vorabversions-Tags gelten sie normalerweise als instabil und werden nicht empfohlen Produktion. Version verwendet.
4.2 Abhängigkeitsversions-Upgrade
Nach der Installation eines Abhängigkeitspakets wird eine neue Version veröffentlicht. Wie verwende ich npm, um die Version zu aktualisieren?
Fazit zur Verwendung von npm3:
Fazit zur Verwendung von npm5:
4.3 geändert. Best Practice
Mein häufig verwendeter Knoten ist 8.11.x, npm ist 5.6 .
升级依赖包:
降级依赖包:
删除依赖包:
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 教程!
Das obige ist der detaillierte Inhalt vonDieser Artikel hilft Ihnen, die Prinzipien von npm zu verstehen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!