Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLI: Detect vite project, use vite builder automatically #17860

Merged
merged 5 commits into from
Apr 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion lib/cli/src/automigrate/fixes/builder-vite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ export const builderVite: Fix<BuilderViteOptions> = {
const builderName = typeof builder === 'string' ? builder : builder?.name;

if (builderName !== 'storybook-builder-vite') {
logger.info(`Not using community vite builder, skipping`);
return null;
}

Expand Down
3 changes: 3 additions & 0 deletions lib/cli/src/detect.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ jest.mock('./js-package-manager', () => ({

jest.mock('fs', () => ({
existsSync: jest.fn(),
stat: jest.fn(),
lstat: jest.fn(),
access: jest.fn(),
}));

jest.mock('path', () => ({
Expand Down
24 changes: 23 additions & 1 deletion lib/cli/src/detect.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import path from 'path';
import fs from 'fs';
import findUp from 'find-up';

import {
ProjectType,
Expand All @@ -9,10 +10,13 @@ import {
TemplateConfiguration,
TemplateMatcher,
unsupportedTemplate,
CoreBuilder,
} from './project_types';
import { getBowerJson } from './helpers';
import { getBowerJson, paddedLog } from './helpers';
import { PackageJson, readPackageJson } from './js-package-manager';

const viteConfigFiles = ['vite.config.ts', 'vite.config.js', 'vite.config.mjs'];

const hasDependency = (
packageJson: PackageJson,
name: string,
Expand Down Expand Up @@ -94,6 +98,24 @@ export function detectFrameworkPreset(packageJson = {}) {
return result ? result.preset : ProjectType.UNDETECTED;
}

/**
* Attempts to detect which builder to use, by searching for a vite config file. If one is found, the vite builder
* will be used, otherwise, webpack4 is the default.
*
* @returns CoreBuilder
*/
export function detectBuilder() {
const viteConfig = findUp.sync(viteConfigFiles);

if (viteConfig) {
paddedLog('Detected vite project, setting builder to @storybook/builder-vite');
return CoreBuilder.Vite;
}

// Fallback to webpack4
return CoreBuilder.Webpack4;
}

export function isStorybookInstalled(dependencies: PackageJson | false, force?: boolean) {
if (!dependencies) {
return false;
Expand Down
50 changes: 25 additions & 25 deletions lib/cli/src/initiate.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { UpdateNotifier, Package } from 'update-notifier';
import chalk from 'chalk';
import prompts from 'prompts';
import { detect, isStorybookInstalled, detectLanguage } from './detect';
import { installableProjectTypes, ProjectType, Builder, CoreBuilder } from './project_types';
import { detect, isStorybookInstalled, detectLanguage, detectBuilder } from './detect';
import { installableProjectTypes, ProjectType, Builder } from './project_types';
import { commandLog, codeLog, paddedLog } from './helpers';
import angularGenerator from './generators/ANGULAR';
import aureliaGenerator from './generators/AURELIA';
Expand Down Expand Up @@ -57,7 +57,7 @@ const installStorybook = (projectType: ProjectType, options: CommandOptions): Pr

const generatorOptions = {
language,
builder: options.builder || CoreBuilder.Webpack4,
builder: options.builder || detectBuilder(),
linkable: !!options.linkable,
commonJs: options.commonJs,
};
Expand Down Expand Up @@ -92,7 +92,7 @@ const installStorybook = (projectType: ProjectType, options: CommandOptions): Pr
case ProjectType.UPDATE_PACKAGE_ORGANIZATIONS:
return updateOrganisationsGenerator(packageManager, options.parser, npmOptions)
.then(() => null) // commandLog doesn't like to see output
.then(commandLog('Upgrading your project to the new Storybook packages.'))
.then(commandLog('Upgrading your project to the new Storybook packages.\n'))
.then(end);

case ProjectType.REACT_SCRIPTS:
Expand All @@ -102,7 +102,7 @@ const installStorybook = (projectType: ProjectType, options: CommandOptions): Pr

case ProjectType.REACT:
return reactGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding Storybook support to your "React" app'))
.then(commandLog('Adding Storybook support to your "React" app\n'))
.then(end);

case ProjectType.REACT_NATIVE: {
Expand All @@ -120,7 +120,7 @@ const installStorybook = (projectType: ProjectType, options: CommandOptions): Pr
]) as Promise<{ server: boolean }>)
)
.then(({ server }) => reactNativeGenerator(packageManager, npmOptions, server))
.then(commandLog('Adding Storybook support to your "React Native" app'))
.then(commandLog('Adding Storybook support to your "React Native" app\n'))
.then(end)
.then(() => {
logger.log(chalk.red('NOTE: installation is not 100% automated.'));
Expand All @@ -134,97 +134,97 @@ const installStorybook = (projectType: ProjectType, options: CommandOptions): Pr

case ProjectType.METEOR:
return meteorGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding Storybook support to your "Meteor" app'))
.then(commandLog('Adding Storybook support to your "Meteor" app\n'))
.then(end);

case ProjectType.WEBPACK_REACT:
return webpackReactGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding Storybook support to your "Webpack React" app'))
.then(commandLog('Adding Storybook support to your "Webpack React" app\n'))
.then(end);

case ProjectType.REACT_PROJECT:
return reactGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding Storybook support to your "React" library'))
.then(commandLog('Adding Storybook support to your "React" library\n'))
.then(end);

case ProjectType.SFC_VUE:
return sfcVueGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding Storybook support to your "Single File Components Vue" app'))
.then(commandLog('Adding Storybook support to your "Single File Components Vue" app\n'))
.then(end);

case ProjectType.VUE:
return vueGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding Storybook support to your "Vue" app'))
.then(commandLog('Adding Storybook support to your "Vue" app\n'))
.then(end);

case ProjectType.VUE3:
return vue3Generator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding Storybook support to your "Vue 3" app'))
.then(commandLog('Adding Storybook support to your "Vue 3" app\n'))
.then(end);

case ProjectType.ANGULAR:
return angularGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding Storybook support to your "Angular" app'))
.then(commandLog('Adding Storybook support to your "Angular" app\n'))
.then(end);

case ProjectType.EMBER:
return emberGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding Storybook support to your "Ember" app'))
.then(commandLog('Adding Storybook support to your "Ember" app\n'))
.then(end);

case ProjectType.MITHRIL:
return mithrilGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding Storybook support to your "Mithril" app'))
.then(commandLog('Adding Storybook support to your "Mithril" app\n'))
.then(end);

case ProjectType.MARIONETTE:
return marionetteGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding Storybook support to your "Marionette.js" app'))
.then(commandLog('Adding Storybook support to your "Marionette.js" app\n'))
.then(end);

case ProjectType.MARKO:
return markoGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding Storybook support to your "Marko" app'))
.then(commandLog('Adding Storybook support to your "Marko" app\n'))
.then(end);

case ProjectType.HTML:
return htmlGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding Storybook support to your "HTML" app'))
.then(commandLog('Adding Storybook support to your "HTML" app\n'))
.then(end);

case ProjectType.WEB_COMPONENTS:
return webComponentsGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding Storybook support to your "web components" app'))
.then(commandLog('Adding Storybook support to your "web components" app\n'))
.then(end);

case ProjectType.RIOT:
return riotGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding Storybook support to your "riot.js" app'))
.then(commandLog('Adding Storybook support to your "riot.js" app\n'))
.then(end);

case ProjectType.PREACT:
return preactGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding Storybook support to your "Preact" app'))
.then(commandLog('Adding Storybook support to your "Preact" app\n'))
.then(end);

case ProjectType.SVELTE:
return svelteGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding Storybook support to your "Svelte" app'))
.then(commandLog('Adding Storybook support to your "Svelte" app\n'))
.then(end);

case ProjectType.RAX:
return raxGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding Storybook support to your "Rax" app'))
.then(commandLog('Adding Storybook support to your "Rax" app\n'))
.then(end);

case ProjectType.AURELIA:
return aureliaGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding Storybook support to your "Aurelia" app'))
.then(commandLog('Adding Storybook support to your "Aurelia" app\n'))
.then(end);

case ProjectType.SERVER:
return serverGenerator(packageManager, npmOptions, generatorOptions)
.then(commandLog('Adding Storybook support to your "Server" app'))
.then(commandLog('Adding Storybook support to your "Server" app\n'))
.then(end);

case ProjectType.UNSUPPORTED:
Expand Down