Vue3 企业级优雅实战 - 组件库框架 - 11 组件库的打包构建和发布

Posted 程序员优雅哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue3 企业级优雅实战 - 组件库框架 - 11 组件库的打包构建和发布相关的知识,希望对你有一定的参考价值。

回顾第一篇文章中谈到的组件库的几个方面,只剩下最后的、也是最重要的组件库的打包构建、本地发布、远程发布了。

1 组件库构建

组件库的入口是 packages/yyg-demo-ui,构建组件库有两个步骤:

  1. 添加 TypeScript 的配置文件: tsconfig.json
  2. 添加 vite.config.ts 配置文件,配置打包方式。

1.1 tsconfig.json

packages/yyg-demo-ui 中添加 tsconfig.json 文件:


  "compilerOptions": 
    "target": "ESNext",
    "useDefineForClassFields": true,
    "module": "ESNext",
    "moduleResolution": "Node",
    "strict": true,
    "jsx": "preserve",
    "sourceMap": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "esModuleInterop": true,
    "lib": ["ESNext", "DOM"],
    "skipLibCheck": true,
    "declaration": true,
    "baseUrl": "."
  ,
  "include": ["../**/*.ts", "../**/*.d.ts", "../**/*.tsx", "../**/*.vue"],
  "exclude": ["../**/node_modules/"]

1.2 vite.config.ts

打包构建时需要提取类型定义,可以使用 vite 插件 vite-plugin-dts。首先在 packages/yyg-demo-ui 中添加该插件为开发依赖:

pnpm install vite-plugin-dts -D

然后创建 vite.config.ts 文件:

import  defineConfig  from 'vite'
import vue from '@vitejs/plugin-vue'
import * as path from 'path'
import VueJsx from '@vitejs/plugin-vue-jsx'
import viteDts from 'vite-plugin-dts'

export default defineConfig(
  plugins: [
    vue(),
    VueJsx(),
    viteDts(
      insertTypesEntry: true,
      staticImport: true,
      skipDiagnostics: true
    )
  ],
  build: 
    lib: 
      entry: path.resolve(__dirname, './index.ts'),
      name: 'yyg-demo-ui',
      fileName: format => `yyg-demo-ui.$format.js`
    ,
    outDir: path.resolve(__dirname, '../../lib'),
    rollupOptions: 
      external: ['vue'],
      output: 
        globals: 
          vue: 'Vue'
        
      
    
  
)

1.3 package.json

packages/yyg-demo-ui/package.json 中添加打包 scripts,上面的配置指定了打包输出目录为项目根目录下的 lib,每次打包前希望先删除该目录,可以使用 rimraf。在该模块中先安装 rimraf

pnpm install rimraf -D

package.json 中添加 script:

"scripts": 
  "build": "rimraf ../../lib && vue-tsc --noEmit && vite build"
,

执行 pnpm run build 开始打包。

打包成功后,项目根目录下生成 lib 目录,包括 ES 规范和 UMD 规范和类型定义文件。

2 组件库的本地发布

2.1 根目录 package.json scripts

到目前为止,整个组件库有很多个包,每个包都有一些 scripts:

cli:
	- gen: 创建新组件
docs:
	- dev:本地开发组件库文档
	- build:打包构建组件库文档
	- serve:预览组件库文档打包
example:
	- dev:dev、dev:uat、dev:prod:本地开发 example
	- build:dev、build:uat、build:prod:打包构建 example
	- preview:预览 example 打包构建后的结果
packages/yyg-demo-ui:
	- build:打包构建组件库

上面这些 scripts 都需要进入到对应的目录执行,这样比较麻烦,所以可以将这些命令汇总到根目录的 package.json 中,这样无论是哪个模块的 scripts,都从根目录执行即可。

