为了多喝两杯奶茶☕,我给自己的项目写了自动化脚本

8,063 阅读6分钟

这是我参与8月更文挑战的第31天,活动详情查看:8月更文挑战

🍃 前言

  • 事情是这样的,之前有段时间在搭自己的组件库,每次新增一个组件的时候都需要进行一些重复的操作
    • 创建一个组件文件夹
    • 文件夹里面新增两个文件分别是.vueindex.js分别用来编写组件代码和导出组件
    • styles文件夹里面新建一个.scss文件来存放该组件的样式
    • styles文件夹里引入刚刚创建的.scss
    • 在主index.js文件里引入刚刚创建的组件并注册
    • 在文档里面创建该组件的示例
  • 原本我以为每次新增一个组件花不了多少时间,直到我不小心测试了一下我每次创建新组件基础文件时用的时间...🤷‍♂️

time.jpg

  • 好家伙我每次光是添加基本的初始化文件就用了快4分钟??这4分钟我都可以下楼去奶茶店买杯喝的了...
  • 每次都是重复机械式的操作,其实仔细一想这些文件里面本质上没什么变动,就是关键信息组件名称不同罢了...🤦‍♂️
  • 众所周知,我们程序员就是为了产出让人更有 效(更)率(懒) 的办法,刚好前段时间重新看了会node,那我们就用node来写一个自动化脚本吧。

细节.jfif

👨‍💼 ToDoList

  • 创建配置文件和基本目录
  • 创建组件目录
  • 创建组件文件
  • 引入组件样式
  • 引入组件

👨‍💻 Just Do It

创建配置文件和基本目录

  • 首先创建一个auto文件夹来存放我们所有的文件,下面是目录树。
auto
├─ addComponent
│  ├─ add.js
│  └─ data.js
└─ page
   └─ index.js
  • add.js主要是存放我们主要的node操作代码。
  • data.js主要是存放我们的组件名称和要生成的目录名称,例如一个button组件和radio组件是这样配置的:
/** data.js **/
exports.data = [
  {
      folder:'button',
      componentsName:'button',
  },
  {
      folder:'radio',
      componentsName:'radio',
  }
];
  • index.js主要存放我们的所有模板,也就是我们希望的文件初始化的样子,具体下面会讲到。

创建组件目录

  • 因为我们的组件结构和样式是分别存放在src文件夹内的packages目录和styles目录中,也就是说我们接下来要生成的文件是要放在这两个目录里面(这里的路径是我自己的项目,不同项目的路径要自己调整喔~)
/** add.js **/
const fs = require("fs");
const path = require("path");
// 创建目录
function mkdirsSync(dirname) {
    //判断目录是否存在
  if (fs.existsSync(dirname)) {
      return true;
  } else {
      if (mkdirsSync(path.dirname(dirname))) {
          fs.mkdirSync(dirname);
          return console.log(`创建目录成功-${dirname}`);
      }
  }   
}
mkdirsSync(`./src/packages`);
mkdirsSync(`./src/styles`);
  • 我们使用fs模块的existsSync来检查目录是否存在,使用mkdirSync来创建对应路径的目录,相关的fs模块学习可以参考「从零开始」前端node够用指北(二)⚡---文件操作
  • 接下来在终端运行一下node ./auto/addComponent/add.js即可生成对应文件夹。
  • 当然每次执行这么长的命令可不行,我们需要在package.json配置一下:
/** package.json **/
  "scripts": {
    ...
    "add":"node ./auto/addComponent/add.js"
  }
  • 接下来每次执行npm run add即可。

image.png

创建组件文件

  • 对于我们的组件文件在我这个项目中主要有三个分别是xx.vue index.js xx.scss
  • 这三个文件有什么共同店呢,就是基本模板是一样的,不同的只是组件名称罢了,比如这个inputinputNumber组件的index.js

image.png

  • 那我们首先需要在page文件夹中的index.js定义三个模板来分别存放这些基本信息。
/** page/index.js **/
exports.indexPage = function (componentsName) {
  return `
import ${componentsName.charAt(0).toUpperCase() + componentsName.slice(1)} from './${componentsName}.vue';
export default ${componentsName.charAt(0).toUpperCase() + componentsName.slice(1)};
  `;
  
};

