47

I've been trying to use webpack with a nodejs application, and the client side is going fine - a reasonably good documentation on their website + links from google search.

Has anyone used webpack on server side of nodejs? or please guide me to any useful links.

Thanks.

3 Answers 3

32

This might be useful: http://jlongster.com/Backend-Apps-with-Webpack--Part-I

Key point is to make external all third party module (in node_modules directory) in webpack config file

Final config file

var webpack = require('webpack');
var path = require('path');
var fs = require('fs');

var nodeModules = {};
fs.readdirSync('node_modules')
  .filter(function(x) {
    return ['.bin'].indexOf(x) === -1;
  })
  .forEach(function(mod) {
    nodeModules[mod] = 'commonjs ' + mod;
  });

module.exports = {
  entry: './src/main.js',
  target: 'node',
  output: {
    path: path.join(__dirname, 'build'),
    filename: 'backend.js'
  },
  externals: nodeModules,
  plugins: [
    new webpack.IgnorePlugin(/\.(css|less)$/),
    new webpack.BannerPlugin('require("source-map-support").install();',
                             { raw: true, entryOnly: false })
  ],
  devtool: 'sourcemap'
}
Sign up to request clarification or add additional context in comments.

3 Comments

For some reason I had to add libraryTarget : "commonjs" inside the output section for me to work
how do you then bring in the "dependencies" (and not devDependencies) into /build/node_modules?
I had to use libraryTarget : "commonjs2" to make it work
26

A real example with webpack 2.x

I want to highlight the difference from client side config:

1. target: 'node'

2. externals: [nodeExternals()]

for node.js, it doesn't make much sense to bundle node_modules/

3. output.libraryTarget: 'commonjs2'

without this, you cannot require('your-library')

webpack.config.js

import nodeExternals from 'webpack-node-externals'

const config = {
  target: 'node',
  externals: [nodeExternals()],
  entry: {
    'src/index': './src/index.js',
    'test/index': './test/index.js'
  },
  output: {
    path: __dirname,
    filename: '[name].bundle.js',
    libraryTarget: 'commonjs2'
  },
  module: {
    rules: [{
      test: /\.js$/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: [
            ['env', {
              'targets': {
                'node': 'current'
              }
            }]
          ]
        }
      }
    }]
  }
}

export default [config]

6 Comments

Can you please explain - for node.js, it doesn't make much sense to bundle node_modules/ - is this because it's running on the server and we don't need to worry about bundling our code to reduce the number of requests? Learning here ... thanks.
@Ryan-NealMes it's running on the server and we don't need to worry about bundling our code to reduce the number of requests is correct. Another reason is there is duplicate code if some libraries exist both in 'node_modules/' and in your bundle.
How do you use this generated server-side bundle?
@1252748 I am mainly talking about server side libraries here. Most likely I will publish it to npmjs.org. Then every one can install and use it just like other node.js libraries. If what you have is an app instead of a library, you can always extract some code and make it a library just to reuse code.
Ah, I was using the target: 'node' setting so I could bundle up an express server, and dockerize both front and back end bundles for production use. Would you say that's a typical use of this config option?
|
1

Here is the webpack configuration I have used to in my Nodejs application when I wanted it to read JSX which as you know, Node cannot do.

const path = require('path');

module.exports = {
  // inform webpack that I am building a bundle for nodejs rather than for the
  // browser
  target: 'node',

  // tell webpack the root file of my server application
  entry: './src/index.js',

  // tells webpack where to put the output file generated
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'build')
  },

  // tells webpack to run babel on every file it runs through
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
        options: {
          presets: [
            'react',
            'stage-0',
            ['env', { targets: { browsers: ['last 2 versions'] } }]
          ]
        }
      }
    ]
  }
};

After you implement this though, don't forget to head over to your package.json file and include this script:

{
  "name": "react-ssr",
  "version": "1.0.0",
  "description": "Server side rendering project",
  "main": "index.js",
  "scripts": {
    "dev:build:server": "webpack --config webpack.server.js"
  },

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.