基於vueCli2發佈一個vue組件的npm包

[toc]

這篇文章主要記錄了從零發佈一個vue的npm包(包含一個簡單的指令和一個vue組件)的實踐過程及些許心得。

初始化項目

這裏我們通過@vue/cli拉取簡單配置的模板來初始化一個2.X的項目,不瞭解的同學可以看下vueCli3官方文檔

vue init webpack-simple vue-directive-kit

初始化的項目目錄如下

├── README.md
├── index.html
├── package.json
├── src
│   ├── App.vue
│   ├── assets
│   └── main.js
└── webpack.config.js

接下來做一些改動。src目錄改爲examples用於本地開發及案例展示,新增一個packages目錄用於存放組件源碼及導出文件。

├── README.md
├── examples
│   ├── App.vue
│   └── main.js
├── index.html
├── package.json
├── packages
│   ├── componentName // 單個組件
│   │   ├── index.js
│   │   └── src
│   │       └── componentName.vue
│   └── index.js  // 導出文件
└── webpack.config.js

由於文件名稱做了改動,webpack的打包配置也要做對應修改。默認webpack.config.js會導出一個對象,這裏我們改爲導出一個函數,然後由函數把配置對象導出,這樣可以接受一個通過package.json傳過來的參數env,同時修改entryoutput

module.exports = env => {
    return {
        entry: env.lib ? "./packages/index.js" : "./examples/main.js",
        output: {
            // 打包文件的生成路徑
            path: path.resolve(__dirname, env.lib ? "./lib" : "./dist"),
            publicPath: env.lib ? "/lib/" : "/dist/",
            // 打包後生成的文件名
            filename: env.lib ? "vue-directive-kit.js" : "build.js",
            /**
             * library指定的就是你使用require時引入的模塊名
             * 這裏便是require(“vue-directive-kit”)
             */
            library: env.lib ? "vue-directive-kit" : "",
            /**
             * libraryTarget可以指定打包文件中代碼的模塊化方式,默認爲var,常見有如下幾種:
             * commonjs/commonjs2: 將你的library暴露爲CommonJS模塊
             * amd: 將你的library暴露爲amd模塊
             * umd: 將你的library暴露爲所有的模塊定義下都可運行的方式
             * 其中AMD和UMD需要指定library,如果不聲明組件庫則不能正常運行,
             * 這是爲了在瀏覽器上通過script標籤加載時,用AMD模塊方式輸出的組件庫可以有明確的模塊名
             */
            libraryTarget: env.lib ? "umd" : "var",
            /**
             * 當使用了 libraryTarget: "umd",
             * 設置umNamedDefine爲true時,
             * 會對 UMD 的構建過程中的 AMD 模塊進行命名。否則就使用匿名的 define。
             */
            umdNamedDefine: env.lib ? true : false,
        },
    };
};

上面的配置可以知道,我們需要通過env來控制打包類型。env需要在package.json中傳入

    "scripts": {
        // 本地開發運行npm run dev
        "dev": "cross-env NODE_ENV=development webpack-dev-server --env --open --hot",
        "build": "cross-env NODE_ENV=production webpack --env --progress --hide-modules",
        // 需要發佈的時候執行npm run lib打包
        "lib": "cross-env NODE_ENV=production webpack --env.lib --progress --hide-modules"
    },

完善內容

編寫組件

packages/componentName/src/componentName.vue文件中寫如下你內容。當然這個是爲了演示內容很簡單,其實這個文件就是真實的組件了。

<template>
    <div>
        <h1>我是一個組件</h1>
    </div>
</template>

<script>
export default {
    name: 'componentName',
    data () {
        return { }
    }
}
</script>

packages/componentName/src/index.js中註冊並導出單個組件

// 引入組件
import componentName from './componentName/src'
componentName.install = Vue => Vue.component(componentName.name, componentName);

if (typeof window !== 'undefined' && window.Vue) {
    window.Vue.use(componentName);
}

export default componentName;

編寫指令

我們增加一個名稱爲testDirective的指令。
創建'packages/testDirective/src/testDirective.js'文件:

export default {
    bind: () => {
        console.log(`directive bind`);
    },
    inserted: (el, binding) => {
        console.log(`el:`, el);
    },
}

創建packages/testDirective/index.js文件:

// 引入組件
import testDirective from './src/testDirective'
const install = Vue => {
    Vue.directive('testDirective', testDirective);
};

if (typeof window !== 'undefined' && window.Vue) {
    window.Vue.use({install});
}

export default {
    install
};

統一導出

編輯出口文件packages/index.js,將packages目錄下所有的指令及組件統一註冊導出:

