-
Notifications
You must be signed in to change notification settings - Fork 70
/
build.js
92 lines (85 loc) · 2.65 KB
/
build.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import execa from 'execa';
import fs from 'fs';
import path from 'path';
import semver from 'semver';
import tmp from 'tmp-promise';
import yarnOrNpm, { hasYarn } from 'yarn-or-npm';
import { createTask, transitionTo } from '../lib/tasks';
import buildFailed from '../ui/messages/errors/buildFailed';
import { failed, initial, pending, skipped, success } from '../ui/tasks/build';
export const setSourceDir = async (ctx) => {
if (ctx.options.outputDir) {
ctx.sourceDir = ctx.options.outputDir;
} else if (semver.lt(ctx.storybook.version, '5.0.0')) {
// Storybook v4 doesn't support absolute paths like tmp.dir would yield
ctx.sourceDir = 'storybook-static';
} else {
const tmpDir = await tmp.dir({ unsafeCleanup: true, prefix: `chromatic-` });
ctx.sourceDir = tmpDir.path;
}
};
export const setSpawnParams = (ctx) => {
ctx.spawnParams = {
client: yarnOrNpm(),
platform: process.platform,
command: yarnOrNpm(),
clientArgs: ['run', '--silent'],
scriptArgs: [
ctx.options.buildScriptName,
hasYarn() ? '' : '--',
'--output-dir',
ctx.sourceDir,
].filter(Boolean),
spawnOptions: {
preferLocal: true,
localDir: path.resolve('node_modules/.bin'),
},
};
};
const timeoutAfter = (ms) =>
new Promise((resolve, reject) => setTimeout(reject, ms, new Error(`Operation timed out`)));
export const buildStorybook = async (ctx) => {
ctx.buildLogFile = path.resolve('./build-storybook.log');
const logFile = fs.createWriteStream(ctx.buildLogFile);
await new Promise((resolve, reject) => {
logFile.on('open', resolve);
logFile.on('error', reject);
});
try {
const { command, clientArgs, scriptArgs, spawnOptions } = ctx.spawnParams;
ctx.log.debug('Using spawnParams:', JSON.stringify(ctx.spawnParams, null, 2));
await Promise.race([
execa(command, [...clientArgs, ...scriptArgs], {
stdio: [null, logFile, logFile],
...spawnOptions,
}),
timeoutAfter(ctx.env.STORYBOOK_BUILD_TIMEOUT),
]);
} catch (e) {
const buildLog = fs.readFileSync(ctx.buildLogFile, 'utf8');
ctx.log.error(buildFailed(ctx, e, buildLog));
ctx.exitCode = 201;
ctx.userError = true;
throw new Error(failed(ctx).output);
} finally {
logFile.end();
}
};
export default createTask({
title: initial.title,
skip: async (ctx) => {
if (ctx.skip) return true;
if (ctx.options.storybookBuildDir) {
ctx.sourceDir = ctx.options.storybookBuildDir;
return skipped(ctx).output;
}
return false;
},
steps: [
setSourceDir,
setSpawnParams,
transitionTo(pending),
buildStorybook,
transitionTo(success, true),
],
});