2019独角兽企业重金招聘Python工程师标准>>>
本文介绍如何发布一个包到 npmjs.org,包括创建、发布、撤回、更新、使用分支等等,以及其中 包含的一些小技巧。
0. 创建
创建一个包很简单,就是手动或者用 npm init
命令直接生成一个 package.json 文件,一个 包就算是创建出来了。剩下的就是给它添加内容而已了。
如果使用
npm init
命令配合-y
或者--yes
参数,可以不使用命令行交互模式,而 快速地创建一个 package.json 文件。
npm init -y
比如我这里创建出来的是:
name 字段默认是当前所在的目录名称。
{
"name": "test",
"version": "0.1.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "Angus.Fenying (https://fenying.net/)",
"license": "Apache-2.0"
}
什么,你说你创建出来是下面这样的?有些字段的初始值和我的不一样?
{ "name": "test", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC" }
别急,那是因为你没有设置 NPM 的一些默认配置。通过下面三条命令,可以设置创建新的 NPM 包时使用的默认属性。
npm config set init-author-name "Angus.Fenying" # 你的名称 npm config set init-author-email "[email protected]" # 你的邮箱 npm config set init-author-url "https://fenying.net" # 你的个人网页 npm config set init-license "Apache-2.0" # 开源授权协议名 npm config set init-version "0.1.0" # 版本号
1. 准备
现在你可以为 package.json 添加内容了,比如修改如下:
{
"name": "npm-tutorial-test-1",
"version": "0.1.0",
"description": "This is a test package for my NPM tutorial.",
"main": "index.js",
"scripts": {
"test": "echo hello"
},
"keywords": [
"test"
],
"author": "NPM Learner (https://sample.com/)",
"license": "MIT"
}
然后添加一个 README.md 文件,内容如下:
# NPM Tutorial Test 1
This is a test package for my NPM tutorial.
## License
This package is published under [MIT license](./LICENSE).
添加你的 LICENSE 文件(开源协议),以及一个 index.js 文件。
现在,一个最基本的包就是准备好了,等待发布了。
2. 发布
既然包已经准备好了,那么就可以发布了。
2.0. 修正下载源
如果你曾经为了加速 NPM 下载速度而修改了它的下载源,那么请改回去,不然是无法发布的。
检查方式:
npm config get registry
NPM 的官方源是 https://registry.npmjs.org/
,如果你看到控制台打印是这个,那么就没 问题了。而如果不是,那么请使用下面的命令修改回去:
npm config set registry https://registry.npmjs.org/
2.1. 创建并登录 npmjs.org 账户
如果你没有 npmjs.org 账户,那么先要创建一个,方法很简单:
npm adduser
根据提示创建即可。
记得验证邮箱,否则将无法发布包。
如果已经有 npmjs.org 账户了,请直接登录:
npm login
3. 真正的开始
上面的教程只是一个最简单的 DEMO,远远不能满足我们的发布需要,下面以一个需要编译的 TypeScript 包为例,看看如何发布和管理。
3.1. 合理的 package.json
先来看一个 package.json 的内容:
{
"name": "full-sample",
"version": "0.1.0",
"description": "A sample to learn NPM.",
"main": "./dist/index.js",
"scripts": {
"prepare": "npm run rebuild",
"build": "tsc -p .",
"rebuild": "npm run clean && npm run lint && npm run build",
"test": "echo See directory sources/tests",
"clean": "rm -rf dist",
"lint": "tslint --project tslint.json"
},
"keywords": [
"npm",
"sample"
],
"author": "NPM Learner (https://sample.com/)",
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": "git+https://github.com/learn-npm/full-sample.git"
},
"bugs": {
"url": "https://github.com/learn-npm/full-sample/issues"
},
"homepage": "https://github.com/learn-npm/full-sample#readme",
"types": "./dist/index.d.ts",
"typings": "./dist/index.d.ts",
"dependencies": {
"sequelize": "^4.24.0"
},
"devDependencies": {
"@types/node": "^8.0.51",
"@types/sequelize": "^4.0.79",
"typescript": "^2.6.1"
},
"engines": {
"node": ">=8.0.0"
}
}
假定项目的 TypeScript 源代码都在 sources 目录,编译结果都在 dist 目录。
上面与 DEMO 有什么区别呢?下面逐个字段解释:
-
homepage
指定项目的主页地址,如果没有一般可以使用项目的 GitHub 地址。
-
bugs.url
指定项目的 Bug 反馈地址,一般可以用项目的 GitHub Issue 地址。
-
repository.url
和repository.type
指定项目的源码仓库地址,可以指定是 git/cvs/svn。
-
main
指定 Node.js 中 require("moduel-name") 导入的默认文件。
-
keywords
指定项目的关键词,合理设置有利于让他人发现你的项目。
-
engines
设置项目对引擎的版本要求,比如 node、electron、vscode 等。
-
types
和typings
设置项目内置的 TypeScript 模块声明文件入口文件。
3.2. scripts 字段
scripts 字段作为单独一节解释,因为它是用于构建控制和发布控制的工具。
-
scripts.build
这个允许使用
npm run build
命令直接编译 TS 代码。 -
scripts.lint
这个允许使用
npm run lint
命令调用 TSLinter 对代码进行格式检查。 -
scripts.clean
这个允许使用
npm run clean
命令清理编译结果。 -
scripts.rebuild
这个允许使用
npm run rebuild
命令清理编译结果然后重新生成。 -
scripts.prepare
这个不是给我们用的,而是 NPM 提供的钩子,这个命令会在执行
npm publish
的时候 被调用。因此可以用这个钩子进行发布前构建。
3.3. Git 设置
Git 应当使用 .gitignore
文件忽略那些编译结果,以及 NPM 依赖的包文件:
/node_modules/
/dist/
*.log
3.4. NPM 包文件设置
NPM 打包发布的时候,会默认把当前目录下所有文件打包。但是 Git 仓库中,有些东西是不需要 发布到 NPM 的,因此我们需要使用一个文件 .npmignore
来忽略这些文件,常用配置如下:
/.git/
/.vscode/
/docs/
/node_modules/
.gitignore
.npmignore
tslint.json
tsconfig.json
*.log
这些文件都不是发布需要的内容,因此可以忽略。
3.5. 配置 tsconfig.json
前面说了,假定 TypeScript 的代码在 sources 目录下,编译的输出目录则为 dist。那么需要 在 tsconfig.json 里面通过 rootDir
和 outDir
选项指定。
其次,为了让其它 TypeScript 程序能正常使用你的包,你还应该设置 declaration
字段为 true
,使之自动生成 *.d.ts
文件。此处我们假定模块的入口是 index.js
,因此你必须 实现一个 index.ts
文件,作为模块的入口。
另外,如果要实现 TypeScript 源码调试,则需要开启 sourceMap
选项,以生成源码映射 文件。
3.6. 使用 tslint.json
现在,就可以愉快地编写代码了吗?不不不,为了规范代码,我们还需要配置下 TSLinter。通过 下面的命令初始化一个 tslint.json 文件。
npm install tslint -g
tslint --init
TS Linter 的规则非常多,而且默认规则限制非常严格,可以适当根据提示解除一些限制。比如 作者就采用了如下配置,仅供参考:
{
"defaultSeverity": "error",
"extends": [
"tslint:recommended"
],
"jsRules": {
},
"rules": {
"interface-name": false,
"trailing-comma": false,
"max-classes-per-file": false,
"ordered-imports": false,
"variable-name": false,
"prefer-const": false,
"member-ordering": false,
"no-bitwise": false,
"forin": false,
"object-literal-sort-keys": false,
"one-line": [false],
"object-literal-key-quotes": [false],
"no-string-literal": false,
"no-angle-bracket-type-assertion": false,
"only-arrow-functions": false,
"no-namespace": false,
"no-internal-module": false,
"unified-signatures": false,
"ban-types": false,
"no-conditional-assignment": false,
"radix": false
},
"rulesDirectory": []
}
如果想在 Visual Studio Code 里面实现 TS Linter 智能提示,则还需要安装 VSCode 的 TSLint 扩展。
现在,可以尽情地编写代码了。
4. 维护
4.1. 版本号维护
维护一个包,肯定是要进行包的版本升级的。如何进行呢?手动修改 package.json 的 version 字段是一个办法,但是显得有点 low。可以使用下面的命令:
npm version v0.1.0 # 版本号变成 0.1.0,即显式设置版本号。
npm version patch # 版本号从 0.1.0 变成 0.1.1,即修订版本号加一。
npm version minor # 版本号从 0.1.1 变成 0.2.0,即子版本号加一。
npm version major # 版本号从 0.2.0 变成 1.0.0,即主版本号加一。
但是,除此之外,还有四条命令,用于创建“预发布版本”,也就是非稳定版本。
npm version v1.2.3
# 版本号从 1.2.3 变成 1.2.4-0,就是 1.2.4 版本的第一个预发布版本。
npm version prepatch
# 版本号从 1.2.4-0 变成 1.3.0-0,就是 1.3.0 版本的第一个预发布版本。
npm version preminor
# 版本号从 1.2.3 变成 2.0.0-0,就是 2.0.0 版本的第一个预发布版本。
npm version premajor
# 版本号从 2.0.0-0 变成 2.0.0-1,就是使预发布版本号加一。
npm version prerelease
注意: version 命令默认会给你的 git 仓库自动 commit 一把,并打一个 tag。如果不想它动你的 git 仓库,你应该使用
--no-git-tag-version
参数,例如:npm --no-git-tag-version version patch
如果你想一劳永逸,那么可以使用如下 NPM 设置彻底禁止它:
npm config set git-tag-version false # 不要自动打 tag npm config set commit-hooks false # 不要自动 commit
4.2. 使用标签
以 TypeScript 为例,通过 npm info typescript
可以看到 dist-tags
字段有着五个 值,分别是 latest
, beta
, rc
, next
, insiders
,这些都是 dist-tag
,可以 称之为标签——你可以把它理解为 git 里面的分支。
有什么用呢?其实,我们平时用 npm install xxxxxx
的时候,是使用了一个潜在的选项 tag = latest
,可以通过 npm config list -l | grep tag
看到。
因此实际上是执行了 npm install xxxxxx@latest
。也就是安装了 latest
这个标签 对应的最新版本。
不同的标签可以有不同的版本,这就方便我们发表非稳定版本到 npm 上,与稳定版本分开。
默认是发布到 latest 标签下的。
例如 npm publish --tag dev
就可以发布一个版本到 dev 标签下。
4.3. 使用前缀
如果你使用过 AngularJS 或者 TypeScript,那么肯定知道有一些包的名字是这样的:
@types/node
@types/jquery
@angular/core
这里面的 @types/
和 @angular/
叫做包前缀(scope)。
作者起初以为使用包前缀也是收费的,后来仔细阅读了文档才发现公开的包可以免费使用 包前缀。
那我们怎么使用呢?很简单,首先在 package.json 里面把 name 字段加上一个前缀。
前缀必须是你 NPM 账户的用户名,比如你注册了一个用户名为 abc 的账户,则你只能使用
@abc/
为你的包前缀。
举个例子,将你的包名设置为 @abc/test
。
如果你要初始化一个带包前缀的包,则可以使用下面的命令。
npm init --scope=abc # 当然你还可以加上个 `-y` 快速创建。
或者你想每次都使用
@abc/
包前缀?加个设置即可:# 这样每次初始化新的 package.json,都将自动应用 @abc/ 包前缀。 npm config set scope abc
现在,可以发布你的包到 npmjs.org
了。哦不,别忘了一点:
官方文档表示:所有带前缀的包,在发布的时候,默认都是发布为私有包。
这意味着你不能就这么发布,因为你(可能)不是付费用户,不能发布私有的包。那怎么办呢?别 担心,npm publish
命令还有一个参数 --access
,通过这个参数可以指定发布的是公共包 还是私有包。因此,只要用下面的命令就可以发布一个公共的,带包前缀的包了:
npm publish --access=public
(完)