一,组件发布
1,项目目录结构
2,代码
(1)package.json
{
"name": "tl-app",
"private": false,
"version": "0.1.3",
"type": "module",
"files": [
"lib"
], // 发布的文件清单
"module": "./lib/tl-app.js",
"main": "./lib/tl-app.umd.cjs",
"exports": {
".": {
"import": "./lib/tl-app.js",
"require": "./lib/tl-app.umd.cjs"
}
},
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"build:components": "node --trace-warnings ./command/build.js",
"lib": "npm run build:components",
"test": "jest"
},
"peerDependencies": {
"vue": ">=3.0.0"
},
"devDependencies": {
"@babel/core": "^7.20.5",
"@babel/preset-env": "^7.20.2",
"@babel/preset-typescript": "^7.18.6",
"@types/jest": "^29.2.4",
"@vitejs/plugin-vue": "^3.0.0",
"@vitejs/plugin-vue-jsx": "^2.0.0",
"@vue/test-utils": "^2.0.0-rc.18",
"babel-jest": "^26.6.3",
"jest": "^26.6.3",
"sass": "^1.56.2",
"ts-jest": "^26.5.6",
"vite": "^3.0.0",
"vue": "^3.2.37",
"vue-jest": "^5.0.0-alpha.10",
"async-validator": "^4.2.5",
"mitt": "^3.0.0"
}
}
(2)vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()]
})
(3).npmignore
# 忽略目录
.idea
.vscode
build/
docs/
examples/
src/
packages/
public/
node_modules/
typings/
test/
command/
# 忽略指定文件
.babel.config.js
tsconfig.json
tslint.json
vue.config.js
.gitignore
.browserslistrc
*.map
jest.config.js
(4)command/build.js
/**
* 实现组件全局(全量)打包
* @description 因为通过 node 打包,所以采用 CommonJS 规范,也就是 require
*/
import { createRequire } from 'module';
import path from "path"
const requireds = createRequire(import.meta.url);
const __dirname = path.resolve();
// vite 打包需要的配置
const { defineConfig, build } = requireds('vite');
// vite 插件
const vue = requireds('@vitejs/plugin-vue');
const vueJsx = requireds('@vitejs/plugin-vue-jsx');
// 添加打包入口文件夹 packages(需要手动创建)
const entryDir = path.resolve(__dirname, 'packages');
// 添加出口文件夹 lib(不需要手动创建,会自动生成)
const outDir = path.resolve(__dirname, 'lib');
// vite 配置
const baseConfig = defineConfig({
configFile: false,
publicDir: false,
plugins: [vue(), vueJsx()]
});
// rollup 配置(vite 基于 rollup 打包)
const rollupOptions = {
// 这两个库不需要打包
external: ['vue', 'vue-router'],
output: {
globals: {
vue: 'Vue'
}
}
};
/**
* 全量打包构建的方法
*/
const buildAll = async () => {
await build({
...baseConfig,
build: {
rollupOptions,
lib: {
// 入口
entry: path.resolve(entryDir, 'index.ts'),
// 组件库名字
name: 'tl-app',
fileName: 'tl-app',
// 输出格式
formats: ['es', 'umd']
},
outDir
}
})
};
/**
* 打包成库
*/
const buildLib = async () => {
await buildAll();
};
buildLib();
(5)packages/index.ts
import { App } from 'vue'
import TlButton from './button/index.ts'
const install = (app:App) => { // 进行注册
app.use(TlButton)
}
const LUI = {
install
}
export { // 按需导出
TlButton
}
export default LUI // 默认全部导出
(6)packages/button/index.ts
//index.ts
import { App } from 'vue'
import TlButton from './index.vue'
TlButton.install = (app:App) => {
app.component(TlButton.name, TlButton)
}
export default TlButton
(7)packages/button/index.vue
<template>
<button class="tl-button" :class="[size ? `tl-button--${size}` : '']">
<slot />
</button>
</template>
<script lang="ts">
export default {
name: "TlButton", // 注册的时候会用到
};
</script>
<script setup lang="ts">
import { computed, withDefaults } from "vue";
interface Props {
size?: "" | "small" | "medium" | "large";
}
const props = withDefaults(defineProps<Props>(), {
size: "",
});
</script>
<style lang="scss" scoped>
@import '../styles/mixin.scss';
.tl-button--small {
width: 50px;
height: 20px;
}
.tl-button--medium {
width: 80px;
height: 40px;
}
.tl-button--large {
width: 100px;
height: 50px;
}
</style>
3,组件打包、发布
执行以下指令
组件打包:npm run lib
npm登录(初次上传才需要):npm login -registry=https://registry.npmjs.org/
组件发布:npm publish
注:这个操作需要npm帐号,在官网上直接申请即可
二,组件使用
1,组件下载
npm install tl-app
2,组件引入(main.js)
import { createApp } from 'vue'
import App from './App.vue'
import LUI from 'tl-app';
createApp(App).use(LUI).mount('#app')
3,组件使用(App.vue)
<script setup>
</script>
<template>
<tl-button>测试</tl-button>
</template>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
注:该组件只能供vue3+vite项目引入使用