exports.vuePage = function (componentsName) {
  return `
<template>
    <div class="${componentsName}">

    </div>
</template>
<script>
export default {
  name: '${componentsName}',
  data(){
    return{}
  }
}
</script>
  `;
};

exports.stylePage = function () {
  return `
@charset "UTF-8";
@import "common/var";
@import "mixins/mixins";
  `;
};
  • 如上我们就定义了.vue 文件 index.js文件和.scss文件的模板,中间使用了一些首字母大写等拼接来接收我们的componentsName传进来的组件名称。
  • 定义了模板之后我们要使用呀,要怎么使用?很简单,继续在add.js文件中加入我们的node代码:
/** add.js **/
...
const configData = require("./data");
...
//遍历配置文件并调用创建目录方法
configData.data.forEach((item) => {
  if(item.folder){
      mkdirsSync(`./src/packages/${item.folder}`);
  }
});
  • 在这里首先对在配置文件中的每个组件进行遍历创建相对应的文件夹来存放我们的.vue文件和index.js文件。
  • 执行npm run add,给我们的data.js提前写写好两个组件配置button radio

image.png

  • 文件夹创建成功,接下来我们要在每个文件夹添加相对应模板的.vueindex.js文件并且在styles文件夹中添加对应的.scss文件。
/** add.js **/
...
//引入文件模板
let componentsPage = require("../page/index");
// index模板
let indexPage = componentsPage.indexPage;
//vue模板
let vuePage = componentsPage.vuePage;
//style模板
let stylePage = componentsPage.stylePage;
...
//遍历配置文件创建index、vue、style文件
configData.data.forEach((item) => {
    if(item.componentsName){
        let indexPath=`./src/packages/${item.folder}/index.js`;
        let vuePath=`./src/packages/${item.folder}/${item.componentsName}.vue`;
        let stylePath=`./src/styles/${item.componentsName}.scss`;
        let name=item.componentsName;
        //创建index.js文件
        if (fs.existsSync(indexPath)) {
            console.log(indexPath+'已存在');
        }else{
            fs.writeFile(indexPath, indexPage(name), function(err){
                if(err){
                    return console.log('创建index文件失败', err);
                }
                console.log(`创建index文件成功!-${name}.js`);
            });
        }
        //创建组件vue文件
        if (fs.existsSync(vuePath)) {
            console.log(vuePath+'已存在');
        }else{
            fs.writeFile(vuePath, vuePage(name), function(err){
                if(err){
                    return console.log('创建vue文件失败', err);
                }
                console.log(`创建vue文件成功!-${name}.vue`);
            });
        }
        //创建组件style文件
        if (fs.existsSync(stylePath)) {
            console.log(stylePath+'已存在');
        }else{
            fs.writeFile(stylePath, stylePage(), function(err){
                if(err){
                    return console.log('创建style文件失败', err);
                }
                console.log(`创建style文件成功!-${name}.scss`);
            });
        }
    }
});
  • 以上就是添加对应文件的代码啦,你不要看它很长,其实分开来很好理解,都是一样的操作,请听我细细道来:
    • 首先引入文件模板../page/index.js,分别拿出三个模板用indexPage vuePage stylePage来存放。
    • 再者还是遍历我们的组件配置文件
    • 在遍历过程中我们根据不同的组件提前保存一下路径的变量indexPath vuePath stylePath这个路径等下会使用。
    • 接下来的三个if判断其实都是一样的,目的是为了在对应文件夹写入对应文件,我在上面已经分好了注释,我们来看第一个创建index.js文件。
    • 还是通过fs模块的existsSync判断刚刚定义的路径变量是否存在,这个路径变量其实就是这个index.js文件,如果存在则跳过。
    • 再通过fs模块的writeFile写入相关的信息,将组件名称传进去这样index.js模板就创建完成了。
    • 接下来的vue文件和scss文件也是一样的,值得注意的是如果不进行判断文件是否存在的操作会直接覆盖原油的文件。
  • 怎么样?我这样一说是不是也比较好理解了呢?如果还有不清楚的可以在评论区留言喔~😀
  • 我们执行一下npm run add试试

