美文网首页
umijs使用服务器端渲染ssr

umijs使用服务器端渲染ssr

作者: 第2世界 | 来源:发表于2020-02-06 22:49 被阅读0次

server.js demo 文章已更新,请看下面更新之后的内容
使用官网上教程中的代码有点问题,自己参照实例改了下,修改了个express的ssr server。如果使用的话注意把其中dist改成你build之后的目录名。

require('regenerator-runtime/runtime');
const server = require('umi-server');
const express = require('express');
const compression = require('compression');
const helmet = require('helmet');
const { join, extname } = require('path');
const { createReadStream } = require('fs');

const isDev = process.env.NODE_ENV === 'development';

const root = join(__dirname, 'dist');
const render = server({
  root,
  polyfill: false,
  dev: isDev,
});

const app = express();
app.use(compression());
app.use(helmet());
// app.use('.', express.static(root));

app.get('*', async (req, res, next) => {
  const headerMap = {
    '.js': 'text/javascript',
    '.css': 'text/css',
    '.jpg': 'image/jpeg',
    '.png': 'image/jpeg',
  }
  const ext = extname(req.url);
  const header = {
    'Content-Type': headerMap[ext] || 'text/html'
  }
  if (!ext) {
    const { ssrHtml } = await render({
      req: {
        url: req.originalUrl,
      },
    });
    res.status(200).send(ssrHtml);
  } else {
    // static file url
    const path = join(root, req.url);
    res.sendFile(path);
  }
});

if (!process.env.NOW_ZEIT_ENV) {
  app.listen(8080);
  console.log('http://localhost:8080');
}

module.exports = app;

需要安装包的package.json,里面乱七八糟,我也是新手,不敢随便删减...

{
  "private": true,
  "scripts": {
    "build": "umi build",
    "server": "npm run build && nodemon server.js",
    "start": "cross-env NODE_ENV=development concurrently \"umi dev\" \"nodemon server.js\"",
    "debug": "cross-env RM_TMPDIR=none COMPRESS=none UMI_ENV=prod umi build && node server.js"
  },
  "dependencies": {
    "antd": "^3.19.5",
    "axios": "^0.19.2",
    "compression": "^1.7.4",
    "cross-env": "^5.2.0",
    "dva": "^2.6.0-beta.6",
    "express": "^4.17.1",
    "helmet": "^3.21.2",
    "lodash": "^4.17.15",
    "prettier": "^1.19.1",
    "prop-types": "^15.7.2",
    "react": "^16.8.6",
    "react-axios": "^2.0.3",
    "react-document-title": "^2.0.3",
    "react-dom": "^16.8.6",
    "regenerator-runtime": "^0.13.2",
    "roadhog-api-doc": "^1.1.2",
    "umi-request": "^1.2.4",
    "umi-server": "^1.0.0"
  },
  "devDependencies": {
    "@types/jest": "^23.3.12",
    "@types/react": "^16.7.18",
    "@types/react-dom": "^16.0.11",
    "@types/react-test-renderer": "^16.0.3",
    "babel-eslint": "^9.0.0",
    "eslint": "^5.4.0",
    "eslint-config-umi": "^1.4.0",
    "eslint-plugin-flowtype": "^2.50.0",
    "eslint-plugin-import": "^2.14.0",
    "eslint-plugin-jsx-a11y": "^5.1.1",
    "eslint-plugin-react": "^7.11.1",
    "husky": "^0.14.3",
    "lint-staged": "^7.2.2",
    "react-test-renderer": "^16.7.0",
    "umi": "^2.9.0",
    "umi-plugin-react": "^1.8.0",
    "umi-types": "^0.3.0"
  },
  "lint-staged": {
    "*.{ts,tsx}": [
      "eslint --fix",
      "git add"
    ],
    "*.{js,jsx}": [
      "eslint --fix",
      "git add"
    ]
  },
  "engines": {
    "node": ">=8.0.0"
  }
}

最后执行

node server.js

====================================

更新

上面的做法确实可以执行,但是存在一个很大的问题,就是生成的umi-server.js仍然依赖开发时用的各种包,经过再次查看官方文档,找到了原因。

https://umijs.org/zh/config/#ssr

