diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d8b83df --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +package-lock.json diff --git a/docs/npm/basic.md b/docs/npm/basic.md index 0089d93..ea94080 100644 --- a/docs/npm/basic.md +++ b/docs/npm/basic.md @@ -295,7 +295,7 @@ $ npm install --save-dev babel-cli@6 babel-preset-es2015@6 运行上面的脚本,会将`source`目录里面的ES6源码文件,转为`distribution`目录里面的ES5源码文件。然后,在项目根目录下面创建两个文件`.npmignore`和`.gitignore`,分别写入以下内容。 -```javascrip +```javascript // .npmignore source diff --git a/docs/npm/npm-create.md b/docs/npm/npm-create.md new file mode 100644 index 0000000..29115c4 --- /dev/null +++ b/docs/npm/npm-create.md @@ -0,0 +1,11 @@ +# npm create 命令 + +npm create 是 npm init 命令的一个别名。 + +不过,如果执行`npm create xyz`,实际上执行的是`npx create-xyz`。它会暂时性安装`create-xyz`,然后执行它的`package.json`里面定义的脚本命令。 + +下面是一些例子。 + +- `npm create svelte@latest` +- `npm create vue@latest` +- `npm init react-app my-app` diff --git a/docs/npm/npm-exec.md b/docs/npm/npm-exec.md new file mode 100644 index 0000000..c3f8500 --- /dev/null +++ b/docs/npm/npm-exec.md @@ -0,0 +1,38 @@ +# npm exec 命令 + +`npm exec`用来执行某个 npm 模块的内部命令,不管该模块在本地还是在远程。它有一个别名`x`,即`npm exec`等同于`npm x`。 + +该命令与`npx`命令的作用类似,但是使用上有所不同。 + +`npx`会将所有参数原样传入模块内部。 + +```bash +$ npx foo@latest bar --param=@npmcli/foo +# 等同于 +$ foo bar --param=@npmcli/foo +``` + +`npm exec`则需要使用`--`分隔符,指定所要执行的命令和它的参数。 + +```bash +$ npm exec -- foo@latest bar --param=@npmcli/foo +# 等同于 +$ foo bar --param=@npmcli/foo +``` + +`npm exec`也可以用`--package`参数指定模块。 + +```bash +$ npm exec --package=foo -- bar --bar-argument +# 等同于 +$ npx --package=foo bar --bar-argument +``` + +`--call`或`-c`参数用来指定执行的整个命令。 + +```bash +$ npm exec -c 'eslint && say "hooray, lint passed"' +# 等同于 +$ npx -c 'eslint && say "hooray, lint passed"' +``` + diff --git a/docs/npm/npm-init.md b/docs/npm/npm-init.md new file mode 100644 index 0000000..bb2ab49 --- /dev/null +++ b/docs/npm/npm-init.md @@ -0,0 +1,54 @@ +# npm init 命令 + +`npm init`命令的作用,是生成`package.json`文件。它的别名是`create`。 + +新建一个目录,作为模块的开发目录。进入该目录,执行`npm init`,屏幕上会依次出现一些问题,要求用户回答。用户回答以后,就会生成`package.json`文件。 + +```bash +$ npm init +``` + +如果觉得回答问题太麻烦,想使用`package.json`的默认值,那就使用`--yes`或`-y`参数。 + +```bash +$ npm init --yes +# 或者 +$ npm init -y +``` + +如果想设置`package.json`的一些默认值(作者、Email、许可证),需要提前用`npm set`命令设置。 + +```bash +$ npm set init-author-email "example-user@example.com" +$ npm set init-author-name "example_user" +$ npm set init-license "MIT" +``` + +`npm init`也可以格式化创建项目。 + +```bash +$ npm init foo +# 等同于 +$ npm exec create-foo +``` + +上面的`npm init foo`这条命令,会去执行`create-foo`这个模块(`package.json`的`bin`属性)。 + +举例来说,如果要执行`create-react-app`创建一个 React 项目,可以执行下面的命令。 + +```bash +$ npm init react-app ./my-react-app +``` + +这种用法时,往往使用`npm init`命令的别名`npm create`。 + +```bash +$ npm create xyz + +// 等同于 +$ npm init xyz + +// 等同于 +$ npx create-xyz +``` + diff --git a/docs/npm/npm-link.md b/docs/npm/npm-link.md new file mode 100644 index 0000000..fb63fe0 --- /dev/null +++ b/docs/npm/npm-link.md @@ -0,0 +1,44 @@ +# npm link 命令 + +有时候,我们在本地修改了一些模块,想先测试这些修改是否有效。那么,怎么才能让依赖于该模块的应用,能够加载这些本地模块呢? + +一种方法是使用`npm install`的`--save`参数。 + +```bash +$ npm install --no-save <模块的本地路径h> +``` + +上面的命令会从本地目录安装指定模块,但是不写入`package.json`。这样就可以让应用加载本地模块。 + +另一种则是使用`npm link`命令,在`node_modules`目录里面建立一个符号链接,链接到本地模块。 + +它分成两步,第一步先在本地模块的目录里,执行`npm link`。 + +```bash +$ npm link +``` + +第二步是到你的应用目录,执行`npm link <本地模块名>`,在`node_modules`目录里面产生本地模块的符号链接。 + +```bash +$ npm link <本地模块名> +``` + +也可以将上面两步合二为一,在应用目录里面,直接链接本地模块的路径。 + +```bash +$ npm link <本地模块的路径> +``` + +等到测试完毕,再用`npm unlink`命令,先在应用目录删除符号链接。 + +```bash +$ npm unlink --no-save <本地模块名> +``` + +再到本地模块的目录里面,执行`npm unlink`。 + +```bash +$ npm unlink +``` + diff --git a/docs/npm/npm-tag.md b/docs/npm/npm-tag.md new file mode 100644 index 0000000..f7bc4ee --- /dev/null +++ b/docs/npm/npm-tag.md @@ -0,0 +1,46 @@ +# npm tag + +npm 允许为版本添加标签,方便用户安装特定版本。只要指定标签,就可以安装该标签下的最新版本。 + +发布模块时,如果不指定 tag,默认使用`latest`。安装时也是如此,不指定版本时,npm 默认安装`latest`标签对应的最新版本。 + +如果指定 tag,发布时会将该 tag 指向最新发布的版本。用户如果想安装该版本,需要在安装时指定 tag。 + +```bash +$ npm publish --tag beta +``` + +上面示例中,新发布版本的标签是`beta`。 + +下面的命令为已发布的版本指定标签。注意,这一步之前不需要先移除已经存在的标签。 + +```bash +# 语法 +$ npm dist-tag add [PackageName]@[Version] [Tag] + +# 例子 +$ npm dist-tag add foo-package@0.0.0 latest +``` + +安装时指定标签。 + +```bash +$ npm install @ +# 或者 +$ npm install --tag +``` + +下面的命令查看所有 tag 和对应的版本。 + +```bash +$ npm dist-tag ls +# 或者 +$ npm view [模块名] dist-tags +``` + +删除已经发布的标签。 + +```bash +$ npm dist-tag rm [PackageName] [Tag] +``` + diff --git a/docs/npm/npm-token.md b/docs/npm/npm-token.md new file mode 100644 index 0000000..506bfb8 --- /dev/null +++ b/docs/npm/npm-token.md @@ -0,0 +1,26 @@ +# npm token + +`npm token`命令用来管理认证令牌。 + +`npm token list`命令列出所有激活的认证令牌。 + +```bash +$ npm token list +``` + +上面命令的返回结果,以表格形式显示。如果加上`--json`参数,则返回 JSON 格式;加上`--parseable`参数,返回 Tab 键分隔的数据。 + +`npm token create`命令生成一个新的认证令牌。 + +```bash +$ npm token create +``` + +`--read-only`参数用来生成只读令牌,默认是读写令牌。`--cidr=`参数用来指定令牌生效的 IP 地址范围。 + +`npm token revoke`命令收回令牌。 + +```bash +$ npm token revoke +``` + diff --git a/docs/npm/npm-update.md b/docs/npm/npm-update.md new file mode 100644 index 0000000..24187a1 --- /dev/null +++ b/docs/npm/npm-update.md @@ -0,0 +1,20 @@ +# npm update + +更新所有依赖项。 + +```bash +$ npm update +``` + +更新单个依赖。 + +```bash +$ npm update xml2js +``` + +同时更新 package.json 里面每个依赖的版本号。 + +```bash +$ npm update --save +``` + diff --git a/docs/npm/npm-version.md b/docs/npm/npm-version.md new file mode 100644 index 0000000..6ecf66c --- /dev/null +++ b/docs/npm/npm-version.md @@ -0,0 +1,143 @@ +# npm version + +`npm version`用来指定模块的版本,然后会将新的版本号写入`package.json`和`package-lock.json`。 + +它的命令行用法如下。 + +```bash +npm version [ + | + major | minor | patch | premajor | preminor | prepatch | prerelease | + from-git +] +``` + +上面可以归纳为三种用法。 + +(1)``:自己指定版本号。 + +(2)七个版本关键字:patch,minor,major,prepatch,preminor,premajor,prerelease。这时原有版本号,会在相应的位置增加1。 + +`major`:规则如下。 + +(1)如果没有预发布号,则增加主版本号,并将次版本号和预发布号设为`0`。 + +```bash +# 版本号从 3.1.0 变为 4.0.0 +$ npm version major +``` + +(2)如果有预发布号,且次版本号和补丁号都为`0`,则不升级主版本号,只去掉预发布号。 + +```bash +# 版本号从 4.0.0 变为 5.0.0-0 +$ npm version premajor + +# 版本号从 5.0.0-0 变为 5.0.0 +$ npm version major +``` + +(3)如果有预发布号,且次版本号和补丁号都不为`0`,则增加主版本号,将次版本号和补丁号都置为`0`,并去掉预发布号。 + +```bash +# 版本号从 5.0.0-0 变为 5.1.0-0 +$ npm version preminor : 5.0.0-0–> 5.1.0-0 + +# 版本号从 5.1.0-0 变为 6.0.0 +$ npm version major +``` + +`minor`:规则如下。 + +(1)如果没有预发布号,则增加次版本号,并将补丁号设为`0`。 + +```bash +# 版本号从 2.0.1 变为 2.1.0 +$ npm version minor +``` + +(2)如果有预发布号,且补丁号为`0`,则去掉预发布号,其他不变。 + +```bash +# 版本号从 2.1.0 变为 3.0.0-0 +$ npm version premajor + +# 版本号从 3.0.0-0 变为 3.0.0 +$ npm version minor +``` + +(3)如果有预发布号,且补丁号不为`0`,则去掉预发布号,增加次版本号,补丁号设为`0`。 + +```bash +# 版本号从 3.0.0 变为 3.0.1-0 +$ npm version prepatch + +# 版本号从 3.0.1-0 变为 3.1.0 +$ npm version minor +``` + +`patch`:如果预发布号,则去掉预发布后,其他保持不变;如果没有预发布号,则升级补丁号。 + +```bash +# 版本号从 2.0.0-0 变为 2.0.0 +$ npm version patch + +# 版本号从 2.0.0 变为 2.0.1 +$ npm version patch +``` + +`premajor`:增加主版本号,将次版本号和补丁号都设为`0`,增加预发布号为`0`。 + +```bash +# 版本号从 1.1.0-0 变为 2.0.0-0 +$ npm version premajor +``` + +`preminor`:增加次版本号,补丁号设为`0`,预发布号设为`0`。 + +```bash +# 版本号从 1.0.2-0 变为 1.1.0-0 +$ npm version preminor +``` + +`prepatch`:增加补丁号,同时预发布号设为`0`。 + +```bash +# 版本号从 1.0.1-1 变为 1.0.2-0 +$ npm version prepatch +``` + +`prerelease`:如果没有预发布号,则增加补丁号,同时预发布号设为0;如果有预发布号,则预发布号增加1。 + +```bash +# 版本号从 1.0.0 变为 1.0.1-0 +$ npm version prerelease + +# 版本号从 1.0.1-0 变为 1.0.1-1 +$ npm version prerelease +``` + +(3)`from-git`:使用最新的 Git 标签,将其作为 npm 版本。 + +这个命令如果是在一个 Git 仓库里面运行,它会创造一个新的提交和标签。如果不希望生成标签,可以使用命令行参数`--no-git-tag-version`。 + +命令行参数`-m`或者`--message`可以指定提交信息。提交信息里面的`%s`参数会被替换成新的版本号。 + +```bash +$ npm version patch -m "Upgrade to %s for reasons" +``` + +## --pre-id + +`npm version`命令的`--pre-id`参数,可以指定预发布号的前缀。 + +```bash +$ npm version prerelease --pre-id rc +``` + +上面的命令会产生诸如`1.0.0-rc.0`的版本号。 + +## 参考链接 + +- [npm version 常用命令及用法示例](https://blog.csdn.net/weixin_40817115/article/details/90384398) + diff --git a/docs/npm/npm-view.md b/docs/npm/npm-view.md new file mode 100644 index 0000000..9a5aa13 --- /dev/null +++ b/docs/npm/npm-view.md @@ -0,0 +1,7 @@ +# npm view 命令 + +查看某个模块发布过的所有版本。 + +```bash +$ npm view [PackageName] versions +``` diff --git a/docs/npm/npm-whoami.md b/docs/npm/npm-whoami.md new file mode 100644 index 0000000..7733ceb --- /dev/null +++ b/docs/npm/npm-whoami.md @@ -0,0 +1,8 @@ +# npm whoami + +`npm whoami`命令返回当前登录的 npm 用户名。 + +```bash +$ npm whoami +``` + diff --git a/docs/npm/npx.md b/docs/npm/npx.md index 36f270d..6a8b206 100644 --- a/docs/npm/npx.md +++ b/docs/npm/npx.md @@ -4,7 +4,7 @@ npm 从5.2版开始,增加了 npx 命令,它有很多用处。 ![](https://www.wangbase.com/blogimg/asset/201902/bg2019020901.jpg) -Node 自带 npm 模块,所以可以直接使用 npx 命令。万一不能用,就要手动安装一下。 +Node 自带 npx 模块,所以可以直接使用 npx 命令。万一不能用,就要手动安装一下。 ```bash $ npm install -g npx @@ -49,7 +49,7 @@ $ npx ls $ npx create-react-app my-react-app ``` -上面代码运行时,npx 将`create-react-app`下载到一个临时目录,使用以后再删除。所以,以后再次执行上面的命令,会重新下载`create-react-app`。 +上面代码运行时,npx 将`create-react-app`下载到一个临时目录,然后自动执行`package.json`文件的`bin`字段指定的命令,执行以后再删除整个模块。所以,以后再次执行上面的命令,会重新下载`create-react-app`。 下载全局模块时,npx 允许指定版本。 @@ -65,6 +65,8 @@ $ npx uglify-js@3.1.0 main.js -o ./dist/main.js $ npx http-server ``` +npx 也可以执行`package.json`文件的`scripts`字段的命令,比如`npx foo dev`会执行`foo`模块的`scripts`字段的`dev`命令。 + ## `--no-install` 参数和`--ignore-existing` 参数 如果想让 npx 强制使用本地模块,不下载远程模块,可以使用`--no-install`参数。如果本地不存在该模块,就会报错。 diff --git a/docs/npm/package.json.md b/docs/npm/package.json.md index 1d04b34..d2eea83 100644 --- a/docs/npm/package.json.md +++ b/docs/npm/package.json.md @@ -1,5 +1,24 @@ # package.json +## 简介 + +npm 模块就是一个包含 package.json 文件的目录。 + +npm 模块分成 CommonJS 和 ES 两种格式。以下情况会以 ES 格式处理模块。 + +- 脚本后缀名为`.mjs`。 +- 脚本后缀名为`.js`,并且 package.json 文件的`type`字段的值为`module`。 +- `node`运行时带有`--input-type=module`,这时通过`--eval`或`--print`参数传入的代码字符串会被当作 ES 格式处理。 +- 脚本包含一些 ES 才有的语法特征,比如`import`语句、`export`语句、`import.meta`等。 + +以下情况会以 CommonJS 格式处理模块。 + +- 脚本后缀名为`.cjs`。 +- 脚本后缀名为`.js`,并且 package.json 文件的`type`字段的值为`commonjs`。 +- `node`运行时带有`--input-type=commonjs`,这时通过`--eval`或`--print`参数传入的代码字符串会被当作 CommonJS 格式处理。 + +其他情况下,Node.js 目前会以 CommonJS 格式处理模块,不过以后可能会改成 ES 格式。 + ## files 字段 `files`字段是一个数组,里面指定了一组文件。当模块发布到 NPM 网站时,这组文件会被包括。这个字段是可选的,如果没有指定内容,那么发布时所有文件都会被包括在内。如果`files`字段包含目录名,该目录里面的所有文件都会被计入。 @@ -53,3 +72,193 @@ 基本上,npm 会发布`files`字段指定的文件和目录,以及那些总是会包含在内的文件(比如`package.json`),然后再除去那些被其他规则排除的文件和目录。 [npm-packlist](https://github.com/npm/npm-packlist) 模块会列出所有将要打包发布的文件和模块。`npm pack`命令则会将那些将要发布的内容打成一个`tgz`压缩包,放在项目的根目录下。 + +## 字段 + +### main + +`main`字段指定模块的入口文件。比如,当前模块叫做`foo`,那么`require('foo')`时,加载哪个文件,由该字段指定。 + +`main`字段的值应该是一个相对路径,相对于模块的根目录进行计算。 + +如果没有指定`main`字段,那么默认的入口文件是模块根目录的`index.js`。 + +### exports + +`exports`字段也是指定模块的入口文件,它比`main`字段更强大。一般来说,优先使用`exports`字段,只有对 Node.js 10 和更低的版本,才推荐使用`main`字段。如果同时定义了`exports`和`main`两个字段,前者的优先级更高。 + +另外,`exports`字段只针对模块的消费者,并不在模块内部使用。 + +`exports`字段可以指定模块的唯一入口。 + +```javascript +{ + "exports": "./index.js" +} +``` + +上面字段中,`exports`指定了唯一入口,这意味着只能从模块名加载(`require('pkg')`),而不能从子路径加载,比如`require('pkg/subpath.js')`会报错。 + +为了保证模块的兼容性,常常同时定义`main`和`exports`。 + +```javascript +{ + "main": "./index.js", + "exports": "./index.js" +} +``` + +如果当前模块有多个入口,可以在`exports`字段里面一一指定。 + +```javascript +{ + "exports": { + ".": "./index.js", + "./submodule.js": "./src/submodule.js" + } +} +``` + +上面示例中,模块有两个入口,`.`表示通过模块名加载,`./submodule.js`表示通过模块的子路径加载,写成`import submodule from 'es-module-package/submodule.js';`。 + +这时,`exports`字段的值是一个对象。前面,`exports`的值为字符串,其实是简写形式。 + +```javascript +{ + "exports": "./index.js" +} +// 等同于 +{ + "exports": { + ".": "./index.js" + } +} +``` + +一般来说,对于同一个入口,模块作者最好同时指定有`.js`后缀名和没有`.js`后缀名两种情况。 + +```javascript +{ + "name": "my-package", + "exports": { + ".": "./lib/index.js", + "./lib": "./lib/index.js", + "./lib/index": "./lib/index.js", + "./lib/index.js": "./lib/index.js", + "./feature": "./feature/index.js", + "./feature/index": "./feature/index.js", + "./feature/index.js": "./feature/index.js", + "./package.json": "./package.json" + } +} +``` + +上面示例中,就同时指定了`./lib/index`和`./lib/index.js`两种入口形式。 + +`exports`字段也可以使用通配符。 + +```javascript +{ + "name": "my-package", + "exports": { + ".": "./lib/index.js", + "./lib": "./lib/index.js", + "./lib/*": "./lib/*.js", + "./lib/*.js": "./lib/*.js", + "./feature": "./feature/index.js", + "./feature/*": "./feature/*.js", + "./feature/*.js": "./feature/*.js", + "./package.json": "./package.json" + } +} +``` + +上面示例中,`exports`字段里面使用了通配符,指定了`lib`目录和`feature`目录下的所有入口对应的脚本文件。注意,入口包括`.js`后缀名和没有后缀名两种情况。另外,通配符`*`包括了多层目录的情况。 + +由于`exports`允许逐一指定不同入口对应的脚本文件,如果以后修改了脚本名称,可以只修改`exports`字段,不改变入口。另外,`exports`也排除某些内部脚本被加载。 + +```javascript +{ + "name": "my-package", + "exports": { + ".": "./lib/index.js", + "./feature/*.js": "./feature/*.js", + "./feature/internal/*": null + } +} +``` + +上面示例中,`exports`字段共有三个映射,其中第二个映射是指定加载`featrue`子目录下的脚本,而第三个映射则是排除`feature`目录的子目录`internal/*`下的脚本。 + +`exports`还支持条件加载,即不同的情况加载不同的脚本。 + +```javascript +{ + "exports": { + "import": "./index-module.js", + "require": "./index-require.cjs" + }, + "type": "module" +} +``` + +上面示例中,`import`指定 ES 格式加载时,入口文件为`./index-module.js`,CommonJS 格式加载时(`require`命令),入口文件为`./index-require.cjs`。 + +`exports`支持以下的条件关键词。 + +- node-addons:Node.js 的扩展 +- node:Node.js 环境 +- import:ES 格式加载时,特指使用`import`或`import()`加载时。 +- require:CommonJS 格式加载时。 +- default:其他条件都不匹配时的默认入口文件,总是放在最后。 + +下面是一个例子。 + +```javascript +{ + "exports": { + ".": "./index.js", + "./feature.js": { + "node": "./feature-node.js", + "default": "./feature.js" + } + } +} +``` + +`exports`还支持嵌套条件。 + +```javascript +{ + "exports": { + "node": { + "import": "./feature-node.mjs", + "require": "./feature-node.cjs" + }, + "default": "./feature.mjs" + } +} +``` + +注意,`exports`的映射不允许指向外部模块。 + +### imports + +`imports`字段用于模块的内部,为入口文件指定别名。它的路径总是从`#`开始,避免与实际路径相混淆。 + +```javascript +{ + "imports": { + "#dep": { + "node": "dep-node-native", + "default": "./dep-polyfill.js" + } + }, + "dependencies": { + "dep-node-native": "^1.0.0" + } +} +``` + +上面示例中,`imports`字段的意思是,加载`#dep`这个别名时(`import dep from "#def";`),对于 Node.js 加载外部模块`dep-node-native`,对于构建工具则会加载本地文件`./dep-polyfill.js`。 +

AltStyle によって変換されたページ (->オリジナル) /