diff --git a/.changeset/curly-emus-ring.md b/.changeset/curly-emus-ring.md new file mode 100644 index 000000000..c69539971 --- /dev/null +++ b/.changeset/curly-emus-ring.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Honors users HMR settings diff --git a/packages/astro/snowpack-plugin.cjs b/packages/astro/snowpack-plugin.cjs index 124c94edc..5f99dd86f 100644 --- a/packages/astro/snowpack-plugin.cjs +++ b/packages/astro/snowpack-plugin.cjs @@ -2,8 +2,11 @@ const { readFile } = require('fs').promises; // Snowpack plugins must be CommonJS :( const transformPromise = import('./dist/compiler/index.js'); +const DEFAULT_HMR_PORT = 12321; + /** @type {import('snowpack').SnowpackPluginFactory} */ -module.exports = (snowpackConfig, { resolvePackageUrl, hmrPort, renderers, astroConfig } = {}) => { +module.exports = (snowpackConfig, { resolvePackageUrl, renderers, astroConfig } = {}) => { + let hmrPort = DEFAULT_HMR_PORT; return { name: 'snowpack-astro', knownEntrypoints: ['astro/dist/internal/h.js', 'astro/components/Prism.astro'], @@ -43,6 +46,11 @@ ${contents}`; return result; } }, + config(snowpackConfig) { + if(!isNaN(snowpackConfig.devOptions.hmrPort)) { + hmrPort = snowpackConfig.devOptions.hmrPort; + } + }, async load({ filePath }) { const { compileComponent } = await transformPromise; const projectRoot = snowpackConfig.root; diff --git a/packages/astro/src/compiler/transform/head.ts b/packages/astro/src/compiler/transform/head.ts index 5ddc40d7d..6d008ffa4 100644 --- a/packages/astro/src/compiler/transform/head.ts +++ b/packages/astro/src/compiler/transform/head.ts @@ -62,7 +62,7 @@ export default function (opts: TransformOptions): Transformer { type: 'Element', name: 'script', attributes: [], - children: [{ type: 'Text', data: `window.HMR_WEBSOCKET_URL = 'ws://localhost:${hmrPort}'`, start: 0, end: 0 }], + children: [{ type: 'Text', data: `window.HMR_WEBSOCKET_URL = window.HMR_WEBSOCKET_URL || 'ws://localhost:${hmrPort}';`, start: 0, end: 0 }], start: 0, end: 0, }, diff --git a/packages/astro/src/runtime.ts b/packages/astro/src/runtime.ts index 1ff0734a4..a761739b1 100644 --- a/packages/astro/src/runtime.ts +++ b/packages/astro/src/runtime.ts @@ -309,7 +309,6 @@ interface CreateSnowpackOptions { resolvePackageUrl?: (pkgName: string) => Promise; } -const DEFAULT_HMR_PORT = 12321; const DEFAULT_RENDERERS = ['@astrojs/renderer-vue', '@astrojs/renderer-svelte', '@astrojs/renderer-react', '@astrojs/renderer-preact']; /** Create a new Snowpack instance to power Astro */ @@ -329,8 +328,7 @@ async function createSnowpack(astroConfig: AstroConfig, options: CreateSnowpackO hmrPort?: number; } = { astroConfig, - resolvePackageUrl, - hmrPort: isHmrEnabled ? DEFAULT_HMR_PORT : undefined, + resolvePackageUrl }; const mountOptions = { @@ -413,7 +411,6 @@ async function createSnowpack(astroConfig: AstroConfig, options: CreateSnowpackO output: 'stream', port: 0, hmr: isHmrEnabled, - hmrPort: isHmrEnabled ? DEFAULT_HMR_PORT : undefined, tailwindConfig: astroConfig.devOptions.tailwindConfig, }, buildOptions: { diff --git a/packages/astro/test/astro-hmr.test.js b/packages/astro/test/astro-hmr.test.js new file mode 100644 index 000000000..9b8fa6588 --- /dev/null +++ b/packages/astro/test/astro-hmr.test.js @@ -0,0 +1,34 @@ +import { suite } from 'uvu'; +import * as assert from 'uvu/assert'; +import { doc } from './test-utils.js'; +import { setup } from './helpers.js'; + +const HMR = suite('HMR tests'); + +setup(HMR, './fixtures/astro-hmr', { + runtimeOptions: { + mode: 'development', + }, +}); + +HMR('Honors the user provided port', async ({ runtime }) => { + const result = await runtime.load('/'); + if (result.error) throw new Error(result.error); + + const html = result.contents; + assert.ok(/window\.HMR_WEBSOCKET_URL = window\.HMR_WEBSOCKET_URL || 'ws:\/\/localhost:5555'/.test(html), 'Uses the user\'s websocket port'); +}); + +HMR('Does not override script added by the user', async ({ runtime }) => { + const result = await runtime.load('/manual'); + console.log(result.error); + + const html = result.contents; + + assert.ok(!/window\.HMR_WEBSOCKET_URL = 'ws:\/\/localhost:3333'/.test(html), + 'Users script included'); + assert.ok(/window\.HMR_WEBSOCKET_URL = window\.HMR_WEBSOCKET_URL || 'ws:\/\/localhost:5555'/.test(html), + 'Our script defers to the port already being set'); +}); + +HMR.run(); \ No newline at end of file diff --git a/packages/astro/test/fixtures/astro-hmr/snowpack.config.json b/packages/astro/test/fixtures/astro-hmr/snowpack.config.json new file mode 100644 index 000000000..6fddc0add --- /dev/null +++ b/packages/astro/test/fixtures/astro-hmr/snowpack.config.json @@ -0,0 +1,6 @@ +{ + "workspaceRoot": "../../../../../", + "devOptions": { + "hmrPort": 5555 + } +} diff --git a/packages/astro/test/fixtures/astro-hmr/src/components/Tour.jsx b/packages/astro/test/fixtures/astro-hmr/src/components/Tour.jsx new file mode 100644 index 000000000..f05f3f9d8 --- /dev/null +++ b/packages/astro/test/fixtures/astro-hmr/src/components/Tour.jsx @@ -0,0 +1,5 @@ +import { h } from 'preact'; + +export default function() { + return
Testing
+} \ No newline at end of file diff --git a/packages/astro/test/fixtures/astro-hmr/src/pages/index.astro b/packages/astro/test/fixtures/astro-hmr/src/pages/index.astro new file mode 100644 index 000000000..754749f90 --- /dev/null +++ b/packages/astro/test/fixtures/astro-hmr/src/pages/index.astro @@ -0,0 +1,12 @@ +--- +import Tour from '../components/Tour.jsx'; +--- + + + My Test + + +
Hello world
+ + + \ No newline at end of file diff --git a/packages/astro/test/fixtures/astro-hmr/src/pages/manual.astro b/packages/astro/test/fixtures/astro-hmr/src/pages/manual.astro new file mode 100644 index 000000000..29bcb5b23 --- /dev/null +++ b/packages/astro/test/fixtures/astro-hmr/src/pages/manual.astro @@ -0,0 +1,15 @@ +--- +import Tour from '../components/Tour.jsx'; +--- + + + My Test + + + +
Hello world
+ + + \ No newline at end of file