服务器端渲染上的webpack4开发服务器代理发生错误,导致热加载应用

时间:2018-08-01 19:38:20

标签: reactjs webpack webpack-dev-server serverside-rendering webpack-hmr

已经有一段时间,我试图使我的SSR React应用程序能够通过热重载工作,但是没有任何效果...

当我如上所述设置我的应用程序时,我的第一个重新加载页面会正确显示,但是一旦我进行了更改,HMR就会触发并重新加载该页面,最终导致出现错误页面: 尝试代理到localhost:8080 /

时发生错误

这是我的应用程序

webpack.config.js

const path = require('path');
const webpack = require('webpack');
const nodeExternals = require('webpack-node-externals');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const ErrorOverlayPlugin = require('error-overlay-webpack-plugin');


const isProd = process.argv.slice(-1)[0] === 'production';

const outPath = path.resolve(__dirname, 'public/dist');
const publicPath = '/public/dist/';

const common = {
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader'
                }
            },
            {
                test: /\.woff2?$/,
                loader: 'url-loader',
                options: {
                    name: 'fonts/[name].[ext]',
                    limit: 1000,
                },
            },
        ],
    },

    resolve: {
        alias: {
            app: path.resolve(__dirname, 'app'),
            test: path.resolve(__dirname, 'test'),
        },
    },

    optimization: {
        minimizer: [
            new UglifyJsPlugin({
                cache: true,
                parallel: true,
                sourceMap: true,
            }),
        ],
    },
};

const configs = {
    client: {
        entry: [
            'babel-polyfill',
            'react-hot-loader/patch',
            'webpack-dev-server/client?http://localhost:8080',
            'webpack/hot/only-dev-server',
            './app/components'
        ],
        output: {
            publicPath,
            path: outPath,
            filename: 'client.js',
        },
        devtool: isProd ? 'source-map' : 'eval-source-map',
        devServer: {
            publicPath,
            contentBase: outPath,
            proxy: {
                '*': {
                    target: 'http://localhost:8000',
                    secure: false,
                },
            },
        },
        plugins: isProd ? [] : [
            new ErrorOverlayPlugin(),
            new webpack.HotModuleReplacementPlugin(),
        ]
    },

    server: {
        target: 'node',
        entry: ['babel-polyfill', './app/server'],
        output: {
            path: outPath,
            publicPath,
            filename: 'server.js',
            libraryTarget: 'commonjs2'
        },
        devtool: false,
        node: { __dirname: true },
        externals: [ nodeExternals() ],
    },
};

module.exports = [
    Object.assign({}, common, configs.client),
    Object.assign({}, common, configs.server),
];

app / server / app.js

import express from 'express';
import cookieParser from 'cookie-parser';

import config from './config';
import { handleRender } from './render';


const app = express();

const publicDir = config.get('server.publicPath');

app.use('/public', express.static(publicDir));

app.use(cookieParser());
app.use(handleRender);

export default app;

app / components / index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { Provider } from 'react-redux';

import store from 'app/redux/store';

import App from './App';

const html = (
    <Provider store={store}>
        <BrowserRouter>
            <App />
        </BrowserRouter>
    </Provider>
);

if (window.ssr) {
    ReactDOM.hydrate(html, document.getElementById('root'));
} else {
    ReactDOM.render(html, document.getElementById('root'));
}

app / components / App.js

import _ from 'lodash';
import React from 'react';
import { Route, Switch } from 'react-router-dom';
import { hot } from 'react-hot-loader'
import { ThemeProvider } from 'styled-components';

import theme from 'app/assets/style/theme';
import Head from 'app/components/html/Head';

const App = () => (
    <ThemeProvider theme={theme}>
        <React.Fragment>
            <Head />
            <Switch>
                {* my routes... *}
            </Switch>
        </React.Fragment>
    </ThemeProvider>
);

export default hot(module)(App);

package.json

