核心要点
- 通过 vite 搭建运行环境
- 通过 gulp 执行编译流程
- 通过 vite 编译组件代码
- 编写 组件
- 测试 组件
- 打包 编译组件
- 上传 npm
1、通过 vite 搭建运行环境
这里主要是创建一个可以运行的测试的组件的环境,全局安装vite脚手架,并初始化项目
npm create vite@latest mtt-component-vite -- --template vue
修改文件夹名称和基本配置的修改
2、通过 gulp 执行编译流程
安装gulp执行流程中所需要用到的插件
npm install -D gulp@4.0.2 fs-extra@11.1.0 cross-spawn@7.0.3 sass gulp-sass gulp-postcss autoprefixer@9.8.6
在根目录的build文件底下创建一个gulpfile.js的文件
//gulpfile.js
const gulp = require('gulp');//执行流程
const fs = require('fs-extra');//该插件主要用于操作文件
const spawn = require('cross-spawn');//该插件主要用于运行终端命名
const sass = require('gulp-sass')(require('sass'));//该插件用于将sass编译成css
const postcss = require('gulp-postcss');//该插件处理css
const autoprefixer = require('autoprefixer');//该插件为css自动加前缀
const {pathDist, pathPackagesStyles} = require('./path.config.js');//公共路径配置
//清空组件文件
gulp.task('cleanComponents', done => {
fs.removeSync(`${pathDist}/cjs`);
fs.removeSync(`${pathDist}/es`);
fs.removeSync(`${pathDist}/umd`);
fs.removeSync(`${pathDist}/styles`);
done();
});
//打包编译css
gulp.task('buildStyles', done => {
gulp.src(`${pathPackagesStyles}/**/*.scss`)
.pipe(sass().on('error', sass.logError))
.pipe(postcss([
autoprefixer({
overrideBrowserslist: [
'last 2 version',
'>1%',
'ios 7'
]
})
]))
.pipe(gulp.dest(`${pathDist}/styles`));
done();
});
//构建组件
gulp.task('buildComponents', done => {
spawn.sync('npm run build:vite', [], {stdio: 'inherit'});
done();
});
//gulp执行流程
gulp.task('default', gulp.series(['cleanComponents', 'buildStyles', 'buildComponents'], done => {
console.log('编译成功');
done();
}));
3、通过 vite 编译组件代码
在根目录的build文件底下创建一个vite.build.js的文件
// vite.build.js
const path = require('path');
const {build, defineConfig} = require('vite');
const vue = require('@vitejs/plugin-vue');//用于处理 .vue文件,针对vue3的文件
const autoprefixer = require('autoprefixer');//该插件为css自动加前缀
const {pathDist} = require('./path.config.js');//公共路径配置
const {getPackageFiles} = require('./utils.js');//获得所有组件路径及名称
// 所有组件列表
const arrayComponents = getPackageFiles();
// 基础配置
const configBaseVite = {
configFile: false,
publicDir: false,
cssCodeSplit: true,
plugins: [
vue({
style: {
css: true,
compileTemplate: true,
postcssPlugins: [autoprefixer({
overrideBrowserslist: [
'last 2 version',
'>1%',
'ios 7'
]
})]
}
})
]
};
// 基础配置- rullup
const configBaseRollup = {
external: ['vue'],
output: {
globals: {
vue: 'Vue',
},
},
};
// 全量构建
const buildIndex = async (format) => {
await build({
...configBaseVite,
build: {
rollupOptions: configBaseRollup,
lib: {
entry: arrayComponents[0].inputPath,
name: 'index',
fileName: format => `[name].js`,
formats: [format]
},
outDir: path.resolve(pathDist, format)
}
});
};
// 单个组件构建
const buildSingle = async (item, format) => {
await build({
...configBaseVite,
build: {
rollupOptions: configBaseRollup,
lib: {
entry: item.inputPath,
name: 'index',
fileName: format => `[name].js`,
formats: [format]
},
outDir: path.resolve(pathDist, `${format}/${item.outputPath}`)
}
});
};
// 总打包入口
const buildDist = async () => {
const formatArray = ['es', 'cjs', 'umd'];
const childComponents = arrayComponents.slice(1, arrayComponents.length);
for (let format of formatArray) {
await buildIndex(format);
if (format === 'umd') {
continue;
}
for (let item of childComponents) {
await buildSingle(item, format);
}
}
return defineConfig({
mode: 'production'
});
};
buildDist()
4、编写组件
借助chatgpt编写了个简单的button组件
然后,在button文件夹下,建立一个index.js,用于导出单个组件
import button from './button.vue'
// 为组件提供 install 安装方法,供按需引入
button.install = function (Vue) {
Vue.component(button.name, button)
}
// 默认导出组件
export default button
然后,在components的根目录下,建立一个index.js,该文件用于导出所有组件
// 导入按钮
import MttButton from './button'
// 存储组件列表
const components = [
MttButton
]
// 定义 install 方法,接收 Vue 作为参数。如果使用 use 注册插件,则所有的组件都将被注册
const install = function (Vue) {
// 判断是否安装
if (install.installed) return
// 遍历注册全局组件
components.map(component => Vue.component(component.name, component))
}
// 判断是否是直接引入文件
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue)
}
export default {
// 导出的对象必须具有 install,才能被 Vue.use() 方法安装
install,
// 以下是具体的组件列表
MttButton
}
5、测试组件
在业务端引入组件
运行到浏览器,运行成功了,得出了预期的结果
6、打包编译组件
终端运行打包命令
npm run build
打包完后,得到dist目录下的打包后的代码,为了方便测试,我们先不上传到npm,而是通过npm link软连接的方式,引入组件再次测试,得到一样的结果
7、上传 npm
配置 package.json,通过npm publish即可上传至npm,要注意的事,上传npm时,不要用淘宝镜像,切换npm自身的镜像,否则会有10分钟的延迟
到npm官网查看下,发现我们的发布的组件库已经成功了
8、附加说明
- 该组件库可以支持全量引入和按需引入,关于按需引入方面,可以参考 element的按需引入方式
- 目前该组件库的基础架构既可以针对vue2开发,也可以针对vue3进行组件库开发
- 另外也写了一篇 通过 Gulp+Rollup 从零到一搭建前端组件库的文章