核心要点
- 通过 webpack 搭建运行环境
- 通过 gulp 执行编译流程
- 通过 rollup 编译组件代码
- 编写 组件
- 测试 组件
- 打包 编译组件
- 上传 npm
1、通过 webpack 搭建运行环境
这里主要是创建一个可以运行的测试的组件的环境,全局安装vue-cli脚手架,并初始化项目
vue create mtt-component
修改文件夹名称和基本配置的修改
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:rollup', [], {stdio: 'inherit'});done();
});//gulp执行流程
gulp.task('default', gulp.series(['cleanComponents', 'buildStyles', 'buildComponents'], done => {console.log('编译成功');done();
}));
3、通过 rollup 编译组件代码
安装rollup编译流程中所需要用到的插件
npm install -D @rollup/plugin-babel@6.0.3 rollup-plugin-vue@5.1.9 @rollup/plugin-node-resolve@15.0.1 @rollup/plugin-commonjs@24.0.1 @rollup/plugin-json@6.0.0 @rollup/plugin-terser@0.4.0 rollup-plugin-postcss@4.0.2
在根目录的build文件底下创建一个rollup.config.js的文件
// rollup.config.js
const babel = require('@rollup/plugin-babel');//在rollup里应用 babel 解析ES6的桥梁
const vue = require('rollup-plugin-vue');//用于处理 .vue文件,针对vue2的文件
const resolve = require('@rollup/plugin-node-resolve');//让rollup可以找到node环境的其他依赖
const commonjs = require('@rollup/plugin-commonjs');//将commonJS代码转译成 esmodule的代码
const json = require('@rollup/plugin-json');//它允许 Rollup 从 JSON 文件导入数据
const terser = require('@rollup/plugin-terser');//压缩代码
const postcss = require('rollup-plugin-postcss');//处理css,它支持css文件的加载、css加前缀、css压缩、对scss/less的支持等等
const postcssPlugin = require('./postcss.config.js');//postcss配置文件
const {getPackageFiles} = require('./utils.js');//获得所有组件路径及名称//rollup插件基本配置
const getConfigBase = function () {return {plugins: [resolve(),vue({css: true,compileTemplate: true,style: {postcssPlugins: postcssPlugin}}),json(),commonjs(),babel({babelHelpers: 'bundled',exclude: 'node_modules/**',extensions: ['.mjs', '.js', '.json', '.ts'],presets: [['@babel/preset-env',{'targets': {'ie': '8'}}]]}),postcss({extensions: ['.css', '.scss'],extract: true,plugins: postcssPlugin}),terser({format: {comments: RegExp('eslint-disable')}})],external: ['vue',]};
};//rollup文件完整配置
const getConfigArray = (function () {let componentsObject = getPackageFiles();let formatArray = ['es', 'cjs', 'umd'];let filesArray = formatArray.reduce((preArr, format) => {let resArr = [];let data = getConfigBase();data.input = {};data.output = {banner: '/* eslint-disable */ ',dir: `./dist/${format}`,format: format,name: 'mtt',globals: {vue: 'Vue' // 告诉rollup全局变量Vue即是vue}};for (let x of componentsObject) {let item = {};item[x.inputName] = x.inputPath;data.input = {...data.input,...item};if (format === 'umd') {break;}}resArr.push(data);return preArr.concat(resArr);}, []);return filesArray;
})();module.exports = getConfigArray;
4、编写组件
现在chatgpt这么火,借助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进行开发,只需要改变rollup的部分插件即可,不过建议可以和vite架构结合,关于vite版本的可以看我另外一篇博客,通过gulp+vite搭建vue3组件库
- 文章中的代码地址在这里