Skip to content

Commit

Permalink
Merge pull request #25264 from storybookjs/norbert/no-conflicting-cac…
Browse files Browse the repository at this point in the history
…he-dir-in-builders

Core: Unique outputDir/cacheDir for each configDir
  • Loading branch information
ndelangen authored Dec 21, 2023
2 parents c92a672 + 977570c commit aa37ebd
Show file tree
Hide file tree
Showing 10 changed files with 62 additions and 38 deletions.
2 changes: 0 additions & 2 deletions code/builders/builder-manager/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,12 @@
"@storybook/manager": "workspace:*",
"@storybook/node-logger": "workspace:*",
"@types/ejs": "^3.1.1",
"@types/find-cache-dir": "^3.2.1",
"@yarnpkg/esbuild-plugin-pnp": "^3.0.0-rc.10",
"browser-assert": "^1.2.1",
"ejs": "^3.1.8",
"esbuild": "^0.18.0",
"esbuild-plugin-alias": "^0.2.1",
"express": "^4.17.3",
"find-cache-dir": "^3.0.0",
"fs-extra": "^11.1.0",
"process": "^0.11.10",
"util": "^0.12.4"
Expand Down
4 changes: 1 addition & 3 deletions code/builders/builder-manager/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,8 @@ export const getConfig: ManagerBuilder['getConfig'] = async (options) => {
? [...addonsEntryPoints, customManagerEntryPoint]
: addonsEntryPoints;

const realEntryPoints = await wrapManagerEntries(entryPoints);

return {
entryPoints: realEntryPoints,
entryPoints: await wrapManagerEntries(entryPoints, options.cacheKey),
outdir: join(options.outputDir || './', 'sb-addons'),
format: 'iife',
write: false,
Expand Down
6 changes: 3 additions & 3 deletions code/builders/builder-manager/src/utils/managerEntries.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import findCacheDirectory from 'find-cache-dir';
import fs from 'fs-extra';
import { resolvePathInStorybookCache } from '@storybook/core-common';
import { join, parse, relative, sep } from 'node:path';
import slash from 'slash';

Expand Down Expand Up @@ -34,11 +34,11 @@ const sanitizeFinal = (path: string) => {
*
* We need to wrap each managerEntry with a try-catch because if we do not, a failing managerEntry can stop execution of other managerEntries.
*/
export async function wrapManagerEntries(entrypoints: string[]) {
export async function wrapManagerEntries(entrypoints: string[], uniqueId?: string) {
return Promise.all(
entrypoints.map(async (entry, i) => {
const { name, dir } = parse(entry);
const cacheLocation = findCacheDirectory({ name: 'sb-manager' });
const cacheLocation = resolvePathInStorybookCache('sb-manager', uniqueId);

if (!cacheLocation) {
throw new Error('Could not create/find cache directory');
Expand Down
10 changes: 7 additions & 3 deletions code/builders/builder-vite/src/vite-config.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import * as path from 'path';
import findCacheDirectory from 'find-cache-dir';
import type {
ConfigEnv,
InlineConfig as ViteInlineConfig,
PluginOption,
UserConfig as ViteConfig,
InlineConfig,
} from 'vite';
import { isPreservingSymlinks, getFrameworkName, getBuilderOptions } from '@storybook/core-common';
import {
isPreservingSymlinks,
getFrameworkName,
getBuilderOptions,
resolvePathInStorybookCache,
} from '@storybook/core-common';
import { globalsNameReferenceMap } from '@storybook/preview/globals';
import type { Options } from '@storybook/types';
import {
Expand Down Expand Up @@ -54,7 +58,7 @@ export async function commonConfig(

const sbConfig: InlineConfig = {
configFile: false,
cacheDir: findCacheDirectory({ name: 'sb-vite' }),
cacheDir: resolvePathInStorybookCache('sb-vite', options.cacheKey),
root: projectRoot,
// Allow storybook deployed as subfolder. See https://github.com/storybookjs/builder-vite/issues/238
base: './',
Expand Down
6 changes: 3 additions & 3 deletions code/lib/core-common/src/utils/resolve-path-in-sb-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import findCacheDirectory from 'find-cache-dir';
* @param fileOrDirectoryName {string} Name of the file or directory
* @return {string} Absolute path to the file or directory
*/
export function resolvePathInStorybookCache(fileOrDirectoryName: string): string {
export function resolvePathInStorybookCache(fileOrDirectoryName: string, sub = 'default'): string {
let cacheDirectory = findCacheDirectory({ name: 'storybook' });
cacheDirectory ||= path.join(process.cwd(), '.cache/storybook');
cacheDirectory ||= path.join(process.cwd(), '.cache', 'storybook');

return path.join(cacheDirectory, fileOrDirectoryName);
return path.join(cacheDirectory, sub, fileOrDirectoryName);
}
26 changes: 19 additions & 7 deletions code/lib/core-server/src/build-dev.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { BuilderOptions, CLIOptions, LoadOptions, Options } from '@storybook/types';
import {
getProjectRoot,
loadAllPresets,
loadMainConfig,
resolveAddonName,
Expand All @@ -10,9 +11,9 @@ import {
import prompts from 'prompts';
import invariant from 'tiny-invariant';
import { global } from '@storybook/global';
import { telemetry } from '@storybook/telemetry';
import { telemetry, oneWayHash } from '@storybook/telemetry';

import { join, resolve } from 'path';
import { join, relative, resolve } from 'path';
import { deprecate } from '@storybook/node-logger';
import dedent from 'ts-dedent';
import { readFile } from 'fs-extra';
Expand Down Expand Up @@ -49,17 +50,28 @@ export async function buildDevStandalone(
name: 'shouldChangePort',
message: `Port ${options.port} is not available. Would you like to run Storybook on port ${port} instead?`,
});
if (!shouldChangePort) process.exit(1);
if (!shouldChangePort) {
process.exit(1);
}
}

const rootDir = getProjectRoot();
const configDir = resolve(options.configDir);
const cacheKey = oneWayHash(relative(rootDir, configDir));

const cacheOutputDir = resolvePathInStorybookCache('public', cacheKey);
let outputDir = resolve(options.outputDir || cacheOutputDir);
if (options.smokeTest) {
outputDir = cacheOutputDir;
}

/* eslint-disable no-param-reassign */
options.port = port;
options.versionCheck = versionCheck;
options.configType = 'DEVELOPMENT';
options.configDir = resolve(options.configDir);
options.outputDir = options.smokeTest
? resolvePathInStorybookCache('public')
: resolve(options.outputDir || resolvePathInStorybookCache('public'));
options.configDir = configDir;
options.cacheKey = cacheKey;
options.outputDir = outputDir;
options.serverChannelUrl = getServerChannelUrl(port, options);
/* eslint-enable no-param-reassign */

Expand Down
8 changes: 3 additions & 5 deletions code/lib/core-server/src/build-static.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import chalk from 'chalk';
import { copy, emptyDir, ensureDir } from 'fs-extra';
import { dirname, isAbsolute, join, resolve } from 'path';
import { dirname, join, relative, resolve } from 'path';
import { global } from '@storybook/global';
import { deprecate, logger } from '@storybook/node-logger';
import { getPrecedingUpgrade, telemetry } from '@storybook/telemetry';
Expand Down Expand Up @@ -35,13 +35,11 @@ export async function buildStaticStandalone(options: BuildStaticStandaloneOption
throw new Error("Won't remove current directory. Check your outputDir!");
}

options.outputDir = isAbsolute(options.outputDir)
? options.outputDir
: join(process.cwd(), options.outputDir);
options.outputDir = resolve(options.outputDir);
options.configDir = resolve(options.configDir);
/* eslint-enable no-param-reassign */

logger.info(chalk`=> Cleaning outputDir: {cyan ${options.outputDir.replace(process.cwd(), '')}}`);
logger.info(chalk`=> Cleaning outputDir: {cyan ${relative(process.cwd(), options.outputDir)}}`);
if (options.outputDir === '/') {
throw new Error("Won't remove directory '/'. Check your outputDir!");
}
Expand Down
29 changes: 22 additions & 7 deletions code/lib/core-server/src/utils/copy-all-static-files.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import chalk from 'chalk';
import fs from 'fs-extra';
import path from 'path';
import { join, relative } from 'path';
import { logger } from '@storybook/node-logger';
import { getDirectoryFromWorkingDir } from '@storybook/core-common';
import { parseStaticDir } from './server-statics';
Expand All @@ -11,11 +11,19 @@ export async function copyAllStaticFiles(staticDirs: any[] | undefined, outputDi
staticDirs.map(async (dir) => {
try {
const { staticDir, staticPath, targetDir } = await parseStaticDir(dir);
const targetPath = path.join(outputDir, targetDir);
logger.info(chalk`=> Copying static files: {cyan ${staticDir}} => {cyan ${targetDir}}`);
const targetPath = join(outputDir, targetDir);

// we copy prebuild static files from node_modules/@storybook/manager & preview
if (!staticDir.includes('node_modules')) {
logger.info(
chalk`=> Copying static files: {cyan ${print(staticDir)}} => {cyan ${print(
targetDir
)}}`
);
}

// Storybook's own files should not be overwritten, so we skip such files if we find them
const skipPaths = ['index.html', 'iframe.html'].map((f) => path.join(targetPath, f));
const skipPaths = ['index.html', 'iframe.html'].map((f) => join(targetPath, f));
await fs.copy(staticPath, targetPath, {
dereference: true,
preserveTimestamps: true,
Expand Down Expand Up @@ -49,13 +57,20 @@ export async function copyAllStaticFilesRelativeToMain(
})
);

const targetPath = path.join(outputDir, to);
const skipPaths = ['index.html', 'iframe.html'].map((f) => path.join(targetPath, f));
logger.info(chalk`=> Copying static files: {cyan ${from}} at {cyan ${targetPath}}`);
const targetPath = join(outputDir, to);
const skipPaths = ['index.html', 'iframe.html'].map((f) => join(targetPath, f));
if (!from.includes('node_modules')) {
logger.info(
chalk`=> Copying static files: {cyan ${print(from)}} at {cyan ${print(targetPath)}}`
);
}
await fs.copy(from, targetPath, {
dereference: true,
preserveTimestamps: true,
filter: (_, dest) => !skipPaths.includes(dest),
});
}, Promise.resolve());
}
function print(p: string): string {
return relative(process.cwd(), p);
}
1 change: 1 addition & 0 deletions code/lib/types/src/modules/core-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ export interface LoadOptions {
packageJson: PackageJson;
outputDir?: string;
configDir?: string;
cacheKey?: string;
ignorePreview?: boolean;
extendServer?: (server: Server) => void;
}
Expand Down
8 changes: 3 additions & 5 deletions code/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5136,14 +5136,12 @@ __metadata:
"@storybook/manager": "workspace:*"
"@storybook/node-logger": "workspace:*"
"@types/ejs": "npm:^3.1.1"
"@types/find-cache-dir": "npm:^3.2.1"
"@yarnpkg/esbuild-plugin-pnp": "npm:^3.0.0-rc.10"
browser-assert: "npm:^1.2.1"
ejs: "npm:^3.1.8"
esbuild: "npm:^0.18.0"
esbuild-plugin-alias: "npm:^0.2.1"
express: "npm:^4.17.3"
find-cache-dir: "npm:^3.0.0"
fs-extra: "npm:^11.1.0"
process: "npm:^0.11.10"
slash: "npm:^5.0.0"
Expand Down Expand Up @@ -11204,9 +11202,9 @@ __metadata:
linkType: hard

"caniuse-lite@npm:^1.0.30001406, caniuse-lite@npm:^1.0.30001538, caniuse-lite@npm:^1.0.30001565":
version: 1.0.30001566
resolution: "caniuse-lite@npm:1.0.30001566"
checksum: cd163075b1a9feaf9c9f657c3551279fcdac471471d67ee57ab2286c7b5480168e6336e359741b469fa40e94716f0f95ec185d87bd57d58894d66d8c21d7db04
version: 1.0.30001570
resolution: "caniuse-lite@npm:1.0.30001570"
checksum: e47230d2016edea56e002fa462a5289f697b48dcfbf703fb01aecc6c98ad4ecaf945ab23c253cb7af056c2d05f266e4e4cbebf45132100e2c9367439cb95b95b
languageName: node
linkType: hard

Expand Down

0 comments on commit aa37ebd

Please sign in to comment.