Skip to content

Commit

Permalink
[nextjs] Fix path resolution
Browse files Browse the repository at this point in the history
This reverts the previous "fix" and uses the newly available
loaderContext from unplugin to do path resolution. Previous solution was
"hacky" in a sense since at that time, Unplugin did not expose loader's
context. So we had to do things manually which did not work reliably.
Now that we have "loaderContext" data, it's straighforward to just call
`loaderContext.resolve()` with the path and this works as expected.

Tested on our docs and user submitted repro repository.
  • Loading branch information
Brijesh Bittu committed Nov 10, 2024
1 parent 5c42fc3 commit a6085c8
Showing 1 changed file with 33 additions and 46 deletions.
79 changes: 33 additions & 46 deletions packages/pigment-css-unplugin/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
transform,
createFileReporter,
} from '@wyw-in-js/transform';
import { asyncResolveFallback, slugify } from '@wyw-in-js/shared';
import { slugify } from '@wyw-in-js/shared';
import {
UnpluginFactoryOutput,
WebpackPluginInstance,
Expand All @@ -25,7 +25,6 @@ import {
type PluginCustomOptions,
} from '@pigment-css/react/utils';
import { styledEngineMockup } from '@pigment-css/react/internal';

import { handleUrlReplacement, type AsyncResolver } from './utils';

type NextMeta = {
Expand Down Expand Up @@ -158,19 +157,6 @@ export const plugin = createUnplugin<PigmentOptions, true>((options) => {
};
const projectPath = meta?.type === 'next' ? meta.projectPath : process.cwd();

let webpackResolver: AsyncResolver;

const asyncResolve: AsyncResolver = async (what, importer, stack) => {
const result = await asyncResolveOpt?.(what, importer, stack);
if (typeof result === 'string') {
return result;
}
if (webpackResolver) {
return webpackResolver(what, importer, stack);
}
return asyncResolveFallback(what, importer, stack);
};

const withRtl = (selector: string, cssText: string) => {
return basePreprocessor(selector, cssText, css);
};
Expand All @@ -184,41 +170,42 @@ export const plugin = createUnplugin<PigmentOptions, true>((options) => {
transformInclude(id) {
return isZeroRuntimeProcessableFile(id, finalTransformLibraries);
},
webpack(compiler) {
compiler.resolverFactory.hooks.resolver
.for('normal')
.tap(`${pluginName}Resolver`, (resolver) => {
webpackResolver = (what: string, importer: string, stack: string[]) => {
const context = path.isAbsolute(importer)
? path.dirname(importer)
: path.join(projectPath, path.dirname(importer));
return new Promise((resolve, reject) => {
resolver.resolve(
{},
context,
what,
{
stack: new Set(stack),
},
(err, result) => {
if (typeof result !== 'string') {
reject(new Error(`${process.env.PACKAGE_NAME}: Could not resolve ${what}`));
} else if (result) {
resolve(result);
} else {
reject(err);
}
},
);
});
};
});
},
async transform(code, url) {
const [filePath] = url.split('?');
// Converts path separator as per platform, even on Windows, path segments have `/` instead of the usual `\`,
// so this function replaces such path separators.
const id = path.normalize(filePath);
// @ts-ignore
const nativeContext = this.getNativeBuildContext();
if (nativeContext?.framework !== 'webpack') {
throw new Error('This plugin should only be used with Webpack/Next.js.');
}
const asyncResolve = async (
token: string,
importer: string,
stack: string[],
): Promise<string> => {
const njsResult = await asyncResolveOpt?.(token, importer, stack);
if (typeof njsResult === 'string') {
return njsResult;
}
const context = path.isAbsolute(importer)
? path.dirname(importer)
: path.join(projectPath, path.dirname(importer));
return new Promise((resolve, reject) => {
nativeContext.loaderContext!.resolve(context, token, (err, result) => {
if (err) {
console.error(err);
reject(err);
} else if (result) {
nativeContext.loaderContext!.addDependency(result);
resolve(result);
} else {
reject(new Error(`${process.env.PACKAGE_NAME}: Cannot resolve ${token}`));
}
});
});
};
const transformServices = {
options: {
filename: id,
Expand Down Expand Up @@ -344,7 +331,7 @@ export const plugin = createUnplugin<PigmentOptions, true>((options) => {
};
}

const rootPath = process.cwd();
const rootPath = projectPath;

const cssFilename = path
.normalize(`${id.replace(/\.[jt]sx?$/, '')}-${slug}.pigment.css`)
Expand Down

0 comments on commit a6085c8

Please sign in to comment.