storybook/scripts/build-package.js
2020-05-09 11:34:50 +02:00

187 lines
5.3 KiB
JavaScript

#!/usr/bin/env node
/* eslint-disable global-require */
const { resolve } = require('path');
const terminalSize = require('window-size');
const { checkDependenciesAndRun, spawn } = require('./utils/cli-utils');
const getStorybookPackages = () => {
const listCommand = spawn(`lerna list`, {
stdio: 'pipe',
});
const packages = listCommand.output
.toString()
.match(/@storybook\/(.)*/g)
.sort();
return packages;
};
function run() {
const inquirer = require('inquirer');
const program = require('commander');
const chalk = require('chalk');
const log = require('npmlog');
log.heading = 'storybook';
const prefix = 'build';
log.addLevel('aborted', 3001, { fg: 'red', bold: true });
const packages = getStorybookPackages();
const packageTasks = packages
.map((package) => {
return {
name: package,
suffix: package.replace('@storybook/', ''),
defaultValue: false,
helpText: `build only the ${package} package`,
};
})
.reduce((acc, next) => {
acc[next.name] = next;
return acc;
}, {});
const tasks = {
watch: {
name: `watch`,
defaultValue: false,
suffix: '--watch',
helpText: 'build on watch mode',
},
...packageTasks,
};
const groups = {
'mode (leave unselected if you just want to build)': ['watch'],
packages,
};
const main = program.version('5.0.0').option('--all', `build everything ${chalk.gray('(all)')}`);
Object.keys(tasks)
.reduce((acc, key) => acc.option(tasks[key].suffix, tasks[key].helpText), main)
.parse(process.argv);
Object.keys(tasks).forEach((key) => {
// checks if a flag is passed e.g. yarn build --@storybook/addon-docs --watch
const containsFlag = program.rawArgs.includes(tasks[key].suffix);
tasks[key].value = containsFlag || program.all;
});
const createSeparator = (input) => `- ${input}${' ---------'.substr(0, 12)}`;
const choices = Object.values(groups)
.map((l) =>
l.map((key) => ({
name: (tasks[key] && tasks[key].name) || key,
checked: (tasks[key] && tasks[key].defaultValue) || false,
}))
)
.reduce(
(acc, i, k) =>
acc.concat(new inquirer.Separator(createSeparator(Object.keys(groups)[k]))).concat(i),
[]
);
let selection;
let watchMode = false;
if (
!Object.keys(tasks)
.map((key) => tasks[key].value)
.filter(Boolean).length
) {
const ui = new inquirer.ui.BottomBar();
ui.log.write(
chalk.yellow(
'You can also run directly with package name like `yarn build core`, or `yarn build --all` for all packages!'
)
);
selection = inquirer
.prompt([
{
type: 'checkbox',
message: 'Select the packages to build',
name: 'todo',
pageSize: terminalSize.height - 3, // 3 lines for extra info
choices,
},
])
.then(({ todo }) => {
watchMode = todo.includes('watch');
return todo
.filter((name) => name !== 'watch') // remove watch option as it served its purpose
.map((name) => tasks[Object.keys(tasks).find((i) => tasks[i].name === name)]);
});
} else {
// hits here when running yarn build --packagename
watchMode = process.argv.includes('--watch');
selection = Promise.resolve(
Object.keys(tasks)
.map((key) => tasks[key])
.filter((item) => item.value === true)
);
}
selection
.then((list) => {
if (list.length === 0) {
log.warn(prefix, 'Nothing to build!');
} else {
const packageNames = list
// filters out watch command if --watch is used
.filter((key) => key.name !== 'watch')
.map((key) => key.suffix)
.filter(Boolean);
const glob =
packageNames.length > 1
? `@storybook/{${packageNames.join(',')}}`
: `@storybook/${packageNames[0]}`;
if (watchMode) {
const runWatchMode = () => {
const baseWatchCommand = `lerna exec --scope "${glob}" -- cross-env-shell node ${resolve(
__dirname
)}`;
const watchTsc = `${baseWatchCommand}/utils/watch-tsc.js`;
const watchBabel = `${baseWatchCommand}/utils/watch-babel.js`;
const command = `concurrently --kill-others "${watchTsc}" "${watchBabel}"`;
spawn(command);
};
if (packageNames.length < 5) {
runWatchMode();
} else {
inquirer
.prompt([
{
type: 'confirm',
message:
'You selected a lot of packages on watch mode. This is a very expensive action and might slow your computer down. Do you want to continue?',
name: 'confirmation',
},
])
.then(({ confirmation }) => {
if (confirmation === true) {
runWatchMode();
}
});
}
} else {
spawn(`lerna run prepare --scope "${glob}"`);
}
process.stdout.write('\x07');
}
})
.catch((e) => {
log.aborted(prefix, chalk.red(e.message));
log.silly(prefix, e);
process.exit(1);
});
}
checkDependenciesAndRun(run);