// 導入顏色選擇器組件
import componentName from './componentName/src/componentName.vue'
import testDirective from './testDirective/src/testDirective'

// 存儲組件列表
const components = [
    componentName,
]

// 存儲指令映射
export const directives = {
    testDirective,
}

// 定義 install 方法,接收 Vue 作爲參數。如果使用 use 註冊插件,則所有的組件都將被註冊
const install = function (Vue) {
    // 遍歷註冊全局組件
    components.map(component => Vue.component(component.name, component))

    // 遍歷註冊指令
    Reflect.ownKeys(directives).map(name => Vue.directive(name, directives[name]))
}

// 判斷是否是直接引入文件
if (typeof window !== 'undefined' && window.Vue) {
    install(window.Vue)
}

export default {
    // 導出的對象必須具有 install,才能被 Vue.use() 方法安裝
    install,
    // 以下是具體的組件列表
    componentName,
    ...directives,
}

到這裏,我們的包裏就包含了一個名爲componentName的組件和一個名爲testDirective的指令,本地測試一下,先在examples/main.js中引入

// 單獨引入指令文件
// import pkgName from '../packages/test-directive/index'
// 整體引入包
import pkgName from '../packages/index'

Vue.use(pkgName)

examples/App.vue中使用

<template>
    <div id="app">
        <h1 v-test-directive>Test Directive</h1>
        <component-name></component-name>
    </div>
</template>

然後運行yarn dev本地查看效果

看起來本地測試已經沒有問題,可以打包發佈了。
不過在打包發佈之前,需要先做一些準備工作。

發佈前準備

generator-standard-readme

一個標準的npm包或者開源項目都會一個有完善且好看的README幫用戶快速瞭解你的項目。通過generator-standard-readme可以快速生成一個README模板

npm install --global yo generator-standard-readme
yo standard-readme

完善package.json文件

package.json增加一些發佈npm包所需要的基本字段:

    /**
     * npm包名,要符合幾個規則:
     * 1. name的長度必須小於等於214個字符。
     * 2. name不能以"."(點)或者"_"(下劃線)開頭。
     * 3. name中不能包含大寫字母。
     * 4. name最終將被用作URL的一部分、命令行的參數和文件夾名。因此,name不能含有非URL安全的字符。
     */
    "name": "vue-directive-kit",
    "description": "A collection of vue directives.",
    "version": "1.0.1",
    "author": "slevin <[email protected]>",
    "license": "MIT",
    // 是否私有,默認爲true,改爲false
    "private": false,
    // 是一個字符串的數組。它可以幫助人們在使用npm search時找到這個包
    "keywords": [
        "vue",
        "vue-directive-kit",
        "vue-directive"
    ],
    /**
     * files字段是一個被項目包含的文件名數組
     * 如果你在裏面放一個文件夾名,那麼這個文件夾中的所有文件都會被包含進項目中(除非是那些在其他規則中被忽略的文件)。
     * 你還可以在包的根目錄或子目錄下提供一個".npmignore"文件來忽略項目包含文件,即使這些文件被包含在files字段中
     * 某些文件總是被包含的,不論是否在規則中指定了它們:
     * package.json
     * README (and its variants)
     * CHANGELOG (and its variants)
     * LICENSE / LICENCE
     */
    "files": [
        "lib/vue-directive-kit.js",
        "package.json",
        "README.md"
    ],
    /**
     * main字段用來指定入口文件
     * 
     */
    "main": "lib/vue-directive-kit.js",
    /**
     * 指明你的代碼被託管在何處,也就是遠程倉庫的地址
     */
    "repository": {
        "type": "git",
        "url": "[email protected]:slevin57/vue-directive-kit.git"
    }

本地包測試

隨便找一個項目,安裝這個包進行測試。這裏我們就在根目錄下再初始化一個vue基本項目用來測試包的使用,然後把npm包文件放到測試項目根路徑執行安裝,同時安裝項目依賴。

vue init webpack-simple test
mv xxx.tgz ./test
cd test
npm i xxx.tgz && npm i

main.js中像正常引入第三方包那樣操作就可以。測試完成後記得刪掉test目錄。
準備操作及測試都做完後就可以打包發佈了。

發佈到npm

先打包

npm run lib

登錄npm,輸入npm註冊的用戶名、密碼及郵箱

npm login

發佈

npm publish

不出意外的話,登錄npm就可以看到你發佈的包了。發佈的包在72小時內是可以刪除的,過了72小時就永遠無法刪除了,所以記得不要隨意發一些沒有意義的包。
如果需要卸載,在發佈後72小時內執行:

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