Git Product home page Git Product logo

Comments (26)

smashercosmo avatar smashercosmo commented on July 3, 2024 1

Alright, unfortunately, after some thinking, I have to say that I have no idea how to tackle this issue. The problem is that I want compiled server bundle to be passed as a middleware to webpack-plugin-serve. Something like this:

const serve = new WebpackPluginServe({
  middleware: (app, builtins) => {
      app.use(/* here we need to pass compiled server bundle somehow */)
  }      
});

const config = [
   {
      entry: { client: './src/client.js' },
      output: {
        path: path.resolve(__dirname, 'dist'),
      },
      plugins: [serve],
      watch: true,
   },
   {
      entry: { server: './src/server.js' },
      output: {
        path: path.resolve(__dirname, 'dist'),
        libraryTarget: 'commonjs2',
      },
      target: 'node',
      plugins: [serve.attach()],
   },
]

But I don't know how it can be implemented or even if it's the right direction of thinking.

from webpack-plugin-serve.

smashercosmo avatar smashercosmo commented on July 3, 2024 1

Ok. Finally made it work. How to you want me to make a recipe? As a simple .md file or as a project, like react recipe?

from webpack-plugin-serve.

shellscape avatar shellscape commented on July 3, 2024 1

@smashercosmo I'm good with that approach. Since your first approach worked as well, I would suggest keeping both and explaining the differences, benefits to users in the README for the recipe.

from webpack-plugin-serve.

shellscape avatar shellscape commented on July 3, 2024

(Note: I updated your issue with the Documentation template. Please use an appropriate issue template for your next issue)

While I don't personally have a lot of experience with server-side rendering, we'd be completely open to included documentation/recipes for SSR. Someone with the relevant experience will have to put that together.

from webpack-plugin-serve.

smashercosmo avatar smashercosmo commented on July 3, 2024

Thx for quick response and for what you're doing to make webpack DX better. I'll definitely play and experiment with webpack-plugin-serve and ssr (let's see if I can figure it out), but advice from developers who fill themself confident about ssr and server-side hot reloading is very much appreciated.

(Note: sorry for missing template. For some reason I chose Support, Help, and Advice option instead of Documentation one)

from webpack-plugin-serve.

shellscape avatar shellscape commented on July 3, 2024

No worries! If you can share a minimal repo that tries to accomplish this, I can try to assist. At the very least I can help with errors and such.

from webpack-plugin-serve.

matheus1lva avatar matheus1lva commented on July 3, 2024

The only thing that is going to be different is the way that you were used to work. We don't have a middleware with the same essence as WPS (YET), but you can do whatever you did before using the middleware options since you have access to Koa's app instance. All the other things are going to work flawlessly!

from webpack-plugin-serve.

shellscape avatar shellscape commented on July 3, 2024

This SurviveJS article on SSR might be a good reference: https://survivejs.com/webpack/output/server-side-rendering/

Particularly this part:

app.get("/", (req, res) =>
    res.status(200).send(renderMarkup(renderToString(SSR)))
  );

from webpack-plugin-serve.

smashercosmo avatar smashercosmo commented on July 3, 2024

I'm not quite sure how it might help. The problem is that I want compiled server bundle (taken from webpack's memory fs during compilation) to be passed as a middleware to webpack-plugin-serve. This is what webpack-hot-server-middleware is doing. And this could give us both ssr and hot-reloadable server code.

from webpack-plugin-serve.

shellscape avatar shellscape commented on July 3, 2024

