Skip to content

Commit 0bddcd1

Browse files
committed
Support vite publicDir config
1 parent 12dc6f6 commit 0bddcd1

File tree

3 files changed

+135
-36
lines changed

3 files changed

+135
-36
lines changed

src/bin/copy-dsfr-to-public.ts

Lines changed: 133 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,147 @@
11
#!/usr/bin/env node
22

3-
import { join as pathJoin } from "path";
3+
import { join as pathJoin, relative as pathRelative } from "path";
44
import * as fs from "fs";
55
import { getProjectRoot } from "./tools/getProjectRoot";
6+
import { assert } from "tsafe/assert";
7+
import type { Equals } from "tsafe";
68

7-
const projectDirPath = process.cwd();
9+
(async () => {
10+
const projectDirPath = process.cwd();
811

9-
const publicDirPath = pathJoin(projectDirPath, "public");
12+
const viteConfigFilePath = (() => {
13+
for (const ext of [".js", ".ts"]) {
14+
const candidateFilePath = pathJoin(projectDirPath, `vite.config${ext}`);
1015

11-
if (!fs.existsSync(publicDirPath)) {
16+
if (!fs.existsSync(candidateFilePath)) {
17+
continue;
18+
}
19+
20+
return candidateFilePath;
21+
}
22+
23+
return undefined;
24+
})();
25+
26+
const publicDirPath =
27+
viteConfigFilePath !== undefined
28+
? await (async function getVitePublicDirPath() {
29+
const viteConfig = fs.readFileSync(viteConfigFilePath).toString("utf8");
30+
31+
if (!viteConfig.includes("publicDir")) {
32+
return pathJoin(projectDirPath, "public");
33+
}
34+
35+
const [, afterPublicDir] = viteConfig.split(/\s["']?publicDir["']?\s*:/);
36+
37+
for (let indexEnd = 0; indexEnd < afterPublicDir.length; indexEnd++) {
38+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
39+
const {
40+
default: path,
41+
basename,
42+
dirname,
43+
delimiter,
44+
extname,
45+
format,
46+
isAbsolute,
47+
join,
48+
normalize,
49+
parse,
50+
posix,
51+
relative,
52+
resolve,
53+
sep,
54+
toNamespacedPath,
55+
win32,
56+
...rest
57+
} = await import("path");
58+
assert<Equals<keyof typeof rest, never>>();
59+
60+
const part = afterPublicDir
61+
.substring(0, indexEnd)
62+
.replace(/__dirname/g, `"${projectDirPath}"`);
63+
64+
let candidate: string;
65+
66+
try {
67+
candidate = eval(part);
68+
} catch {
69+
continue;
70+
}
71+
72+
if (typeof candidate !== "string") {
73+
continue;
74+
}
75+
76+
return candidate;
77+
}
78+
79+
console.error(
80+
`Can't parse the vite configuration please open an issue about it ${getRepoIssueUrl()}`
81+
);
82+
83+
process.exit(-1);
84+
})()
85+
: pathJoin(projectDirPath, "public");
86+
87+
edit_gitignore: {
88+
const gitignoreFilePath = pathJoin(projectDirPath, ".gitignore");
89+
90+
if (!fs.existsSync(gitignoreFilePath)) {
91+
fs.writeFileSync(gitignoreFilePath, Buffer.from("", "utf8"));
92+
}
93+
94+
const gitignoreRaw = fs.readFileSync(gitignoreFilePath).toString("utf8");
95+
96+
const pathToIgnore = `/${pathJoin(pathRelative(projectDirPath, publicDirPath), "dsfr")}/`;
97+
98+
if (gitignoreRaw.split("\n").find(line => line.startsWith(pathToIgnore)) !== undefined) {
99+
break edit_gitignore;
100+
}
101+
102+
fs.writeFileSync(
103+
gitignoreFilePath,
104+
Buffer.from(`${gitignoreRaw}\n${pathToIgnore}\n`, "utf8")
105+
);
106+
}
107+
108+
if (!fs.existsSync(publicDirPath)) {
109+
if (viteConfigFilePath === undefined) {
110+
console.error(
111+
[
112+
"There is no public/ directory in the current working directory, we don't know your framework",
113+
"you are not calling this script at the right location or we don't know your React framework",
114+
`please submit an issue about it here ${getRepoIssueUrl()}`
115+
].join(" ")
116+
);
117+
118+
process.exit(-1);
119+
}
120+
121+
fs.mkdirSync(publicDirPath, { "recursive": true });
122+
}
123+
124+
const dsfrDirPath = pathJoin(publicDirPath, "dsfr");
125+
126+
if (fs.existsSync(dsfrDirPath)) {
127+
fs.rmSync(dsfrDirPath, { "recursive": true, "force": true });
128+
}
129+
130+
fs.cpSync(
131+
pathJoin(projectDirPath, "node_modules", "@codegouvfr", "react-dsfr", "dsfr"),
132+
dsfrDirPath,
133+
{
134+
"recursive": true
135+
}
136+
);
137+
})();
138+
139+
function getRepoIssueUrl() {
12140
const reactDsfrRepoUrl = JSON.parse(
13141
fs.readFileSync(pathJoin(getProjectRoot(), "package.json")).toString("utf8")
14142
)
15143
["repository"]["url"].replace(/^git/, "https:")
16144
.replace(/\.git$/, "");
17145

18-
console.error(
19-
[
20-
"There is no public/ directory in the current working directory, we don't know your framework",
21-
"you are not calling this script at the right location or we don't know your React framework",
22-
`please submit an issue about it here ${reactDsfrRepoUrl}/issues`
23-
].join(" ")
24-
);
25-
26-
process.exit(-1);
146+
return `${reactDsfrRepoUrl}/issues`;
27147
}
28-
29-
const dsfrDirPath = pathJoin(publicDirPath, "dsfr");
30-
31-
if (fs.existsSync(dsfrDirPath)) {
32-
fs.rmSync(dsfrDirPath, { "recursive": true, "force": true });
33-
}
34-
35-
fs.cpSync(
36-
pathJoin(projectDirPath, "node_modules", "@codegouvfr", "react-dsfr", "dsfr"),
37-
dsfrDirPath,
38-
{
39-
"recursive": true
40-
}
41-
);

test/integration/vite/.gitignore

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,3 @@
1-
# Logs
2-
logs
3-
*.log
4-
npm-debug.log*
5-
yarn-debug.log*
6-
yarn-error.log*
7-
pnpm-debug.log*
8-
lerna-debug.log*
91

102
node_modules
113
dist
@@ -23,4 +15,4 @@ dist-ssr
2315
*.sln
2416
*.sw?
2517

26-
/public/dsfr
18+
/public/dsfr/

test/integration/vite/vite.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import react from "@vitejs/plugin-react";
44
// https://vitejs.dev/config/
55
export default defineConfig({
66
plugins: [react()],
7+
publicDir: "public",
78
server: {
89
fs: {
910
allow: ['../../..']

0 commit comments

Comments
 (0)