-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcreateSelfApp.js
149 lines (128 loc) · 4.76 KB
/
createSelfApp.js
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
'use strict';
const path = require('path');
const validateProjectName = require('validate-npm-package-name');// 检测包名中的字符是不是都是合法的
const chalk = require('chalk');// 一个颜色的插件
const commander = require('commander');// 解析用户命令行输入和参数
const fs = require('fs-extra');// 系统fs模块的扩展,提供了更多便利的 API
const packageJson = require('./package.json');
const templateJson = require('./config.json');
let projectName;// 定义了一个用来存储项目名称的变量
const program = new commander.Command(packageJson.name)
.version(packageJson.version)// 输入版本信息,使用`lt-self-cli -V`的时候就用打印版本信息
.arguments('<project-directory>')
.usage(`${chalk.green('<project-directory>')} [options]`)
.action(name => {
projectName = name;
})
.option('--verbose', 'print additional logs')
.allowUnknownOption()
.on('--help', () => {
console.log(` Only ${chalk.green('<project-directory>')} is required.`);
console.log();
})
.parse(process.argv);
if (typeof projectName === 'undefined') {
console.error('Please specify the project directory:');
console.log('For example:');
console.log(` ${chalk.cyan(program.name())} ${chalk.green('my-react-app')}`);
console.log();
console.log(
`Run ${chalk.cyan(`${program.name()} --help`)} to see all options.`
);
process.exit(1);
}
const hiddenProgram = new commander.Command()
.option(
'--internal-testing-template <path-to-template>',
'(internal usage only, DO NOT RELY ON THIS) ' +
'use a non-standard application template'
)
.parse(process.argv);
createApp(projectName, program.verbose, program.scriptsVersion, hiddenProgram.internalTestingTemplate);
function createApp(name, verbose, version, template) {
const root = path.resolve(name);
const appName = path.basename(root);
checkAppName(appName);
fs.ensureDirSync(name);// 检测临时文件是否存在
if (!isSafeToCreateProjectIn(root)) {
console.log(
`The directory ${chalk.green(name)} contains files that could conflict.`
);
console.log('Try using a new directory name.');
process.exit(1);
}
console.log(`Creating a new React app in ${chalk.green(root)}.`);
console.log();
fs.writeFileSync(
path.join(root, 'package.json'),
JSON.stringify(templateJson, null, 2)
);
//const originalDirectory = process.cwd();// 当前目录
process.chdir(root);// 改变工作目录
copyTemplate(root);
// root--e:/test/xx appName--xx version--undefined verbose--undefined originalDirectory--e:/test/ template--undefined
// run(root, appName, version, verbose, originalDirectory, template);
}
function copyTemplate(root) {
// Copy the files for the user
const templatePath = path.join(__dirname, 'template');
if (fs.existsSync(templatePath)) {
fs.copySync(templatePath, root);
} else {
console.error(
`Could not locate supplied template: ${chalk.green(templatePath)}`
);
}
}
function checkAppName(appName) {
const validationResult = validateProjectName(appName);
if (!validationResult.validForNewPackages) {
console.error(
`Could not create a project called ${chalk.red(`"${appName}"`)} because of npm naming restrictions:`
);
printValidationResults(validationResult.errors);
printValidationResults(validationResult.warnings);
process.exit(1);
}
// TODO: there should be a single place that holds the dependencies
const dependencies = ['react', 'react-dom'];
const devDependencies = ['react-scripts'];
const allDependencies = dependencies.concat(devDependencies).sort();
if (allDependencies.indexOf(appName) >= 0) {
console.error(
chalk.red(
`We cannot create a project called ${chalk.green(appName)} because a dependency with the same name exists.\n` +
`Due to the way npm works, the following names are not allowed:\n\n`
) +
chalk.cyan(allDependencies.map(depName => ` ${depName}`).join('\n')) +
chalk.red('\n\nPlease choose a different project name.')
);
process.exit(1);
}
}
// If project only contains files generated by GH, it’s safe.
// We also special case IJ-based products .idea because it integrates with CRA:
// https://github.com/facebookincubator/create-react-app/pull/368#issuecomment-243446094
function isSafeToCreateProjectIn(root) {
const validFiles = [
'.DS_Store',
'Thumbs.db',
'.git',
'.gitignore',
'.idea',
'README.md',
'LICENSE',
'web.iml',
'.hg',
'.hgignore',
'.hgcheck',
];
return fs.readdirSync(root).every(file => validFiles.indexOf(file) >= 0);
}
function printValidationResults(results) {
if (typeof results !== 'undefined') {
results.forEach(error => {
console.error(chalk.red(` * ${error}`));
});
}
}