web: simplify ?inline
handler for Storybook (#12246)
* web: Add InvalidationFlow to Radius Provider dialogues ## What - Bugfix: adds the InvalidationFlow to the Radius Provider dialogues - Repairs: `{"invalidation_flow":["This field is required."]}` message, which was *not* propagated to the Notification. - Nitpick: Pretties `?foo=${true}` expressions: `s/\?([^=]+)=\$\{true\}/\1/` ## Note Yes, I know I'm going to have to do more magic when we harmonize the forms, and no, I didn't add the Property Mappings to the wizard, and yes, I know I'm going to have pain with the *new* version of the wizard. But this is a serious bug; you can't make Radius servers with *either* of the current dialogues at the moment. * web: simplify `?inline` handler for Storybook # What - Revise the `?inline` handler for Storybook - Enable headless test runs of E2E - Reduce headless testing to single instances # Why ## `?inline` handling Vite-for-Storybook-for-Web-Components has a requirement that all component CSS imports be suffixed with an `?inline` argument so Vite knows to put the CSS into the component and not inject it into the document head. This `?inline` argument is an implementation detail of Storybook. It would be irrelevant clutter added to our codebase. We were using `rollup-plugin-modify` to find every instance of an import-to-component, but the implementation was clunky and involved scanning the source code manually. `rollup-plugin-modify` version 3 has regular expressions and takes a function as an argument. This allows us to generate the CSS import maps on-the-fly when Storybook is run, eliminating a fragile build step. We can also remove the source code scanner for those imports. ## Changes to testing It's just nice to be able to run the E2E tests headlessly, without them eating up your screen real estate, flashing, or grabbing your mouse. WebdriverIO's testing of Web Components is new and, as we've seen, a bit cranky. The WebdriverIO team currently recommends not running the tests in parallel. We only have about 70 tests so far, and they're fairly speedy, especially when you don't have to invoke a browser session for every test.
This commit is contained in:
@ -1,91 +0,0 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
|
||||
const __dirname = fileURLToPath(new URL(".", import.meta.url));
|
||||
|
||||
function* walkFilesystem(dir) {
|
||||
const openeddir = fs.opendirSync(dir);
|
||||
if (!openeddir) {
|
||||
return;
|
||||
}
|
||||
let d;
|
||||
while ((d = openeddir?.readSync())) {
|
||||
if (!d) {
|
||||
break;
|
||||
}
|
||||
const entry = path.join(dir, d.name);
|
||||
if (d.isDirectory()) yield* walkFilesystem(entry);
|
||||
else if (d.isFile()) yield entry;
|
||||
}
|
||||
openeddir.close();
|
||||
}
|
||||
|
||||
const import_re = /^(import \w+ from .*\.css)";/;
|
||||
|
||||
function extractImportLinesFromFile(path) {
|
||||
const source = fs.readFileSync(path, { encoding: "utf8", flag: "r" });
|
||||
const lines = source?.split("\n") ?? [];
|
||||
return lines.filter((l) => import_re.test(l));
|
||||
}
|
||||
|
||||
function createOneImportLine(line) {
|
||||
const importMatch = import_re.exec(line);
|
||||
if (!importMatch) {
|
||||
throw new Error("How did an unmatchable line get here?");
|
||||
}
|
||||
const importContent = importMatch[1];
|
||||
if (!importContent) {
|
||||
throw new Error("How did an unmatchable line get here!?");
|
||||
}
|
||||
return ` '${importContent}";',`;
|
||||
}
|
||||
|
||||
const isSourceFile = /\.ts$/;
|
||||
|
||||
function getTheSourceFiles() {
|
||||
return Array.from(walkFilesystem(path.join(__dirname, "..", "src"))).filter((path) =>
|
||||
isSourceFile.test(path),
|
||||
);
|
||||
}
|
||||
|
||||
function getTheImportLines(importPaths) {
|
||||
const importLines = importPaths.reduce(
|
||||
(acc, path) => [...acc, extractImportLinesFromFile(path)].flat(),
|
||||
[],
|
||||
);
|
||||
const uniqueImportLines = new Set(importLines);
|
||||
const sortedImportLines = Array.from(uniqueImportLines.keys());
|
||||
sortedImportLines.sort();
|
||||
return sortedImportLines;
|
||||
}
|
||||
|
||||
const importPaths = getTheSourceFiles();
|
||||
const importLines = getTheImportLines(importPaths);
|
||||
|
||||
const outputFile = `// THIS IS A GENERATED FILE. DO NOT EDIT BY HAND.
|
||||
//
|
||||
// This file is generated by the build-storybook-import-maps script in the UI's base directory.
|
||||
// This is a *hack* to work around an inconsistency in the way rollup, vite, and storybook
|
||||
// import CSS modules.
|
||||
//
|
||||
// Sometime around 2030 or so, the Javascript community may finally get its collective act together
|
||||
// and we'll have one unified way of doing this. I can only hope.
|
||||
|
||||
const rawCssImportMaps = [
|
||||
${importLines.map(createOneImportLine).join("\n")}
|
||||
];
|
||||
|
||||
const cssImportMaps = rawCssImportMaps.reduce(
|
||||
(acc, line) => ({ ...acc, [line]: line.replace(/\\.css/, ".css?inline") }),
|
||||
{},
|
||||
);
|
||||
|
||||
export { cssImportMaps };
|
||||
export default cssImportMaps;
|
||||
`;
|
||||
|
||||
fs.writeFileSync(path.join(__dirname, "..", ".storybook", "css-import-maps.ts"), outputFile, {
|
||||
encoding: "utf8",
|
||||
flag: "w",
|
||||
});
|
Reference in New Issue
Block a user