Webpack-dev-server: onBeforeSetupMiddleware server isn't accessible

Created on 28 Mar 2021  路  17Comments  路  Source: webpack/webpack-dev-server

  • Operating System: MacOS v11.2.3
  • Node Version: v15.12.0
  • NPM Version: v7.7.5
  • webpack Version: v5.28.0
  • webpack-dev-server Version: v4.0.0-beta.1
  • Browser: Chrome ARM v89.0.4389.90

  • [x] This is a bug

  • [ ] This is a modification request

Code

When I was using webpack-dev-server v3, I was configuring the before option like below.

// webpack.config.js

 before(app, server) {
    const files = [
      path.resolve(rootFolder, 'resources/views/**/*.html.twig'),
      path.resolve(rootFolder, 'content/collections/**/*.md')
    ]

    // Reload the browser on content/template files change
    chokidar.watch(files).on('all', () => {
      server.sockWrite(server.sockets, 'content-changed')
    })
  },

Since I've upgrade to webpack-dev-server v4.0.0-beta.1 this is not working even if I've follow the release notes.
I'm getting an error : TypeError: Cannot read property 'sockWrite' of undefined
I've looked at the source code to understand how the new onBeforeSetupMiddleware but sadly, nothing I've tried worked...

Any help would really appreciated, thank you 馃槄 !

// webpack.config.js

 onBeforeSetupMiddleware({ server, sockets }) {
    const files = [
      path.resolve(rootFolder, 'resources/views/**/*.html.twig'),
      path.resolve(rootFolder, 'content/collections/**/*.md')
    ]

    // Reload the browser on content/template files change
    chokidar.watch(files).on('all', () => {
      server.sockWrite(sockets, 'content-changed')
    })
  },

Most helpful comment

hm, we can implement option watchFiles: string | { paths, options }, so you can watch files without dirty hacks

All 17 comments

hm, it is private API, why you need this?

hi @alexander-akait,
It helps speed up dev workflow a lot by preventing to manually reload the browser on a any changes.
With this setup it automatically reload the browser when I change a Twig template file or a mardown content file.

If you want to keep this API private, we could maybe add an option to handle this case internally ?

hm, we can implement option watchFiles: string | { paths, options }, so you can watch files without dirty hacks

That would be awesome and cleaner for sure 馃槃

https://github.com/webpack/webpack-dev-server/blob/cd39491ea395c985f2014dfc03379db5c894f711/lib/Server.js#L989 should work for this case, right? we can just read the watch files from the option and pass it to this watcher or is this specific for static option?

Yep, easy to implement, just pass this options to watchFiles, i.e. const watchers = watchFiles.map((item) => watchFiles(item.path, item.options)), move this code to setupWatchFiles method, don't forget to close them in close method and add CLI option for this

got it, thanks

got it, thanks

Can I help you ?

Thanks but PR is ready 馃槃

Can't believe how fast this feature as been implemented, thank you guys 鉂わ笍

Anyway you can fix your code (should work):

onBeforeSetupMiddleware(devServer) {
    const files = [
      path.resolve(rootFolder, 'resources/views/**/*.html.twig'),
      path.resolve(rootFolder, 'content/collections/**/*.md')
    ]

    // Reload the browser on content/template files change
    chokidar.watch(files).on('all', () => {
      devServer.sockWrite(sockets, 'content-changed')
    })
  },

Hey @alexander-akait in the above code socket is not defined.
But even by fixing it by using devServer.sockets instead, it doesn't work because it returns an empty array.

onBeforeSetupMiddleware(devServer) {
    // Reload the browser on content/template files change
    chokidar.watch([WEBPACKER_SETTINGS.files.template, WEBPACKER_SETTINGS.files.content], { ignoreInitial: true }).on('all', () => {
      devServer.sockWrite(devServer.sockets, 'content-changed')
    })
  },

Anyway, I can totally wait for a new release with the merge PR to use this feature now 馃槃 !

devServer.sockets is empty only on initial stage, after it should contain array of socket contentions... I think I will do release tomorrow/after tomorrow

The new release seems not work for me. I tried the sockWrite option锛宐ut the this.socketServer seems to be undefined.

  sockWrite(sockets, type, data) {
    sockets.forEach((socket) => {
      this.socketServer.send(socket, JSON.stringify({ type, data }));
    });
  }

@flyyang because you need wait when socket server starts

Perfectly working ! Thank you so much @alexander-akait / @anshumanv 鉂わ笍

Was this page helpful?
0 / 5 - 0 ratings

Related issues

MJ111 picture MJ111  路  3Comments

tulika21-zz picture tulika21-zz  路  3Comments

subblue picture subblue  路  3Comments

antoinerousseau picture antoinerousseau  路  3Comments

uMaxmaxmaximus picture uMaxmaxmaximus  路  3Comments