Skip to content

Commit

Permalink
(types/refactor): be more specific than 'any' in build code (#401)
Browse files Browse the repository at this point in the history
- add types for all options and use those types throughout the
  build/watch code
- fix some incorrect types in a few places that became more obvious
  or errors once types were added
- fix default target from 'web' (not an option) to 'browser'

- extract createBuildConfigs into a separate file as it's fairly long
  and has some relatively complex code
  - and refactor it a bit to make it a bit easier to read as well as
    easier to type (and type cast)

Co-authored-by: Jared Palmer <jaredloganpalmer@gmail.com>
  • Loading branch information
agilgur5 and jaredpalmer committed Dec 31, 2019
1 parent a38041f commit 158ee9a
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 91 deletions.
89 changes: 89 additions & 0 deletions src/createBuildConfigs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { RollupOptions, OutputOptions } from 'rollup';
import * as fs from 'fs-extra';
import { concatAllArray } from 'jpjs';

import { paths } from './constants';
import { TsdxOptions, NormalizedOpts } from './types';

import { createRollupConfig } from './createRollupConfig';

// check for custom tsdx.config.js
let tsdxConfig = {
rollup(config: RollupOptions, _options: TsdxOptions): RollupOptions {
return config;
},
};

if (fs.existsSync(paths.appConfig)) {
tsdxConfig = require(paths.appConfig);
}

export async function createBuildConfigs(
opts: NormalizedOpts
): Promise<Array<RollupOptions & { output: OutputOptions }>> {
const allInputs = concatAllArray(
opts.input.map((input: string) =>
createAllFormats(opts, input).map(
(options: TsdxOptions, index: number) => ({
...options,
// We want to know if this is the first run for each entryfile
// for certain plugins (e.g. css)
writeMeta: index === 0,
})
)
)
);

return await Promise.all(
allInputs.map(async (options: TsdxOptions) => {
// pass the full rollup config to tsdx.config.js override
const config = await createRollupConfig(options);
return tsdxConfig.rollup(config, options);
})
);
}

function createAllFormats(
opts: NormalizedOpts,
input: string
): [TsdxOptions, ...TsdxOptions[]] {
return [
opts.format.includes('cjs') && {
...opts,
format: 'cjs',
env: 'development',
input,
},
opts.format.includes('cjs') && {
...opts,
format: 'cjs',
env: 'production',
input,
},
opts.format.includes('esm') && { ...opts, format: 'esm', input },
opts.format.includes('umd') && {
...opts,
format: 'umd',
env: 'development',
input,
},
opts.format.includes('umd') && {
...opts,
format: 'umd',
env: 'production',
input,
},
opts.format.includes('system') && {
...opts,
format: 'system',
env: 'development',
input,
},
opts.format.includes('system') && {
...opts,
format: 'system',
env: 'production',
input,
},
].filter(Boolean) as [TsdxOptions, ...TsdxOptions[]];
}
101 changes: 19 additions & 82 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,21 @@ import shell from 'shelljs';
import ora from 'ora';
import { paths } from './constants';
import * as Messages from './messages';
import { createRollupConfig } from './createRollupConfig';
import { createBuildConfigs } from './createBuildConfigs';
import { createJestConfig } from './createJestConfig';
import { createEslintConfig } from './createEslintConfig';
import { resolveApp, safePackageName, clearConsole } from './utils';
import { concatAllArray } from 'jpjs';
import getInstallCmd from './getInstallCmd';
import getInstallArgs from './getInstallArgs';
import { Input, Select } from 'enquirer';
import { PackageJson, TsdxOptions } from './types';
import {
PackageJson,
WatchOpts,
BuildOpts,
ModuleFormat,
NormalizedOpts,
} from './types';
import { createProgressEstimator } from './createProgressEstimator';
import { templates } from './templates';
import { composePackageJson } from './templates/utils';
Expand All @@ -47,17 +53,6 @@ try {
appPackageJson = fs.readJSONSync(paths.appPackageJson);
} catch (e) {}

// check for custom tsdx.config.js
let tsdxConfig = {
rollup(config: RollupOptions, _options: TsdxOptions): RollupOptions {
return config;
},
};

if (fs.existsSync(paths.appConfig)) {
tsdxConfig = require(paths.appConfig);
}

export const isDir = (name: string) =>
fs
.stat(name)
Expand All @@ -80,8 +75,11 @@ async function jsOrTs(filename: string) {
return resolveApp(`${filename}${extension}`);
}

async function getInputs(entries: string[], source?: string) {
let inputs: any[] = [];
async function getInputs(
entries?: string | string[],
source?: string
): Promise<string[]> {
let inputs: string[] = [];
let stub: any[] = [];
stub
.concat(
Expand All @@ -96,67 +94,6 @@ async function getInputs(entries: string[], source?: string) {
return concatAllArray(inputs);
}

async function createBuildConfigs(
opts: any
): Promise<Array<RollupOptions & { output: OutputOptions }>> {
return await Promise.all(
concatAllArray(
opts.input.map((input: string) =>
[
opts.format.includes('cjs') && {
...opts,
format: 'cjs',
env: 'development',
input,
},
opts.format.includes('cjs') && {
...opts,
format: 'cjs',
env: 'production',
input,
},
opts.format.includes('esm') && { ...opts, format: 'esm', input },
opts.format.includes('umd') && {
...opts,
format: 'umd',
env: 'development',
input,
},
opts.format.includes('umd') && {
...opts,
format: 'umd',
env: 'production',
input,
},
opts.format.includes('system') && {
...opts,
format: 'system',
env: 'development',
input,
},
opts.format.includes('system') && {
...opts,
format: 'system',
env: 'production',
input,
},
]
.filter(Boolean)
.map((options: TsdxOptions, index: number) => ({
...options,
// We want to know if this is the first run for each entryfile
// for certain plugins (e.g. css)
writeMeta: index === 0,
}))
)
).map(async (options: TsdxOptions) => {
// pass the full rollup config to tsdx.config.js override
const config = await createRollupConfig(options);
return tsdxConfig.rollup(config, options);
})
);
}

async function moveTypes() {
try {
// Move the typescript types to the base of the ./dist folder
Expand Down Expand Up @@ -320,7 +257,7 @@ prog
.describe('Rebuilds on any change')
.option('--entry, -i', 'Entry module(s)')
.example('watch --entry src/foo.tsx')
.option('--target', 'Specify your target environment', 'web')
.option('--target', 'Specify your target environment', 'browser')
.example('watch --target node')
.option('--name', 'Specify name exposed in UMD builds')
.example('watch --name Foo')
Expand All @@ -346,7 +283,7 @@ prog
.example('build --transpileOnly')
.option('--extractErrors', 'Extract invariant errors to ./errors/codes.json.')
.example('build --extractErrors')
.action(async (dirtyOpts: any) => {
.action(async (dirtyOpts: WatchOpts) => {
const opts = await normalizeOpts(dirtyOpts);
const buildConfigs = await createBuildConfigs(opts);
if (!opts.noClean) {
Expand Down Expand Up @@ -438,7 +375,7 @@ prog
.describe('Build your project once and exit')
.option('--entry, -i', 'Entry module(s)')
.example('build --entry src/foo.tsx')
.option('--target', 'Specify your target environment', 'web')
.option('--target', 'Specify your target environment', 'browser')
.example('build --target node')
.option('--name', 'Specify name exposed in UMD builds')
.example('build --name Foo')
Expand All @@ -455,7 +392,7 @@ prog
.example(
'build --extractErrors=https://reactjs.org/docs/error-decoder.html?invariant='
)
.action(async (dirtyOpts: any) => {
.action(async (dirtyOpts: BuildOpts) => {
const opts = await normalizeOpts(dirtyOpts);
const buildConfigs = await createBuildConfigs(opts);
await cleanDistFolder();
Expand Down Expand Up @@ -491,7 +428,7 @@ prog
}
});

async function normalizeOpts(opts: any) {
async function normalizeOpts(opts: WatchOpts): Promise<NormalizedOpts> {
return {
...opts,
name: opts.name || appPackageJson.name,
Expand All @@ -501,7 +438,7 @@ async function normalizeOpts(opts: any) {
return 'esm';
}
return format;
}),
}) as [ModuleFormat, ...ModuleFormat[]],
};
}

Expand Down
46 changes: 37 additions & 9 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,46 @@
export interface TsdxOptions {
// path to file
input: string;
// Name of package
name: string;
interface SharedOpts {
// JS target
target: 'node' | 'browser';
// Module format
format: 'cjs' | 'umd' | 'esm' | 'system';
// Environment
env: 'development' | 'production';
// Path to tsconfig file
tsconfig?: string;
// Is error extraction running?
extractErrors?: boolean;
}

export type ModuleFormat = 'cjs' | 'umd' | 'esm' | 'system';

export interface BuildOpts extends SharedOpts {
name?: string;
entry?: string | string[];
format: 'cjs,esm';
target: 'browser';
}

export interface WatchOpts extends BuildOpts {
verbose?: boolean;
noClean?: boolean;
// callback hooks
onFirstSuccess?: string;
onSuccess?: string;
onFailure?: string;
}

export interface NormalizedOpts
extends Omit<WatchOpts, 'name' | 'input' | 'format'> {
name: string;
input: string[];
format: [ModuleFormat, ...ModuleFormat[]];
}

export interface TsdxOptions extends SharedOpts {
// Name of package
name: string;
// path to file
input: string;
// Environment
env: 'development' | 'production';
// Module format
format: ModuleFormat;
// Is minifying?
minify?: boolean;
// Is this the very first rollup config (and thus should one-off metadata be extracted)?
Expand Down

0 comments on commit 158ee9a

Please sign in to comment.