Skip to content

Commit 197061b

Browse files
authored
refactor: prefer native methods to lodash where possible (#328)
- _.endsWith -> String.endsWith - _.concat -> Array.concat - _.each -> Array.forEach - _.filter -> Array.filter - _.map -> Array.map - _.some -> Array.some - _.has -> `key in Object` - _.defaults -> Object.assign - _.get -> `?.` and `??` (optional chaining and nullish coalescing) - refactor: replace fairly complicated `expandIncludeWithDirs` func to just use a few simple `forEach`s - not as FP anymore, more imperative, but much simpler to read IMO - refactor: add a `getDiagnostics` helper to DRY up some code - also aids readability IMO - a few places are still using lodash, but this paves the way toward removing it or replacing it with much smaller individual deps - _.compact still used because Array.filter heavily complicates the type-checking currently - _.isFunction still used because while it's a one-liner natively, need to import a function in several places - also the package `lodash.isFunction` is lodash v3 and quite different from the v4 implementation, so couldn't replace with it unfortunately - _.merge is a deep merge, so there's no native version of this - but we may remove deep merges entirely in the future (as tsconfig doesn't quite perform a deep merge), or could replace this with a smaller `lodash.merge` package or similar - see also https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore
1 parent 529c853 commit 197061b

File tree

6 files changed

+51
-74
lines changed

6 files changed

+51
-74
lines changed

src/get-options-overrides.ts

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { createFilter as createRollupFilter} from "@rollup/pluginutils";
22
import { tsModule } from "./tsproxy";
33
import * as tsTypes from "typescript";
44
import { IOptions } from "./ioptions";
5-
import * as _ from "lodash";
65
import { join } from "path";
76
import { IContext } from "./context";
87

