Skip to content

Commit

Permalink
perf(less): less allocations in importer
Browse files Browse the repository at this point in the history
  • Loading branch information
Anidetrix committed Mar 20, 2020
1 parent 16f9e02 commit bf3710a
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 29 deletions.
37 changes: 16 additions & 21 deletions src/loaders/less/import-plugin.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import fs from "fs-extra";
import { LoadedFile, Plugin, Less } from "less";
import { LoadedFile, Plugin, FileManagerInterface, Less } from "less";
import resolveAsync from "../../utils/resolve-async";
import { moduleRe, getUrlOfPartial } from "../../utils/resolve-utils";

// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
const getManager = () => {
const getStylesFileManager = (): FileManagerInterface => {
const less = require("less") as Less;

class StylesFileManager extends less.FileManager {
return new (class extends less.AbstractFileManager implements FileManagerInterface {
supports(): boolean {
return true;
}
Expand All @@ -16,50 +14,47 @@ const getManager = () => {
return false;
}

async loadFile(filename: string, currentDirectory: string): Promise<LoadedFile> {
const options = { basedir: currentDirectory, extensions: [".less", ".css"] };
async loadFile(filename: string, basedir: string): Promise<LoadedFile> {
const options = { basedir, extensions: [".less", ".css"] };
let id: string;

if (!moduleRe.test(filename)) {
let resolved: string;
try {
// Give precedence to importing a partial
try {
resolved = await resolveAsync(getUrlOfPartial(filename), options);
id = await resolveAsync(getUrlOfPartial(filename), options);
} catch (error) {
resolved = await resolveAsync(filename, options);
id = await resolveAsync(filename, options);
}
} catch (error) {
// Give precedence to importing a partial
try {
resolved = await resolveAsync(`./${getUrlOfPartial(filename)}`, options);
id = await resolveAsync(`./${getUrlOfPartial(filename)}`, options);
} catch (error) {
resolved = await resolveAsync(`./${filename}`, options);
id = await resolveAsync(`./${filename}`, options);
}
}
return { filename: resolved, contents: await fs.readFile(resolved, "utf8") };
return { filename: id, contents: await fs.readFile(id, "utf8") };
}

const moduleUrl = filename.slice(1);
const partialUrl = getUrlOfPartial(moduleUrl);

// Give precedence to importing a partial
let resolved: string;
try {
resolved = await resolveAsync(partialUrl, options);
id = await resolveAsync(partialUrl, options);
} catch (error) {
resolved = await resolveAsync(moduleUrl, options);
id = await resolveAsync(moduleUrl, options);
}

return { filename: resolved, contents: await fs.readFile(resolved, "utf8") };
return { filename: id, contents: await fs.readFile(id, "utf8") };
}
}

return new StylesFileManager();
})();
};

const importPlugin: Plugin = {
install(_, pluginManager) {
pluginManager.addFileManager(getManager());
pluginManager.addFileManager(getStylesFileManager());
},
};

Expand Down
29 changes: 21 additions & 8 deletions src/typings/less.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ declare module "less" {
filename: string;
relativeUrls: boolean;
rootpath: string;
currentDirectory: string;
currentDir: string;
entryPath: string;
rootFilename: string;
reference: boolean;
Expand Down Expand Up @@ -34,18 +34,30 @@ declare module "less" {

export type LoadOptions = { [k: string]: unknown };

class AbstractFileManager {}
class FileManager extends AbstractFileManager {
supports(filename: string, currentDirectory: string, options: LoadOptions): boolean;
supportsSync(filename: string, currentDirectory: string, options: LoadOptions): boolean;
loadFile(filename: string, currentDirectory: string, options: LoadOptions): Promise<LoadedFile>;
loadFileSync(filename: string, currentDirectory: string, options: LoadOptions): LoadedFileSync;
export interface AbstractFileManagerInterface {
supportsSync(filename: string, currentDir: string, options: LoadOptions): boolean;
}

export interface FileManagerInterface extends AbstractFileManagerInterface {
supports(filename: string, currentDir: string, options: LoadOptions): boolean;
loadFile(filename: string, currentDir: string, options: LoadOptions): Promise<LoadedFile>;
loadFileSync?(filename: string, currentDir: string, options: LoadOptions): LoadedFileSync;
}

class AbstractFileManager implements AbstractFileManagerInterface {
supportsSync(filename: string, currentDir: string, options: LoadOptions): boolean;
}

class FileManager extends AbstractFileManager implements FileManagerInterface {
supports(filename: string, currentDir: string, options: LoadOptions): boolean;
loadFile(filename: string, currentDir: string, options: LoadOptions): Promise<LoadedFile>;
loadFileSync?(filename: string, currentDir: string, options: LoadOptions): LoadedFileSync;
}

class PluginManager {
constructor(less: Less);
addPreProcessor(preProcessor: PreProcessor, priority?: number): void;
addFileManager(fileManager: FileManager): void;
addFileManager(fileManager: FileManagerInterface): void;
}

export interface Plugin {
Expand Down Expand Up @@ -113,6 +125,7 @@ declare module "less" {
sheets: HTMLLinkElement[];
version: number[];

AbstractFileManager: typeof AbstractFileManager;
FileManager: typeof FileManager;

render(input: string, callback: RenderCallback): void;
Expand Down

0 comments on commit bf3710a

Please sign in to comment.