Skip to content

Commit 1e71d50

Browse files
authored
clean: remove ConsoleContext entirely by using buildStart (ezolenko#414)
- the only reason that `ConsoleContext` was still used was because the `options` hook doesn't support certain context functions like `this.error` / `this.warn` etc - but `buildStart` does! so we can just move pretty much everything into `buildStart` instead - didn't move setting `rollupOptions` because that value gets hashed and the value in `buildStart` is different, as it is after all plugins' `options` hooks have ran - this way we don't need `ConsoleContext` what-so-ever and so can remove it entirely! - as well as `IContext`, its tests, etc - use `this.error` instead of `throw`ing errors in `parse-tsconfig` as it exists now - couldn't in the `options` hook, can in `buildStart` - this also ensure we don't have all the `rpt2: ` prefixes ever missing again - c.f. ff88951, 0628482 - refactor `parse-tsconfig.spec` to account for this change - c.f. Rollup hooks docs: https://rollupjs.org/guide/en/#options, https://rollupjs.org/guide/en/#buildstart
1 parent 79053fe commit 1e71d50

9 files changed

+57
-132
lines changed

__tests__/context.spec.ts

+1-45
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,14 @@
11
import { jest, test, expect } from "@jest/globals";
22

33
import { makeContext } from "./fixtures/context";
4-
import { ConsoleContext, RollupContext } from "../src/context";
4+
import { RollupContext } from "../src/context";
55

66
(global as any).console = {
77
warn: jest.fn(),
88
log: jest.fn(),
99
info: jest.fn(),
1010
};
1111

12-
test("ConsoleContext", () => {
13-
const proxy = new ConsoleContext(6, "=>");
14-
15-
proxy.warn("test");
16-
expect(console.log).toHaveBeenLastCalledWith("=>test");
17-
18-
proxy.error("test2");
19-
expect(console.log).toHaveBeenLastCalledWith("=>test2");
20-
21-
proxy.info("test3");
22-
expect(console.log).toHaveBeenLastCalledWith("=>test3");
23-
24-
proxy.debug("test4");
25-
expect(console.log).toHaveBeenLastCalledWith("=>test4");
26-
27-
proxy.warn(() => "ftest");
28-
expect(console.log).toHaveBeenLastCalledWith("=>ftest");
29-
30-
proxy.error(() => "ftest2");
31-
expect(console.log).toHaveBeenLastCalledWith("=>ftest2");
32-
33-
proxy.info(() => "ftest3");
34-
expect(console.log).toHaveBeenLastCalledWith("=>ftest3");
35-
36-
proxy.debug(() => "ftest4");
37-
expect(console.log).toHaveBeenLastCalledWith("=>ftest4");
38-
});
39-
40-
test("ConsoleContext 0 verbosity", () => {
41-
const proxy = new ConsoleContext(-100);
42-
43-
proxy.warn("no-test");
44-
expect(console.log).not.toHaveBeenLastCalledWith("no-test");
45-
46-
proxy.info("no-test2");
47-
expect(console.log).not.toHaveBeenLastCalledWith("no-test2");
48-
49-
proxy.debug("no-test3");
50-
expect(console.log).not.toHaveBeenLastCalledWith("no-test3");
51-
52-
proxy.error("no-test4");
53-
expect(console.log).not.toHaveBeenLastCalledWith("no-test4");
54-
});
55-
5612
test("RollupContext", () => {
5713
const innerContext = makeContext();
5814
const context = new RollupContext(5, false, innerContext);

__tests__/fixtures/context.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { jest } from "@jest/globals";
22
import { PluginContext } from "rollup";
33

4-
import { IContext } from "../../src/context";
4+
import { RollupContext } from "../../src/context";
55

66
// if given a function, make sure to call it (for code coverage etc)
77
function returnText (message: string | (() => string)) {
@@ -11,11 +11,11 @@ function returnText (message: string | (() => string)) {
1111
return message();
1212
}
1313

14-
export function makeContext(): PluginContext & IContext {
14+
export function makeContext(): PluginContext & RollupContext {
1515
return {
1616
error: jest.fn(returnText),
1717
warn: jest.fn(returnText),
1818
info: jest.fn(returnText),
1919
debug: jest.fn(returnText),
20-
} as unknown as PluginContext & IContext;
20+
} as unknown as PluginContext & RollupContext;
2121
};

__tests__/parse-tsconfig.spec.ts

+27-11
Original file line numberDiff line numberDiff line change
@@ -11,41 +11,57 @@ const local = (x: string) => normalize(path.resolve(__dirname, x));
1111
const defaultOpts = makeOptions("", "");
1212

1313
test("parseTsConfig", () => {
14-
expect(() => parseTsConfig(makeContext(), defaultOpts)).not.toThrow();
14+
const context = makeContext();
15+
16+
parseTsConfig(context, defaultOpts);
17+
18+
expect(context.error).not.toBeCalled();
1519
});
1620

1721
test("parseTsConfig - incompatible module", () => {
18-
expect(() => parseTsConfig(makeContext(), {
22+
const context = makeContext();
23+
24+
parseTsConfig(context, {
1925
...defaultOpts,
2026
tsconfigOverride: { compilerOptions: { module: "none" } },
21-
})).toThrow("Incompatible tsconfig option. Module resolves to 'None'. This is incompatible with Rollup, please use");
27+
});
28+
29+
expect(context.error).toHaveBeenLastCalledWith(expect.stringContaining("Incompatible tsconfig option. Module resolves to 'None'. This is incompatible with Rollup, please use"));
2230
});
2331

2432
test("parseTsConfig - tsconfig errors", () => {
2533
const context = makeContext();
2634

27-
// should not throw when the tsconfig is buggy, but should still print an error (below)
28-
expect(() => parseTsConfig(context, {
35+
parseTsConfig(context, {
2936
...defaultOpts,
3037
tsconfigOverride: {
3138
include: "should-be-an-array",
3239
},
33-
})).not.toThrow();
40+
});
41+
3442
expect(context.error).toHaveBeenLastCalledWith(expect.stringContaining("Compiler option 'include' requires a value of type Array"));
3543
});
3644

3745
test("parseTsConfig - failed to open", () => {
38-
expect(() => parseTsConfig(makeContext(), {
46+
const context = makeContext();
47+
const nonExistentTsConfig = "non-existent-tsconfig";
48+
49+
parseTsConfig(context, {
3950
...defaultOpts,
40-
tsconfig: "non-existent-tsconfig",
41-
})).toThrow("rpt2: failed to open 'non-existent-tsconfig'");
51+
tsconfig: nonExistentTsConfig,
52+
})
53+
54+
expect(context.error).toHaveBeenLastCalledWith(expect.stringContaining(`failed to open '${nonExistentTsConfig}`));
4255
});
4356

4457
test("parseTsConfig - failed to parse", () => {
58+
const context = makeContext();
4559
const notTsConfigPath = local("fixtures/options.ts"); // a TS file should fail to parse
4660

47-
expect(() => parseTsConfig(makeContext(), {
61+
parseTsConfig(context, {
4862
...defaultOpts,
4963
tsconfig: notTsConfigPath,
50-
})).toThrow(`rpt2: failed to parse '${notTsConfigPath}'`);
64+
})
65+
66+
expect(context.error).toHaveBeenLastCalledWith(expect.stringContaining(`failed to parse '${notTsConfigPath}'`));
5167
});

src/context.ts

+2-48
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,5 @@
11
import { PluginContext } from "rollup";
22

3-
export interface IContext
4-
{
5-
warn(message: string | (() => string)): void;
6-
error(message: string | (() => string)): void;
7-
info(message: string | (() => string)): void;
8-
debug(message: string | (() => string)): void;
9-
}
10-
113
export enum VerbosityLevel
124
{
135
Error = 0,
@@ -20,46 +12,8 @@ function getText (message: string | (() => string)): string {
2012
return typeof message === "string" ? message : message();
2113
}
2214

23-
/* tslint:disable:max-classes-per-file -- generally a good rule to follow, but these two classes could basically be one */
24-
25-
/** mainly to be used in options hook, but can be used in other hooks too */
26-
export class ConsoleContext implements IContext
27-
{
28-
constructor(private verbosity: VerbosityLevel, private prefix: string = "")
29-
{
30-
}
31-
32-
public warn(message: string | (() => string)): void
33-
{
34-
if (this.verbosity < VerbosityLevel.Warning)
35-
return;
36-
console.log(`${this.prefix}${getText(message)}`);
37-
}
38-
39-
public error(message: string | (() => string)): void
40-
{
41-
if (this.verbosity < VerbosityLevel.Error)
42-
return;
43-
console.log(`${this.prefix}${getText(message)}`);
44-
}
45-
46-
public info(message: string | (() => string)): void
47-
{
48-
if (this.verbosity < VerbosityLevel.Info)
49-
return;
50-
console.log(`${this.prefix}${getText(message)}`);
51-
}
52-
53-
public debug(message: string | (() => string)): void
54-
{
55-
if (this.verbosity < VerbosityLevel.Debug)
56-
return;
57-
console.log(`${this.prefix}${getText(message)}`);
58-
}
59-
}
60-
6115
/** cannot be used in options hook (which does not have this.warn and this.error), but can be in other hooks */
62-
export class RollupContext implements IContext
16+
export class RollupContext
6317
{
6418
constructor(private verbosity: VerbosityLevel, private bail: boolean, private context: PluginContext, private prefix: string = "")
6519
{
@@ -72,7 +26,7 @@ export class RollupContext implements IContext
7226
this.context.warn(`${getText(message)}`);
7327
}
7428

75-
public error(message: string | (() => string)): void
29+
public error(message: string | (() => string)): void | never
7630
{
7731
if (this.verbosity < VerbosityLevel.Error)
7832
return;

src/get-options-overrides.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { createFilter as createRollupFilter, normalizePath as normalize } from "
44

55
import { tsModule } from "./tsproxy";
66
import { IOptions } from "./ioptions";
7-
import { IContext } from "./context";
7+
import { RollupContext } from "./context";
88

99
export function getOptionsOverrides({ useTsconfigDeclarationDir, cacheRoot }: IOptions, preParsedTsconfig?: tsTypes.ParsedCommandLine): tsTypes.CompilerOptions
1010
{
@@ -51,7 +51,7 @@ function expandIncludeWithDirs(include: string | string[], dirs: string[])
5151
return newDirs;
5252
}
5353

54-
export function createFilter(context: IContext, pluginOptions: IOptions, parsedConfig: tsTypes.ParsedCommandLine)
54+
export function createFilter(context: RollupContext, pluginOptions: IOptions, parsedConfig: tsTypes.ParsedCommandLine)
5555
{
5656
let included = pluginOptions.include;
5757
let excluded = pluginOptions.exclude;

src/index.ts

+13-14
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { normalizePath as normalize } from "@rollup/pluginutils";
55
import { blue, red, yellow, green } from "colors/safe";
66
import findCacheDir from "find-cache-dir";
77

8-
import { ConsoleContext, RollupContext, IContext, VerbosityLevel } from "./context";
8+
import { RollupContext, VerbosityLevel } from "./context";
99
import { LanguageServiceHost } from "./host";
1010
import { TsCache, convertDiagnostic, convertEmitOutput, getAllReferences, ICode } from "./tscache";
1111
import { tsModule, setTypescriptModule } from "./tsproxy";
@@ -24,7 +24,7 @@ const typescript: PluginImpl<RPT2Options> = (options) =>
2424
let watchMode = false;
2525
let generateRound = 0;
2626
let rollupOptions: InputOptions;
27-
let context: ConsoleContext;
27+
let context: RollupContext;
2828
let filter: any;
2929
let parsedConfig: tsTypes.ParsedCommandLine;
3030
let tsConfigPath: string | undefined;
@@ -54,7 +54,7 @@ const typescript: PluginImpl<RPT2Options> = (options) =>
5454
}));
5555
}
5656

57-
const typecheckFile = (id: string, snapshot: tsTypes.IScriptSnapshot | undefined, tcContext: IContext) =>
57+
const typecheckFile = (id: string, snapshot: tsTypes.IScriptSnapshot | undefined, tcContext: RollupContext) =>
5858
{
5959
if (!snapshot)
6060
return;
@@ -119,8 +119,13 @@ const typescript: PluginImpl<RPT2Options> = (options) =>
119119

120120
options(config)
121121
{
122-
rollupOptions = {... config};
123-
context = new ConsoleContext(pluginOptions.verbosity, "rpt2: ");
122+
rollupOptions = { ...config };
123+
return config;
124+
},
125+
126+
buildStart()
127+
{
128+
context = new RollupContext(pluginOptions.verbosity, pluginOptions.abortOnError, this, "rpt2: ");
124129

125130
watchMode = process.env.ROLLUP_WATCH === "true" || !!this.meta.watchMode; // meta.watchMode was added in 2.14.0 to capture watch via Rollup API (i.e. no env var) (c.f. https://github.com/rollup/rollup/blob/master/CHANGELOG.md#2140)
126131
({ parsedTsConfig: parsedConfig, fileName: tsConfigPath } = parseTsConfig(context, pluginOptions));
@@ -157,8 +162,6 @@ const typescript: PluginImpl<RPT2Options> = (options) =>
157162
if (diagnostics.length > 0)
158163
noErrors = false;
159164
}
160-
161-
return config;
162165
},
163166

164167
watchChange(id)
@@ -210,8 +213,6 @@ const typescript: PluginImpl<RPT2Options> = (options) =>
210213
if (!filter(id))
211214
return undefined;
212215

213-
const contextWrapper = new RollupContext(pluginOptions.verbosity, pluginOptions.abortOnError, this, "rpt2: ");
214-
215216
const snapshot = servicesHost.setSnapshot(id, code);
216217

217218
// getting compiled file from cache or from ts
@@ -223,7 +224,7 @@ const typescript: PluginImpl<RPT2Options> = (options) =>
223224
{
224225
noErrors = false;
225226
// always checking on fatal errors, even if options.check is set to false
226-
typecheckFile(id, snapshot, contextWrapper);
227+
typecheckFile(id, snapshot, context);
227228
// since no output was generated, aborting compilation
228229
this.error(red(`Emit skipped for '${id}'. See https://github.com/microsoft/TypeScript/issues/49790 for potential reasons why this may occur`));
229230
}
@@ -233,7 +234,7 @@ const typescript: PluginImpl<RPT2Options> = (options) =>
233234
});
234235

235236
if (pluginOptions.check)
236-
typecheckFile(id, snapshot, contextWrapper);
237+
typecheckFile(id, snapshot, context);
237238

238239
if (!result)
239240
return undefined;
@@ -299,8 +300,6 @@ const typescript: PluginImpl<RPT2Options> = (options) =>
299300
});
300301
}
301302

