接上一個博客源碼共讀-UMI-2,接下來,我們來繼續執行 umi generate
從第一個博客中我們知道,執行umi generate 會執行lib/scripts/ generate.js
lib/scripts/generate.js
import yParser from 'yargs-parser';
import generate from '../generate';
const argv = yParser(process.argv.slice(2));
const [type, file] = argv._;
generate({
type,
file,
useClass: argv.c || argv.class || false,
isDirectory: argv.d || argv.directory || false,
});
取出參數調用generate
../generate.js
import assert from 'assert';
import page from './generators/page';
const generators = {
page,
};
這裏應該是爲了後續擴展使用的,這裏暫時只有一個page
export default function(opts = {}) {
const { type, file } = opts;
assert(type, 'opts.type should be supplied');
assert(typeof type === 'string', 'opts.file should be string');
assert(file, 'opts.file should be supplied');
assert(typeof file === 'string', 'opts.file should be string');
assert(generators[type], `generator of type (${type}) not found`);
delete opts.type;
generators[type](opts);
}
./generators/page
import assert from 'assert';
該模塊用於編寫應用程序的單元測試
import ejs from 'ejs';
嵌入式JavaScript模板
import uppercamelcase from 'uppercamelcase';
首字母大寫轉換 如 foo-bar => FooBar
import { join, basename } from 'path';
import { existsSync, statSync, readFileSync, writeFileSync } from 'fs';
屬性 | 說明 |
---|---|
existsSync | 測試某個路徑下的文件是否存在 |
statSync | 獲取文件信息 |
readFileSync | 讀取文件 |
writeFileSync | 寫文件 |
//目錄存在
function directoryExists(path) {
return existsSync(path) && statSync(path).isDirectory();
}
//文件存在
function fileExists(path) {
return existsSync(path) && statSync(path).isFile();
}
//去除空行
function stripEmptyLine(content) {
const ret = content
.trim()
// 兩行 -> 一行
.replace(/\n\n/g, '\n');
// 結尾空行
return `${ret}\n`;
}
//看一下代碼時,可先忽略assert
export default function(opts = {}) {
const { file } = opts;
//斷言
assert(
!('isDirectory' in opts) || typeof opts.isDirectory === 'boolean',
'opts.isDirectory should be boolean',
);
assert(
!('useClass' in opts) || typeof opts.useClass === 'boolean',
'opts.useClass should be boolean',
);
//目錄
const isDirectory = opts.isDirectory || false;
//當前執行路徑
const cwd = opts.cwd || process.cwd();
console.log(`[DEBUG] generate page ${file} with isDirectory ${isDirectory}`);
let cssTargetPath;
let jsTargetPath;
//是目錄的時候,在file目錄下新建page文件
//不是目錄的時候,新建file文件
if (isDirectory) {
assert(
!directoryExists(join(cwd, 'src', 'page', file)),
`directory src/page/${file} exists`,
);
jsTargetPath = join(cwd, 'src', 'page', file, 'page.js');
cssTargetPath = join(cwd, 'src', 'page', file, 'page.css');
} else {
jsTargetPath = join(cwd, 'src', 'page', `${file}.js`);
cssTargetPath = join(cwd, 'src', 'page', `${file}.css`);
}
assert(!fileExists(jsTargetPath), `file src/page/${file} exists`);
assert(!fileExists(cssTargetPath), `file src/page/${file} exists`);
//從模板中讀取文件
const jsTpl = readFileSync(
join(__dirname, '../../template/page.js'),
'utf-8',
);
const cssTpl = readFileSync(
join(__dirname, '../../template/page.css'),
'utf-8',
);
const fileName = basename(file);
const componentName = uppercamelcase(fileName);
//使用ejs render文件
//ejs.render(str, data, options);
//options https://www.npmjs.com/package/ejs#options
const jsContent = ejs.render(
jsTpl,
{
useClass: opts.useClass,
fileName,
componentName,
},
{
_with: false,
localsName: 'umi',
},
);
const cssContent = ejs.render(
cssTpl,
{},
{
_with: false,
localsName: 'umi',
},
);
//寫入文件
writeFileSync(jsTargetPath, stripEmptyLine(jsContent), 'utf-8');
writeFileSync(cssTargetPath, stripEmptyLine(cssContent), 'utf-8');
}
本節課就到此結束了,喜歡我的博客的朋友可以關注我。後續會有實戰演練哦。
Github地址
https://github.com/xiaohuoni/source-code-co-reading-umi
感謝您的閱讀。
我是莽夫,希望你開心。
如果你覺得本文對你有幫助,請掃描文末二維碼,支持博主原創。
希望大家關注我的個人公衆號ionic_