简体   繁体   English

React + Material UI + Typescript + Webpack + SSR 不起作用

[英]React + Material UI + Typescript + Webpack + SSR not working

I have this app which I'm rendering on the server side.我有我在服务器端渲染的这个应用程序。 Everything was working fine until I tried to add Material UI to it.一切正常,直到我尝试向其中添加 Material UI。

My directory structure is this:我的目录结构是这样的:

app/
   build/ * This is created by webpack
        server_bundle.js
        public/
              client_bundle.js
              fonts/
              images/
   src/
      client/
            Client.tsx
      server/
            server.tsx
      shared/
            App.tsx
            routes.tsx
   webpack.config.js

And here are my files content:这是我的文件内容:

webpack.config.js webpack.config.js

const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
    target: 'node',
    entry: {
        server: path.resolve(__dirname, 'src/server/server.tsx'),
        "public/client": path.resolve(__dirname, 'src/client/client.tsx')

    },
    output: {
        filename: '[name]_bundle.js',
        path: path.resolve(__dirname, 'build'),
        publicPath: '/build'
    },
    resolve: {
        extensions: ['.ts', '.tsx', '.js', '.jsx']
    },
    module: {
        rules: [{
                test: /\.(tsx|ts)?$/,
                loader: 'awesome-typescript-loader',
                options: {
                    jsx: 'react'
                }
            },
            {
                test: /\.(scss|sass|css)$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    {
                        loader: 'css-loader',
                        options: {
                            sourceMap: true
                        }
                    },
                ]
            },
            {
                test: /\.(ico)$/,
                loader: 'file-loader',
                options: { outputPath: '/public', publicPath: '/public', name: '[name].[ext]' }
            },
            {
                test: /\.(png|svg|jpg|jpeg|gif)$/,
                loader: 'file-loader',
                options: { outputPath: '/public/images', publicPath: 'images' }
            },
            {
                test: /\.(woff|woff2|eot|ttf|otf)$/,
                loader: 'file-loader',
                options: { outputPath: '/public/fonts', publicPath: 'fonts' }
            },
        ]
    },
    optimization: {
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: 'public/styles_bundle.css',
            chunkFilename: "public/styles/[id].css"
        })
    ]
}

server.tsx服务器.tsx

import * as express from "express";
import * as bodyParser from "body-parser";
import * as React from "react";
import * as ReactDOMServer from "react-dom/server";
import {StaticRouter} from "react-router";
import { matchPath } from "react-router-dom";
import {Helmet} from "react-helmet";
import App from "../shared/App";
import routes from '../shared/routes';

const app = express();
const PORT = process.env.PORT || 3000;

app.use(bodyParser.urlencoded());
app.use(bodyParser.json());
app.use(express.static("build/public"));

app.get('*', (req, res, next) => {

    const activeRoute = routes.find(route => !!matchPath(req.url, route)) || {path: "/"};

    const now = new Date();
    console.log(`GET ${now} - ${req.url}`);

    const context = {}
    const content = ReactDOMServer.renderToString(
            <StaticRouter location={req.url} context={context}>
                <App />
            </StaticRouter>
    );

    const helmet = Helmet.renderStatic();

    const html = `
        <!DOCTYPE html>
        <html>
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            ${helmet.title.toString()}
            ${helmet.meta.toString()}
            <link rel="stylesheet" href="styles_bundle.css">
            <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
            <link rel="icon" href="/favicon.ico" type="image/x-icon" />
        </head>
        <body>
            <div id="root" style="overflow-x: hidden; width: 100%; margin: 0;">${content}</div>
            <script src="client_bundle.js"></script>
        </body>
        </html>
    `;

    res.send(html);
});



app.listen(PORT, () => {
    console.log(`App is running on port ${PORT}`)
})

Client.tsx客户端.tsx

import * as React from "react";
import * as ReactDOM from 'react-dom';
import { BrowserRouter } from "react-router-dom";

import App from "../shared/App";

// Because it's already been rendered, we only need to hydrate event
// handlers and wire things up. 
ReactDOM.hydrate(
    <BrowserRouter>
        <App />
    </BrowserRouter>,
    document.querySelector("#root")
);

App.tsx应用程序.tsx

import * as React from 'react';
import routes from "../shared/routes";
import { Helmet } from 'react-helmet';
import { Switch, Route } from "react-router";
import 'typeface-roboto';

class App extends React.Component {
    render() {
        return (
            <React.Fragment>            

                <Switch>
                    {routes.map(({path, exact, component: C}) => {
                        return <Route 
                            path={path} 
                            exact={exact}                                                       
                            render={(props) => <C {...props}/> }
                        />
                    })}                   
                </Switch>

            </React.Fragment>
        )
    }
}

export default App;

And finally, routes.tsx最后, routes.tsx

import * as React from 'react';
import { Button } from '@material-ui/core';

const routes = [
    {
        name: "Home",
        exact: true,
        path: "/",
        component: (props:any) => {return (

            <Button variant="contained" color="primary">
                Hello World
            </Button>
        )}
    }
];

export default routes;

I get this error in my browser console and obviously no material ui styles whatsoever:我在浏览器控制台中收到此错误,显然没有任何材质 ui 样式:

client_bundle.js:44 Uncaught ReferenceError: global is not defined
    at Object.<anonymous> (client_bundle.js:44)
    at n (client_bundle.js:1)
    at Object.<anonymous> (client_bundle.js:1)
    at n (client_bundle.js:1)
    at Object.<anonymous> (client_bundle.js:17)
    at n (client_bundle.js:1)
    at Object.<anonymous> (client_bundle.js:17)
    at n (client_bundle.js:1)
    at Object.<anonymous> (client_bundle.js:36)
    at n (client_bundle.js:1)

That part of the client_bundle.js looks like this: client_bundle.js那部分看起来像这样:

... __esModule",{value:!0});global.CSS;t.default=function(e){return e}} ...

What do you think might be happenning here??你认为这里可能会发生什么?

 try this workaround in your 

 plugins: [
            new webpack.DefinePlugin({
           'global': {} //  webpack workaround
          }),
            new MiniCssExtractPlugin({
            filename: 'public/styles_bundle.css',
            chunkFilename: "public/styles/[id].css"
            })
          ]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 SSR with Node, Webpack, React, Express, Material UI, React Router - 错误 [ERR_REQUIRE_ESM]: 必须使用导入加载 ES 模块 - SSR with Node, Webpack, React, Express, Material UI, React Router - Error [ERR_REQUIRE_ESM]: Must use import to load ES Module SSR + 材质 UI 抽屉 + webpack 生产构建损坏 - SSR + Material UI Drawer + webpack production build broken 传播运算符不适用于 setState(React、Typescript 和 Material-ui) - Spread operator not working with setState (React, Typescript & Material-ui) Next.js - Material-ui css SSR 不适用于组件 - Next.js - Material-ui css SSR not working with components 如何使用Typescript设置React的Material-UI? - How to setup Material-UI for React with Typescript? 使用 TypeScript/React/Material-UI 的全局主题 - Global theme with TypeScript/React/Material-UI Material UI / Webpack / React - 生产模式下的 className 优化/缩小 - Material UI / Webpack / React - the className optimization/minification in production mode 无法通过 webpack/rollup/react 在外部库中使用 Material UI - Can't use Material UI in external library with webpack/rollup/react Modal 内的滑块不起作用 - React + Material UI - Slider inside of Modal is not working - React + Material UI Material UI React Slider 组件在移动设备上不起作用 - Material UI React Slider Component Not Working on mobile
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM