buner 1.0.5 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{bin → dist}/buner.js +40 -34
- package/{integration.ts → dist/integration.js} +51 -100
- package/dist/migrate-scss.js +33 -0
- package/dist/prerender.js +158 -0
- package/dist/scripts.js +36 -0
- package/dist/server.js +171 -0
- package/dist/states.js +41 -0
- package/dist/styles.js +165 -0
- package/index.html +1 -1
- package/package.json +3 -12
- package/xpack/alias.ts +3 -2
- package/xpack/hooks/options.ts +2 -2
- package/xpack/hooks/transform-index-html.ts +4 -2
- package/xpack/react-loader-init.tsx +1 -1
- package/cli/README.md +0 -1
- package/cli/buner.ts +0 -264
- package/cli/cli.ts +0 -125
- package/cli/create-app.ts +0 -59
- package/cli/helpers/copy.ts +0 -61
- package/cli/helpers/format-files.ts +0 -197
- package/cli/helpers/git.ts +0 -77
- package/cli/helpers/install.ts +0 -26
- package/cli/helpers/is-folder-empty.ts +0 -40
- package/cli/helpers/is-writeable.ts +0 -14
- package/cli/helpers/make-dir.ts +0 -7
- package/cli/helpers/validate-pkg.ts +0 -17
- package/cli/install-template.ts +0 -72
- package/migrate-scss.ts +0 -42
- package/prerender.ts +0 -229
- package/scripts.ts +0 -56
- package/server.ts +0 -29
- package/states.ts +0 -63
- package/styles.ts +0 -232
package/cli/buner.ts
DELETED
|
@@ -1,264 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-console */
|
|
2
|
-
|
|
3
|
-
import path from 'path';
|
|
4
|
-
import { execSync, spawn, SpawnOptions } from 'child_process';
|
|
5
|
-
import { fileURLToPath } from 'url';
|
|
6
|
-
|
|
7
|
-
import { Command } from 'commander';
|
|
8
|
-
import chalk from 'chalk';
|
|
9
|
-
import fetch from 'node-fetch';
|
|
10
|
-
import prompts from 'prompts';
|
|
11
|
-
|
|
12
|
-
import packageJson from '../package.json';
|
|
13
|
-
|
|
14
|
-
import { createApp } from './create-app.js';
|
|
15
|
-
import { validateNpmName } from './helpers/validate-pkg.js';
|
|
16
|
-
|
|
17
|
-
const { green, yellow, bold, cyan, red } = chalk;
|
|
18
|
-
const packageName = 'buner';
|
|
19
|
-
|
|
20
|
-
// Package's own directory (where server.ts, styles.ts, etc. live)
|
|
21
|
-
const packageDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
22
|
-
|
|
23
|
-
/** Resolve a file path relative to the buner package directory */
|
|
24
|
-
const pkg = (file: string) => path.join(packageDir, file);
|
|
25
|
-
|
|
26
|
-
/** Resolve a binary from buner's own node_modules */
|
|
27
|
-
const bin = (name: string) => {
|
|
28
|
-
const ext = process.platform === 'win32' ? '.cmd' : '';
|
|
29
|
-
const local = path.join(packageDir, 'node_modules', '.bin', name + ext);
|
|
30
|
-
|
|
31
|
-
try {
|
|
32
|
-
if (require('fs').existsSync(local)) return local;
|
|
33
|
-
} catch {
|
|
34
|
-
// ignore
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Fallback: try to find it in the consumer's node_modules
|
|
38
|
-
const consumerBin = path.join(process.cwd(), 'node_modules', '.bin', name + ext);
|
|
39
|
-
|
|
40
|
-
try {
|
|
41
|
-
if (require('fs').existsSync(consumerBin)) return consumerBin;
|
|
42
|
-
} catch {
|
|
43
|
-
// ignore
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Last resort: rely on PATH
|
|
47
|
-
return name;
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
const run = (cmd: string, args: string[] = [], options: SpawnOptions = {}) => {
|
|
51
|
-
return new Promise<void>((resolve, reject) => {
|
|
52
|
-
const child = spawn(cmd, args, {
|
|
53
|
-
stdio: 'inherit',
|
|
54
|
-
shell: true,
|
|
55
|
-
cwd: process.cwd(),
|
|
56
|
-
...options,
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
child.on('close', (code) => {
|
|
60
|
-
if (code !== 0) {
|
|
61
|
-
reject(new Error(`Command "${cmd} ${args.join(' ')}" exited with code ${code}`));
|
|
62
|
-
} else {
|
|
63
|
-
resolve();
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
child.on('error', reject);
|
|
68
|
-
});
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
const runSync = (cmd: string) => {
|
|
72
|
-
execSync(cmd, { stdio: 'inherit', cwd: process.cwd() });
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
const onPromptState = (state: { value?: string; aborted?: boolean }) => {
|
|
76
|
-
if (state?.aborted) {
|
|
77
|
-
process.stdout.write('\x1B[?25h');
|
|
78
|
-
process.stdout.write('\n');
|
|
79
|
-
process.exit(1);
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
const parseVersion = (version: string): number => {
|
|
84
|
-
return parseInt(version.replaceAll('.', ''));
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
const update = fetch(`https://registry.npmjs.org/${packageJson.name}/latest`)
|
|
88
|
-
.then((res) => res.json())
|
|
89
|
-
.catch(() => null);
|
|
90
|
-
|
|
91
|
-
async function notifyUpdate(): Promise<void> {
|
|
92
|
-
try {
|
|
93
|
-
const data = (await update) as { version: string };
|
|
94
|
-
|
|
95
|
-
if (data.version && parseVersion(data.version) !== parseVersion(packageJson.version)) {
|
|
96
|
-
const updateMessage = `npm update -g ${packageName}`;
|
|
97
|
-
|
|
98
|
-
console.log(
|
|
99
|
-
yellow(bold(`A new version of '${packageName}' is available!`)) + '\n' + 'You can update by running: ' + cyan(updateMessage) + '\n'
|
|
100
|
-
);
|
|
101
|
-
}
|
|
102
|
-
} catch {
|
|
103
|
-
// ignore error
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const program = new Command();
|
|
108
|
-
|
|
109
|
-
program.name(packageName).description('Frontend build toolkit for Vite + React SSR projects').version(packageJson.version);
|
|
110
|
-
|
|
111
|
-
// buner create [dir]
|
|
112
|
-
program
|
|
113
|
-
.command('create')
|
|
114
|
-
.argument('[project-directory]', 'the project name', '')
|
|
115
|
-
.description('Scaffold a new frontend project')
|
|
116
|
-
.action(async (projectPath: string) => {
|
|
117
|
-
if (!projectPath) {
|
|
118
|
-
const validation = validateNpmName('my-app');
|
|
119
|
-
|
|
120
|
-
const res = await prompts({
|
|
121
|
-
onState: onPromptState,
|
|
122
|
-
type: 'text',
|
|
123
|
-
name: 'path',
|
|
124
|
-
message: 'What is your project named?',
|
|
125
|
-
initial: 'my-app',
|
|
126
|
-
validate: (name) => {
|
|
127
|
-
const validation = validateNpmName(path.basename(path.resolve(name)));
|
|
128
|
-
|
|
129
|
-
if (validation.valid) {
|
|
130
|
-
return true;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
return `Invalid project name ${validation?.problems?.[0] ? validation?.problems?.[0] : ''}`;
|
|
134
|
-
},
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
if (typeof res.path === 'string') {
|
|
138
|
-
projectPath = res.path.trim();
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
if (!projectPath) {
|
|
143
|
-
console.log(
|
|
144
|
-
'\nPlease specify the project directory:\n' +
|
|
145
|
-
` ${cyan('buner create')} ${green('<project-directory>')}\n` +
|
|
146
|
-
'For example:\n' +
|
|
147
|
-
` ${cyan('buner create')} ${green('my-app')}\n`
|
|
148
|
-
);
|
|
149
|
-
process.exit(1);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
const resolvedProjectPath = path.resolve(projectPath);
|
|
153
|
-
|
|
154
|
-
await createApp({ appPath: resolvedProjectPath });
|
|
155
|
-
await notifyUpdate();
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
// buner dev
|
|
159
|
-
program
|
|
160
|
-
.command('dev')
|
|
161
|
-
.description('Start development mode with all watchers')
|
|
162
|
-
.action(async () => {
|
|
163
|
-
await run(bin('concurrently'), [
|
|
164
|
-
'--kill-others',
|
|
165
|
-
`"${bin('tsx')} ${pkg('styles.ts')} --watch"`,
|
|
166
|
-
`"${bin('tsx')} ${pkg('states.ts')} --watch"`,
|
|
167
|
-
`"${bin('cross-env')} scriptOnly=true ${bin('vite')} build --config ${pkg('vite.config.ts')} --mode development --watch"`,
|
|
168
|
-
`"${bin('tsx')} ${pkg('server.ts')} --mode development"`,
|
|
169
|
-
]);
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
// buner serve
|
|
173
|
-
program
|
|
174
|
-
.command('serve')
|
|
175
|
-
.description('Start the SSR dev server')
|
|
176
|
-
.option('--mode <mode>', 'server mode', 'development')
|
|
177
|
-
.action(async (opts) => {
|
|
178
|
-
await run(bin('tsx'), [pkg('server.ts'), '--mode', opts.mode]);
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
// buner build
|
|
182
|
-
program
|
|
183
|
-
.command('build')
|
|
184
|
-
.description('Build the project (static + SSR)')
|
|
185
|
-
.action(async () => {
|
|
186
|
-
runSync(`${bin('vite')} build --config ${pkg('vite.config.ts')} --outDir dist/static`);
|
|
187
|
-
runSync(`${bin('vite')} build --config ${pkg('vite.config.ts')} --ssr src/entry-server.tsx --outDir dist/server`);
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
// buner generate
|
|
191
|
-
program
|
|
192
|
-
.command('generate')
|
|
193
|
-
.description('Full static site generation (states + styles + build + prerender)')
|
|
194
|
-
.option('--mode <mode>', 'build mode', 'production')
|
|
195
|
-
.action(async (opts) => {
|
|
196
|
-
runSync(`${bin('tsx')} ${pkg('states.ts')}`);
|
|
197
|
-
runSync(`${bin('tsx')} ${pkg('styles.ts')}`);
|
|
198
|
-
if (opts.mode === 'production') {
|
|
199
|
-
runSync(`${bin('vite')} build --config ${pkg('vite.config.ts')} --outDir dist/static`);
|
|
200
|
-
runSync(`${bin('vite')} build --config ${pkg('vite.config.ts')} --ssr src/entry-server.tsx --outDir dist/server`);
|
|
201
|
-
} else {
|
|
202
|
-
runSync(`${bin('vite')} build --config ${pkg('vite.config.ts')} --outDir dist/static --mode ${opts.mode}`);
|
|
203
|
-
runSync(`${bin('vite')} build --config ${pkg('vite.config.ts')} --ssr src/entry-server.tsx --outDir dist/server --mode ${opts.mode}`);
|
|
204
|
-
}
|
|
205
|
-
runSync(`${bin('tsx')} ${pkg('prerender.ts')} --add-hash --mode ${opts.mode}`);
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
// buner eshn
|
|
209
|
-
program
|
|
210
|
-
.command('eshn')
|
|
211
|
-
.description('Generate with --mode eshn')
|
|
212
|
-
.action(async () => {
|
|
213
|
-
runSync(`${bin('tsx')} ${pkg('states.ts')}`);
|
|
214
|
-
runSync(`${bin('tsx')} ${pkg('styles.ts')}`);
|
|
215
|
-
runSync(`${bin('vite')} build --config ${pkg('vite.config.ts')} --outDir dist/static --mode eshn`);
|
|
216
|
-
runSync(`${bin('vite')} build --config ${pkg('vite.config.ts')} --ssr src/entry-server.tsx --outDir dist/server --mode eshn`);
|
|
217
|
-
runSync(`${bin('tsx')} ${pkg('prerender.ts')} --add-hash --mode eshn`);
|
|
218
|
-
});
|
|
219
|
-
|
|
220
|
-
// buner inte
|
|
221
|
-
program
|
|
222
|
-
.command('inte')
|
|
223
|
-
.description('Build and integrate with backend (styles + build + prerender + integration)')
|
|
224
|
-
.action(async () => {
|
|
225
|
-
runSync(`${bin('tsx')} ${pkg('styles.ts')}`);
|
|
226
|
-
runSync(`${bin('vite')} build --config ${pkg('vite.config.ts')} --outDir dist/static`);
|
|
227
|
-
runSync(`${bin('vite')} build --config ${pkg('vite.config.ts')} --ssr src/entry-server.tsx --outDir dist/server`);
|
|
228
|
-
runSync(`${bin('tsx')} ${pkg('prerender.ts')}`);
|
|
229
|
-
runSync(`${bin('tsx')} ${pkg('integration.ts')}`);
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
// buner styles
|
|
233
|
-
program
|
|
234
|
-
.command('styles')
|
|
235
|
-
.description('Compile SCSS')
|
|
236
|
-
.option('--watch', 'Watch for changes')
|
|
237
|
-
.action(async (opts) => {
|
|
238
|
-
const args = [pkg('styles.ts')];
|
|
239
|
-
|
|
240
|
-
if (opts.watch) args.push('--watch');
|
|
241
|
-
await run(bin('tsx'), args);
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
// buner prerender
|
|
245
|
-
program
|
|
246
|
-
.command('prerender')
|
|
247
|
-
.description('Pre-render HTML files')
|
|
248
|
-
.option('--add-hash', 'Add content hashes to asset URLs')
|
|
249
|
-
.option('--mode <mode>', 'build mode', 'production')
|
|
250
|
-
.action(async (opts) => {
|
|
251
|
-
const args = [pkg('prerender.ts')];
|
|
252
|
-
|
|
253
|
-
if (opts.addHash) args.push('--add-hash');
|
|
254
|
-
args.push('--mode', opts.mode);
|
|
255
|
-
await run(bin('tsx'), args);
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
program.parseAsync(process.argv).catch(async (error) => {
|
|
259
|
-
console.log(red(error));
|
|
260
|
-
await notifyUpdate();
|
|
261
|
-
process.exit(1);
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
export { packageName };
|
package/cli/cli.ts
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/* eslint-disable no-console */
|
|
3
|
-
|
|
4
|
-
import path from 'path';
|
|
5
|
-
|
|
6
|
-
import { Command } from 'commander';
|
|
7
|
-
import chalk from 'chalk';
|
|
8
|
-
import fetch from 'node-fetch';
|
|
9
|
-
import prompts from 'prompts';
|
|
10
|
-
|
|
11
|
-
import packageJson from '../package.json';
|
|
12
|
-
|
|
13
|
-
import { createApp } from './create-app.js';
|
|
14
|
-
import { validateNpmName } from './helpers/validate-pkg.js';
|
|
15
|
-
|
|
16
|
-
let projectPath = '';
|
|
17
|
-
const program = new Command();
|
|
18
|
-
const { green, yellow, bold, cyan, red } = chalk;
|
|
19
|
-
const packageName = 'x-pkg';
|
|
20
|
-
|
|
21
|
-
const onPromptState = (state: { value?: string; aborted?: boolean }) => {
|
|
22
|
-
if (state?.aborted) {
|
|
23
|
-
// If we don't re-enable the terminal cursor before exiting
|
|
24
|
-
// the program, the cursor will remain hidden
|
|
25
|
-
process.stdout.write('\x1B[?25h');
|
|
26
|
-
process.stdout.write('\n');
|
|
27
|
-
process.exit(1);
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
program
|
|
32
|
-
.name(packageName)
|
|
33
|
-
.description('Create a FE framework')
|
|
34
|
-
.version(packageJson.version)
|
|
35
|
-
.argument('[project-directory]', 'the project name', '')
|
|
36
|
-
.usage(`${green('[project-directory]')} [options]`)
|
|
37
|
-
.action((name) => {
|
|
38
|
-
projectPath = name;
|
|
39
|
-
})
|
|
40
|
-
.allowUnknownOption()
|
|
41
|
-
.parse(process.argv);
|
|
42
|
-
|
|
43
|
-
const parseVersion = (version: string): number => {
|
|
44
|
-
return parseInt(version.replaceAll('.', ''));
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
const update = fetch(`https://registry.npmjs.org/${packageJson.name}/latest`)
|
|
48
|
-
.then((res) => res.json())
|
|
49
|
-
.catch(() => null);
|
|
50
|
-
|
|
51
|
-
async function notifyUpdate(): Promise<void> {
|
|
52
|
-
try {
|
|
53
|
-
const data = (await update) as { version: string };
|
|
54
|
-
|
|
55
|
-
if (data.version && parseVersion(data.version) !== parseVersion(packageJson.version)) {
|
|
56
|
-
const updateMessage = `npm update ${packageName}`;
|
|
57
|
-
|
|
58
|
-
console.log(
|
|
59
|
-
yellow(bold(`A new version of '${packageName}' is available!`)) + '\n' + 'You can update by running: ' + cyan(updateMessage) + '\n'
|
|
60
|
-
);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
process.exit();
|
|
64
|
-
} catch {
|
|
65
|
-
// ignore error
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const run = async () => {
|
|
70
|
-
const validation = validateNpmName(path.basename(path.resolve(projectPath)));
|
|
71
|
-
|
|
72
|
-
if (!validation.valid) {
|
|
73
|
-
const res = await prompts({
|
|
74
|
-
onState: onPromptState,
|
|
75
|
-
type: 'text',
|
|
76
|
-
name: 'path',
|
|
77
|
-
message: 'What is your project named?',
|
|
78
|
-
initial: 'my-app',
|
|
79
|
-
validate: (name) => {
|
|
80
|
-
const validation = validateNpmName(path.basename(path.resolve(name)));
|
|
81
|
-
|
|
82
|
-
if (validation.valid) {
|
|
83
|
-
return true;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return `Invalid project name ${validation?.problems?.[0] ? validation?.problems?.[0] : ''}`;
|
|
87
|
-
},
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
if (typeof res.path === 'string') {
|
|
91
|
-
projectPath = res.path.trim();
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
if (!projectPath) {
|
|
96
|
-
console.log(
|
|
97
|
-
'\nPlease specify the project directory:\n' +
|
|
98
|
-
` ${cyan(program.name())} ${green('<project-directory>')}\n` +
|
|
99
|
-
'For example:\n' +
|
|
100
|
-
` ${cyan(program.name())} ${green('my-app')}\n\n` +
|
|
101
|
-
`Run ${cyan(`${program.name()} --help`)} to see all options.`
|
|
102
|
-
);
|
|
103
|
-
process.exit(1);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const resolvedProjectPath = path.resolve(projectPath);
|
|
107
|
-
|
|
108
|
-
await createApp({
|
|
109
|
-
appPath: resolvedProjectPath,
|
|
110
|
-
});
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
run()
|
|
114
|
-
.then(async () => {
|
|
115
|
-
await notifyUpdate();
|
|
116
|
-
})
|
|
117
|
-
.catch(async (error) => {
|
|
118
|
-
console.log(red(error));
|
|
119
|
-
|
|
120
|
-
await notifyUpdate();
|
|
121
|
-
|
|
122
|
-
process.exit(1);
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
export { packageName };
|
package/cli/create-app.ts
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-console */
|
|
2
|
-
import path from 'path';
|
|
3
|
-
|
|
4
|
-
import chalk from 'chalk';
|
|
5
|
-
|
|
6
|
-
import { isWriteable } from './helpers/is-writeable.js';
|
|
7
|
-
import { makeDir } from './helpers/make-dir.js';
|
|
8
|
-
import { isFolderEmpty } from './helpers/is-folder-empty.js';
|
|
9
|
-
import { tryGitInit } from './helpers/git.js';
|
|
10
|
-
import { installTemplate } from './install-template.js';
|
|
11
|
-
|
|
12
|
-
interface Props {
|
|
13
|
-
appPath: string;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const { green } = chalk;
|
|
17
|
-
|
|
18
|
-
const createApp = async (model: Props) => {
|
|
19
|
-
const { appPath } = model;
|
|
20
|
-
const root = path.resolve(appPath);
|
|
21
|
-
|
|
22
|
-
if (!(await isWriteable(path.dirname(root)))) {
|
|
23
|
-
console.error('The application path is not writable, please check folder permissions and try again.');
|
|
24
|
-
|
|
25
|
-
console.error('It is likely you do not have write permissions for this folder.');
|
|
26
|
-
|
|
27
|
-
process.exit(1);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const appName = path.basename(root);
|
|
31
|
-
|
|
32
|
-
await makeDir(root);
|
|
33
|
-
|
|
34
|
-
if (!isFolderEmpty(root)) {
|
|
35
|
-
console.log(`\nThe directory ${green(appName)} contains files that could conflict or not empty`);
|
|
36
|
-
console.log('\nEither try using a new directory name, or remove these files.');
|
|
37
|
-
|
|
38
|
-
process.exit(1);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
console.log(`\nCreating a new app in ${green(root)}.`);
|
|
42
|
-
|
|
43
|
-
process.chdir(root);
|
|
44
|
-
|
|
45
|
-
await installTemplate({
|
|
46
|
-
appName,
|
|
47
|
-
root,
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
console.log('\nInitializing a git repository.');
|
|
51
|
-
|
|
52
|
-
if (tryGitInit(root)) {
|
|
53
|
-
console.log('\nInitialized a git repository.');
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
console.log(`\n${green('Success!')} Created ${appName} at ${appPath}`);
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
export { createApp };
|
package/cli/helpers/copy.ts
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
import fs from 'fs/promises';
|
|
3
|
-
|
|
4
|
-
import { globby } from 'globby';
|
|
5
|
-
|
|
6
|
-
interface CopyOption {
|
|
7
|
-
cwd: string;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const excludeFiles = [
|
|
11
|
-
'.git',
|
|
12
|
-
'.github',
|
|
13
|
-
'.npmrc',
|
|
14
|
-
'bin',
|
|
15
|
-
'cli',
|
|
16
|
-
'xpack',
|
|
17
|
-
'.vscode',
|
|
18
|
-
'.build',
|
|
19
|
-
'node_modules',
|
|
20
|
-
'server.ts',
|
|
21
|
-
'prerender.ts',
|
|
22
|
-
'integration.ts',
|
|
23
|
-
'styles.ts',
|
|
24
|
-
'scripts.ts',
|
|
25
|
-
'states.ts',
|
|
26
|
-
'migrate-scss.ts',
|
|
27
|
-
'vite.config.ts',
|
|
28
|
-
'vite.cli.config.ts',
|
|
29
|
-
'src',
|
|
30
|
-
'public/samples',
|
|
31
|
-
'public/assets/vendors',
|
|
32
|
-
];
|
|
33
|
-
|
|
34
|
-
const copy = async (src: string | string[], dest: string, { cwd }: CopyOption) => {
|
|
35
|
-
const sourceFiles = await globby(src, {
|
|
36
|
-
cwd,
|
|
37
|
-
dot: true,
|
|
38
|
-
absolute: false,
|
|
39
|
-
gitignore: true,
|
|
40
|
-
ignore: excludeFiles,
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
const destRelativeToCwd = path.resolve(dest);
|
|
44
|
-
|
|
45
|
-
return Promise.all(
|
|
46
|
-
sourceFiles.map(async (p) => {
|
|
47
|
-
const dirname = path.dirname(p);
|
|
48
|
-
const basename = path.basename(p);
|
|
49
|
-
|
|
50
|
-
const from = path.resolve(cwd, p);
|
|
51
|
-
const filePath = path.join(destRelativeToCwd, dirname, basename);
|
|
52
|
-
|
|
53
|
-
// Ensure the destination directory exists
|
|
54
|
-
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
55
|
-
|
|
56
|
-
return fs.copyFile(from, filePath);
|
|
57
|
-
})
|
|
58
|
-
);
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
export { copy };
|
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
import os from 'os';
|
|
3
|
-
import fs from 'fs/promises';
|
|
4
|
-
|
|
5
|
-
const writeFile = async (filePath: string, data: string) => {
|
|
6
|
-
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
7
|
-
await fs.writeFile(filePath, data);
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
const formatFiles = async (root: string) => {
|
|
11
|
-
let filePath, data;
|
|
12
|
-
|
|
13
|
-
// mock handler file
|
|
14
|
-
filePath = path.join(root, 'src/mocks/handlers.ts');
|
|
15
|
-
data = "import { handlers } from './consts';\n\nexport { handlers };";
|
|
16
|
-
|
|
17
|
-
await writeFile(filePath, data + os.EOL);
|
|
18
|
-
|
|
19
|
-
// example mock file
|
|
20
|
-
filePath = path.join(root, 'src/mocks/example/index.ts');
|
|
21
|
-
data = `
|
|
22
|
-
import { handlers } from '@mocks/handlers';
|
|
23
|
-
import { rest } from 'msw';
|
|
24
|
-
|
|
25
|
-
handlers.push(
|
|
26
|
-
rest.get('/api/example', (req, res, ctx) => {
|
|
27
|
-
return res(ctx.status(200), ctx.json({test: 'test'}));
|
|
28
|
-
})
|
|
29
|
-
);
|
|
30
|
-
`;
|
|
31
|
-
|
|
32
|
-
await writeFile(filePath, data + os.EOL);
|
|
33
|
-
|
|
34
|
-
// react loader
|
|
35
|
-
filePath = path.join(root, 'src/react-loader.tsx');
|
|
36
|
-
data = [
|
|
37
|
-
"import { lazy } from 'react';",
|
|
38
|
-
'',
|
|
39
|
-
'export const blocks: { [name: string]: any } = {',
|
|
40
|
-
"\troot: lazy(() => import('./organisms/root/Root')),",
|
|
41
|
-
'};',
|
|
42
|
-
'',
|
|
43
|
-
].join('\n');
|
|
44
|
-
|
|
45
|
-
await writeFile(filePath, data);
|
|
46
|
-
|
|
47
|
-
// src/_types/atoms.d.ts
|
|
48
|
-
filePath = path.join(root, 'src/_types/atoms.d.ts');
|
|
49
|
-
|
|
50
|
-
await writeFile(
|
|
51
|
-
filePath,
|
|
52
|
-
`
|
|
53
|
-
import { BasedAtomicModel } from "./_general";
|
|
54
|
-
`
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
// src/_types/molecules.d.d.ts
|
|
58
|
-
filePath = path.join(root, 'src/_types/molecules.d.ts');
|
|
59
|
-
|
|
60
|
-
await writeFile(
|
|
61
|
-
filePath,
|
|
62
|
-
`
|
|
63
|
-
import { BasedAtomicModel } from "./_general";
|
|
64
|
-
`
|
|
65
|
-
);
|
|
66
|
-
|
|
67
|
-
// src/_types/organisms.d.ts
|
|
68
|
-
filePath = path.join(root, 'src/_types/organisms.d.ts');
|
|
69
|
-
|
|
70
|
-
await writeFile(
|
|
71
|
-
filePath,
|
|
72
|
-
`
|
|
73
|
-
import { BasedAtomicModel } from "./_general";
|
|
74
|
-
|
|
75
|
-
interface FooterModel extends BasedAtomicModel {}
|
|
76
|
-
|
|
77
|
-
interface HeaderModel extends BasedAtomicModel {}
|
|
78
|
-
`
|
|
79
|
-
);
|
|
80
|
-
|
|
81
|
-
// pages/Home.tsx
|
|
82
|
-
filePath = path.join(root, 'src/pages/Home.tsx');
|
|
83
|
-
|
|
84
|
-
await writeFile(
|
|
85
|
-
filePath,
|
|
86
|
-
`
|
|
87
|
-
import Template from '@templates/home/Home';
|
|
88
|
-
|
|
89
|
-
const Home = () => {
|
|
90
|
-
return <Template footer={footer} header={header} />;
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
export default Home;
|
|
94
|
-
`
|
|
95
|
-
);
|
|
96
|
-
|
|
97
|
-
// templates/home/Home.tsx
|
|
98
|
-
filePath = path.join(root, 'src/templates/home/Home.tsx');
|
|
99
|
-
|
|
100
|
-
await writeFile(
|
|
101
|
-
filePath,
|
|
102
|
-
`
|
|
103
|
-
import { FooterModel, HeaderModel } from '@_types/organisms';
|
|
104
|
-
import Footer from '@organisms/footer/Footer';
|
|
105
|
-
import Header from '@organisms/header/Header';
|
|
106
|
-
|
|
107
|
-
interface Props {
|
|
108
|
-
header?: HeaderModel;
|
|
109
|
-
footer?: FooterModel;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const Home = (model: Props) => {
|
|
113
|
-
const { header, footer } = model;
|
|
114
|
-
|
|
115
|
-
return (
|
|
116
|
-
<>
|
|
117
|
-
{header && <Header {...header} />}
|
|
118
|
-
|
|
119
|
-
<main>
|
|
120
|
-
// write components here
|
|
121
|
-
</main>
|
|
122
|
-
|
|
123
|
-
<Footer {...footer} />
|
|
124
|
-
</>
|
|
125
|
-
);
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
export default Home;
|
|
129
|
-
`
|
|
130
|
-
);
|
|
131
|
-
|
|
132
|
-
// src/organisms/header/Header.tsx
|
|
133
|
-
filePath = path.join(root, 'src/organisms/header/Header.tsx');
|
|
134
|
-
|
|
135
|
-
await writeFile(
|
|
136
|
-
filePath,
|
|
137
|
-
`
|
|
138
|
-
import { getModifiers } from '@helpers/functions';
|
|
139
|
-
import RequireCss from '@helpers/RequireCss';
|
|
140
|
-
import { HeaderModel } from '@_types/organisms';
|
|
141
|
-
|
|
142
|
-
const Header = (model: HeaderModel) => {
|
|
143
|
-
const modifiers = getModifiers(model, 'zzz-o-header');
|
|
144
|
-
|
|
145
|
-
return (
|
|
146
|
-
<header className={modifiers}>
|
|
147
|
-
<h2>Header</h2>
|
|
148
|
-
<RequireCss path="b-header" />
|
|
149
|
-
</header>
|
|
150
|
-
);
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
export default Header;
|
|
154
|
-
`
|
|
155
|
-
);
|
|
156
|
-
|
|
157
|
-
// src/organisms/header/Header.scss
|
|
158
|
-
filePath = path.join(root, 'src/organisms/header/Header.scss');
|
|
159
|
-
|
|
160
|
-
await writeFile(filePath, '');
|
|
161
|
-
|
|
162
|
-
// src/organisms/footer/Footer.tsx
|
|
163
|
-
filePath = path.join(root, 'src/organisms/footer/Footer.tsx');
|
|
164
|
-
|
|
165
|
-
await writeFile(
|
|
166
|
-
filePath,
|
|
167
|
-
`
|
|
168
|
-
import { getModifiers } from '@helpers/functions';
|
|
169
|
-
import RequireCss from '@helpers/RequireCss';
|
|
170
|
-
import { FooterModel } from '@_types/organisms';
|
|
171
|
-
|
|
172
|
-
const Footer = (model: FooterModel) => {
|
|
173
|
-
const modifiers = getModifiers(model, 'zzz-o-footer');
|
|
174
|
-
|
|
175
|
-
return (
|
|
176
|
-
<footer className={modifiers}>
|
|
177
|
-
<h2>Footer</h2>
|
|
178
|
-
<RequireCss path="b-footer" />
|
|
179
|
-
</footer>
|
|
180
|
-
);
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
export default Footer;
|
|
184
|
-
`
|
|
185
|
-
);
|
|
186
|
-
|
|
187
|
-
// src/organisms/footer/Footer.scss
|
|
188
|
-
filePath = path.join(root, 'src/organisms/footer/Footer.scss');
|
|
189
|
-
|
|
190
|
-
await writeFile(filePath, '');
|
|
191
|
-
|
|
192
|
-
return ['xxx'];
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
// formatFiles('E:\\projects\\test-x-pkg');
|
|
196
|
-
|
|
197
|
-
export { formatFiles };
|