【问题标题】:Material UI: Class names in development are uglifiedMaterial UI:开发中的类名被丑化了
【发布时间】:2019-07-18 01:10:24
【问题描述】:

我有一个带有 SSR 的材质 ui 设置。我工作正常...

我的问题是,当我编译代码时,material-ui 会生成一些奇怪的类名,例如 jss116jss19

在开发中检查我的代码时,这真的很烦人。我想要(在我的开发环境中)更有意义的类名。这可能吗?

server.tsx

import * as path from 'path';
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 { createStore, Action } from 'redux';
import { Provider } from 'react-redux';

import {SheetsRegistry, create} from 'jss';
import JssProvider from 'react-jss/lib/JssProvider';
import {MuiThemeProvider, jssPreset, createGenerateClassName} from '@material-ui/core/styles';

import App from "../shared/App";
import routes from '../shared/routes';
import theme from '../shared/MainTheme';


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

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

console.log("Public path:", path.join(__dirname, "public"));

const appReducer = (prevState: any, action: Action) => ({...prevState, message: "Reducer"});

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

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

    const activeRoute = routes.find(route => !!matchPath(req.url, route)) || {
     path: "/" };
    // TODO: Fetch initial state according to the active route.
    const preloadedState = {activeRoute};
    const store = createStore(appReducer, preloadedState as any);

    const sheetsRegistry = new SheetsRegistry();
    const sheetsManager = new Map();
    const generateClassName = createGenerateClassName();
    const jss = create(jssPreset());



    const context = {}
    const content = ReactDOMServer.renderToString(
        <StaticRouter location={req.url} context={context}>
            <JssProvider jss={jss} registry={sheetsRegistry} generateClassName={generateClassName}>
                <MuiThemeProvider theme={theme} sheetsManager={sheetsManager}>
                    <Provider store={store}>
                        <App/>
                    </Provider>
                </MuiThemeProvider>
            </JssProvider>
        </StaticRouter>
    );

    const helmet = Helmet.renderStatic();
    const css = sheetsRegistry.toString();

    const html = `
        <!DOCTYPE html>
        <html>
        <head>
            <meta charset="UTF-8">            
            <meta name="viewport" content="width=device-width, initial-scale=1.0">            
            <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
            <link rel="icon" href="/favicon.ico" type="image/x-icon" />
            <style id="jss-server-side">${css}</style>            
        </head>
        <body>
            <div id="root" style="overflow-x: hidden; width: 100%; margin: 0;">${content}</div>
            <script src="client_bundle.js" type="text/javascript"></script>
            <script type="text/javascript">
                window.__PRELOADED_STATE__ = ${JSON.stringify(preloadedState).replace(/</g, '\\u003c')}
            </script>
        </body>
        </html>
    `;

    res.send(html);
});

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

client.tsx

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

import {createStore} from 'redux';
import {Provider} from 'react-redux';
import {appReducer} from '../shared/reducers';

import App from "../shared/App";
import {create} from "jss";
import {createGenerateClassName, MuiThemeProvider, jssPreset} from '@material-ui/core/styles';
import theme from '../shared/MainTheme';
import JssProvider from 'react-jss/lib/JssProvider';
import configureStore from '../shared/store/index';

declare global {
    interface Window {
        __PRELOADED_STATE__ : any
    }
}

const preloadedState = window.__PRELOADED_STATE__;
delete window.__PRELOADED_STATE__;
// const store = createStore(appReducer, preloadedState);
// const store = configureStore(appReducer, preloadedState);
const store = configureStore(preloadedState);

const Main = () => {
    React
        .useEffect(function didMount() {
            const jssStyles = document.getElementById('jss-server-side');
            if (jssStyles && jssStyles.parentNode) {
                jssStyles
                    .parentNode
                    .removeChild(jssStyles);
            }
        }, []);

    return <App/>
}

const generateClassName = createGenerateClassName();
const jss = create(jssPreset());

ReactDOM.hydrate(
    <JssProvider jss={jss} generateClassName={generateClassName}>
    <MuiThemeProvider theme={theme}>
        <BrowserRouter>
            <Provider store={store}>
                <Main/>
            </Provider>
        </BrowserRouter>
    </MuiThemeProvider>
</JssProvider>, document.querySelector('#root'),);

【问题讨论】:

    标签: reactjs debugging material-ui development-environment jss


    【解决方案1】:

    我终于通过像这样运行 webpack 来解决这个问题:

    webpack --mode=development ./server.ts

    结果,出于某种原因,webpack 不听 NODE_ENV

    【讨论】:

    • 你在哪里运行这个?我不知道我们在运行我们的 react 应用程序时必须单独运行 webpack。
    • 谢谢丹尼尔,你拯救了一天,我在客户端和服务器的不同 webpack 模式下遇到了完全相同的问题
    【解决方案2】:

    通过在构建工具中正确设置 NODE_ENV,您应该能够在开发中获得有意义的名称。

    【讨论】:

      【解决方案3】:

      您可以根据环境将 generateClassName 属性值更改为您的自定义生成器。在生产中,您可以使用通常的createGenerateClassName

      例如:

      let generateClassName = null;
      
      if (process.env.NODE_ENV === "production") {
        // use the default class name creator from mui
        generateClassName = createGenerateClassName();
      } else {
        // make your own name generator
        const createGenerateId = () => {
          let counter = 0;
          return (rule, sheet) => `pizza--${rule.key}-${counter++}`;
        };
        generateClassName = createGenerateId();
      }
      
      // ... in render
      <JssProvider generateClassName={generateClassName} ...>
        ...
      </JssProvider>
      

      这个例子取自CSS-in-JS Docs

      【讨论】:

        【解决方案4】:

        我遇到了这个问题,并通过使用createGenerateClassName 函数并将disableGlobal 选项设置为true 来修复它。

        const generateClassName = createGenerateClassName({
            disableGlobal: true,
        });
        
        const App = () => ({
            <StylesProvider generateClassName={generateClassName}>...</StylesProvider>
        });
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-11-27
          • 2021-03-20
          • 2016-02-14
          • 1970-01-01
          • 2021-11-13
          • 2011-07-02
          • 2021-09-06
          • 2020-07-04
          相关资源
          最近更新 更多