npm 相關,看這篇就夠了!

前言

最近在研究組件發佈,配到一些相關問題,算是整理一下。第一次寫的博客,同事也看的雲裏霧裏,開發組件的時候還是遇到一些問題,特此重新整理了一下,應該差不多相關的問題都涉及到了。

涉及內容

  • package.json 文件介紹
  • .npmrc 的作用及配置
  • 公網 npm 組件發佈

package.json

概述

package.json 定義了當前項目中 npm包 之間的依賴關係和項目的一些配置信息(項目名稱,版本,描述,開發人,許可證 等等)。

當說到包管理器,就會遇到 yarnnpm 的選擇性問題。我是喜歡用 yarn的,看看 github 上的開源項目,比如 vue 項目下就有 yarn.lock 文件,由此我猜測 yarn 可能更受歡迎一些,日常使用中我也是 yarn 用的比較多。

當我們 npm installyarn install 會根據項目下的 package.json 解析依賴包之間的依賴關係然後從配置的 npm registry.npmrc 可以配置對應的 registry)地址中搜索並下載包。

我們可以在 yarn.lockpackage-lock.json 看到包從哪裏下載和依賴關係。

提交代碼的時候排除 node_modules 目錄,但是要提交 yarn.lockpackage-lock.json ,用於鎖定項目依賴包的版本。並且升級包的時候不要手動改 package.json 中的版本號,要使用命令 yarn upgradenpm upgrade 升級。

npm inityarn 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源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章