Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: update svelte-hmr and enable partial accept #440

Merged
merged 3 commits into from Sep 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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.