diff --git a/src/runtime/server/index.ts b/src/runtime/server/index.ts index 7d7088ad81b6..da510f2fbf99 100644 --- a/src/runtime/server/index.ts +++ b/src/runtime/server/index.ts @@ -3,7 +3,7 @@ import type { AstroGlobalPartial, SSRResult, SSRElement } from '../../@types/ast import type { AstroRequest } from '../../core/render/request'; import shorthash from 'shorthash'; -import { extractDirectives, generateHydrateScript } from './hydration.js'; +import { extractDirectives, generateHydrateScript, serializeProps } from './hydration.js'; import { serializeListValue } from './util.js'; import { escapeHTML, HTMLString, markHTMLString } from './escape.js'; @@ -278,8 +278,8 @@ If you're still stuck, please open an issue on GitHub or join us at https://astr return markHTMLString(html.replace(/\<\/?astro-fragment\>/g, '')); } - // Include componentExport name and componentUrl in hash to dedupe identical islands - const astroId = shorthash.unique(`\n${html}`); + // Include componentExport name, componentUrl, and props in hash to dedupe identical islands + const astroId = shorthash.unique(`\n${html}\n${serializeProps(props)}`); // Rather than appending this inline in the page, puts this into the `result.scripts` set that will be appended to the head. // INVESTIGATE: This will likely be a problem in streaming because the `` will be gone at this point. diff --git a/test/fixtures/react-component/src/components/Hello.jsx b/test/fixtures/react-component/src/components/Hello.jsx index 4b6c416a98e7..4c241162d368 100644 --- a/test/fixtures/react-component/src/components/Hello.jsx +++ b/test/fixtures/react-component/src/components/Hello.jsx @@ -1,5 +1,5 @@ import React from 'react'; -export default function ({ name }) { - return

Hello {name}!

; +export default function ({ name, unused }) { + return

Hello {name}!

; } diff --git a/test/fixtures/react-component/src/pages/index.astro b/test/fixtures/react-component/src/pages/index.astro index 597a4a546a51..049b5fb6aa48 100644 --- a/test/fixtures/react-component/src/pages/index.astro +++ b/test/fixtures/react-component/src/pages/index.astro @@ -17,7 +17,12 @@ const someProps = { - + + + + + + diff --git a/test/fixtures/vue-component/src/components/Counter.vue b/test/fixtures/vue-component/src/components/Counter.vue index 49d2936edcd3..8cbb0f5503c4 100644 --- a/test/fixtures/vue-component/src/components/Counter.vue +++ b/test/fixtures/vue-component/src/components/Counter.vue @@ -20,12 +20,17 @@ export default { start: { type: String, required: true + }, + stepSize: { + type: String, + default: "1" } }, setup(props) { const count = ref(parseInt(props.start)) - const add = () => (count.value = count.value + 1); - const subtract = () => (count.value = count.value - 1); + const stepSize = ref(parseInt(props.stepSize)) + const add = () => (count.value = count.value + stepSize.value); + const subtract = () => (count.value = count.value - stepSize.value); return { count, add, diff --git a/test/fixtures/vue-component/src/pages/index.astro b/test/fixtures/vue-component/src/pages/index.astro index eed6624cce9d..7cae724dc9b1 100644 --- a/test/fixtures/vue-component/src/pages/index.astro +++ b/test/fixtures/vue-component/src/pages/index.astro @@ -20,6 +20,10 @@ import Counter from '../components/Counter.vue'
SSR Rendered, No Client SSR Rendered, client:load + + SSR Rendered, client:load + + SSR Rendered, client:load SSR Rendered, client:idle SSR Rendered, client:visible diff --git a/test/react-component.test.js b/test/react-component.test.js index a05f76cf9170..8e90f88ae420 100644 --- a/test/react-component.test.js +++ b/test/react-component.test.js @@ -25,10 +25,10 @@ describe('React Components', () => { const $ = cheerio.load(html); // test 1: basic component renders - expect($('#react-h2').text()).to.equal('Hello world!'); + expect($('#react-static').text()).to.equal('Hello static!'); // test 2: no reactroot - expect($('#react-h2').attr('data-reactroot')).to.equal(undefined); + expect($('#react-static').attr('data-reactroot')).to.equal(undefined); // test 3: Can use function components expect($('#arrow-fn-component')).to.have.lengthOf(1); @@ -44,6 +44,13 @@ describe('React Components', () => { // test 7: Can use Pure components expect($('#pure')).to.have.lengthOf(1); + + // test 8: Check number of islands + expect($('astro-root[uid]')).to.have.lengthOf(5); + + // test 9: Check island deduplication + const uniqueRootUIDs = new Set($('astro-root').map((i, el) => $(el).attr('uid'))); + expect(uniqueRootUIDs.size).to.equal(4); }); it('Can load Vue', async () => { diff --git a/test/vue-component.test.js b/test/vue-component.test.js index 46edcfbac376..7b226b91127d 100644 --- a/test/vue-component.test.js +++ b/test/vue-component.test.js @@ -29,17 +29,17 @@ describe('Vue component', () => { .map((el) => $(el).text()); // test 1: renders all components correctly - expect(allPreValues).to.deep.equal(['0', '1', '10', '100', '1000']); + expect(allPreValues).to.deep.equal(['0', '1', '1', '1', '10', '100', '1000']); // test 2: renders 3 s - expect($('astro-root')).to.have.lengthOf(4); + expect($('astro-root')).to.have.lengthOf(6); // test 3: all s have uid attributes - expect($('astro-root[uid]')).to.have.lengthOf(4); + expect($('astro-root[uid]')).to.have.lengthOf(6); - // test 5: all s have unique uid attributes + // test 5: components with identical render output and props have been deduplicated const uniqueRootUIDs = $('astro-root').map((i, el) => $(el).attr('uid')); - expect(new Set(uniqueRootUIDs).size).to.equal(4); + expect(new Set(uniqueRootUIDs).size).to.equal(5); }); });