Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,5 +77,8 @@
}
}
]
},
"dependencies": {
"json5": "^2.2.3"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,24 +45,22 @@ describe('StyleX Alias Configuration', () => {
}
};

test('discovers aliases from package.json', () => {
test('discovers aliases from package.json imports', () => {
setupFiles({
'package.json': {
name: 'test-package',
stylex: {
aliases: {
'@components': './src/components',
'@utils/*': ['./src/utils/*'],
},
imports: {
'#components': './src/components',
'#utils/*': './src/utils/*',
},
},
});

const manager = new StateManager(state);

expect(manager.options.aliases).toEqual({
'@components': ['./src/components'],
'@utils/*': ['./src/utils/*'],
'components': ['./src/components'],
'utils/*': ['./src/utils/*'],
});
});

Expand All @@ -88,14 +86,31 @@ describe('StyleX Alias Configuration', () => {
});
});

test('merges aliases from both package.json and tsconfig.json', () => {
test('discovers aliases from deno.json', () => {
setupFiles({
'package.json': { name: 'test-package' },
'deno.json': {
imports: {
'@components/': './src/components/',
'@utils/': './src/utils/',
},
},
});

const manager = new StateManager(state);

expect(manager.options.aliases).toEqual({
'@components/': ['./src/components/'],
'@utils/': ['./src/utils/'],
});
});

test('merges aliases from all config files', () => {
setupFiles({
'package.json': {
name: 'test-package',
stylex: {
aliases: {
'@components': './src/components',
},
imports: {
'#components': './src/components',
},
},
'tsconfig.json': {
Expand All @@ -106,38 +121,42 @@ describe('StyleX Alias Configuration', () => {
},
},
},
'deno.json': {
imports: {
'@styles/': './src/styles/',
},
},
});

const manager = new StateManager(state);

expect(manager.options.aliases).toEqual({
'@components': ['./src/components'],
'components': ['./src/components'],
'@utils': ['src/utils'],
'@styles/': ['./src/styles/'],
});
});

test('manual configuration overrides discovered aliases', () => {
setupFiles({
'package.json': {
name: 'test-package',
stylex: {
aliases: {
'@components': './src/components',
},
imports: {
'#components': './src/components',
},
},
});

state.opts = {
aliases: {
'@components': './custom/path',
'components': './custom/path',
},
};

const manager = new StateManager(state);

expect(manager.options.aliases).toEqual({
'@components': ['./custom/path'],
'components': ['./custom/path'],
});
});

Expand All @@ -150,6 +169,7 @@ describe('StyleX Alias Configuration', () => {
setupFiles({
'package.json': '{invalid json',
'tsconfig.json': '{also invalid',
'deno.json': '{more invalid',
});

const manager = new StateManager(state);
Expand Down
57 changes: 41 additions & 16 deletions packages/babel-plugin/src/utils/state-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -624,17 +624,34 @@ export default class StateManager {

let packageAliases = {};
let tsconfigAliases = {};
const projectDir = this.findProjectRoot(this.filename);
let denoAliases = {};

// Load aliases from package.json
const pkgInfo = this.getPackageNameAndPath(this.filename);
if (!pkgInfo) {
return manualAliases ? this.normalizeAliases(manualAliases) : null;
}

const [_packageName, projectDir] = pkgInfo;

// Load aliases from package.json imports field
try {
const packageJsonPath = path.join(projectDir, 'package.json');
if (fs.existsSync(packageJsonPath)) {
const packageJson = JSON.parse(
fs.readFileSync(packageJsonPath, 'utf8'),
);
if (packageJson.stylex?.aliases) {
packageAliases = packageJson.stylex.aliases;

// Handle Node.js native imports
const imports = packageJson.imports;
if (imports && typeof imports === 'object') {
packageAliases = Object.fromEntries(
Object.entries(imports)
.filter(([key]) => key.startsWith('#'))
.map(([key, value]) => [
key.slice(1),
Array.isArray(value) ? value : [value],
])
);
}
}
} catch (err) {
Expand Down Expand Up @@ -672,8 +689,27 @@ export default class StateManager {
console.warn('Failed to load aliases from tsconfig.json:', err.message);
}

// Merge aliases in priority: manual > package.json > tsconfig.json
// Load aliases from deno.json
try {
const denoConfigPath = path.join(projectDir, 'deno.json');
if (fs.existsSync(denoConfigPath)) {
const denoConfig = JSON5.parse(fs.readFileSync(denoConfigPath, 'utf8'));
if (denoConfig.imports) {
denoAliases = Object.fromEntries(
Object.entries(denoConfig.imports).map(([key, value]) => [
key,
Array.isArray(value) ? value : [value],
])
);
}
}
} catch (err) {
console.warn('Failed to load aliases from deno.json:', err.message);
}

// Merge aliases in priority: manual > package.json > tsconfig.json > deno.json
const mergedAliases = {
...denoAliases,
...tsconfigAliases,
...packageAliases,
...(manualAliases || {}),
Expand All @@ -697,17 +733,6 @@ export default class StateManager {
);
}

findProjectRoot(filePath: string): string {
const dir = path.dirname(filePath);
if (fs.existsSync(path.join(dir, 'package.json'))) {
return dir;
}
if (dir === path.parse(dir).root) {
return dir;
}
return this.findProjectRoot(dir);
}

normalizePath(filePath: string): string {
return filePath.split(path.sep).join('/');
}
Expand Down
Loading