Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 3 additions & 12 deletions code/core/src/common/utils/interpret-files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,9 @@ import { extname } from 'node:path';

import { ResolverFactory } from 'oxc-resolver';

export const supportedExtensions = [
'.js',
'.ts',
'.jsx',
'.tsx',
'.mjs',
'.mts',
'.mtsx',
'.cjs',
'.cts',
'.ctsx',
] as const;
import { storybookConfigExtensions } from '../../shared/constants/extensions.ts';

export const supportedExtensions = storybookConfigExtensions;

export function getInterpretedFile(pathToFile: string) {
return supportedExtensions
Expand Down
3 changes: 2 additions & 1 deletion code/core/src/common/utils/validate-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {

import { resolveModulePath } from 'exsolve';

import { jsModuleExtensions } from '../../shared/constants/extensions.ts';
import { extractFrameworkPackageName } from '../index.ts';
import { frameworkPackages } from './get-storybook-info.ts';

Expand Down Expand Up @@ -36,7 +37,7 @@ export function validateFrameworkName(
// If it's not a known framework, we need to validate that it's a valid package at least
try {
resolveModulePath(`${frameworkName}/preset`, {
extensions: ['.mjs', '.js', '.cjs'],
extensions: [...jsModuleExtensions],
conditions: ['node', 'import', 'require'],
});
} catch (err) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { parseWithOxc } from 'storybook/internal/oxc-parser';

import { jsTsSourceExtensions } from '../../../shared/constants/extensions.ts';
import { mdxParse } from './mdx-parse.ts';
import type { ImportParser } from './types.ts';

/** Default parser for JavaScript/TypeScript source. Uses `oxc-parser` under the hood. */
export const oxcImportParser: ImportParser = {
extensions: ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs'],
extensions: [...jsTsSourceExtensions],
async parse({ filePath, source }) {
return parseWithOxc(filePath, source);
},
Expand Down
21 changes: 3 additions & 18 deletions code/core/src/mocking-utils/resolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,19 @@ import { createRequire } from 'node:module';
import { ResolverFactory } from 'oxc-resolver';
import { dirname, isAbsolute, resolve } from 'pathe';

import { userModuleExtensions } from '../shared/constants/extensions.ts';
import { isModuleDirectory } from './extract.ts';

const require = createRequire(import.meta.url);

/**
* Module file extensions the resolvers in this file know how to handle. Covers the JS/TS family
* plus JSON and common SFC types (`.vue`, `.svelte`).
*/
const moduleExtensions = [
'.js',
'.mjs',
'.cjs',
'.ts',
'.tsx',
'.jsx',
'.json',
'.vue',
'.svelte',
] as const;

/**
* Browser-condition resolver used for `sb.mock()` external module resolution.
*/
const externalResolver = new ResolverFactory({
conditionNames: ['browser', 'import', 'module', 'default'],
mainFields: ['browser', 'module', 'main'],
aliasFields: [['browser']],
extensions: [...moduleExtensions],
extensions: [...userModuleExtensions],
});

/**
Expand Down Expand Up @@ -133,7 +118,7 @@ export function getRealPath(path: string, preserveSymlinks: boolean): string {
* @returns The resolved path
*/
export function resolveWithExtensions(path: string, from: string) {
for (const extension of moduleExtensions) {
for (const extension of userModuleExtensions) {
try {
return require.resolve(path + extension, { paths: [from] });
} catch (e) {
Expand Down
45 changes: 45 additions & 0 deletions code/core/src/shared/constants/extensions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* JS-only module extensions. Used by code that loads runtime JS modules through Node's resolver
* without TypeScript transpilation in scope.
*/
export const jsModuleExtensions = ['.mjs', '.js', '.cjs'] as const;

/**
* JS/TS source file extensions (incl. JSX/TSX). Used by parsers, bundlers, and other tooling that
* understands both languages but not framework single-file-component formats.
*/
export const jsTsSourceExtensions = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs'] as const;

/**
* Storybook config file extensions for `main.{ext}`, `preview.{ext}`, `manager.{ext}`. Covers the
* JS/TS family plus the Node module-system variants (`.mts`, `.cts`, etc.).
*/
export const storybookConfigExtensions = [
'.js',
'.ts',
'.jsx',
'.tsx',
'.mjs',
'.mts',
'.mtsx',
'.cjs',
'.cts',
'.ctsx',
] as const;

/**
* Module file extensions for user-code resolution (e.g. `sb.mock()`). Covers JS/TS plus JSON and
* common single-file-component types (`.vue`, `.svelte`).
*/
export const userModuleExtensions = [
'.astro',
'.js',
'.mjs',
'.cjs',
'.ts',
'.tsx',
'.jsx',
'.json',
'.vue',
'.svelte',
Comment on lines +31 to +44
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks so much for that!

WDYT about my suggestion on the other PR to also add e.g. Solid or Astro? Like Vue and Svelte, these are supported when the relevant framework is used.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has Solid its own file extension and DSL? I'm okay with adding astro for sure!

] as const;
Comment thread
valentinpalkovic marked this conversation as resolved.
4 changes: 3 additions & 1 deletion code/core/src/shared/utils/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
import { resolveModulePath } from 'exsolve';
import { dirname, join } from 'pathe';

import { jsModuleExtensions } from '../constants/extensions.ts';

/**
* This is just an alias for import.meta.resolve. It makes it possible to mock it in Vitest with
* module-mocking, as Vitest currently does not support import.meta.resolve in tests.
Expand Down Expand Up @@ -126,7 +128,7 @@ export async function importModule(
export const safeResolveModule = ({
specifier,
parent,
extensions = ['.mjs', '.js', '.cjs'],
extensions = [...jsModuleExtensions],
}: {
specifier: string;
parent?: string;
Expand Down
Loading