mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-06 01:11:06 +08:00
175 lines
5.9 KiB
TypeScript
175 lines
5.9 KiB
TypeScript
import webpack from 'webpack';
|
|
import { logger } from '@storybook/node-logger';
|
|
import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin';
|
|
import { targetFromTargetString, Target } from '@angular-devkit/architect';
|
|
import { sync as findUpSync } from 'find-up';
|
|
import semver from '@storybook/semver';
|
|
|
|
import { workspaces } from '@angular-devkit/core';
|
|
import {
|
|
findAngularProjectTarget,
|
|
getDefaultProjectName,
|
|
readAngularWorkspaceConfig,
|
|
} from './angular-read-workspace';
|
|
import {
|
|
AngularCliWebpackConfig,
|
|
extractAngularCliWebpackConfig,
|
|
} from './angular-devkit-build-webpack';
|
|
import { moduleIsAvailable } from './utils/module-is-available';
|
|
import { filterOutStylingRules } from './utils/filter-out-styling-rules';
|
|
import { getWebpackConfig as getWebpackConfig12_2_x } from './angular-cli-webpack-12.2.x';
|
|
import { getWebpackConfig as getWebpackConfig13_x_x } from './angular-cli-webpack-13.x.x';
|
|
import { PresetOptions } from './options';
|
|
|
|
export async function webpackFinal(baseConfig: webpack.Configuration, options: PresetOptions) {
|
|
/**
|
|
* Find angular version and use right getWebpackConfig
|
|
*
|
|
* ⚠️ Only work with angular storybook builder
|
|
*/
|
|
const packageJson = await import(findUpSync('package.json', { cwd: options.configDir }));
|
|
const angularCliVersion = semver.coerce(packageJson.devDependencies['@angular/cli'])?.version;
|
|
|
|
const isNg12_2_x = semver.satisfies(angularCliVersion, '12.2.x');
|
|
if (isNg12_2_x && options.angularBuilderContext) {
|
|
return getWebpackConfig12_2_x(baseConfig, options);
|
|
}
|
|
|
|
const isNg13_x_x = semver.satisfies(angularCliVersion, '13.x.x');
|
|
if (isNg13_x_x && options.angularBuilderContext) {
|
|
return getWebpackConfig13_x_x(baseConfig, options);
|
|
}
|
|
|
|
/**
|
|
* Classic way currently support version lower than 12.2.x
|
|
*/
|
|
const dirToSearch = process.cwd();
|
|
|
|
if (!moduleIsAvailable('@angular-devkit/build-angular')) {
|
|
logger.info('=> Using base config because "@angular-devkit/build-angular" is not installed');
|
|
return baseConfig;
|
|
}
|
|
logger.info('=> Loading angular-cli config');
|
|
|
|
// Read angular workspace
|
|
let workspaceConfig;
|
|
try {
|
|
workspaceConfig = await readAngularWorkspaceConfig(dirToSearch);
|
|
} catch (error) {
|
|
logger.error(
|
|
`=> Could not find angular workspace config (angular.json) on this path "${dirToSearch}"`
|
|
);
|
|
logger.info(`=> Fail to load angular-cli config. Using base config`);
|
|
return baseConfig;
|
|
}
|
|
|
|
// Find angular project target
|
|
let project: workspaces.ProjectDefinition;
|
|
let target: workspaces.TargetDefinition;
|
|
let confName: string;
|
|
try {
|
|
// Default behavior when `angularBrowserTarget` are not explicitly defined to null
|
|
if (options.angularBrowserTarget !== null) {
|
|
const browserTarget = options.angularBrowserTarget
|
|
? targetFromTargetString(options.angularBrowserTarget)
|
|
: ({
|
|
configuration: undefined,
|
|
project: getDefaultProjectName(workspaceConfig),
|
|
target: 'build',
|
|
} as Target);
|
|
|
|
const fondProject = findAngularProjectTarget(
|
|
workspaceConfig,
|
|
browserTarget.project,
|
|
browserTarget.target
|
|
);
|
|
project = fondProject.project;
|
|
target = fondProject.target;
|
|
confName = browserTarget.configuration;
|
|
|
|
logger.info(
|
|
`=> Using angular project "${browserTarget.project}:${browserTarget.target}${
|
|
confName ? `:${confName}` : ''
|
|
}" for configuring Storybook`
|
|
);
|
|
}
|
|
// Start storybook when only tsConfig is provided.
|
|
if (options.angularBrowserTarget === null && options.tsConfig) {
|
|
logger.info(`=> Using default angular project with "tsConfig:${options.tsConfig}"`);
|
|
|
|
project = { root: '', extensions: {}, targets: undefined };
|
|
target = { builder: '', options: { tsConfig: options.tsConfig } };
|
|
}
|
|
} catch (error) {
|
|
logger.error(`=> Could not find angular project: ${error.message}`);
|
|
logger.info(`=> Fail to load angular-cli config. Using base config`);
|
|
return baseConfig;
|
|
}
|
|
|
|
// Use angular-cli to get some webpack config
|
|
let angularCliWebpackConfig: AngularCliWebpackConfig;
|
|
try {
|
|
angularCliWebpackConfig = await extractAngularCliWebpackConfig(
|
|
dirToSearch,
|
|
project,
|
|
target,
|
|
confName
|
|
);
|
|
logger.info(`=> Using angular-cli webpack config`);
|
|
} catch (error) {
|
|
logger.error(`=> Could not get angular cli webpack config`);
|
|
throw error;
|
|
}
|
|
|
|
return mergeAngularCliWebpackConfig(angularCliWebpackConfig, baseConfig);
|
|
}
|
|
|
|
function mergeAngularCliWebpackConfig(
|
|
{ cliCommonWebpackConfig, cliStyleWebpackConfig, tsConfigPath }: AngularCliWebpackConfig,
|
|
baseConfig: webpack.Configuration
|
|
) {
|
|
// Don't use storybooks styling rules because we have to use rules created by @angular-devkit/build-angular
|
|
// because @angular-devkit/build-angular created rules have include/exclude for global style files.
|
|
const rulesExcludingStyles = filterOutStylingRules(baseConfig);
|
|
|
|
// styleWebpackConfig.entry adds global style files to the webpack context
|
|
const entry = [
|
|
...(baseConfig.entry as string[]),
|
|
...Object.values(cliStyleWebpackConfig.entry).reduce((acc, item) => acc.concat(item), []),
|
|
];
|
|
|
|
const module = {
|
|
...baseConfig.module,
|
|
rules: [...cliStyleWebpackConfig.module.rules, ...rulesExcludingStyles],
|
|
};
|
|
|
|
// We use cliCommonConfig plugins to serve static assets files.
|
|
const plugins = [
|
|
...cliStyleWebpackConfig.plugins,
|
|
...cliCommonWebpackConfig.plugins,
|
|
...baseConfig.plugins,
|
|
];
|
|
|
|
const resolve = {
|
|
...baseConfig.resolve,
|
|
modules: Array.from(
|
|
new Set([...baseConfig.resolve.modules, ...cliCommonWebpackConfig.resolve.modules])
|
|
),
|
|
plugins: [
|
|
new TsconfigPathsPlugin({
|
|
configFile: tsConfigPath,
|
|
mainFields: ['browser', 'module', 'main'],
|
|
}),
|
|
],
|
|
};
|
|
|
|
return {
|
|
...baseConfig,
|
|
entry,
|
|
module,
|
|
plugins,
|
|
resolve,
|
|
resolveLoader: cliCommonWebpackConfig.resolveLoader,
|
|
};
|
|
}
|