Vue3 学习搭建组件库---(环境搭建)

246 阅读3分钟

git地址:github.com/Xaw-xu/vue3…

准备工作

1. 安装lerna
`  npm i lerna -g  `
2. 初始化
`  lerna init`

1.png

3. 修改 lerna.json 配置
    "npmClient":"yarn", // 使用yarn管理包
    "useWorkspaces": true // 使用工作区

2.png

4. 修改 package.json 配置
    "workspaces":[
    "packages/*" // 设置工作区包
  ],

3.png

3. 执行 yarn 命令 (可以让我们写的包安装到nodemodules中)

开始创建第一个组件Button

1. 执行 lerna create button 命令,输入包名及相关信息

4.png

会生成一下几个相关文件

5.png

同样操作,再生成一个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 组件同理

6.png

创建主包(可以整体引入也可单独引入)

执行 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
}

7.png

新建一个website文件夹用来看效果

导入组件库 8.png

安装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.jsconst 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语法
            ]
        }
    ]
}

9.png

10.png

 package.json 配置脚本,将项目跑起来可以看到效果
 "scripts":{
    "website-dev":"webpack serve --config  ./website/webpack.config.js"
  }

11.png

新建样式管理文件

lerna create theme-chalk

12.png

icon就在https://www.iconfont.cn/随意添加几个,添加的时候将前缀改成组件库名称相关的前缀,
这里选的是font-class下载至本地的方式引入

13.png

将icon资源放到fonts文件下,给组件icon添加样式,将路径以及默认的选择器改成如下

14.png

15.png

16.png

icon添加好后,重新yarn一下,将新加的样式包添加至项目,就可以在website中的main.ts中导入

17.png

给icon组件添加一个props控制icon,就可以使用了

18.png

19.png

20.png

安装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"

21.png

22.png

组件打包

组件库的打包格式
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(),
    ]
}

23.png

添加相关打包命令,即可在main.ts中使用

24.png

25.png

安装rollup ,打包esmodule格式组件库
yarn add rollup rollup-plugin-typescript2 @rollup/plugin-node-resolve rollup-plugin-vue -D -W
新建rollup.config.js 先将整个包以esmodule格式打包

26.png

添加命令行 "build:esm-bundle": "rollup -c ./builds/rollup.config.bundle.js"
尝试打包运行,在website中main.ts引入看效果(这里报红了,但是是可以运行的)

28.png

29.png

上面是整个包进行打包,下面尝试将每个包单独打包,可以按需导入
新建rollup.config.js

30.png

添加命令行 "build:esm": "rollup -c ./builds/rollup.config.js"
尝试打包运行,在website中main.ts引入看效果

31.png

29.png

环境准备到此完成,后面就是专注组件编写