Skip to content

Commit

Permalink
Fix importing client-side components with alias (#5845)
Browse files Browse the repository at this point in the history
  • Loading branch information
bluwy committed Jan 14, 2023
1 parent 3a00ecb commit e818cc0
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/ninety-garlics-fly.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Fix importing client-side components with alias
2 changes: 2 additions & 0 deletions packages/astro/src/core/build/static-build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { generatePages } from './generate.js';
import { trackPageData } from './internal.js';
import type { PageBuildData, StaticBuildOptions } from './types';
import { getTimeStat } from './util.js';
import { vitePluginAliasResolve } from './vite-plugin-alias-resolve.js';
import { vitePluginAnalyzer } from './vite-plugin-analyzer.js';
import { rollupPluginAstroBuildCSS } from './vite-plugin-css.js';
import { vitePluginHoistedScripts } from './vite-plugin-hoisted-scripts.js';
Expand Down Expand Up @@ -221,6 +222,7 @@ async function clientBuild(
},
},
plugins: [
vitePluginAliasResolve(internals),
vitePluginInternals(input, internals),
vitePluginHoistedScripts(settings, internals),
rollupPluginAstroBuildCSS({
Expand Down
50 changes: 50 additions & 0 deletions packages/astro/src/core/build/vite-plugin-alias-resolve.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import type { Alias, Plugin as VitePlugin } from 'vite';
import type { BuildInternals } from '../../core/build/internal.js';

/**
* `@rollup/plugin-alias` doesn't resolve aliases in Rollup input by default. This plugin fixes it
* with a partial fork of it's resolve function. https://github.com/rollup/plugins/blob/master/packages/alias/src/index.ts
* When https://github.com/rollup/plugins/pull/1402 is merged, we can remove this plugin.
*/
export function vitePluginAliasResolve(internals: BuildInternals): VitePlugin {
let aliases: Alias[];

return {
name: '@astro/plugin-alias-resolve',
enforce: 'pre',
configResolved(config) {
aliases = config.resolve.alias;
},
async resolveId(id, importer, opts) {
if (
!importer &&
(internals.discoveredHydratedComponents.has(id) ||
internals.discoveredClientOnlyComponents.has(id))
) {
const matchedEntry = aliases.find((entry) => matches(entry.find, id));
if (!matchedEntry) {
return null;
}

const updatedId = id.replace(matchedEntry.find, matchedEntry.replacement);

return this.resolve(updatedId, importer, Object.assign({ skipSelf: true }, opts)).then(
(resolved) => resolved || { id: updatedId }
);
}
},
};
}

function matches(pattern: string | RegExp, importee: string) {
if (pattern instanceof RegExp) {
return pattern.test(importee);
}
if (importee.length < pattern.length) {
return false;
}
if (importee === pattern) {
return true;
}
return importee.startsWith(pattern + '/');
}
17 changes: 17 additions & 0 deletions packages/astro/test/alias.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,21 @@ describe('Aliases', () => {
expect(scripts.length).to.be.greaterThan(0);
});
});

describe('build', () => {
before(async () => {
await fixture.build();
});

it('can load client components', async () => {
const html = await fixture.readFile('/index.html');
const $ = cheerio.load(html);

// Should render aliased element
expect($('#client').text()).to.equal('test');

const scripts = $('script').toArray();
expect(scripts.length).to.be.greaterThan(0);
});
});
});

0 comments on commit e818cc0

Please sign in to comment.