Skip to content

Commit

Permalink
fix: move alias rewriting to babel plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
nmn committed Jan 13, 2025
1 parent 10e5495 commit 7e3b37c
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 152 deletions.
44 changes: 44 additions & 0 deletions packages/babel-plugin/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ import type { NodePath } from '@babel/traverse';
import type { PluginObj } from '@babel/core';
import type { StyleXOptions } from './utils/state-manager';
import StateManager from './utils/state-manager';
import {
EXTENSIONS,
filePathResolver,
matchesFileSuffix,
getRelativePath,
} from './utils/state-manager';
import { readImportDeclarations, readRequires } from './visitors/imports';
import transformStyleXCreate from './visitors/stylex-create';
import transformStyleXDefineVars from './visitors/stylex-define-vars';
Expand Down Expand Up @@ -74,6 +80,44 @@ function styleXTransform(): PluginObj<> {
// variables entirely if they're not needed.
exit: (path: NodePath<t.Program>) => {
path.traverse({
ImportDeclaration(path: NodePath<t.ImportDeclaration>) {
const filename = state.filename;
if (filename == null || !state.options.rewriteAliases) {
return;
}

const source = path.node.source.value;

const aliases = state.options.aliases;

const themeFileExtension = '.stylex';
if (!matchesFileSuffix(themeFileExtension)(source)) {
return;
}
const resolvedFilePath = filePathResolver(
source,
filename,
aliases,
);

if (resolvedFilePath == null) {
return;
}

let relativeFilePath = getRelativePath(
filename,
resolvedFilePath,
);

const extension = EXTENSIONS.find((ext) =>
relativeFilePath.endsWith(ext),
);
if (extension != null) {
relativeFilePath = relativeFilePath.slice(0, -extension.length);
}

path.node.source.value = relativeFilePath;
},
Identifier(path: NodePath<t.Identifier>) {
// Look for variables bound to `stylex.create` calls that are used
// outside of `stylex(...)` calls
Expand Down
21 changes: 20 additions & 1 deletion packages/babel-plugin/src/utils/state-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,15 @@ export type StyleXOptions = $ReadOnly<{
genConditionalClasses: boolean,
unstable_moduleResolution?: ?ModuleResolution,
aliases?: ?$ReadOnly<{ [string]: string | $ReadOnlyArray<string> }>,
rewriteAliases?: boolean,
...
}>;

type StyleXStateOptions = $ReadOnly<{
...StyleXOptions,
runtimeInjection: ?string | $ReadOnly<{ from: string, as: ?string }>,
aliases?: ?$ReadOnly<{ [string]: $ReadOnlyArray<string> }>,
rewriteAliases: boolean,
...
}>;

Expand Down Expand Up @@ -289,6 +291,10 @@ export default class StateManager {
styleResolution,
unstable_moduleResolution,
treeshakeCompensation,
rewriteAliases:
typeof options.rewriteAliases === 'boolean'
? options.rewriteAliases
: false,
};
return opts;
}
Expand Down Expand Up @@ -694,7 +700,7 @@ export const filePathResolver = (
return null;
};

const EXTENSIONS = ['.js', '.ts', '.tsx', '.jsx', '.mjs', '.cjs'];
export const EXTENSIONS = ['.js', '.ts', '.tsx', '.jsx', '.mjs', '.cjs'];

const addFileExtension = (
importedFilePath: string,
Expand Down Expand Up @@ -744,3 +750,16 @@ const getProgramStatement = (path: NodePath<>): NodePath<> => {
}
return programPath;
};

export function getRelativePath(from: string, to: string): string {
const relativePath = path.relative(path.parse(from).dir, to);
return formatRelativePath(toPosixPath(relativePath));
}

function toPosixPath(filePath: string): string {
return filePath.split(path.sep).join(path.posix.sep);
}

function formatRelativePath(filePath: string) {
return filePath.startsWith('.') ? filePath : './' + filePath;
}
142 changes: 0 additions & 142 deletions packages/cli/src/plugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ import type { NodePath } from '@babel/traverse';
import { getRelativePath } from './files';
import { findModuleDir } from './modules';
import * as t from '@babel/types';
import { moduleResolve } from '@dual-bundle/import-meta-resolve';
import url from 'url';

import * as nodePath from 'path';

Expand Down Expand Up @@ -121,143 +119,3 @@ export const createModuleImportModifierPlugin = (
},
};
};

export const createAliasRewritePlugin = (
sourceFilePath: string,
aliasConfig: $ReadOnly<{ [string]: string | $ReadOnlyArray<string> }>,
): ImportModifierPlugin => {
return {
visitor: {
Program: {
exit(path: NodePath<t.Program>) {
path.traverse({
ImportDeclaration: {
enter(path: NodePath<t.ImportDeclaration>) {
const source = path.node.source.value;

const aliases =
aliasConfig == null
? aliasConfig
: Object.fromEntries(
Object.entries(aliasConfig).map(([key, value]) => {
if (typeof value === 'string') {
return [key, [value]];
}
return [key, value];
}),
);

const themeFileExtension = '.stylex';
if (!matchesFileSuffix(themeFileExtension)(source)) {
return;
}
const resolvedFilePath = filePathResolver(
source,
sourceFilePath,
aliases,
);

if (resolvedFilePath == null) {
return;
}

let relativeFilePath = getRelativePath(
sourceFilePath,
resolvedFilePath,
);

const extension = EXTENSIONS.find((ext) =>
relativeFilePath.endsWith(ext),
);
if (extension != null) {
relativeFilePath = relativeFilePath.slice(
0,
-extension.length,
);
}

path.node.source.value = relativeFilePath;
},
},
});
},
},
},
};
};

const matchesFileSuffix = (allowedSuffix: string) => (filename: string) =>
filename.endsWith(`${allowedSuffix}.js`) ||
filename.endsWith(`${allowedSuffix}.ts`) ||
filename.endsWith(`${allowedSuffix}.tsx`) ||
filename.endsWith(`${allowedSuffix}.jsx`) ||
filename.endsWith(`${allowedSuffix}.mjs`) ||
filename.endsWith(`${allowedSuffix}.cjs`) ||
filename.endsWith(allowedSuffix);

const EXTENSIONS = ['.js', '.ts', '.tsx', '.jsx', '.mjs', '.cjs'];
const filePathResolver = (
relativeFilePath: string,
sourceFilePath: string,
aliases: $ReadOnly<{ [string]: $ReadOnlyArray<string> }>,
): ?string => {
// Try importing without adding any extension
// and then every supported extension
for (const ext of ['', ...EXTENSIONS]) {
const importPathStr = relativeFilePath + ext;

// Try to resolve relative paths as is
if (importPathStr.startsWith('.')) {
try {
return moduleResolve(importPathStr, url.pathToFileURL(sourceFilePath))
.pathname;
} catch {
continue;
}
}

// Otherwise, try to resolve the path with aliases
const allAliases = possibleAliasedPaths(importPathStr, aliases);
for (const possiblePath of allAliases) {
try {
return moduleResolve(possiblePath, url.pathToFileURL(sourceFilePath))
.pathname;
} catch {
continue;
}
}
}
// Failed to resolve the file path
return null;
};

function possibleAliasedPaths(
importPath: string,
aliases: $ReadOnly<{ [string]: $ReadOnlyArray<string> }>,
): $ReadOnlyArray<string> {
const result = [importPath];
if (aliases == null || Object.keys(aliases).length === 0) {
return result;
}

for (const [alias, value] of Object.entries(aliases)) {
if (alias.includes('*')) {
const [before, after] = alias.split('*');
if (importPath.startsWith(before) && importPath.endsWith(after)) {
const replacementString = importPath.slice(
before.length,
after.length > 0 ? -after.length : undefined,
);
value.forEach((v) => {
result.push(v.split('*').join(replacementString));
});
}
} else if (alias === importPath) {
value.forEach((v) => {
result.push(v);
});
}
}

return result;
}
11 changes: 2 additions & 9 deletions packages/cli/src/transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import {
getDefaultCachePath,
} from './cache';
import {
createAliasRewritePlugin,
createImportPlugin,
createModuleImportModifierPlugin,
} from './plugins';
Expand Down Expand Up @@ -156,8 +155,6 @@ export async function transformFile(
: path.join(config.output, config.styleXBundleName),
);

const aliases = config.styleXConfig?.aliases;

const result = await babel.transformFileAsync(inputFilePath, {
babelrc: false,
presets: config.babelPresets,
Expand All @@ -173,15 +170,11 @@ export async function transformFile(
rootDir: path.parse(config.output).dir,
},
...(config.styleXConfig as $FlowFixMe),
rewriteAliases: true,
},
],
createImportPlugin(relativeImport),
...[
aliases != null
? createAliasRewritePlugin(inputFilePath, aliases)
: null,
...(config.babelPluginsPost ?? []),
].filter(Boolean),
...(config.babelPluginsPost ?? []),
],
});
if (result == null) {
Expand Down

0 comments on commit 7e3b37c

Please sign in to comment.