"scripts": 
  "dev:dev": "pnpm run -C example dev:dev",
  "dev:uat": "pnpm run -C example dev:uat",
  "dev:prod": "pnpm run -C example dev:prod",
  "build:dev": "pnpm run -C example build:dev",
  "build:uat": "pnpm run -C example build:uat",
  "build:prod": "pnpm run -C example build:prod",
  "preview:example": "pnpm run -C example preview",
  "build:lib": "pnpm run -C packages/yyg-admin-ui build",
  "docs:dev": "pnpm run -C docs dev",
  "docs:build": "pnpm run -C docs build",
  "docs:preview": "pnpm run -C docs serve",
  "gen:component": "pnpm run -C cli gen",
  "lint": "eslint \\"cli,packages,docs,example/**/*.js,ts,vue,jsx,tsx\\" --fix"
,

通过 -C 指定 scripts 的位置。

2.2 安装本地私服 verdaccio

几个月前程序员优雅哥分享过使用 Docker 搭建 Nexus3 私服,Nexus3 相对重量级,如果在本地测试,使用 verdaccio 即可,verdaccio 算得上本地的一款轻量级私服了。

  1. 安装 verdaccio

verdaccio 通常是全局安装(-g),在咱们组件库中为了大家 clone 代码操作方便,便将其安装到根目录的开发依赖中:

pnpm install verdaccio -D -w
  1. 启动 verdaccio

在根目录 package.jsonscripts 中添加启动 verdaccio 的命令

"start:verdaccio": "pnpm verdaccio",

这一步可省略,只因为我用 WebStorm,添加到 scripts中不用每次输入命令,能偷懒的必须偷懒。

执行 start:verdaccio 后,控制台会提示访问地址 http://localhost:4873/ 。在浏览器中访问该路径。

  1. 创建用户、登录

在浏览器中按照界面提示创建用户、登录。在命令行中执行下列命令创建用户:

npm adduser --registry http://localhost:4873/

依次输入用户名、密码、邮箱,回车便成功创建账号并自动登录上。

使用刚才输入的用户名和密码,在浏览器中登录,登录前刷新浏览器。

2.3 本地发布

在发布前,需要修改项目根目录 package.json 的几个地方:

  1. 添加如下配置,指定 private 为 false、设置 main、module、types、files等属性:

  ...
  "private": false,
  "type": "module",
  "main": "./lib/yyg-demo-ui.umd.js",
  "module": "./lib/yyg-demo-ui.es.js",
  "types": "./lib/yyg-demo-ui/index.d.ts",
  "files": [
    "./lib",
    "package.json",
    "README.md"
  ],
  "exports": 
    ".": 
      "require": "./lib/yyg-demo-ui.umd.js",
      "import": "./lib/yyg-demo-ui.es.js"
    
  ,
  ...

  1. 自己修改 author
  2. 在 scripts 中添加发布组件库的命令:
"pub:local": "pnpm publish --registry http://localhost:4873/",
  1. 在项目根目录下添加一份 README.md 文件。

在发布前,如果代码纳入 git 管理,需要提交代码,再执行 pnpm run pub:local。显示如下信息则发布成功:

刷新浏览器,可以看到刚才发布的组件库。

3 测试使用组件库

3.1 创建新项目

使用 vite 或 yyg-cli 创建新的 vue 项目:

pnpm create vite

进入新创建的 vue 项目,pnpm install 安装依赖,依赖安装成功后先执行 pnpm run dev 测试项目是否正常运行。

3.2 安装依赖

由于咱们的组件库依赖于 element-plus,故首先安装element-plus:

pnpm install element-plus

由于安装咱自己的组件库需要指定 registry,registry 变了,pnpm 需要重新执行 install:

pnpm install --registry http://localhost:4873/

最后指定 registry 安装咱们的组件库:

pnpm install yyg-demo-ui --registry http://localhost:4873/

3.3 引入组件库

在 main.ts 中引入 element-plus 和 yyg-demo-ui:

...
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import YygDemoUi from 'yyg-demo-ui'

