@makcbrain/storybook-builder-esbuild 1.2.2 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +5 -9
- package/dist/utils/createEsbuildContext.d.ts +1 -1
- package/dist/utils/createEsbuildContext.js +2 -2
- package/dist/utils/createStaticServer.d.ts +7 -0
- package/dist/utils/createStaticServer.js +68 -0
- package/dist/utils/getEsbuildConfig.d.ts +1 -1
- package/dist/utils/getEsbuildConfig.js +9 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { clearDistDirectory } from './utils/clearDistDirectory.js';
|
|
2
2
|
import { createEsbuildContext } from './utils/createEsbuildContext.js';
|
|
3
|
+
import { createStaticServer } from './utils/createStaticServer.js';
|
|
3
4
|
import { generateIframeHtml } from './utils/generateIframeHtml.js';
|
|
4
5
|
import { getAbsolutePathToDistDir } from './utils/getAbsolutePathToDistDir.js';
|
|
5
6
|
import { listStories } from './utils/listStories.js';
|
|
@@ -11,16 +12,11 @@ export const start = async (params) => {
|
|
|
11
12
|
const { startTime, options, router } = params;
|
|
12
13
|
await clearDistDirectory(options);
|
|
13
14
|
const stories = await listStories(options);
|
|
14
|
-
|
|
15
|
+
const distDir = getAbsolutePathToDistDir(options);
|
|
16
|
+
const server = await createStaticServer(distDir);
|
|
17
|
+
ctx = await createEsbuildContext(stories, options, server.notifyReload);
|
|
15
18
|
await ctx.watch();
|
|
16
|
-
const
|
|
17
|
-
servedir: getAbsolutePathToDistDir(options),
|
|
18
|
-
port: 0, // Auto-select port
|
|
19
|
-
cors: {
|
|
20
|
-
origin: '*',
|
|
21
|
-
},
|
|
22
|
-
});
|
|
23
|
-
const esbuildServerUrl = `http://localhost:${serveResult.port}`;
|
|
19
|
+
const esbuildServerUrl = server.url;
|
|
24
20
|
console.log(`[ESBuild Builder] Dev server started at ${esbuildServerUrl}`);
|
|
25
21
|
router.get('/iframe.html', async (_req, res) => {
|
|
26
22
|
const html = await generateIframeHtml(options, esbuildServerUrl);
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import * as esbuild from 'esbuild';
|
|
2
2
|
import type { Options } from 'storybook/internal/types';
|
|
3
|
-
export declare const createEsbuildContext: (stories: string[], options: Options) => Promise<esbuild.BuildContext>;
|
|
3
|
+
export declare const createEsbuildContext: (stories: string[], options: Options, onRebuild?: () => void) => Promise<esbuild.BuildContext>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as esbuild from 'esbuild';
|
|
2
2
|
import { getEsbuildConfig } from './getEsbuildConfig.js';
|
|
3
|
-
export const createEsbuildContext = async (stories, options) => {
|
|
4
|
-
const config = await getEsbuildConfig(stories, options);
|
|
3
|
+
export const createEsbuildContext = async (stories, options, onRebuild) => {
|
|
4
|
+
const config = await getEsbuildConfig(stories, options, onRebuild);
|
|
5
5
|
return esbuild.context(config);
|
|
6
6
|
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { createReadStream, existsSync } from 'node:fs';
|
|
2
|
+
import { createServer } from 'node:http';
|
|
3
|
+
import { extname, join } from 'node:path';
|
|
4
|
+
const CONTENT_TYPES = {
|
|
5
|
+
'.js': 'application/javascript',
|
|
6
|
+
'.mjs': 'application/javascript',
|
|
7
|
+
'.css': 'text/css',
|
|
8
|
+
'.json': 'application/json',
|
|
9
|
+
'.map': 'application/json',
|
|
10
|
+
'.html': 'text/html',
|
|
11
|
+
'.svg': 'image/svg+xml',
|
|
12
|
+
'.png': 'image/png',
|
|
13
|
+
'.jpg': 'image/jpeg',
|
|
14
|
+
'.woff': 'font/woff',
|
|
15
|
+
'.woff2': 'font/woff2',
|
|
16
|
+
};
|
|
17
|
+
export const createStaticServer = (servedir) => {
|
|
18
|
+
const sseClients = new Set();
|
|
19
|
+
const handleSSE = (_req, res) => {
|
|
20
|
+
res.writeHead(200, {
|
|
21
|
+
'Content-Type': 'text/event-stream',
|
|
22
|
+
'Cache-Control': 'no-cache',
|
|
23
|
+
Connection: 'keep-alive',
|
|
24
|
+
'Access-Control-Allow-Origin': '*',
|
|
25
|
+
});
|
|
26
|
+
sseClients.add(res);
|
|
27
|
+
res.on('close', () => sseClients.delete(res));
|
|
28
|
+
};
|
|
29
|
+
const handleFile = (req, res) => {
|
|
30
|
+
const url = new URL(req.url || '/', 'http://localhost');
|
|
31
|
+
const filePath = join(servedir, decodeURIComponent(url.pathname));
|
|
32
|
+
if (!existsSync(filePath)) {
|
|
33
|
+
res.writeHead(404, { 'Access-Control-Allow-Origin': '*' });
|
|
34
|
+
res.end('Not found');
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const ext = extname(filePath);
|
|
38
|
+
const contentType = CONTENT_TYPES[ext] || 'application/octet-stream';
|
|
39
|
+
res.writeHead(200, {
|
|
40
|
+
'Content-Type': contentType,
|
|
41
|
+
'Access-Control-Allow-Origin': '*',
|
|
42
|
+
});
|
|
43
|
+
createReadStream(filePath).pipe(res);
|
|
44
|
+
};
|
|
45
|
+
const server = createServer((req, res) => {
|
|
46
|
+
if (req.url === '/esbuild') {
|
|
47
|
+
handleSSE(req, res);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
handleFile(req, res);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
return new Promise((resolve) => {
|
|
54
|
+
server.listen(0, () => {
|
|
55
|
+
const address = server.address();
|
|
56
|
+
const port = typeof address === 'object' && address ? address.port : 0;
|
|
57
|
+
resolve({
|
|
58
|
+
url: `http://localhost:${port}`,
|
|
59
|
+
notifyReload: () => {
|
|
60
|
+
for (const client of sseClients) {
|
|
61
|
+
client.write('event: change\ndata: {}\n\n');
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
close: () => new Promise((res) => server.close(() => res())),
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { BuildOptions } from 'esbuild';
|
|
2
2
|
import type { Options } from 'storybook/internal/types';
|
|
3
|
-
export declare const getEsbuildConfig: (stories: string[], options: Options) => Promise<BuildOptions>;
|
|
3
|
+
export declare const getEsbuildConfig: (stories: string[], options: Options, onRebuild?: () => void) => Promise<BuildOptions>;
|
|
@@ -11,7 +11,7 @@ const stringifyEnvs = (envs) => {
|
|
|
11
11
|
return acc;
|
|
12
12
|
}, {});
|
|
13
13
|
};
|
|
14
|
-
export const getEsbuildConfig = async (stories, options) => {
|
|
14
|
+
export const getEsbuildConfig = async (stories, options, onRebuild) => {
|
|
15
15
|
const { presets } = options;
|
|
16
16
|
const envs = await presets.apply('env');
|
|
17
17
|
const framework = await presets.apply('framework');
|
|
@@ -60,6 +60,14 @@ export const getEsbuildConfig = async (stories, options) => {
|
|
|
60
60
|
reactDocGenPlugin(),
|
|
61
61
|
getMdxPlugin({ jsx: true }),
|
|
62
62
|
...(userEsbuildConfig.plugins || []),
|
|
63
|
+
...(onRebuild
|
|
64
|
+
? [
|
|
65
|
+
{
|
|
66
|
+
name: 'rebuild-notify',
|
|
67
|
+
setup: (build) => build.onEnd(onRebuild),
|
|
68
|
+
},
|
|
69
|
+
]
|
|
70
|
+
: []),
|
|
63
71
|
],
|
|
64
72
|
};
|
|
65
73
|
return presets.apply('esbuildFinal', config, options);
|