草庐IT

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

coder 2024-07-20 原文

我正在尝试使用 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 报告样式表已加载:

编辑

除了 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>标记出现在标记中但出现在网络中:

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

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

最佳答案

您遇到问题是因为您使用的是 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/

有关javascript - 没有样式表的加载/服务 - react的更多相关文章

  1. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  2. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  3. ruby - 难道Lua没有和Ruby的method_missing相媲美的东西吗? - 2

    我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/

  4. ruby - 如何使用文字标量样式在 YAML 中转储字符串? - 2

    我有一大串格式化数据(例如JSON),我想使用Psychinruby​​同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解

  5. ruby-on-rails - rails 目前在重启后没有安装 - 2

    我有一个奇怪的问题:我在rvm上安装了ruby​​onrails。一切正常,我可以创建项目。但是在我输入“railsnew”时重新启动后,我有“程序'rails'当前未安装。”。SystemUbuntu12.04ruby-v"1.9.3p194"gemlistactionmailer(3.2.5)actionpack(3.2.5)activemodel(3.2.5)activerecord(3.2.5)activeresource(3.2.5)activesupport(3.2.5)arel(3.0.2)builder(3.0.0)bundler(1.1.4)coffee-rails(

  6. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  7. ruby - 如何在 Ruby 中拆分参数字符串 Bash 样式? - 2

    我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"

  8. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  9. ruby-on-rails - 启动 Rails 服务器时 ImageMagick 的警告 - 2

    最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru

  10. ruby-on-rails - s3_direct_upload 在生产服务器中不工作 - 2

    在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo

随机推荐