createApp(App)
    .use(ElementPlus)
    .use(YygDemoUi)
    .mount('#app')

在 App.vue 中使用组件库中的 foo 组件:

<yyg-foo msg="测试组件库"></yyg-foo>

启动项目,测试运行效果。从浏览器和浏览器 console 中可以看出一切正常。这样组件库便成功发布了。

4 其他说明

  1. 发布到 npmjs 与本地发布的操作一样,registry 需要指定为 https://registry.npmjs.org/
  2. 无论是发布到本地还是 npmjs,如果提示无权限,都可以使用 npm login 先登录:
npm login --registry http://xxxxxx
  1. 再次发布前需要修改版本号。可以使用如下 npm 命令修改版本号:
// 最后一位(patch)版本号加1
npm version patch

// 中间一位(minor)版本号加1
npm version minor

// 第一位(major)版本号加1
npm version major

组件库的打包构建和发布,咱就聊到这里。

感谢阅读本文,如果本文给了你一点点帮助或者启发,还请三连支持一下,了解更多内容工薇号“程序员优雅哥”。

个人项目实战2,springboot集成(Html+vue.js)前端框架

前言

上一篇:【个人项目实战】1,搭建springboot+mybatis框架项目

为了减少项目部署简单,因此将前端与后端写在同一项目中,但风格仍是前后端分离的方式,前端使用的vue.js的框架来实现前端页面开发,后端采用的json报文的接口方式。

使用vue的好处:
1,它帮我完成了变量的双向绑定,自动赋值
2,样式统一且美观

一,导入VUE组件库

js文件可从https://unpkg.com里进行下载,然后放置项目本地

<!--https://unpkg.com/element-ui@2.14.1/lib/theme-chalk/index.css-->
    <!--https://unpkg.com/element-ui@1.4.13/lib/theme-default/fonts/element-icons.woff-->
<link rel="stylesheet" href="../../css/index.css">

<!-- import Vue before Element -->
<script src="../../js/vue.js"></script>
<script src="../../js/axios.js"></script>

<!-- import JavaScript -->
<script src="../../js/index.js"></script>

二,springboot引入html

1,springboot配置文件中配置静态资源

2,编写一个html


通过相对路径来访问html页面。
http://localhost:8086/html/doctor/ylCard.html
(还未精修):

3,关键代码

(1)引入饿了么CSS

<head>
    <meta charset="UTF-8">
    <title>
        医疗账户管理
    </title>
    <!-- import CSS -->
    <!--https://unpkg.com/element-ui@2.14.1/lib/theme-chalk/index.css-->
    <!--https://unpkg.com/element-ui@1.4.13/lib/theme-default/fonts/element-icons.woff-->
    <link rel="stylesheet" href="../../css/index.css">
</head>

(2)引入关键JS

<!-- import Vue before Element -->
<script src="../../js/vue.js"></script>
<script src="../../js/axios.js"></script>
<script src="../../js/httpUtil.js"></script>
<!-- import JavaScript -->
<script src="../../js/index.js"></script>

(3)编写页面body内容

