npm,看這篇就夠了

前言

最近在研究 npm 組件發佈,碰到一些相關問題,算是整理一下。vue

涉及內容

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

package.json

概述

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

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

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

咱們能夠在 yarn.lockpackage-lock.json 看到包從哪裏下載和依賴關係。github

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

npm inityarn 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":{}
}

複製代碼

package.json 字段介紹

name

name 字段做爲項目的名稱。 好比 vue 中的一個組件 @vue/cli-plugin-babel ,前面這個 @vue 其實就當前包的 scope ,既命名空間。咱們能夠根據 scope 配置一些私有包 registry,從而達到一些包來源於特定的地址。shell

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-patchnpm

# 更新 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 必定要和之前的不同,不然發佈不成功。json

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 " > 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

.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

img
相關文章
相關標籤/搜索