Skip to content

Commit

Permalink
fix: update svelte-hmr and enable partial accept (#440)
Browse files Browse the repository at this point in the history
* fix: update svelte-hmr and enable partial accept to allow context=module updates, see issue #134

* test: harden partialAccept test (#441)

* refactor: improve test logic to avoid jest syntax from hell

Co-authored-by: rixo <rixo@rixo.fr>
  • Loading branch information
dominikg and rixo committed Sep 17, 2022
1 parent 9a7115f commit f6d7007
Show file tree
Hide file tree
Showing 12 changed files with 84 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .changeset/little-ligers-look.md
@@ -0,0 +1,5 @@
---
'@sveltejs/vite-plugin-svelte': patch
---

update svelte-hmr and enable partial hmr accept by default (fixes #134)
17 changes: 17 additions & 0 deletions packages/e2e-tests/hmr/__tests__/hmr.spec.ts
Expand Up @@ -4,6 +4,7 @@ import {
getEl,
getText,
editFileAndWaitForHmrComplete,
hmrCount,
untilMatches,
sleep,
getColor,
Expand Down Expand Up @@ -54,6 +55,10 @@ test('should respect transforms', async () => {
if (!isBuild) {
describe('hmr', () => {
const updateHmrTest = editFileAndWaitForHmrComplete.bind(null, 'src/components/HmrTest.svelte');
const updateModuleContext = editFileAndWaitForHmrComplete.bind(
null,
'src/components/partial-hmr/ModuleContext.svelte'
);
const updateApp = editFileAndWaitForHmrComplete.bind(null, 'src/App.svelte');
const updateStore = editFileAndWaitForHmrComplete.bind(null, 'src/stores/hmr-stores.js');

Expand Down Expand Up @@ -136,6 +141,18 @@ if (!isBuild) {
expect(await getText(`#hmr-test-3 .counter`)).toBe('0');
});

test('should work when editing script context="module"', async () => {
expect(await getText(`#hmr-with-context`)).toContain('x=0 y=1 slot=1');
expect(await getText(`#hmr-without-context`)).toContain('x=0 y=1 slot=');
expect(hmrCount('UsingNamed.svelte'), 'updates for UsingNamed.svelte').toBe(0);
expect(hmrCount('UsingDefault.svelte'), 'updates for UsingDefault.svelte').toBe(0);
await updateModuleContext((content) => content.replace('y = 1', 'y = 2'));
expect(await getText(`#hmr-with-context`)).toContain('x=0 y=2 slot=2');
expect(await getText(`#hmr-without-context`)).toContain('x=0 y=2 slot=');
expect(hmrCount('UsingNamed.svelte'), 'updates for UsingNamed.svelte').toBe(1);
expect(hmrCount('UsingDefault.svelte'), 'updates for UsingDefault.svelte').toBe(0);
});

test('should work with emitCss: false in vite config', async () => {
await editViteConfig((c) => c.replace('svelte()', 'svelte({emitCss:false})'));
expect(await getText(`#hmr-test-1 .counter`)).toBe('0');
Expand Down
4 changes: 4 additions & 0 deletions packages/e2e-tests/hmr/src/App.svelte
Expand Up @@ -2,6 +2,7 @@
import StaticImport from './components/StaticImport.svelte';
import Dependency from 'e2e-test-dep-svelte-simple';
import HmrTest from './components/HmrTest.svelte';
import PartialHmr from './components/partial-hmr/PartialHmr.svelte';
const jsTransform = '__JS_TRANSFORM_1__';
let dynamicImportComponent;
function importDynamic() {
Expand All @@ -25,6 +26,9 @@
<HmrTest id="hmr-test-2" />

<!-- HMR-TEMPLATE-INJECT -->

<PartialHmr />

<style>
h1 {
color: #111111;
Expand Down
@@ -0,0 +1,12 @@
<script context="module">
export let y = 1;
</script>

<script>
export let id;
let x = 0;
</script>

<pre {id}>
x={x} y={y} slot=<slot />
</pre>
@@ -0,0 +1,7 @@
<script>
import UsingNamed from './UsingNamed.svelte';
import UsingOnlyDefault from './UsingOnlyDefault.svelte';
</script>

<UsingNamed />
<UsingOnlyDefault />
@@ -0,0 +1,5 @@
<script>
import ModuleContext, { y } from './ModuleContext.svelte';
</script>

<ModuleContext id="hmr-with-context">{y}</ModuleContext>
@@ -0,0 +1,5 @@
<script>
import ModuleContext from './ModuleContext.svelte';
</script>

<ModuleContext id="hmr-without-context" />
6 changes: 5 additions & 1 deletion packages/e2e-tests/testUtils.ts
Expand Up @@ -7,7 +7,7 @@ import colors from 'css-color-names';
import { ElementHandle } from 'playwright-core';
import fetch from 'node-fetch';

import { isBuild, isWin, isCI, page, testDir, viteTestUrl } from './vitestSetup';
import { isBuild, isWin, isCI, page, testDir, viteTestUrl, browserLogs } from './vitestSetup';

export * from './vitestSetup';

Expand Down Expand Up @@ -177,6 +177,10 @@ export async function editFileAndWaitForHmrComplete(file, replacer, fileUpdateTo
}
}

export function hmrCount(file) {
return browserLogs.filter((line) => line.includes('hot updated') && line.includes(file)).length;
}

export async function saveScreenshot(name: string) {
if (!page) {
return;
Expand Down
2 changes: 1 addition & 1 deletion packages/playground/kit-demo-app/src/routes/about/+page.js
@@ -1,4 +1,4 @@
import { browser, dev } from '$app/env';
import { browser, dev } from '$app/environment';

// we don't need any JS on this page, though we'll load
// it in dev so that we get hot module replacement...
Expand Down
2 changes: 1 addition & 1 deletion packages/vite-plugin-svelte/package.json
Expand Up @@ -51,7 +51,7 @@
"deepmerge": "^4.2.2",
"kleur": "^4.1.5",
"magic-string": "^0.26.3",
"svelte-hmr": "^0.14.12"
"svelte-hmr": "^0.15.0"
},
"peerDependencies": {
"diff-match-patch": "^1.0.5",
Expand Down
20 changes: 18 additions & 2 deletions packages/vite-plugin-svelte/src/utils/options.ts
Expand Up @@ -170,7 +170,12 @@ export function resolveOptions(
viteConfig: ResolvedConfig
): ResolvedOptions {
const defaultOptions: Partial<Options> = {
hot: viteConfig.isProduction ? false : { injectCss: !preResolveOptions.emitCss },
hot: viteConfig.isProduction
? false
: {
injectCss: !preResolveOptions.emitCss,
partialAccept: !!viteConfig.experimental?.hmrPartialAccept
},
compilerOptions: {
css: !preResolveOptions.emitCss,
dev: !viteConfig.isProduction
Expand Down Expand Up @@ -331,6 +336,17 @@ export function buildExtraViteConfig(
// @ts-ignore
extraViteConfig.ssr = buildSSROptionsForSvelte(svelteDeps, options, config, extraViteConfig);

// enable hmrPartialAccept if not explicitly disabled
if (
(options.hot == null ||
options.hot === true ||
(options.hot && options.hot.partialAccept !== false)) && // deviate from svelte-hmr, default to true
config.experimental?.hmrPartialAccept !== false
) {
log.debug('enabling "experimental.hmrPartialAccept" in vite config');
extraViteConfig.experimental = { hmrPartialAccept: true };
}

return extraViteConfig;
}

Expand Down Expand Up @@ -500,7 +516,7 @@ export interface PluginOptions {
* @see https://github.com/rixo/svelte-hmr#options
* @default true for development, always false for production
*/
hot?: boolean | { injectCss?: boolean; [key: string]: any };
hot?: boolean | { injectCss?: boolean; partialAccept?: boolean; [key: string]: any };

/**
* Some Vite plugins can contribute additional preprocessors by defining `api.sveltePreprocess`.
Expand Down
8 changes: 4 additions & 4 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 f6d7007

Please sign in to comment.