自动化脚本1.gif

引入组件样式

  • 我们的组件相应的文件都做好了,因为我的项目之前是在styles文件夹的index.scss引入所有的.scss文件,接下来我们只需要每次执行脚本时更新覆盖这个index.scss文件添加新的组件样式即可。
/** add.js **/
...
//一个覆盖index.scss的方法
function dealIndexStyle(){
    let file='';
    configData.data.forEach((item) => {
        //遍历所有组件引入每个组件样式 例如:@import "button";
        let name=item.componentsName; //首字母大写
        file+=`@import "${name}";\n`;
    });
    fs.writeFile(`./src/styles/index.scss`,file,function(err){
        if(err){
            return console.log('主样式文件引入scss失败', err);
        }else{
            console.log('主样式文件引入scss成功');
        }
    });
}
dealIndexStyle();
  • 我们只需要像这样每次运行都重写我们的index.scss文件即可,运行后得到的文件是这样的:

image.png

引入组件

  • 在我的项目中是通过一个addComponents.js文件来引入存放我们的所有组件文件再将其导出,大概的格式是这样的:
/** addComponents.js **/
import xxx from 'xxx';
const allComponents ={
lxxx: xxx,
};
export default allComponents;
  • 所以其实跟上一步的样式是一样的,我们只需要每次对这个文件格式做些处理然后覆盖这个文件即可。
/** add.js **/
...
//遍历配置文件获取对应组件拼装组件初始化
function addComponentsList(){
    let file='';
    let allComponents='';
    configData.data.forEach((item) => {
        //遍历所有组件每个组件添加依赖 例如:import Button from './packages/button';
        let name=item.componentsName.charAt(0).toUpperCase() + item.componentsName.slice(1); //首字母大写
        file+=`import ${name} from './packages/${item.componentsName}';\n`;
    });
    configData.data.forEach((item) => {
        //遍历所有组件每个组件添加   例如:lButton: Button,
        let name=item.componentsName.charAt(0).toUpperCase() + item.componentsName.slice(1); //首字母大写
        allComponents+=`l${name}: ${name},\n`;
    });
    file +=`const allComponents ={\n${allComponents}};\nexport default allComponents;`;
    //写入组件列表
    fs.writeFile(`./src/addComponents.js`,file,function(err){
        if(err){
            return console.log('写入组件列表失败', err);
        }else{
            console.log('写入组件列表成功');
            console.log('结束创建文件');
            console.log('>>>>>>>>>>>>>');
        }
    });
}
addComponentsList();
  • addComponentsList方法里大部分都是对文件内容进行的拼接,主要的代码还是fs模块的writeFile写入功能,每个人的项目内容都不同,以上只是举例我的文件是怎么写的,具体内容还得具体分析。
  • 至此,对于一个组件的初始化的自动化脚本就完成了,我们来看看效果如何。

自动化脚本2.gif

  • 完美!!!!!好了我要去喝奶茶了。

奶茶.jfif

👋 写在最后

  • 好了这次的文章就分享到这里,首先感谢大家看到这里!!!我也没想到我会坚持写作31天,感谢大家对我的支持!!
  • 以上就是我在优化自己项目时候所做的一些小操作,目的就是为了帮助我们减少一些重复机械性的动作,主要是提供一些思路,更细的优化其实还有很多,我们虽然对外说是CV工程师但是真的不仅仅只是会复制粘贴而已,希望可以帮到大家。
  • 记得之前有位大佬说过: 前端如果只是仅仅写页面的话 那你真的只是CV工程师罢了
  • 以上的内容跟着一步步敲是完全没有问题的如果有的话我把源码放在这里,有需要可以自取。
  • 如果您觉得这篇文章有帮助到您的的话不妨🍉关注+点赞+收藏+评论+转发🍉支持一下哟~~😛您的支持就是我更新的最大动力。
  • 大家可以关注公众号『前端快快跑』加入学习交流群。

🌅 往期精彩

一个"剑气"加载🌪️

一个"水"按钮💧

产品经理:你能不能让词云动起来?

一文搞定echarts地图轮播高亮⚡