Skip to content

Commit 2508075

Browse files
author
zhaozhiwen
committed
chore(new-comp): 增加组件初始化脚本
1 parent 674a849 commit 2508075

File tree

9 files changed

+514
-7
lines changed

9 files changed

+514
-7
lines changed

package.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
"test": "jest",
1818
"test:watch": "jest --watch",
1919
"test:coverage": "jest --coverage",
20-
"test:update": "jest --updateSnapshot"
20+
"test:update": "jest --updateSnapshot",
21+
"new:comp": "node scripts/new-comp"
2122
},
2223
"repository": {
2324
"type": "git",
@@ -58,6 +59,8 @@
5859
"@umijs/fabric": "^1.2.12",
5960
"antd": "^3.26.3",
6061
"babel-plugin-import": "^1.13.0",
62+
"chalk": "^3.0.0",
63+
"change-case": "^4.1.1",
6164
"commitizen": "^4.0.3",
6265
"cz-conventional-changelog": "^3.0.2",
6366
"docz": "^2.2.0",
@@ -68,11 +71,14 @@
6871
"gulp-babel": "^8.0.0",
6972
"gulp-cssnano": "^2.1.3",
7073
"gulp-less": "^4.0.1",
74+
"handlebars": "^4.7.3",
7175
"husky": "^3.1.0",
7276
"identity-obj-proxy": "^3.0.0",
77+
"inquirer": "^7.0.4",
7378
"jest": "^24.9.0",
7479
"less": "^3.10.3",
7580
"lint-staged": "^9.5.0",
81+
"metalsmith": "^2.3.0",
7682
"prettier": "^1.19.1",
7783
"prismjs": "^1.17.1",
7884
"raw-loader": "^4.0.0",

scripts/new-comp.js

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
const inquirer = require('inquirer');
2+
const changeCase = require('change-case');
3+
const Handlebars = require('handlebars');
4+
const Metalsmith = require('metalsmith');
5+
const chalk = require('chalk');
6+
const path = require('path');
7+
const fs = require('fs');
8+
9+
const questions = [
10+
{
11+
name: 'dirName',
12+
message: '组件目录名,中横线命名法(param-case)',
13+
type: 'input',
14+
default: 'new-comp',
15+
},
16+
{
17+
name: 'compNameZH',
18+
message: '组件中文名',
19+
type: 'input',
20+
default: '测试组件',
21+
},
22+
];
23+
24+
/**
25+
* 确认组件目录是否已经存在
26+
* @param {string} path 文件夹路径
27+
*/
28+
function isDirExisted(path) {
29+
try {
30+
fs.accessSync(path);
31+
} catch (e) {
32+
return false;
33+
}
34+
return true;
35+
}
36+
37+
/**
38+
* 渲染组件初始化模板
39+
* @param {string} dest 目标文件夹名称
40+
* @param {Object} state 模板数据
41+
*/
42+
function renderTemplate(dest, state) {
43+
return new Promise((resolve, reject) => {
44+
const source = path.join(__dirname, '../template');
45+
const metalsmith = Metalsmith(process.cwd())
46+
.metadata(state)
47+
.clean(false)
48+
.source(source)
49+
.destination(dest);
50+
51+
metalsmith
52+
.use((files, metalsmith, done) => {
53+
const meta = metalsmith.metadata();
54+
Object.keys(files).forEach(fileName => {
55+
try {
56+
const t = files[fileName].contents.toString();
57+
files[fileName].contents = new Buffer(Handlebars.compile(t)(meta));
58+
} catch (error) {
59+
console.error(chalk.red(`render file error: ${fileName}`));
60+
}
61+
});
62+
done(undefined, files, metalsmith);
63+
})
64+
.build(err => {
65+
if (err) {
66+
reject(err);
67+
} else {
68+
resolve();
69+
console.log(chalk.yellowBright(`- 目录创建成功`));
70+
}
71+
});
72+
});
73+
}
74+
75+
/**
76+
* 向入口文件 re-export 组件
77+
* @param {string} dirName 目标文件夹名称
78+
* @param {string} compNameEN 组件英文名称
79+
*/
80+
function insert2EntryFile(dirName, compNameEN) {
81+
const entryFilePath = path.join(__dirname, '../components/index.ts');
82+
fs.appendFileSync(
83+
entryFilePath,
84+
`\nexport { default as ${compNameEN} } from './${dirName}';\n`,
85+
'utf8',
86+
);
87+
console.log(chalk.yellowBright(`- 入口文件写入成功`));
88+
}
89+
90+
async function main() {
91+
const { dirName, compNameZH } = await inquirer.prompt(questions);
92+
const dest = path.join(__dirname, `../components/${dirName}`);
93+
if (isDirExisted(dest)) {
94+
console.log(chalk.red(`💣 该组件目录已存在`));
95+
return;
96+
}
97+
const compNameEN = changeCase.pascalCase(dirName);
98+
const state = { compNameZH, compNameEN, line_for_keep_metadata: '---' };
99+
await renderTemplate(dest, state);
100+
insert2EntryFile(dirName, compNameEN);
101+
console.log(chalk.green(`✨ ${compNameEN}-${compNameZH} 组件创建成功`));
102+
}
103+
104+
main();

template/__tests__/index.test.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import React from 'react';
2+
import { render } from '@testing-library/react';
3+
import '@testing-library/jest-dom/extend-expect';
4+
import {{compNameEN}} from '../index';
5+
6+
describe('<{{compNameEN}} />', () => {
7+
test('should render default', () => {
8+
const { container } = render(<{{compNameEN}} />);
9+
expect(container).toMatchSnapshot();
10+
});
11+
});

template/demo/1-demo-basic.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import React from 'react';
2+
3+
import {{compNameEN}} from '..';
4+
import '../style';
5+
6+
export default () => (
7+
<>
8+
<{{compNameEN}} />
9+
</>
10+
);

template/index.mdx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{{line_for_keep_metadata}}
2+
name: {{compNameEN}} {{compNameZH}}
3+
route: /{{compNameEN}}
4+
menu: {{compNameEN}}
5+
{{line_for_keep_metadata}}
6+
7+
import CodeBox from '../../doc-comps/happy-box';
8+
9+
import BasicDemo from './demo/1-demo-basic';
10+
import BasicDemoCode from '!raw-loader!./demo/1-demo-basic';
11+
12+
# {{compNameEN}} {{compNameZH}}
13+
14+
组件介绍
15+
16+
## 代码演示
17+
18+
### 基本用法
19+
20+
<CodeBox code={BasicDemoCode}>
21+
<BasicDemo></BasicDemo>
22+
</CodeBox>
23+
24+
## API
25+
26+
| 属性 | 说明 | 类型 | 默认值 |
27+
| ---- | ---- | ---- | ------ |
28+
| | | | |

template/index.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import React, { Component } from 'react';
2+
import PropTypes from 'prop-types';
3+
4+
interface Props {}
5+
6+
interface State {}
7+
8+
class {{compNameEN}} extends Component<Props, State> {
9+
static propTypes = {};
10+
11+
static defaultProps: Partial<Props> = {};
12+
13+
constructor(props: Props) {
14+
super(props);
15+
this.state = {};
16+
}
17+
18+
render() {
19+
return <>{{compNameEN}}</>;
20+
}
21+
}
22+
23+
export default {{compNameEN}};

template/style/index.less

Whitespace-only changes.

template/style/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import './index.less';

0 commit comments

Comments
 (0)