Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build: Write and store esbuild metafiles #29117

Merged
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
2806b81
move metafiles
JReinhold Sep 13, 2024
568d96d
use bench-dir for esbuild metafile, fix addon-test collision
JReinhold Sep 13, 2024
1439a0d
fix mixing nx project names
JReinhold Sep 13, 2024
bc838f2
store esbuild metafiles in circleci artifacts
JReinhold Sep 13, 2024
f5537b9
add analyzed metafiles to the output
JReinhold Sep 16, 2024
c5c640f
save metafiles from addons
JReinhold Sep 16, 2024
1f25aaf
add bench story that visualizes metafiles
JReinhold Sep 16, 2024
8af039d
Merge branch 'next' into 29105-save-esbuild-metafiles-and-make-them-a…
JReinhold Sep 16, 2024
1ef0911
cleanup
JReinhold Sep 16, 2024
5fd2058
Merge branch '29105-save-esbuild-metafiles-and-make-them-available-fr…
JReinhold Sep 16, 2024
2649625
persist bench dir between CI jobs
JReinhold Sep 17, 2024
4662d2f
prevent filename collision in core metafiles
JReinhold Sep 17, 2024
a130700
Merge branch 'next' of github.com:storybookjs/storybook into 29105-sa…
JReinhold Sep 17, 2024
6f75f30
Merge branch 'next' into 29105-save-esbuild-metafiles-and-make-them-a…
JReinhold Sep 19, 2024
c376578
fix create-storybook package name in bench stories
JReinhold Sep 21, 2024
5bf9baa
Merge branch '29105-save-esbuild-metafiles-and-make-them-available-fr…
JReinhold Sep 21, 2024
13a9574
merge all metafiles per package, name files after package names inste…
JReinhold Sep 24, 2024
12db3ed
strip @storybook from metafiles
JReinhold Sep 25, 2024
9bf3117
Update .circleci/config.yml
JReinhold Sep 25, 2024
f02e568
Merge branch '29105-save-esbuild-metafiles-and-make-them-available-fr…
JReinhold Sep 25, 2024
173de14
move metafiles to code, so nx can cache it properly
JReinhold Sep 25, 2024
24b85d4
rename nx projects to match package names
JReinhold Sep 25, 2024
ae0d306
don't eagerly import all metafiles in story
JReinhold Sep 25, 2024
18f8cc1
fix bench path in circleci
JReinhold Sep 25, 2024
0266e9e
Merge branch 'next' into 29105-save-esbuild-metafiles-and-make-them-a…
JReinhold Sep 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ jobs:
cd code
yarn local-registry --publish
- report-workflow-on-failure
- store_artifacts:
path: bench/esbuild-metafiles
- save_cache:
name: Save Yarn cache
key: build-yarn-2-cache-v4--{{ checksum "code/yarn.lock" }}--{{ checksum "scripts/yarn.lock" }}
Expand All @@ -175,6 +177,7 @@ jobs:
- code/ui
- code/renderers
- code/presets
- bench
- .verdaccio-cache
lint:
executor:
Expand Down Expand Up @@ -258,8 +261,8 @@ jobs:
root: .
paths:
- code/coverage
- report-workflow-on-failure
- cancel-workflow-on-failure
- report-workflow-on-failure
- cancel-workflow-on-failure
JReinhold marked this conversation as resolved.
Show resolved Hide resolved
coverage:
executor:
class: small
Expand Down
123 changes: 123 additions & 0 deletions code/.storybook/bench.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import React from 'react';

import type { Meta } from '@storybook/react';

// @ts-expect-error - TS doesn't know about import.meta.glob from Vite
JReinhold marked this conversation as resolved.
Show resolved Hide resolved
const allMetafiles = import.meta.glob(
[
'../../bench/esbuild-metafiles/**/*.json',
// the following metafiles are too big to be loaded automatically in the iframe
'!**/core-0.cjs.json',
'!**/core-2.esm.json',
],
{
// eagerly loading is not ideal because it imports all metafiles upfront,
// but it's the only way to create the argTypes from this list,
// as otherwise it would be an async operation
eager: true,
JReinhold marked this conversation as resolved.
Show resolved Hide resolved
}
);

const METAFILES_DIR = '../../bench/esbuild-metafiles/';
const METAFILE_DIR_PKG_NAME_MAP = {
cli: 'storybook',
'cli-sb': 'sb',
'cli-storybook': '@storybook/cli',
'create-storybook': 'create-storybook',
docs: '@storybook/addon-docs',
'addon-test': '@storybook/experimental-addon-test',
} as const;
const TOO_BIG_METAFILES = ['@storybook/core core-0.cjs', '@storybook/core core-2.esm'];

// allows the metafile path to be used in the URL hash
const safeMetafileArg = (path: string) =>
path.replace(METAFILES_DIR, '').replaceAll('/', '_SLASH_').replaceAll('.', '_DOT_');

