简体   繁体   English

如何在服务器端渲染图像?

[英]How to render images with react on server side?

How can I render images and css files on server side with React?如何使用 React 在服务器端渲染图像和 css 文件?

Here is my server code:这是我的服务器代码:

const express = require('express')
const router = express.Router()
const ReactDOM = require('react-dom/server');

import Master from '../../../client/Master'

router.get('/', (req, res) => {
    res.render('test.html', {reactOutput: ReactDOM.renderToString(<Master/>)});
});

Master component:主组件:

import React from "react";
import Intro from "./pages/Intro";
import Footer from "./components/Footer";
import Header from "./components/Header";

export default class Master extends React.Component {
    constructor() {
        super();
        this.state = {appStatus: 'INTRO'}
    }

    render() {
        let layout;
        switch (this.state.appStatus) {
            case "INTRO":
                layout = <Intro/>;
        }

        return (
            <div>
                <Header/>
                {layout}
                <Footer/>
            </div>
        )
    }
}

But when I run server with babel I got this error:但是当我用 babel 运行服务器时,我得到了这个错误:

/assets/img/logo.png: Unexpected character '?' /assets/img/logo.png:意外字符“?” (1:0) (1:0)

And this is the Header component which tries to require logo.这是试图要求徽标的 Header 组件。

import React from "react";
**import logo  from '../../assets/img/logo.png';**

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

    render() {
        return (
            <nav class="navbar navbar-default">
                <div class="container-fluid">
                    <div class="navbar-header">
                        <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                            <span class="sr-only">Toggle navigation</span>
                            <span class="icon-bar"></span>
                            <span class="icon-bar"></span>
                            <span class="icon-bar"></span>
                        </button>
                        <a class="navbar-brand" href="#">**<img width="250" src={logo} alt=""/></a>**
                    </div>


                </div>
            </nav>
        );
    }
}

But it works fine with webpack for client side..但对于客户端,它可以与 webpack 一起正常工作。

You need a separate webpack config for your server 您需要为服务器使用单独的webpack配置

  1. Install this module to exclude node_modules: 安装此模块以排除node_modules:

     npm install --save webpack-node-externals 
  2. Create a separate webpack config for your server: 为您的服务器创建一个单独的webpack配置:

     module.exports = { const path = require('path') const nodeExternals = require('webpack-node-externals') context: path.resolve(__dirname, 'directory of your server file'), entry: ['./filename of your server file'], output: { path: path.join(__dirname, 'directory of your bundled file'), filename: 'filename of your bundled file' }, target: 'node', externals: [nodeExternals()], module: { rules: [ { test: /\\.(jpe?g|png|gif|svg|ico)$/i, use: 'url-loader?limit=8192' } ] } } 
  3. Here's an example server webpack.config.js: 这是一个示例服务器webpack.config.js:

     module.exports = { const path = require('path') const nodeExternals = require('webpack-node-externals') context: path.resolve(__dirname, 'src'), entry: ['./index.js'], output: { path: path.join(__dirname, 'dist'), filename: 'bundle.js' }, target: 'node', externals: [nodeExternals()], module: { rules: [ { test: /\\.(jpe?g|png|gif|svg|ico)$/i, use: 'url-loader?limit=8192' } ] } } 
  4. If using the above webpack.config.js example, run webpack then the compiled server file: 如果使用上面的webpack.config.js示例,请运行webpack然后运行编译的服务器文件:

     webpack node dist/bundle.js 

The above answer is either old or has a couple issues.上面的答案要么是旧的,要么有几个问题。 Here is a updated answer for webpack 5. This imports fonts and images from their respective folders. 是 webpack 5 的更新答案。这会从各自的文件夹中导入 fonts 和图像。

const path = require("path");

module.exports = {
  target: "node",
  entry: {
    server: "./server.js"
  },
  output: {
    path: path.join(__dirname),
    filename: "[name]-packed.js",
  },
  module: {
    rules: [
      {
        test: /\.(jpe?g|png|gif|svg|ico)$/i,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: '[name].[ext]',
              outputPath: 'img/'
            }
          }
        ]
      },
      {
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                loader: "babel-loader"
            },
      {
        test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: '[name].[ext]',
              outputPath: 'fonts/'
            }
          }
        ]
      }
    ],
  },
};

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM