-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Expand file tree
/
Copy pathindex.ts
More file actions
146 lines (127 loc) · 4.97 KB
/
index.ts
File metadata and controls
146 lines (127 loc) · 4.97 KB
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
import { execSync } from "child_process";
import { spawn } from "cross-spawn";
import { existsSync } from "fs";
import { copy, pathExists } from "fs-extra";
import { join } from "path";
import { stripVTControlCharacters } from "node:util";
import { FrameworkType, SupportLevel } from "../interfaces";
import { select } from "../../prompt";
import {
simpleProxy,
warnIfCustomBuildScript,
findDependency,
getNodeModuleBin,
relativeRequire,
} from "../utils";
export const name = "Vite";
export const support = SupportLevel.Experimental;
export const type = FrameworkType.Toolchain;
export const supportedRange = "3 - 6";
export const DEFAULT_BUILD_SCRIPT = ["vite build", "tsc && vite build"];
export const initViteTemplate = (template: string) => async (setup: any, config: any) =>
await init(setup, config, template);
export async function init(setup: any, config: any, baseTemplate: string = "vanilla") {
const template = await select({
default: "JavaScript",
message: "What language would you like to use?",
choices: [
{ name: "JavaScript", value: baseTemplate },
{ name: "TypeScript", value: `${baseTemplate}-ts` },
],
});
execSync(
`npm create vite@"${supportedRange}" ${setup.featureInfo.hosting.source} --yes -- --template ${template}`,
{
stdio: "inherit",
cwd: config.projectDir,
},
);
execSync(`npm install`, {
stdio: "inherit",
cwd: join(config.projectDir, setup.featureInfo.hosting.source),
});
}
export const viteDiscoverWithNpmDependency = (dep: string) => async (dir: string) =>
await discover(dir, undefined, dep);
export const vitePluginDiscover = (plugin: string) => async (dir: string) =>
await discover(dir, plugin);
export async function discover(dir: string, plugin?: string, npmDependency?: string) {
if (!existsSync(join(dir, "package.json"))) return;
// If we're not searching for a vite plugin, depth has to be zero
const additionalDep =
npmDependency && findDependency(npmDependency, { cwd: dir, depth: 0, omitDev: false });
const depth = plugin ? undefined : 0;
const configFilesExist = await Promise.all([
pathExists(join(dir, "vite.config.js")),
pathExists(join(dir, "vite.config.ts")),
]);
const anyConfigFileExists = configFilesExist.some((it) => it);
const version: string | undefined = findDependency("vite", {
cwd: dir,
depth,
omitDev: false,
})?.version;
if (!anyConfigFileExists && !version) return;
if (npmDependency && !additionalDep) return;
const { appType, publicDir: publicDirectory, plugins } = await getConfig(dir);
if (plugin && !plugins.find(({ name }) => name === plugin)) return;
return {
mayWantBackend: appType !== "spa",
publicDirectory,
version,
vite: true,
};
}
export async function build(root: string, target: string) {
const { build } = await relativeRequire(root, "vite");
await warnIfCustomBuildScript(root, name, DEFAULT_BUILD_SCRIPT);
// SvelteKit uses process.cwd() unfortunately, chdir
const cwd = process.cwd();
process.chdir(root);
const originalNodeEnv = process.env.NODE_ENV;
// Downcasting as `string` as otherwise it is inferred as `readonly 'NODE_ENV'`,
// but `env[key]` expects a non-readonly variable.
const envKey: string = "NODE_ENV";
// Voluntarily making .env[key] not statically analyzable to avoid
// Webpack from converting it to "development" = target;
process.env[envKey] = target;
await build({ root, mode: target });
process.chdir(cwd);
// Voluntarily making .env[key] not statically analyzable to avoid
// Webpack from converting it to "development" = target;
process.env[envKey] = originalNodeEnv;
return { rewrites: [{ source: "**", destination: "/index.html" }] };
}
export async function ɵcodegenPublicDirectory(root: string, dest: string) {
const viteConfig = await getConfig(root);
const viteDistPath = join(root, viteConfig.build.outDir);
await copy(viteDistPath, dest);
}
export async function getDevModeHandle(dir: string) {
const host = new Promise<string>((resolve, reject) => {
// Can't use scheduleTarget since that—like prerender—is failing on an ESM bug
// will just grep for the hostname
const cli = getNodeModuleBin("vite", dir);
const serve = spawn(cli, [], { cwd: dir });
serve.stdout.on("data", (data: any) => {
process.stdout.write(data);
const dataWithoutAnsiCodes = stripVTControlCharacters(data.toString());
const match = dataWithoutAnsiCodes.match(/(http:\/\/.+:\d+)/);
if (match) resolve(match[1]);
});
serve.stderr.on("data", (data: any) => {
process.stderr.write(data);
});
serve.on("exit", reject);
});
return simpleProxy(await host);
}
async function getConfig(root: string) {
const { resolveConfig } = await relativeRequire(root, "vite");
// SvelteKit uses process.cwd() unfortunately, we should be defensive here
const cwd = process.cwd();
process.chdir(root);
const config = await resolveConfig({ root }, "build", "production");
process.chdir(cwd);
return config;
}