export default {
title: 'Bench',
parameters: {
layout: 'fullscreen',
chromatic: { disableSnapshot: true },
},
argTypes: {
metafile: {
options: Object.keys(allMetafiles).map(safeMetafileArg).concat(TOO_BIG_METAFILES),
mapping: Object.fromEntries(
Object.keys(allMetafiles).map((path) => [safeMetafileArg(path), path])
),
control: {
type: 'select',
labels: Object.fromEntries(
Object.keys(allMetafiles)
.concat(TOO_BIG_METAFILES)
.map((path) => {
if (TOO_BIG_METAFILES.includes(path)) {
return [path, `${path} - TOO BIG PLEASE UPLOAD MANUALLY`];
}
// example path: ../../bench/esbuild-metafiles/actions/previewEntries-esm.json

const pkgDir = path.split('/').at(-2)!; // 'actions'
const basename = path.split('/').at(-1)!.split('.').at(0)!; // 'previewEntries-esm'
const entriesMatch = path.match(/\w+Entries/); // ['previewEntries']

let pkgName;
if (pkgDir in METAFILE_DIR_PKG_NAME_MAP) {
pkgName = METAFILE_DIR_PKG_NAME_MAP[pkgDir];
} else if (entriesMatch) {
// only addons have specific xEntries files
pkgName = `@storybook/addon-${pkgDir}`;
} else {
pkgName = `@storybook/${pkgDir}`;
}

let extraInfo = '';

if (pkgDir === 'core') {
extraInfo = `- ${basename} `;
} else if (entriesMatch) {
extraInfo = `- ${entriesMatch[0]} `;
}
const moduleType = path.includes('cjs') ? 'CJS' : 'ESM';

return [safeMetafileArg(path), `${pkgName} ${extraInfo}- ${moduleType}`];
})
),
},
},
},
render: (args) => {
if (!args.metafile) {
return (
<div
style={{
width: '100%',
height: '100vh',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
<span>
Select a metafile in the <code>metafile</code> Control
</span>
</div>
);
}
const metafile = allMetafiles[args.metafile];
const encodedMetafile = btoa(JSON.stringify(metafile));

return (
<iframe
// esbuild analyzer has a hidden feature to load a base64-encoded metafile from the the URL hash
// see https://github.com/esbuild/esbuild.github.io/blob/ccf70086543a034495834b4135e15e91a3ffceb8/src/analyze/index.ts#L113-L116
src={`https://esbuild.github.io/analyze/#${encodedMetafile}`}
style={{ border: 'none', width: '100%', height: '100vh' }}
key={args.metafile} // force re-render on args change
/>
);
},
} satisfies Meta;

export const ESBuildAnalyzer = {
name: 'ESBuild Metafiles',
};
1 change: 1 addition & 0 deletions code/.storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const managerApiPath = join(__dirname, '../core/src/manager-api');

const config: StorybookConfig = {
stories: [
'./*.stories.@(js|jsx|ts|tsx)',
{
directory: '../core/template/stories',
titlePrefix: 'core',
Expand Down
41 changes: 26 additions & 15 deletions code/core/scripts/prep.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
process,
} from '../../../scripts/prepare/tools';
import pkg from '../package.json';
import meta from '../src/components/components/Badge/Badge.stories';
import { globalsModuleInfoMap } from '../src/manager/globals-module-info';
import { getBundles, getEntries, getFinals } from './entries';
import { generatePackageJsonFile } from './helpers/generatePackageJsonFile';
Expand Down Expand Up @@ -306,27 +307,37 @@ async function run() {
console.log(`compiled ${chalk.cyan(filename)}`);
});
} else {
// repo root/bench/esbuild-metafiles/core
const metafilesDir = join(__dirname, '..', '..', '..', 'bench', 'esbuild-metafiles', 'core');
if (existsSync(metafilesDir)) {
await rm(metafilesDir, { recursive: true });
}
ndelangen marked this conversation as resolved.
Show resolved Hide resolved
await mkdir(metafilesDir, { recursive: true });

await Promise.all(
compile.map(async (context, index) => {
const out = await context.rebuild();
await context.dispose();

if (out.metafile) {
const { outputs } = out.metafile;
const keys = Object.keys(outputs);
const format = keys.every((key) => key.endsWith('.js')) ? 'esm' : 'cjs';
const outName =
keys.length === 1 ? dirname(keys[0]).replace('dist/', '') : `meta-${format}-${index}`;

if (!existsSync('report')) {
mkdirSync('report');
}
await writeFile(`report/${outName}.json`, JSON.stringify(out.metafile, null, 2));
await writeFile(
`report/${outName}.txt`,
await esbuild.analyzeMetafile(out.metafile, { color: false, verbose: false })
);
if (!out.metafile) {
return;
}

const { outputs } = out.metafile;
const keys = Object.keys(outputs);
const format = keys.every((key) => key.endsWith('.js')) ? 'esm' : 'cjs';
const moduleName =
keys.length === 1 ? dirname(keys[0]).replace('dist/', '') : `core-${index}`;
const basename = `${moduleName}.${format}`;

await writeFile(
join(metafilesDir, `${basename}.json`),
JSON.stringify(out.metafile, null, 2)
);
await writeFile(
join(metafilesDir, `${basename}.txt`),
await esbuild.analyzeMetafile(out.metafile, { color: false, verbose: false })
);
})
);
}
Expand Down
1 change: 1 addition & 0 deletions code/lib/instrumenter/project.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"name": "instrumenter",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"projectType": "library",
"targets": {
Expand Down
1 change: 1 addition & 0 deletions code/lib/test/project.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"name": "test",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"projectType": "library",
"targets": {
Expand Down
2 changes: 1 addition & 1 deletion code/nx.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
"{workspaceRoot}/../scripts/prepare/{bundle,addon-bundle,esm-bundle}.ts"
],
"dependsOn": ["^build"],
"outputs": ["{projectRoot}/dist"],
"outputs": ["{projectRoot}/dist", "{workspaceRoot}/../bench/esbuild-metafiles/{projectName}"],
"cache": true
},
"test": {
Expand Down
Loading