Skip to content

Commit

Permalink
Vue: Remove hasDefaultExport check from appEntrypoint logic (#9333)
Browse files Browse the repository at this point in the history
  • Loading branch information
natemoo-re committed Dec 6, 2023
1 parent cfb2055 commit b832cd1
Show file tree
Hide file tree
Showing 12 changed files with 149 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changeset/selfish-lamps-build.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/vue': patch
---

Fixes issue with `appEntrypoint` when running `astro dev`
27 changes: 22 additions & 5 deletions packages/integrations/vue/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Options as VueOptions } from '@vitejs/plugin-vue';
import type { Options as VueJsxOptions } from '@vitejs/plugin-vue-jsx';
import type { AstroIntegration, AstroIntegrationLogger, AstroRenderer } from 'astro';
import type { UserConfig, Rollup } from 'vite';
import type { UserConfig, Plugin } from 'vite';

import { fileURLToPath } from 'node:url';
import vue from '@vitejs/plugin-vue';
Expand Down Expand Up @@ -42,15 +42,32 @@ function getJsxRenderer(): AstroRenderer {
function virtualAppEntrypoint(options: ViteOptions) {
const virtualModuleId = 'virtual:@astrojs/vue/app';
const resolvedVirtualModuleId = '\0' + virtualModuleId;
let getExports: (id: string) => Promise<string[]>;
return {
name: '@astrojs/vue/virtual-app',
buildStart() {
if (!getExports) {
getExports = async (id: string) => {
const info = await this.load.call(this, { id });
return info.exports ?? [];
}
}
},
configureServer(server) {
if (!getExports) {
getExports = async (id: string) => {
const mod = await server.ssrLoadModule(id);
return Object.keys(mod) ?? [];
}
}
},
resolveId(id: string) {
if (id == virtualModuleId) {
return resolvedVirtualModuleId;
}
},
async load(id: string) {
const noop = `export const setup = () => {}`;
const noop = `export const setup = (app) => app;`;
if (id === resolvedVirtualModuleId) {
if (options.appEntrypoint) {
try {
Expand All @@ -66,8 +83,8 @@ function virtualAppEntrypoint(options: ViteOptions) {
// This error is handled below, the message isn't shown to the user
throw new Error('Unable to resolve appEntrypoint');
}
const loaded = await this.load(resolved);
if (!loaded.hasDefaultExport) {
const exports = await getExports(resolved.id);
if (!exports.includes('default')) {
options.logger.warn(
`appEntrypoint \`${options.appEntrypoint}\` does not export a default function. Check out https://docs.astro.build/en/guides/integrations-guide/vue/#appentrypoint.`
);
Expand All @@ -83,7 +100,7 @@ function virtualAppEntrypoint(options: ViteOptions) {
return noop;
}
},
} satisfies Rollup.Plugin;
} satisfies Plugin;
}

async function getViteConfiguration(options: ViteOptions): Promise<UserConfig> {
Expand Down
64 changes: 64 additions & 0 deletions packages/integrations/vue/test/app-entrypoint.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,39 @@ describe('App Entrypoint', () => {
});
});

describe('App Entrypoint no export default (dev)', () => {
/** @type {import('./test-utils').Fixture} */
let fixture;
let devServer;

before(async () => {
fixture = await loadFixture({
root: './fixtures/app-entrypoint-no-export-default/',
});
devServer = await fixture.startDevServer();
});

after(async () => {
await devServer.stop();
});

it('loads during SSR', async () => {
const html = await fixture.fetch('/').then(res => res.text());
const { document } = parseHTML(html);
const bar = document.querySelector('#foo > #bar');
expect(bar).not.to.be.undefined;
expect(bar.textContent).to.eq('works');
});

it('loads svg components without transforming them to assets', async () => {
const html = await fixture.fetch('/').then(res => res.text());
const { document } = parseHTML(html);
const client = document.querySelector('astro-island svg');

expect(client).not.to.be.undefined;
});
});

describe('App Entrypoint no export default', () => {
/** @type {import('./test-utils').Fixture} */
let fixture;
Expand Down Expand Up @@ -121,3 +154,34 @@ describe('App Entrypoint relative', () => {
expect(js).not.to.match(/\w+\.component\(\"Bar\"/gm);
});
});

describe('App Entrypoint /src/absolute', () => {
/** @type {import('./test-utils').Fixture} */
let fixture;

before(async () => {
fixture = await loadFixture({
root: './fixtures/app-entrypoint-src-absolute/',
});
await fixture.build();
});

it('loads during SSR', async () => {
const data = await fixture.readFile('/index.html');
const { document } = parseHTML(data);
const bar = document.querySelector('#foo > #bar');
expect(bar).not.to.be.undefined;
expect(bar.textContent).to.eq('works');
});

it('component not included in renderer bundle', async () => {
const data = await fixture.readFile('/index.html');
const { document } = parseHTML(data);
const island = document.querySelector('astro-island');
const client = island.getAttribute('renderer-url');
expect(client).not.to.be.undefined;

const js = await fixture.readFile(client);
expect(js).not.to.match(/\w+\.component\(\"Bar\"/gm);
});
});
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
console.log(123);
export const setup = () => {}

// no default export
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { defineConfig } from 'astro/config';
import vue from '@astrojs/vue';

export default defineConfig({
integrations: [vue({
appEntrypoint: '/src/vue.ts'
})]
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "@test/vue-app-entrypoint-src-absolute",
"version": "0.0.0",
"private": true,
"scripts": {
"astro": "astro"
},
"dependencies": {
"@astrojs/vue": "workspace:*",
"astro": "workspace:*"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<template>
<div id="bar">works</div>
</template>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script setup>
import Bar from './Bar.vue'
import Circle from './Circle.svg?component'
</script>

<template>
<div id="foo">
<Bar />
<Circle/>
</div>
</template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
import Foo from '../components/Foo.vue';
---

<html>
<head>
<title>Vue App Entrypoint</title>
</head>
<body>
<Foo client:load />
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default () => {}
9 changes: 9 additions & 0 deletions pnpm-lock.yaml

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

0 comments on commit b832cd1

Please sign in to comment.