Skip to content

Commit

Permalink
Fix: catastrophic backtracking and esbuild platform (#238)
Browse files Browse the repository at this point in the history
* Update lock file

* Fix: use browser build for client components

* Change: escape quot

* Fix: catastrophic backtracking

* Add: performance test

* Revert lock file
  • Loading branch information
eight04 authored Mar 3, 2022
1 parent a6e88b9 commit 4f14a7e
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 8 deletions.
2 changes: 1 addition & 1 deletion src/esbuild/esbuildBundler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ const svelteHandler = async ({ elderConfig, svelteConfig, replacements, restartH
},
format: 'esm',
target: ['es2020'],
platform: 'node',
platform: 'browser',
sourcemap: !production,
minify: true,
splitting: true,
Expand Down
16 changes: 13 additions & 3 deletions src/partialHydration/__tests__/mountComponentsInHtml.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ describe('#mountComponentsInHtml', () => {

mountComponentsInHtml.default({
page,
html: `<div class="svelte-datepicker"><div class="ejs-component" data-ejs-component="Datepicker" data-ejs-props="{ "a": "b" }" data-ejs-options="{ "loading": "lazy" }"></div></div>`,
html: `<div class="svelte-datepicker"><div class="ejs-component" data-ejs-component="Datepicker" data-ejs-props="{ &quot;a&quot;: &quot;b&quot; }" data-ejs-options="{ &quot;loading&quot;: &quot;lazy&quot; }"></div></div>`,
hydrateOptions: undefined,
});
expect(hydrated).toEqual(['{"name":"Datepicker","props":{"a":"b"},"hydrateOptions":{"loading":"lazy"}}']);
Expand All @@ -48,7 +48,7 @@ describe('#mountComponentsInHtml', () => {

mountComponentsInHtml.default({
page,
html: `<div class="svelte-datepicker"><div class="ejs-component" data-ejs-component="Picker" data-ejs-props="{ "a": "b" }" data-ejs-options="{ "loading": "lazy" }"></div><div class="ejs-component" data-ejs-component="Picker" data-ejs-props="{ "a": "b" }" data-ejs-options="{ "loading": "eager" }"></div></div>`,
html: `<div class="svelte-datepicker"><div class="ejs-component" data-ejs-component="Picker" data-ejs-props="{ &quot;a&quot;: &quot;b&quot; }" data-ejs-options="{ &quot;loading&quot;: &quot;lazy&quot; }"></div><div class="ejs-component" data-ejs-component="Picker" data-ejs-props="{ &quot;a&quot;: &quot;b&quot; }" data-ejs-options="{ &quot;loading&quot;: &quot;eager&quot; }"></div></div>`,
hydrateOptions: undefined,
});
expect(hydrated).toEqual([
Expand All @@ -64,7 +64,7 @@ describe('#mountComponentsInHtml', () => {

mountComponentsInHtml.default({
page,
html: `<div class="svelte-datepicker"><div class="ejs-component" data-ejs-component="Sicker" data-ejs-props="{ "a": "b" }" data-ejs-options="{ "loading": "lazy" }"></div><div class="ejs-component" data-ejs-component="Picker" data-ejs-props="{ "a": "b" }" data-ejs-options="{ "loading": "eager" }"></div><div class="ejs-component" data-ejs-component="Ricker" data-ejs-props="{ "a": "b" }" data-ejs-options="{ "loading": "lazy" }"></div>`,
html: `<div class="svelte-datepicker"><div class="ejs-component" data-ejs-component="Sicker" data-ejs-props="{ &quot;a&quot;: &quot;b&quot; }" data-ejs-options="{ &quot;loading&quot;: &quot;lazy&quot; }"></div><div class="ejs-component" data-ejs-component="Picker" data-ejs-props="{ &quot;a&quot;: &quot;b&quot; }" data-ejs-options="{ &quot;loading&quot;: &quot;eager&quot; }"></div><div class="ejs-component" data-ejs-component="Ricker" data-ejs-props="{ &quot;a&quot;: &quot;b&quot; }" data-ejs-options="{ &quot;loading&quot;: &quot;lazy&quot; }"></div>`,
hydrateOptions: undefined,
});
expect(hydrated).toEqual([
Expand Down Expand Up @@ -94,4 +94,14 @@ describe('#mountComponentsInHtml', () => {
'{"name":"Alock","props":{},"hydrateOptions":{"loading":"lazy"}}',
]);
});

it('Performance test (#235)', () => {
const mountComponentsInHtml = require('../mountComponentsInHtml');
const comp = '<p><div class="ejs-component" data-ejs-component="Sicker" data-ejs-props="{ &quot;a&quot;: &quot;b&quot; }" data-ejs-options="{ &quot;loading&quot;: &quot;lazy&quot; }"></div></p>\n';
mountComponentsInHtml.default({
page,
html: comp.repeat(1000),
hydrateOptions: undefined,
});
});
});
2 changes: 1 addition & 1 deletion src/partialHydration/mountComponentsInHtml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default function mountComponentsInHtml({ page, html, hydrateOptions }): s
let outputHtml = html;
// sometimes svelte adds a class to our inlining.
const matches = outputHtml.matchAll(
/<(\S+) class="ejs-component[^]*?" data-ejs-component="([A-Za-z]+)" data-ejs-props="({[^]*?})" data-ejs-options="({[^]*?})"><\/\1>/gim,
/<([^<>\s]+) class="ejs-component[^"]*?" data-ejs-component="([A-Za-z]+)" data-ejs-props="({[^"]*?})" data-ejs-options="({[^"]*?})"><\/\1>/gim,
);

for (const match of matches) {
Expand Down
6 changes: 3 additions & 3 deletions src/utils/__tests__/svelteComponent.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ describe('#svelteComponent', () => {
render: () => ({
head: '<head>',
css: { code: '<old>' },
html: '<div class="svelte-datepicker"><div class="ejs-component" data-ejs-component="Datepicker" data-ejs-props="{ "a": "b" }" data-ejs-options="{ "loading": "lazy", "element": "div" }"></div></div>',
html: '<div class="svelte-datepicker"><div class="ejs-component" data-ejs-component="Datepicker" data-ejs-props="{ &quot;a&quot;: &quot;b&quot; }" data-ejs-options="{ &quot;loading&quot;: &quot;lazy&quot;, &quot;element&quot;: &quot;div&quot; }"></div></div>',
}),
_css: ['<css>', '<css2>'],
}),
Expand Down Expand Up @@ -125,7 +125,7 @@ describe('#svelteComponent', () => {
render: () => ({
head: '<head>',
css: { code: '<old>' },
html: '<div class="svelte-datepicker"><div class="ejs-component" data-ejs-component="Datepicker" data-ejs-props="{ "a": "b" }" data-ejs-options="{ "loading": "lazy", "element": "div" }"></div></div>',
html: '<div class="svelte-datepicker"><div class="ejs-component" data-ejs-component="Datepicker" data-ejs-props="{ &quot;a&quot;: &quot;b&quot; }" data-ejs-options="{ &quot;loading&quot;: &quot;lazy&quot;, &quot;element&quot;: &quot;div&quot; }"></div></div>',
}),
_css: ['<css>', '<css2>'],
_cssMap: ['<cssmap>', '<cssmap2>'],
Expand Down Expand Up @@ -204,7 +204,7 @@ describe('#svelteComponent', () => {
render: () => ({
head: '<head>',
css: { code: '<old>' },
html: '<div class="svelte-datepicker"><div class="ejs-component" data-ejs-component="Datepicker" data-ejs-props="{ "a": "b" }" data-ejs-options="{ "loading": "lazy", "element": "div" }"></div></div>',
html: '<div class="svelte-datepicker"><div class="ejs-component" data-ejs-component="Datepicker" data-ejs-props="{ &quot;a&quot;: &quot;b&quot; }" data-ejs-options="{ &quot;loading&quot;: &quot;lazy&quot;, &quot;element&quot;: &quot;div&quot; }"></div></div>',
}),
_css: ['<css>', '<css2>'],
_cssMap: ['<cssmap>', '<cssmap2>'],
Expand Down

0 comments on commit 4f14a7e

Please sign in to comment.