diff --git a/MIGRATION.md b/MIGRATION.md index 97d8b8b263e6..98bb17233c2a 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -214,6 +214,16 @@ If you require PostCSS support, please install `@storybook/addon-postcss` in you Further information is available at https://github.com/storybookjs/storybook/issues/12668 and https://github.com/storybookjs/storybook/pull/13669. +If you're not using Postcss and you don't want to see the warning, you can disable it by adding the following to your `.storybook/main.js`: + +```js +module.exports = { + features: { + postcss: false, + }, +}; +``` + #### Deprecated default PostCSS plugins When relying on the [implicit PostCSS loader](#deprecated-implicit-postcss-loader), it would also add [autoprefixer v9](https://www.npmjs.com/package/autoprefixer/v/9.8.6) and [postcss-flexbugs-fixes v4](https://www.npmjs.com/package/postcss-flexbugs-fixes/v/4.2.1) plugins to the `postcss-loader` configuration when you didn't have a PostCSS config file (such as `postcss.config.js`) within your project. diff --git a/examples/react-ts/main.ts b/examples/react-ts/main.ts index fdccb0981e20..3427cbbc2528 100644 --- a/examples/react-ts/main.ts +++ b/examples/react-ts/main.ts @@ -28,4 +28,7 @@ module.exports = { core: { builder: 'webpack4', }, + features: { + postcss: false, + }, } as StorybookConfig; diff --git a/lib/builder-webpack4/src/preview/base-webpack.config.ts b/lib/builder-webpack4/src/preview/base-webpack.config.ts index 72be4d951194..3b19c7c083e8 100644 --- a/lib/builder-webpack4/src/preview/base-webpack.config.ts +++ b/lib/builder-webpack4/src/preview/base-webpack.config.ts @@ -4,7 +4,7 @@ import path from 'path'; import { logger } from '@storybook/node-logger'; import deprecate from 'util-deprecate'; import dedent from 'ts-dedent'; -import type { BuilderOptions } from '@storybook/core-common'; +import type { BuilderOptions, LoadedPreset, Options } from '@storybook/core-common'; const warnImplicitPostcssPlugins = deprecate( () => ({ @@ -26,74 +26,83 @@ const warnImplicitPostcssPlugins = deprecate( ); const warnGetPostcssOptions = deprecate( - async () => { - const postcssConfigFiles = [ - '.postcssrc', - '.postcssrc.json', - '.postcssrc.yml', - '.postcssrc.js', - 'postcss.config.js', - ]; - // This is done naturally by newer postcss-loader (through cosmiconfig) - const customPostcssConfig = await findUp(postcssConfigFiles); - - if (customPostcssConfig) { - logger.info(`=> Using custom ${path.basename(customPostcssConfig)}`); - return { - config: customPostcssConfig, - }; - } - return warnImplicitPostcssPlugins; - }, + () => {}, dedent` Relying on the implicit PostCSS loader is deprecated and will be removed in Storybook 7.0. If you need PostCSS, include '@storybook/addon-postcss' in your '.storybook/main.js' file. See https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#deprecated-implicit-postcss-loader for details. - ` + ` ); -export async function createDefaultWebpackConfig( - storybookBaseConfig: any, - options: { presetsList: any[] } -) { +const getPostcssOptions = async () => { + const postcssConfigFiles = [ + '.postcssrc', + '.postcssrc.json', + '.postcssrc.yml', + '.postcssrc.js', + 'postcss.config.js', + ]; + // This is done naturally by newer postcss-loader (through cosmiconfig) + const customPostcssConfig = await findUp(postcssConfigFiles); + + if (customPostcssConfig) { + logger.info(`=> Using custom ${path.basename(customPostcssConfig)}`); + warnGetPostcssOptions(); + return { + config: customPostcssConfig, + }; + } + return warnImplicitPostcssPlugins(); +}; + +const presetName = (preset: LoadedPreset | string): string => + typeof preset === 'string' ? preset : preset.name; + +export async function createDefaultWebpackConfig(storybookBaseConfig: any, options: Options) { if ( options.presetsList.some((preset) => - /@storybook(\/|\\)preset-create-react-app/.test(preset.name || preset) + /@storybook(\/|\\)preset-create-react-app/.test(presetName(preset)) ) ) { return storybookBaseConfig; } const hasPostcssAddon = options.presetsList.some((preset) => - /@storybook(\/|\\)addon-postcss/.test(preset.name || preset) + /@storybook(\/|\\)addon-postcss/.test(presetName(preset)) ); + const features = await options.presets.apply<{ postcss?: boolean }>('features'); + let cssLoaders = {}; if (!hasPostcssAddon) { logger.info(`=> Using implicit CSS loaders`); + const use = [ + // TODO(blaine): Decide if we want to keep style-loader & css-loader in core + // Trying to apply style-loader or css-loader to files that already have been + // processed by them causes webpack to crash, so no one else can add similar + // loader configurations to the `.css` extension. + require.resolve('style-loader'), + { + loader: require.resolve('css-loader'), + options: { + importLoaders: 1, + }, + }, + + features?.postcss !== false + ? { + loader: require.resolve('postcss-loader'), + options: { + postcssOptions: await getPostcssOptions(), + }, + } + : null, + ]; cssLoaders = { test: /\.css$/, sideEffects: true, - use: [ - // TODO(blaine): Decide if we want to keep style-loader & css-loader in core - // Trying to apply style-loader or css-loader to files that already have been - // processed by them causes webpack to crash, so no one else can add similar - // loader configurations to the `.css` extension. - require.resolve('style-loader'), - { - loader: require.resolve('css-loader'), - options: { - importLoaders: 1, - }, - }, - { - loader: require.resolve('postcss-loader'), - options: { - postcssOptions: await warnGetPostcssOptions(), - }, - }, - ], + use: use.filter(Boolean), }; } diff --git a/lib/builder-webpack5/src/preview/base-webpack.config.ts b/lib/builder-webpack5/src/preview/base-webpack.config.ts index dc03b52acfaf..743b56a3f93b 100644 --- a/lib/builder-webpack5/src/preview/base-webpack.config.ts +++ b/lib/builder-webpack5/src/preview/base-webpack.config.ts @@ -1,5 +1,5 @@ import { logger } from '@storybook/node-logger'; -import type { Options, BuilderOptions } from '@storybook/core-common'; +import type { Options } from '@storybook/core-common'; import type { Configuration } from 'webpack'; export async function createDefaultWebpackConfig( diff --git a/lib/core-server/src/__snapshots__/vue-3-cli_preview-dev b/lib/core-server/src/__snapshots__/vue-3-cli_preview-dev index 0d160837f83e..de20b3b5b574 100644 --- a/lib/core-server/src/__snapshots__/vue-3-cli_preview-dev +++ b/lib/core-server/src/__snapshots__/vue-3-cli_preview-dev @@ -425,7 +425,13 @@ Object { Object { "loader": "NODE_MODULES/postcss-loader/dist/cjs.js", "options": Object { - "postcssOptions": [Function], + "postcssOptions": Object { + "config": false, + "plugins": Array [ + [Function], + [Function], + ], + }, }, }, ], diff --git a/lib/core-server/src/__snapshots__/vue-3-cli_preview-prod b/lib/core-server/src/__snapshots__/vue-3-cli_preview-prod index f31c305f1b0f..f3bb033f5d72 100644 --- a/lib/core-server/src/__snapshots__/vue-3-cli_preview-prod +++ b/lib/core-server/src/__snapshots__/vue-3-cli_preview-prod @@ -424,7 +424,13 @@ Object { Object { "loader": "NODE_MODULES/postcss-loader/dist/cjs.js", "options": Object { - "postcssOptions": [Function], + "postcssOptions": Object { + "config": false, + "plugins": Array [ + [Function], + [Function], + ], + }, }, }, ], diff --git a/lib/core-server/src/__snapshots__/web-components-kitchen-sink_preview-dev b/lib/core-server/src/__snapshots__/web-components-kitchen-sink_preview-dev index 1770ad27b183..f1a5112afea5 100644 --- a/lib/core-server/src/__snapshots__/web-components-kitchen-sink_preview-dev +++ b/lib/core-server/src/__snapshots__/web-components-kitchen-sink_preview-dev @@ -456,7 +456,13 @@ Object { Object { "loader": "NODE_MODULES/postcss-loader/dist/cjs.js", "options": Object { - "postcssOptions": [Function], + "postcssOptions": Object { + "config": false, + "plugins": Array [ + [Function], + [Function], + ], + }, }, }, ], diff --git a/lib/core-server/src/__snapshots__/web-components-kitchen-sink_preview-prod b/lib/core-server/src/__snapshots__/web-components-kitchen-sink_preview-prod index 113c43c2e08d..2dbe26c2109d 100644 --- a/lib/core-server/src/__snapshots__/web-components-kitchen-sink_preview-prod +++ b/lib/core-server/src/__snapshots__/web-components-kitchen-sink_preview-prod @@ -455,7 +455,13 @@ Object { Object { "loader": "NODE_MODULES/postcss-loader/dist/cjs.js", "options": Object { - "postcssOptions": [Function], + "postcssOptions": Object { + "config": false, + "plugins": Array [ + [Function], + [Function], + ], + }, }, }, ], diff --git a/lib/core-server/src/presets/common-preset.ts b/lib/core-server/src/presets/common-preset.ts index f81c06e1cf37..589dce355e8d 100644 --- a/lib/core-server/src/presets/common-preset.ts +++ b/lib/core-server/src/presets/common-preset.ts @@ -55,3 +55,8 @@ export const typescript = () => ({ savePropValueAsString: true, }, }); + +export const features = async (existing: Record) => ({ + ...existing, + postcss: true, +});