react-cosmos-plugin-vite 6.2.4-canary.fa66419.0 → 7.0.0-beta.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.
@@ -1,7 +1,7 @@
1
1
  import { CosmosConfig } from 'react-cosmos';
2
2
  export type CosmosViteConfig = {
3
3
  configPath: string | false;
4
- indexPath: string | null;
4
+ mainScriptUrl: string | null;
5
5
  port: number;
6
6
  };
7
7
  type CosmosViteConfigInput = Partial<CosmosViteConfig>;
@@ -1,5 +1,5 @@
1
1
  import path from 'node:path';
2
- import { fileExists, resolveFromSilent, resolveLoose, } from 'react-cosmos';
2
+ import { fileExists, resolveFromSilent } from 'react-cosmos';
3
3
  export function createCosmosViteConfig(config) {
4
4
  const { rootDir } = config;
5
5
  const configInput = config.vite || {};
@@ -7,9 +7,7 @@ export function createCosmosViteConfig(config) {
7
7
  logViteConfigInfo(configPath);
8
8
  return {
9
9
  configPath,
10
- indexPath: configInput.indexPath
11
- ? resolveLoose(rootDir, configInput.indexPath)
12
- : null,
10
+ mainScriptUrl: configInput.mainScriptUrl ?? null,
13
11
  port: getCosmosVitePort(configInput),
14
12
  };
15
13
  }
@@ -28,7 +26,7 @@ function getViteConfigPath({ configPath }, rootDir) {
28
26
  resolveFromSilent(rootDir, './vite.config.js') ||
29
27
  false);
30
28
  }
