git地址:github.com/Xaw-xu/vue3…
准备工作
1. 安装lerna
` npm i lerna -g `
2. 初始化
` lerna init`
3. 修改 lerna.json 配置
"npmClient":"yarn", // 使用yarn管理包
"useWorkspaces": true // 使用工作区
4. 修改 package.json 配置
"workspaces":[
"packages/*" // 设置工作区包
],
3. 执行 yarn 命令 (可以让我们写的包安装到nodemodules中)
开始创建第一个组件Button
1. 执行 lerna create button 命令,输入包名及相关信息
会生成一下几个相关文件
同样操作,再生成一个icon组件,将lib文件改为src,后续在src下面写相关代码
2. 创建.vue 相关文件,初始化ts
yarn add typescript -W 安装ts在根目录,因为所有的组件都会用到
npx tsc --init 初始化ts文件
tsconfig.json 文件配置如下
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig.json to read more about this file */
"target": "ESNext", // 打包的目标语法 es6
"module": "ESNext", // 模块转化后的格式
"esModuleInterop": true, // 支持模块转化 esmodule 和 commonjs
"skipLibCheck": true, // 忽略编译器检查公共库
"forceConsistentCasingInFileNames": true, // 强制区分大小写
"moduleResolution": "node", // 模块解析方式
"jsx": "preserve", // 不转化 jsx
"declaration": true, // 生成申明文件
"sourceMap": true, // 生成映射文件
}
}
3. 创建typings 类型文件夹
yarn add vue@next -W 安装vue
创建vue-shim.d.ts文件
declare module '*.vue' {
import {App, defineComponent} from 'vue';
const component:ReturnType<typeof defineComponent> & {install(app:App):void}; // 获取组件类型,install 方法 组件注册会用到
export default component
}
4. Button 组件添加注册方法 install
在button包下新建index.ts文件,内容为
import { App } from 'vue';
import Button from './src/button.vue';
Button.install = function (app:App) {
// 注册组件
app.component(Button.name, Button);
}
type IWidthInstall<T> = T & {install(app:App):void};
const _Button:IWidthInstall<typeof Button> = Button;
export default _Button;
icon 组件同理
创建主包(可以整体引入也可单独引入)
执行 lerna create z-ui
执行 yarn 将两个包生成包文件,后面可以以包的形式导入
在主包新建index.ts(将此处自动生成的lib文件夹删除)
import { App } from 'vue'
import Button from '@z-ui/button'
import Icon from '@z-ui/icon'
const components = [
Button,
Icon
]
const install = function (app: App) {
components.forEach(component => {
app.component(component.name, component)
})
}
// 后面可以使用 createApp().use(xxx) 来注册组件
export default {
install
}
新建一个website文件夹用来看效果
导入组件库
安装webpack相关依赖
yarn add webpack webpack-cli webpack-dev-server vue-loader@next @vue/compiler-sfc -D -W
yarn add babel-loader @babel/core @babel/preset-env @babel/preset-typescript @babel/plugin-transform-typescript url-loader
file-loader html-webpack-plugin css-loader sass-loader style-loader sass -D -W
webpack 配置(webpack.config.js)
const HTMLWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const {VueLoaderPlugin} = require('vue-loader');
module.exports = {
mode:'development',
devtool:'source-map',
entry: path.resolve(__dirname,'main.ts'),
output:{
path:path.resolve(__dirname,'../website-dist'),
filename:'bundle.js',
},
resolve:{
extensions:['.ts','.tsx','.js','.vue'],
},
module:{
rules:[
{
test:/\.(js|ts)x?$/,
exclude:/node_modules/,
loader:'babel-loader',
},
{
test:/\.vue$/,
loader:'vue-loader',
},
{
test:/\.(svg|otf|ttf|woff|eot|gif|png|jpg)$/,
loader:'url-loader',
},
{
test:/\.(scss|css)$/,
use:['style-loader','css-loader','sass-loader'],
}
]
},
plugins:[
new VueLoaderPlugin(),
new HTMLWebpackPlugin({
template:path.resolve(__dirname,'./templae.html'),
})
]
}
babel 配置(babel.config.js)
module.exports = {
presets:[//babel 解析预设 反着执行
'@babel/preset-env',
'@babel/preset-typescript',
],
overrides:[
{
test:/\.vue$/,
plugins:[
'@babel/plugin-transform-typescript',//解析vuets语法
]
}
]
}
package.json 配置脚本,将项目跑起来可以看到效果
"scripts":{
"website-dev":"webpack serve --config ./website/webpack.config.js"
}
新建样式管理文件
lerna create theme-chalk
icon就在https://www.iconfont.cn/随意添加几个,添加的时候将前缀改成组件库名称相关的前缀,
这里选的是font-class下载至本地的方式引入
将icon资源放到fonts文件下,给组件icon添加样式,将路径以及默认的选择器改成如下
icon添加好后,重新yarn一下,将新加的样式包添加至项目,就可以在website中的main.ts中导入
给icon组件添加一个props控制icon,就可以使用了
安装gulp,打包scss
yarn add gulp gulp-autoprefixer gulp-cssmin gulp-dart-sass gulp-rename -D -W
在样式文件theme-chalk中新建gulpfile.js配置文件,将之前的资源放入src目录
const {series,src,dest} = require('gulp');
const sass = require('gulp-dart-sass');
const autoprefixer = require('gulp-autoprefixer');
const cssmin = require('gulp-cssmin');
function compile() {
return src('./src/*.scss')
.pipe(sass())
.pipe(autoprefixer())
.pipe(cssmin())
.pipe(dest('./lib'));
}
function coypfont() {
return src('./src/fonts/**')
.pipe(cssmin())
.pipe(dest('./lib/fonts'));
}
exports.build = series(compile, coypfont);
添加打包命令,打包后会生成lib文件夹
"build:theme": "gulp build --gulpfile packages/theme-chalk/gulpfile.js"
组件打包
组件库的打包格式
1.整个打包umd格式
2.esModule
3.组件按需加载,需要把每个文件单独打包
根目录创建builds文件夹,新建webpack.config.js配置组件打包的config
const path = require('path');
const {VueLoaderPlugin} = require('vue-loader');
module.exports = {
mode:'production',
entry: path.resolve(__dirname,'../packages/z-ui/index.ts'),
output:{
path:path.resolve(__dirname,'../lib'),
filename:'index.js',
libraryTarget:'umd', // 可以支持commonjs 和 amd 不支持es6,可以在浏览器中使用
library:'z-ui',
},
externals:{
vue:{// 忽略组件引用的vue变量
root:'Vue',
commonjs:'vue',
commonjs2:'vue'
}
},
resolve:{
extensions:['.ts','.tsx','.js','.vue'],
},
module:{
rules:[
{
test:/\.(js|ts)x?$/,
exclude:/node_modules/,
loader:'babel-loader',
},
{
test:/\.vue$/,
loader:'vue-loader',
},
]
},
plugins:[
new VueLoaderPlugin(),
]
}
添加相关打包命令,即可在main.ts中使用
安装rollup ,打包esmodule格式组件库
yarn add rollup rollup-plugin-typescript2 @rollup/plugin-node-resolve rollup-plugin-vue -D -W
新建rollup.config.js 先将整个包以esmodule格式打包
添加命令行 "build:esm-bundle": "rollup -c ./builds/rollup.config.bundle.js"
尝试打包运行,在website中main.ts引入看效果(这里报红了,但是是可以运行的)
上面是整个包进行打包,下面尝试将每个包单独打包,可以按需导入
新建rollup.config.js
添加命令行 "build:esm": "rollup -c ./builds/rollup.config.js"
尝试打包运行,在website中main.ts引入看效果
环境准备到此完成,后面就是专注组件编写