diff --git a/code/package.json b/code/package.json index 77f8d397acf0..a4d29b408b16 100644 --- a/code/package.json +++ b/code/package.json @@ -278,6 +278,7 @@ "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", "esbuild": "^0.14.48", + "esbuild-loader": "^2.19.0", "esbuild-plugin-alias": "^0.2.1", "eslint": "^7.17.0", "eslint-plugin-cypress": "^2.11.2", diff --git a/code/yarn.lock b/code/yarn.lock index 940aa44590bf..05cd20b0c5fb 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -9006,6 +9006,7 @@ __metadata: enzyme: ^3.11.0 enzyme-adapter-react-16: ^1.15.5 esbuild: ^0.14.48 + esbuild-loader: ^2.19.0 esbuild-plugin-alias: ^0.2.1 eslint: ^7.17.0 eslint-plugin-cypress: ^2.11.2 @@ -20455,6 +20456,22 @@ __metadata: languageName: node linkType: hard +"esbuild-loader@npm:^2.19.0": + version: 2.19.0 + resolution: "esbuild-loader@npm:2.19.0" + dependencies: + esbuild: ^0.14.39 + joycon: ^3.0.1 + json5: ^2.2.0 + loader-utils: ^2.0.0 + tapable: ^2.2.0 + webpack-sources: ^2.2.0 + peerDependencies: + webpack: ^4.40.0 || ^5.0.0 + checksum: 309b4bd169ffd1d743ad7099182323a179dec789cd5eb4f5f0258c1c13034a154917679e2402bfcedd90c9b03d06d773e97fe4aa1056274dc43d30633c5707e1 + languageName: node + linkType: hard + "esbuild-netbsd-64@npm:0.14.49": version: 0.14.49 resolution: "esbuild-netbsd-64@npm:0.14.49" diff --git a/scripts/example.ts b/scripts/example.ts index 0493103754ae..4c7adb744f70 100644 --- a/scripts/example.ts +++ b/scripts/example.ts @@ -155,16 +155,47 @@ async function readMainConfig({ cwd }: { cwd: string }) { return readConfig(mainConfigPath); } +// NOTE: the test here will apply whether the path is symlink-preserved or otherwise +const webpackFinalCode = ` + (config) => ({ + ...config, + module: { + ...config.modules, + rules: [ + { + test: [/\\/node_modules\\/@storybook\\/[^/]*\\/template\\/stories\\//], + loader: '../../code/node_modules/esbuild-loader', + options: { + loader: 'tsx', + target: 'es2015', + }, + }, + ...config.module.rules, + ], + }, + })`; + +// paths are of the form 'node_modules/@storybook/react' async function addStories(paths: string[], { cwd }: { cwd: string }) { const mainConfig = await readMainConfig({ cwd }); const stories = mainConfig.getFieldValue(['stories']) as string[]; - const extraStories = paths.map((p) => path.resolve(p, './template/stories/*.stories.*')); + const extraStoryDirsAndExistence = await Promise.all( + paths + .map((p) => path.join(p, 'template', 'stories')) + .map(async (p) => [p, await pathExists(path.resolve(codeDir, p))] as const) + ); + + const extraStories = extraStoryDirsAndExistence + .filter(([, exists]) => exists) + .map(([p]) => path.join('..', p, '*.stories.@(js|jsx|ts|tsx)')); mainConfig.setFieldValue(['stories'], [...stories, ...extraStories]); - const code = '(c) => ({ ...c, rules: { ...c.rules, } })'; - // @ts-ignore (not sure why TS complains here, it does exist) - mainConfig.setFieldNode(['webpackFinal'], babelParse(code).program.body[0].expression); + mainConfig.setFieldNode( + ['webpackFinal'], + // @ts-ignore (not sure why TS complains here, it does exist) + babelParse(webpackFinalCode).program.body[0].expression + ); await writeConfig(mainConfig); } @@ -201,10 +232,9 @@ async function main() { // TODO -- can we get the options type to return something more specific const renderer = renderersMap[framework as 'react' | 'angular']; - const isTS = isTSMap[framework as 'react' | 'angular']; const storiesToAdd = [] as string[]; - storiesToAdd.push(path.join(codeDir, 'renderers', renderer)); + storiesToAdd.push(path.join('node_modules', '@storybook', renderer)); // TODO -- sb add doesn't actually work properly: // - installs in `deps` not `devDeps` @@ -217,9 +247,8 @@ async function main() { } for (const addon of [...defaultAddons, ...optionValues.addon]) { - storiesToAdd.push(path.join(codeDir, 'addons', addon)); + storiesToAdd.push(path.join('node_modules', '@storybook', `addon-${addon}`)); } - await addStories(storiesToAdd, { cwd }); if (link) {