Skip to content

Commit

Permalink
refactor(core): improve typings of dev build and dev server
Browse files Browse the repository at this point in the history
  • Loading branch information
gaetanmaisse committed Oct 30, 2020
1 parent 269ba34 commit 26ffe19
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 26 deletions.
48 changes: 37 additions & 11 deletions lib/core/src/server/build-dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,32 @@ import prettyTime from 'pretty-hrtime';
import inquirer from 'inquirer';
import detectFreePort from 'detect-port';

import { Stats } from 'webpack';
import { storybookDevServer } from './dev-server';
import { getDevCli } from './cli';
import { DevCliOptions, getDevCli } from './cli';
import { resolvePathInStorybookCache } from './utils/resolve-path-in-sb-cache';
import { ReleaseNotesData, VersionCheck, PackageJson, LoadOptions } from './types';

const cache = Cache({
basePath: resolvePathInStorybookCache('dev-server'),
ns: 'storybook', // Optional. A grouping namespace for items.
});

const writeStats = async (name: string, stats: any) => {
const writeStats = async (name: string, stats: Stats) => {
await fs.writeFile(
resolvePathInStorybookCache(`public/${name}-stats.json`),
JSON.stringify(stats.toJson(), null, 2),
'utf8'
);
};

const getFreePort = (port: any) =>
const getFreePort = (port: number) =>
detectFreePort(port).catch((error) => {
logger.error(error);
process.exit(-1);
});

const updateCheck = async (version: string) => {
const updateCheck = async (version: string): Promise<VersionCheck> => {
let result;
const time = Date.now();
try {
Expand Down Expand Up @@ -63,7 +65,7 @@ const updateCheck = async (version: string) => {
// For this reason, we convert the actual version of the build here so that
// every place that relies on this data can reference the version of the
// release notes that we expect to use.
const getReleaseNotesVersion = (version: string) => {
const getReleaseNotesVersion = (version: string): string => {
const { major, minor } = semver.parse(version);
const { version: releaseNotesVersion } = semver.coerce(`${major}.${minor}`);
return releaseNotesVersion;
Expand All @@ -79,7 +81,10 @@ const getReleaseNotesFailedState = (version: string) => {

export const RELEASE_NOTES_CACHE_KEY = 'releaseNotesData';

export const getReleaseNotesData = async (currentVersionToParse: any, fileSystemCache: any) => {
export const getReleaseNotesData = async (
currentVersionToParse: string,
fileSystemCache: any
): Promise<ReleaseNotesData> => {
let result;
try {
const fromCache = await fileSystemCache.get('releaseNotesData', []);
Expand Down Expand Up @@ -119,7 +124,7 @@ export const getReleaseNotesData = async (currentVersionToParse: any, fileSystem
return result;
};

function createUpdateMessage(updateInfo: any, version: any) {
function createUpdateMessage(updateInfo: VersionCheck, version: string): string {
let updateMessage;

try {
Expand All @@ -143,7 +148,14 @@ function createUpdateMessage(updateInfo: any, version: any) {
return updateMessage;
}

function outputStartupInformation(options: any) {
function outputStartupInformation(options: {
updateInfo: VersionCheck;
version: string;
address: string;
networkAddress: string;
managerTotalTime: [number, number];
previewTotalTime: [number, number];
}) {
const {
updateInfo,
version,
Expand Down Expand Up @@ -206,7 +218,7 @@ function outputStartupInformation(options: any) {
);
}

async function outputStats(previewStats: any, managerStats: any) {
async function outputStats(previewStats: Stats, managerStats: Stats) {
if (previewStats) {
await writeStats('preview', previewStats);
}
Expand All @@ -216,7 +228,16 @@ async function outputStats(previewStats: any, managerStats: any) {
);
}

export async function buildDevStandalone(options: any) {
export async function buildDevStandalone(
options: DevCliOptions &
LoadOptions & {
packageJson: PackageJson;
ignorePreview: boolean;
docsMode: boolean;
configDir: string;
cache: any;
}
) {
try {
const { packageJson, versionUpdates, releaseNotes } = options;
const { version } = packageJson;
Expand Down Expand Up @@ -244,7 +265,9 @@ export async function buildDevStandalone(options: any) {

/* eslint-disable no-param-reassign */
options.port = port;
// @ts-ignore
options.versionCheck = updateInfo;
// @ts-ignore
options.releaseNotesData = releaseNotesData;
/* eslint-enable no-param-reassign */

Expand Down Expand Up @@ -307,7 +330,10 @@ export async function buildDevStandalone(options: any) {
}
}

export async function buildDev({ packageJson, ...loadOptions }: any) {
export async function buildDev({
packageJson,
...loadOptions
}: { packageJson: PackageJson } & LoadOptions) {
const cliOptions = await getDevCli(packageJson);

await buildDevStandalone({
Expand Down
18 changes: 14 additions & 4 deletions lib/core/src/server/dev-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import loadConfig from './config';
import loadManagerConfig from './manager/manager-config';
import { resolvePathInStorybookCache } from './utils/resolve-path-in-sb-cache';
import { getPrebuiltDir } from './utils/prebuilt-manager';
import { ManagerResult, PreviewResult } from './types';

const defaultFavIcon = require.resolve('./public/favicon.ico');
const dllPath = path.join(__dirname, '../../dll');
Expand Down Expand Up @@ -194,7 +195,7 @@ const startManager = async ({
outputDir,
configDir,
prebuiltDir,
}: any) => {
}: any): Promise<ManagerResult> => {
let managerConfig;
if (!prebuiltDir) {
// this is pretty slow
Expand Down Expand Up @@ -225,7 +226,9 @@ const startManager = async ({
}

if (!managerConfig) {
return { managerStats: {}, managerTotalTime: 0 };
// FIXME: This object containing default values should match ManagerResult
// @ts-ignore
return { managerStats: {}, managerTotalTime: 0 } as ManagerResult;
}

const compiler = webpack(managerConfig);
Expand Down Expand Up @@ -256,9 +259,16 @@ const startManager = async ({
return { managerStats, managerTotalTime: process.hrtime(startTime) };
};

const startPreview = async ({ startTime, options, configType, outputDir }: any) => {
const startPreview = async ({
startTime,
options,
configType,
outputDir,
}: any): Promise<PreviewResult> => {
if (options.ignorePreview) {
return { previewStats: {}, previewTotalTime: 0 };
// FIXME: This object containing default values should match PreviewResult
// @ts-ignore
return { previewStats: {}, previewTotalTime: 0 } as PreviewResult;
}

const previewConfig = await loadConfig({
Expand Down
6 changes: 3 additions & 3 deletions lib/core/src/server/manager/manager-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import { Configuration } from 'webpack';
import loadPresets from '../presets';
import loadCustomPresets from '../common/custom-presets';
import { typeScriptDefaults } from '../config/defaults';
import { Presets, PresetsOptions, StorybookConfigOptions } from '../types';
import { Presets, PresetsOptions, Ref, StorybookConfigOptions } from '../types';

export const getAutoRefs = async (options: { configDir: string }) => {
export const getAutoRefs = async (options: { configDir: string }): Promise<Ref[]> => {
const location = await findUp('package.json', { cwd: options.configDir });
const directory = path.dirname(location);

Expand Down Expand Up @@ -79,7 +79,7 @@ async function getManagerWebpackConfig(
const definedRefs = await presets.apply('refs', undefined, options);
const entries = await presets.apply('managerEntries', [], options);

const refs: Record<string, any> = {};
const refs: Record<string, Ref> = {};

if (autoRefs && autoRefs.length) {
autoRefs.forEach(({ id, url, title, version }) => {
Expand Down
6 changes: 5 additions & 1 deletion lib/core/src/server/manager/manager-preset.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { Configuration } from 'webpack';
import { loadManagerOrAddonsFile } from '../utils/load-manager-or-addons-file';
import createDevConfig from './manager-webpack.config';
import { ManagerWebpackOptions } from '../types';

export async function managerWebpack(_: Configuration, options: any): Promise<Configuration> {
export async function managerWebpack(
_: Configuration,
options: ManagerWebpackOptions
): Promise<Configuration> {
return createDevConfig(options);
}

Expand Down
59 changes: 53 additions & 6 deletions lib/core/src/server/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Configuration } from 'webpack';
import { Configuration, Stats } from 'webpack';
import { TransformOptions } from '@babel/core';
import { typeScriptDefaults } from './config/defaults';

Expand All @@ -7,14 +7,14 @@ export interface ManagerWebpackOptions {
configType?: string;
docsMode?: boolean;
entries: string[];
refs: any;
refs: Record<string, Ref>;
uiDll: boolean;
dll: any;
dll: boolean;
outputDir?: string;
cache: any;
cache: boolean;
previewUrl?: string;
versionCheck: any;
releaseNotesData: any;
versionCheck: VersionCheck;
releaseNotesData: ReleaseNotesData;
presets: any;
}

Expand Down Expand Up @@ -68,3 +68,50 @@ export type PresetConfig =
name: string;
options?: unknown;
};

export interface Ref {
id: string;
url: string;
title: string;
version: string;
type?: string;
}

export interface VersionCheck {
success: boolean;
data?: any;
error?: any;
time: number;
}

export interface ReleaseNotesData {
success: boolean;
currentVersion: string;
showOnFirstLaunch: boolean;
}

export interface PreviewResult {
previewStats: Stats;
previewTotalTime: [number, number];
}

export interface ManagerResult {
managerStats: Stats;
managerTotalTime: [number, number];
}

// TODO: this is a generic interface that we can share across multiple SB packages (like @storybook/cli)
export interface PackageJson {
name: string;
version: string;
dependencies?: Record<string, string>;
devDependencies?: Record<string, string>;
}

// TODO: This could be exported to the outside world and used in `options.ts` file of each `@storybook/APP`
// like it's described in docs/api/new-frameworks.md
export interface LoadOptions {
packageJson: PackageJson;
framework: string;
frameworkPresets: string[];
}
2 changes: 1 addition & 1 deletion lib/core/src/server/utils/prebuilt-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const getPrebuiltDir = async ({
}: {
configDir: string;
options: { managerCache?: boolean };
}) => {
}): Promise<string | false> => {
if (options.managerCache === false) return false;

const prebuiltDir = path.join(__dirname, '../../../prebuilt');
Expand Down

0 comments on commit 26ffe19

Please sign in to comment.