1.前言一直想搭建自己的博客系统,今年年底终于有时间开发了。在开发后台cms系统的时候,用到了antd的组件库,突然问自己,组件库是怎么实现的,内部是怎么工作的,打包部署的原理,带着这些问题,我开始萌生了自己开发一个组件库。去做就对了。我用了大约2个月的时间才完成了deer-ui第一版的组件开发。现分享出来,记录下自己在开发过程中踩过的坑。deer-ui源码|官网预览地址二、组件库开发准备工作需求准备首先确定需求,初步考察流行的组件库,如antd、vant、zarm-web、cuke-ui、iview等,最后选择antd作为ui参考。技术准备组件库预览网站技术选择,比较了几个(docz、styleguidist、storebook),最终选择storebook作为展示网站,不限于此,项目还集成了docz、styleguidist封装,有需要的可以实现。最终确定了两种组件调试方案,可根据需求定制。1、在源码中使用create-react-app搭建react环境。在example文件夹下,使用npmrundev打开调试环境,导入编写好的组件。2、在源码中搭建一套组件库的文档部署环境,使用命令npmrunstorybook进入文档模式,导入编写好的组件。组件库代码打包。参考了几个比较流行的组件库后,决定自己手写打包配置文件来打包发布版本。组件库引入自动发布,运行脚本后直接发布npm仓库第一期的组件分类。由于时间原因,不可能一次开发完所有的组件,所以第一阶段准备开发以下16个组件3.构建项目3.1项目结构.storebookstorebook的一些配置组件放置所有组件example组件调试环境代码脚本发布,打包脚本文件stories项目静态文件,负责demo演示和一些配置文件Module、commonjs、script脚本的引入,这就需要我们的组件库满足这些规范。通常使用webpack将它们打包成umd规范,以满足上述不同的导入。...模式:“生产”,条目:{[名称]:[”。/components/index.js”]},输出:{路径:path.join(process.cwd(),“dist”),库:name,libraryTarget:"umd",umdNamedDefine:true,filename:"index.js",},...打包入口为components/index.js文件,主要是导出组件export{defaultasButton}from'./button';export{defaultasTabs}from'./tabs';export{defaultasIcon}from'./icons';打包后,所有打包的组件都会在dist目录下生成一个index.js文件。其他的webpack配置就不一一详述了。如有必要,检查脚本目录。3.3按需加载组件打包3.3.1打包js文件通过上述webpack打包的组件库代码全部导入,所有组件代码一起打包。为了减小导入的组件库的大小,一般采用按需加载的方式。按需加载的核心是将各个组件单独打包,单独导入。通过babel打包js文件"build:lib":"cross-envOUTPUT_MODULE=commonjsbabelcomponents-dlib""build:es":"babelcomponents-des",3.3.2打包样式文件各样式文件component将其解压到lib和es文件对应的components下,css打包代码如下。这块是基于cuke-ui的配置,通过gulpflow打包css文件。/***@namegulpfile.js*@description打包项目css依赖*/constpath=require("path");constgulp=require("gulp");constconcat=require("gulp-concat");constless=require("gulp-less");constautoprefixer=require("gulp-autoprefixer");constcssnano=require("gulp-cssnano");constsize=require("gulp-filesize");constsourcemaps=require("gulp-sourcemaps");constrename=require("gulp-rename");const{name,browserList}=require("../package.json");constDIR={less:path.resolve(__dirname,"../components/**/*.less"),buildSrc:[path.resolve(__dirname,"../components/**/style.less"),path.resolve(__dirname,"../components/**/index.less")],lib:path.resolve(__dirname,"../lib"),es:path.resolve(__dirname,"../es"),dist:路径。resolve(__dirname,"../dist")};gulp.task("copyLess",()=>{returngulp.src(DIR.less).pipe(gulp.dest(DIR.lib)).pipe(gulp.dest(DIR.es));});gulp.task("copyCss",()=>{returngulp.src(DIR.buildSrc).pipe(sourcemaps.init()).pipe(less({outputStyle:"compressed"})).pipe(autoprefixer({browsers:browserList})).pipe(size()).pipe(cssnano()).pipe(gulp.dest(DIR.lib)).pipe(gulp.dest(DIR.es));});gulp.task("dist",()=>{returngulp.src(DIR.buildSrc).pipe(sourcemaps.init()).pipe(less({outputStyle:"compressed"})).pipe(autoprefixer({browsers:browserList})).pipe(concat(`${name}.css`)).pipe(size()).pipe(gulp.dest(DIR.dist)).pipe(sourcemaps.write()).pipe(size()).pipe(gulp.dest(DIR.dist)).pipe(cssnano()).pipe(concat(`${name}.min.css`)).pipe(size()).pipe(gulp.dest(DIR.dist)).pipe(sourcemaps.write()).pipe(size()).pipe(gulp.dest(DIR.dist));});gulp.task("默认",gulp.series(["copyLess","copyCss","dist"]));3.3.3组件库文档构建通过storybook构建文档,文档地址预览。具体配置如下importReactfrom"react";import{configure,addDecorator,addParameters}from'@storybook/react';const{name,repository,version}=require("../package.json")import{configureActions}from'@storybook/addon-actions';import'@storybook/插件控制台';导入“@storybook/addon-options/register”;import"../stories/style/index.less"import"../stories/style/code.less"functionloadStories(){//介绍require('../stories/index');//基本组件require('../stories/basis');//数据展示require('../stories/showData');//操作反馈require('../stories/feedback');//交互组件require('../stories/interaction');//布局组件require('../stories/layout');}configureActions({depth:100})//加载配置addParameters({options:{name:`${name}v${version}`,title:"Deer-ui",url:repository,showSearchBox:false,showPanel:false,enableShortcuts:false,isToolshown:false,selectedPanel:undefined,hierarchySeparator:null,hierarchyRootSeparator:null,showAddonPanel:false,}})//中间内容保证金addDecorator(story=>
