gpt4 book ai didi

javascript - 没有样式表的加载/服务 - react

转载 作者:数据小太阳 更新时间:2023-10-29 04:16:37 29 4
gpt4 key购买 nike

我正在尝试使用 React 路由器的 StaticRouter 进行 SSR .

express.js (服务器)

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

res.status(200).send(`
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="/app.css" type="text/css"/>
</head>
<body>
<div id="app">${html}</div>
</body>
</html>
`);

静态文件服务:

app.use(express.static(path.resolve(__dirname, "../dist/client")));

App.js (共享)

import React from "react";
import { Switch, Route } from "react-router";

export default () => {
return (
<Switch>
...
</Switch>
);
};

index.jsx (客户端)

import React from "react";
import { BrowserRouter } from "react-router-dom";
import ReactDOM from "react-dom";
import App from "./App";

ReactDOM.render(
<BrowserRouter>
<App/>
</BrowserRouter>,
document.getElementById("app")
);

./styles/Main.scss

.header {
background-color: #002933;
}

我有 2 个 webpack 配置,1 个用于客户端,1 个用于服务器:

webpack.config.dev.js

const nodeExternals = require("webpack-node-externals");
const webpack = require("webpack");
const ExtractTextPlugin = require("extract-text-webpack-plugin");

module.exports = {
devtool: "cheap-module-eval-source-map",
entry: {
app: [
"eventsource-polyfill",
"webpack-hot-middleware/client",
"webpack/hot/only-dev-server",
"react-hot-loader/patch",
"./client/index.jsx",
],
vendor: [
"react",
"react-dom",
],
},
output: {
path: `${__dirname}/dist/client`,
...
},
...
module: {
loaders: [
...
}, {
test: /\.scss$/,
exclude: /node_modules/,
loader: ExtractTextPlugin.extract({
fallback: "style-loader",
use: [
{
loader: "css-loader",
query: {
localIdentName: "[hash:8]",
modules: true
}
}, {
loader: "postcss-loader"
}, {
loader: "sass-loader"
}
]
}),
},
],
},
plugins: [
new ExtractTextPlugin({
filename: "[name].css",
allChunks: true
}),
]
};

webpack.config.server.js

const ExternalsPlugin = require("webpack-externals-plugin");

module.exports = {
...
output: {
path: `${__dirname}/dist/`,
filename: "server.bundle.js",
},
...
resolve: {
...
modules: [
"client",
],
},
module: {
loaders: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: "babel-loader",
}, {
test: /\.scss$/,
loader: 'style-loader!css-loader/locals?module&localIdentName=[name]__[local]___[hash:base64:5]!sass-loader',
},
],
},
plugins: [
new ExternalsPlugin({
type: "commonjs",
include: `${__dirname}/node_modules/`,
}),
],
};

我有一个 JSX 文件,其中 .header应该应用于:

import React from "react";

import Links from "./Links.jsx";
import profilePic from "../../img/brand/profilePic.jpg";

import styles from "../../styles/Main.scss";

export default class Header extends React.Component {
constructor() {
super();
}

render() {
return (
<header className={styles.header}>
<img src={profilePic} alt="Professional Picture"/>
<h5>{this.props.pageName}</h5>
<Links/>
</header>
);
}
}

这会引发错误:

