diff --git a/code/builders/builder-webpack5/package.json b/code/builders/builder-webpack5/package.json index f601717dfa02..1b1cc9d002eb 100644 --- a/code/builders/builder-webpack5/package.json +++ b/code/builders/builder-webpack5/package.json @@ -36,6 +36,11 @@ "node": "./dist/presets/preview-preset.js", "require": "./dist/presets/preview-preset.js" }, + "./loaders/export-order-loader": { + "types": "./dist/loaders/export-order-loader.d.ts", + "node": "./dist/loaders/export-order-loader.js", + "require": "./dist/loaders/export-order-loader.js" + }, "./templates/virtualModuleModernEntry.js.handlebars": "./templates/virtualModuleModernEntry.js.handlebars", "./templates/preview.ejs": "./templates/preview.ejs", "./package.json": "./package.json" @@ -69,15 +74,16 @@ "@types/node": "^18.0.0", "@types/semver": "^7.3.4", "babel-loader": "^9.0.0", - "babel-plugin-named-exports-order": "^0.0.2", "browser-assert": "^1.2.1", "case-sensitive-paths-webpack-plugin": "^2.4.0", "constants-browserify": "^1.0.0", "css-loader": "^6.7.1", + "es-module-lexer": "^0.9.3", "express": "^4.17.3", "fork-ts-checker-webpack-plugin": "^8.0.0", "fs-extra": "^11.1.0", "html-webpack-plugin": "^5.5.0", + "magic-string": "^0.30.5", "path-browserify": "^1.0.1", "process": "^0.11.10", "semver": "^7.3.7", @@ -114,7 +120,8 @@ "entries": [ "./src/index.ts", "./src/presets/custom-webpack-preset.ts", - "./src/presets/preview-preset.ts" + "./src/presets/preview-preset.ts", + "./src/loaders/export-order-loader.ts" ], "platform": "node" }, diff --git a/code/builders/builder-webpack5/src/loaders/export-order-loader.ts b/code/builders/builder-webpack5/src/loaders/export-order-loader.ts new file mode 100644 index 000000000000..2ac744fc913d --- /dev/null +++ b/code/builders/builder-webpack5/src/loaders/export-order-loader.ts @@ -0,0 +1,25 @@ +import { parse } from 'es-module-lexer'; +import MagicString from 'magic-string'; +import type { LoaderContext } from 'webpack'; + +export default async function loader(this: LoaderContext, source: string) { + const callback = this.async(); + + try { + // eslint-disable-next-line @typescript-eslint/naming-convention + const [_, exports] = parse(source); + + if (exports.includes('__namedExportsOrder')) { + return callback(null, source); + } + + const magicString = new MagicString(source); + const orderedExports = exports.filter((e) => e !== 'default'); + magicString.append(`;export const __namedExportsOrder = ${JSON.stringify(orderedExports)};`); + + const map = magicString.generateMap({ hires: true }); + return callback(null, magicString.toString(), map); + } catch (err) { + return callback(err as any); + } +} diff --git a/code/builders/builder-webpack5/src/presets/preview-preset.ts b/code/builders/builder-webpack5/src/presets/preview-preset.ts index eba1e361bbdf..bf061b5bd32d 100644 --- a/code/builders/builder-webpack5/src/presets/preview-preset.ts +++ b/code/builders/builder-webpack5/src/presets/preview-preset.ts @@ -18,16 +18,5 @@ export const entries = async (_: unknown, options: any) => { return result; }; -export const babel = async (config: any, options: any) => ({ - ...config, - overrides: [ - ...(config?.overrides || []), - { - test: /\.(story|stories).*$/, - plugins: [require.resolve('babel-plugin-named-exports-order')], - }, - ], -}); - export const previewMainTemplate = () => require.resolve('@storybook/builder-webpack5/templates/preview.ejs'); diff --git a/code/builders/builder-webpack5/src/preview/iframe-webpack.config.ts b/code/builders/builder-webpack5/src/preview/iframe-webpack.config.ts index e34cb0d70ef1..ab97a724f491 100644 --- a/code/builders/builder-webpack5/src/preview/iframe-webpack.config.ts +++ b/code/builders/builder-webpack5/src/preview/iframe-webpack.config.ts @@ -301,6 +301,14 @@ export default async ( ].filter(Boolean), module: { rules: [ + { + test: /\.stories\.([tj])sx?$|(stories|story)\.mdx$/, + use: [ + { + loader: require.resolve('@storybook/builder-webpack5/loaders/export-order-loader'), + }, + ], + }, { test: /\.m?js$/, type: 'javascript/auto', diff --git a/code/lib/cli/src/generators/REACT_SCRIPTS/index.ts b/code/lib/cli/src/generators/REACT_SCRIPTS/index.ts index 5a0300c25b5a..866b2210664a 100644 --- a/code/lib/cli/src/generators/REACT_SCRIPTS/index.ts +++ b/code/lib/cli/src/generators/REACT_SCRIPTS/index.ts @@ -44,8 +44,6 @@ const generator: Generator = async (packageManager, npmOptions, options) => { const extraPackages = []; extraPackages.push('webpack'); - // Miscellaneous dependency used in `babel-preset-react-app` but not listed as dep there - extraPackages.push('babel-plugin-named-exports-order'); // Miscellaneous dependency to add to be sure Storybook + CRA is working fine with Yarn PnP mode extraPackages.push('prop-types'); diff --git a/code/yarn.lock b/code/yarn.lock index c86bd332309d..4ea9b0a2dd7b 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -6165,15 +6165,16 @@ __metadata: "@types/webpack-hot-middleware": "npm:^2.25.6" "@types/webpack-virtual-modules": "npm:^0.1.1" babel-loader: "npm:^9.0.0" - babel-plugin-named-exports-order: "npm:^0.0.2" browser-assert: "npm:^1.2.1" case-sensitive-paths-webpack-plugin: "npm:^2.4.0" constants-browserify: "npm:^1.0.0" css-loader: "npm:^6.7.1" + es-module-lexer: "npm:^0.9.3" express: "npm:^4.17.3" fork-ts-checker-webpack-plugin: "npm:^8.0.0" fs-extra: "npm:^11.1.0" html-webpack-plugin: "npm:^5.5.0" + magic-string: "npm:^0.30.5" path-browserify: "npm:^1.0.1" pretty-hrtime: "npm:^1.0.3" process: "npm:^0.11.10" @@ -11511,13 +11512,6 @@ __metadata: languageName: node linkType: hard -"babel-plugin-named-exports-order@npm:^0.0.2": - version: 0.0.2 - resolution: "babel-plugin-named-exports-order@npm:0.0.2" - checksum: e1d001722bddabc296b74f7cd020418a3cce9ca7052d5dd5dbd2870745d9566e286d14707c0bbfc9d4b4b643031052b358124ec735069f214d22b0b6768daf9d - languageName: node - linkType: hard - "babel-plugin-polyfill-corejs2@npm:^0.4.4, babel-plugin-polyfill-corejs2@npm:^0.4.5, babel-plugin-polyfill-corejs2@npm:^0.4.6": version: 0.4.6 resolution: "babel-plugin-polyfill-corejs2@npm:0.4.6" @@ -21281,6 +21275,15 @@ __metadata: languageName: node linkType: hard +"magic-string@npm:^0.30.5": + version: 0.30.5 + resolution: "magic-string@npm:0.30.5" + dependencies: + "@jridgewell/sourcemap-codec": "npm:^1.4.15" + checksum: 38ac220ca7539e96da7ea2f38d85796bdf5c69b6bcae728c4bc2565084e6dc326b9174ee9770bea345cf6c9b3a24041b767167874fab5beca874d2356a9d1520 + languageName: node + linkType: hard + "make-dir@npm:^2.0.0, make-dir@npm:^2.1.0": version: 2.1.0 resolution: "make-dir@npm:2.1.0"