Skip to content

Commit

Permalink
Merge pull request #29230 from 43081j/without-express-polka
Browse files Browse the repository at this point in the history
Core: Migrate from `express` to `polka`
  • Loading branch information
JReinhold authored Oct 8, 2024
2 parents 596f270 + 6c3a0bb commit d16f880
Show file tree
Hide file tree
Showing 25 changed files with 291 additions and 243 deletions.
4 changes: 2 additions & 2 deletions code/builders/builder-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,15 @@
"@types/find-cache-dir": "^3.2.1",
"browser-assert": "^1.2.1",
"es-module-lexer": "^1.5.0",
"express": "^4.19.2",
"find-cache-dir": "^3.0.0",
"magic-string": "^0.30.0",
"ts-dedent": "^2.0.0"
},
"devDependencies": {
"@types/express": "^4.17.21",
"@types/node": "^22.0.0",
"glob": "^10.0.0",
"polka": "^1.0.0-next.28",
"sirv": "^2.0.4",
"slash": "^5.0.0",
"typescript": "^5.3.2",
"vite": "^4.0.4"
Expand Down
33 changes: 19 additions & 14 deletions code/builders/builder-vite/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ import { cp, readFile } from 'node:fs/promises';
import { join, parse } from 'node:path';

import { NoStatsForViteDevError } from 'storybook/internal/server-errors';
import type { Options } from 'storybook/internal/types';
import type { Middleware, Options } from 'storybook/internal/types';

import type { RequestHandler } from 'express';
import express from 'express';
import sirv from 'sirv';
import { corePath } from 'storybook/core-path';
import type { ViteDevServer } from 'vite';

Expand All @@ -20,16 +19,18 @@ export { hasVitePlugins } from './utils/has-vite-plugins';

export * from './types';

function iframeMiddleware(options: Options, server: ViteDevServer): RequestHandler {
function iframeMiddleware(options: Options, server: ViteDevServer): Middleware {
return async (req, res, next) => {
if (!req.url.match(/^\/iframe\.html($|\?)/)) {
if (!req.url || !req.url.match(/^\/iframe\.html($|\?)/)) {
next();
return;
}
// the base isn't used for anything, but it's required by the URL constructor
const url = new URL(req.url, 'http://localhost:6006');

// We need to handle `html-proxy` params for style tag HMR https://github.com/storybookjs/builder-vite/issues/266#issuecomment-1055677865
// e.g. /iframe.html?html-proxy&index=0.css
if (req.query['html-proxy'] !== undefined) {
if (url.searchParams.has('html-proxy')) {
next();
return;
}
Expand All @@ -40,7 +41,9 @@ function iframeMiddleware(options: Options, server: ViteDevServer): RequestHandl
const generated = await transformIframeHtml(indexHtml, options);
const transformed = await server.transformIndexHtml('/iframe.html', generated);
res.setHeader('Content-Type', 'text/html');
res.status(200).send(transformed);
res.statusCode = 200;
res.write(transformed);
res.end();
};
}

Expand All @@ -59,10 +62,14 @@ export const start: ViteBuilder['start'] = async ({
server = await createViteServer(options as Options, devServer);

const previewResolvedDir = join(corePath, 'dist/preview');
const previewDirOrigin = previewResolvedDir;

router.use(`/sb-preview`, express.static(previewDirOrigin, { immutable: true, maxAge: '5m' }));

router.use(
'/sb-preview',
sirv(previewResolvedDir, {
maxAge: 300000,
dev: true,
immutable: true,
})
);
router.use(iframeMiddleware(options as Options, server));
router.use(server.middlewares);

Expand All @@ -81,10 +88,8 @@ export const build: ViteBuilder['build'] = async ({ options }) => {
const viteCompilation = viteBuild(options as Options);

const previewResolvedDir = join(corePath, 'dist/preview');
const previewDirOrigin = previewResolvedDir;
const previewDirTarget = join(options.outputDir || '', `sb-preview`);

const previewFiles = cp(previewDirOrigin, previewDirTarget, {
const previewFiles = cp(previewResolvedDir, previewDirTarget, {
filter: (src) => {
const { ext } = parse(src);
if (ext) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export function codeGeneratorPlugin(options: Options): Plugin {
},
config(config, { command }) {
// If we are building the static distribution, add iframe.html as an entry.
// In development mode, it's not an entry - instead, we use an express middleware
// In development mode, it's not an entry - instead, we use a middleware
// to serve iframe.html. The reason is that Vite's dev server (at the time of writing)
// does not support virtual files as entry points.
if (command === 'build') {
Expand Down
2 changes: 1 addition & 1 deletion code/builders/builder-webpack5/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@
"constants-browserify": "^1.0.0",
"css-loader": "^6.7.1",
"es-module-lexer": "^1.5.0",
"express": "^4.19.2",
"fork-ts-checker-webpack-plugin": "^8.0.0",
"html-webpack-plugin": "^5.5.0",
"magic-string": "^0.30.5",
Expand All @@ -95,6 +94,7 @@
"@types/terser-webpack-plugin": "^5.2.0",
"@types/webpack-hot-middleware": "^2.25.6",
"pretty-hrtime": "^1.0.3",
"sirv": "^2.0.4",
"slash": "^5.0.0",
"typescript": "^5.3.2"
},
Expand Down
18 changes: 10 additions & 8 deletions code/builders/builder-webpack5/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import type { Builder, Options } from 'storybook/internal/types';

import { checkWebpackVersion } from '@storybook/core-webpack';

import express from 'express';
import prettyTime from 'pretty-hrtime';
import sirv from 'sirv';
import { corePath } from 'storybook/core-path';
import type { Configuration, Stats, StatsOptions } from 'webpack';
import webpack, { ProgressPlugin } from 'webpack';
Expand Down Expand Up @@ -180,10 +180,14 @@ const starter: StarterFunction = async function* starterGeneratorFn({
compilation = webpackDevMiddleware(compiler, middlewareOptions);

const previewResolvedDir = join(corePath, 'dist/preview');
const previewDirOrigin = previewResolvedDir;

router.use(`/sb-preview`, express.static(previewDirOrigin, { immutable: true, maxAge: '5m' }));

router.use(
'/sb-preview',
sirv(previewResolvedDir, {
maxAge: 300000,
dev: true,
immutable: true,
})
);
router.use(compilation);
router.use(webpackHotMiddleware(compiler, { log: false }));

Expand Down Expand Up @@ -289,10 +293,8 @@ const builder: BuilderFunction = async function* builderGeneratorFn({ startTime,
});

const previewResolvedDir = join(corePath, 'dist/preview');
const previewDirOrigin = previewResolvedDir;
const previewDirTarget = join(options.outputDir || '', `sb-preview`);

const previewFiles = cp(previewDirOrigin, previewDirTarget, {
const previewFiles = cp(previewResolvedDir, previewDirTarget, {
filter: (src) => {
const { ext } = parse(src);
if (ext) {
Expand Down
8 changes: 3 additions & 5 deletions code/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -278,12 +278,10 @@
},
"dependencies": {
"@storybook/csf": "^0.1.11",
"@types/express": "^4.17.21",
"better-opn": "^3.0.2",
"browser-assert": "^1.2.1",
"esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0",
"esbuild-register": "^3.5.0",
"express": "^4.19.2",
"jsdoc-type-pratt-parser": "^4.0.0",
"process": "^0.11.10",
"recast": "^0.23.5",
Expand All @@ -307,6 +305,7 @@
"@emotion/use-insertion-effect-with-fallbacks": "^1.0.1",
"@fal-works/esbuild-plugin-global-externals": "^2.1.2",
"@ndelangen/get-tarball": "^3.0.7",
"@polka/compression": "^1.0.0-next.28",
"@popperjs/core": "^2.6.0",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-scroll-area": "1.2.0-rc.7",
Expand All @@ -316,7 +315,6 @@
"@storybook/icons": "^1.2.10",
"@tanstack/react-virtual": "^3.3.0",
"@testing-library/react": "^14.0.0",
"@types/compression": "^1.7.0",
"@types/cross-spawn": "^6.0.2",
"@types/detect-port": "^1.3.0",
"@types/diff": "^5.0.9",
Expand Down Expand Up @@ -346,7 +344,6 @@
"cli-table3": "^0.6.1",
"commander": "^12.1.0",
"comment-parser": "^1.4.1",
"compression": "^1.7.4",
"copy-to-clipboard": "^3.3.1",
"cross-spawn": "^7.0.3",
"css": "^3.0.0",
Expand All @@ -362,7 +359,6 @@
"esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0",
"esbuild-plugin-alias": "^0.2.1",
"execa": "^8.0.1",
"express": "^4.19.2",
"fd-package-json": "^1.2.0",
"fetch-retry": "^6.0.0",
"find-cache-dir": "^5.0.0",
Expand All @@ -386,6 +382,7 @@
"picomatch": "^2.3.0",
"picoquery": "^1.4.0",
"polished": "^4.2.2",
"polka": "^1.0.0-next.28",
"prettier": "^3.2.5",
"pretty-hrtime": "^1.0.3",
"prompts": "^2.4.0",
Expand All @@ -401,6 +398,7 @@
"react-transition-group": "^4.4.5",
"require-from-string": "^2.0.2",
"resolve-from": "^5.0.0",
"sirv": "^2.0.4",
"slash": "^5.0.0",
"source-map": "^0.7.4",
"store2": "^2.14.2",
Expand Down
36 changes: 27 additions & 9 deletions code/core/src/builder-manager/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { logger } from '@storybook/core/node-logger';
import { globalExternals } from '@fal-works/esbuild-plugin-global-externals';
import { pnpPlugin } from '@yarnpkg/esbuild-plugin-pnp';
import aliasPlugin from 'esbuild-plugin-alias';
import express from 'express';
import sirv from 'sirv';

import type {
BuilderBuildResult,
Expand All @@ -26,6 +26,7 @@ import { wrapManagerEntries } from './utils/managerEntries';
import { safeResolve } from './utils/safeResolve';
import { getTemplatePath, renderHTML } from './utils/template';

const isRootPath = /^\/($|\?)/;
let compilation: Compilation;
let asyncIterator: ReturnType<StarterFunction> | ReturnType<BuilderFunction>;

Expand Down Expand Up @@ -165,8 +166,22 @@ const starter: StarterFunction = async function* starterGeneratorFn({
'manager'
);

router.use(`/sb-addons`, express.static(addonsDir, { immutable: true, maxAge: '5m' }));
router.use(`/sb-manager`, express.static(coreDirOrigin, { immutable: true, maxAge: '5m' }));
router.use(
'/sb-addons',
sirv(addonsDir, {
maxAge: 300000,
dev: true,
immutable: true,
})
);
router.use(
'/sb-manager',
sirv(coreDirOrigin, {
maxAge: 300000,
dev: true,
immutable: true,
})
);

const { cssFiles, jsFiles } = await readOrderedFiles(addonsDir, compilation?.outputFiles);

Expand All @@ -193,15 +208,19 @@ const starter: StarterFunction = async function* starterGeneratorFn({

yield;

router.use(`/`, ({ path }, res, next) => {
if (path === '/') {
res.status(200).send(html);
router.use('/', ({ url }, res, next) => {
if (url && isRootPath.test(url)) {
res.statusCode = 200;
res.write(html);
res.end();
} else {
next();
}
});
router.use(`/index.html`, ({ path }, res) => {
res.status(200).send(html);
router.use(`/index.html`, (req, res) => {
res.statusCode = 200;
res.write(html);
res.end();
});

return {
Expand Down Expand Up @@ -250,7 +269,6 @@ const builder: BuilderFunction = async function* builderGeneratorFn({ startTime,
// TODO: this doesn't watch, we should change this to use the esbuild watch API: https://esbuild.github.io/api/#watch
compilation = await instance({
...config,

minify: true,
});

Expand Down
Loading

0 comments on commit d16f880

Please sign in to comment.