302-
const contextWrapper = new RollupContext(pluginOptions.verbosity, pluginOptions.abortOnError, this, "rpt2: ");
303-
304303
// type-check missed files as well
305304
parsedConfig.fileNames.forEach((name) =>
306305
{
@@ -310,7 +309,7 @@ const typescript: PluginImpl<RPT2Options> = (options) =>
310309

311310
context.debug(() => `type-checking missed '${key}'`);
312311
const snapshot = servicesHost.getScriptSnapshot(key);
313-
typecheckFile(key, snapshot, contextWrapper);
312+
typecheckFile(key, snapshot, context);
314313
});
315314

316315
buildDone();

src/parse-tsconfig.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@ import { dirname } from "path";
22
import * as _ from "lodash";
33

44
import { tsModule } from "./tsproxy";
5-
import { IContext } from "./context";
5+
import { RollupContext } from "./context";
66
import { printDiagnostics } from "./print-diagnostics";
77
import { convertDiagnostic } from "./tscache";
88
import { getOptionsOverrides } from "./get-options-overrides";
99
import { IOptions } from "./ioptions";
1010

11-
export function parseTsConfig(context: IContext, pluginOptions: IOptions)
11+
export function parseTsConfig(context: RollupContext, pluginOptions: IOptions)
1212
{
1313
const fileName = tsModule.findConfigFile(pluginOptions.cwd, tsModule.sys.fileExists, pluginOptions.tsconfig);
1414

1515
// if the value was provided, but no file, fail hard
1616
if (pluginOptions.tsconfig !== undefined && !fileName)
17-
throw new Error(`rpt2: failed to open '${pluginOptions.tsconfig}'`);
17+
context.error(`failed to open '${pluginOptions.tsconfig}'`);
1818

1919
let loadedConfig: any = {};
2020
let baseDir = pluginOptions.cwd;
@@ -29,7 +29,7 @@ export function parseTsConfig(context: IContext, pluginOptions: IOptions)
2929
if (result.error !== undefined)
3030
{
3131
printDiagnostics(context, convertDiagnostic("config", [result.error]), pretty);
32-
throw new Error(`rpt2: failed to parse '${fileName}'`);
32+
context.error(`failed to parse '${fileName}'`);
3333
}
3434

3535
loadedConfig = result.config;
@@ -46,7 +46,7 @@ export function parseTsConfig(context: IContext, pluginOptions: IOptions)
4646

4747
const module = parsedTsConfig.options.module!;
4848
if (module !== tsModule.ModuleKind.ES2015 && module !== tsModule.ModuleKind.ES2020 && module !== tsModule.ModuleKind.ESNext)
49-
throw new Error(`rpt2: Incompatible tsconfig option. Module resolves to '${tsModule.ModuleKind[module]}'. This is incompatible with Rollup, please use 'module: "ES2015"', 'module: "ES2020"', or 'module: "ESNext"'.`);
49+
context.error(`Incompatible tsconfig option. Module resolves to '${tsModule.ModuleKind[module]}'. This is incompatible with Rollup, please use 'module: "ES2015"', 'module: "ES2020"', or 'module: "ESNext"'.`);
5050

5151
printDiagnostics(context, convertDiagnostic("config", parsedTsConfig.errors), pretty);
5252

src/print-diagnostics.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { red, white, yellow } from "colors/safe";
22

33
import { tsModule } from "./tsproxy";
4-
import { IContext } from "./context";
4+
import { RollupContext } from "./context";
55
import { IDiagnostics } from "./tscache";
66

7-
export function printDiagnostics(context: IContext, diagnostics: IDiagnostics[], pretty = true): void
7+
export function printDiagnostics(context: RollupContext, diagnostics: IDiagnostics[], pretty = true): void
88
{
99
diagnostics.forEach((diagnostic) =>
1010
{

0 commit comments

Comments
 (0)