web-dev-qa-db-ja.com

webpack-dev-serverを使用してノードエクスプレスサーバーを実行する

私はwebpackを使用して、次の設定を使用して反応フロントエンドを正常に実行しています:

{
    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']
                }
            }
        ]
    }
}

Node.jsエクスプレスバックエンドも設定しようとしていますが、webpackでも同様に実行したいので、バックエンドとフロントエンドの両方を実行する単一のサーバーがあります。私のjavascript。

私は次のような簡単なテストサーバーを作成しました。

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

node index.jsでこれを実行し、localhost:3000でブラウザを開くと、「Hello world from Express !!」と出力されます。ここまでは順調ですね。次に、そのためのWebパック構成を作成してみました。

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

コマンドwebpack-dev-serverを実行すると、正常に起動します(と思われます)。ただし、localhost:3000でブラウザにアクセスすると、サーバーがまったく実行されていないときと同じように、Webページが利用できないと表示されます。

私はnodeとwebpackの両方にとても慣れていないので、どこかで小さな間違いを犯したか、もう少し離れています;)

58

Webpack-dev-serverはクライアント側の開発には最適ですが、Express apiまたはミドルウェアをデプロイしません。したがって、開発では、クライアント用とサーバー側API用の2つのサーバーを実行することをお勧めします。

Nodemon npm install --save-dev nodemonは、APIのホット再デプロイを可能にする優れたバックエンド開発サーバーです。または、変更を加えたときにエクスプレスを使用して再起動することもできます。本番環境でも、クライアントとAPIは同じエクスプレスサーバーによって提供されます。

package.jsonでnodemonとwebpack-dev-serverの両方のライフサイクルイベントを設定して、簡単に起動できるようにします(例:npm run dev-server)。

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

または、ノードから直接エクスプレスを実行するには:

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

注:APIサーバーはwebpack-dev-serverとは異なるポートを使用する必要があります。

最後に、webpack-dev-configで、プロキシを使用してAPIへの呼び出しを新しいポートにリダイレクトする必要があります。

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

**両方を開始および終了する単一のスクリプトがあることに対するボーナスポイント

88
perilandmishap

webpack-dev-server は、変更時のコンパイルとホットリロードを行う小さなエクスプレスサーバーであるためです。

したがって、バックエンドAPI用のエクスプレスサーバーを既に取得している場合は、compile on change and hot reloadをエクスプレスサーバーにマージするだけです。

次に、 webpack-dev-serverpackage.jsonを見てみると、キーは 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!'))

したがって、BEサーバーを実行すると、webpackを使用してすべてのものがコンパイルされ、変更を監視しますLOL〜

また、ホットリロード機能について webpack-hot-middleware を追加します。 ホットモジュール交換 を参照してください。

14
Shawn Wang

ここでの質問と here から、ReactJSとES6を使用しているようです。私はまったく同じ問題に直面しました、そして、ここに私がそれに取り組む方法があります-

  1. アプリケーションに複数のエントリポイントがある

特に、JQuery、Reactなどのすべてのベンダーファイルを1つのチャンクに入れることができます。この方法では、ソースファイルを変更しても、ベンダーファイルは同じままです。この行をwebpack configに追加できます

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

CommonsChunkPluginを使用して、最も多く使用するコード/モジュールをwebpackで決定し、アプリケーション内のどこででも使用できるように別のバンドルに入れます。

plugins: [
    new webpack.optimize.CommonsChunkPlugin('vendors', 'dist/js/vendors.js', Infinity),
]
  1. React Hot Loaderを使用します

npm install react-hot-loader --save-devを実行します。最初にwebpack-dev-serverをインストールしたことを確認してください。

次に、ローダーをこれに変更する必要があります-

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

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

ローダー配列でReact Hot LoaderがBabelの前に来ることを確認してください。また、node_modulesの処理を避けるためにinclude: path.join(__dirname, 'public')があることを確認してください。そうしないと、次のようなエラーが表示される場合があります-

Uncaught TypeError: Cannot read property 'NODE_ENV' of undefined

  1. index.htmlページのスクリプトタグの変更

HTMLに次のようなものがある場合-

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

これをwebpack-dev-serverプロキシを指すように変更します-

<script src="http://localhost:8080/dist/js/vendors.js"></script>
<script src="http://localhost:8080/dist/js/app.bundle.js"></script>
  1. webpack-dev-server --hot --inlineを実行し、

バンドルが完了するのを待ってから、ブラウザで http:// localhost:30 (エクスプレスサーバーポート)を押します。

エラーが発生した場合、これを見つけることができます トラブルシューティングガイド 非常に便利です。

これがお役に立てば幸いです。私のプロジェクトのウェブパックのセットアップをご覧ください here

7
booleanhunter