[css] resolve modules without require

This commit is contained in:
Martin Aeschlimann
2019-06-05 13:04:45 +02:00
parent 3460fb97b0
commit 8f72934706
2 changed files with 22 additions and 14 deletions

View File

@@ -7,6 +7,9 @@ import { DocumentContext } from 'vscode-css-languageservice';
import { endsWith, startsWith } from '../utils/strings';
import * as url from 'url';
import { WorkspaceFolder } from 'vscode-languageserver';
import URI from 'vscode-uri';
import { join, dirname } from 'path';
import { existsSync } from 'fs';
function getModuleNameFromPath(path: string) {
// If a scoped module (starts with @) then get up until second instance of '/', otherwise get until first isntance of '/'
@@ -16,19 +19,14 @@ function getModuleNameFromPath(path: string) {
return path.substring(0, path.indexOf('/'));
}
function resolvePathToModule(_moduleName: string, _relativeTo: string) {
// if we require.resolve('my-module') then it will follow the main property in the linked package.json
// but we want the root of the module so resolve to the package.json and then trim
let resolved;
try {
// resolved = require
// .resolve(`${moduleName}/package.json`, { paths: [relativeTo] });
throw new Error();
function resolvePathToModule(_moduleName: string, _relativeTo: string): string | undefined {
// resolve the module relative to the document. We can't use `require` here as the code is webpacked.
const documentFolder = dirname(URI.parse(_relativeTo).fsPath);
const packPath = join(documentFolder, 'node_modules', _moduleName, 'package.json');
if (existsSync(packPath)) {
return URI.file(packPath).toString();
}
catch (ex) {
return null;
}
return resolved.slice(0, -12); // remove trailing `package.json`
return undefined;
}
export function getDocumentContext(documentUri: string, workspaceFolders: WorkspaceFolder[]): DocumentContext {
@@ -59,7 +57,7 @@ export function getDocumentContext(documentUri: string, workspaceFolders: Worksp
// and [sass-loader's](https://github.com/webpack-contrib/sass-loader#imports)
// convention, if an import path starts with ~ then use node module resolution
// *unless* it starts with "~/" as this refers to the user's home directory.
if (ref[0] === '~' && ref[1] !== '/') {
if (ref[0] === '~' && ref[1] !== '/' && startsWith(base, 'file://')) {
const moduleName = getModuleNameFromPath(ref.substring(1));
const modulePath = resolvePathToModule(moduleName, base);
if (modulePath) {