摘要:自動(dòng)工具先推薦兩個(gè)干貨,關(guān)于正則的,,前者驗(yàn)證正則是否和預(yù)期一樣,后者以圖的形式表達(dá)正則,有助于理解天書(shū)般的別人寫(xiě)的正則作為一個(gè)前端打字員,一個(gè)經(jīng)常遇到的場(chǎng)景就是在路由文件中引入模塊,比如這樣在中寫(xiě)入如果修改了模塊的名字,增加了模塊或者刪
自動(dòng) import 工具
先推薦兩個(gè)干貨,關(guān)于正則的
regexr,regexper,前者驗(yàn)證正則是否和預(yù)期一樣,后者以圖的形式表達(dá)正則,有助于理解天書(shū)般的別人寫(xiě)的正則
作為一個(gè)前端打字員,一個(gè)經(jīng)常遇到的場(chǎng)景就是在路由文件中引入模塊,比如這樣
在 router/index.js 中寫(xiě)入
import Vue from "vue" import Router from "vue-router" const About = () => import("../pages/About.vue") const Home = () => import("../pages/Home.vue") Vue.use(Router) ...
如果修改了模塊的名字,增加了模塊或者刪除了模塊,就需要重新修改這個(gè)路由文件
總是做這么機(jī)械的事情無(wú)異于消耗我這個(gè)前端打字員的壽命
不能忍,遂寫(xiě)個(gè)工具
整理思路如下其中,監(jiān)視目錄下文件的變動(dòng)依靠的是 node API 中fs.watch(filename[, options][, listener])
替換目標(biāo)文件中引入模塊的部分,則是通過(guò)正則來(lái)實(shí)現(xiàn)
在這里五星推薦一個(gè)驗(yàn)證正則是否正確的網(wǎng)站,regexr
代碼實(shí)現(xiàn)監(jiān)視包含模塊的目錄
fs.watch(dir, { recursive: true // 目錄下子目錄也被監(jiān)視 }, (event, filename) => { // event 是文件變動(dòng)的類型,添加文件、刪除文件和修改文件名都是"rename" 事件 // filename 是變化的文件或目錄 if(event === "rename"){ // 判斷文件變動(dòng)類型 } })
當(dāng)發(fā)生rename事件后,需要重新獲得目錄下(from)所有的模塊,包括模塊名moduleName,模塊文件相對(duì)于引用模塊文件(to)的相對(duì)路徑modulePath,將它們存入變量modules中
實(shí)際項(xiàng)目中,模塊通常都是.vue文件,或者.jsx文件,因此只將這些作為模塊,在路由文件中引用
另外有些模塊文件因?yàn)楦鞣N原因,希望人工引入,而不被watch,這樣的文件存入excludeArr中
const _ = require("lodash") let excludeArr = [...] let modules = [] let extname = ".vue" let from = "./src/pages" let to = "./src/router/index.js"" const mapDir = d => { // 獲得當(dāng)前文件夾下的所有的文件夾和文件 const [dirs, files] = _(fs.readdirSync(d)).partition(p => fs.statSync(path.join(d, p)).isDirectory() ) // 映射文件夾 dirs.forEach(dir => { modules.concat(mapDir(path.join(d, dir))) }) // 映射文件 files.forEach(file => { // 文件后綴名 let filename = path.join(d, file) if (path.extname(file) === extname) { if (!excludeArr.includes(path.resolve(__dirname, filename))) { let moduleName = path.basename(file, extname) // 若存在 - if (moduleName.match("-")) { moduleName = moduleName.replace( /(-)(.{1})/, (match, p1, p2, offset, string) => p2.toUpperCase() ) } modules.push({ moduleName, modulePath: path.relative(path.dirname(to), filename) }) } } }) }
生成好新的待引入的模塊后,接下來(lái)就是在路由文件中,將對(duì)應(yīng)的內(nèi)容替換掉
所以需要讀寫(xiě)文件以及正則替換
const regex = //*sautoImport(.* )*/*sautoImports*//g let importStr = "" modules.forEach((m, index) => { importStr = importStr + fillTemplate(template, m.moduleName, m.modulePath) + (cache.length - 1 === index ? "" : " ") }) fs.readFile(to, "utf8", (err, data) => { if (err) return console.log(err) let result = "" if (data.match(regex)) { result = data.replace( regex, `/* autoImport */ ${importStr} /* autoImport */` ) } else { /* 首次插入在文件最后的import插入 */ result = data.replace( /(.*import.*)( )([^(import)])/, (match, p1, p2, p3, offset, string) => { return `${p1} /* autoImport */ ${importStr} /* autoImport */ ${p3}` } ) } fs.writeFile(to, result, "utf8", err => { if (err) return console.log(err) }) })
其中//*sautoImport(.* )*/*sautoImports*//g是用于匹配兩段注釋/* autoImport */及其中間的內(nèi)容
import Vue from "vue" import Router from "vue-router" /* autoImport */ const About = () => import("../pages/About.vue") const Home = () => import("../pages/Home.vue") /* autoImport */ Vue.use(Router)
當(dāng)?shù)谝淮问褂茫瑳](méi)有/* autoImport */時(shí),就需要在最后一個(gè)import后面,插入引入的模塊
data.replace( /(.*import.*)( )([^(import)])/, (match, p1, p2, p3, offset, string) => { return `${p1} /* autoImport */ ${importStr} /* autoImport */ ${p3}`
在這里還可以自定義了引入模塊的方式,例如懶加載,"const moduleName = () => import(modulePath)"
const template = "const moduleName = () => import(modulePath)" const fillTemplate = (template, moduleName, modulePath) => template .replace("moduleName", moduleName) .replace("modulePath", `"${modulePath}"`)
為了工具的靈活性,把可配置項(xiàng)寫(xiě)成json文件的形式
{ "extname": ".vue", "from": "src/pages", "to": "src/router/index.js", "template": "const moduleName = () => import(modulePath)", "exclude": [ "./src/pages/login.vue", "./src/pages/404.vue", "./src/pages/overall/**", "./src/pages/account-result/**" ] }
然后通過(guò)以下的方式來(lái)獲得
const config = fs.readFileSync("./autoImport.json") const { extname, from, to, template, exclude } = JSON.parse(config)后記
下一步準(zhǔn)備把這個(gè)工具寫(xiě)成webpack的插件,名字我都起好了,AutoImportPlugin,先在github上占了個(gè)坑,順手給顆星,不用改Bug
同時(shí)準(zhǔn)備用更加成熟的模塊chokidar來(lái)代替原生的watch
工具有問(wèn)題提issue啊
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/92311.html
摘要:故事背景前情提要自動(dòng)工具,前端打字員的自我救贖的功能根據(jù)配置文件,在目標(biāo)文件中自動(dòng)導(dǎo)入規(guī)定目錄下自定義模塊,并監(jiān)聽(tīng)規(guī)定目錄下文件的變動(dòng),自動(dòng)更新尚在測(cè)試中的使用安裝工具編寫(xiě)配置文件需要自動(dòng)導(dǎo)入的模塊的后綴名自動(dòng)導(dǎo)入的模塊的來(lái)源目 故事背景 前情提要:自動(dòng) Import 工具,前端打字員的自我救贖 github: smart-import smart-import 的功能 根據(jù)配置文件...
摘要:前情提要自動(dòng)工具,前端打字員的自我救贖記第一次發(fā)布包經(jīng)歷,是重構(gòu)中的代碼是版本可以工作的代碼配置文件待導(dǎo)入的模塊引用模塊的文件引用模塊的方式忽略的模塊實(shí)現(xiàn)監(jiān)聽(tīng)文件的刪除和添加以上代碼主要使用了來(lái)監(jiān)聽(tīng)文件的變化。 前情提要 自動(dòng) Import 工具,前端打字員的自我救贖 記第一次發(fā)布npm包經(jīng)歷,smart-import GitHub:smart-import develop是重構(gòu)中的代...
摘要:重溫一個(gè)面試題內(nèi)容數(shù)組內(nèi)容為數(shù)組內(nèi)容為個(gè)英文字母,使用兩個(gè)線程分別輸入兩個(gè)數(shù)組,打印內(nèi)容為這樣的規(guī)律提取一下核心內(nèi)容,去除次要內(nèi)容兩個(gè)線程需要交替執(zhí)行,打印數(shù)字的線程需要先執(zhí)行,數(shù)組打印完畢后線程需要結(jié)束。 一道多線程面試題引起的自我救贖 近日去一個(gè)知名互聯(lián)網(wǎng)企業(yè)參加面試,之前準(zhǔn)備多多信心滿滿,但是面試一開(kāi)始就是一道不起眼的編程題 數(shù)組A內(nèi)容為 1,2,3,4...52 ,數(shù)組B內(nèi)容...
摘要:聽(tīng)了鵬哥的教導(dǎo),也開(kāi)始寫(xiě)起了博客現(xiàn)在多粉,感覺(jué)都是機(jī)器人哈哈,最近粉絲也不漲了,不知道是不是我最近不發(fā)文章的原因。這一個(gè)多月,基本就是學(xué)刷算法題。在這里不得不吐槽一下學(xué)校,每條早上做早操,晚自習(xí)到點(diǎn),感覺(jué)浪費(fèi)了我很多學(xué)習(xí)技術(shù)的時(shí)間。 ...
閱讀 3793·2023-04-25 21:09
閱讀 3139·2021-10-20 13:48
閱讀 3053·2021-09-24 10:25
閱讀 2947·2021-08-21 14:08
閱讀 1804·2019-08-30 15:56
閱讀 993·2019-08-30 15:52
閱讀 1862·2019-08-29 14:11
閱讀 3578·2019-08-29 11:01