Running a node express server using webpack-dev-server

后端 未结 4 860
梦如初夏
梦如初夏 2020-12-22 17:52

I\'m using webpack to run my react frontend successfully using the following config:

{
    name: \'client\',
    entry: \'./scripts/main.js\',
    output: {
         


        
相关标签:
4条回答
  • 2020-12-22 18:09

    Webpack-dev-server is great for client side development but it will not deploy Express api's or middleware. So in development I recommend running two separate servers: One for the client and one for your server side api's.

    Nodemon npm install --save-dev nodemon is a good backend development server that will give you hot-redeploy of your api's, or you can just use express and restart when you make changes. In production the client and api will still be served by the same express server.

    Set a lifecycle event for both nodemon and webpack-dev-server in your package.json to make starting them easy (example: npm run dev-server).

    "scripts": {
       "start": "webpack --progress --colors",
       "dev-server": "nodemon ./server.js localhost 8080",
       "dev-client": "webpack-dev-server --port 3000",
    }
    

    Or, to run express directly from node:

    "scripts": {
       "start": "webpack --progress --colors",
       "dev-server": "node dev-server.js",
       "dev-client": "webpack-dev-server --port 3000",
    }
    
    // dev-server.js
    const express = require('express');
    const app = express();
    // Import routes
    require('./_routes')(app);   // <-- or whatever you do to include your API endpoints and middleware
    app.set('port', 8080);
    app.listen(app.get('port'), function() {
        console.log('Node App Started');
    });
    

    Note: The api server must use a different port than webpack-dev-server.

    And finally in your webpack-dev-config you need to use a proxy to redirect calls to your api to the new port:

    devServer: {
      historyApiFallback: true,
      hot: true,
      inline: true,
    
      host: 'localhost', // Defaults to `localhost`
      port: 3000, // Defaults to 8080
      proxy: {
        '^/api/*': {
          target: 'http://localhost:8080/api/',
          secure: false
        }
      }
    },
    // and separately, in your plugins section
    plugins: [
      new webpack.HotModuleReplacementPlugin({
        multiStep: true
      })
    ]
    

    **Bonus points for having a single script to start and kill both

    0 讨论(0)
  • 2020-12-22 18:10

    Since webpack-dev-server is just a tiny express server with compile on change and hot reload.

    So, if you already got a express server for backend API, just merge the compile on change and hot reload into your express server.

    Then after take a look at the package.json of webpack-dev-server, i find the key is just webpack-dev-middleware

    const express = require('express'); //your original BE server
    const app = express();
    
    const webpack = require('webpack');
    const middleware = require('webpack-dev-middleware'); //webpack hot reloading middleware
    const compiler = webpack({ .. webpack options .. }); //move your `devServer` config from `webpack.config.js`
    
    
    app.use(middleware(compiler, {
      // webpack-dev-middleware options
    }));
    
    app.listen(3000, () => console.log('Example app listening on port 3000!'))
    

    So, when you run your BE server, it will compile all the things using webpack, and watch for changes, LOL ~

    Also, add webpack-hot-middleware for hot reloading function, see Hot Module Replacement

    0 讨论(0)
  • 2020-12-22 18:12

    Just faced the same issue and came with another solution (found out more information about it later, but here it is).

    Instead of using the webpack-dev-server, use the webpack --watch command so files are compiled again upon changes. Once the files are updated on the dist (or any other compiled files folder) you can set to run the nodemon on the dist folder and watch only the dist files.

    This way it is possible to have the express server running and serving the front-end as you would in a production environment (or kinda) and benefit from the fast reloads.

    Here's a link with some solutions to combine the webpack watch and nodemon.

    My scripts section is something like this at this moment (I'm using the run-all solution):

      "scripts": {
        "serve": "npm-run-all --parallel serve:webpack serve:nodemon",
        "serve:webpack": "webpack --progress --colors --watch",
        "serve:nodemon": "nodemon ./dist/app.js --watch dist"
      },
    
    0 讨论(0)
  • 2020-12-22 18:15

    From your questions here and here, it appears that you are using ReactJS with ES6. I faced the exact same issue, and here is how I tackled it -

    1. Have multiple entry points for your application

    In particular you can put all your vendor files like JQuery, React etc into one chunk. This way, your vendor files will remain the same even when you modify your souce files. You can add this line to your webpack config

    entry: {
        vendors: ['react','reactDom','jquery'] //Any other libraries
    }
    

    Use the CommonsChunkPlugin to have webpack determine what code/modules you use the most, and put it in a separate bundle to be used anywhere in your application.

    plugins: [
        new webpack.optimize.CommonsChunkPlugin('vendors', 'dist/js/vendors.js', Infinity),
    ]
    
    1. Use React Hot Loader

    Run npm install react-hot-loader --save-dev. Make sure you have installed webpack-dev-server first.

    Then you need to change your loaders to this -

    loaders: [
            { 
                test: /\.jsx?$/, 
                loaders: ['react-hot'],
                include: path.join(__dirname, 'public')
    
            },{ 
               loader: 'babel',
                query: {
                    presets: ['react', 'es2015']
                },
                include: path.join(__dirname, 'public')
            }, 
        ]
    

    Make sure React Hot Loader comes before Babel in the loaders array. Also make sure you have include: path.join(__dirname, 'public') to avoid processing node_modules, or you may get an error like this -

    Uncaught TypeError: Cannot read property 'NODE_ENV' of undefined

    1. Modifications to your script tags in your index.html page

    If your html has something like this -

    <script src="/dist/js/vendors.js"></script>
    <script src="/dist/js/app.bundle.js"></script>
    

    Change this to point to your webpack-dev-server proxy -

    <script src="http://localhost:8080/dist/js/vendors.js"></script>
    <script src="http://localhost:8080/dist/js/app.bundle.js"></script>
    
    1. Run webpack-dev-server --hot --inline,

    wait for the bundling to finish, then hit http://localhost:3000 (your express server port) in your browser.

    If you run into any errors, you could find this troubleshooting guide very useful.

    Hope this helps, and you can take a look at the webpack setup for my project here

    0 讨论(0)
提交回复
热议问题