-
Notifications
You must be signed in to change notification settings - Fork 0
/
create-project.js
122 lines (102 loc) · 2.65 KB
/
create-project.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
'use strict';
const path = require('path');
const mkdirp = require('make-dir');
const pEachSeries = require('p-each-series');
// ora 模块显示loading
const ora = require('ora');
const fs = require('fs');
const handlebars = require('handlebars');
const globby = require('globby');
const execa = require('execa');
const templateBlacklist = new Set([
'public/favicon.ico'
]);
module.exports = async (info) => {
const {
manager,
template,
name,
templatePath
} = info;
if (!name) {
throw new Error('invalid input; you must pass a valid project name');
process.exit(1);
}
// 处理包名作用域
const parts = name.split('/');
info.shortName = parts[parts.length - 1];
const dest = path.join(process.cwd(), info.shortName);
info.dest = dest;
// 在当前目录下创建目录(info.shortName)
await mkdirp(dest);
const source = template === 'custom'
? path.join(process.cwd(), templatePath)
: path.join(__dirname, '..', 'template', template);
const files = await globby(source, {
dot: true
});
{
const promise = pEachSeries(files, async (file) => {
return module.exports.copyTemplateFile({
file,
source,
dest,
info
})
})
ora.promise(promise, `Copying ${template} template to ${dest}`)
await promise
}
{
const promise = module.exports.initProjectManager({ dest, info })
ora.promise(promise, `Running ${manager} install`)
await promise
}
return dest;
}
module.exports.copyTemplateFile = async (opts) => {
const {
file,
source,
dest,
info
} = opts;
const fileRelativePath = path.relative(source, file);
const destFilePath = path.join(dest, fileRelativePath);
const destFileDir = path.parse(destFilePath).dir;
await mkdirp(destFileDir);
if (fileRelativePath.includes('package.json')) {
const content = fs.readFileSync(file, 'utf8');
const newCon = JSON.parse(content);
newCon.name = info.name;
newCon.description = info.description;
newCon.author = info.author;
fs.writeFileSync(destFilePath, JSON.stringify(newCon));
} else if (info.template === 'custom' || templateBlacklist.has(fileRelativePath)) {
const content = fs.readFileSync(file);
fs.writeFileSync(destFilePath, content);
} else {
const template = handlebars.compile(fs.readFileSync(file, 'utf8'));
const content = template({
...info,
yarn: (info.manager === 'yarn')
});
fs.writeFileSync(destFilePath, content, 'utf8');
}
return fileRelativePath;
}
module.exports.initProjectManager = async (opts) => {
const {
dest,
info
} = opts;
const commands = [
{
cmd: `${info.manager} install`,
cwd: dest
},
];
return pEachSeries(commands, async ({ cmd, cwd }) => {
return execa.shell(cmd, { cwd })
})
}