@@ -39,17 +38,15 @@ export function getOptionsOverrides({ useTsconfigDeclarationDir, cacheRoot }: IO
3938

4039
function expandIncludeWithDirs(include: string | string[], dirs: string[])
4140
{
42-
return _
43-
.chain(dirs)
44-
.flatMap((root) =>
45-
{
46-
if (include instanceof Array)
47-
return include.map((x) => join(root, x));
48-
else
49-
return join(root, include);
50-
})
51-
.uniq()
52-
.value();
41+
const newDirs: string[] = [];
42+
43+
dirs.forEach(root => {
44+
if (include instanceof Array)
45+
include.forEach(x => newDirs.push(join(root, x)));
46+
else
47+
newDirs.push(join(root, include));
48+
});
49+
return newDirs;
5350
}
5451

5552
export function createFilter(context: IContext, pluginOptions: IOptions, parsedConfig: tsTypes.ParsedCommandLine)
@@ -65,8 +62,8 @@ export function createFilter(context: IContext, pluginOptions: IOptions, parsedC
6562

6663
if (parsedConfig.projectReferences)
6764
{
68-
included = _.concat(included, expandIncludeWithDirs(included, parsedConfig.projectReferences.map((x) => x.path)));
69-
excluded = _.concat(excluded, expandIncludeWithDirs(excluded, parsedConfig.projectReferences.map((x) => x.path)));
65+
included = expandIncludeWithDirs(included, parsedConfig.projectReferences.map((x) => x.path)).concat(included);
66+
excluded = expandIncludeWithDirs(excluded, parsedConfig.projectReferences.map((x) => x.path)).concat(excluded);
7067
}
7168

7269
context.debug(() => `included:\n${JSON.stringify(included, undefined, 4)}`);

src/host.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { tsModule } from "./tsproxy";
22
import * as tsTypes from "typescript";
3-
import * as _ from "lodash";
43
import { normalizePath as normalize } from "@rollup/pluginutils";
54
import { TransformerFactoryCreator } from "./ioptions";
65

@@ -44,7 +43,7 @@ export class LanguageServiceHost implements tsTypes.LanguageServiceHost
4443
{
4544
fileName = normalize(fileName);
4645

47-
if (_.has(this.snapshots, fileName))
46+
if (fileName in this.snapshots)
4847
return this.snapshots[fileName];
4948

5049
const source = tsModule.sys.readFile(fileName);
@@ -136,11 +135,11 @@ export class LanguageServiceHost implements tsTypes.LanguageServiceHost
136135
{
137136
const factory = creator(this.service);
138137
if (factory.before)
139-
transformer.before = _.concat(transformer.before!, factory.before);
138+
transformer.before = transformer.before!.concat(factory.before);
140139
if (factory.after)
141-
transformer.after = _.concat(transformer.after!, factory.after);
140+
transformer.after = transformer.after!.concat(factory.after);
142141
if (factory.afterDeclarations)
143-
transformer.afterDeclarations = _.concat(transformer.afterDeclarations!, factory.afterDeclarations);
142+
transformer.afterDeclarations = transformer.afterDeclarations!.concat(factory.afterDeclarations);
144143
}
145144

146145
return transformer;

src/index.ts

Lines changed: 21 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,18 @@ const typescript: PluginImpl<RPT2Options> = (options) =>
4646
return _cache;
4747
};
4848

49-
const pluginOptions = { ...options } as IOptions;
49+
const getDiagnostics = (id: string, snapshot: tsTypes.IScriptSnapshot) =>
50+
{
51+
return cache().getSyntacticDiagnostics(id, snapshot, () =>
52+
{
53+
return service.getSyntacticDiagnostics(id);
54+
}).concat(cache().getSemanticDiagnostics(id, snapshot, () =>
55+
{
56+
return service.getSemanticDiagnostics(id);
57+
}));
58+
}
5059

51-
_.defaults(pluginOptions,
60+
const pluginOptions: IOptions = Object.assign({},
5261
{
5362
check: true,
5463
verbosity: VerbosityLevel.Warning,
@@ -65,7 +74,7 @@ const typescript: PluginImpl<RPT2Options> = (options) =>
6574
tsconfigDefaults: {},
6675
objectHashIgnoreUnknownHack: false,
6776
cwd: process.cwd(),
68-
});
77+
}, options as IOptions);
6978

7079
if (!pluginOptions.typescript) {
7180
pluginOptions.typescript = require("typescript");
@@ -87,7 +96,7 @@ const typescript: PluginImpl<RPT2Options> = (options) =>
8796

8897
if (generateRound === 0)
8998
{
90-
parsedConfig.fileNames.forEach((fileName) => { allImportedFiles.add(fileName); });
99+
parsedConfig.fileNames.map(allImportedFiles.add, allImportedFiles);
91100

92101
context.info(`typescript version: ${tsModule.version}`);
93102
context.info(`tslib version: ${tslibVersion}`);
@@ -151,7 +160,7 @@ const typescript: PluginImpl<RPT2Options> = (options) =>
151160
if (filter(result.resolvedModule.resolvedFileName))
152161
cache().setDependency(result.resolvedModule.resolvedFileName, importer);
153162

154-
if (_.endsWith(result.resolvedModule.resolvedFileName, ".d.ts"))
163+
if (result.resolvedModule.resolvedFileName.endsWith(".d.ts"))
155164
return;
156165

157166
const resolved = pluginOptions.rollupCommonJSResolveHack
@@ -198,16 +207,7 @@ const typescript: PluginImpl<RPT2Options> = (options) =>
198207
noErrors = false;
199208

200209
// always checking on fatal errors, even if options.check is set to false
201-
const diagnostics = _.concat(
202-
cache().getSyntacticDiagnostics(id, snapshot, () =>
203-
{
204-
return service.getSyntacticDiagnostics(id);
205-
}),
206-
cache().getSemanticDiagnostics(id, snapshot, () =>
207-
{
208-
return service.getSemanticDiagnostics(id);
209-
}),
210-
);
210+
const diagnostics = getDiagnostics(id, snapshot);
211211
printDiagnostics(contextWrapper, diagnostics, parsedConfig.options.pretty === true);
212212

213213
// since no output was generated, aborting compilation
@@ -222,17 +222,7 @@ const typescript: PluginImpl<RPT2Options> = (options) =>
222222

223223
if (pluginOptions.check)
224224
{
225-
const diagnostics = _.concat(
226-
cache().getSyntacticDiagnostics(id, snapshot, () =>
227-
{
228-
return service.getSyntacticDiagnostics(id);
229-
}),
230-
cache().getSemanticDiagnostics(id, snapshot, () =>
231-
{
232-
return service.getSemanticDiagnostics(id);
233-
}),
234-
);
235-
225+
const diagnostics = getDiagnostics(id, snapshot);
236226
if (diagnostics.length > 0)
237227
noErrors = false;
238228

@@ -295,17 +285,7 @@ const typescript: PluginImpl<RPT2Options> = (options) =>
295285
if (!snapshot)
296286
return;
297287

298-
const diagnostics = _.concat(
299-
cache().getSyntacticDiagnostics(id, snapshot, () =>
300-
{
301-
return service.getSyntacticDiagnostics(id);
302-
}),
303-
cache().getSemanticDiagnostics(id, snapshot, () =>
304-
{
305-
return service.getSemanticDiagnostics(id);
306-
}),
307-
);
308-
288+
const diagnostics = getDiagnostics(id, snapshot);
309289
printDiagnostics(context, diagnostics, parsedConfig.options.pretty === true);
310290
});
311291
}
@@ -323,10 +303,10 @@ const typescript: PluginImpl<RPT2Options> = (options) =>
323303
if (!parsedConfig.options.declaration)
324304
return;
325305

326-
_.each(parsedConfig.fileNames, (name) =>
306+
parsedConfig.fileNames.forEach((name) =>
327307
{
328308
const key = normalize(name);
329-
if (_.has(declarations, key))
309+
if (key in declarations)
330310
return;
331311
if (!allImportedFiles.has(key))
332312
{
@@ -390,8 +370,9 @@ const typescript: PluginImpl<RPT2Options> = (options) =>
390370
}
391371
};
392372

393-
_.each(declarations, ({ type, map }, key) =>
373+
Object.keys(declarations).forEach((key) =>
394374
{
375+
const { type, map } = declarations[key];
395376
emitDeclaration(key, ".d.ts", type);
396377
emitDeclaration(key, ".d.ts.map", map);
397378
});

src/parse-tsconfig.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export function parseTsConfig(context: IContext, pluginOptions: IOptions)
2727
throw new Error(`rpt2: failed to read '${fileName}'`);
2828

2929
const result = tsModule.parseConfigFileTextToJson(fileName, text);
30-
pretty = _.get(result.config, "pretty", pretty);
30+
pretty = result.config?.pretty ?? pretty;
3131

3232
if (result.error !== undefined)
3333
{

src/print-diagnostics.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@ import { tsModule } from "./tsproxy";
22
import { red, white, yellow } from "colors/safe";
33
import { IContext } from "./context";
44
import { IDiagnostics } from "./tscache";
5-
import * as _ from "lodash";
65

76
export function printDiagnostics(context: IContext, diagnostics: IDiagnostics[], pretty: boolean): void
87
{
9-
_.each(diagnostics, (diagnostic) =>
8+
diagnostics.forEach((diagnostic) =>
109
{
1110
let print;
1211
let color;

src/tscache.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@ export function convertEmitOutput(output: tsTypes.EmitOutput, references?: strin
4747

4848
output.outputFiles.forEach((e) =>
4949
{
50-
if (_.endsWith(e.name, ".d.ts"))
50+
if (e.name.endsWith(".d.ts"))
5151
out.dts = e;
52-
else if (_.endsWith(e.name, ".d.ts.map"))
52+
else if (e.name.endsWith(".d.ts.map"))
5353
out.dtsmap = e;
54-
else if (_.endsWith(e.name, ".map"))
54+
else if (e.name.endsWith(".map"))
5555
out.map = e.text;
5656
else
5757
out.code = e.text;
@@ -67,7 +67,7 @@ export function getAllReferences(importer: string, snapshot: tsTypes.IScriptSnap
6767

6868
const info = tsModule.preProcessFile(snapshot.getText(0, snapshot.getLength()), true, true);
6969

70-
return _.compact(_.concat(info.referencedFiles, info.importedFiles).map((reference) =>
70+
return _.compact(info.referencedFiles.concat(info.importedFiles).map((reference) =>
7171
{
7272
const resolved = tsModule.nodeModuleNameResolver(reference.fileName, importer, options, tsModule.sys);
7373
return resolved.resolvedModule ? resolved.resolvedModule.resolvedFileName : undefined;
@@ -76,7 +76,7 @@ export function getAllReferences(importer: string, snapshot: tsTypes.IScriptSnap
7676

7777
export function convertDiagnostic(type: string, data: tsTypes.Diagnostic[]): IDiagnostics[]
7878
{
79-
return _.map(data, (diagnostic) =>
79+
return data.map((diagnostic) =>
8080
{
8181
const entry: IDiagnostics =
8282
{
@@ -131,11 +131,11 @@ export class TsCache
131131
this.dependencyTree = new Graph({ directed: true });
132132
this.dependencyTree.setDefaultNodeLabel((_node: string) => ({ dirty: false }));
133133

134-
const automaticTypes = _.map(tsModule.getAutomaticTypeDirectiveNames(options, tsModule.sys), (entry) => tsModule.resolveTypeReferenceDirective(entry, undefined, options, tsModule.sys))
134+
const automaticTypes = tsModule.getAutomaticTypeDirectiveNames(options, tsModule.sys).map((entry) => tsModule.resolveTypeReferenceDirective(entry, undefined, options, tsModule.sys))
135135
.filter((entry) => entry.resolvedTypeReferenceDirective && entry.resolvedTypeReferenceDirective.resolvedFileName)
136136
.map((entry) => entry.resolvedTypeReferenceDirective!.resolvedFileName!);
137137

138-
this.ambientTypes = _.filter(rootFilenames, (file) => _.endsWith(file, ".d.ts"))
138+
this.ambientTypes = rootFilenames.filter(file => file.endsWith(".d.ts"))
139139
.concat(automaticTypes)
140140
.map((id) => ({ id, snapshot: this.host.getScriptSnapshot(id) }));
141141

@@ -180,13 +180,13 @@ export class TsCache
180180

181181
if (acyclic)
182182
{
183-
_.each(alg.topsort(this.dependencyTree), (id: string) => cb(id));
183+
alg.topsort(this.dependencyTree).forEach(id => cb(id));
184184
return;
185185
}
186186

187187
this.context.info(yellow("import tree has cycles"));
188188

189-
_.each(this.dependencyTree.nodes(), (id: string) => cb(id));
189+
this.dependencyTree.nodes().forEach(id => cb(id));
190190
}
191191

192192
public done()
@@ -252,7 +252,7 @@ export class TsCache
252252
}
253253

254254
this.context.debug(blue("Ambient types:"));
255-
const typeNames = _.filter(this.ambientTypes, (snapshot) => snapshot.snapshot !== undefined)
255+
const typeNames = this.ambientTypes.filter((snapshot) => snapshot.snapshot !== undefined)
256256
.map((snapshot) =>
257257
{
258258
this.context.debug(` ${snapshot.id}`);
@@ -264,7 +264,7 @@ export class TsCache
264264
if (this.ambientTypesDirty)
265265
this.context.info(yellow("ambient types changed, redoing all semantic diagnostics"));
266266

267-
_.each(typeNames, (name) => this.typesCache.touch(name));
267+
typeNames.forEach(this.typesCache.touch, this);
268268
}
269269

270270
private getDiagnostics(type: string, cache: ICache<IDiagnostics[]>, id: string, snapshot: tsTypes.IScriptSnapshot, check: () => tsTypes.Diagnostic[]): IDiagnostics[]
@@ -342,8 +342,9 @@ export class TsCache
342342

343343
const dependencies = alg.dijkstra(this.dependencyTree, id);
344344

345-
return _.some(dependencies, (dependency, node) =>
345+
return Object.keys(dependencies).some(node =>
346346
{
347+
const dependency = dependencies[node];
347348
if (!node || dependency.distance === Infinity)
348349
return false;
349350

0 commit comments

Comments
 (0)