接上一个博客源码共读-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_