Skip to content

Commit

Permalink
fix: respect esm and styles for sync resolves
Browse files Browse the repository at this point in the history
  • Loading branch information
Anidetrix committed Jan 24, 2021
1 parent eb0674d commit 0c51253
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 26 deletions.
2 changes: 1 addition & 1 deletion src/loaders/less/importer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import fs from "fs-extra";
import resolveAsync from "../../utils/resolve-async";
import { resolveAsync } from "../../utils/resolve";
import { getUrlOfPartial, normalizeUrl } from "../../utils/url";

const extensions = [".less", ".css"];
Expand Down
2 changes: 1 addition & 1 deletion src/loaders/postcss/icss/load.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import path from "path";
import fs from "fs-extra";
import { ProcessOptions } from "postcss";
import Processor from "postcss/lib/processor";
import resolveAsync from "../../../utils/resolve-async";
import { resolveAsync } from "../../../utils/resolve";

export type Load = (
url: string,
Expand Down
2 changes: 1 addition & 1 deletion src/loaders/postcss/import/resolve.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import fs from "fs-extra";
import { parseUrl } from "query-string";
import resolveAsync from "../../../utils/resolve-async";
import { resolveAsync } from "../../../utils/resolve";

/** File resolved by `@import` resolver */
export interface ImportFile {
Expand Down
2 changes: 1 addition & 1 deletion src/loaders/postcss/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import cssnano from "cssnano";
import { PostCSSLoaderOptions, InjectOptions } from "../../types";
import { humanlizePath, normalizePath } from "../../utils/path";
import { mm } from "../../utils/sourcemap";
import resolveAsync from "../../utils/resolve-async";
import { resolveAsync } from "../../utils/resolve";
import safeId from "../../utils/safe-id";
import { Loader } from "../types";
import loadConfig from "./config";
Expand Down
2 changes: 1 addition & 1 deletion src/loaders/postcss/url/resolve.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import fs from "fs-extra";
import { parseUrl, stringifyUrl } from "query-string";
import resolveAsync from "../../../utils/resolve-async";
import { resolveAsync } from "../../../utils/resolve";

/** File resolved by URL resolver */
export interface UrlFile {
Expand Down
11 changes: 3 additions & 8 deletions src/loaders/sass/importer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import path from "path";
import { sync as resolveSync } from "resolve";
import resolveAsync from "../../utils/resolve-async";
import { resolveAsync, resolveSync } from "../../utils/resolve";
import { getUrlOfPartial, isModule, normalizeUrl } from "../../utils/url";

const extensions = [".scss", ".sass", ".css"];
Expand All @@ -22,14 +21,10 @@ export const importerSync: sass.Importer = (url, importer): sass.Data => {
if (!isModule(url)) return null;
const moduleUrl = normalizeUrl(url);
const partialUrl = getUrlOfPartial(moduleUrl);
const options = { basedir: path.dirname(importer), extensions };
const options = { caller: "Sass importer", basedirs: [path.dirname(importer)], extensions };
// Give precedence to importing a partial
try {
try {
return finalize(resolveSync(partialUrl, options));
} catch {
return finalize(resolveSync(moduleUrl, options));
}
return finalize(resolveSync([partialUrl, moduleUrl], options));
} catch {
return null;
}
Expand Down
18 changes: 11 additions & 7 deletions src/utils/load-module.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
/* eslint-disable @typescript-eslint/no-var-requires */
import { sync as resolveSync, SyncOpts } from "resolve";
import { resolveSync, ResolveOpts } from "./resolve";

const loaded: Record<string, unknown> = {};
const options: SyncOpts = { basedir: process.cwd(), preserveSymlinks: false };

const options: ResolveOpts = {
caller: "Module loader",
basedirs: [process.cwd()],
extensions: [".js", ".mjs", ".json"],
preserveSymlinks: false,
packageFilter: pkg => pkg,
};

export default function (moduleId: string): unknown {
if (loaded[moduleId]) return loaded[moduleId];
if (loaded[moduleId] === null) return;

try {
try {
loaded[moduleId] = require(resolveSync(moduleId, options)) as unknown;
} catch {
loaded[moduleId] = require(resolveSync(`./${moduleId}`, options)) as unknown;
}
loaded[moduleId] = require(resolveSync([moduleId, `./${moduleId}`], options));
} catch {
loaded[moduleId] = null;
return;
Expand Down
32 changes: 26 additions & 6 deletions src/utils/resolve-async.ts → src/utils/resolve.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import resolver, { AsyncOpts } from "resolve";
import resolver, { sync, AsyncOpts, SyncOpts } from "resolve";
import arrayFmt from "./array-fmt";

export interface ResolveOpts {
Expand Down Expand Up @@ -40,19 +40,39 @@ const defaultOpts: ResolveDefaultOpts = {
},
};

const resolveAsync = async (id: string, options: AsyncOpts = {}): Promise<string | undefined> =>
const resolverAsync = async (id: string, options: AsyncOpts = {}): Promise<string | undefined> =>
new Promise(resolve => resolver(id, options, (_, res) => resolve(res)));

export default async function (ids: string[], userOpts: ResolveOpts): Promise<string> {
export async function resolveAsync(ids: string[], userOpts: ResolveOpts): Promise<string> {
const options = { ...defaultOpts, ...userOpts };
for await (const basedir of options.basedirs) {
const opts = { ...options, basedir, basedirs: undefined, caller: undefined };
for await (const id of ids) {
const resolved = await resolveAsync(id, opts);
const resolved = await resolverAsync(id, opts);
if (resolved) return resolved;
}
}

const idsFmt = arrayFmt(ids);
throw new Error(`${options.caller} could not resolve ${idsFmt}`);
throw new Error(`${options.caller} could not resolve ${arrayFmt(ids)}`);
}

const resolverSync = (id: string, options: SyncOpts = {}): string | undefined => {
try {
return sync(id, options);
} catch {
return;
}
};

export function resolveSync(ids: string[], userOpts: ResolveOpts): string {
const options = { ...defaultOpts, ...userOpts };
for (const basedir of options.basedirs) {
const opts = { ...options, basedir, basedirs: undefined, caller: undefined };
for (const id of ids) {
const resolved = resolverSync(id, opts);
if (resolved) return resolved;
}
}

throw new Error(`${options.caller} could not resolve ${arrayFmt(ids)}`);
}

0 comments on commit 0c51253

Please sign in to comment.