compiled server bundle (taken from webpack's memory fs during compilation) to be passed as a middleware

that would require access to the compiler, which you don't have in this context. WPS doesn't write bundles to a memory-fs like webpack-dev-middleware (and by extension, webpack-serve and webpack-dev-server) does. The plugin just let's the compiler do what it wants to do. In the link I pasted, the server setup is requiring a file which exports the render methods. I have no knowledge of your bundle or environment, but exporting a function in the resulting server bundle, which would give you the function or info you need, seems reasonable (and happens to be what webpack-hot-server-middleware requires: https://github.com/60frames/webpack-hot-server-middleware/blob/master/src/index.js#L62)

From https://www.npmjs.com/package/webpack-hot-server-middleware:

Webpack Hot Server Middleware is designed to be used in conjunction with webpack-dev-middleware

That's a pretty important detail when comparing that with this plugin. You'll have to pull bundle content from the filesystem, rather than memory-fs like webpack-dev-middleware uses.

This is the function in hot-server-middleware that does most of the magic: https://github.com/60frames/webpack-hot-server-middleware/blob/dc02c342ec77de742bf15c361eb846af5e4a55db/src/index.js#L61-L77. That, along with createKoaHandler. buffer there is just the content of the file using the compier's filesystem: https://github.com/60frames/webpack-hot-server-middleware/blob/master/src/index.js#L153. And since you know where your files are being written (since you configured it) there's no need for direct access to the compiler, because we don't have to use compiler.outputFileSystem. The bundle files are already on disk.

So I think it's just a matter of breaking down that package to it's base components, knowing that the bundle is on disk, and implementing the portions of that which you actually need in order to get this to work.

from webpack-plugin-serve.

smashercosmo avatar smashercosmo commented on July 3, 2024

Thank you very much for the explanation. Somehow I missed that WPS doesn't use memory fs. Yes, having compiled bundles in the filesystem makes it much easier. Side question: how big of a impact on performance/build times does this approach have (I mean always writng to file system)?

from webpack-plugin-serve.

shellscape avatar shellscape commented on July 3, 2024

how big of a impact on performance/build times does this approach have (I mean always writng to file system)?

I personally haven't seen any drawback. On machines that don't have SSD drives, there's the possibility that it could be slower. The advantages in less complexity were worth the risk. Nearly everyone at my current and former positions all have laptops/desktops with SSDs, so there's really no noticeable difference. Everyone I interact with regularly that uses this plugin does immediately note how much less memory is being used though.

from webpack-plugin-serve.

matheus1lva avatar matheus1lva commented on July 3, 2024

Ok. Finally made it work. How to you want me to make a recipe? As a simple .md file or as a project, like react recipe?

One .md file are usually for "config recipes", if the recipe you had done is a little bit more complex, i would add a project similar to react/vue, which is better to be understood and also people can download to reuse.

from webpack-plugin-serve.

shellscape avatar shellscape commented on July 3, 2024

@smashercosmo anything we can do to help?

from webpack-plugin-serve.

smashercosmo avatar smashercosmo commented on July 3, 2024

@shellscape sorry, didn't have time to finish PR. Will do today.

from webpack-plugin-serve.

smashercosmo avatar smashercosmo commented on July 3, 2024

@shellscape I'm trying to submit PR but getting an error Error: Cannot find module 'babel-eslint'. Error is produced by npm run lint-staged command. If I just run npm run lint there are no errors. I checked if I have eslint installed globally and I don't. Any ideas?

from webpack-plugin-serve.

shellscape avatar shellscape commented on July 3, 2024

Try rm -rf node_modules && npm install. I ran it successfully from fresh node_modules here, and I don't have eslint installed globally. Sounds like a funky node_modules issue.

from webpack-plugin-serve.

ozyman42 avatar ozyman42 commented on July 3, 2024

I wouldn't really call this an ideal hot-reloading solution on the server-side. This recipe uses the import-fresh module for hot reloading. It would be better if we could server-side HMR with the same HMR API we use on the client-side. For example change server/main.js to this:

const React = require('react');
const { renderToString } = require('react-dom/server');

const rootHolder = {
    root: require('../client/Root').default,
    render: function() {
        const Root = this.root;
        return renderToString(<Root />);
    }
}

function render() {
  const markup = rootHolder.render();

  return `
    <!doctype html>
    <html lang="en">
      <body>
        <div id="react">${markup}</div>
        <script src="client.js"></script>
      </body>
    </html>
  `;
}

if(module.hot) {
    module.hot.accept('../client/Root', () => {
        rootHolder.root = require('../client/Root').default;
    });
}

module.exports = async (ctx, next) => {
  ctx.body = `${render()}`;
  await next();
};

then change the importFresh to a normal require call in webpack.config.js, and change the watch option in the webpack config from

watch: !isServer && !optimize

to

watch: !optimize

so it recompiles the server bundle. One advantage of this new approach is that now we don't need to write a new importFresh line for every root file we might want to change at some point.

I know it should be able to be done in theory because of this https://www.npmjs.com/package/node-hot-loader it's just a matter of creating a node.js client for webpack-plugin-serve.

from webpack-plugin-serve.

smashercosmo avatar smashercosmo commented on July 3, 2024

@alexleung that's neat) I chose the easiest way) We should definitely update recipe with your solution.

from webpack-plugin-serve.

ozyman42 avatar ozyman42 commented on July 3, 2024

^ I don't think my solution will work, because we would need to add in a client into the server entry in the webpack config. However the entry we would need to add does not exist I think.

from webpack-plugin-serve.

smashercosmo avatar smashercosmo commented on July 3, 2024

Oh, right

from webpack-plugin-serve.

ozyman42 avatar ozyman42 commented on July 3, 2024

For example, there is a webpack-plugin-serve/client for injecting the browser runtime, but we would need some kind of webpack-plugin-serve/node-client to add into the server entry.

from webpack-plugin-serve.

smashercosmo avatar smashercosmo commented on July 3, 2024

Managed to make it work)

from webpack-plugin-serve.

smashercosmo avatar smashercosmo commented on July 3, 2024

I reused the same logic, that we have on the client, something like

const WebSocket = require('ws');
const ws = new WebSocket('http://[::]:3000/wps');

if(module.hot) {
  module.hot.accept(['../client/Root'], () => {
    rootHolder.root = require('../client/Root').default;
  });
}

ws.on('message', function incoming(message) {
  const { action, data = {} } = JSON.parse(message);
  const { hash = '<?>' } = data || {};
  const { wpsId } = data;

  switch (action) {
    case 'replace':
      if (wpsId && wpsId === ʎɐɹɔosǝʌɹǝs.wpsId) {
        replace('<unknown>', hash);
      }
      break;
    default:
  }
});

And and worked like a charm)

from webpack-plugin-serve.

smashercosmo avatar smashercosmo commented on July 3, 2024

@shellscape what do you think about such approach? I mean creating 'webpack-plugin-serve/server-hot-client' entry?

from webpack-plugin-serve.

smashercosmo avatar smashercosmo commented on July 3, 2024

@alexleung could you create separate issue so we can discuss there?

from webpack-plugin-serve.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.