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

Move builds to core #2937

Merged
merged 7 commits into from
Feb 7, 2018
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
7 changes: 0 additions & 7 deletions app/angular/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@
"babel-preset-stage-0": "^6.24.1",
"babel-runtime": "^6.23.0",
"case-sensitive-paths-webpack-plugin": "^2.0.0",
"chalk": "^2.1.0",
"commander": "^2.14.0",
"common-tags": "^1.7.2",
"configstore": "^3.1.0",
"core-js": "^2.4.1",
Expand Down Expand Up @@ -76,17 +74,12 @@
"request": "^2.81.0",
"rxjs": "^5.4.2",
"sass-loader": "^6.0.6",
"serve-favicon": "^2.4.3",
"shelljs": "^0.8.1",
"style-loader": "^0.20.1",
"ts-loader": "^2.2.2",
"uglifyjs-webpack-plugin": "^1.1.7",
"url-loader": "^0.6.2",
"util-deprecate": "^1.0.2",
"uuid": "^3.2.1",
"webpack": "^2.5.1 || ^3.0.0",
"webpack-dev-middleware": "^1.10.2",
"webpack-hot-middleware": "^2.18.0",
"zone.js": "^0.8.20"
},
"devDependencies": {
Expand Down
93 changes: 6 additions & 87 deletions app/angular/src/server/build.js
Original file line number Diff line number Diff line change
@@ -1,93 +1,12 @@
import '@storybook/core/env';

import webpack from 'webpack';
import program from 'commander';
import { buildStatic } from '@storybook/core/server';
import path from 'path';
import fs from 'fs';
import chalk from 'chalk';
import shelljs from 'shelljs';
import { logger } from '@storybook/node-logger';
import packageJson from '../../package.json';
import getBaseConfig from './config/webpack.config.prod';
import loadConfig from './config';
import { parseList, getEnvConfig } from './utils';

process.env.NODE_ENV = process.env.NODE_ENV || 'production';

program
.version(packageJson.version)
.option('-s, --static-dir <dir-names>', 'Directory where to load static files from', parseList)
.option('-o, --output-dir [dir-name]', 'Directory where to store built files')
.option('-c, --config-dir [dir-name]', 'Directory where to load Storybook configurations from')
.option('-w, --watch', 'Enable watch mode')
.option('-d, --db-path [db-file]', 'DEPRECATED!')
.option('--enable-db', 'DEPRECATED!')
.parse(process.argv);

logger.info(chalk.bold(`${packageJson.name} v${packageJson.version}\n`));

if (program.enableDb || program.dbPath) {
logger.error(
[
'Error: the experimental local database addon is no longer bundled with',
'react-storybook. Please remove these flags (-d,--db-path,--enable-db)',
'from the command or npm script and try again.',
].join(' ')
);
process.exit(1);
}

// The key is the field created in `program` variable for
// each command line argument. Value is the env variable.
getEnvConfig(program, {
staticDir: 'SBCONFIG_STATIC_DIR',
outputDir: 'SBCONFIG_OUTPUT_DIR',
configDir: 'SBCONFIG_CONFIG_DIR',
buildStatic({
packageJson,
getBaseConfig,
loadConfig,
defaultFavIcon: path.resolve(__dirname, 'public/favicon.ico'),
});

const configDir = program.configDir || './.storybook';
const outputDir = program.outputDir || './storybook-static';

// create output directory if not exists
shelljs.mkdir('-p', path.resolve(outputDir));
// clear the static dir
shelljs.rm('-rf', path.resolve(outputDir, 'static'));
shelljs.cp(path.resolve(__dirname, 'public/favicon.ico'), outputDir);

// Build the webpack configuration using the `baseConfig`
// custom `.babelrc` file and `webpack.config.js` files
// NOTE changes to env should be done before calling `getBaseConfig`
const config = loadConfig('PRODUCTION', getBaseConfig(configDir), configDir);
config.output.path = path.resolve(outputDir);

// copy all static files
if (program.staticDir) {
program.staticDir.forEach(dir => {
if (!fs.existsSync(dir)) {
logger.error(`Error: no such directory to load static files: ${dir}`);
process.exit(-1);
}
logger.info(`=> Copying static files from: ${dir}`);
shelljs.cp('-r', `${dir}/*`, outputDir);
});
}

// compile all resources with webpack and write them to the disk.
logger.info('Building storybook ...');
const webpackCb = (err, stats) => {
if (err || stats.hasErrors()) {
logger.error('Failed to build the storybook');
// eslint-disable-next-line no-unused-expressions
err && logger.error(err.message);
// eslint-disable-next-line no-unused-expressions
stats && stats.hasErrors() && stats.toJson().errors.forEach(e => logger.error(e));
process.exitCode = 1;
}
logger.info('Building storybook completed.');
};
const compiler = webpack(config);
if (program.watch) {
compiler.watch({}, webpackCb);
} else {
compiler.run(webpackCb);
}
2 changes: 1 addition & 1 deletion app/angular/src/server/config/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import Dotenv from 'dotenv-webpack';
import InterpolateHtmlPlugin from 'react-dev-utils/InterpolateHtmlPlugin';
import CaseSensitivePathsPlugin from 'case-sensitive-paths-webpack-plugin';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import { WatchMissingNodeModulesPlugin } from '@storybook/core/server';
import { managerPath } from '@storybook/core/client';
import WatchMissingNodeModulesPlugin from './WatchMissingNodeModulesPlugin';

import { includePaths, excludePaths, nodeModulesPaths, loadEnv, nodePaths } from './utils';
import babelLoaderConfig from './babel';
Expand Down
171 changes: 9 additions & 162 deletions app/angular/src/server/index.js
Original file line number Diff line number Diff line change
@@ -1,165 +1,12 @@
import '@storybook/core/env';

import express from 'express';
import https from 'https';
import favicon from 'serve-favicon';
import program from 'commander';
import { buildDev } from '@storybook/core/server';
import path from 'path';
import fs from 'fs';
import chalk from 'chalk';
import shelljs from 'shelljs';
import { logger } from '@storybook/node-logger';
import storybook, { webpackValid } from './middleware';
import packageJson from '../../package.json';
import { parseList, getEnvConfig } from './utils';

process.env.NODE_ENV = process.env.NODE_ENV || 'development';

program
.version(packageJson.version)
.option('-p, --port [number]', 'Port to run Storybook (Required)', parseInt)
.option('-h, --host [string]', 'Host to run Storybook')
.option('-s, --static-dir <dir-names>', 'Directory where to load static files from')
.option('-c, --config-dir [dir-name]', 'Directory where to load Storybook configurations from')
.option(
'--https',
'Serve Storybook over HTTPS. Note: You must provide your own certificate information.'
)
.option(
'--ssl-ca <ca>',
'Provide an SSL certificate authority. (Optional with --https, required if using a self-signed certificate)',
parseList
)
.option('--ssl-cert <cert>', 'Provide an SSL certificate. (Required with --https)')
.option('--ssl-key <key>', 'Provide an SSL key. (Required with --https)')
.option('--smoke-test', 'Exit after successful start')
.option('-d, --db-path [db-file]', 'DEPRECATED!')
.option('--enable-db', 'DEPRECATED!')
.parse(process.argv);

logger.info(chalk.bold(`${packageJson.name} v${packageJson.version}`) + chalk.reset('\n'));

if (program.enableDb || program.dbPath) {
logger.error(
[
'Error: the experimental local database addon is no longer bundled with',
'react-storybook. Please remove these flags (-d,--db-path,--enable-db)',
'from the command or npm script and try again.',
].join(' ')
);
process.exit(1);
}

// The key is the field created in `program` variable for
// each command line argument. Value is the env variable.
getEnvConfig(program, {
port: 'SBCONFIG_PORT',
host: 'SBCONFIG_HOSTNAME',
staticDir: 'SBCONFIG_STATIC_DIR',
configDir: 'SBCONFIG_CONFIG_DIR',
});

if (!program.port) {
logger.error('Error: port to run Storybook is required!\n');
program.help();
process.exit(-1);
}

// Used with `app.listen` below
const listenAddr = [program.port];

if (program.host) {
listenAddr.push(program.host);
}

const app = express();
let server = app;

if (program.https) {
if (!program.sslCert) {
logger.error('Error: --ssl-cert is required with --https');
process.exit(-1);
}
if (!program.sslKey) {
logger.error('Error: --ssl-key is required with --https');
process.exit(-1);
}

const sslOptions = {
ca: (program.sslCa || []).map(ca => fs.readFileSync(ca, 'utf-8')),
cert: fs.readFileSync(program.sslCert, 'utf-8'),
key: fs.readFileSync(program.sslKey, 'utf-8'),
};

server = https.createServer(sslOptions, app);
}

let hasCustomFavicon = false;

if (program.staticDir) {
program.staticDir = parseList(program.staticDir);
program.staticDir.forEach(dir => {
const staticPath = path.resolve(dir);
if (!fs.existsSync(staticPath)) {
logger.error(`Error: no such directory to load static files: ${staticPath}`);
process.exit(-1);
}
logger.info(`=> Loading static files from: ${staticPath} .`);
app.use(express.static(staticPath, { index: false }));

const faviconPath = path.resolve(staticPath, 'favicon.ico');
if (fs.existsSync(faviconPath)) {
hasCustomFavicon = true;
app.use(favicon(faviconPath));
}
});
}

if (!hasCustomFavicon) {
app.use(favicon(path.resolve(__dirname, 'public/favicon.ico')));
}

const configDir = program.configDir || './.storybook';

// The repository info is sent to the storybook while running on
// development mode so it'll be easier for tools to integrate.
const exec = cmd => shelljs.exec(cmd, { silent: true }).stdout.trim();
process.env.STORYBOOK_GIT_ORIGIN =
process.env.STORYBOOK_GIT_ORIGIN || exec('git remote get-url origin');
process.env.STORYBOOK_GIT_BRANCH =
process.env.STORYBOOK_GIT_BRANCH || exec('git symbolic-ref HEAD --short');

// NOTE changes to env should be done before calling `getBaseConfig`
// `getBaseConfig` function which is called inside the middleware
app.use(storybook(configDir));

let serverResolve = () => {};
let serverReject = () => {};
const serverListening = new Promise((resolve, reject) => {
serverResolve = resolve;
serverReject = reject;
});
server.listen(...listenAddr, error => {
if (error) {
serverReject(error);
} else {
serverResolve();
}
import getBaseConfig from './config/webpack.config';
import loadConfig from './config';

buildDev({
packageJson,
getBaseConfig,
loadConfig,
defaultFavIcon: path.resolve(__dirname, 'public/favicon.ico'),
});

Promise.all([webpackValid, serverListening])
.then(() => {
const address = `http://${program.host || 'localhost'}:${program.port}/`;
logger.info(`Storybook started on => ${chalk.cyan(address)}\n`);
if (program.smokeTest) {
process.exit(0);
}
})
.catch(error => {
if (error instanceof Error) {
logger.error(error);
}
if (program.smokeTest) {
process.exit(1);
}
});
26 changes: 0 additions & 26 deletions app/angular/src/server/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ import deprecate from 'util-deprecate';
const fallbackHeadUsage = deprecate(() => {},
'Usage of head.html has been deprecated. Please rename head.html to preview-head.html');

export function parseList(str) {
return str.split(',');
}

export function getPreviewHeadHtml(configDirPath) {
const headHtmlPath = path.resolve(configDirPath, 'preview-head.html');
const fallbackHtmlPath = path.resolve(configDirPath, 'head.html');
Expand All @@ -32,25 +28,3 @@ export function getManagerHeadHtml(configDirPath) {

return scriptHtml;
}

export function getEnvConfig(program, configEnv) {
Object.keys(configEnv).forEach(fieldName => {
const envVarName = configEnv[fieldName];
const envVarValue = process.env[envVarName];
if (envVarValue) {
program[fieldName] = envVarValue; // eslint-disable-line
}
});
}

export function getMiddleware(configDir) {
const middlewarePath = path.resolve(configDir, 'middleware.js');
if (fs.existsSync(middlewarePath)) {
let middlewareModule = require(middlewarePath); // eslint-disable-line
if (middlewareModule.__esModule) { // eslint-disable-line
middlewareModule = middlewareModule.default;
}
return middlewareModule;
}
return () => {};
}
10 changes: 2 additions & 8 deletions app/polymer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@
"babel-preset-stage-0": "^6.24.1",
"babel-runtime": "^6.26.0",
"case-sensitive-paths-webpack-plugin": "^2.1.1",
"chalk": "^2.3.0",
"commander": "^2.14.0",
"common-tags": "^1.4.0",
"configstore": "^3.1.1",
"copy-webpack-plugin": "^4.2.0",
Expand All @@ -73,15 +71,11 @@
"react-modal": "^3.1.12",
"redux": "^3.7.2",
"request": "^2.83.0",
"serve-favicon": "^2.4.5",
"shelljs": "^0.8.1",
"style-loader": "^0.20.1",
"uglifyjs-webpack-plugin": "^1.1.7",
"url-loader": "^0.6.2",
"util-deprecate": "^1.0.2",
"uuid": "^3.2.1",
"webpack": "^3.6.0",
"webpack-dev-middleware": "^1.12.0",
"webpack-hot-middleware": "^2.20.0"
"webpack": "^3.6.0"
},
"devDependencies": {
"babel-cli": "^6.26.0",
Expand Down
Loading