相信在咱们平常遇到的项目中,不管是在前端网站仍是后台管理系统中都会有功能相似的页面。咱们在开发这些功能相似的页面的时候,为了提升效率,通常都会运用咱们的CV大法。可是当咱们CV久了以后,会不会以为这样的开发方式有些许枯燥?咱们能不能经过代码来生成代码,进一步提升咱们的效率呢?下面咱们就来经过一个例子来探索一下怎么经过node来生成咱们须要的前端代码。html
假设咱们正在作一个后台管理系统(react),页面文件目录结构以下图:前端
page文件夹下有两个文件夹:home和network,他们分别表明了不一样的模块。稍微观察一下,咱们不难发现,这两个模块下面的文件目录结构是同样的,并且部分文件名也是同样的。有些人面对这种状况,包括最开始开发项目的我,可能会想,直接CV,简单快捷。可是这一次,咱先不急,咱们再看看js文件需里面的须要的初始代码:node
结构基本同样,可是模块和组件的名称却不同。react
在上面的这种状况下,咱们是能够对相似的文件夹以及文件进行复制粘贴,可是咱们也必须针对不一样的模块和组件进行重命名等操做,页面文件少还好说,可是当页面比较多的时候,好比有七八个模块以及几十个页面的时候,咱们进行这些无心义的重复操做,会不会比较难受?git
因此咱们可否想一想办法,尽量的规避这些操做?github
泰伦卢:办法?固然是把球传给詹姆斯!后端
开个玩笑。首先,咱们应该再仔细分析一下pages下面的文件,home和network文件夹下面有着相同的文件目录结构,可是部分文件夹下面的文件名称以及内容可能不同。这有点相似与组件的复用,so咱们是否能够利用相似组件复用的思想,编写一个统一的模板,而后给其传递不一样的参数,就能够生成不一样的组件。api
基本思路以下图:框架
经过配置参数的形式来配置咱们的文件夹名称、文件名以及文件模板的参数,而后再一键生成咱们的文件夹、文件和文件的内容。异步
基本思路肯定,可是咱们怎么去自动生成文件夹和文件呢?我相信后端的小伙伴确定不陌生,而前端的小伙伴平时在业务中对于这方面的知识可能涉及的就比较少了。可是只要熟悉node,这一切都不是问题了。
这里咱们就能够利用node的fs(文件系统)API来帮助咱们作这些事。
在node中建立文件(目录)夹有两种方式:
第一种(异步):fs.mkdir(path[, options], callback)
参数
options 参数能够是:
基本用法
fs.mkdir('/pages/home', (err) => { if (err) throw err; });
第二种(同步):fs.mkdirSync(path[, options])
基本用法
fs.mkdirSync('/pages/home');
建立文件也有两种方式:
第一种(异步):fs.writeFile(file, data[, options], callback)
参数
基本用法
fs.writeFile('文件.txt', '你好~', (err) => { if (err) throw err; console.log('文件已被保存'); });
第二种(同步):fs.writeFileSync(file, data[, options])
基本用法
fs.writeFileSync('文件.txt', '你好~');
基本的知识咱们已经有所了解,接下来就可进行代码的编写了。固然电脑上须要有node环境,关于node环境通常来讲你们都应该配置的有,若是实在没有网上搜一下就OK了~
首先搭建好咱们的项目:
主要关注红框里面的文件夹和文件
index.js
为咱们的主程序,文件夹(目录)和文件的生成的程序逻辑都在里面,也是最终运行的文件template里面有两个文件
data.js
为咱们的配置文件,包含了文件夹(目录)和文件名称以及文件模板的参数等配置template.js
为咱们的各类文件的模板这里说一下,由于咱们这里是假设是在react的项目下,因此其它的文件基本上是与react相关的。红框里面的代码逻辑与react不耦合,其它框架下也一样适用。
回到开始的实例,咱们须要在pages文件夹下生成下图格式种的文件夹和文件:
这里须要注意的是,不管是fs.mkdir()
仍是fs.mkdirSync()
,他们都是已有的文件夹上进行建立的,例如咱们要在pages下建立list文件夹,咱们不能直接以下所写:
index.js
const fs = require("fs"); fs.mkdirSync('./page/home/list'); //报错
由于这里的home文件夹是不存在的,因此list文件夹也不会建立成功。正确的应该这样写:
const fs = require("fs"); fs.mkdirSync('./page/home'); fs.mkdirSync('./page/home/list');
固然咱们不可能直接就这样来写,咱们能够利用递归的方式来建立目录:
index.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('./page/home/list');
接下来是配置文件:
data.js
exports.data = [ { folder:'home', }, { folder:'home/list', }, { folder:'home/images' }, { folder:'home/form', }, { folder:'network', }, { folder:'network/list', }, { folder:'network/images' }, { folder:'network/form', } ]
引入配置文件,并进行遍历生成文件:
index.js
const fs = require("fs"); const path = require("path"); //引入配置文件 const profileData = require("./template/data"); // 递归建立目录 同步方法 function mkdirsSync(dirname) { if (fs.existsSync(dirname)) { return true; } else { if (mkdirsSync(path.dirname(dirname))) { fs.mkdirSync(dirname); return console.log(`建立目录成功-${dirname}`); } } } //遍历配置文件并调用建立目录方法 profileData.data.forEach((item) => { if(item.folder){ mkdirsSync(`./pages/${item.folder}`) } })
咱们把目录生成了,生成文件时就主要关注于文件名和文件内容就好了。首先咱们要定义好文件的模板,这里主要要用到模板字符串(``)。由于其中的一些文件内容种的 class的名称不同, 因此在定义模板的时候, 能够为这类模板定义一个参数, 以下所示的className
:
template.js
exports.page = function (className) { return ` import * as React from 'react'; export class ${className} extends React.Component{ constructor(props){ super(props); this.state = {} } componentDidMount(){ } render() { return ( <div></div> ) } } ` } exports.api = `const API = "localhost://8080/my-api";` exports.route = ` import * as React from 'react'; export const route = []; `
模板定义好后, 继续在配置文件data.js添加相应的阿配置项,以下所示的file
和className
:
data.js
exports.data = [ { folder:'home', file:'api.js' }, { folder:'home', file:'route.js' }, { folder:'home/list', file:'home.js', className:'Home' }, { folder:'home/images' }, { folder:'home/form', file:'modal.js', className:'homeModal' }, { folder:'network', file:'api.js', }, { folder:'network', file:'route.js' }, { folder:'network/list', file:'network.js', className:'Network' }, { folder:'network/images' }, { folder:'network/form', file:'modal.js', className:'networkModal' } ]
最后进行的就是文件生成代码的编写:
index.js
const fs = require("fs"); const path = require("path"); //引入配置文件 const profileData = require("./template/data") //引入文件模板 let template = require("./template/template"); let page = template.page; let api = template.api; let route = template.route; //遍历建立文件 profileData.data.forEach((item) => { if(item.file){ //建立API文件 if(item.file.indexOf("api") != -1){ fs.writeFile(`./pages/${item.folder}/${item.file}`, api, function(err){ if(err){ return console.log('建立失败', err); } console.log(`建立文件成功!-${item.file}`); }) } //建立route文件 if (item.file.indexOf("route") != -1){ fs.writeFile(`./pages/${item.folder}/${item.file}`, route, function(err){ if(err){ return console.log('建立失败', err); } console.log(`建立文件成功!-${item.file}`); }) } //建立主体页面 if (item.className){ fs.writeFile(`./pages/${item.folder}/${item.file}`, page(item.className), function(err){ if(err){ return console.log('建立失败', err); } console.log(`建立文件成功!-${item.file}`); }) } } })
最后, 咱们能够直接运行index.js:
咱们能够看见控制台打印出来的信息是是咱们建立成功了文件夹(目录)和文件, 最后在看看pages文件夹下面的目录与文件:
咱们能够把的到的目录和文件与开始实例中的文件相对比, 发现咱们已经成功生成了想要获得的目录和文件了~
大功告成~
完整的代码和例子我已经放在了个人GitHub上面了,小伙伴们能够根据本身的实际需求来进行修改,提升本身的开发效率。
https://www.runoob.com/nodejs...
上述经过文件配置和模板调用的方式,自动生成了重复的代码文件。这种方式在必定程度上能够减小咱们复制粘贴的重复劳动,提升咱们的工做效率。这种方式也是我在开发中的一种尝试,其中还有不少不足之处。若是有小伙伴在工做中也有过相似提升开发效率的尝试,欢迎和你们一块儿分享~
文中如有错误的地方,也欢迎提出来~