-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Rename addon-styling to addon-styling-webpack * Check for missing dependencies * Fix installs for theme decorators
- Loading branch information
Shaun Evening
authored
Aug 25, 2023
1 parent
7b154f1
commit 17ffdcd
Showing
24 changed files
with
348 additions
and
172 deletions.
There are no files selected for viewing
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
import dedent from 'dedent'; | ||
|
||
import { DEFAULT_CONFIGURATION_MAP, ConfigurationMap, ConfigurationKey } from '../types'; | ||
|
||
import { generateCssRules } from './css-rules'; | ||
import { generateSassRules } from './sass-rules'; | ||
import { generateLessRules } from './less-rules'; | ||
import { JsPackageManager } from '@storybook/cli'; | ||
|
||
const setConfigWithDefaults = (configMap: Partial<ConfigurationMap>): ConfigurationMap => ({ | ||
...DEFAULT_CONFIGURATION_MAP, | ||
...configMap, | ||
}); | ||
|
||
export const buildImports = (configMap: Partial<ConfigurationMap>): string => { | ||
const { vanillaExtract } = setConfigWithDefaults(configMap); | ||
|
||
return vanillaExtract | ||
? dedent` | ||
import { VanillaExtractPlugin } from "@vanilla-extract/webpack-plugin"; | ||
import MiniCssExtractPlugin from "mini-css-extract-plugin"; | ||
` | ||
: ''; | ||
}; | ||
|
||
const buildPluginsArray = ({ vanillaExtract }: ConfigurationMap): string => | ||
vanillaExtract | ||
? dedent` | ||
plugins: [new VanillaExtractPlugin(), new MiniCssExtractPlugin()],` | ||
: ''; | ||
|
||
export const buildAddonConfig = (configMap: Partial<ConfigurationMap>): string => { | ||
const config = setConfigWithDefaults(configMap); | ||
|
||
return dedent`({ | ||
name: "@storybook/addon-styling-webpack", | ||
options: {${buildPluginsArray(config)} | ||
rules: [${generateCssRules(config)}${generateSassRules(config)}${generateLessRules(config)}], | ||
} | ||
})`; | ||
}; | ||
|
||
const BASE_DEPENDENCIES = { | ||
'style-loader': '', | ||
'css-loader': '', | ||
}; | ||
|
||
const REQUIRED_DEPENDENCIES: Record<ConfigurationKey, Record<string, string>> = { | ||
cssModules: {}, | ||
sass: { | ||
'sass-loader': '', | ||
'resolve-url-loader': '', | ||
}, | ||
less: { | ||
'less-loader': '', | ||
}, | ||
postcss: { | ||
'postcss-loader': '', | ||
postcss: '', | ||
}, | ||
vanillaExtract: { | ||
'@vanilla-extract/webpack-plugin': '', | ||
'mini-css-extract-plugin': '', | ||
}, | ||
}; | ||
|
||
export const checkForMissingDependencies = async ( | ||
packageManager: JsPackageManager, | ||
configMap: Partial<ConfigurationMap>, | ||
extraDependencies: Record<string, string> = {}, | ||
): Promise<Record<string, string>> => { | ||
const configured = Object.entries(configMap) | ||
.filter(([key, isUsed]) => isUsed) | ||
.map(([key]) => key) as ConfigurationKey[]; | ||
|
||
const dependenciesToCheck = configured.reduce((deps, key) => ({ ...deps, ...REQUIRED_DEPENDENCIES[key] }), { | ||
...BASE_DEPENDENCIES, | ||
...extraDependencies, | ||
}); | ||
|
||
const userDependencies = await packageManager.getAllDependencies(); | ||
|
||
const missingDependencies = Object.entries(dependenciesToCheck).reduce( | ||
(missing, [dependency, version]) => { | ||
if (!userDependencies[dependency]) { | ||
return { ...missing, [dependency]: version }; | ||
} | ||
|
||
return missing; | ||
}, | ||
{} as Record<string, string>, | ||
); | ||
|
||
return missingDependencies; | ||
}; |
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { logger, colors } from '@storybook/node-logger'; | ||
import dedent from 'dedent'; | ||
import prompt from 'prompts'; | ||
|
||
import { ConfigSummary, printError, printWarning } from '../../utils/output.utils'; | ||
|
||
const printUnsupportedBuilderError = () => { | ||
printError( | ||
'Unsupported builder', | ||
dedent`"${colors.green.bold('@storybook/addon-styling-webpack')}" is for webpack projects only. | ||
Please remove it from your project to avoid unneeded dependencies.`, | ||
); | ||
}; | ||
|
||
export const Errors = { | ||
unsupportedBuilder: printUnsupportedBuilderError, | ||
}; | ||
|
||
export const askToInstallMissingDependencies = async ( | ||
missingDependencies: Record<string, string>, | ||
): Promise<boolean> => { | ||
printWarning( | ||
'💬 Missing dependencies', | ||
`I noticed that you're missing some dependencies for this configuration. | ||
Would you like me to install the following dependencies for you? | ||
${Object.keys(missingDependencies) | ||
.map((dep) => ` - ${colors.blue(dep)}`) | ||
.join('\n')}`, | ||
); | ||
|
||
const { installDependencies } = await prompt( | ||
{ | ||
type: 'confirm', | ||
name: 'installDependencies', | ||
message: 'Install missing dependencies?', | ||
initial: true, | ||
}, | ||
{ onCancel: () => process.exit(0) }, | ||
); | ||
logger.line(1); | ||
|
||
return installDependencies; | ||
}; | ||
|
||
export const buildSummary = (summary: ConfigSummary) => | ||
`${ | ||
summary.strategy === 'custom' | ||
? "I configured Storybook's Webpack as you asked!" | ||
: `"${colors.blue.bold(summary.strategy)}" has been configured and will now work in your stories!` | ||
} | ||
${colors.purple.bold('What I did:')} | ||
${summary.changed.map((change) => ` - ${change}`).join('\n')} | ||
${colors.purple.bold('Next steps:')} | ||
${summary.nextSteps.map((step) => ` - ${step}`).join('\n')}`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
82 changes: 82 additions & 0 deletions
82
src/@storybook/addon-styling-webpack/strategies/tailwind/tailwind.strategy.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import { logger, colors } from '@storybook/node-logger'; | ||
import prompt from 'prompts'; | ||
|
||
import { addImports, createNode } from '../../../../utils/ast.utils'; | ||
|
||
import { AddonStylingConfigurationStrategy, CONFIGURATION_STRATEGY_KEYS } from '../../types'; | ||
import { buildAddonConfig, checkForMissingDependencies } from '../../configure'; | ||
import { ChangeSummary } from 'src/utils/strategy.utils'; | ||
import { printWarning } from 'src/utils/output.utils'; | ||
import { askToInstallMissingDependencies } from '../../helpers'; | ||
|
||
const projectHasTailwind = (deps: Record<string, string>) => Boolean(deps['tailwindcss']) && Boolean(deps['postcss']); | ||
|
||
export const tailwindStrategy: AddonStylingConfigurationStrategy = { | ||
name: CONFIGURATION_STRATEGY_KEYS.TAILWIND, | ||
predicate: projectHasTailwind, | ||
main: async (mainConfig, meta) => { | ||
const summary: ChangeSummary = { | ||
changed: [], | ||
nextSteps: [], | ||
}; | ||
|
||
const configMap = { | ||
postcss: true, | ||
sass: false, | ||
less: false, | ||
vanillaExtract: false, | ||
cssModules: false, | ||
}; | ||
|
||
const [addonConfigNode] = createNode(buildAddonConfig(configMap)); | ||
|
||
mainConfig.appendNodeToArray(['addons'], addonConfigNode.expression); | ||
|
||
summary.changed.push(`Configured ${colors.blue.bold('PostCSS')} for ${colors.blue.bold('Webpack')}`); | ||
|
||
const missingDependencies = await checkForMissingDependencies(meta.packageManager, configMap); | ||
|
||
if (Object.keys(missingDependencies).length > 0) { | ||
const installDependencies = await askToInstallMissingDependencies(missingDependencies); | ||
|
||
if (installDependencies) { | ||
await meta.packageManager.addDependencies( | ||
{ installAsDevDependencies: true }, | ||
Object.entries(missingDependencies).map(([name, version]) => | ||
version === '' ? name : `${name}@${version}`, | ||
), | ||
); | ||
|
||
summary.changed.push(`Installed dependencies for configuration`); | ||
} else { | ||
summary.nextSteps.push( | ||
`Install ${colors.blue.bold( | ||
Object.keys(missingDependencies).join(', '), | ||
)} to complete the configuration`, | ||
); | ||
} | ||
} | ||
|
||
return summary; | ||
}, | ||
preview: async (previewConfig, meta) => { | ||
const { importPath } = await prompt( | ||
{ | ||
type: 'text', | ||
name: 'importPath', | ||
message: 'Where is your global CSS file? (relative to the .storybook folder)', | ||
initial: '../src/tailwind.css', | ||
}, | ||
{ onCancel: () => process.exit(1) }, | ||
); | ||
|
||
const globalCssImport = createNode(`import '${importPath}';`); | ||
|
||
addImports(previewConfig._ast, globalCssImport); | ||
|
||
return { | ||
changed: [`Imported your global CSS into ${colors.blue.bold(previewConfig.fileName)}`], | ||
nextSteps: [], | ||
}; | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.