npm包的釋出和管理
npm包管理
npm
其實是Node.js
的包管理工具(node package manager
)。
為啥我們需要一個包管理工具呢?因為我們在Node.js
上開發時,會用到很多別人寫的JavaScript
程式碼。如果我們要使用別人寫的某個包,每次都根據名稱搜尋一下官方網站,下載程式碼,解壓,再使用,非常繁瑣。於是一個集中管理的工具應運而生:大家都把自己開發的模組打包後放到npm
官網上,如果要使用,直接通過npm安裝就可以直接用,不用管程式碼存在哪,應該從哪下載。
更重要的是,如果我們要使用模組A,而模組A又依賴於模組B,模組B又依賴於模組C和模組D,npm
可以根據依賴關係,把所有依賴的包都下載下來並管理起來。否則,靠我們自己手動管理,肯定既麻煩又容易出錯。
npm的基礎使用
npm
的指令其實常用的並不多官方文件;列出來如下面:
-
access
Set access level on published packages -
``` Add a registry user account ```adduser
-
``` Run a security audit ```audit
-
``` Display npm bin folder ```bin
-
``` Bugs for a package in a web browser maybe ```bugs
-
``` Build a package ```build
-
``` REMOVED *已刪除* ```bundle
-
``` Manipulates packages cache ```cache
-
``` Install a project with a clean slate ```ci
-
``` Tab Completion for npm ```completion
-
``` Manage the npm configuration files ```config
-
``` Reduce duplication ```dedupe
-
``` Deprecate a version of a package ```deprecate
-
``` Modify package distribution tags ```dist-tag
-
``` Docs for a package in a web browser maybe ```docs
-
``` Check your environments ```doctor
-
``` Edit an installed package ```edit
-
``` Browse an installed package ```explore
-
``` Search npm help documentation ```help-search
-
``` Get help on npm ```help
-
``` Manage registry hooks ```hook
-
``` create a package.json file ```init
-
``` Install a project with a clean slate and run tests ```install-ci-test
-
``` Install package(s) and run tests ```install-test
-
``` Install a package ```install
-
``` Symlink a package folder ```link
-
``` Log out of the registry ```logout
-
``` List installed packages ```ls
-
``` javascript package manager ```npm
-
``` Check for outdated packages ```outdated
-
``` Manage package owners ```owner
-
``` Create a tarball from a package ```pack
-
``` Ping npm registry ```ping
-
``` Display prefix ```prefix
-
``` Change settings on your registry profile ```profile
-
``` Remove extraneous packages ```prune
-
``` Publish a package ```publish
-
``` Rebuild a package ```rebuild
-
``` Open package repository page in the browser ```repo
-
``` Restart a package ```restart
-
``` Display npm root ```root
-
``` Run arbitrary package scripts ```run-script
-
``` Search for packages ```search
-
shrinkwrap
``` Lock down dependency versions for publication ``` -
``` Mark your favorite packages ```star
-
``` View packages marked as favorites ```stars
-
``` Start a package ```start
-
``` Stop a package ```stop
-
``` Manage organization teams and team memberships ```team
-
``` Test a package ```test
-
``` Manage your authentication tokens ```token
-
``` Remove a package ```uninstall
-
``` Remove a package from the registry ```unpublish
-
``` Update a package ```update
-
``` Bump a package version ```version
-
``` View registry info ```view
-
``` Display npm username ```whoami
init
初始化建立package.json
npm init [--force|-f|--yes|-y|--scope]
npm init <@scope> (same asnpx <@scope>/create
)
npm init [<@scope>/]<name> (same asnpx [<@scope>/]create-<name>
)
search
搜尋檢視遠端npm
相關資源包資訊
npm search [-l|--long] [--json] [--parseable] [--no-description] [search terms ...]
aliases: s, se, find
install
可以是說是install
是最為常見的命令官方介紹,
npm install (with no args, in package dir)
npm install [<@scope>/]<name>
npm install [<@scope>/]<name>@<tag>
npm install [<@scope>/]<name>@<version>
npm install [<@scope>/]<name>@<version range>
npm install <git-host>:<git-user>/<repo-name>
npm install <git repo url>
npm install <tarball file>
npm install <tarball url>
npm install <folder>alias: npm i
common options: [-P|--save-prod|-D|--save-dev|-O|--save-optional] [-E|--save-exact] [-B|--save-bundle] [--no-save] [--dry-run]In global mode (ie, with -g or --global appended to the command), it installs the current package context (ie, the current working directory) as a global package. The -g or --global argument will cause npm to install the package globally rather than locally.
The -f or --force argument will force npm to fetch remote resources even if a local copy exists on disk.
上面的還介紹已經很詳細了,所以這裡只是講一下npm install packageName [|--save |--save-prod|--save-dev]
的區別;
- npm install babel
npm5以前,會把X包安裝到node_modules目錄中,不會修改package.json的dependencies欄位,之後執行npm install命令時,不會自動安裝X - npm install babel
npm5以後,會把X包安裝到node_modules目錄中,會修改package.json的dependencies欄位,之後執行npm install命令時,會自動安裝X, 線上環境時會被安裝 - npm install babel -P
-P, --save-prod: Package will appear in your dependencies. This is the default unless -D or -O are present. Package will appear in your dependencies, With the --production flag (or when the NODE_ENV environment variable is set to production), npm will install modules listed in dependencies. - npm install babel -D
Package will appear in your devDependencies,With the --production flag (or when the NODE_ENV environment variable is set to production), npm will not install modules listed in devDependencies. 會把X包安裝到node_modules目錄中,會在package.json的devDependencies屬性下新增X,之後執行npm install命令時,會自動安裝X到node_modules目錄中,之後執行npm install –production或者註明NODE_ENV變數值為production時,不會自動安裝X到node_modules目錄中
update
升級某個資源包或者全部資源包到某一個版本或者匹配的最新版本。
npm update [-g] [<pkg>...]
aliases: up, upgrade
uninstall
移除某個資源包
npm uninstall [<@scope>/]<pkg>[@<version>]... [-S|--save|-D|--save-dev|-O|--save-optional|--no-save]
aliases: remove, rm, r, un, unlink
npm包建立、編寫、測試、維護
Node
出現之前,JavaScript
是缺少包結構的。CommonJS
致力於改變這種現狀,於是定義了包的結構規範。而NPM
的出現則是為了在CommonJS
規範的基礎上,實現解決包的安裝解除安裝,依賴管理,版本管理等問題。require
的查詢機制明瞭之後,我們來看一下包的細節。
一個符合CommonJS
規範的包應該是如下這種結構:
- 一個
package.json
檔案應該存在於包頂級目錄下 - 二進位制檔案應該包含在
bin
目錄下(可選) -
JavaScript
程式碼入庫是index.js
,其他包含在lib
目錄下 - 文件應該在
doc
目錄下(可選) - 單元測試應該在
test
目錄下(可選)
初始化包
-
建立包的根目錄
``` mkdir testpackage ``` -
初始化
``` npm init // 需要進行一些基本配置 ```
編寫
-
建立入口檔案
``` touch index.js ``` -
編寫程式碼
``` const updateQueryString = function(url, key, value) { let urlParts = url.split('#'), hash = '', uri = urlParts.shift(), re = new RegExp(`([?&])${key}=.*?(&|$)`, 'i'), separator = uri.indexOf('?') !== -1 ? '&' : '?', encodeKey = encodeURIComponent(key), encodeValue = encodeURIComponent(value); urlParts.length > 0 && (hash = `#${urlParts.join('#')}`); if (uri.match(re)) { return uri.replace(re, `$1${encodeKey}=${encodeValue}$2`) + hash; } else { return `${uri}${separator}${encodeKey}=${encodeValue}${hash}`; } }; // 最後的匯出部分 module.exports = { updateQueryString }; ``` -
測試
-
建立包的根目錄
``` npm i mocha -D // 安裝測試庫 npm i chai -D // 安裝斷言庫 mkdir test cd test touch index.test.js ``` -
編寫測試程式碼
``` const utils = require('./../index.js'); const expect = require('chai').expect; let { updateQueryString } = utils; describe('updateQueryString函式的測試', function() { it('https://test.com/path?test=11 修改test引數為22 應該等於 https://test.com/path?test=22', function() { expect(updateQueryString('https://test.com/path?test=11', 'test', 22)).to.be.equal('https://test.com/path?test=22'); }); }); ``` -
執行測試
``` cd .. ./node_modules/mocha/bin/mocha ```
-
npm包的釋出
- 註冊賬號npm官網
- 終端執行
npm login
,輸入使用者名稱和密碼 、郵箱 -
npm publish
釋出
Organization包
我們經常可以看到@angular
、@ionic
他們的包, 都可以以@開頭,那麼我們的可不可以,原來angular、ionic
都屬於一個組織(Organization
)只有新建立一個Organization
組織之後,才能建立@testorg/testpackname
這樣的包!!!
那麼我們就可以去官網上建立我們的Organization
,命名之後,官方步驟,
-
初始化
``` npm init --scope=<your_org_name> ```npm init foo -> npx create-foo
npm init @usr/foo -> npx @usr/create-foo
npm init @usr -> npx @usr/create - 修改
package.json
裡面的name
欄位為@your_org_name/<pkg_name>
-
釋出
``` npm publish --access public // 公開包釋出 ```
npm包支援esmodule
使用babel來進行一些現代JavaScript的支援,
-
建立配置檔案
``` touch .babelrc ``` - 安裝先關包
-
配置babel
``` { "presets": [ [ "@babel/preset-env", { "targets": { "browsers": [ "last 2 versions", "safari >= 7" ], "chrome": 52, "node": "6.10.0" }, "modules": "commonjs", "useBuiltIns": "usage" } ] ], "plugins": [ "@babel/plugin-syntax-dynamic-import", "@babel/plugin-syntax-import-meta", "@babel/plugin-proposal-class-properties", "@babel/plugin-proposal-json-strings", [ "@babel/plugin-proposal-decorators", { "legacy": true } ], "@babel/plugin-proposal-function-sent", "@babel/plugin-proposal-export-namespace-from", "@babel/plugin-proposal-numeric-separator", "@babel/plugin-proposal-throw-expressions", "@babel/plugin-proposal-export-default-from", "@babel/plugin-proposal-logical-assignment-operators", "@babel/plugin-proposal-optional-chaining", [ "@babel/plugin-proposal-pipeline-operator", { "proposal": "minimal" } ], "@babel/plugin-proposal-nullish-coalescing-operator", "@babel/plugin-proposal-do-expressions" ] } ``` -
編譯
``` ./node_modules/.bin/babel src -d lib ```
最後的測試程式碼地址test-demo-npm