自定义发布npm包

手把手教你快速制作基于Element UI组件npm包

2020-12-09  本文已影响0人  该帐号已被查封_才怪

本文主要介绍如何快速实现基于Element UI二次封装的组件发至npm,并在自己的项目中通过安装该npm包来调用该组件。

一、发布npm包

1、通过vue-cli初始化一个项目后,编写可复用子组件
这里我把可复用子组件放在了 src\components\common\组件名 目录中

image.png
项目中我开发了 DatePickerHasOps.vueDatePickerLimit .vueDialogWithBtn.vueTablePage.vue 四个可复用子组件
这里贴一下DialogWithBtn.vue的代码
<template>
    <el-dialog :visible.sync="visibleDialog" v-bind="$attrs" v-on="$listeners">
      <slot></slot>
      <template #footer>
        <slot name="footer">
          <div class="dialog-footer-ct">
            <el-button @click="cancelOp">取 消</el-button>
            <el-button @click="sureOp" type="primary">确 定</el-button>
          </div>
        </slot>
      </template>
    </el-dialog>
</template>

<script>
    export default {
      name: 'dialog-with-btn',
      props: {
        visible: {
          default: false,
          type: Boolean,
        },

      },
      computed: {
        visibleDialog: {
          get() {
            return this.visible
          },
          set(val) {
            this.$emit('update:visible', val)
          },

        },
      },
      methods: {
        cancelOp() {
          this.$emit('cancelEvent')
          this.visibleDialog = false;
        },
        sureOp() {
          this.$emit('sureEvent')
          this.visibleDialog = false;
        },

      },
     //  data:{
     //      return {
     //        visibleDialog
     //      }
     // }
    }
</script>

<style scoped>
  .dialog-footer-ct{
    margin: 10px auto;
    text-align: center;
  }

</style>


2、在src\components\common\目录下新建一个index.js文件
index.js

import DatePickerHasOps from './DatePickerHasOps/DatePickerHasOps'
import DatePickerLimit from './DatePickerLimit/DatePickerLimit'
import DialogWithBtn from './DialogWithBtn/DialogWithBtn'
import TablePage from './TablePage/TablePage'

let plugins={};
const componentArray=[DatePickerHasOps,DatePickerLimit,DialogWithBtn,TablePage]

plugins.install=function (Vue) {
    // 判断是否安装过
    if(plugins.installed) return;
    plugins.installed=true
  //  console.log('plugins.installed==========',plugins.installed)
    // 获取地址栏特定搜索串内容
    // Vue.prototype.$getSearchParam=function(name){
    //     const reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`, 'i');
    //     const r = window.location.search.substr(1).match(reg);
    //     if (r != null) {
    //         return decodeURIComponent(r[2]);
    //     }
    //     return '';
    // }

    componentArray.forEach((item)=>{
        Vue.component(item.name,item)
    })

}
// /* 支持使用标签的方式引入 */
// if (typeof window !== 'undefined' && window.Vue) {
//     install(window.Vue);
// }
// 也可参考 https://cn.vuejs.org/v2/cookbook/packaging-sfc-for-npm.html

export default plugins


3、编辑package.json文件
注意看里面的注释说明。

{
  "name": "vue-ele-component-zonst", // 即将发布的npm包名
  "version": "0.0.1",
  "private": false, // 是否为私有 这里记得改为false
  "description": "封装了zonst常用的组件库,如日期选择器、表格及弹窗等",
  "license": "MIT",
  "files": ["lib"],   // 发布npm包后 使用者能够看到的你的文件夹或文件  
  "scripts": {
    "dev": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "lib": "vue-cli-service build --target lib --name vue-ele-component-zonst --dest lib/all src/components/common/index.js"  // 为发布npm进行打包 里面的具体参数可参考 https://cli.vuejs.org/zh/guide/cli-service.html#vue-cli-service-build
  },
  "main": "lib/all/vue-ele-component-zonst.umd.min.js", // 这里为了 使用者在调用npm包时 可直接使用import xxxx  from '你的npm包名'
  "repository": {
    "type": "git",
    "url": "https://git.xxxxxx.com/xxxx-demo/vue-element-component.git"
  },
  "keywords": [
    "vue",
    "element-ui",
    "dialog",
    "datePicker",
    "table"
  ],
  "homepage": "https://github.com/",
  "dependencies": {
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~4.4.0",
    "@vue/cli-plugin-eslint": "~4.4.0",
    "@vue/cli-service": "~4.4.0",
    "babel-eslint": "^10.1.0",
    "eslint": "^6.7.2",
    "eslint-plugin-vue": "^6.2.2",
    "vue-template-compiler": "^2.6.11",
    "core-js": "^3.6.5",
    "element-ui": "~2.3.9",
    "vue": "^2.6.11",
    "vue-router": "~3.3.4"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "eslint:recommended"
    ],
    "parserOptions": {
      "parser": "babel-eslint"
    },
    "rules": {}
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ]
}

4、运行 npm run lib 以便构建npm包文件
下图是构建生成的commonJS、umd及source map系列文件


image.png

5、本地测试构建后的效果
在main.js中

import Vue from 'vue'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import router from './router'
import App from './App.vue'
// eslint-disable-next-line
import vueEleComponentZonst from '../lib/all/vue-ele-component-zonst.umd.min'
// import dialogWithBtn from '../lib/part/dialog-with-btn.umd.min'