<body>
<div id="app" v-cloak>
    <div style="padding: 20px;">
        <div>
            <div class="commonCss">
                <el-row>
                    <el-col :span="3" class="firstCol line-height-32" style="text-align: right;">
                        医疗账号:
                    </el-col>
                    <el-col :span="4">
                        <el-input v-model="ylCard" style="border:0px;"></el-input>
                    </el-col>
                    <el-col :span="3" class="firstCol line-height-32" style="text-align: right;">
                        户主姓名:
                    </el-col>
                    <el-col :span="4">
                        <el-input v-model="master" style="border:0px;"></el-input>
                    </el-col>
                </el-row>
                <el-row>
                    <el-col :span="20">
                    </el-col>
                    <el-col :span="2">
                        <el-button size="small" type="info" plain @click="clear">
                            重 置
                        </el-button>
                    </el-col>
                    <el-col :span="2">
                        <el-button size="small" type="primary" icon="el-icon-search" :loading="loading"
                                   @click="queryClick">
                            <b>查 询</b>
                        </el-button>
                    </el-col>
                </el-row>
                <el-row class="fromHeader">
                    <el-col :span=3>
                        <span class="titleTop"></span>
                        <span class="headerText">
                            查询结果
                          </span>
                    </el-col>
                </el-row>
            </div>
            <el-table ref="singleTable" :data="migrationResultList" v-loading="loading" :border=true
                      tooltip-effect="dark"
                      highlight-current-row max-height="500" style="width: 100%;"
                      :default-sort="prop: 'createDate', order: 'descending'">
                <el-table-column prop="ylCard" label="医疗账号" show-overflow-tooltip width="500">
                </el-table-column>
                <el-table-column prop="master" label="户主姓名" show-overflow-tooltip width="400">
                </el-table-column>
                <el-table-column prop="createDate" label="创建时间" show-overflow-tooltip sortable width="400">
                </el-table-column>
            </el-table>
            <div class="pagination-block">
                <el-pagination :current-page="currentPage" :page-sizes="pageSizes" :total="total"
                               :page-size="currentPageSize"
                               layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
                               @current-change="handleCurrentChange"/>
            </div>
        </div>
    </div>
</div>
</body>

(4)编写变量与事件方法

<script type="module">
    new Vue(
        el: '#app',
        data: function () 
            return 
                migrationResultList: [],
                ylCard: '',
                master: '',
                createDate: '',
                currentPage: 1,
                total: 0,

                currentPageSize: 10,
                pageSizes: [10, 50, 100, 200, 300],
                loading: false
            
        ,
        methods: 
            handleSizeChange(pageSize) 
                this.currentPage = 1;
                this.currentPageSize = pageSize;
                this.queryClick();
            ,
            handleCurrentChange(page) 
                this.currentPage = page;
                this.queryClick();
            ,
            clear() 
                this.ylCard = '';
                this.master = '';
            ,
            queryClick() 
                this.loading = true;
                alert("出发查询按钮单击事件");
                const params = 
                    'epmMigrationResultBo.createdBy': this.createdBy,
                    'epmMigrationResultBo.pageData.pageNum': this.currentPage,
                    'epmMigrationResultBo.pageData.pageSize': this.currentPageSize
                ;
                // 调用后端--查询接口
                httpUtil.httpPost("",params).then(result => 
                    if (result.code == '0000') 
                        this.migrationResultList = result.rows.map(item => 
                            return item;
                        );
                        this.total = result.total;
                     else 
                        alert(result.msg);
                    
                    this.loading = false;
                );
            

        
    )
</script>

三,踩过的坑

1,页面的部门图标显示方框(错误)

原因是找不到框架的特殊符号编码
后来发现是由于下边的两个文件的版本和index.css,index.js的版本不一致导致的。

解决方法:
取同一版本的文件即可,比如我这里是从https://unpkg.com/browse/element-ui@2.14.1/lib/
取的这四个文件,重新导入后启动项目正常了

总结

html集成vue.js组件总而言之就是导入关键的几个js和css,然后剩下的工作是就从饿了么组件库选取自己想要的元素标签来做前端:https://element.eleme.cn/#/zh-CN/component/installation

下一篇:【个人项目实战】3,springboot集成mybatis分页插件

以上是关于Vue3 企业级优雅实战 - 组件库框架 - 11 组件库的打包构建和发布的主要内容,如果未能解决你的问题,请参考以下文章

PrimeVue - 全面升级!免费开源优雅好用的 Vue3 UI 组件库,可选主题超多

百度云mksz466Vue3.0+TS打造企业级组件库前端中高级开发者必修课

组件库实战 | 用vue3+ts实现全局Header和列表数据渲染ColumnList

Vue3 UI 框架候选

使用vite构建Vue3组件库,发布npm包

vue3 构建属于自己的组件库dxui