Skip to content

Commit df9b668

Browse files
authored
Merge pull request microsoft#70693 from penx/feature/node-module-resolution-for-css-import
Node module resolution for CSS import
2 parents 78378de + 2e9bd07 commit df9b668

1 file changed

Lines changed: 34 additions & 0 deletions

File tree

extensions/css-language-features/server/src/utils/documentContext.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,28 @@ import { endsWith, startsWith } from '../utils/strings';
88
import * as url from 'url';
99
import { WorkspaceFolder } from 'vscode-languageserver';
1010

11+
function getModuleNameFromPath(path: string) {
12+
// If a scoped module (starts with @) then get up until second instance of '/', otherwise get until first isntance of '/'
13+
if (path[0] === '@') {
14+
return path.substring(0, path.indexOf('/', path.indexOf('/') + 1));
15+
}
16+
return path.substring(0, path.indexOf('/'));
17+
}
18+
19+
function resolvePathToModule(moduleName: string, relativeTo: string) {
20+
// if we require.resolve('my-module') then it will follow the main property in the linked package.json
21+
// but we want the root of the module so resolve to the package.json and then trim
22+
let resolved;
23+
try {
24+
resolved = require
25+
.resolve(`${moduleName}/package.json`, { paths: [relativeTo] });
26+
}
27+
catch (ex) {
28+
return null;
29+
}
30+
return resolved.slice(0, -12); // remove trailing `package.json`
31+
}
32+
1133
export function getDocumentContext(documentUri: string, workspaceFolders: WorkspaceFolder[]): DocumentContext {
1234
function getRootFolder(): string | undefined {
1335
for (let folder of workspaceFolders) {
@@ -32,6 +54,18 @@ export function getDocumentContext(documentUri: string, workspaceFolders: Worksp
3254
}
3355
}
3456
}
57+
// Following [css-loader](https://github.com/webpack-contrib/css-loader#url)
58+
// and [sass-loader's](https://github.com/webpack-contrib/sass-loader#imports)
59+
// convention, if an import path starts with ~ then use node module resolution
60+
// *unless* it starts with "~/" as this refers to the user's home directory.
61+
if (ref[0] === '~' && ref[1] !== '/') {
62+
const moduleName = getModuleNameFromPath(ref.substring(1));
63+
const modulePath = resolvePathToModule(moduleName, base);
64+
if (modulePath) {
65+
const pathWithinModule = ref.substring(moduleName.length + 2);
66+
return url.resolve(modulePath, pathWithinModule);
67+
}
68+
}
3569
return url.resolve(base, ref);
3670
},
3771
};

0 commit comments

Comments
 (0)