31
- const absPath = resolveLoose(rootDir, configPath);
29
+ const absPath = path.join(rootDir, configPath);
32
30
  if (!fileExists(absPath)) {
33
31
  const relPath = path.relative(process.cwd(), absPath);
34
32
  throw new Error(`Vite config not found at path: ${relPath}`);
@@ -38,9 +36,9 @@ function getViteConfigPath({ configPath }, rootDir) {
38
36
  function logViteConfigInfo(viteConfigPath) {
39
37
  if (viteConfigPath) {
40
38
  const relPath = path.relative(process.cwd(), viteConfigPath);
41
- console.log(`[Cosmos] Using vite config found at ${relPath}`);
39
+ console.log(`[Cosmos] Using Vite config found at ${relPath}`);
42
40
  }
43
41
  else {
44
- console.log(`[Cosmos] No vite config found, using default settings`);
42
+ console.log(`[Cosmos] No Vite config found, using default settings`);
45
43
  }
46
44
  }
@@ -0,0 +1 @@
1
+ export declare function createIndexHtml(htmlPath: string): string;
@@ -0,0 +1,22 @@
1
+ import fs from 'node:fs';
2
+ import { defaultMainScriptUrl } from './defaultMainScriptUrl.js';
3
+ export function createIndexHtml(htmlPath) {
4
+ console.log(`[Cosmos] Vite index.html not found, creating a default one...`);
5
+ const html = generateViteIndexHtml();
6
+ fs.writeFileSync(htmlPath, html);
7
+ return html;
8
+ }
9
+ function generateViteIndexHtml() {
10
+ return `<!DOCTYPE html>
11
+ <html lang="en">
12
+ <head>
13
+ <meta charset="utf-8" />
14
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
15
+ <title>React Cosmos Vite Renderer</title>
16
+ </head>
17
+ <body>
18
+ <div id="root"></div>
19
+ <script type="module" src="${defaultMainScriptUrl()}"></script>
20
+ </body>
21
+ </html>\n`;
22
+ }
@@ -0,0 +1 @@
1
+ export declare function defaultMainScriptUrl(): string;
@@ -0,0 +1,5 @@
1
+ import { moduleExists } from 'react-cosmos';
2
+ export function defaultMainScriptUrl() {
3
+ const ext = moduleExists('typescript') ? 'tsx' : 'jsx';
4
+ return `/src/main.${ext}`;
5
+ }
@@ -0,0 +1 @@
1
+ export declare function ensureMainScriptUrl(html: string): string;
@@ -0,0 +1,9 @@
1
+ import { defaultMainScriptUrl } from './defaultMainScriptUrl.js';
2
+ import { getHtmlScriptUrls } from './getHtmlScriptUrls.js';
3
+ export function ensureMainScriptUrl(html) {
4
+ const scripts = getHtmlScriptUrls(html);
5
+ if (scripts.length === 0) {
6
+ html = html.replace(/(\s+)?<\/body>/, `$1 <script type="module" src="${defaultMainScriptUrl()}"></script>$1</body>`);
7
+ }
8
+ return html;
9
+ }
@@ -0,0 +1 @@
1
+ export declare function findMainScriptUrl(html: string, mainScriptUrl?: string | null): string;
@@ -0,0 +1,49 @@
1
+ import { defaultMainScriptUrl } from './defaultMainScriptUrl.js';
2
+ import { getHtmlScriptUrls } from './getHtmlScriptUrls.js';
3
+ const mainUrlPattern = new RegExp(`/(src/)?(index|main)\\.(js|ts)x?$`);
4
+ export function findMainScriptUrl(html, mainScriptUrl = null) {
5
+ const scripts = getHtmlScriptUrls(html).map(normalizeUrl);
6
+ if (mainScriptUrl !== null) {
7
+ const mainUrl = scripts.find(url => url === normalizeUrl(mainScriptUrl));
8
+ if (mainUrl)
9
+ return mainUrl;
10
+ throw new Error(`Script URL "${mainScriptUrl}" not found in index.html. ` +
11
+ `Add it or change vite.mainScriptUrl in your Cosmos config.`);
12
+ }
13
+ // NOTE: This assumes the html will also be transformed to include a script
14
+ // tag with the default main script URL.
15
+ if (scripts.length === 0)
16
+ return defaultMainScriptUrl();
17
+ if (scripts.length === 1)
18
+ return scripts[0];
19
+ const mainUrl = guessMainScriptUrl(scripts);
20
+ if (mainUrl)
21
+ return mainUrl;
22
+ throw new Error(`Multiple script paths found in index.html. ` +
23
+ `Please set vite.mainScriptUrl in your Cosmos config: ` +
24
+ `https://reactcosmos.org/docs/getting-started/vite#configuration`);
25
+ }
26
+ function normalizeUrl(url) {
27
+ // "src/main.tsx" => "/src/main.tsx"
28
+ // "./src/main.tsx" => "/src/main.tsx"
29
+ // "../src/main.tsx" => "/src/main.tsx"
30
+ return `/${url
31
+ .split('/')
32
+ .filter(p => !['', '.', '..'].includes(p))
33
+ .join('/')}`;
34
+ }
35
+ function guessMainScriptUrl(urls) {
36
+ // Find main script URL from multiple script tags based on common patterns
37
+ // and pick the longest match when multiple matches are found.
38
+ // Eg. Between "/src/main.tsx" and "/foo/main.tsx", pick "/src/index.tsx"
39
+ let bestUrl = null;
40
+ let bestUrlLength = 0;
41
+ for (const url of urls) {
42
+ const match = url.match(mainUrlPattern);
43
+ if (match && match[0].length > bestUrlLength) {
44
+ bestUrl = url;
45
+ bestUrlLength = match[0].length;
46
+ }
47
+ }
48
+ return bestUrl;
49
+ }
@@ -0,0 +1 @@
1
+ export declare function getHtmlScriptUrls(html: string): string[];
@@ -0,0 +1,16 @@
1
+ import * as parse5 from 'parse5';
2
+ export function getHtmlScriptUrls(html) {
3
+ const document = parse5.parse(html);
4
+ const urls = [];
5
+ function walk(node) {
6
+ if ('tagName' in node && node.tagName === 'script') {
7
+ const srcAttr = node.attrs.find(attr => attr.name === 'src');
8
+ if (srcAttr)
9
+ urls.push(srcAttr.value);
10
+ }
11
+ if ('childNodes' in node)
12
+ node.childNodes.forEach(walk);
13
+ }
14
+ walk(document);
15
+ return urls.filter(url => !url.startsWith('/@vite'));
16
+ }
@@ -1,7 +1,8 @@
1
1
  import { CosmosConfig } from 'react-cosmos';
2
2
  import { CosmosMode } from 'react-cosmos-core';
3
- import { Plugin } from 'rollup';
3
+ import { Plugin } from 'vite';
4
4
  import { CosmosViteConfig } from './createCosmosViteConfig.js';
5
+ export declare const rendererResolvedModuleId: string;
5
6
  export declare const userImportsVirtualModuleId = "virtual:cosmos-imports";
6
7
  export declare const userImportsResolvedModuleId: string;
7
8
  export declare function reactCosmosViteRollupPlugin(config: CosmosConfig, cosmosViteConfig: CosmosViteConfig, mode: CosmosMode): Plugin;
@@ -1,61 +1,67 @@
1
+ import fs from 'node:fs';
1
2
  import path from 'node:path';
2
- import { findUserModulePaths, generateUserImports, getWebSocketUrl, slash, } from 'react-cosmos';
3
+ import { findUserModulePaths, generateUserImports, getWebSocketUrl, } from 'react-cosmos';
3
4
  import { createViteRendererIndex } from './createViteRendererIndex.js';
5
+ import { createIndexHtml } from './indexHtml/createIndexHtml.js';
6
+ import { ensureMainScriptUrl } from './indexHtml/ensureMainScriptUrl.js';
7
+ import { findMainScriptUrl } from './indexHtml/findMainScriptUrl.js';
8
+ export const rendererResolvedModuleId = '\0' + 'virtual:cosmos-renderer';
4
9
  export const userImportsVirtualModuleId = 'virtual:cosmos-imports';
5
10
  export const userImportsResolvedModuleId = '\0' + userImportsVirtualModuleId;
6
- const defaultIndexPattern = new RegExp(`^(src\\${path.sep})?(index|main)\.(js|ts)x?$`);
7
11
  export function reactCosmosViteRollupPlugin(config, cosmosViteConfig, mode) {
12
+ let mainScriptUrl;
8
13
  return {
9
14
  name: 'react-cosmos-vite-renderer',
15
+ enforce: 'pre',
16
+ async buildStart() {
17
+ const htmlPath = path.resolve(config.rootDir, 'index.html');
18
+ // Other plugins might intercept <root>/index.html and resolve it to
19
+ // a different path. We need to respect that and avoid generating a new
20
+ // index.html in the root if it already exists.
21
+ const resolved = await this.resolve(htmlPath);
22
+ const html = resolved
23
+ ? fs.readFileSync(resolved.id, 'utf-8')
24
+ : createIndexHtml(htmlPath);
25
+ mainScriptUrl = findMainScriptUrl(html, cosmosViteConfig.mainScriptUrl);
26
+ },
27
+ transformIndexHtml(html) {
28
+ // Redetect the main script URL when index.html changes
29
+ mainScriptUrl = findMainScriptUrl(html, cosmosViteConfig.mainScriptUrl);
30
+ return ensureMainScriptUrl(html);
31
+ },
10
32
  resolveId(id) {
11
- if (id === userImportsVirtualModuleId) {
12
- return userImportsResolvedModuleId;
13
- }
14
- else {
15
- return null;
33
+ switch (id) {
34
+ case mainScriptUrl:
35
+ return rendererResolvedModuleId;
36
+ case userImportsVirtualModuleId:
37
+ return userImportsResolvedModuleId;
38
+ default:
39
+ return null;
16
40
  }
17
41
  },
18
42
  async load(id) {
19
- if (id == userImportsResolvedModuleId) {
20
- const modulePaths = await findUserModulePaths(config);
21
- return generateUserImports({
22
- config,
23
- modulePaths,
24
- rendererConfig: {
25
- webSocketUrl: mode === 'dev' ? getWebSocketUrl(config) : null,
26
- rendererUrl: null,
27
- containerQuerySelector: config.dom.containerQuerySelector,
28
- },
29
- relativeToDir: null,
30
- typeScript: false,
31
- });
32
- }
33
- else {
34
- return null;
35
- }
36
- },
37
- transform(src, id) {
38
- const absPath = cosmosViteConfig.indexPath &&
39
- absoluteIndexPath(cosmosViteConfig.indexPath, config.rootDir);
40
- const isRendererIndex = absPath
41
- ? absPath === id
42
- : path.relative(config.rootDir, id).match(defaultIndexPattern);
43
- if (isRendererIndex) {
44
- const relPath = path.relative(process.cwd(), id);
45
- console.log(`[Cosmos] Replacing vite index module at ${relPath}`);
46
- return {
47
- code: createViteRendererIndex(userImportsVirtualModuleId),
48
- map: null,
49
- };
50
- }
51
- else {
52
- return null;
43
+ switch (id) {
44
+ case rendererResolvedModuleId: {
45
+ console.log(`[Cosmos] Loading Cosmos renderer at ${mainScriptUrl}`);
46
+ return createViteRendererIndex(userImportsVirtualModuleId);
47
+ }
48
+ case userImportsResolvedModuleId: {
49
+ const modulePaths = await findUserModulePaths(config);
50
+ return generateUserImports({
51
+ config,
52
+ modulePaths,
53
+ rendererConfig: {
54
+ webSocketUrl: mode === 'dev' ? getWebSocketUrl(config) : null,
55
+ rendererUrl: null,
56
+ containerQuerySelector: config.dom.containerQuerySelector,
57
+ },
58
+ relativeToDir: null,
59
+ typeScript: false,
60
+ });
61
+ }
62
+ default:
63
+ return null;
53
64
  }
54
65
  },
55
66
  };
56
67
  }
57
- function absoluteIndexPath(indexPath, rootDir) {
58
- return indexPath.startsWith(rootDir)
59
- ? indexPath
60
- : slash(path.join(rootDir, indexPath));
61
- }
@@ -1 +1 @@
1
- {"root":["../src/constants.ts","../src/createCosmosViteConfig.ts","../src/createViteRendererIndex.ts","../src/dom.ts","../src/reactCosmosViteRollupPlugin.ts","../src/viteConfigPlugin.ts","../src/viteDevServerPlugin.ts","../src/viteExportPlugin.ts","../src/viteServerPlugin.ts"],"version":"5.7.3"}
1
+ {"root":["../src/constants.ts","../src/createcosmosviteconfig.ts","../src/createviterendererindex.ts","../src/dom.ts","../src/reactcosmosviterollupplugin.ts","../src/viteconfigplugin.ts","../src/vitedevserverplugin.ts","../src/viteexportplugin.ts","../src/viteserverplugin.ts","../src/indexhtml/createindexhtml.ts","../src/indexhtml/defaultmainscripturl.ts","../src/indexhtml/ensuremainscripturl.ts","../src/indexhtml/findmainscripturl.ts","../src/indexhtml/gethtmlscripturls.ts"],"version":"5.8.3"}
@@ -6,10 +6,10 @@ import { createCosmosViteConfig } from './createCosmosViteConfig.js';
6
6
  import { reactCosmosViteRollupPlugin } from './reactCosmosViteRollupPlugin.js';
7
7
  export async function viteExportPlugin({ config }) {
8
8
  const { rootDir, exportPath, publicUrl } = config;
9
- const viteConfig = createCosmosViteConfig(config);
9
+ const cosmosViteConfig = createCosmosViteConfig(config);
10
10
  const outDir = path.join(exportPath, publicUrl);
11
11
  await build({
12
- configFile: viteConfig.configPath,
12
+ configFile: cosmosViteConfig.configPath,
13
13
  root: rootDir,
14
14
  base: publicUrl,
15
15
  build: {
@@ -17,7 +17,7 @@ export async function viteExportPlugin({ config }) {
17
17
  emptyOutDir: false,
18
18
  minify: false,
19
19
  },
20
- plugins: [reactCosmosViteRollupPlugin(config, viteConfig, 'export')],
20
+ plugins: [reactCosmosViteRollupPlugin(config, cosmosViteConfig, 'export')],
21
21
  });
22
22
  await rename(path.join(outDir, 'index.html'), path.join(outDir, RENDERER_FILENAME));
23
23
  }
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "react-cosmos-plugin-vite",
3
- "version": "6.2.4-canary.fa66419.0+fa66419",
3
+ "version": "7.0.0-beta.0",
4
4
  "description": "Vite plugin for React Cosmos",
5
5
  "repository": "https://github.com/react-cosmos/react-cosmos/tree/main/packages/react-cosmos-plugin-vite",
6
6
  "license": "MIT",
7
7
  "type": "module",
8
8
  "main": "cosmos.plugin.json",
9
9
  "dependencies": {
10
- "react-cosmos-core": "6.2.4-canary.fa66419.0+fa66419",
11
- "react-cosmos-dom": "6.2.4-canary.fa66419.0+fa66419"
10
+ "react-cosmos-core": "7.0.0-beta.0",
11
+ "react-cosmos-dom": "7.0.0-beta.0"
12
12
  },
13
13
  "peerDependencies": {
14
14
  "vite": "*"
15
15
  },
16
- "gitHead": "fa66419918274f7fac6da86521f44cf097eb17b9"
16
+ "gitHead": "c01fecbf8b3342846f24d5860bf2d5146801ae3e"
17
17
  }