Skip to content

Commit cfe6dcb

Browse files
committed
fix: 🐛 prevent ts from removing unused imports
Closes #81
1 parent 71913ba commit cfe6dcb

File tree

1 file changed

+45
-63
lines changed

1 file changed

+45
-63
lines changed

src/transformers/typescript.ts

+45-63
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { Transformer, Options } from '../typings';
66

77
type CompilerOptions = Options.Typescript['compilerOptions'];
88

9-
function createFormatDiagnosticsHost(cwd: string) {
9+
function createFormatDiagnosticsHost(cwd: string): ts.FormatDiagnosticsHost {
1010
return {
1111
getCanonicalFileName: (fileName: string) => fileName,
1212
getCurrentDirectory: () => cwd,
@@ -63,28 +63,20 @@ function isValidSvelteImportDiagnostic(filename: string, diagnostic: any) {
6363
return existsSync(importeePath) === false;
6464
}
6565

66-
const TS_TRANSFORMERS = {
67-
before: [
68-
(context: any) => {
69-
const visit = (node: ts.Node): ts.VisitResult<ts.Node> => {
70-
if (ts.isImportDeclaration(node)) {
71-
const importedFilename = node.moduleSpecifier.getText().slice(1, -1);
72-
// istanbul ignore else
73-
if (isSvelteFile(importedFilename)) {
74-
return ts.createImportDeclaration(
75-
node.decorators,
76-
node.modifiers,
77-
node.importClause,
78-
node.moduleSpecifier,
79-
);
80-
}
81-
}
82-
return ts.visitEachChild(node, child => visit(child), context);
83-
};
84-
85-
return (node: any) => ts.visitNode(node, visit);
86-
},
87-
],
66+
const importTransformer: ts.TransformerFactory<ts.SourceFile> = context => {
67+
const visit: ts.Visitor = node => {
68+
if (ts.isImportDeclaration(node)) {
69+
return ts.createImportDeclaration(
70+
node.decorators,
71+
node.modifiers,
72+
node.importClause,
73+
node.moduleSpecifier,
74+
);
75+
}
76+
return ts.visitEachChild(node, child => visit(child), context);
77+
};
78+
79+
return node => ts.visitNode(node, visit);
8880
};
8981

9082
function compileFileFromMemory(
@@ -96,62 +88,52 @@ function compileFileFromMemory(
9688

9789
const realHost = ts.createCompilerHost(compilerOptions, true);
9890
const dummyFilePath = filename;
99-
const dummySourceFile = ts.createSourceFile(
100-
dummyFilePath,
101-
code,
102-
ts.ScriptTarget.Latest,
103-
);
10491

105-
const host = {
106-
fileExists: (filePath: string) =>
92+
const host: ts.CompilerHost = {
93+
fileExists: filePath =>
10794
filePath === dummyFilePath || realHost.fileExists(filePath),
108-
directoryExists:
109-
realHost.directoryExists && realHost.directoryExists.bind(realHost),
110-
getCurrentDirectory: realHost.getCurrentDirectory.bind(realHost),
111-
getDirectories: realHost.getDirectories.bind(realHost),
112-
getCanonicalFileName: (fileName: string) =>
113-
realHost.getCanonicalFileName(fileName),
114-
getNewLine: realHost.getNewLine.bind(realHost),
115-
getDefaultLibFileName: realHost.getDefaultLibFileName.bind(realHost),
95+
getCanonicalFileName: fileName => realHost.getCanonicalFileName(fileName),
11696
getSourceFile: (
117-
fileName: string,
118-
languageVersion: ts.ScriptTarget,
119-
onError: () => any,
120-
shouldCreateNewSourceFile: boolean,
97+
fileName,
98+
languageVersion,
99+
onError,
100+
shouldCreateNewSourceFile,
121101
) =>
122102
fileName === dummyFilePath
123-
? dummySourceFile
103+
? ts.createSourceFile(dummyFilePath, code, languageVersion)
124104
: realHost.getSourceFile(
125105
fileName,
126106
languageVersion,
127107
onError,
128108
shouldCreateNewSourceFile,
129109
),
130-
readFile: (filePath: string) =>
110+
readFile: filePath =>
131111
// istanbul ignore next
132112
filePath === dummyFilePath ? content : realHost.readFile(filePath),
133-
useCaseSensitiveFileNames: () => realHost.useCaseSensitiveFileNames(),
134-
writeFile: (fileName: string, data: string) => {
113+
writeFile: (fileName, data) => {
135114
if (fileName.endsWith('.map')) {
136115
map = data;
137116
} else {
138117
code = data;
139118
}
140119
},
120+
directoryExists:
121+
realHost.directoryExists && realHost.directoryExists.bind(realHost),
122+
getCurrentDirectory: realHost.getCurrentDirectory.bind(realHost),
123+
getDirectories: realHost.getDirectories.bind(realHost),
124+
getNewLine: realHost.getNewLine.bind(realHost),
125+
getDefaultLibFileName: realHost.getDefaultLibFileName.bind(realHost),
126+
resolveModuleNames:
127+
realHost.resolveModuleNames && realHost.resolveModuleNames.bind(realHost),
128+
useCaseSensitiveFileNames: realHost.useCaseSensitiveFileNames.bind(
129+
realHost,
130+
),
141131
};
142132

143-
const program = ts.createProgram(
144-
[dummyFilePath],
145-
compilerOptions,
146-
(host as any) as ts.CompilerHost,
147-
);
148-
const emitResult = program.emit(
149-
undefined,
150-
undefined,
151-
undefined,
152-
undefined,
153-
TS_TRANSFORMERS,
154-
);
133+
const program = ts.createProgram([dummyFilePath], compilerOptions, host);
134+
const emitResult = program.emit(undefined, undefined, undefined, undefined, {
135+
before: [importTransformer],
136+
});
155137

156138
// collect diagnostics without svelte import errors
157139
const diagnostics = [
@@ -170,19 +152,19 @@ const transformer: Transformer<Options.Typescript> = ({
170152
// default options
171153
const compilerOptionsJSON = {
172154
moduleResolution: 'node',
173-
sourceMap: true,
174-
strict: true,
175155
target: 'es6',
176156
};
157+
177158
let basePath = process.cwd();
178159

179160
if (options.tsconfigFile !== false || options.tsconfigDirectory) {
180161
const fileDirectory = (options.tsconfigDirectory ||
181162
dirname(filename)) as string;
182-
const tsconfigFile = (options.tsconfigFile ||
183-
ts.findConfigFile(fileDirectory, ts.sys.fileExists)) as string;
163+
const tsconfigFile =
164+
options.tsconfigFile ||
165+
ts.findConfigFile(fileDirectory, ts.sys.fileExists);
184166

185-
if (tsconfigFile) {
167+
if (typeof tsconfigFile === 'string') {
186168
basePath = dirname(tsconfigFile);
187169

188170
const { error, config } = ts.readConfigFile(

0 commit comments

Comments
 (0)