mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-07 18:31:46 +08:00
feat(angular): split get webpack config in one per supported version
This commit is contained in:
parent
c988bb2cd6
commit
ed5912e308
@ -1 +1,7 @@
|
|||||||
export declare function getWebpackConfig(baseConfig: any, options: any): any;
|
import { JsonObject } from '@angular-devkit/core';
|
||||||
|
import { BuilderContext } from '@angular-devkit/architect';
|
||||||
|
|
||||||
|
export declare function getWebpackConfig(
|
||||||
|
baseConfig: any,
|
||||||
|
options: { builderOptions: JsonObject; builderContext: BuilderContext }
|
||||||
|
): any;
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
const { targetFromTargetString } = require('@angular-devkit/architect');
|
|
||||||
|
|
||||||
// Private angular devkit stuff
|
// Private angular devkit stuff
|
||||||
const {
|
const {
|
||||||
generateI18nBrowserWebpackConfigFromContext,
|
generateI18nBrowserWebpackConfigFromContext,
|
||||||
@ -7,53 +5,47 @@ const {
|
|||||||
const {
|
const {
|
||||||
getCommonConfig,
|
getCommonConfig,
|
||||||
getStylesConfig,
|
getStylesConfig,
|
||||||
getTypescriptWorkerPlugin,
|
getTypeScriptConfig,
|
||||||
} = require('@angular-devkit/build-angular/src/webpack/configs');
|
} = require('@angular-devkit/build-angular/src/webpack/configs');
|
||||||
|
|
||||||
const { filterOutStylingRules } = require('./utils/filter-out-styling-rules');
|
const { filterOutStylingRules } = require('./utils/filter-out-styling-rules');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract wepack config from angular-cli 12.2.x
|
* Extract webpack config from angular-cli 12.2.x
|
||||||
* ⚠️ This file is in JavaScript to not use TypeScript. Because current storybook TypeScript version is not compatible with Angular CLI.
|
* ⚠️ This file is in JavaScript to not use TypeScript. Because current storybook TypeScript version is not compatible with Angular CLI.
|
||||||
* FIXME: Try another way with TypeScript on future storybook version (7 maybe 🤞)
|
* FIXME: Try another way with TypeScript on future storybook version (7 maybe 🤞)
|
||||||
*
|
*
|
||||||
* @param {*} baseConfig Previous webpack config from storybook
|
* @param {*} baseConfig Previous webpack config from storybook
|
||||||
* @param {*} options PresetOptions
|
* @param {*} options { builderOptions, builderContext }
|
||||||
|
*/
|
||||||
|
exports.getWebpackConfig = async (baseConfig, { builderOptions, builderContext }) => {
|
||||||
|
/**
|
||||||
|
* Get angular-cli Webpack config
|
||||||
*/
|
*/
|
||||||
exports.getWebpackConfig = async (baseConfig, options) => {
|
|
||||||
const builderContext = options.angularBuilderContext;
|
|
||||||
const target = options.angularBrowserTarget;
|
|
||||||
|
|
||||||
let targetOptions = {};
|
|
||||||
|
|
||||||
if (target) {
|
|
||||||
targetOptions = await builderContext.getTargetOptions(targetFromTargetString(target));
|
|
||||||
}
|
|
||||||
|
|
||||||
const tsConfig = options.tsConfig ?? targetOptions.tsConfig;
|
|
||||||
|
|
||||||
const { config: cliConfig } = await generateI18nBrowserWebpackConfigFromContext(
|
const { config: cliConfig } = await generateI18nBrowserWebpackConfigFromContext(
|
||||||
{
|
{
|
||||||
// Default required options
|
// Default options
|
||||||
index: 'noop-index',
|
index: 'noop-index',
|
||||||
main: 'noop-main',
|
main: 'noop-main',
|
||||||
outputPath: 'noop-out',
|
outputPath: 'noop-out',
|
||||||
|
|
||||||
// Target options to override
|
// Options provided by user
|
||||||
...targetOptions,
|
...builderOptions,
|
||||||
|
|
||||||
// Fixed options
|
// Fixed options
|
||||||
optimization: false,
|
optimization: false,
|
||||||
namedChunks: false,
|
namedChunks: false,
|
||||||
progress: false,
|
progress: false,
|
||||||
tsConfig,
|
|
||||||
buildOptimizer: false,
|
buildOptimizer: false,
|
||||||
aot: false,
|
aot: false,
|
||||||
},
|
},
|
||||||
builderContext,
|
builderContext,
|
||||||
(wco) => [getCommonConfig(wco), getStylesConfig(wco), getTypescriptWorkerPlugin(wco)]
|
(wco) => [getCommonConfig(wco), getStylesConfig(wco), getTypeScriptConfig(wco)]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge baseConfig Webpack with angular-cli Webpack
|
||||||
|
*/
|
||||||
const entry = [
|
const entry = [
|
||||||
...baseConfig.entry,
|
...baseConfig.entry,
|
||||||
...(cliConfig.entry.styles ?? []),
|
...(cliConfig.entry.styles ?? []),
|
||||||
@ -63,6 +55,12 @@ exports.getWebpackConfig = async (baseConfig, options) => {
|
|||||||
// Don't use storybooks styling rules because we have to use rules created by @angular-devkit/build-angular
|
// 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.
|
// because @angular-devkit/build-angular created rules have include/exclude for global style files.
|
||||||
const rulesExcludingStyles = filterOutStylingRules(baseConfig);
|
const rulesExcludingStyles = filterOutStylingRules(baseConfig);
|
||||||
|
const module = {
|
||||||
|
...baseConfig.module,
|
||||||
|
rules: [...cliConfig.module.rules, ...rulesExcludingStyles],
|
||||||
|
};
|
||||||
|
|
||||||
|
const plugins = [...(cliConfig.plugins ?? []), ...baseConfig.plugins];
|
||||||
|
|
||||||
const resolve = {
|
const resolve = {
|
||||||
...baseConfig.resolve,
|
...baseConfig.resolve,
|
||||||
@ -72,11 +70,8 @@ exports.getWebpackConfig = async (baseConfig, options) => {
|
|||||||
return {
|
return {
|
||||||
...baseConfig,
|
...baseConfig,
|
||||||
entry,
|
entry,
|
||||||
module: {
|
module,
|
||||||
...baseConfig.module,
|
plugins,
|
||||||
rules: [...cliConfig.module.rules, ...rulesExcludingStyles],
|
|
||||||
},
|
|
||||||
plugins: [...(cliConfig.plugins ?? []), ...baseConfig.plugins],
|
|
||||||
resolve,
|
resolve,
|
||||||
resolveLoader: cliConfig.resolveLoader,
|
resolveLoader: cliConfig.resolveLoader,
|
||||||
};
|
};
|
||||||
|
@ -1 +1,7 @@
|
|||||||
export declare function getWebpackConfig(baseConfig: any, options: any): any;
|
import { JsonObject } from '@angular-devkit/core';
|
||||||
|
import { BuilderContext } from '@angular-devkit/architect';
|
||||||
|
|
||||||
|
export declare function getWebpackConfig(
|
||||||
|
baseConfig: any,
|
||||||
|
options: { builderOptions: JsonObject; builderContext: BuilderContext }
|
||||||
|
): any;
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
const { targetFromTargetString } = require('@angular-devkit/architect');
|
|
||||||
|
|
||||||
// Private angular devkit stuff
|
// Private angular devkit stuff
|
||||||
const {
|
const {
|
||||||
generateI18nBrowserWebpackConfigFromContext,
|
generateI18nBrowserWebpackConfigFromContext,
|
||||||
@ -13,40 +11,31 @@ const {
|
|||||||
const { filterOutStylingRules } = require('./utils/filter-out-styling-rules');
|
const { filterOutStylingRules } = require('./utils/filter-out-styling-rules');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract wepack config from angular-cli 12.2.x
|
* Extract webpack config from angular-cli 13.x.x
|
||||||
* ⚠️ This file is in JavaScript to not use TypeScript. Because current storybook TypeScript version is not compatible with Angular CLI.
|
* ⚠️ This file is in JavaScript to not use TypeScript. Because current storybook TypeScript version is not compatible with Angular CLI.
|
||||||
* FIXME: Try another way with TypeScript on future storybook version (7 maybe 🤞)
|
* FIXME: Try another way with TypeScript on future storybook version (7 maybe 🤞)
|
||||||
*
|
*
|
||||||
* @param {*} baseConfig Previous webpack config from storybook
|
* @param {*} baseConfig Previous webpack config from storybook
|
||||||
* @param {*} options PresetOptions
|
* @param {*} options { builderOptions, builderContext }
|
||||||
|
*/
|
||||||
|
exports.getWebpackConfig = async (baseConfig, { builderOptions, builderContext }) => {
|
||||||
|
/**
|
||||||
|
* Get angular-cli Webpack config
|
||||||
*/
|
*/
|
||||||
exports.getWebpackConfig = async (baseConfig, options) => {
|
|
||||||
const builderContext = options.angularBuilderContext;
|
|
||||||
const target = options.angularBrowserTarget;
|
|
||||||
|
|
||||||
let targetOptions = {};
|
|
||||||
|
|
||||||
if (target) {
|
|
||||||
targetOptions = await builderContext.getTargetOptions(targetFromTargetString(target));
|
|
||||||
}
|
|
||||||
|
|
||||||
const tsConfig = options.tsConfig ?? targetOptions.tsConfig;
|
|
||||||
|
|
||||||
const { config: cliConfig } = await generateI18nBrowserWebpackConfigFromContext(
|
const { config: cliConfig } = await generateI18nBrowserWebpackConfigFromContext(
|
||||||
{
|
{
|
||||||
// Default required options
|
// Default options
|
||||||
index: 'noop-index',
|
index: 'noop-index',
|
||||||
main: 'noop-main',
|
main: 'noop-main',
|
||||||
outputPath: 'noop-out',
|
outputPath: 'noop-out',
|
||||||
|
|
||||||
// Target options to override
|
// Options provided by user
|
||||||
...targetOptions,
|
...builderOptions,
|
||||||
|
|
||||||
// Fixed options
|
// Fixed options
|
||||||
optimization: false,
|
optimization: false,
|
||||||
namedChunks: false,
|
namedChunks: false,
|
||||||
progress: false,
|
progress: false,
|
||||||
tsConfig,
|
|
||||||
buildOptimizer: false,
|
buildOptimizer: false,
|
||||||
aot: false,
|
aot: false,
|
||||||
},
|
},
|
||||||
@ -54,6 +43,9 @@ exports.getWebpackConfig = async (baseConfig, options) => {
|
|||||||
(wco) => [getCommonConfig(wco), getStylesConfig(wco), getTypescriptWorkerPlugin(wco)]
|
(wco) => [getCommonConfig(wco), getStylesConfig(wco), getTypescriptWorkerPlugin(wco)]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge baseConfig Webpack with angular-cli Webpack
|
||||||
|
*/
|
||||||
const entry = [
|
const entry = [
|
||||||
...baseConfig.entry,
|
...baseConfig.entry,
|
||||||
...(cliConfig.entry.styles ?? []),
|
...(cliConfig.entry.styles ?? []),
|
||||||
@ -63,6 +55,12 @@ exports.getWebpackConfig = async (baseConfig, options) => {
|
|||||||
// Don't use storybooks styling rules because we have to use rules created by @angular-devkit/build-angular
|
// 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.
|
// because @angular-devkit/build-angular created rules have include/exclude for global style files.
|
||||||
const rulesExcludingStyles = filterOutStylingRules(baseConfig);
|
const rulesExcludingStyles = filterOutStylingRules(baseConfig);
|
||||||
|
const module = {
|
||||||
|
...baseConfig.module,
|
||||||
|
rules: [...cliConfig.module.rules, ...rulesExcludingStyles],
|
||||||
|
};
|
||||||
|
|
||||||
|
const plugins = [...(cliConfig.plugins ?? []), ...baseConfig.plugins];
|
||||||
|
|
||||||
const resolve = {
|
const resolve = {
|
||||||
...baseConfig.resolve,
|
...baseConfig.resolve,
|
||||||
@ -72,11 +70,8 @@ exports.getWebpackConfig = async (baseConfig, options) => {
|
|||||||
return {
|
return {
|
||||||
...baseConfig,
|
...baseConfig,
|
||||||
entry,
|
entry,
|
||||||
module: {
|
module,
|
||||||
...baseConfig.module,
|
plugins,
|
||||||
rules: [...cliConfig.module.rules, ...rulesExcludingStyles],
|
|
||||||
},
|
|
||||||
plugins: [...(cliConfig.plugins ?? []), ...baseConfig.plugins],
|
|
||||||
resolve,
|
resolve,
|
||||||
resolveLoader: cliConfig.resolveLoader,
|
resolveLoader: cliConfig.resolveLoader,
|
||||||
};
|
};
|
||||||
|
146
app/angular/src/server/angular-cli-webpack-older.ts
Normal file
146
app/angular/src/server/angular-cli-webpack-older.ts
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
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 { workspaces } from '@angular-devkit/core';
|
||||||
|
import {
|
||||||
|
findAngularProjectTarget,
|
||||||
|
getDefaultProjectName,
|
||||||
|
readAngularWorkspaceConfig,
|
||||||
|
} from './angular-read-workspace';
|
||||||
|
import {
|
||||||
|
AngularCliWebpackConfig,
|
||||||
|
extractAngularCliWebpackConfig,
|
||||||
|
} from './angular-devkit-build-webpack';
|
||||||
|
import { filterOutStylingRules } from './utils/filter-out-styling-rules';
|
||||||
|
import { PresetOptions } from './options';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Old way currently support version lower than 12.2.x
|
||||||
|
*/
|
||||||
|
export async function getWebpackConfig(baseConfig: webpack.Configuration, options: PresetOptions) {
|
||||||
|
logger.info('=> Loading angular-cli config for angular <=12.2.0');
|
||||||
|
const dirToSearch = process.cwd();
|
||||||
|
|
||||||
|
// 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,
|
||||||
|
};
|
||||||
|
}
|
@ -1,174 +1,126 @@
|
|||||||
import webpack from 'webpack';
|
import webpack from 'webpack';
|
||||||
import { logger } from '@storybook/node-logger';
|
import { logger } from '@storybook/node-logger';
|
||||||
import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin';
|
import { targetFromTargetString, BuilderContext } from '@angular-devkit/architect';
|
||||||
import { targetFromTargetString, Target } from '@angular-devkit/architect';
|
|
||||||
import { sync as findUpSync } from 'find-up';
|
import { sync as findUpSync } from 'find-up';
|
||||||
import semver from '@storybook/semver';
|
import semver from '@storybook/semver';
|
||||||
|
|
||||||
import { workspaces } from '@angular-devkit/core';
|
import { logging, JsonObject } 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 { 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 getWebpackConfig12_2_x } from './angular-cli-webpack-12.2.x';
|
||||||
import { getWebpackConfig as getWebpackConfig13_x_x } from './angular-cli-webpack-13.x.x';
|
import { getWebpackConfig as getWebpackConfig13_x_x } from './angular-cli-webpack-13.x.x';
|
||||||
|
import { getWebpackConfig as getWebpackConfigOlder } from './angular-cli-webpack-older';
|
||||||
import { PresetOptions } from './options';
|
import { PresetOptions } from './options';
|
||||||
|
|
||||||
export async function webpackFinal(baseConfig: webpack.Configuration, options: PresetOptions) {
|
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')) {
|
if (!moduleIsAvailable('@angular-devkit/build-angular')) {
|
||||||
logger.info('=> Using base config because "@angular-devkit/build-angular" is not installed');
|
logger.info('=> Using base config because "@angular-devkit/build-angular" is not installed');
|
||||||
return baseConfig;
|
return baseConfig;
|
||||||
}
|
}
|
||||||
logger.info('=> Loading angular-cli config');
|
|
||||||
|
|
||||||
// Read angular workspace
|
const packageJson = await import(findUpSync('package.json', { cwd: options.configDir }));
|
||||||
let workspaceConfig;
|
const angularCliVersion = semver.coerce(packageJson.devDependencies['@angular/cli'])?.version;
|
||||||
try {
|
|
||||||
workspaceConfig = await readAngularWorkspaceConfig(dirToSearch);
|
/**
|
||||||
} catch (error) {
|
* Ordered array to use the specific getWebpackConfig according to some condition like angular-cli version
|
||||||
logger.error(
|
*/
|
||||||
`=> Could not find angular workspace config (angular.json) on this path "${dirToSearch}"`
|
const webpackGetterByVersions: {
|
||||||
);
|
info: string;
|
||||||
logger.info(`=> Fail to load angular-cli config. Using base config`);
|
condition: boolean;
|
||||||
return baseConfig;
|
getWebpackConfig(
|
||||||
|
baseConfig: webpack.Configuration,
|
||||||
|
options: PresetOptions
|
||||||
|
): Promise<webpack.Configuration> | webpack.Configuration;
|
||||||
|
}[] = [
|
||||||
|
{
|
||||||
|
info: '=> Loading angular-cli config for angular >= 13.0.0',
|
||||||
|
condition: semver.satisfies(angularCliVersion, '>=13.0.0'),
|
||||||
|
getWebpackConfig: async (_baseConfig, _options) => {
|
||||||
|
const builderContext = getBuilderContext(_options);
|
||||||
|
const builderOptions = await getBuilderOptions(_options, builderContext);
|
||||||
|
|
||||||
|
return getWebpackConfig13_x_x(_baseConfig, {
|
||||||
|
builderOptions,
|
||||||
|
builderContext,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
info: '=> Loading angular-cli config for angular 12.2.x',
|
||||||
|
condition: semver.satisfies(angularCliVersion, '12.2.x') && options.angularBuilderContext,
|
||||||
|
getWebpackConfig: async (_baseConfig, _options) => {
|
||||||
|
const builderContext = getBuilderContext(_options);
|
||||||
|
const builderOptions = await getBuilderOptions(_options, builderContext);
|
||||||
|
|
||||||
|
return getWebpackConfig12_2_x(_baseConfig, {
|
||||||
|
builderOptions,
|
||||||
|
builderContext,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
info: '=> Loading angular-cli config for angular lower than 12.2.0',
|
||||||
|
condition: true,
|
||||||
|
getWebpackConfig: getWebpackConfigOlder,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const webpackGetter = webpackGetterByVersions.find((wg) => wg.condition);
|
||||||
|
|
||||||
|
logger.info(webpackGetter.info);
|
||||||
|
return Promise.resolve(webpackGetter.getWebpackConfig(baseConfig, options));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find angular project target
|
/**
|
||||||
let project: workspaces.ProjectDefinition;
|
* Get Builder Context
|
||||||
let target: workspaces.TargetDefinition;
|
* If storybook is not start by angular builder create dumb BuilderContext
|
||||||
let confName: string;
|
*/
|
||||||
try {
|
function getBuilderContext(options: PresetOptions): BuilderContext {
|
||||||
// Default behavior when `angularBrowserTarget` are not explicitly defined to null
|
return (
|
||||||
if (options.angularBrowserTarget !== null) {
|
options.angularBuilderContext ??
|
||||||
const browserTarget = options.angularBrowserTarget
|
(({
|
||||||
? targetFromTargetString(options.angularBrowserTarget)
|
target: { project: 'noop-project', builder: '', options: {} },
|
||||||
: ({
|
workspaceRoot: process.cwd(),
|
||||||
configuration: undefined,
|
getProjectMetadata: () => ({}),
|
||||||
project: getDefaultProjectName(workspaceConfig),
|
getTargetOptions: () => ({}),
|
||||||
target: 'build',
|
logger: new logging.Logger('Storybook'),
|
||||||
} as Target);
|
} as unknown) as BuilderContext)
|
||||||
|
|
||||||
const fondProject = findAngularProjectTarget(
|
|
||||||
workspaceConfig,
|
|
||||||
browserTarget.project,
|
|
||||||
browserTarget.target
|
|
||||||
);
|
);
|
||||||
project = fondProject.project;
|
}
|
||||||
target = fondProject.target;
|
|
||||||
confName = browserTarget.configuration;
|
/**
|
||||||
|
* Get builder options
|
||||||
|
* Merge target options from browser target and from storybook options
|
||||||
|
*/
|
||||||
|
async function getBuilderOptions(
|
||||||
|
options: PresetOptions,
|
||||||
|
builderContext: BuilderContext
|
||||||
|
): Promise<JsonObject> {
|
||||||
|
/**
|
||||||
|
* Get Browser Target options
|
||||||
|
*/
|
||||||
|
let browserTargetOptions: JsonObject = {};
|
||||||
|
if (options.angularBrowserTarget) {
|
||||||
|
const browserTarget = targetFromTargetString(options.angularBrowserTarget);
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
`=> Using angular project "${browserTarget.project}:${browserTarget.target}${
|
`=> Using angular browser target options from "${browserTarget.project}:${
|
||||||
confName ? `:${confName}` : ''
|
browserTarget.target
|
||||||
}" for configuring Storybook`
|
}${browserTarget.configuration ? `:${browserTarget.configuration}` : ''}"`
|
||||||
);
|
);
|
||||||
}
|
browserTargetOptions = await builderContext.getTargetOptions(browserTarget);
|
||||||
// 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;
|
* Merge target options from browser target options and from storybook options
|
||||||
try {
|
*/
|
||||||
angularCliWebpackConfig = await extractAngularCliWebpackConfig(
|
const builderOptions = {
|
||||||
dirToSearch,
|
...browserTargetOptions,
|
||||||
project,
|
tsConfig:
|
||||||
target,
|
options.tsConfig ??
|
||||||
confName
|
browserTargetOptions.tsConfig ??
|
||||||
);
|
findUpSync('tsconfig.json', { cwd: options.configDir }),
|
||||||
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],
|
|
||||||
};
|
};
|
||||||
|
logger.info(`=> Using angular project with "tsConfig:${builderOptions.tsConfig}"`);
|
||||||
|
|
||||||
// We use cliCommonConfig plugins to serve static assets files.
|
return builderOptions;
|
||||||
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,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user