前言
最近在研究組件發佈,配到一些相關問題,算是整理一下。第一次寫的博客,同事也看的雲裏霧裏,開發組件的時候還是遇到一些問題,特此重新整理了一下,應該差不多相關的問題都涉及到了。
涉及內容
-
package.json 文件介紹 -
.npmrc 的作用及配置 -
公網 npm 組件發佈
package.json
概述
package.json 定義了當前項目中 npm包
之間的依賴關係和項目的一些配置信息(項目名稱,版本,描述,開發人,許可證 等等)。
當說到包管理器,就會遇到 yarn
和 npm
的選擇性問題。我是喜歡用 yarn
的,看看 github
上的開源項目,比如 vue
項目下就有 yarn.lock
文件,由此我猜測 yarn
可能更受歡迎一些,日常使用中我也是 yarn
用的比較多。
當我們 npm install
或 yarn install
會根據項目下的 package.json
解析依賴包之間的依賴關係然後從配置的 npm registry
( .npmrc
可以配置對應的 registry
)地址中搜索並下載包。
我們可以在 yarn.lock
或 package-lock.json
看到包從哪裏下載和依賴關係。
提交代碼的時候排除 node_modules
目錄,但是要提交 yarn.lock
或 package-lock.json
,用於鎖定項目依賴包的版本。並且升級包的時候不要手動改 package.json
中的版本號,要使用命令 yarn upgrade
或 npm upgrade
升級。
npm init
或 yarn init
可以生成 package.json。
{
"name": "@mflyyou/npm-description",
"version": "0.1.0",
"private": true,
"author": "張攀欽",
"license": "MIT",
"main":"index.js",
"keywords": [
"npm 搜索關鍵詞"
],
"publishConfig": {
"registry": "https://registry.npmjs.com/"
},
"repository": {
"type": "git",
"url": "http://git.com/項目git地址"
},
"files": [
"dist",
"src"
],
"bugs": {
"url": "http://localhost:8080//issues",
"email": "[email protected]"
},
"contributors": [
{
"name": "zhangpanqin",
"email": "[email protected]"
}
],
"scripts": {
"dev": "sh ./build/build.sh",
"npm-version": "npm -v",
"serve": "vue-cli-service serve"
},
"dependencies": {
"vue": "^2.5.21"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.3.0"
},
"peerDependencies":{}
}
package.json 字段介紹
name
name
字段作爲項目的名稱。比如 vue 中的一個組件 @vue/cli-plugin-babel
,前面這個 @vue
其實就當前包的 scope ,既命名空間。我們可以根據 scope
配置一些私有包 registry
,從而達到一些包來源於特定的地址。
registry=https://registry.npm.taobao.org/
@pay-plugin:registry=https://npm.udolphin.com
version
npm version [<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease [--preid=<prerelease-id>] | from-git]
'npm [-v | --version]' to print npm version
'npm view <pkg> version' to view a package's published version
'npm ls' to inspect current package/dependency versions
"version": "0.1.0”, 對應 major-minor-patch
# 更新 major 的位置,其餘位置爲 0
npm version major
# 更新 minor 的位置,major 不變,其餘位置爲 0
npm version minor
# 更新 patch 的位置,其餘位置不變
npm version patch
-
major 對應一次大的迭代,比如 vue 3.0 ts 重新,添加新的功能,更新 major 版本號 -
minor 對應小版本迭代,發生兼容舊版API的修改或功能添加時,更新 minor 版本號 -
patch 對應修訂版本號,一般針對 bug 修復時,修改 patch 的版本號
當你的項目需要發佈的時候,version 一定要和以前的不一樣,否則發佈不成功。
private
標識當前包是否私有,爲 true
時包不能發佈。
main
默認 index.js。指定 import 或 require 的時候加載的 js。
keywords
描述當前項目的關鍵字,用於檢索當前插件。
publishConfig
"publishConfig": {
"registry": "https://registry.npmjs.com/"
}
有的時候呢我們在 .npmrc
配置了別的 registry
,比如淘寶鏡像。我安裝依賴包的時候呢,想從淘寶鏡像安裝。發佈插件的時候想發佈到官網上。就可以在 publishConfig
中配置了。
files
指定發佈的依賴包,包含的文件,默認會忽略一些文件。也可以根目錄下創建 .npmignore 忽略一些文件。
scripts
配置一些執行腳本。比如說 npm run dev
就是運行 sh ./build/build.sh
。
"scripts": {
// 運行 shell 腳本
"dev": "sh ./build/build.sh",
"build": "npm -v",
// build 成功之後會執行 publish
"pub": "npm run build && npm publish"
}
dependencies
項目的開發依賴。key 爲模塊名稱,value 爲版本範圍。項目打包時會將這裏的依賴打包進去。
fly-npm 地址
fly-npm 和 fly-use-npm 已發佈。
注意,這裏也有個坑。比如我有兩個插件 fly-npm,fly-use-npm,fly-use-npm 中 dependencies 中依賴 fly-npm。我在 my-vue 項目開發的時候引入 fly-use-npm。我是可以直接 import fly-use-npm
項目可以正常運行。但是當你 import fly-npm
項目解析依賴會報錯。因爲只有在當前項目中 dependencies 引入的依賴纔可以被 import。
<template>
<div>
<button @click="clickTest">
測試
</button>
</div>
</template>
<script>
// fly-npm 只有在當前 my-vue 項目 dependencies 引入纔可以被 import
//import flyNpm from 'fly-npm';
import flyUseNpm from 'fly-use-npm';
export default {
name: 'TestPlugin',
methods: {
clickTest() {
flyUseNpm();
},
},
};
</script>
devDependencies
爲開發依賴,打包的時候不會打包進去。比如我們使用的 babel
webpak
等相關的插件,打包的時候,並不會被打包進去。
peerDependencies
在將這個之前,我們先來了解 npm 的樹形依賴是什麼意思。
我創建一個 vue 項目 my-vue 依賴 fly-use-npm(它依賴 fly-npm 1.0.0),fly-npm(2.0.0),在我們項目中可以看到。
當 my-vue
沒有引入 fly-npm 2.0.0
的時候,my-vue/node_modules/fly-npm
爲 1.0.0。
當我們引入 fly-npm 2.0.0
的時候,依賴關係圖如上圖,這就是樹形依賴。
下面是測試引入 fly-npm 2.0.0
之後的變化。
<template>
<div>
<button @click="clickTest">
測試
</button>
</div>
</template>
<script>
import flyUseNpm from 'fly-use-npm';
import flyNpm from 'fly-npm';
export default {
name: 'TestPlugin',
methods: {
clickTest() {
// 打印 2.0.0
console.log('fly-npm', flyNpm);
// 使用的是 1.0.0
flyUseNpm();
},
},
};
</script>
從上面我們可以看到,一個項目存在了兩份 fly-npm 的包。這樣打包的體積相應也會增大。爲了解決這個問題,引入了 peerDependencies
。
創建 vue 項目 my-vue,依賴 fly-use-npm(4.0.0,其 peerDependencies
是 fly-npm 1.0.0 )。
peerDependencies
添加的依賴包,不會(測試的 yarn 1.22.0,npm 6.13.7)自動安裝的。
當我在 my-vue 項目 yarn install
的時候,由於沒有引入 fly-npm
會報錯。
當我在項目中引入 fly-npm 2.0.0
安裝會在當前項目下,出現警告信息。
warning " > [email protected]" has incorrect peer dependency "[email protected]”。
當你開發一個組件,依賴特定包的版本就需要這樣處理。
// fly-use-npm
import flyNpm from 'fly-npm';
const obj = () => {
console.log('引用的 fly-npm 版本爲:', flyNpm.version);
if (flyNpm.version > 1) {
throw new Error('版本大於 1');
}
}
export default obj;
算是場景模擬,fly-npm 最新包是 2.0.0,這算是一個重大版本升級,可能存在不兼容 1.0.0 的東西。所以我在 fly-use-npm 推薦使用(peerDependencies)1.0.0。當我在實際用的時候呢,引入 fly-npm 2.0.0 ,發現某個功能依賴 fly-npm 2.0.0 報錯了,就需要想到是不是依賴包不兼容的問題了。
但是同時你還想用 fly-npm 2.0.0 的功能,那你只能去提交一個 pr 兼容 fly-npm 或者 fly-use-npm 。
這種情況很少會遇到,一般版本升級都會兼容以前的功能的,也不用太在意這樣的問題。
一般我們很少會遇到這種問題。github
上流行的庫也很少會用到 peerDependencies
。
.npmrc
package.json
中的依賴包從哪裏安裝呢?.npmrc 可以配置依賴包從哪裏安裝,也可以配置 npm 的一些別的配置。
.npmrc 配置文件優先級
-
項目配置文件: /project/.npmrc
-
用戶配置文件: ~/.npmrc
-
全局配置文件: /usr/local/etc/npmrc
-
npm 內置配置文件 /path/to/npm/npmrc
# 獲取 .npmrc 用戶配置文件路徑
npm config get userconfig
項目下 .npmrc 文件的優先級最高,可以每個項目配置不同的鏡像,項目之間的配置互不影響。我們也可以指定特殊的命名空間(scope)的來源。
以@thingjs-plugin
開頭的包從 registry=https://npm.udolphin.com
這裏下載,其餘全去淘寶鏡像下載。
registry=https://registry.npm.taobao.org/
@thingjs-plugin:registry=https://npm.udolphin.com
npm config set <key> <value> [-g|--global] //給配置參數key設置值爲value;
npm config get <key> //獲取配置參數key的值;
npm config delete <key> [-g|--global] //刪除置參數key及其值;
npm config list [-l] //顯示npm的所有配置參數的信息;
npm config edit //編輯用戶配置文件
npm get <key> //獲取配置參數 key 生效的值;
npm set <key> <value> [-g|--global] //給配置參數key設置值爲value;
沒有加 -g 配置的是用戶配置文件
-g 會配置到全局配置文件
npm 組件發佈流程
-
去 npm 官網申請賬號 -
添加賬號到你電腦 -
開發你的組件,使用 webpack,babel 處理 -
npm 發佈你的包
申請賬號
官網申請一個賬號,用於登錄和發佈組件。
在項目的根路徑下創建 .npmrc
配置文件,添加如下內容。
# 安裝包的時候,配置阿里鏡像
registry = https://registry.npm.taobao.org
在 package.json
中配置發佈源。
"publishConfig": {
"registry": "https://registry.npmjs.com/"
}
這樣下載依賴包會從淘寶鏡像下載,發佈依賴包會發布到 npm 官網去。
添加賬號到你電腦
添加賬號命令官網說明 npm adduser
# npm adduser [--registry=url] [--scope=@orgname] [--always-auth] [--auth-type=legacy]
npm adduser --registry=https://registry.npmjs.com/
運行上述命令,.npmrc 用戶配置文件生成一下內容
registry=https://registry.npmjs.com/
//registry.npmjs.com/:_authToken=xxx
開發你的組件,使用 webpack,babel 處理
由於 webpack,babel 配置比較麻煩,這裏使用 vue-cli 腳手架進行開發
package.json
{
"name": "@thingjs-ad/thingjs-app",
"version": "0.1.1",
"private": false,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build --target lib --name thingjs-app ./src/index.js",
"lint": "vue-cli-service lint",
"pub": "npm run build && npm publish --access=public"
},
"main": "dist/thingjs-app.umd.min.js",
"files": [
"src",
"dist"
],
"devDependencies": {
"@vue/cli-plugin-babel": "^4.2.0",
"@vue/cli-plugin-eslint": "^4.2.0",
"@vue/cli-service": "^4.2.0",
"babel-eslint": "^10.0.3",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.1.2",
"vue-template-compiler": "^2.6.11"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions"
]
}
組件內容
-
AA.vue
<template>
<div>
AA 組件
</div>
</template>
<script>
export default {
name:'AA'
};
</script>
-
index.js
import AA from './components/AA.vue';
const components = [AA];
// 當調用 Vue.use,實際會調用這個 install 方法。Vue.component 註冊全局組件。
const install = function (Vue) {
components.forEach(component => {
Vue.component(component.name, component);
});
};
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue);
}
export default {
version: '1.0.0',
install,
AA
}
發佈組件
npm publish --access=public
本文分享自微信公衆號 - Mflyyou(Mflyyou)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。