基于vueCli2发布一个vue组件的npm包

27次阅读

共计 5239 个字符,预计需要花费 14 分钟才能阅读完成。

[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 <575720013@qq.com>",
    "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": "git@github.com: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>]

正文完
 0