在手头的项目中,由于业务所属范围的区分,团队之间负责的不同的业务,但是需要把这些业务整合到同一个侧边栏中,且需要使用相同的权限控制系统。
所以决定将侧边栏,以顶部状态栏抽离成一个 framework,发布到 npm ,其余子项目中共同发布。
但是我真的对 npm、node_module 的原理不是很熟悉。那么下面我来整理一番。
node_modules
使用 npm install XXX ,当前项目会自动生成 node_modules 文件夹。我们从它说起。
require
在 node 环境下输出 module ,得到如下结果。
╭─~/MyWorkspace/npm-module
╰─➤ node
> module
Module {
id: '<repl>',
exports: {},
parent: undefined,
filename: null,
loaded: false,
children: [],
paths:
[ '/Users/leiliao/MyWorkspace/npm-module/repl/node_modules',
'/Users/leiliao/MyWorkspace/npm-module/node_modules',
'/Users/leiliao/MyWorkspace/node_modules',
'/Users/leiliao/node_modules',
'/Users/node_modules',
'/node_modules',
'/Users/leiliao/.node_modules',
'/Users/leiliao/.node_libraries',
'/Users/leiliao/.nvm/versions/node/v10.15.3/lib/node' ] }
>
id 是表示 module 的唯一标示,我们把重点放到 paths 中,当我们使用 import 或者 require 命令时,会从 paths 中的如下路径依次寻找。
在当前项目根目录下 也就是 /MyWorkspace/npm-module
新建 node_modules
文件,然后在 node_modules
中新建 framework.js
文件 console.log('i am framework');
- node_modules
- framework.js
- index.js
在当前项目根目录下新建 index.js
, require('framework');
使用 node index
,输出 i am framework
, 使用 require 在 /Users/leiliao/MyWorkspace/npm-module/node_modules
找到了 framework.js
注意,如果在项目根目录和
node_modules
中同时存在 framework.js 会优先寻找node_modules
的文件。
- node_modules
- frameworkjs
- index.js
- frameworkjs
我们在 node_modules
创建一个 framework
文件夹,具体文件结构如下
- node_modules
- framework
- index.js
- start.js
- package.json
- index.js
- framework.js
使用 require('framework');
时, 如果 framework 文件夹中没有 package.json 文件,默认寻找当前文件夹 index.js ,如果有 package.json 文件,则寻找 "main"
字段中的路径。 比如 "main": "start.js",
package.json
来看一段 package 的文件。
{
"name": "npm-framework-test",
"version": "a.b.c",
"license": "MIT",
"description": "",
"author": "Leo",
"files": [
"src",
"public",
"dist",
"webpack"
],
"scripts": {
"build": "node build/build.js",
"start": "node build/dev-server.js"
"prepublish": "npm run build"
},
"main": "dist/index.js",
"types": "dist/index.d.ts",
"dependencies": {
"js-cookie": "^2.2.0",
"uuid": "^3.2.1"
},
"devDependencies": {
"autoprefixer": "^8.6.2",
"axios": "0.18.0",
"vue": "^2.5.16",
},
"peerDependencies": {
"axios": "^0.18.0",
"vue": "^2.5.16",
},
"engines": {
"node": ">= 6.0.0",
"npm": ">= 4.0.0"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}
对以上规则做出解释:
version
即 "版本号",当使用 npm i
时每一个模块都默认带有版本号,且版本号不能重复,以 "version": "a.b.c",
作为例子。
- a - major version 大版本的升级意味着与低版本的不兼容和重大升级,比如 vue2.x -> vue3.x
- b - minor version 小版本的升级在当前大版本下的 api 和 使用都是兼容的。
- c - patch 用于修复 bug 等。
"1.2.3-beta.2" - 带预发布关键词的,如 alpha, beta, rc, pr 等。
使用 npm i
具体安装某个模块。使用 npm outdated
npm outdated。
╭─~/MyWorkspace/npm-module
╰─➤ npm view vue versions
[
...
'2.0.0',
'2.0.1',
'2.0.2',
'2.0.3',
'2.0.4',
'2.0.5',
'2.0.6',
'2.0.7',
'2.0.8',
'2.1.0',
'2.1.1',
'2.1.2',
'2.1.3',
'2.1.4',
'2.1.5',
'2.1.6',
'2.1.7',
'2.1.8',
'2.1.9',
'2.1.10',
...
'2.2.0',
'2.2.3',
'2.2.4',
'2.2.5',
'2.2.6',
'2.3.0-beta.1',
'2.3.0',
'2.3.1',
'2.3.2',
...
'2.5.17-beta.0',
'2.5.17',
'2.5.18-beta.0',
'2.5.18',
'2.5.19',
'2.5.20',
'2.5.21',
'2.5.22',
...
'2.6.8',
'2.6.9',
'2.6.10' ]
首先需要在新建文件夹中
npm init
- npm i vue
╭─~/MyWorkspace/npm-module
╰─➤ npm i vue
+ vue@2.6.10
added 1 package from 1 contributor in 1.658s
我们可以看到默认安装了当前的最新版本。
- npm i vue@x.x.x
请使用npm uninstall 卸载重复的模块
指定版本进行安装
╭─~/MyWorkspace/npm-module
╰─➤ npm i vue@2.0.0
+ vue@2.0.0
added 1 package from 1 contributor in 1.986s
版本范围匹配
─~/MyWorkspace/npm-module
╰─➤ npm i vue@^2.1.1
npm WARN npm-module@1.0.0 No description
npm WARN npm-module@1.0.0 No repository field.
+ vue@2.6.10
added 1 package from 1 contributor in 1.38s
^2.1.1
安装 2.x.x
版本下的最高版本。
╭─~/MyWorkspace/npm-module
╰─➤ npm i vue@~2.1.1
npm WARN npm-module@1.0.0 No description
npm WARN npm-module@1.0.0 No repository field.
+ vue@2.1.10
added 1 package from 1 contributor in 1.716s
~2.1.1
安装 2.1.x
下的最高版本。
以下需要在
package.json
指定后,再使用npm i
进行安装。>=2.1.1
安装大于或等于2.1.1
的最高版本,<=2.1.1
同理。
license
模块的遵守的协议吃,常见的是MIT 。我们使用 阮一峰 老师的图。
peerDependencies
主要是用在 framework 的开发时,现有项目依赖于 framework 但是,某些特殊的依赖又不想被 framework 给限制在本版本当中(想使用更高的版本)。
比如 framework 中依赖 "axios": "0.18.1", 在 peerDependencies
中声明 "axios": "^0.18.1" 后,在实际项目中安装大于 0.18.1 的版本,framework会优先使用项目中的现有高版本。
使用
peerDependencies
时建议和devDependencies
配合使用,不要在第三方库中下载任何依赖。
npm or yarn
yarn 的出现只要是想解决早期 npm 下载速度和版本锁定的问题。但是现在 npm > 5 的版本中已经没有这些问题了。
需要注意的是:项目请使用单一管理包工具进行管理,不是使用 npm 和 yarn 混用。
发布
注册
npm 现有社区最大的平台就是 npmjs。我们一般会从这上面取轮子。
但是各个公司中会存在自己的 npm 库。在注册之前需要指定全局的 npm 仓库地址。
# 将registry 指定为需要发布的库
npm config set registry https://registry.npmjs.org/
# 可查看当前库的指向
npm config list
可以在 npm 官网 直接注册,也可以使用以下命令:
npm adduser
准备一个 npm 包
在上文中已经讲到 node_modules 如何能够被 require,这里使用 package.json 的方式。
如上文中的
package.json
, 其中scripts
字段中的prepublish
命令,可以在发布之前会prepublish
上传远程仓库
╭─~
╰─➤ npm login
Username: leolei
Password:
Email: (this IS public) 810364013@qq.com
Logged in as leolei on https://registry.npmjs.org/.
╭─~/MyWorkspace/npm-module
╰─➤ npm publish
npm notice
npm notice 📦 npm-framework-test@1.0.0
npm notice === Tarball Contents ===
npm notice 242B package.json
npm notice 47B index.js
npm notice === Tarball Details ===
npm notice name: npm-framework-test
npm notice version: 1.0.0
npm notice package size: 322 B
npm notice unpacked size: 289 B
npm notice shasum: ae09a4635fbcf27b34ad6c643038ceb7d20de8dc
npm notice integrity: sha512-50nWTjDIq03U8[...]t8ZW8iGTngnxQ==
npm notice total files: 2
npm notice
+ npm-framework-test@1.0.0
发布失败可能是包名重复,版本号重复,登录失败等原因。
登录 npm 就可以看到发布信息。