{
  "name": "staycation-ui",
  "version": "1.0.0",
  "private": true,
  "description": "Staycation client UI",
  "repository": "git+https://wario4@bitbucket.org/wario4/staycation.git",
  "author": "Staycation",
  "license": "ISC",
  "engines": {
    "node": "9"
  },
  "scripts": {
    "build": "rm -rf ./public/dist && npm run build:client",
    "build:client": "webpack --mode production --progress",
    "dev:client": "TARGET=client webpack-dev-server --mode development & TARGET=server webpack --mode development --watch",
    "dev:server": "nodemon ./public/dist/server.js",
    "lint": "eslint --color ./app/**/",
    "lint:fix": "eslint --fix ./app/**/",
    "stats": "webpack --config webpack.stats.js --mode production --progress",
    "test": "jest",
    "test:watch": "jest --watch"
  },
  "dependencies": {
    "babel-polyfill": "^6.26.0",
    "convict": "^4.3.2",
    "cookie-parser": "^1.4.3",
    "date-fns": "2.0.0-alpha.7",
    "express": "^4.16.3",
    "isomorphic-fetch": "^2.2.1",
    "jwt-decode": "^2.2.0",
    "lodash": "^4.17.10",
    "prop-types": "^15.6.1",
    "react": "^16.3.2",
    "react-dom": "^16.3.2",
    "react-final-form": "^3.6.5",
    "react-helmet": "^5.2.0",
    "react-lazyload": "^2.3.0",
    "react-redux": "^5.0.7",
    "react-router-dom": "^4.2.2",
    "react-sticky": "^6.0.3",
    "react-swipeable-views": "^0.12.15",
    "react-tap-event-plugin": "^3.0.3",
    "redux": "^4.0.0",
    "redux-devtools-extension": "^2.13.2",
    "redux-saga": "^0.16.0",
    "smooth-ui": "^4.2.2",
    "styled-components": "^3.2.6"
  },
  "devDependencies": {
    "babel-cli": "^6.26.0",
    "babel-core": "^6.26.3",
    "babel-eslint": "^8.2.3",
    "babel-jest": "^22.4.3",
    "babel-loader": "^7.1.4",
    "babel-plugin-styled-components": "^1.5.1",
    "babel-plugin-transform-class-properties": "^6.24.1",
    "babel-plugin-transform-object-rest-spread": "^6.26.0",
    "babel-preset-env": "^1.6.1",
    "babel-preset-react": "^6.24.1",
    "error-overlay-webpack-plugin": "^0.1.5",
    "eslint": "4.5.0",
    "eslint-config-airbnb": "15.1.0",
    "eslint-import-resolver-webpack": "^0.9.0",
    "eslint-plugin-import": "2.7.0",
    "eslint-plugin-jest": "21.15.1",
    "eslint-plugin-jsx-a11y": "5.1.1",
    "eslint-plugin-lodash": "2.7.0",
    "eslint-plugin-react": "7.2.0",
    "file-loader": "^1.1.11",
    "jest": "^22.4.3",
    "nodemon": "^1.17.3",
    "react-hot-loader": "^4.3.4",
    "supertest": "^3.0.0",
    "url-loader": "^1.0.1",
    "webpack": "^4.7.0",
    "webpack-bundle-analyzer": "^2.11.1",
    "webpack-cli": "^2.1.3",
    "webpack-dev-server": "^3.1.5",
    "webpack-node-externals": "^1.7.2"
  }
}

我发现很多关于GitHub的问题和论坛帖子 -Webpack开发服务器和代理 -如何使用SSR应用程序热加载 -HMR插件,如何配置Webpack ...

但是他们都没有帮助。我得到的更好的结果就是我现在得到的结果。

如果我做了一些更改,我可能会遇到相同的错误“尝试代理到时发生错误” ,但是在浏览器控制台中,当HMR尝试获取hot-update.js [上]个文件。 在进行“错误代理页面”或“错误代理控制台日志”之前,我进行了一次“热重装更新”,一切顺利。 关于这部分的奇怪之处在于,热更新的文件名哈希与我文件系统中保存的哈希不匹配。

无论如何,我完全迷路了,不知道该如何解决。

如果某人的答案或至少有任何解释可以帮助您找到正确的方向,那将非常有帮助!

谢谢!

0 个答案:

没有答案