一驾讲、vue-cli的簡(jiǎn)單實(shí)現(xiàn)
- 新建一個(gè)vue-cli-sample的文件夾益眉,該文件夾下打開(kāi)命令行,輸入
yarn init
生成package.json文件缸逃。 - package.json文件中新增一行
"bin": "cli.js"
指定cli.js作為入口文件吏饿。 - 新建cli.js文件春寿,第一行寫(xiě)入
#!/usr/bin/env node
步脓。因?yàn)镹ode cli應(yīng)用入口文件必須有這樣的文件頭堡僻,如果是linux或者macOS系統(tǒng)還需要通過(guò)命令行輸入chomd 755 cli.js
修改讀寫(xiě)權(quán)限钥平。 - 命令行輸入
yarn add inquirer ejs --dev
安裝用戶問(wèn)詢模塊和模板渲染引擎实撒。 - cli.js文件里寫(xiě)入以下代碼姊途。
#!/usr/bin/env node
// 1、先詢問(wèn)用戶信息
// 2知态、指定模板路徑和生成路徑
// 3捷兰、讀取模板文件,生成對(duì)應(yīng)文件
const fs = require('fs');
const path = require('path');
const inquirer = require('inquirer');
const ejs = require('ejs');
// 在命令行詢問(wèn)用戶輸入信息
inquirer.prompt([
{
type: 'input',
name: 'name', // 用戶輸入內(nèi)容賦值給name
message: 'Project name?', // 控制臺(tái)顯示提示語(yǔ)
}
])
.then(anwsers => { // aswers為命令行用戶輸入的信息
const tmplDir = path.join(__dirname, 'templates');
const destDir = process.cwd(); // 當(dāng)前命令行所在的目錄下
// 將模板下的文件全部轉(zhuǎn)換到目標(biāo)目錄
fs.readdir(tmplDir, (err, files) => {
if (err) throw err;
files.forEach(file => {
// 通過(guò)ejs模板引擎渲染文件
ejs.renderFile(path.join(tmplDir, file), anwsers, (err, result) => {
if (err) throw err;
// 將結(jié)果寫(xiě)入目標(biāo)文件路徑
fs.writeFileSync(path.join(destDir, file), result);
});
});
});
});
- 在當(dāng)前目錄下新建templates目錄负敏,放入一個(gè)test.js文件贡茅,文件內(nèi)容
<%= name %>
指定用ejs語(yǔ)法填充數(shù)據(jù)。 - 命令行輸入
yarn link
將當(dāng)前vue-cli-sample(項(xiàng)目名)鏈接到全局其做。 - 新建空文件夾顶考,該文件夾下打開(kāi)命令行輸入剛才鏈接的項(xiàng)目名
vue-cli-sample
即可執(zhí)行該模塊。然后按提示輸入名字假設(shè)為test回車妖泄,會(huì)看到該空文件夾生成了test.js內(nèi)容為test驹沿,則代表成功。
二蹈胡、優(yōu)化
將上面templates文件夾里的內(nèi)容替換成我們前兩步(實(shí)現(xiàn)vue-cli(一):gulp自動(dòng)化構(gòu)建渊季、實(shí)現(xiàn)vue-cli(二):webpack實(shí)現(xiàn)項(xiàng)目打包)生成的 gulpfile.js、webpack配置內(nèi)容和項(xiàng)目?jī)?nèi)容罚渐。此時(shí)vue-cli自動(dòng)生成的不止一兩個(gè)文件却汉,文件多了會(huì)有幾個(gè)問(wèn)題,我們分別解決下搅轿。
-
fs.readdir
只會(huì)讀取一層目錄病涨,如果templates里有很多子目錄,則ejs渲染目錄會(huì)失敗璧坟。我們用fs.stat
方法增加個(gè)類型檢測(cè)既穆,如果是文件夾則繼續(xù)遍歷。 - 遍歷到新文件夾還要?jiǎng)?chuàng)建雀鹃,不然最后生成文件會(huì)找不到文件夾幻工。用
yarn add mkdirp --dev
添加對(duì)應(yīng)插件。 - 圖片等文件是不需要用ejs進(jìn)行渲染的黎茎,否則可能會(huì)錯(cuò)誤地把
<%=
解析成填充內(nèi)容囊颅,此處判斷為圖片就直接copy。
#!/usr/bin/env node
// 1傅瞻、先詢問(wèn)用戶信息
// 2踢代、指定模板路徑和生成路徑
// 3、讀取模板文件嗅骄,生成對(duì)應(yīng)文件
const fs = require('fs');
const path = require('path');
const inquirer = require('inquirer');
const ejs = require('ejs');
const mkdirp = require('mkdirp');
// 在命令行詢問(wèn)用戶輸入信息
inquirer.prompt([
{
type: 'input',
name: 'name',
message: 'Project name?'
}
])
.then(anwsers => { // aswers為命令行用戶輸入的信息
const tmplDir = path.join(__dirname, 'templates');
const destDir = process.cwd();
// 將模板下的文件全部轉(zhuǎn)換到目標(biāo)目錄
const handleFiles = (dir, rootDir) => {
fs.readdir(dir, (err, files) => {
if (err) throw err;
files.forEach(file => {
let filePath = path.resolve(dir, file);
let targetPath = path.join(destDir, path.relative(rootDir, filePath));
fs.stat(filePath, (err, stats) => {
if (err) throw err;
if (stats.isDirectory()) {
mkdirp(targetPath).then(() => {
handleFiles(filePath, rootDir);
});
return;
}
if (stats.isFile()) {
// 如果是圖片則直接copy不需要ejs渲染胳挎,不然文件中帶有<%可能會(huì)出錯(cuò)
if (/\.jpg$|\.gif$|\.png$|\.ico$/.test(filePath)) {
fs.copyFileSync(filePath, targetPath);
return;
}
// 通過(guò)模板引擎渲染文件
ejs.renderFile(filePath, anwsers, (err, result) => {
if (err) throw err;
// 將結(jié)果寫(xiě)入目標(biāo)文件路徑
fs.writeFileSync(targetPath, result);
});
}
});
});
});
}
handleFiles(tmplDir, tmplDir);
});
最后,在空文件夾命令行執(zhí)行vue-cli-sample
自動(dòng)生成對(duì)應(yīng)資源溺森,然后yarn install
安裝依賴包慕爬,執(zhí)行yarn gulp develop
打開(kāi)瀏覽器頁(yè)面正常即代表成功窑眯。