相信在咱們平常遇到的項目中,不管是在前端網站仍是後臺管理系統中都會有功能相似的頁面。咱們在開發這些功能相似的頁面的時候,爲了提升效率,通常都會運用咱們的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...
上述經過文件配置和模板調用的方式,自動生成了重複的代碼文件。這種方式在必定程度上能夠減小咱們複製粘貼的重複勞動,提升咱們的工做效率。這種方式也是我在開發中的一種嘗試,其中還有不少不足之處。若是有小夥伴在工做中也有過相似提升開發效率的嘗試,歡迎和你們一塊兒分享~
文中如有錯誤的地方,也歡迎提出來~