web-dev-qa-db-de.com

Ausführen eines Node-Express-Servers mit webpack-dev-server

Ich verwende Webpack, um mein Reaktions-Frontend mit der folgenden Konfiguration erfolgreich auszuführen:

{
    name: 'client',
    entry: './scripts/main.js',
    output: {
        path: __dirname,
        filename: 'bundle.js'  
    },
    module: {
        loaders: [
            {
                test: /.jsx?$/,
                loader: 'babel-loader',
                exclude: /node_modules/,
                query:{
                    presets: ['es2015', 'react', 'stage-2']
                }
            }
        ]
    }
}

Ich versuche, auch ein node.js-Express-Backend einzurichten, und möchte dies auch über das Webpack ausführen, damit ein einziger Server sowohl das Backend als auch das Frontend ausführt und ich babel zum Transpilieren verwenden möchte mein Javascript.

Ich habe einen schnellen Testserver erstellt, der so aussieht:

var express = require('express');
console.log('test');

var app = express();

app.get('/', function(req, res){
    res.send("Hello world from Express!!");
});

app.listen(3000, function(){
    console.log('Example app listening on port 3000');
});

Wenn ich dies mit node index.js Ausführe und meinen Browser auf localhost:3000 Öffne, wird "Hello world from Express !!" gedruckt. So weit, ist es gut. Dann habe ich versucht, eine Web-Pack-Konfiguration dafür zu erstellen:

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 = [
{
    name: 'server',
    target: 'node',
    entry: './index.js',
    output: {
        path: __dirname,
        filename: 'bundle.js'
    },
    externals: nodeModules,
    module: {
        loaders: [
            { 
                test: /\.js$/,
                loaders: [
                    'babel-loader'
                ]
            },
            {
                test:  /\.json$/, 
                loader: 'json-loader'
            }
        ]
    }
}   

Wenn ich den Befehl webpack-dev-server Ausführe, wird er erfolgreich gestartet (es scheint). Wenn ich jedoch jetzt auf localhost:3000 Zu meinem Browser gehe, heißt es nur, dass die Webseite nicht verfügbar ist, genau wie wenn der Server überhaupt nicht läuft.

Ich bin sowohl für Node als auch für Webpack sehr neu. Entweder habe ich irgendwo einen kleinen Fehler gemacht, oder ich bin weit weg.

58

Der Webpack-Dev-Server eignet sich hervorragend für die clientseitige Entwicklung, stellt jedoch keine Express-APIs oder Middleware bereit. In der Entwicklung empfehle ich daher, zwei separate Server zu betreiben: einen für den Client und einen für die serverseitigen APIs.

Nodemon npm install --save-dev nodemon ist ein guter Back-End-Entwicklungsserver, mit dem Sie Ihre APIs im laufenden Betrieb erneut bereitstellen können, oder Sie können Express verwenden und neu starten, wenn Sie Änderungen vornehmen. In der Produktion werden Client und API weiterhin vom selben Express-Server bedient.

Setze ein Lifecycle Event für nodemon und webpack-dev-server in deinem package.json um das Starten zu vereinfachen (Beispiel: npm run dev-server).

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

Oder, um Express direkt vom Knoten auszuführen:

"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');
});

Hinweis: Der API-Server muss einen anderen Port als der webpack-dev-server verwenden.

Und schließlich müssen Sie in Ihrer Webpack-Dev-Config einen Proxy verwenden, um Aufrufe an Ihre API an den neuen Port umzuleiten:

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
  })
]

** Bonuspunkte für das Starten und Beenden eines einzelnen Skripts

88
perilandmishap

Da webpack-dev-server nur ein winziger Express-Server mit Kompilierung bei Änderung und Hot-Reload ist.

Wenn Sie bereits einen Express-Server für die Backend-API haben, fügen Sie einfach das compile on change and hot reload in Ihren Express-Server.

Dann nach einem Blick auf die package.json von Webpack-Dev-Server , ich finde, der Schlüssel ist nur 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!'))

Wenn Sie also Ihren BE-Server ausführen, kompiliert er alle Dinge mit Webpack und sucht nach Änderungen: LOL ~

Fügen Sie auch webpack-hot-middleware hinzu, um Informationen zum Hot-Reload zu erhalten, siehe Hot Module Replacement

14
Shawn Wang

Aus Ihren Fragen hier und hier geht hervor, dass Sie ReactJS mit ES6 verwenden. Ich hatte genau das gleiche Problem und hier ist, wie ich es angegangen bin -

  1. Haben Sie mehrere Einstiegspunkte für Ihre Anwendung

Insbesondere können Sie alle Ihre Herstellerdateien wie JQuery, React etc.) In einem Block zusammenfassen. Auf diese Weise bleiben Ihre Herstellerdateien auch dann erhalten, wenn Sie Ihre Quellendateien ändern. Sie können diese Zeile hinzufügen zu deiner webpack config

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

Verwenden Sie das CommonsChunkPlugin, damit das Webpack ermittelt, welchen Code/welche Module Sie am häufigsten verwenden, und legen Sie ihn in einem separaten Bundle ab, das Sie an einer beliebigen Stelle in Ihrer Anwendung verwenden können.

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

Führen Sie npm install react-hot-loader --save-dev Aus. Stellen Sie sicher, dass Sie zuerst webpack-dev-server Installiert haben.

Dann müssen Sie Ihre Lader auf diese ändern -

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

        },{ 
           loader: 'babel',
            query: {
                presets: ['react', 'es2015']
            },
            include: path.join(__dirname, 'public')
        }, 
    ]

Stellen Sie sicher, dass React Hot Loader vor Babel im Loader-Array steht. Stellen Sie auch sicher, dass include: path.join(__dirname, 'public') vorhanden ist, um die Verarbeitung von node_modules zu vermeiden. Anderenfalls wird möglicherweise ein Fehler wie dieser angezeigt.

Uncaught TypeError: Cannot read property 'NODE_ENV' of undefined

  1. Änderungen an Ihren Skript-Tags auf Ihrer Seite index.html

Wenn Ihr HTML hat so etwas -

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

Ändern Sie dies, um auf Ihren Webpack-Dev-Server-Proxy zu verweisen.

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

warten Sie, bis die Bündelung abgeschlossen ist, und drücken Sie dann http: // localhost: 30 (Ihr Express-Server-Port) in Ihrem Browser.

Wenn Sie auf Fehler stoßen, finden Sie dies Anleitung zur Fehlerbehebung sehr nützlich.

Ich hoffe, das hilft, und Sie können sich das Webpack-Setup für mein Projekt ansehen hier

7
booleanhunter