Skip to content

Commit

Permalink
chore: 调整目录
Browse files Browse the repository at this point in the history
  • Loading branch information
YufJi committed Feb 26, 2025
1 parent 3c77380 commit 1373dc2
Show file tree
Hide file tree
Showing 4 changed files with 403 additions and 228 deletions.
163 changes: 163 additions & 0 deletions packages/mako/src/lessLoader/plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import EnhancedResolve, { type ResolveFunctionAsync } from 'enhanced-resolve';

/* eslint-disable class-methods-use-this */
const trailingSlash = /[/\\]$/;

// This somewhat changed in Less 3.x. Now the file name comes without the
// automatically added extension whereas the extension is passed in as `options.ext`.
// So, if the file name matches this regexp, we simply ignore the proposed extension.
const IS_SPECIAL_MODULE_IMPORT = /^~[^/]+$/;

// `[drive_letter]:\` + `\\[server]\[share_name]\`
const IS_NATIVE_WIN32_PATH = /^[a-z]:[/\\]|^\\\\/i;

// Examples:
// - ~package
// - ~package/
// - ~@org
// - ~@org/
// - ~@org/package
// - ~@org/package/
const IS_MODULE_IMPORT =
/^~([^/]+|[^/]+\/|@[^/]+[/][^/]+|@[^/]+\/?|@[^/]+[/][^/]+\/)$/;
const MODULE_REQUEST_REGEX = /^[^?]*~/;

export function createLessPlugin(less: LessStatic): Less.Plugin {
const resolve = EnhancedResolve.create({
conditionNames: ['less', 'style', '...'],
mainFields: ['less', 'style', 'main', '...'],
mainFiles: ['index', '...'],
extensions: ['.less', '.css'],
preferRelative: true,
});

class FileManager extends less.FileManager {
supports(filename: string) {
if (filename[0] === '/' || IS_NATIVE_WIN32_PATH.test(filename)) {
return true;
}

if (this.isPathAbsolute(filename)) {
return false;
}

return true;
}

supportsSync() {
return false;
}

async resolveFilename(filename: string, currentDirectory: string) {
// Less is giving us trailing slashes, but the context should have no trailing slash
const context = currentDirectory.replace(trailingSlash, '');

let request = filename;

// A `~` makes the url an module
if (MODULE_REQUEST_REGEX.test(filename)) {
request = request.replace(MODULE_REQUEST_REGEX, '');
}

if (IS_MODULE_IMPORT.test(filename)) {
request = request[request.length - 1] === '/' ? request : `${request}/`;
}

return this.resolveRequests(context, [...new Set([request, filename])]);
}

async resolveRequests(
context: string,
possibleRequests: string[],
): Promise<string> {
if (possibleRequests.length === 0) {
return Promise.reject();
}

let result;

try {
result = await asyncResolve(context, possibleRequests[0], resolve);
} catch (error) {
const [, ...tailPossibleRequests] = possibleRequests;

if (tailPossibleRequests.length === 0) {
throw error;
}

result = await this.resolveRequests(context, tailPossibleRequests);
}

return result;
}

async loadFile(
filename: string,
currentDirectory: string,
options: Less.LoadFileOptions,
environment: Less.Environment,
) {
let result;

try {
if (IS_SPECIAL_MODULE_IMPORT.test(filename)) {
const error = new Error() as any;
error.type = 'Next';
throw error;
}

result = await super.loadFile(
filename,
currentDirectory,
options,
environment,
);
} catch (error: any) {
if (error.type !== 'File' && error.type !== 'Next') {
return Promise.reject(error);
}

try {
result = await this.resolveFilename(filename, currentDirectory);
} catch (webpackResolveError) {
return Promise.reject(error);
}

// addDependency(result);

return super.loadFile(result, currentDirectory, options, environment);
}

// const absoluteFilename = path.isAbsolute(result.filename)
// ? result.filename
// : path.resolve(".", result.filename);
// addDependency(path.normalize(absoluteFilename));

return result;
}
}

return {
install(_lessInstance, pluginManager) {
pluginManager.addFileManager(new FileManager());
},
minVersion: [3, 0, 0],
};
}

function asyncResolve(
context: string,
path: string,
resolve: ResolveFunctionAsync,
): Promise<string> {
return new Promise((res, rej) => {
resolve(context, path, (err, result) => {
if (err) {
rej(err);
return;
}

res(result as string);
});
});
}
3 changes: 3 additions & 0 deletions packages/mako/src/lessLoader/render.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import fs from 'fs';
import less from 'less';
import { LessLoaderOpts } from '.';
import { createLessPlugin } from './plugin';

module.exports = async function render(param: {
filename: string;
Expand All @@ -19,6 +20,8 @@ module.exports = async function render(param: {
}
});

pluginInstances?.unshift(createLessPlugin(less));

const result = await less
.render(input, {
filename: param.filename,
Expand Down
Loading

0 comments on commit 1373dc2

Please sign in to comment.