serverless-heaven / serverless-webpack

Serverless plugin to bundle your lambdas with Webpack
MIT License
1.72k stars 414 forks source link

watch with serverless offline #566

Open isitgeorge opened 4 years ago

isitgeorge commented 4 years ago

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!

SyedRFarhan commented 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",
furudean commented 4 years ago

This used to work for me, but after updating my package version it stopped working.

isitgeorge commented 4 years ago

This used to work for me, but after updating my package version it stopped working.

webpack used to watch and rebuild automatically?

furudean commented 4 years ago

Serverless offline with serverless-webpack did have the watch thing work, yeah

soda0289 commented 4 years ago

Do you know which version broke watch?

AshUK commented 4 years ago
serverless-offline:
  useChildProcesses: true
haroonKhan-10p commented 4 years ago

facing the same issue. Using nodemon as a workaround works fine. But it is not as fast as serverless-webpack

isitgeorge commented 4 years ago

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

polson commented 4 years ago

Also wondering how to do this

haroonKhan-10p commented 4 years ago

webpack-watch is fixed by this: working on macOS Catalina. Update serverless.yml to add custom attribute like this:

custom:
  serverless-offline:
    useChildProcesses: true
furudean commented 4 years ago

@AshUK @haroonKhan-10p Worth noting that these are not fixes, more so workarounds. They massively degrade performance, especially for larger projects.

polson commented 4 years ago

@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

francisu commented 4 years ago

And this one: dherault/serverless-offline#864 The above is what broke it. This was a change introduced in serverless-offline 6.0.0

ZentPeople commented 1 year ago

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

cullylarson commented 1 year ago

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"),
  }),
],
jrobichaud commented 1 year ago

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.

iSeiryu commented 1 year ago

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",
thetrevdev commented 10 months ago

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

j0k3r commented 10 months ago

@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?

thetrevdev commented 10 months ago

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'))
ps2-controller commented 4 months ago

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?

https://github.com/ps2-controller/serverless-offline-issue

ps2-controller commented 4 months ago

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

ps2-controller commented 4 months ago

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.