Material UI: Class 开发中的名字被丑化了
Material UI: Class names in development are uglified
我有一个 material ui 设置和 SSR。我工作正常...
我的问题是,当我编译我的代码时,material-ui 生成了一些奇怪的 class 名称,例如 jss116
或 jss19
。
在开发中检查我的代码时,这真的很烦人。我想要(在我的开发环境中)更有意义的 class 名称。这可能吗?
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'),);
您可以根据环境将 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。
通过在构建工具中正确设置 NODE_ENV,您应该能够在开发中获得有意义的名称。
我终于通过 运行 webpack 解决了这个问题,如下所示:
webpack --mode=development ./server.ts
事实证明,出于某种原因,webpack 不听 NODE_ENV
我 运行 解决了这个问题,并通过使用 createGenerateClassName
函数并将 disableGlobal
选项设置为 true
来修复它。
const generateClassName = createGenerateClassName({
disableGlobal: true,
});
const App = () => ({
<StylesProvider generateClassName={generateClassName}>...</StylesProvider>
});
我有一个 material ui 设置和 SSR。我工作正常...
我的问题是,当我编译我的代码时,material-ui 生成了一些奇怪的 class 名称,例如 jss116
或 jss19
。
在开发中检查我的代码时,这真的很烦人。我想要(在我的开发环境中)更有意义的 class 名称。这可能吗?
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'),);
您可以根据环境将 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。
通过在构建工具中正确设置 NODE_ENV,您应该能够在开发中获得有意义的名称。
我终于通过 运行 webpack 解决了这个问题,如下所示:
webpack --mode=development ./server.ts
事实证明,出于某种原因,webpack 不听 NODE_ENV
我 运行 解决了这个问题,并通过使用 createGenerateClassName
函数并将 disableGlobal
选项设置为 true
来修复它。
const generateClassName = createGenerateClassName({
disableGlobal: true,
});
const App = () => ({
<StylesProvider generateClassName={generateClassName}>...</StylesProvider>
});