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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aurelia Vite Plugin HMR fails every second edit #1800

Open
davidsk opened this issue Jul 16, 2023 · 3 comments
Open

Aurelia Vite Plugin HMR fails every second edit #1800

davidsk opened this issue Jul 16, 2023 · 3 comments
Assignees
Labels

Comments

@davidsk
Copy link

davidsk commented Jul 16, 2023

馃悰 Bug Report

When using the vite plugin, Hot Module Replacement fails every second edit.

Aurelia-Vite HMR

馃 Expected Behavior

Editing a file should not cause the page to refresh, but the existing state should be preserved, and the changes should be in effect

馃槸 Current Behavior

Editing a file causes a page refresh every second edit. No error message is provided.

No error is logged.

It seems like there's some state in the plugins getHmrCode function that's being toggled each time it's called

I'd like to edit files and have the changes take effect without losing state

馃捇 Code Sample

Repo

stackblitz

馃實 Your Environment

Software Version(s)
Aurelia 2.0.0-beta.72.0.0-beta.7
Language Typescript
Browser MS Edge
Bundler Vite
Operating System Windows
NPM/Node/Yarn NPM 9.6.5
@davidsk davidsk changed the title Aurelia Vite Plugin fails every second edit Aurelia Vite Plugin HMR fails every second edit Jul 16, 2023
@bigopon bigopon added the HMR label Jul 17, 2023
@davidsk
Copy link
Author

davidsk commented Aug 2, 2023

Digging into this a bit more and the core issue seems to be that the created hook is not being called after an HMR update:

A controllers array is defined for each version of the module...

const controllers = [];

...which is populated when the created function on the class prototype is called...

// @ts-ignore
proto.created = function(controller) {
// @ts-ignore
ogCreated && ogCreated.call(this, controller);
controllers.push(controller);
}

...and this is persisted across updates by stashing it on the data object when a module is being disposed

// @ts-ignore
${moduleText}.hot.dispose(function (data) {
// @ts-ignore
data.controllers = controllers;
data.aurelia = aurelia;
});

As the created hook is not being called following an module update, the controller array remains empty, which is then passed to the second update which finds no controllers and invalidates the module.

const previousControllers = ${moduleText}.hot.data.controllers;
if (previousControllers == null || previousControllers.length === 0) {
// @ts-ignore
${moduleText}.hot.invalidate();
}

Hopefully that helps. I don't know enough about the Aurelia lifecycle to understand what/how/when the created method should be called following an HMR update to take this much further.

@bigopon
Copy link
Member

bigopon commented Aug 3, 2023

@davidsk the analysis is a great help , thanks! Should help accelerate the fix 馃憤

@brandonseydel brandonseydel self-assigned this Aug 3, 2023
@davidsk
Copy link
Author

davidsk commented Apr 3, 2024

I did find some time to dig into this a little further. I added some console logging to see what events were being called and on initial load the console looks like this:

image

and after an HMR update:

image

It doesn't appear to be calling the hydrating, hydrated or created methods. Out of curiosity, I changed the method that the HMR module is overrding from created to binding and it works (as I expect, at least); after each edit, the current state is captured and re-applied.

Sample repo here: https://github.com/davidsk/aurelia-vite-plugin-fails-every-second-edit/tree/tweak-au-hmr

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants