Open isitgeorge opened 4 years ago
I've been having trouble with this too. I use nodemon as a workaround. Here are the scripts:
"serve": "sls offline -P 4000",
"serve:watch": "nodemon -e js,ts,jsx,tsx -x yarn run serve",
This used to work for me, but after updating my package version it stopped working.
This used to work for me, but after updating my package version it stopped working.
webpack used to watch and rebuild automatically?
Serverless offline with serverless-webpack did have the watch thing work, yeah
Do you know which version broke watch?
serverless-offline:
useChildProcesses: true
facing the same issue. Using nodemon as a workaround works fine. But it is not as fast as serverless-webpack
Published a little module that I was using internally to solve this, since asking the original question - https://www.npmjs.com/package/serverless-offline-multi but would be great to work out how/when the webpack watch broke
Also wondering how to do this
webpack-watch is fixed by this: working on macOS Catalina. Update serverless.yml to add custom attribute like this:
custom:
serverless-offline:
useChildProcesses: true
@AshUK @haroonKhan-10p Worth noting that these are not fixes, more so workarounds. They massively degrade performance, especially for larger projects.
@haroonKhan-10p that unfortunately didn't do anything for me.
The issue for me is that webpack does watch and transpile correctly, but serverless offline uses cached files and not the new ones. I think the issue lies with the serverless-offline
plugin
I think we will have to dig into the plugin and see if there's some way to fix it. I looked into it yesterday and I don't really see the problem, but I'll keep digging.
Also see this related issue: https://github.com/dherault/serverless-offline/issues/931
And this one: https://github.com/dherault/serverless-offline/issues/864
And this one: dherault/serverless-offline#864 The above is what broke it. This was a change introduced in
serverless-offline
6.0.0
https://github.com/dherault/serverless-offline/releases/tag/v9.0.0
from serverless-offline v 9.0.0 hard reloading is not supported by default. To support hot reloading, you have to use the below flag
--reloadHandler
This is happening for me too. Modifying files does not trigger a rebuild. Running sls offline --stage development
. Versions:
"serverless": "^3.24.1"
"serverless-offline": "^11.2.3"
"serverless-webpack": "^5.10.0"
I tried useChildProcesses: true
and including --reloadHandler
(sls offline --reloadHandler --stage development
). Neither made a difference.
EDIT: The issue turned out to be that our bundles were too big. We were in the process of moving to a monorepo and nodeExternals
no longer marked some packages as external and they were bundled. For some reason it was too much for serverless-webpack
or something. Anyway, including --reloadHandler
in the sls offline
command is all we needed to include to resolve this.
If anyone else runs into this issue, adding this to webpack.config.js
is was fixed the underlying, "bundles are too big" issue for us:
externals: [
nodeExternals(),
// we need another nodeExternals for the root-level node_modules since
// that's where most of our externals will be
nodeExternals({
modulesDir: path.resolve(__dirname, "path/to/root/node_modules"),
}),
],
According to the documentation
reloadHandler
Reloads handler with each request.
--reloadHandler
does not activate a reload when a file changes, it reloads regardless after each request.
This has the side effect to adds delays between each requests.
I solved it by adding this to my serverless.yml
plugins:
- serverless-plugin-typescript
- serverless-offline
...
custom:
serverlessPluginTypescript:
tsConfigFileLocation: './tsconfig.build.json'
and running
sls offline start --config serverless.yml --reloadHandler
Packages:
"serverless-esbuild": "^1.23.3",
"serverless-offline": "^11.6.0",
"serverless-plugin-typescript": "^2.1.4",
According to the documentation
reloadHandler Reloads handler with each request.
--reloadHandler
does not activate a reload when a file changes, it reloads regardless after each request.This has the side effect to adds delays between each requests.
Feel free to use this plugin to only reload after a webpack compilation.
It just wires up the two hooks: webpack:compile:watch:compile
-> offline:functionsUpdated
https://www.npmjs.com/package/serverless-webpack-offline-reload
@thetrevdev if this is working solution maybe this can be directly integrated into serverless-webpack (with condition about enable it or not depending if serverless-offline is part of the project)? WDYT?
It looks like webpack watch is only initiated from serverless-offline. I see no issue with directly integrating this.
It would just be an update to a single line of code. I'll leave the plugin as a stop gap and maybe someone wants to champion a PR with the single line of code below.
https://github.com/serverless-heaven/serverless-webpack/blob/master/index.js#L224
'webpack:compile:watch:compile': BbPromise.bind(this)
.then(() => this.serverless.pluginManager.spawn('offline:functionsUpdated'))
I'm continuing to face this issue. I've created a repository with a minimum viable example and a detailed readme to recreate the issue; could somebody with a good understanding of serverless-webpack take a look?
After running webpack --watch in a separate terminal, and then sls offline start
,
when I make a code change, I do see that webpack says it recompiles immediately after the code change.
However, then I go to .webpack/service/src/path/to/my/file.mjs and sit and watch as it still takes another few minutes before reflecting the code change
In lib/wpwatch.js
I can see that when using serverless-offline plugin, webpack watch is utilized under the hood.
Adding the following lines:
const beforeCompile = () =>
new BbPromise(resolve => {
console.log('Starting recompile...')
// eslint-disable-next-line promise/catch-or-return
BbPromise.resolve(currentCompileWatch)
// Forwarding the error to the then so we don't display it twice
// (once when it was originally thrown, and once when the promise rejects)
.catch(error => error)
.then(error => {
if (error) {
return null;
}
currentCompileWatch = null;
resolve();
return null;
});
});
if (stats) {
console.log('Finished recompile.')
lastHash = stats.hash;
try {
logStats(stats, consoleStats, this.serverless.cli.consoleLog, {
log: this.log,
ServerlessError: this.serverless.classes.Error
});
} catch (error) {
if (this.log) {
this.log.error(error.message);
}
}
}
Allows me to reliably see in the CLI when the hot reload actually starts and finishes. The Starting recompile...
log runs as soon as I save a file in my codebase, and the Finished recompile.
log runs as soon as the changes are available in the .webpack
directory. That's a huge win because I no longer need to kill and restart the sls offline start
process every time I change code. However, the time between the starting recompile and finished recompile log is still extremely slow.
I don't know enough about the serverless lifecycle yet to be able to follow the code path that executes between those two logs; I'm trying to figure out what makes it so slow. It seems to me, it should cache all the files that didn't change, and be able to quickly make the relevant change in the .webpack directory.
This is a Question
Description
When using this plugin with Serverless offline, it transpiles as expected but is it possible to trigger a retranspile when a change is detected? Currently have to restart the serverless offline wrapper.
Thanks!