// 实现免手动引入全局组件
// eslint-disable-next-line
//import globalImortComponents from '@/components/common/js/globalImportComponents'

Vue.config.productionTip = false
Vue.use(ElementUI).use(vueEleComponentZonst);
// Vue.use(ElementUI).use(dialogWithBtn);
// import '../node_modules/vue-ele-component-zonst/lib/all/vue-ele-component-zonst.css'
// import '../node_modules/vue-ele-component-zonst/lib/part/dialog-with-btn.css'
import '../lib/all/vue-ele-component-zonst.css'
// import '../lib/part/dialog-with-btn.css'


new Vue({
    router,
    // methods:{
    //
    // },
   render: h => h(App),
}).$mount('#app')


调用DialogWithBtn 组件测试

<template>
    <div>
        <ol>
            <li>在原有dialog基础上底部增加‘确定’和‘取消’按钮</li>
            <li>支持dialog所有属性和事件</li>
        </ol>
        <el-button @click="editSome" type="primary">打开对话框</el-button>

        <dialog-with-btn title="对话框标题" :close-on-click-modal="false"  @cancelEvent="cancelCallback" @sureEvent="sureCallback" :visible.sync="visible">
            这是一个对话框
        </dialog-with-btn>
    </div>

</template>

<script>
    // const DialogWithBtn = () => import('@/components/common/DialogWithBtn');

    export default {
        name: 'test-dialog',
        // components: {
        //     DialogWithBtn,
        // },
        data() {
            return {
                visible: false,
            }
        },
        methods: {
            editSome() {
                this.visible = true
                console.log('点击了编辑')
            },
            cancelCallback() {
                console.log('点击了取消按钮')
            },
            sureCallback() {
                console.log('点击了确定按钮')
            },
        },
    }
</script>

<style scoped>

</style>

6、将npm的源改为npm官方的网址
以上测试无误后开始准备发布npm包
npm config set registry https://registry.npmjs.org
7、登录你注册好的npm帐号
npm login 输入npm帐号密码及邮箱
8、发布
npm publish
过一段时间后,会收到npm官方发的 npm发布成功的邮件
如果发布的是测试包,则可使用
npm publish --tag=beta
9、查看npm包
https://www.npmjs.com/package/vue-ele-component-zonst

二、使用npm包

1、安装vue-ele-component-zonst
npm i vue-ele-component-zonst
2、引入npm包
main.js

import Vue from 'vue'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
// import vueEleComponentZonst from 'vue-ele-component-zonst/lib/all/vue-ele-component-zonst.umd.min'
// import vueEleComponentZonst from 'vue-ele-component-zonst/lib/part/dialog-with-btn.umd.min'
import vueEleComponentZonst from 'vue-ele-component-zonst'

import App from './App.vue'
// console.log('vueEleComponentZonst',vueEleComponentZonst)
// console.log('ElementUI',ElementUI)

Vue.config.productionTip = false
Vue.use(ElementUI).use(vueEleComponentZonst);
// Vue.use(ElementUI);
// Vue.use(ElementUI).use(DialogWithBtn);
import 'vue-ele-component-zonst/lib/all/vue-ele-component-zonst.css'


new Vue({
  render: h => h(App),
}).$mount('#app')

3、使用npm子组件

三、结语

以上为实现基于Element UI二次封装的组件发至npm最简单的方法,希望大家能够明白原理。在明白原理的基础后其实可以通过修改vue.config.js来分别打包各个组件并通过不同路径或使用babel-plugin-import(或babel-plugin-component)插件来实现按需引入你想要的组件、控制打包后的文件类型等来减少项目的体积;
上述代码 我放在github 仓库中 vue-ele-component-zonst 及发布至npm官网了 https://www.npmjs.com/package/vue-ele-component-zonst

四、npm 私服搭建推荐

https://www.yukapril.com/2020/12/13/npm-server.html

1、Nenus
官网:https://www.sonatype.com/nexus/repository-oss

非常强大,各个公司基本上用的都是它!因为它可以同时处理 maven npm 等私有仓库。所以为了省事,很多公司就不会单独再部署其他私服了。

下载地址:https://www.sonatype.com/nexus/repository-oss/download
2、sinopia
已停止更新。 Github:https://github.com/rlidwka/sinopia
一样号称零配置的私服,整体和 Verdaccio 差不多
3、Verdaccio
官网:https://verdaccio.org
Verdaccio 是 Sinopia 开源框架的一个分支,持续更新,轻量级,操作少。

号称零配置的私服,直接用 node 启动就行,还提供 docker 版本。
体验下来,我觉得好处就是安装特别省事,无需太关注复杂的技术,也可以不用太配置,还带有个简洁的 UI 页面。
单纯是 npm 私服的话,我认为用它非常适合。而且体验和 npm 官网非常类似,支持的 npm 语法也非常好。

具体教程可见:快速搭建npm私服并发布npm步骤(无需数据库)

4、cnpm
依赖较多,相对笨重 ,操作多

五、自动更新版本号指令

npm version patch 更新修订版本
npm version minor 更新次要版本
npm version major 更新主版本

六、npm多人发包

npm owner add <user> [<@scope>/]<pkg>
详见:https://docs.npmjs.com/cli/v7/commands/npm-owner

上一篇下一篇

猜你喜欢

热点阅读