ssr beta 2.8.0+
类型: Boolean | Object
默认值: false
用于服务端渲染(Server-Side Render)。
开启后,生成客户端静态文件的同时,也会生成 umi.server.js 和 ssr-client-mainifest.json 文件。
export default {
ssr: {
// https://github.com/liady/webpack-node-externals#optionswhitelist-
externalWhitelist?: [];
// webpack-node-externals 配置,排除 whiteList
nodeExternalsOpts?: {};
// 客户端资源 manifest 文件名,默认是 ssr-client-mainifest.json
manifestFileName: 'ssr-client-mainifest.json',
// 关闭 ssr external,全量打入 umi.server.js
disableExternal: false,
// 关闭 ssr external 时,白名单模块将进入 externa
// 可用于 react-helmet, react-document-title
disableExternalWhiteList?: string[] | object;
},
};

我之前直接将ssr配置为true,可以生成ssr的文件,但是默认的配置disableExternal: false,它并不会把依赖的js全部打包进去,查看之前build之后的umi-server.js里面仍然有各种require。

看完这个配置之后,我将.umirc.ts文件中的配置改为:

import { IConfig } from 'umi-types'; // ref: https://umijs.org/config/

const config: IConfig = {
  ssr: {
    disableExternal: true,
  },
  treeShaking: true,
  targets: {
    ie: 11,
  },
  ....//此处省略了,自己配置routes,plugins
};
export default config;

然后重新打包 umi build生成的umi.server.js就不需要依赖其他的包了。

回过头来再看https://umijs.org/zh/guide/ssr.html#%E6%9C%8D%E5%8A%A1%E7%AB%AF

const server = require('umi-server');
const http = require('http');
const { createReadStream } = require('fs');
const { join, extname } = require('path');

const root = join(__dirname, 'dist');
const render = server({
  root,
})
const headerMap = {
  '.js': 'text/javascript',
  '.css': 'text/css',
  '.jpg': 'image/jpeg',
  '.png': 'image/jpeg',
}

http.createServer(async (req, res) => {
  const ext = extname(req.url);
  const header = {
    'Content-Type': headerMap[ext] || 'text/html'
  }
  res.writeHead(200, header);

  if (!ext) {
    // url render
    const ctx = {
      req,
      res,
    }
    const { ssrHtml } = await render(ctx);
    res.write(ssrHtml);
    res.end()
  } else {
    // static file url
    const path = join(root, req.url);
    const stream = createReadStream(path);
    stream.on('error', (error) => {
      res.writeHead(404, 'Not Found');
      res.end();
    });
    stream.pipe(res);
  }

}).listen(3000)

console.log('http://localhost:3000');

可以运行了,不会报错。只需要package.json里面有umi-server,然后npm install:

  "dependencies": {
    "umi-server": "^1.0.0"
  },

搞定,好开心,官方的文档真坑,一个disableExternal: false,ssr:true把我坑惨了。

相关文章

  • umijs使用服务器端渲染ssr

    server.js demo 文章已更新,请看下面更新之后的内容使用官网上教程中的代码有点问题,自己参照实例改了下...

  • SSR服务端渲染

    什么是SSR?,SSR有什么用? 服务端渲染(Server Side Render,简称“SSR”),服务器端直接...

  • 关于 SAP 电商云 Spartacus UI Transfer

    Angular 的 TransferState 类使服务器端渲染 (SSR) 和预渲染 (Prerendered-...

  • 服务端渲染

    服务器端渲染(SSR) 学前准备 ES6 Node Vue 什么是服务器端渲染 前端渲染:html页面作为静态文件...

  • 服务器端渲染SSR

    为什么使用服务器端渲染 (SSR)?与传统 SPA (单页应用程序 (Single-Page Applicatio...

  • SSR实践

    为什么使用服务器端渲染 (SSR)?与传统 SPA (单页应用程序 (Single-Page Applicatio...

  • vue 的ssr的轮播图vue-awesome-swiper

    官网使用nuxt将vue服务器端渲染ssr成静态页面,利于seo搜索,使用 starter 模板创建,项目开发完成...

  • 基于vue-cli3的vue-ssr(一)

    为什么使用服务器端渲染 (SSR)? 1.更好的 SEO,由于搜索引擎爬虫抓取工具可以直接查看完全渲染的页面。2....

  • 前端面试题(三)

    1. 服务器端渲染(ssr:service side render) 优点: 解决白屏问题,提高首屏渲染速度 可...

  • 从零搭建个人博客(5)-SSR渲染

    为什么要使用服务器端渲染(SSR) 更好的 SEO,由于搜索引擎爬虫抓取工具可以直接查看完全渲染的页面 解决首屏白...

网友评论

      本文标题:umijs使用服务器端渲染ssr

      本文链接:https://www.haomeiwen.com/subject/lfjpxhtx.html