diff --git a/README.md b/README.md index d90b45f9a..bd1c4e19e 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ yarn # Starting storybook yarn storybook +# You can run 'npx tsc -w -p src' on another terminal for enabling hot reloading. # Starting test apps yarn start-cra # For testing in in a Create React App setup diff --git a/package.json b/package.json index bce0d7a64..8cef7fb1e 100755 --- a/package.json +++ b/package.json @@ -21,8 +21,9 @@ "format": "yarn _format --write", "format:check": "yarn _format --list-different", "grant_exec_perms": "node dist/bin/tools/grant_exec_perms", - "storybook": "yarn build && ((tsc -w -p src) & start-storybook -p 6006)", - "build-storybook": "yarn build && build-storybook" + "storybook": "yarn build && yarn only-include-used-icons && start-storybook -p 6006", + "build-storybook": "yarn build && yarn only-include-used-icons && build-storybook", + "only-include-used-icons": "node dist/bin/only-include-used-icons.js" }, "bin": { "copy-dsfr-to-public": "dist/bin/copy-dsfr-to-public.js", diff --git a/src/bin/only-include-used-icons.ts b/src/bin/only-include-used-icons.ts index 24de95189..0057c5ca4 100644 --- a/src/bin/only-include-used-icons.ts +++ b/src/bin/only-include-used-icons.ts @@ -7,7 +7,7 @@ import { assert } from "tsafe/assert"; import { exclude } from "tsafe/exclude"; import { writeFile, readFile, rm } from "fs/promises"; import { crawl } from "./tools/crawl"; -import { basename as pathBasename, sep as pathSep } from "path"; +import { basename as pathBasename, sep as pathSep, dirname as pathDirname } from "path"; import type { Equals } from "tsafe"; export const pathOfIconsJson = pathJoin("utility", "icons", "icons.json"); @@ -97,9 +97,10 @@ async function main() { const cwd = process.cwd(); - const nodeModulesDirPath = pathJoin(cwd, "node_modules"); - - const dsfrDistDirPath = pathJoin(...[nodeModulesDirPath, ...packageName.split("/"), "dsfr"]); + const dsfrDistDirPath = + getProjectRoot() === cwd + ? pathJoin(cwd, "dist", "dsfr") + : pathJoin(...[cwd, "node_modules", ...packageName.split("/"), "dsfr"]); const icons: Icon[] = JSON.parse( (await readFile(pathJoin(dsfrDistDirPath, pathOfIconsJson))).toString("utf8") @@ -158,6 +159,12 @@ async function main() { return false; } + if ( + pathDirname(relativeDirPath).endsWith(pathJoin(...packageName.split("/"))) + ) { + return pathBasename(relativeDirPath) === "src"; + } + if (pathBasename(relativeDirPath) === "node_modules") { return false; } @@ -230,6 +237,8 @@ async function main() { return { usedIconClassNames }; })(); + console.log("Detected usage of the following icons: ", usedIconClassNames); + const usedIcons = usedIconClassNames.map(className => { const icon = icons.find(({ prefix, iconId }) => `${prefix}${iconId}` === className); @@ -263,14 +272,15 @@ async function main() { rm(nextCacheDir, { "recursive": true, "force": true }); }; - [ - dsfrDistDirPath, - ...(() => { - const dsfrDistInPublic = pathJoin(cwd, "public", "dsfr"); + [dsfrDistDirPath, pathJoin(cwd, "public", "dsfr")].forEach(async dsfrDistDirPath => { + const cssFilePaths = ["icons.css", "icons.min.css"].map(cssFileBasename => + pathJoin(dsfrDistDirPath, "utility", "icons", cssFileBasename) + ); + + if (cssFilePaths.some(cssFilePath => !fs.existsSync(cssFilePath))) { + return; + } - return fs.existsSync(dsfrDistInPublic) ? [dsfrDistInPublic] : []; - })() - ].forEach(async dsfrDistDirPath => { const remixiconDirPath = pathJoin(dsfrDistDirPath, "icons", "remixicon"); if (!fs.existsSync(remixiconDirPath)) { @@ -287,9 +297,7 @@ async function main() { ) ); - ["icons.css", "icons.min.css"].forEach(async cssFileBasename => { - const filePath = pathJoin(dsfrDistDirPath, "utility", "icons", cssFileBasename); - + cssFilePaths.forEach(async filePath => { const currentCode = await readFile(filePath); if (Buffer.compare(rawIconCssCodeBuffer, currentCode) === 0) {