Skip to content

Commit 158ee9a

Browse files
agilgur5jaredpalmer
andcommitted
(types/refactor): be more specific than 'any' in build code (#401)
- 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>
1 parent a38041f commit 158ee9a

File tree

3 files changed

+145
-91
lines changed

3 files changed

+145
-91
lines changed

src/createBuildConfigs.ts

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import { RollupOptions, OutputOptions } from 'rollup';
2+
import * as fs from 'fs-extra';
3+
import { concatAllArray } from 'jpjs';
4+
5+
import { paths } from './constants';
6+
import { TsdxOptions, NormalizedOpts } from './types';
7+
8+
import { createRollupConfig } from './createRollupConfig';
9+
10+
// check for custom tsdx.config.js
11+
let tsdxConfig = {
12+
rollup(config: RollupOptions, _options: TsdxOptions): RollupOptions {
13+
return config;
14+
},
15+
};
16+
17+
if (fs.existsSync(paths.appConfig)) {
18+
tsdxConfig = require(paths.appConfig);
19+
}
20+
21+
export async function createBuildConfigs(
22+
opts: NormalizedOpts
23+
): Promise<Array<RollupOptions & { output: OutputOptions }>> {
24+
const allInputs = concatAllArray(
25+
opts.input.map((input: string) =>
26+
createAllFormats(opts, input).map(
27+
(options: TsdxOptions, index: number) => ({
28+
...options,
29+
// We want to know if this is the first run for each entryfile
30+
// for certain plugins (e.g. css)
31+
writeMeta: index === 0,
32+
})
33+
)
34+
)
35+
);
36+
37+
return await Promise.all(
38+
allInputs.map(async (options: TsdxOptions) => {
39+
// pass the full rollup config to tsdx.config.js override
40+
const config = await createRollupConfig(options);
41+
return tsdxConfig.rollup(config, options);
42+
})
43+
);
44+
}
45+
46+
function createAllFormats(
47+
opts: NormalizedOpts,
48+
input: string
49+
): [TsdxOptions, ...TsdxOptions[]] {
50+
return [
51+
opts.format.includes('cjs') && {
52+
...opts,
53+
format: 'cjs',
54+
env: 'development',
55+
input,
56+
},
57+
opts.format.includes('cjs') && {
58+
...opts,
59+
format: 'cjs',
60+
env: 'production',
61+
input,
62+
},
63+
opts.format.includes('esm') && { ...opts, format: 'esm', input },
64+
opts.format.includes('umd') && {
65+
...opts,
66+
format: 'umd',
67+
env: 'development',
68+
input,
69+
},
70+
opts.format.includes('umd') && {
71+
...opts,
72+
format: 'umd',
73+
env: 'production',
74+
input,
75+
},
76+
opts.format.includes('system') && {
77+
...opts,
78+
format: 'system',
79+
env: 'development',
80+
input,
81+
},
82+
opts.format.includes('system') && {
83+
...opts,
84+
format: 'system',
85+
env: 'production',
86+
input,
87+
},
88+
].filter(Boolean) as [TsdxOptions, ...TsdxOptions[]];
89+
}

src/index.ts

Lines changed: 19 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,21 @@ import shell from 'shelljs';
2525
import ora from 'ora';
2626
import { paths } from './constants';
2727
import * as Messages from './messages';
28-
import { createRollupConfig } from './createRollupConfig';
28+
import { createBuildConfigs } from './createBuildConfigs';
2929
import { createJestConfig } from './createJestConfig';
3030
import { createEslintConfig } from './createEslintConfig';
3131
import { resolveApp, safePackageName, clearConsole } from './utils';
3232
import { concatAllArray } from 'jpjs';
3333
import getInstallCmd from './getInstallCmd';
3434
import getInstallArgs from './getInstallArgs';
3535
import { Input, Select } from 'enquirer';
36-
import { PackageJson, TsdxOptions } from './types';
36+
import {
37+
PackageJson,
38+
WatchOpts,
39+
BuildOpts,
40+
ModuleFormat,
41+
NormalizedOpts,
42+
} from './types';
3743
import { createProgressEstimator } from './createProgressEstimator';
3844
import { templates } from './templates';
3945
import { composePackageJson } from './templates/utils';
@@ -47,17 +53,6 @@ try {
4753
appPackageJson = fs.readJSONSync(paths.appPackageJson);
4854
} catch (e) {}
4955

50-
// check for custom tsdx.config.js
51-
let tsdxConfig = {
52-
rollup(config: RollupOptions, _options: TsdxOptions): RollupOptions {
53-
return config;
54-
},
55-
};
56-
57-
if (fs.existsSync(paths.appConfig)) {
58-
tsdxConfig = require(paths.appConfig);
59-
}
60-
6156
export const isDir = (name: string) =>
6257
fs
6358
.stat(name)
@@ -80,8 +75,11 @@ async function jsOrTs(filename: string) {
8075
return resolveApp(`${filename}${extension}`);
8176
}
8277

83-
async function getInputs(entries: string[], source?: string) {
84-
let inputs: any[] = [];
78+
async function getInputs(
79+
entries?: string | string[],
80+
source?: string
81+
): Promise<string[]> {
82+
let inputs: string[] = [];
8583
let stub: any[] = [];
8684
stub
8785
.concat(
@@ -96,67 +94,6 @@ async function getInputs(entries: string[], source?: string) {
9694
return concatAllArray(inputs);
9795
}
9896

99-
async function createBuildConfigs(
100-
opts: any
101-
): Promise<Array<RollupOptions & { output: OutputOptions }>> {
102-
return await Promise.all(
103-
concatAllArray(
104-
opts.input.map((input: string) =>
105-
[
106-
opts.format.includes('cjs') && {
107-
...opts,
108-
format: 'cjs',
109-
env: 'development',
110-
input,
111-
},
112-
opts.format.includes('cjs') && {
113-
...opts,
114-
format: 'cjs',
115-
env: 'production',
116-
input,
117-
},
118-
opts.format.includes('esm') && { ...opts, format: 'esm', input },
119-
opts.format.includes('umd') && {
120-
...opts,
121-
format: 'umd',
122-
env: 'development',
123-
input,
124-
},
125-
opts.format.includes('umd') && {
126-
...opts,
127-
format: 'umd',
128-
env: 'production',
129-
input,
130-
},
131-
opts.format.includes('system') && {
132-
...opts,
133-
format: 'system',
134-
env: 'development',
135-
input,
136-
},
137-
opts.format.includes('system') && {
138-
...opts,
139-
format: 'system',
140-
env: 'production',
141-
input,
142-
},
143-
]
144-
.filter(Boolean)
145-
.map((options: TsdxOptions, index: number) => ({
146-
...options,
147-
// We want to know if this is the first run for each entryfile
148-
// for certain plugins (e.g. css)
149-
writeMeta: index === 0,
150-
}))
151-
)
152-
).map(async (options: TsdxOptions) => {
153-
// pass the full rollup config to tsdx.config.js override
154-
const config = await createRollupConfig(options);
155-
return tsdxConfig.rollup(config, options);
156-
})
157-
);
158-
}
159-
16097
async function moveTypes() {
16198
try {
16299
// Move the typescript types to the base of the ./dist folder
@@ -320,7 +257,7 @@ prog
320257
.describe('Rebuilds on any change')
321258
.option('--entry, -i', 'Entry module(s)')
322259
.example('watch --entry src/foo.tsx')
323-
.option('--target', 'Specify your target environment', 'web')
260+
.option('--target', 'Specify your target environment', 'browser')
324261
.example('watch --target node')
325262
.option('--name', 'Specify name exposed in UMD builds')
326263
.example('watch --name Foo')
@@ -346,7 +283,7 @@ prog
346283
.example('build --transpileOnly')
347284
.option('--extractErrors', 'Extract invariant errors to ./errors/codes.json.')
348285
.example('build --extractErrors')
349-
.action(async (dirtyOpts: any) => {
286+
.action(async (dirtyOpts: WatchOpts) => {
350287
const opts = await normalizeOpts(dirtyOpts);
351288
const buildConfigs = await createBuildConfigs(opts);
352289
if (!opts.noClean) {
@@ -438,7 +375,7 @@ prog
438375
.describe('Build your project once and exit')
439376
.option('--entry, -i', 'Entry module(s)')
440377
.example('build --entry src/foo.tsx')
441-
.option('--target', 'Specify your target environment', 'web')
378+
.option('--target', 'Specify your target environment', 'browser')
442379
.example('build --target node')
443380
.option('--name', 'Specify name exposed in UMD builds')
444381
.example('build --name Foo')
@@ -455,7 +392,7 @@ prog
455392
.example(
456393
'build --extractErrors=https://reactjs.org/docs/error-decoder.html?invariant='
457394
)
458-
.action(async (dirtyOpts: any) => {
395+
.action(async (dirtyOpts: BuildOpts) => {
459396
const opts = await normalizeOpts(dirtyOpts);
460397
const buildConfigs = await createBuildConfigs(opts);
461398
await cleanDistFolder();
@@ -491,7 +428,7 @@ prog
491428
}
492429
});
493430

494-
async function normalizeOpts(opts: any) {
431+
async function normalizeOpts(opts: WatchOpts): Promise<NormalizedOpts> {
495432
return {
496433
...opts,
497434
name: opts.name || appPackageJson.name,
@@ -501,7 +438,7 @@ async function normalizeOpts(opts: any) {
501438
return 'esm';
502439
}
503440
return format;
504-
}),
441+
}) as [ModuleFormat, ...ModuleFormat[]],
505442
};
506443
}
507444

src/types.ts

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,46 @@
1-
export interface TsdxOptions {
2-
// path to file
3-
input: string;
4-
// Name of package
5-
name: string;
1+
interface SharedOpts {
62
// JS target
73
target: 'node' | 'browser';
8-
// Module format
9-
format: 'cjs' | 'umd' | 'esm' | 'system';
10-
// Environment
11-
env: 'development' | 'production';
124
// Path to tsconfig file
135
tsconfig?: string;
146
// Is error extraction running?
157
extractErrors?: boolean;
8+
}
9+
10+
export type ModuleFormat = 'cjs' | 'umd' | 'esm' | 'system';
11+
12+
export interface BuildOpts extends SharedOpts {
13+
name?: string;
14+
entry?: string | string[];
15+
format: 'cjs,esm';
16+
target: 'browser';
17+
}
18+
19+
export interface WatchOpts extends BuildOpts {
20+
verbose?: boolean;
21+
noClean?: boolean;
22+
// callback hooks
23+
onFirstSuccess?: string;
24+
onSuccess?: string;
25+
onFailure?: string;
26+
}
27+
28+
export interface NormalizedOpts
29+
extends Omit<WatchOpts, 'name' | 'input' | 'format'> {
30+
name: string;
31+
input: string[];
32+
format: [ModuleFormat, ...ModuleFormat[]];
33+
}
34+
35+
export interface TsdxOptions extends SharedOpts {
36+
// Name of package
37+
name: string;
38+
// path to file
39+
input: string;
40+
// Environment
41+
env: 'development' | 'production';
42+
// Module format
43+
format: ModuleFormat;
1644
// Is minifying?
1745
minify?: boolean;
1846
// Is this the very first rollup config (and thus should one-off metadata be extracted)?

0 commit comments

Comments
 (0)