diff --git a/MIGRATION.md b/MIGRATION.md index b96bee548d09..e75f6916a032 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -28,6 +28,7 @@ - [Deploying build artifacts](#deploying-build-artifacts) - [Dropped support for file URLs](#dropped-support-for-file-urls) - [Serving with nginx](#serving-with-nginx) + - [Ignore story files from node\_modules](#ignore-story-files-from-node_modules) - [7.0 Core changes](#70-core-changes) - [7.0 feature flags removed](#70-feature-flags-removed) - [Story context is prepared before for supporting fine grained updates](#story-context-is-prepared-before-for-supporting-fine-grained-updates) @@ -937,6 +938,28 @@ With [nginx](https://www.nginx.com/), you need to extend [the MIME type handling It would otherwise default to serving the `.mjs` files as `application/octet-stream`. +##### Ignore story files from node_modules + +In 6.x Storybook literally followed the glob patterns specified in your `.storybook/main.js` `stories` field. Storybook 7.0 ignores files from `node_modules` unless your glob pattern includes the string `"node_modules"`. + +Given the following `main.js`: + +```js +export default { + stories: ['../**/*.stories.*'] +} +``` + +If you want to restore the previous behavior to include `node_modules`, you can update it to: + +```js +export default { + stories: ['../**/*.stories.*', '../**/node_modules/**/*.stories.*'] +} +``` + +The first glob would have node_modules automatically excluded by Storybook, and the second glob would include all stories that are under a nested `node_modules` directory. + ### 7.0 Core changes #### 7.0 feature flags removed diff --git a/code/lib/builder-vite/src/list-stories.ts b/code/lib/builder-vite/src/list-stories.ts index f3702e4cf826..c51ad5af2c3c 100644 --- a/code/lib/builder-vite/src/list-stories.ts +++ b/code/lib/builder-vite/src/list-stories.ts @@ -1,7 +1,7 @@ import * as path from 'path'; import slash from 'slash'; import { promise as glob } from 'glob-promise'; -import { normalizeStories } from '@storybook/core-common'; +import { normalizeStories, commonGlobOptions } from '@storybook/core-common'; import type { Options } from '@storybook/types'; @@ -17,7 +17,10 @@ export async function listStories(options: Options) { ? pattern : path.join(options.configDir, pattern); - return glob(slash(absolutePattern), { follow: true }); + return glob(slash(absolutePattern), { + ...commonGlobOptions(absolutePattern), + follow: true, + }); }) ) ).reduce((carry, stories) => carry.concat(stories), []); diff --git a/code/lib/cli/src/automigrate/fixes/mdx-gfm.ts b/code/lib/cli/src/automigrate/fixes/mdx-gfm.ts index 7989b5c1517a..b8c215feef06 100644 --- a/code/lib/cli/src/automigrate/fixes/mdx-gfm.ts +++ b/code/lib/cli/src/automigrate/fixes/mdx-gfm.ts @@ -3,6 +3,7 @@ import semver from 'semver'; import { join } from 'path'; import slash from 'slash'; import glob from 'globby'; +import { commonGlobOptions } from '@storybook/core-common'; import { getStorybookData, updateMainConfig } from '../helpers/mainConfigFile'; import type { Fix } from '../types'; import { getStorybookVersionSpecifier } from '../../helpers'; @@ -37,7 +38,7 @@ export const mdxgfm: Fix = { ? slash(join(configDir, item)) : slash(join(configDir, item.directory, item.files)); - const files = await glob(pattern); + const files = await glob(pattern, commonGlobOptions(pattern)); return files.some((f) => f.endsWith('.mdx')); }, Promise.resolve(false)); diff --git a/code/lib/core-common/src/index.ts b/code/lib/core-common/src/index.ts index 726812b67bb3..7296dc814a2c 100644 --- a/code/lib/core-common/src/index.ts +++ b/code/lib/core-common/src/index.ts @@ -6,6 +6,7 @@ export * from './utils/cache'; export * from './utils/check-addon-order'; export * from './utils/envs'; export * from './utils/findDistEsm'; +export * from './utils/common-glob-options'; export * from './utils/get-builder-options'; export * from './utils/get-framework-name'; export * from './utils/get-renderer-name'; diff --git a/code/lib/core-common/src/utils/common-glob-options.ts b/code/lib/core-common/src/utils/common-glob-options.ts new file mode 100644 index 000000000000..482ed8630674 --- /dev/null +++ b/code/lib/core-common/src/utils/common-glob-options.ts @@ -0,0 +1,5 @@ +const NODE_MODULES_RE = /node_modules/; + +// Exclude node_modules stories everywhere we call `glob` +export const commonGlobOptions = (glob: string) => + NODE_MODULES_RE.test(glob) ? {} : { ignore: ['**/node_modules/**'] }; diff --git a/code/lib/core-server/src/utils/StoryIndexGenerator.ts b/code/lib/core-server/src/utils/StoryIndexGenerator.ts index 7043c39bc991..c6e166bd6eb5 100644 --- a/code/lib/core-server/src/utils/StoryIndexGenerator.ts +++ b/code/lib/core-server/src/utils/StoryIndexGenerator.ts @@ -20,7 +20,7 @@ import type { StoryName, } from '@storybook/types'; import { userOrAutoTitleFromSpecifier, sortStoriesV7 } from '@storybook/preview-api'; -import { normalizeStoryPath } from '@storybook/core-common'; +import { commonGlobOptions, normalizeStoryPath } from '@storybook/core-common'; import { logger, once } from '@storybook/node-logger'; import { getStorySortParameter } from '@storybook/csf-tools'; import { toId } from '@storybook/csf'; @@ -121,7 +121,7 @@ export class StoryIndexGenerator { const fullGlob = slash( path.join(this.options.workingDir, specifier.directory, specifier.files) ); - const files = await glob(fullGlob); + const files = await glob(fullGlob, commonGlobOptions(fullGlob)); if (files.length === 0) { once.warn( diff --git a/code/lib/core-server/src/utils/watch-story-specifiers.ts b/code/lib/core-server/src/utils/watch-story-specifiers.ts index f7946940ed55..a0d1818be720 100644 --- a/code/lib/core-server/src/utils/watch-story-specifiers.ts +++ b/code/lib/core-server/src/utils/watch-story-specifiers.ts @@ -6,6 +6,7 @@ import glob from 'globby'; import uniq from 'lodash/uniq.js'; import type { NormalizedStoriesSpecifier, Path } from '@storybook/types'; +import { commonGlobOptions } from '@storybook/core-common'; const isDirectory = (directory: Path) => { try { @@ -74,7 +75,7 @@ export function watchStorySpecifiers( path.basename(specifier.files) ); // glob only supports forward slashes - const files = await glob(slash(dirGlob)); + const files = await glob(slash(dirGlob), commonGlobOptions(dirGlob)); files.forEach((filePath) => { const fileImportPath = toImportPath(