Meta progaming for detecting static assets usage a build time
This commit is contained in:
parent
1c25b69160
commit
3c2820dc31
@ -3,7 +3,6 @@ import { removeDuplicates } from "evt/tools/reducers/removeDuplicates";
|
|||||||
import { join as pathJoin } from "path";
|
import { join as pathJoin } from "path";
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import type { ThemeType } from "../generateFtl";
|
import type { ThemeType } from "../generateFtl";
|
||||||
import { exclude } from "tsafe/exclude";
|
|
||||||
|
|
||||||
/** Assumes the theme type exists */
|
/** Assumes the theme type exists */
|
||||||
export function readFieldNameUsage(params: { keycloakifySrcDirPath: string; themeSrcDirPath: string; themeType: ThemeType }): string[] {
|
export function readFieldNameUsage(params: { keycloakifySrcDirPath: string; themeSrcDirPath: string; themeType: ThemeType }): string[] {
|
||||||
@ -11,9 +10,7 @@ export function readFieldNameUsage(params: { keycloakifySrcDirPath: string; them
|
|||||||
|
|
||||||
const fieldNames: string[] = [];
|
const fieldNames: string[] = [];
|
||||||
|
|
||||||
for (const srcDirPath of ([pathJoin(keycloakifySrcDirPath, themeType), pathJoin(themeSrcDirPath, themeType)] as const).filter(
|
for (const srcDirPath of [pathJoin(keycloakifySrcDirPath, themeType), pathJoin(themeSrcDirPath, themeType)]) {
|
||||||
exclude(undefined)
|
|
||||||
)) {
|
|
||||||
const filePaths = crawl({ "dirPath": srcDirPath, "returnedPathsType": "absolute" }).filter(filePath => /\.(ts|tsx|js|jsx)$/.test(filePath));
|
const filePaths = crawl({ "dirPath": srcDirPath, "returnedPathsType": "absolute" }).filter(filePath => /\.(ts|tsx|js|jsx)$/.test(filePath));
|
||||||
|
|
||||||
for (const filePath of filePaths) {
|
for (const filePath of filePaths) {
|
||||||
|
@ -0,0 +1,87 @@
|
|||||||
|
import { crawl } from "../../tools/crawl";
|
||||||
|
import { join as pathJoin } from "path";
|
||||||
|
import * as fs from "fs";
|
||||||
|
import type { ThemeType } from "../generateFtl";
|
||||||
|
|
||||||
|
/** Assumes the theme type exists */
|
||||||
|
export function readStaticResourcesUsage(params: { keycloakifySrcDirPath: string; themeSrcDirPath: string; themeType: ThemeType }): {
|
||||||
|
resourcesCommonFilePaths: string[];
|
||||||
|
resourcesFilePaths: string[];
|
||||||
|
} {
|
||||||
|
const { keycloakifySrcDirPath, themeSrcDirPath, themeType } = params;
|
||||||
|
|
||||||
|
const resourcesCommonFilePaths = new Set<string>();
|
||||||
|
const resourcesFilePaths = new Set<string>();
|
||||||
|
|
||||||
|
for (const srcDirPath of [pathJoin(keycloakifySrcDirPath, themeType), pathJoin(themeSrcDirPath, themeType)]) {
|
||||||
|
const filePaths = crawl({ "dirPath": srcDirPath, "returnedPathsType": "absolute" }).filter(filePath => /\.(ts|tsx|js|jsx)$/.test(filePath));
|
||||||
|
|
||||||
|
for (const filePath of filePaths) {
|
||||||
|
const rawSourceFile = fs.readFileSync(filePath).toString("utf8");
|
||||||
|
|
||||||
|
if (!rawSourceFile.includes("resourcesCommonPath")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rawSourceFile.includes("resourcesPath")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const wrap = readPaths({ rawSourceFile });
|
||||||
|
|
||||||
|
wrap.resourcesCommonFilePaths.forEach(filePath => resourcesCommonFilePaths.add(filePath));
|
||||||
|
wrap.resourcesFilePaths.forEach(filePath => resourcesFilePaths.add(filePath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"resourcesCommonFilePaths": Array.from(resourcesCommonFilePaths),
|
||||||
|
"resourcesFilePaths": Array.from(resourcesFilePaths)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Exported for testing purpose */
|
||||||
|
export function readPaths(params: { rawSourceFile: string }): {
|
||||||
|
resourcesCommonFilePaths: string[];
|
||||||
|
resourcesFilePaths: string[];
|
||||||
|
} {
|
||||||
|
const { rawSourceFile } = params;
|
||||||
|
|
||||||
|
const resourcesCommonFilePaths = new Set<string>();
|
||||||
|
const resourcesFilePaths = new Set<string>();
|
||||||
|
|
||||||
|
for (const isCommon of [true, false]) {
|
||||||
|
const set = isCommon ? resourcesCommonFilePaths : resourcesFilePaths;
|
||||||
|
|
||||||
|
{
|
||||||
|
const regexp = new RegExp(`resources${isCommon ? "Common" : ""}Path\\s*}([^\`]+)\``, "g");
|
||||||
|
|
||||||
|
const matches = [...rawSourceFile.matchAll(regexp)];
|
||||||
|
|
||||||
|
for (const match of matches) {
|
||||||
|
const filePath = match[1];
|
||||||
|
|
||||||
|
set.add(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const regexp = new RegExp(`resources${isCommon ? "Common" : ""}Path\\s*[+,]\\s*["']([^"'\`]+)["'\`]`, "g");
|
||||||
|
|
||||||
|
const matches = [...rawSourceFile.matchAll(regexp)];
|
||||||
|
|
||||||
|
for (const match of matches) {
|
||||||
|
const filePath = match[1];
|
||||||
|
|
||||||
|
set.add(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const removePrefixSlash = (filePath: string) => (filePath.startsWith("/") ? filePath.slice(1) : filePath);
|
||||||
|
|
||||||
|
return {
|
||||||
|
"resourcesCommonFilePaths": Array.from(resourcesCommonFilePaths).map(removePrefixSlash),
|
||||||
|
"resourcesFilePaths": Array.from(resourcesFilePaths).map(removePrefixSlash)
|
||||||
|
};
|
||||||
|
}
|
91
test/bin/readStaticResourcesUsage.spec.ts
Normal file
91
test/bin/readStaticResourcesUsage.spec.ts
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import { readPaths } from "keycloakify/bin/keycloakify/generateTheme/readStaticResourcesUsage";
|
||||||
|
import { same } from "evt/tools/inDepth/same";
|
||||||
|
import { expect, it, describe } from "vitest";
|
||||||
|
|
||||||
|
describe("Ensure it's able to extract used Keycloak resources", () => {
|
||||||
|
const expectedPaths = {
|
||||||
|
"resourcesCommonFilePaths": [
|
||||||
|
"node_modules/patternfly/dist/css/patternfly.min.css",
|
||||||
|
"node_modules/patternfly/dist/css/patternfly-additions.min.css",
|
||||||
|
"lib/zocial/zocial.css"
|
||||||
|
],
|
||||||
|
"resourcesFilePaths": ["css/login.css"]
|
||||||
|
};
|
||||||
|
|
||||||
|
it("works with coding style n°1", () => {
|
||||||
|
const paths = readPaths({
|
||||||
|
"rawSourceFile": `
|
||||||
|
const { isReady } = usePrepareTemplate({
|
||||||
|
"doFetchDefaultThemeResources": doUseDefaultCss,
|
||||||
|
"styles": [
|
||||||
|
\`\${url.resourcesCommonPath}/node_modules/patternfly/dist/css/patternfly.min.css\`,
|
||||||
|
\`\${
|
||||||
|
url.resourcesCommonPath
|
||||||
|
}/node_modules/patternfly/dist/css/patternfly-additions.min.css\`,
|
||||||
|
\`\${resourcesCommonPath }/lib/zocial/zocial.css\`,
|
||||||
|
\`\${url.resourcesPath}/css/login.css\`
|
||||||
|
],
|
||||||
|
"htmlClassName": getClassName("kcHtmlClass"),
|
||||||
|
"bodyClassName": undefined
|
||||||
|
});
|
||||||
|
`
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(same(paths, expectedPaths)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("works with coding style n°2", () => {
|
||||||
|
const paths = readPaths({
|
||||||
|
"rawSourceFile": `
|
||||||
|
|
||||||
|
const { isReady } = usePrepareTemplate({
|
||||||
|
"doFetchDefaultThemeResources": doUseDefaultCss,
|
||||||
|
"styles": [
|
||||||
|
url.resourcesCommonPath + "/node_modules/patternfly/dist/css/patternfly.min.css",
|
||||||
|
url.resourcesCommonPath + '/node_modules/patternfly/dist/css/patternfly-additions.min.css',
|
||||||
|
url.resourcesCommonPath
|
||||||
|
+ "/lib/zocial/zocial.css",
|
||||||
|
url.resourcesPath +
|
||||||
|
'/css/login.css'
|
||||||
|
],
|
||||||
|
"htmlClassName": getClassName("kcHtmlClass"),
|
||||||
|
"bodyClassName": undefined
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
`
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(paths);
|
||||||
|
console.log(expectedPaths);
|
||||||
|
|
||||||
|
expect(same(paths, expectedPaths)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("works with coding style n°3", () => {
|
||||||
|
const paths = readPaths({
|
||||||
|
"rawSourceFile": `
|
||||||
|
|
||||||
|
const { isReady } = usePrepareTemplate({
|
||||||
|
"doFetchDefaultThemeResources": doUseDefaultCss,
|
||||||
|
"styles": [
|
||||||
|
path.join(resourcesCommonPath,"/node_modules/patternfly/dist/css/patternfly.min.css"),
|
||||||
|
path.join(url.resourcesCommonPath, '/node_modules/patternfly/dist/css/patternfly-additions.min.css'),
|
||||||
|
path.join(url.resourcesCommonPath,
|
||||||
|
"/lib/zocial/zocial.css"),
|
||||||
|
pathJoin(
|
||||||
|
url.resourcesPath,
|
||||||
|
'css/login.css'
|
||||||
|
)
|
||||||
|
],
|
||||||
|
"htmlClassName": getClassName("kcHtmlClass"),
|
||||||
|
"bodyClassName": undefined
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
`
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(same(paths, expectedPaths)).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user