最近在研究 npm
組件發佈,碰到一些相關問題,算是整理一下。vue
package.json 定義了當前項目中 npm包
之間的依賴關係和項目的一些配置信息(項目名稱,版本,描述,開發人,許可證 等等)。node
當說到包管理器,就會遇到 yarn
和 npm
的選擇性問題。我是喜歡用 yarn
的,看看 github
上的開源項目,好比 vue
項目下就有 yarn.lock
文件,由此我猜想 yarn
可能更受歡迎一些,平常使用中我也是 yarn
用的比較多。webpack
當咱們 npm install
或 yarn install
會根據項目下的 package.json
解析依賴包之間的依賴關係而後從配置的 npm registry
( .npmrc
能夠配置對應的 registry
)地址中搜索並下載包。git
咱們能夠在 yarn.lock
或 package-lock.json
看到包從哪裏下載和依賴關係。github
提交代碼的時候排除 node_modules
目錄,可是要提交 yarn.lock
或 package-lock.json
,用於鎖定項目依賴包的版本。而且升級包的時候不要手動改 package.json
中的版本號,要使用命令 yarn upgrade
或 npm upgrade
升級。web
npm init
或 yarn init
能夠生成 package.json。vue-cli
{
"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": "bug@example.com"
},
"contributors": [
{
"name": "zhangpanqin",
"email": "zhangpanqin@email.com"
}
],
"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":{}
}
複製代碼
name
字段做爲項目的名稱。 好比 vue 中的一個組件 @vue/cli-plugin-babel
,前面這個 @vue
其實就當前包的 scope ,既命名空間。咱們能夠根據 scope
配置一些私有包 registry
,從而達到一些包來源於特定的地址。shell
registry=https://registry.npm.taobao.org/
@pay-plugin:registry=https://npm.udolphin.com
複製代碼
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
npm
# 更新 major 的位置,其他位置爲 0
npm version major
# 更新 minor 的位置,major 不變,其他位置爲 0
npm version minor
# 更新 patch 的位置,其他位置不變
npm version patch
複製代碼
當你的項目須要發佈的時候,version 必定要和之前的不同,不然發佈不成功。json
標識當前包是否私有,爲 true
時包不能發佈。
默認 index.js。指定 import 或 require 的時候加載的 js。
描述當前項目的關鍵字,用於檢索當前插件。
"publishConfig": {
"registry": "https://registry.npmjs.com/"
}
複製代碼
有的時候呢咱們在 .npmrc
配置了別的 registry
,好比淘寶鏡像。我安裝依賴包的時候呢,想從淘寶鏡像安裝。發佈插件的時候想發佈到官網上。就能夠在 publishConfig
中配置了。
指定發佈的依賴包,包含的文件,默認會忽略一些文件。也能夠根目錄下建立 .npmignore 忽略一些文件。
配置一些執行腳本。好比說 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"
}
複製代碼
項目的開發依賴。key 爲模塊名稱,value 爲版本範圍。項目打包時會將這裏的依賴打包進去。
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>
複製代碼
爲開發依賴,打包的時候不會打包進去。好比咱們使用的 babel
webpak
等相關的插件,打包的時候,並不會被打包進去。
在將這個以前,咱們先來了解 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 " > fly-use-npm@4.0.0" has incorrect peer dependency "fly-npm@1.0.0」。
當你開發一個組件,依賴特定包的版本就須要這樣處理。
// 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
。
package.json
中的依賴包從哪裏安裝呢?.npmrc 能夠配置依賴包從哪裏安裝,也能夠配置 npm 的一些別的配置。
/project/.npmrc
~/.npmrc
/usr/local/etc/npmrc
/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 會配置到全局配置文件
官網申請一個帳號,用於登陸和發佈組件。
在項目的根路徑下建立 .npmrc
配置文件,添加以下內容。
# 安裝包的時候,配置阿里鏡像
registry = https://registry.npm.taobao.org
複製代碼
在 package.json
中配置發佈源。
"publishConfig": {
"registry": "https://registry.npmjs.com/"
}
複製代碼
這樣下載依賴包會從淘寶鏡像下載,發佈依賴包會發布到 npm 官網去。
# 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 配置比較麻煩,這裏使用 vue-cli 腳手架進行開發
{
"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"
]
}
複製代碼
<template>
<div>
AA 組件
</div>
</template>
<script>
export default {
name:'AA'
};
</script>
複製代碼
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