This repository has been archived by the owner on Dec 6, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.ts
80 lines (66 loc) · 3.09 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import { extractICSS } from 'icss-utils';
import * as ts_module from 'typescript/lib/tsserverlibrary';
import * as path from 'path';
import * as postcss from 'postcss';
import * as postcssIcssSelectors from 'postcss-icss-selectors';
export = function init({ typescript: ts }: { typescript: typeof ts_module }) {
function isCSS(fileName: string): boolean {
return /\.css$/.test(fileName);
}
function isRelativeCSS(fileName: string): boolean {
return isCSS(fileName) && /^\.\.?($|[\\/])/.test(fileName);
}
function create(info: ts.server.PluginCreateInfo) {
const processor = postcss(postcssIcssSelectors({ mode: 'local' }))
function getDtsSnapshot(scriptSnapshot: ts.IScriptSnapshot) {
const css = scriptSnapshot.getText(0, scriptSnapshot.getLength());
const dts = Object.keys(extractICSS(processor.process(css).root).icssExports)
.map(exportName => `export const ${exportName}: string;`)
.join('');
return ts.ScriptSnapshot.fromString(dts);
}
const clssf = ts.createLanguageServiceSourceFile;
ts.createLanguageServiceSourceFile = (fileName: string, scriptSnapshot: ts.IScriptSnapshot, scriptTarget: ts.ScriptTarget, version: string, setNodeParents: boolean, scriptKind?: ts.ScriptKind, cheat?: string): ts.SourceFile => {
if (isCSS(fileName)) {
scriptSnapshot = getDtsSnapshot(scriptSnapshot);
}
var sourceFile = clssf(fileName, scriptSnapshot, scriptTarget, version, setNodeParents, scriptKind);
if (isCSS(fileName)) {
sourceFile.isDeclarationFile = true;
}
return sourceFile;
}
const ulssf = ts.updateLanguageServiceSourceFile;
ts.updateLanguageServiceSourceFile = (sourceFile: ts.SourceFile, scriptSnapshot: ts.IScriptSnapshot, version: string, textChangeRange: ts.TextChangeRange, aggressiveChecks?: boolean, cheat?: string): ts.SourceFile => {
if (isCSS(sourceFile.fileName)) {
scriptSnapshot = getDtsSnapshot(scriptSnapshot);
}
var sourceFile = ulssf(sourceFile, scriptSnapshot, version, textChangeRange, aggressiveChecks);
if (isCSS(sourceFile.fileName)) {
sourceFile.isDeclarationFile = true;
}
return sourceFile;
}
if (info.languageServiceHost.resolveModuleNames) {
const rmn = info.languageServiceHost.resolveModuleNames.bind(info.languageServiceHost);
info.languageServiceHost.resolveModuleNames = (moduleNames, containingFile, reusedNames) => {
const resolvedCSS: ts.ResolvedModuleFull[] = [];
return rmn(moduleNames.filter(moduleName => {
if (isRelativeCSS(moduleName)) {
resolvedCSS.push({
resolvedFileName: path.resolve(path.dirname(containingFile), moduleName),
extension: ts_module.Extension.Dts,
});
return false;
}
return true;
}), containingFile, reusedNames).concat(resolvedCSS);
};
}
return info.languageService;
}
function getExternalFiles(project: ts_module.server.ConfiguredProject) {
return project.getFileNames().filter(isCSS);
}
return { create, getExternalFiles };
};