How can I use webpack with express?
What I ended up doing was I used 2 different configurations, 1 for packing the server stuff together using webpack, and 1 for packing all the browser stuff together and also run webpack dev server for hot reloading.
Server webpack config aka webpack.node.config.js
now looks like this:
var webpack = require('webpack');var path = require('path');var fs = require('fs');var nodeModules = {};// note the path.resolve(__dirname, ...) part// without it, eslint-import-resolver-webpack fails// since eslint might be invoked with different cwdfs.readdirSync(path.resolve(__dirname, 'node_modules')) .filter(x => ['.bin'].indexOf(x) === -1) .forEach(mod => { nodeModules[mod] = `commonjs ${mod}`; });// es5 style alternative// fs.readdirSync(path.resolve(__dirname, 'node_modules'))// .filter(function(x) {// return ['.bin'].indexOf(x) === -1;// })// .forEach(function(mod) {// nodeModules[mod] = 'commonjs ' + mod; // });module.exports ={ // The configuration for the server-side rendering name: 'server', target: 'node', entry: './app/server/serverEntryPrototype.js', output: { path: './bin/', publicPath: 'bin/', filename: 'serverEntryPoint.js' }, externals: nodeModules, module: { loaders: [ { test: /\.js$/, loaders: [ // 'imports?document=this', // 'react-hot', 'babel-loader' //,'jsx-loader' ] }, { test: /\.json$/, loader: 'json-loader' }, ] }, plugins: [ // new webpack.NormalModuleReplacementPlugin("^(react-bootstrap-modal)$", "^(react)$") // new webpack.IgnorePlugin(new RegExp("^(react-bootstrap-modal)$")) // new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/) ]};
Browser webpack config aka webpack.browser.config.js
now looks like this:
var webpack = require('webpack');var path = require('path');var buildPath = path.resolve(__dirname, 'assets');var fs = require('fs');var commonLoaders = [ { test: /\.js$/, loaders: [ 'react-hot', 'babel-loader' //,'jsx-loader' ] }];module.exports ={ // Makes sure errors in console map to the correct file // and line number name: 'browser', devtool: 'eval', entry: [ //'./bin/www.js', './app/index.js', 'webpack/hot/dev-server', 'webpack-dev-server/client?http://localhost:8081' // WebpackDevServer host and port ], output: { path: buildPath, filename: '[name].js', // Everything related to Webpack should go through a build path, // localhost:3000/build. That makes proxying easier to handle publicPath: 'http://localhost:8081/assets/' }, extensions: [ '', '.jsx', '.js', '.json', '.html', '.css', '.styl', '.scss', '.sass' ], module: { loaders: [ // Compile es6 to js. { test: /app\/.*\.jsx?$/, loaders: [ 'react-hot', 'babel-loader' ] }, ///app\/.*\.json$/ { test: /\.json$/, loader: 'json-loader' }, // Styles { test: /\.css$/, loader: 'style-loader!css-loader' }, { test: /\.s(a|c)ss$/, loader: 'style!css?localIdentName=[path][name]---[local]---[hash:base64:5]!postcss!sass' }, // Fonts { test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url-loader?limit=10000&minetype=application/font-woff' }, { test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'file-loader' } //{ test: /\.png$/, loader: 'url-loader?limit=100000' }, //{ test: /\.jpg$/, loader: 'file-loader' } ], plugins: [ new webpack.HotModuleReplacementPlugin(), new webpack.NoErrorsPlugin() ] }, postcss: [ require('autoprefixer-core') ], devtool: 'source-map'};
It can be realized by specifying "node" to "target" option, since v1.10.2.
For reference: http://jlongster.com/Backend-Apps-with-Webpack--Part-I
If you want to bundle the server and the client's code at the same time, it is possible to use multiple configuration in the following manner.
// webpack.config.jsmodule.exports = [ { name: 'server', entry: './src/server/index.js', target: 'node', output: { path: __dirname + '/dist/server', filename: 'bundle.js', }, }, { name: 'client', entry: './src/client/index.js', // target: 'web', // by default output: { path: __dirname + '/dist/client', filename: 'bundle.js', }, }];
I am just clarifying @meta2's answer because I believe it can be written in a more understandable way - although full points to him!
tl;dr - set target: 'node'
in your webpack.config.js
to fix the errors that get generated when using Webpack with Express.
You still get warnings like:
WARNING in ./node_modules/express/lib/view.js 81:13-25 Critical dependency: the request of a dependency is an expression
To fix those, use https://github.com/liady/webpack-node-externals. FYI - this reduces you bundle size significantly (check size before and after) and speeds up the bundling time incredibly.
Full example:
const path = require('path')const nodeExternals = require('webpack-node-externals')module.exports = { entry: './src/app.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') }, target: 'node', // THIS IS THE IMPORTANT PART externals: [nodeExternals()], mode: 'development'}