TypeError: Cannot read property 'header' of undefined
at Header.render (E:/Documents/Projects/website/client/js/components/Header.jsx:22:30)
at resolve (E:\Documents\Projects\website\node_modules\react-dom\cjs\react-dom-server.node.development.js:2149:18)
at ReactDOMServerRenderer.render (E:\Documents\Projects\website\node_modules\react-dom\cjs\react-dom-server.node.development.js:2260:22)
at ReactDOMServerRenderer.read (E:\Documents\Projects\website\node_modules\react-dom\cjs\react-dom-server.node.development.js:2234:19)
at Object.renderToString (E:\Documents\Projects\website\node_modules\react-dom\cjs\react-dom-server.node.development.js:2501:25)
at E:/Documents/Projects/website/server/config/lib/express.js:204:31
at Layer.handle [as handle_request] (E:\Documents\Projects\website\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (E:\Documents\Projects\website\node_modules\express\lib\router\index.js:317:13)
at E:\Documents\Projects\website\node_modules\express\lib\router\index.js:284:7
at Function.process_params (E:\Documents\Projects\website\node_modules\express\lib\router\index.js:335:12)
at next (E:\Documents\Projects\website\node_modules\express\lib\router\index.js:275:10)
at p3p (E:\Documents\Projects\website\node_modules\lusca\lib\p3p.js:15:9)
at E:\Documents\Projects\website\node_modules\lusca\index.js:59:28
at xframe (E:\Documents\Projects\website\node_modules\lusca\lib\xframes.js:12:9)
at E:\Documents\Projects\website\node_modules\lusca\index.js:59:28
at xssProtection (E:\Documents\Projects\website\node_modules\lusca\lib\xssprotection.js:16:9)

运行应用程序时,webpack 报告样式表已加载:

enter image description here

编辑

除了 ES6 导入,我还尝试使用 CommonJS 的 require()MERN但还是没看...

当我构建我的服务器 webpack 配置时,我现在收到错误:

ERROR in (webpack)-dev-middleware/node_modules/mime/index.js
Module not found: Error: Can't resolve './types/standard' in 'E:\Documents\Projects\website\node_modules\webpack-dev middleware\node_modules\mime'
@ (webpack)-dev-middleware/node_modules/mime/index.js 4:26-53
@ (webpack)-dev-middleware/index.js
@ ./server/config/lib/express.js
@ ./server/config/lib/app.js
@ ./server/server.js

我不确定在这种情况下这是否是在转移注意力,但我认为在这里值得一提,因为我很迷茫。感觉此时我好像在抓救命稻草。

这是我的 .babelrc :

{
"presets": [
"react",
"es2015",
"stage-0"
],
"plugins": [
"react-hot-loader/babel",
"transform-decorators-legacy"
],
"env": {
"server": {
"plugins": [
[
"css-modules-transform", {
"preprocessCss": "./loaders/sass-loader.js",
"generateScopedName": "[hash:8]",
"extensions": [".scss"]
}
]
]
},
"production": {
"presets": [
"es2015",
"react",
"react-optimize",
"es2015-native-modules",
"stage-0"
]
}
}
}

我试图回到基础并让我的 babel 处理服务器端捆绑而不是 webpack。这是从 tutorial 构建的对于带有 CSS 模块的 SSR,@mootrichard 友情链接到我

编辑 2

在对样式表使用 es6 导入时,一些可能有帮助的观察:

import styles from "../../styles/Main.scss";

并记录styles进入控制台,它返回undefined (证据表明它由于某种原因找不到文件)

当把 <link> head 中的标签对于初始页面,<link>标记出现在标记中但出现在网络中:

enter image description here

enter image description here

但是,当导航到 localhost:8000/app.css 时, 对样式的肯定响应被发回:

enter image description here

如果浏览器可以独立找到捆绑版本,那么为什么它没有加载到我的初始页面中? (路径正确)

最佳答案

您遇到问题是因为您使用的是 css-loader/locals但不使用 ExtractTextPlugin (至少在开发中)。 https://github.com/webpack-contrib/css-loader/issues/59

Note: For prerendering with extract-text-webpack-plugin you should use css-loader/locals instead of style-loader!css-loader in the prerendering bundle. It doesn't embed CSS but only exports the identifier mappings.

这也解释了为什么您无法访问样式变量 .theHeader .

此外,错误 Resource interpreted as Stylesheet but transferred with MIME type text/html: "http://localhost:3000/app.css".是一条红鲱鱼。如果您尝试加载一个甚至不存在的样式表,那只是您收到的错误消息。在这种情况下,它似乎不在您认为的目录中,或者实际上没有生成到那里的文件中。

ExtractTextPlugin在开发中被禁用,很可能您的 CSS 仅由 css-loader/locals 处理.这在生产中可能不是问题,因为它与 ExtractTextPlugin 配对但可以解释您在开发中运行它的问题。


更新:

在进一步研究这个问题时,我发现了一篇博客文章,我认为它可能会帮助您弄清楚如何配置 CSS 以按您想要的方式工作。 https://medium.com/@mattvagni/server-side-rendering-with-css-modules-6b02f1238eb1

我认为这里复杂化的主要原因是您通过 ReactDOMServer 将 HTML 作为呈现的字符串发送。所以 webpack 没有地方可以注入(inject) <link>标记成。你可能想考虑只拥有一个 <link> header 中的标记以引用所需的 CSS 文件,因为 webpack 无论如何都会创建一个 CSS 文件。

最后,我强烈建议多学习 webpack,特别是因为 SSR 是一个较新的过程,需要做的事情与许多人最初创建 webpack 时最初预期的有所不同。

关于javascript - 没有样式表的加载/服务 - react ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48817285/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com