Fails with webpack
Closed this issue · 13 comments
With webpack
(following the template), attempt to update even the simplest component fails with Failed to init component
. More specifically: TypeError: "cmp.$capture_state is not a function"
.
This happens regardless of the value of optimistic
.
$capture_state
was introduced in Svelte 3.19.1 or so. Since then, Svelte HMR requires at least this version of Svelte, and dev mode enabled to work.
I have a Webpack HMR example somewhere, let me check if it is up to date.
Yes, it still works. See for yourself: https://github.com/rixo/svelte-template-webpack-hot
You're absolutely right. Mind boggles, I'm on latest version of every package and yet it doesn't seem to like me. No matter, I'll start removing things from webpack.config.js
until I find the culprit.
Closing.
Sorry, I didn't mean to scare you off... Double check the dev
option of the Svelte loader, it is required for HMR (and would produce the $capture_state
error you've had if off).
I have this issue too. I'll investigate and find out what can be done.
I can and will.
I noticed something not clear and came back to ask about it.
In https://github.com/rixo/svelte-template-webpack-hot webpack config the svelte-loader-hot
rule options has dev
on line 31 (as below), which seems to be just a boolean that's true in development mode.
I don't see in svelte-loader-hot
documentation for that? Am I missing something?
const mode = process.env.NODE_ENV || 'development'
const prod = mode === 'production'
const dev = !prod
...
{
test: /\.svelte$/,
use: {
loader: 'svelte-loader-hot',
options: {
dev, // <-- what does this do?
hotReload: true,
hotOptions: {
// whether to preserve local state (i.e. any `let` variable) or
// only public props (i.e. `export let ...`)
noPreserveState: false,
// optimistic will try to recover from runtime errors happening
// during component init. This goes funky when your components are
// not pure enough.
optimistic: true,
// See docs of svelte-loader-hot for all available options:
//
// https://github.com/rixo/svelte-loader-hot#usage
},
},
},
}
Here's a link to the webpack.config.js that errors out
Here's the specfic ruleset I'm using
{
test: /\.svelte$/,
use: {
loader: "svelte-loader-hot",
options: {
preprocess,
// NOTE emitCss: true is currently not supported with HMR
emitCss: isProductionMode,
hotReload: !isProductionMode,
hotOptions: {
noPreserveState: false,
noPreserveStateKey: "@!hmr",
noReload: false,
optimistic: false,
acceptAccessors: true,
acceptNamedExports: true,
},
},
},
}
Where preprocess
is:
const sveltePreprocess = require("svelte-preprocess")
const ExtractCssChunks = require("extract-css-chunks-webpack-plugin")
const preprocess = sveltePreprocess({ typescript: true })
I should point out, if it's helpful, that hot loading works just perfectly with SASS => CSS => server pipeline 💯
The template uses this setup for module options:
hotOptions: {
noPreserveState: false,
optimistic: true,
},
I tried using those options alone and still no bueno
The overlay error is:
Failed to init component
<App>
TypeError: cmp.$capture_state is not a function
at captureState (http://localhost:8080/index.js:10486:21)
at App.targetCmp.$replace (http://localhost:8080/index.js:10615:23)
at refreshComponent (http://localhost:8080/index.js:10238:21)
at ProxyAdapterDom.rerender (http://localhost:8080/index.js:10079:5)
at http://localhost:8080/index.js:10433:9
at Array.forEach (<anonymous>)
at Object.reload (http://localhost:8080/index.js:10431:15)
at http://localhost:8080/index.js:9819:31
at next (http://localhost:8080/index.js:10770:11)
at runAcceptHandlers (http://localhost:8080/index.js:10775:9)
From the console it's:
proxy.js:14 [HMR][Svelte] Error during component init: <App>
logError @ proxy.js:14
refreshComponent @ proxy.js:140
rerender @ proxy-adapter-dom.js:62
(anonymous) @ proxy.js:318
reload @ proxy.js:316
(anonymous) @ hot-api.js:155
next @ hot-api.js:52
runAcceptHandlers @ hot-api.js:57
check @ hot-api.js:84
hotSetStatus @ bootstrap:241
hotApplyInternal @ bootstrap:748
hotApply @ bootstrap:361
(anonymous) @ bootstrap:336
Promise.then (async)
hotUpdateDownloaded @ bootstrap:335
hotAddUpdateChunk @ bootstrap:311
webpackHotUpdateCallback @ bootstrap:7
(anonymous) @ index.6f0ce478032676e350e8.hot-update.js:1
proxy.js:18 TypeError: cmp.$capture_state is not a function
at captureState (svelte-hooks.js:25)
at App.targetCmp.$replace (svelte-hooks.js:154)
at refreshComponent (proxy.js:123)
at ProxyAdapterDom.rerender (proxy-adapter-dom.js:62)
at proxy.js:318
at Array.forEach (<anonymous>)
at Object.reload (proxy.js:316)
at hot-api.js:155
at next (hot-api.js:52)
at runAcceptHandlers (hot-api.js:57)
logError @ proxy.js:18
refreshComponent @ proxy.js:140
rerender @ proxy-adapter-dom.js:62
(anonymous) @ proxy.js:318
reload @ proxy.js:316
(anonymous) @ hot-api.js:155
next @ hot-api.js:52
runAcceptHandlers @ hot-api.js:57
check @ hot-api.js:84
hotSetStatus @ bootstrap:241
hotApplyInternal @ bootstrap:748
hotApply @ bootstrap:361
(anonymous) @ bootstrap:336
Promise.then (async)
hotUpdateDownloaded @ bootstrap:335
hotAddUpdateChunk @ bootstrap:311
webpackHotUpdateCallback @ bootstrap:7
(anonymous) @ index.6f0ce478032676e350e8.hot-update.js:1
HEY! I got it working! 🥳
It's that dev
line!
I added that, and it works as expected: rendall/svelte-minimal@990c938
Now I just have to figure out why vscode is saving my files with tabs. 📑
What does that boolean do?
I think just documenting that boolean could close this issue.
Yes, that is definitely helpful! This can be closed now. Thanks very much for your help!