- Notifications
You must be signed in to change notification settings - Fork 28.3k
/
Copy pathscaffold-component.ts
95 lines (78 loc) · 3.07 KB
/
scaffold-component.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*
Component Scaffolding Script
This is a script that enables scaffolding a new JSS component using `jss scaffold <ComponentName>`.
The default convention is that component names must start with a capital letter, and can contain
letters, number, underscores, or dashes.
If the <ComponentName> parameter includes a path, it must be relative to the src/components folder.
For example, `jss scaffold search/SearchBox` will create a component called `SearchBox` in
`src/components/search/SearchBox.tsx`. Specifying a relative path is optional, and just providing
the name is ok.
Edit this script if you wish to use your own conventions for component storage in your JSS app.
*/
/* eslint-disable no-throw-literal,no-console */
importfsfrom"fs";
importpathfrom"path";
importchalkfrom"chalk";
importgenerateComponentSrcfrom"./templates/component-src";
constcomponentRootPath="src/components";
// Matches component names that start with a capital letter, and contain only letters, number,
// underscores, or dashes. Optionally, the component name can be preceded by a relative path
constnameParamFormat=newRegExp(/^((?:[\w-]+\/)*)([A-Z][\w-]+)$/);
constcomponentArg=process.argv[2];
if(!componentArg){
throw"Component name was not passed. Usage: jss scaffold <ComponentName>";
}
constregExResult=nameParamFormat.exec(componentArg);
if(regExResult===null){
throw`Component name should start with an uppercase letter and contain only letters, numbers,
dashes, or underscores. If specifying a path, it must be relative to src/components`;
}
constcomponentPath=regExResult[1];
constcomponentName=regExResult[2];
constfilename=`${componentName}.tsx`;
/**
* Force to use `crlf` line endings, we are using `crlf` across the project.
* Replace: `lf` (\n), `cr` (\r)
* @param {string} content
*/
functioneditLineEndings(content: string){
returncontent.replace(/\r|\n/gm,"\r\n");
}
/**
* Creates a file relative to the specified path if the file doesn't exist. Creates directories as needed.
* @param {string} rootPath - the root path
* @param {string} fileContent - the file content
* @param {string} filename - the filename
* @returns the new file's filepath
*/
functionscaffoldFile(
rootPath: string,
fileContent: string,
filename: string,
): string|null{
constoutputDir=path.join(rootPath,componentPath);
constoutputFile=path.join(outputDir,filename);
if(fs.existsSync(outputFile)){
console.log(chalk.red(`Skipping creating ${outputFile}; already exists.`));
returnnull;
}
fs.mkdirSync(outputDir,{recursive: true});
fs.writeFileSync(outputFile,editLineEndings(fileContent),"utf8");
console.log(chalk.green(`File ${outputFile} has been scaffolded.`));
returnoutputFile;
}
constcomponentOutputPath=scaffoldFile(
componentRootPath,
generateComponentSrc(componentName),
filename,
);
console.log(
chalk.green(`
Scaffolding of ${componentName} complete.
Next steps:`),
);
if(componentOutputPath){
console.log(
`* Implement the React component in ${chalk.green(componentOutputPath)}`,
);
}