fix(storybook): handle output-dir properly for outputs (#21168)
This commit is contained in:
parent
d966d21b96
commit
01ae336eea
@ -66,7 +66,9 @@ export async function configurationGenerator(
|
|||||||
);
|
);
|
||||||
const { compiler } = findStorybookAndBuildTargetsAndCompiler(targets);
|
const { compiler } = findStorybookAndBuildTargetsAndCompiler(targets);
|
||||||
|
|
||||||
const viteConfigFilePath = findViteConfig(tree, root);
|
const viteConfig = findViteConfig(tree, root);
|
||||||
|
const viteConfigFilePath = viteConfig?.fullConfigPath;
|
||||||
|
const viteConfigFileName = viteConfig?.viteConfigFileName;
|
||||||
const nextConfigFilePath = findNextConfig(tree, root);
|
const nextConfigFilePath = findNextConfig(tree, root);
|
||||||
|
|
||||||
if (viteConfigFilePath) {
|
if (viteConfigFilePath) {
|
||||||
@ -130,7 +132,9 @@ export async function configurationGenerator(
|
|||||||
!!nextConfigFilePath,
|
!!nextConfigFilePath,
|
||||||
compiler === 'swc',
|
compiler === 'swc',
|
||||||
usesVite,
|
usesVite,
|
||||||
viteConfigFilePath
|
viteConfigFilePath,
|
||||||
|
hasPlugin,
|
||||||
|
viteConfigFileName
|
||||||
);
|
);
|
||||||
|
|
||||||
if (schema.uiFramework !== '@storybook/angular') {
|
if (schema.uiFramework !== '@storybook/angular') {
|
||||||
|
|||||||
@ -536,7 +536,9 @@ export function createProjectStorybookDir(
|
|||||||
isNextJs?: boolean,
|
isNextJs?: boolean,
|
||||||
usesSwc?: boolean,
|
usesSwc?: boolean,
|
||||||
usesVite?: boolean,
|
usesVite?: boolean,
|
||||||
viteConfigFilePath?: string
|
viteConfigFilePath?: string,
|
||||||
|
hasPlugin?: boolean,
|
||||||
|
viteConfigFileName?: string
|
||||||
) {
|
) {
|
||||||
let projectDirectory =
|
let projectDirectory =
|
||||||
projectType === 'application'
|
projectType === 'application'
|
||||||
@ -579,6 +581,8 @@ export function createProjectStorybookDir(
|
|||||||
usesVite,
|
usesVite,
|
||||||
isRootProject: projectIsRootProjectInStandaloneWorkspace,
|
isRootProject: projectIsRootProjectInStandaloneWorkspace,
|
||||||
viteConfigFilePath,
|
viteConfigFilePath,
|
||||||
|
hasPlugin,
|
||||||
|
viteConfigFileName,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (js) {
|
if (js) {
|
||||||
@ -699,13 +703,19 @@ export async function getE2EProjectName(
|
|||||||
export function findViteConfig(
|
export function findViteConfig(
|
||||||
tree: Tree,
|
tree: Tree,
|
||||||
projectRoot: string
|
projectRoot: string
|
||||||
): string | undefined {
|
): {
|
||||||
|
fullConfigPath: string | undefined;
|
||||||
|
viteConfigFileName: string | undefined;
|
||||||
|
} {
|
||||||
const allowsExt = ['js', 'mjs', 'ts', 'cjs', 'mts', 'cts'];
|
const allowsExt = ['js', 'mjs', 'ts', 'cjs', 'mts', 'cts'];
|
||||||
|
|
||||||
for (const ext of allowsExt) {
|
for (const ext of allowsExt) {
|
||||||
const viteConfigPath = joinPathFragments(projectRoot, `vite.config.${ext}`);
|
const viteConfigPath = joinPathFragments(projectRoot, `vite.config.${ext}`);
|
||||||
if (tree.exists(viteConfigPath)) {
|
if (tree.exists(viteConfigPath)) {
|
||||||
return viteConfigPath;
|
return {
|
||||||
|
fullConfigPath: viteConfigPath,
|
||||||
|
viteConfigFileName: `vite.config.${ext}`,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,11 @@ const config: StorybookConfig = {
|
|||||||
framework: {
|
framework: {
|
||||||
name: '<%= uiFramework %>',
|
name: '<%= uiFramework %>',
|
||||||
options: {
|
options: {
|
||||||
<% if (usesVite && viteConfigFilePath) { %>
|
<% if (usesVite && viteConfigFilePath && hasPlugin) { %>
|
||||||
|
builder: {
|
||||||
|
viteConfigPath: '<%= viteConfigFileName %>',
|
||||||
|
},
|
||||||
|
<% } %><% if (usesVite && viteConfigFilePath && !hasPlugin) { %>
|
||||||
builder: {
|
builder: {
|
||||||
viteConfigPath: '<%= viteConfigFilePath %>',
|
viteConfigPath: '<%= viteConfigFilePath %>',
|
||||||
},
|
},
|
||||||
|
|||||||
@ -13,7 +13,12 @@ const config = {
|
|||||||
framework: {
|
framework: {
|
||||||
name: '<%= uiFramework %>',
|
name: '<%= uiFramework %>',
|
||||||
options: {
|
options: {
|
||||||
<% if (usesVite && viteConfigFilePath) { %>
|
<% if (usesVite && viteConfigFilePath && hasPlugin) { %>
|
||||||
|
builder: {
|
||||||
|
viteConfigPath: '<%= viteConfigFileName %>',
|
||||||
|
},
|
||||||
|
<% } %>
|
||||||
|
<% if (usesVite && viteConfigFilePath && !hasPlugin) { %>
|
||||||
builder: {
|
builder: {
|
||||||
viteConfigPath: '<%= viteConfigFilePath %>',
|
viteConfigPath: '<%= viteConfigFilePath %>',
|
||||||
},
|
},
|
||||||
|
|||||||
@ -72,10 +72,17 @@ describe('@nx/storybook/plugin', () => {
|
|||||||
expect(
|
expect(
|
||||||
nodes?.['projects']?.['my-app']?.targets?.['build-storybook']
|
nodes?.['projects']?.['my-app']?.targets?.['build-storybook']
|
||||||
).toMatchObject({
|
).toMatchObject({
|
||||||
command:
|
command: 'storybook build',
|
||||||
'storybook build --config-dir my-app/.storybook --output-dir dist/storybook/my-app',
|
options: {
|
||||||
|
cwd: 'my-app',
|
||||||
|
},
|
||||||
cache: true,
|
cache: true,
|
||||||
outputs: ['{workspaceRoot}/dist/storybook/{projectRoot}'],
|
outputs: [
|
||||||
|
'{workspaceRoot}/{projectRoot}/static-storybook',
|
||||||
|
'{options.output-dir}',
|
||||||
|
'{options.outputDir}',
|
||||||
|
'{options.o}',
|
||||||
|
],
|
||||||
inputs: [
|
inputs: [
|
||||||
'production',
|
'production',
|
||||||
'^production',
|
'^production',
|
||||||
@ -86,12 +93,12 @@ describe('@nx/storybook/plugin', () => {
|
|||||||
expect(
|
expect(
|
||||||
nodes?.['projects']?.['my-app']?.targets?.['storybook']
|
nodes?.['projects']?.['my-app']?.targets?.['storybook']
|
||||||
).toMatchObject({
|
).toMatchObject({
|
||||||
command: 'storybook dev --config-dir my-app/.storybook',
|
command: 'storybook dev',
|
||||||
});
|
});
|
||||||
expect(
|
expect(
|
||||||
nodes?.['projects']?.['my-app']?.targets?.['test-storybook']
|
nodes?.['projects']?.['my-app']?.targets?.['test-storybook']
|
||||||
).toMatchObject({
|
).toMatchObject({
|
||||||
command: 'test-storybook --config-dir my-app/.storybook',
|
command: 'test-storybook',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -128,13 +135,18 @@ describe('@nx/storybook/plugin', () => {
|
|||||||
).toMatchObject({
|
).toMatchObject({
|
||||||
executor: '@storybook/angular:build-storybook',
|
executor: '@storybook/angular:build-storybook',
|
||||||
options: {
|
options: {
|
||||||
outputDir: 'dist/storybook/my-ng-app',
|
outputDir: 'my-ng-app/static-storybook',
|
||||||
configDir: 'my-ng-app/.storybook',
|
configDir: 'my-ng-app/.storybook',
|
||||||
browserTarget: 'my-ng-app:build-storybook',
|
browserTarget: 'my-ng-app:build-storybook',
|
||||||
compodoc: false,
|
compodoc: false,
|
||||||
},
|
},
|
||||||
cache: true,
|
cache: true,
|
||||||
outputs: ['{workspaceRoot}/dist/storybook/{projectRoot}'],
|
outputs: [
|
||||||
|
'{workspaceRoot}/{projectRoot}/static-storybook',
|
||||||
|
'{options.output-dir}',
|
||||||
|
'{options.outputDir}',
|
||||||
|
'{options.o}',
|
||||||
|
],
|
||||||
inputs: [
|
inputs: [
|
||||||
'production',
|
'production',
|
||||||
'^production',
|
'^production',
|
||||||
@ -161,7 +173,7 @@ describe('@nx/storybook/plugin', () => {
|
|||||||
expect(
|
expect(
|
||||||
nodes?.['projects']?.['my-ng-app']?.targets?.['test-storybook']
|
nodes?.['projects']?.['my-ng-app']?.targets?.['test-storybook']
|
||||||
).toMatchObject({
|
).toMatchObject({
|
||||||
command: 'test-storybook --config-dir my-ng-app/.storybook',
|
command: 'test-storybook',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -64,6 +64,7 @@ export const createNodes: CreateNodes<StorybookPluginOptions> = [
|
|||||||
if (projectRoot === '') {
|
if (projectRoot === '') {
|
||||||
projectRoot = '.';
|
projectRoot = '.';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not create a project if package.json and project.json isn't there.
|
// Do not create a project if package.json and project.json isn't there.
|
||||||
const siblingFiles = readdirSync(join(context.workspaceRoot, projectRoot));
|
const siblingFiles = readdirSync(join(context.workspaceRoot, projectRoot));
|
||||||
if (
|
if (
|
||||||
@ -101,7 +102,7 @@ export const createNodes: CreateNodes<StorybookPluginOptions> = [
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
// For root projects, the name is not inferred from root package.json, so we need to manually set it.
|
// For root projects, the name is not inferred from root package.json, so we need to manually set it.
|
||||||
// TODO(jack): We should handle this in core and remove this workaround.
|
// TODO(katerina): Remove this workaround once Craigory's PR (https://github.com/nrwl/nx/pull/21125) is merged
|
||||||
if (projectRoot === '.') {
|
if (projectRoot === '.') {
|
||||||
result.projects[projectRoot]['name'] = projectName;
|
result.projects[projectRoot]['name'] = projectName;
|
||||||
}
|
}
|
||||||
@ -130,19 +131,20 @@ function buildStorybookTargets(
|
|||||||
targets[options.buildStorybookTargetName] = buildTarget(
|
targets[options.buildStorybookTargetName] = buildTarget(
|
||||||
namedInputs,
|
namedInputs,
|
||||||
buildOutputs,
|
buildOutputs,
|
||||||
configFilePath,
|
|
||||||
projectRoot,
|
projectRoot,
|
||||||
frameworkIsAngular,
|
frameworkIsAngular,
|
||||||
projectName
|
projectName,
|
||||||
|
configFilePath
|
||||||
);
|
);
|
||||||
|
|
||||||
targets[options.serveStorybookTargetName] = serveTarget(
|
targets[options.serveStorybookTargetName] = serveTarget(
|
||||||
configFilePath,
|
projectRoot,
|
||||||
frameworkIsAngular,
|
frameworkIsAngular,
|
||||||
projectName
|
projectName,
|
||||||
|
configFilePath
|
||||||
);
|
);
|
||||||
|
|
||||||
targets[options.testStorybookTargetName] = testTarget(configFilePath);
|
targets[options.testStorybookTargetName] = testTarget(projectRoot);
|
||||||
|
|
||||||
targets[options.staticStorybookTargetName] = serveStaticTarget(
|
targets[options.staticStorybookTargetName] = serveStaticTarget(
|
||||||
options,
|
options,
|
||||||
@ -157,23 +159,21 @@ function buildTarget(
|
|||||||
[inputName: string]: any[];
|
[inputName: string]: any[];
|
||||||
},
|
},
|
||||||
outputs: string[],
|
outputs: string[],
|
||||||
configFilePath: string,
|
|
||||||
projectRoot: string,
|
projectRoot: string,
|
||||||
frameworkIsAngular: boolean,
|
frameworkIsAngular: boolean,
|
||||||
projectName: string
|
projectName: string,
|
||||||
|
configFilePath: string
|
||||||
) {
|
) {
|
||||||
const outputDir = joinPathFragments('dist/storybook', projectRoot);
|
|
||||||
|
|
||||||
let targetConfig: TargetConfiguration;
|
let targetConfig: TargetConfiguration;
|
||||||
|
|
||||||
if (frameworkIsAngular) {
|
if (frameworkIsAngular) {
|
||||||
targetConfig = {
|
targetConfig = {
|
||||||
executor: '@storybook/angular:build-storybook',
|
executor: '@storybook/angular:build-storybook',
|
||||||
options: {
|
options: {
|
||||||
outputDir: `${outputDir}`,
|
|
||||||
configDir: `${dirname(configFilePath)}`,
|
configDir: `${dirname(configFilePath)}`,
|
||||||
browserTarget: `${projectName}:build-storybook`,
|
browserTarget: `${projectName}:build-storybook`,
|
||||||
compodoc: false,
|
compodoc: false,
|
||||||
|
outputDir: joinPathFragments(projectRoot, 'static-storybook'),
|
||||||
},
|
},
|
||||||
cache: true,
|
cache: true,
|
||||||
outputs,
|
outputs,
|
||||||
@ -192,9 +192,8 @@ function buildTarget(
|
|||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
targetConfig = {
|
targetConfig = {
|
||||||
command: `storybook build --config-dir ${dirname(
|
command: `storybook build`,
|
||||||
configFilePath
|
options: { cwd: projectRoot },
|
||||||
)} --output-dir ${outputDir}`,
|
|
||||||
cache: true,
|
cache: true,
|
||||||
outputs,
|
outputs,
|
||||||
inputs: [
|
inputs: [
|
||||||
@ -212,9 +211,10 @@ function buildTarget(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function serveTarget(
|
function serveTarget(
|
||||||
configFilePath: string,
|
projectRoot: string,
|
||||||
frameworkIsAngular: boolean,
|
frameworkIsAngular: boolean,
|
||||||
projectName: string
|
projectName: string,
|
||||||
|
configFilePath: string
|
||||||
) {
|
) {
|
||||||
if (frameworkIsAngular) {
|
if (frameworkIsAngular) {
|
||||||
return {
|
return {
|
||||||
@ -227,14 +227,16 @@ function serveTarget(
|
|||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
command: `storybook dev --config-dir ${dirname(configFilePath)}`,
|
command: `storybook dev`,
|
||||||
|
options: { cwd: projectRoot },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function testTarget(configFilePath: string) {
|
function testTarget(projectRoot: string) {
|
||||||
const targetConfig: TargetConfiguration = {
|
const targetConfig: TargetConfiguration = {
|
||||||
command: `test-storybook --config-dir ${dirname(configFilePath)}`,
|
command: `test-storybook`,
|
||||||
|
options: { cwd: projectRoot },
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
externalDependencies: ['storybook', '@storybook/test-runner'],
|
externalDependencies: ['storybook', '@storybook/test-runner'],
|
||||||
@ -253,8 +255,7 @@ function serveStaticTarget(
|
|||||||
executor: '@nx/web:file-server',
|
executor: '@nx/web:file-server',
|
||||||
options: {
|
options: {
|
||||||
buildTarget: `${options.buildStorybookTargetName}`,
|
buildTarget: `${options.buildStorybookTargetName}`,
|
||||||
// TODO(katerina): need to read the output from CLI args
|
staticFilePath: joinPathFragments(projectRoot, 'static-storybook'),
|
||||||
staticFilePath: joinPathFragments('dist/storybook', projectRoot),
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -316,12 +317,14 @@ function getStorybookConfig(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getOutputs(_projectRoot: string): string[] {
|
function getOutputs(_projectRoot: string): string[] {
|
||||||
// TODO(katerina): need to read the output from CLI args
|
|
||||||
// const outputPath = <output path as read from CLI>;
|
|
||||||
|
|
||||||
const normalizedOutputPath = normalizeOutputPath(undefined, _projectRoot);
|
const normalizedOutputPath = normalizeOutputPath(undefined, _projectRoot);
|
||||||
|
|
||||||
const outputs = [normalizedOutputPath];
|
const outputs = [
|
||||||
|
normalizedOutputPath,
|
||||||
|
`{options.output-dir}`,
|
||||||
|
`{options.outputDir}`,
|
||||||
|
`{options.o}`,
|
||||||
|
];
|
||||||
|
|
||||||
return outputs;
|
return outputs;
|
||||||
}
|
}
|
||||||
@ -330,22 +333,10 @@ function normalizeOutputPath(
|
|||||||
outputPath: string | undefined,
|
outputPath: string | undefined,
|
||||||
projectRoot: string
|
projectRoot: string
|
||||||
): string | undefined {
|
): string | undefined {
|
||||||
if (!outputPath) {
|
|
||||||
if (projectRoot === '.') {
|
if (projectRoot === '.') {
|
||||||
return `{projectRoot}/dist/storybook`;
|
return `{projectRoot}/static-storybook`;
|
||||||
} else {
|
} else {
|
||||||
return `{workspaceRoot}/dist/storybook/{projectRoot}`;
|
return `{workspaceRoot}/{projectRoot}/static-storybook`;
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (isAbsolute(outputPath)) {
|
|
||||||
return `{workspaceRoot}/${relative(workspaceRoot, outputPath)}`;
|
|
||||||
} else {
|
|
||||||
if (outputPath.startsWith('..')) {
|
|
||||||
return join('{workspaceRoot}', join(projectRoot, outputPath));
|
|
||||||
} else {
|
|
||||||
return join('{projectRoot}', outputPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user