這是一篇包教不包會的npm發佈教程,爲了不不少文章中的分享,跟着一步步作,最後發包失敗。。時間沒了,搞得心情都很差了。css
所以,在寫這篇文章的同時[2019-08-18]我從新創建一個npm包,按照如下的流程,發佈了一個npm包,也測試可用,因此童鞋們能夠放心跟着一步步走,學會發布npm包。發包的項目代碼在這裏、 已經發布上線的npm包地址在這裏html
相信前端er對npm包不會陌生,npm 原本是 Node.js 的包管理工具,但隨着 JS 這幾年的蓬勃發展,如今的 npm 已經成了幾乎全部跟 JS 相關的工具和軟件包的管理工具了,此次也會從0到1的走一遍發包的流程,前端
一、本文是以vue項目爲例子進行講解,流程可通用,只是具體項目的安裝有些許區別,無論vue仍是react,相信對你們都有幫助vue
二、⚠️提示: 爲了讓童鞋們理解發包的流程和配置,因此仍是建議按照步驟(1)-(10)的順序來操做,爲了突出整個發包流程,因此封裝的測試組件很是簡單。待理解全部文件的內容和具體原理,併成功發出一個測試npm包後,童鞋們可自行更換成本身的組件,發佈屬於本身的npm包,發佈包的名字設置爲
our-btn
node
在項目中,咱們都但願安裝的插件體積儘量的小,所以,咱們在發包的時候也要儘可能控制咱們的依賴,因此我選擇本身建立一個打包項目,而不是用笨重的vue和react腳手架。 話很少說,下面跟着作👇react
可是因爲本文組件過於簡單,因此刪減
assets
、utils
文件夾(有沒有這兩個文件夾不影響npm發包,僅僅方便你本身整理項目代碼)webpack
├── src
│ ├── assets # 本地靜態資源(本文沒有)
│ ├── components # 業務通用組件
│ │ ├── btnDemo.vue # 本文須要封裝的簡單button組件
│ ├── utils # 工具庫(本文沒有)
│ └── index.js # 應用入口
├── .npmignore // 用於忽略不須要上傳到npm的文件
├── README.md
├── package-lock.json
├── package.json
└── webpack.config.js # webpack配置
// 注意
# utils 文件夾通常存放的是你組件常用的一些工具函數
# assets 文件夾通常存放的是你組件用到的樣式、圖片、icon等靜態資源
複製代碼
button組件
// btnDemo.vue
<template>
<div class="btn">
<button>{{text}}</button>
</div>
</template>
<script>
export default {
name: 'btn', // 組件的name屬性(後面有提到這裏有個坑)
props: {
text: { // 文本
type: String,
default () {
return ''
}
}
},
data () {
return {
}
}
}
</script>
複製代碼
index.js
該文件是爲了將咱們的組件暴露出去git
// src/index.js
// 這裏import 的 btn和btnDemo.vue的name屬性名相同 !
import btn from './btnDemo.vue'
btn.install = Vue => Vue.component(btn.name, btn) // 給組件配置install方法
export default btn;
複製代碼
⚠️(這裏有個坑):因爲
Vue.component(btn.name, btn)
的btn.name
是指向btnDemo.vue
的name
屬性,所以,建議在這裏最好用組件的name
屬性值做爲import
別名github
webpack.config.js
webpack.config.js
配置以下,因爲咱們使用的版本是webpack4
,全部的配置都在webpack.config.js
裏面,在咱們這裏僅僅須要把咱們的資源打包,寫的比較簡單,具體webpack
配置細節能夠學習官方文檔web
這裏配置是用於將/src
中的內容打包到/dist
(打包時會自動生成/dist
文件夾)中的btn.js
,btn.js
其實就至關於咱們的插件(後面在package.json
的main
字段也是指向這裏)
// webpack.config.js
const path = require('path')
const { VueLoaderPlugin } = require('vue-loader')
module.exports = {
entry: {
index: path.join(__dirname, "/src/index.js") // 入口文件(就是剛纔用於暴露組件的index.js)
},
output: {
path: path.join( __dirname, "/dist"), // 打包後的文件存放在dist文件夾
publicPath: '/dist/', // 設置公共路徑
filename: "btn.js", // 打包後輸出文件的文件設置爲btn.js
libraryTarget: 'umd' // 這個選項會嘗試把庫暴露給前使用的模塊定義系統,這使其和CommonJS、AMD兼容或者暴露爲全局變量
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.(scss|sass)$/,
use: ['style-loader', 'css-loader', 'sass-loader']
},
{
test: /\.(png|jpg|svg|gif)$/,
use: ['url-loader']
},
{
test: /\.js$/,
exclude: /node_modules|vue\/dist|vue-router\/|vue-loader\/|vue-hot-reload-api\//,
loader: 'babel-loader'
}
]
},
plugins: [
new VueLoaderPlugin()
]
}
複製代碼
package.json
package.json
字段以下,要強調的是,字段devDependencies
中的依賴項不惟一,你能夠根據本身狀況去寫,可是此時此刻,請務必和我同樣,這也是爲了保證你能夠按照個人操做,成功發包
// 具體字段後面詳細說明
{
"name": "our-btn", // 發佈npm包的名字
"version": "1.0.0", // 你的npm包版本
"description": "A test button", // 包的描述
"main": "dist/btn.js", // *重點*:指定你組件的主入口文件
"scripts": {
"build": "webpack --mode production",
"dev": "webpack-dev-server --open --mode development"
},
"keywords": [
"our-btn",
"button"
],
"repository": {
"type": "git",
"url": "git+https://github.com/thomaszhou63/test-npm.git"
},
"author": "thomaszhou",
"license": "MIT",
"devDependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-preset-env": "^1.7.0",
"css-loader": "^1.0.0",
"file-loader": "^2.0.0",
"style-loader": "^0.23.1",
"url-loader": "^1.1.2",
"node-sass": "^4.12.0",
"sass-loader": "^7.2.0",
"vue": "^2.5.2",
"vue-hot-reload-api": "^2.2.4",
"vue-html-loader": "^1.2.4",
"vue-loader": "^15.4.2",
"vue-style-loader": "^3.0.3",
"vue-template-compiler": "^2.5.9",
"webpack": "^4.19.0",
"webpack-cli": "^3.1.0"
}
}
複製代碼
name
- 包名(包名應該是kebab-case, 即英文單詞全小寫或者中劃線分割)version
- 包的版本號(初版建議1.0.0
,具體命名規則看這裏)description
- 包的描述。在npmjs.com
上搜索時會顯示,有助於用戶在搜索時進行篩選)keywords
- 關鍵字(在npm網站上搜索你這個npm包的關鍵詞)author
- 包的做者。格式通常是name <你的郵箱>
,通常來講,用vue/react
腳手架建立項目的時候會默認這個格式寫法, 固然也能夠是一個github地址,也能夠自定義,但就不那麼標準了license
- 版權許可證,MIT
仍是ISC
,或者其餘均可以,只是我看不少包都是MIT
contributors
- 包的其餘貢獻者(我沒有寫這個)repository
- 包代碼的Repo
信息,包括type
和URL
,type
能夠是git
或svn
,URL
則是包的Repo
地址
git
倉庫的地址,放着個人組件項目代碼,這樣在npm包頁面就有會個github的入口main
- 該字段指定了程序的主入口文件(最好寫dist文件夾
內已經壓縮後的文件)
main
定義了包的入口文件,在NodeJs
環境中,語句import [pkg] from '[package]'
時,其實導入的就是main定義的文件scripts
- 指定了運行腳本命令的npm命令行縮寫。如 npm start
、npm run dev
、npm run build
等dependencies
/ devDependencies
- 生產/開發環境依賴包列表。它們將會被安裝在 node_module
目錄下
dependencies
和devDependencies
其實沒太多區別,由於在執行npm install/yarn add
時都會所有下載dependencies
是運行你的包必須安裝的依賴,即當用戶npm install [package]
或者yarn add [package]
時,這些依賴也會下載devDependencies
是開發你的包時須要安裝的依賴,好比eslint
, jest
等開發工具,當用戶npm install [package]
或yarn add [package]
時,這些依賴並不會下載!我這裏版本是1.0.1,是由於我本身後面迭代了一個版本,若是你是初版,最好是1.0.0
README.md
這是個人README.md
寫的東西,最終都會顯示在npm的內容介紹裏面(也就是上圖),各位童鞋若是發包,也請寫好README.md
哈,畢竟是給人使用的嘛
## our-btn
>一個測試的npm包
# install
```
npm install our-btn
```
# use
```
// main.js
import btn from 'our-btn'
Vue.use(btn)
```
```
// demo.js
<template>
<div class="demo">
<btn :text="msg"></btn>
</div>
</template>
<script>
export default {
name: 'demo',
data () {
return {
msg: '成功'
}
}
}
</script>
```
複製代碼
.npmignore
這個文件同.gitignore
的功能同樣,.gitignore
是忽略自選的文件上傳到github倉庫中,而.npmignore
則是忽略自選的文件上傳到npm上。
可是呢,若是你的項目沒有.npmignore
文件,但有 .gitignore
文件,則發佈時會忽略 .gitignore
中定義的文件;也就是說,.npmignore
的優先級是高於.gitignore
的。
.*
*.md
node_modules/
webpack.config.js
src/
複製代碼
以上文件都配置好後就能夠運行下面命令安裝package.json
的依賴了,而後就會在大家的目錄中生成node_modules
文件夾、package-lock.json
文件
npm install
複製代碼
npm run build
複製代碼
下圖就是個人目錄結構,其中.gitattributes
和.gitignore
文件你能夠忽略,由於我把這個項目放在github倉庫,因此纔會有這兩個文件的。
在項目中執行以下命令
npm run build // 打包
npm pack // 本地生成一個our-btn-1.0.1.tgz的包
複製代碼
你本身在你本地新建一個vue/react
項目,由於我是vue組件,因此我就新建一個vue項目,取名爲test-btn
,咱們把our-btn-1.0.1.tgz
放進咱們的本地項目test-btn
中
npm install our-btn-1.0.1.tgz
npm run dev // 啓動vue項目
複製代碼
而後在項目的main.js
引入咱們的包
// src/main.js
// 注意:btn要保持和以前我們封裝組件的index.js同樣
import btn from 'our-btn' // 引入包
Vue.use(btn)
複製代碼
在咱們demo頁面中引用這個組件
// demo.vue
<template>
<div class="demo">
<btn :text="msg"></btn>
</div>
</template>
<script>
export default {
name: 'demo',
data () {
return {
msg: '成功'
}
}
}
</script>
複製代碼
若測試可用,在測試項目test-btn
中運行npm uninstall our-btn
卸載插件,而後那麼就能夠發佈到npm包上了
發佈以前,你得註冊一個npm帳號吧,否則你怎麼上傳呢,建議上官網註冊一個帳號(順便熟悉那個網站),註冊完帳號以後,咱們就要在本地登陸併發布咱們的組件了
提示:由於有點童鞋會常常用cnpm源,因此呢,必定要切換到npm源上才能夠,否則就會報出以下錯誤
error: no_perms Private mode enable, only admin can publish this module 複製代碼
所以你要切換到npm源,經過
npm config set registry http://registry.npmjs.org
命令
在發包以前,先去npm官網搜索一下有沒有和你包名相同的,若是相同就改一個其餘的名字吧
npm login // 登錄npm
// 而後輸入你的帳號、密碼、郵箱
// 當你在控制檯看到 Logged in as <Username> on https://registry.npmjs.org 說明登錄成功
// 若是你保證是最新版本且已經打包過,則跳過npm run build這一步
npm run build
npm publish // 發佈你的包(若是你出現👇,顯示 +[package]@版本信息 ,那就發佈成功了)
複製代碼
👇這是個人輸入及其對應顯示的東西
🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉此時此刻你的包已經發布成功!!!🎉🎉🎉🎉🎉🎉🎉🎉🎉
⚠️拓展知識:一個版本只能發佈一次,也就是你不能發了
1.0.0
,下次還繼續1.0.0
,理論上能夠覆蓋,可是npm不容許這樣,由於你這樣覆蓋,就沒法知道你的版本信息了啊,插件和項目都是迭代的,like git,是有版本信息的。 方法一:每一次
npm publish
前,自行手動更改package.json
的version 方法二:經過如下命令來發布
假設初始版本爲1.0.0 ➜ npm version preminor (執行這個命令,就會價格當前包發佈爲版本v0.1.0-0) v1.0.0-0 ➜ npm version prepatch v1.0.1-0 ➜ npm version patch (執行這個命令,就會價格當前包發佈爲版本v1.0.1) v1.0.1 複製代碼
這個時候,你稍微等幾分鐘去npm官網搜索一下你的包名字,就能夠找到啦。若是搜不到,那就再等等,或許更新慢,沒有徹底更新,可是你在本身npm帳號能夠查看到本身發佈的包
你本身在你本地新建一個vue/react
項目,由於我是vue組件,因此我就新建一個vue項目,具體使用包的方法就是(以個人測試包爲例)
npm install our-btn // 安裝咱們的包
複製代碼
而後在項目的main.js
引入咱們的包
// src/main.js
// 注意:btn要保持和以前我們封裝組件的index.js同樣
import btn from 'our-btn' // 引入包
Vue.use(btn)
複製代碼
在咱們demo頁面中引用這個組件
// demo.vue
<template>
<div class="demo">
<btn :text="msg"></btn>
</div>
</template>
<script>
export default {
name: 'demo',
data () {
return {
msg: '成功'
}
}
}
</script>
複製代碼
若是錯誤請指正,我也好糾錯更新
若有講的不明白的,請留言,我看到會回覆
over