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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why are Webpack-related packages required unconditionally in server.js? #66

Open
simevidas opened this issue Jan 2, 2017 · 5 comments

Comments

@simevidas
Copy link

simevidas commented Jan 2, 2017

I apologize if this is a stupid question. I’m just about to start using Webpack for my Express web app.

In server.js, I see that webpack, webpack-dev-middleware, and webpack-hot-middleware are required at the top of the file, unconditionally.

const webpack = require('webpack');
const webpackMiddleware = require('webpack-dev-middleware');
const webpackHotMiddleware = require('webpack-hot-middleware');

Shouldn’t these statements be inside the if (isDeveloping) branch? Otherwise, Webpack runs on the actual web server in production, if I understand correctly.

@kbariotis
Copy link
Contributor

kbariotis commented Jan 3, 2017

@simevidas Nope, that's not a stupid question at all. :)

The requirement of these packages doesn't mean that are going to run. The actual invocation happens bellow at lines #15, #16 and still those lines aren't causing webpack to run. Later below, the middleware variable is being passed as a middleware (l. #29) to express.js. This means that Webpack will run once a request comes in. This happens only in development, obviously.

You could add another bootstrap file for production if you like where webpack wont being required.

@simevidas
Copy link
Author

simevidas commented Jan 8, 2017

Hm, if I understand correctly, require executes the module (i.e. the module’s code is parsed and compiled).

Example 1: foo is always parsed/compiled but only used in development:

let foo = require('foo');

if (development) {
  foo();
} 

Example 2: foo is only parsed, compiled and used in in development:

if (development) {
  let foo = require('foo');
  foo();
} 

I’m not sure why Webpack-related modules should be parsed and compiled in production. It just wastes server time and memory. (Correct me if I’m wrong.)

For comparison, this is my own setup and it works fine for HMR:

if (process.env.NODE_ENV === 'development') {
    let webpack = require('webpack');
    let config = require('./webpack.config');
    let compiler = webpack(config);

    app.use(require('webpack-dev-middleware')(compiler));
    app.use(require('webpack-hot-middleware')(compiler));
}

@kbariotis
Copy link
Contributor

kbariotis commented Jan 8, 2017

Indeed they are useless since they are never going to be used in production.

It justs wastes server time and memory.

Well yes but it's only loading the source code, which is really negligible. Actually server processing and usage waste happens when you actually tell webpack to do something.

Like I said, I would separate the server.js file into two. One that will use webpack and one that would not. I would argue that you should keep your requires in one single location, on the top of each file, for consistency and to avoid hidden circular references.

But either way, your code works just fine! :)

@simevidas
Copy link
Author

I got curious so I run a test on my code - I’ve measured the time and memoryUsage before/after loading the 3 Webpack modules that are used for HMR:

if (process.env.NODE_ENV === 'development') {

    console.log(`Memory before: ${JSON.stringify(process.memoryUsage())}`);
    console.time('webpack');
    let webpack = require('webpack');
    let webpackDevMiddleware = require('webpack-dev-middleware');
    let webpackHotMiddleware = require('webpack-hot-middleware');
    console.timeEnd('webpack');
    console.log(`Memory after: ${JSON.stringify(process.memoryUsage())}`);

    let config = require('./webpack.config');
    let compiler = webpack(config);

    app.use(webpackDevMiddleware(compiler));
    app.use(webpackHotMiddleware(compiler));
}

The results are consistent on my machine. Here is one result:

Memory before: {"rss":28860416,"heapTotal":17862656,"heapUsed":9213872}
webpack: 749.479ms
Memory after: {"rss":44367872,"heapTotal":33591296,"heapUsed":21152024}

It looks like the Webpack modules take up ~16 MB, in addition to slowing down server boot (my app is not ready for deployment, so I can’t test on my actual web server yet).

I recommend optimizing the boilerplate, so that server resources aren’t wasted. This seems like a good idea for the default setup.

@kbariotis
Copy link
Contributor

I would love to throw a PR. @christianalfoni what do you think?

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

No branches or pull requests

2 participants