Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

umi3.x ssr 疑问 #4808

Closed
SilentFlute opened this issue Jun 1, 2020 · 33 comments
Closed

umi3.x ssr 疑问 #4808

SilentFlute opened this issue Jun 1, 2020 · 33 comments
Assignees
Labels
type(ssr) UmiJS SSR

Comments

@SilentFlute
Copy link

  • 之前用过nextjs做ssr, 现在打算看看umi3, 使用umi3之后希望能更好的和阿里的生态有个紧密的结合, 以期有新的好的方案, 如果我司需要能更好更方便的集成

What happens?

  1. tdk问题
    title description keywords
    开发环境, title的内容, 页面显示的和源码中的不一样, 但是keywords description是一样的, build之后是正常的
    开发环境:
    image
    image
    build之后:
    image
    image
    不是太明白是什么问题, build之后查看源码是对的倒没什么问题, 但始终感觉有点问题

  2. 部署相关问题
    copy的文档中的express的代码, 打包之后, 本地起一个服务模拟部署到线上/测试环境的情形, 但遇到这么几个问题, 希望大佬们能抽空帮忙看看:

  • express返回的都是text/html, css js也是, 导致样式渲染出问题, res.setHeader('Content-Type', 'text/html'); 这句删掉也是一样的, 是需要判断请求的文件然后设置不同的Content-Type吗?具体是如何操作呢?req和res打印出来一堆, 找起来好蛋疼, 而源码又看不懂找不到....
  • link路由切换会发生真实的请求
  • 页面报错Uncaught SyntaxError: Unexpected token '<', 翻issue, 里面有说到publicPath的问题, 设置了依旧报错
  • targets: {
    ie: 9
    }, 但是打包产物dist/umi.js中依旧有箭头函数

之前用nextjs的话部署是用它自己自带的next start, 然后启动了ssr的服务之后部署, 然后nginx反代到这个ssr服务即可

Mini Showcase Repository(REQUIRED)

Provide a mini GitHub repository which can reproduce the issue. Use yarn create @umijs/umi-app then upload to your GitHub

https://github.com/SilentFlute/umi3.x-ssr.git

How To Reproduce

yarn -> 安装依赖
yarn start -> 本地开发模式
yarn build -> 打包
node server.js -> 本地启动node服务模拟部署

Context

  • Umi Version: 3.2.3
  • Node Version: 12.16.3
  • Platform:win 10

求帮助, 感谢

@petitspois
Copy link

用的是egg,遇到相同问题。部署的时候js,css 的content-type都为text/html

  async index() {
    const { ctx } = this;
    global.host = `${ctx.request.protocol}://${ctx.request.host}`;
    global.href = ctx.request.href;
    const render = require('../public/umi.server');
    ctx.set('Content-Type', 'text/html')
    if(/.css/.test(ctx.request.url)){
        ctx.set('Content-Type', 'text/css')
    }
    if(/.js/.test(ctx.request.url)){
        ctx.set('Content-Type', 'application/javascript')
    }
    const { err, html } = await render({
      path: ctx.request.url,
    });
    if (err) {
      ctx.body = '404 Not Found';
      return;
    }
    ctx.body = html;
  }

不起作用,最后都访问html文件资源了。。。

@SilentFlute
Copy link
Author

用的是egg,遇到相同问题。部署的时候js,css 的content-type都为text/html

  async index() {
    const { ctx } = this;
    global.host = `${ctx.request.protocol}://${ctx.request.host}`;
    global.href = ctx.request.href;
    const render = require('../public/umi.server');
    ctx.set('Content-Type', 'text/html')
    if(/.css/.test(ctx.request.url)){
        ctx.set('Content-Type', 'text/css')
    }
    if(/.js/.test(ctx.request.url)){
        ctx.set('Content-Type', 'application/javascript')
    }
    const { err, html } = await render({
      path: ctx.request.url,
    });
    if (err) {
      ctx.body = '404 Not Found';
      return;
    }
    ctx.body = html;
  }

不起作用,最后都访问html文件资源了。。。

我参考你的设置响应头的代码改了下, 发现content-type设置上去了, 但是返回的结果依旧是html....
以及你有报错吗, 这个错是只要build了之后就有:
image
image

@petitspois
Copy link

@ycjcl868

@ycjcl868 ycjcl868 added the type(ssr) UmiJS SSR label Jun 2, 2020
@petitspois
Copy link

@ycjcl868 部署的时候js,css 的content-type都为text/html, 这是什么问题呢?如何解决呢,准备上线,部署不了。。。

@petitspois
Copy link

@SilentFlute 解决了吗,我改manifest下的路径没作用,public index.html 也不起作用,哎。

@williamnie
Copy link
Contributor

@SilentFlute 解决了吗,我改manifest下的路径没作用,public index.html 也不起作用,哎。

你是遇到什么问题了?我用egg是没问题的,build好是可以启动,访问的,能描述下你遇到的问题么?

@petitspois
Copy link

@williamnie build得后运行start, 静态文件都访问不到, 能加个微信不?

@petitspois
Copy link

目前的配置:

public 下

 app/public/umi.server.js         2.2 MB               708.0 KB
 app/public/umi.55fcf70d.js       1.4 MB               418.5 KB
 app/public/umi.327b84b5.css      111.0 KB             20.8 KB

manifest.json

{
  "umi.css": "/umi.327b84b5.css",
  "umi.js": "/umi.55fcf70d.js",
  "index.html": "/index.html",
  "static/photoswipe.css": "/static/default-skin.f64c3af3.svg"
}

config.default.js

config.assets = {
        publicPath: '/app/public/',
        devServer: {
            debug: true,
            command: 'umi dev',
            port: 8000,
            env: {
                APP_ROOT: process.cwd() + '/app/web',
                BROWSER: 'none',
                ESLINT: 'none',
                SOCKET_SERVER: 'http://172.16.96.21:8000',
                PUBLIC_PATH: 'http://172.16.96.21:8000',
            },
        },
    };

public-index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
    />
    <link rel="stylesheet" href="/umi.327b84b5.css" />
    <script>
      window.routerBase = "/";
    </script>
    <script>
      window.publicPath = "/";
    </script>
    <script>
      //! umi version: 3.2.0-beta.12
    </script>
    <script src="//res.wx.qq.com/open/js/jweixin-1.3.2.js"></script>
    <script src="//as.alipayobjects.com/g/component/fastclick/1.0.6/fastclick.js"></script>
    <script>
      if ("addEventListener" in document) {
        document.addEventListener(
          "DOMContentLoaded",
          function () {
            FastClick.attach(document.body);
          },
          false
        );
      }
      if (!window.Promise) {
        document.writeln(
          '<script src="//as.alipayobjects.com/g/component/es6-promise/3.2.2/es6-promise.min.js"' +
            ">" +
            "<" +
            "/" +
            "script>"
        );
      }
    </script>
    <title>&#x81EA;&#x67E5;</title>
  </head>
  <body>
    <div id="root"></div>

    <script src="/umi.55fcf70d.js"></script>
  </body>
</html>

尝试换了几次路径无果

@SilentFlute
Copy link
Author

@SilentFlute 解决了吗,我改manifest下的路径没作用,public index.html 也不起作用,哎。

没有解决....换nextjs了
话说你和那个哥们聊的怎么样了, 解决这个问题了吗?如果搞定了, 希望你能把解决方法给我以及后来者分享一下哈, 感谢感谢

@petitspois
Copy link

解决了,是umi的bug,你把hash去掉就好了。

@CassielLee
Copy link

请问下部署的具体步骤是什么呢?我copy的官方的代码,但是访问不到页面,难受……

@williamnie
Copy link
Contributor

请问下部署的具体步骤是什么呢?我copy的官方的代码,但是访问不到页面,难受……

贴下你的配置,和部署步骤,我看下能不能帮忙解决,目前umi存在一些问题:

  1. 如果开启hash,umi.server.js内部的html中不会加hash,可以先关闭hash

@CassielLee
Copy link

请问下部署的具体步骤是什么呢?我copy的官方的代码,但是访问不到页面,难受……

贴下你的配置,和部署步骤,我看下能不能帮忙解决,目前umi存在一些问题:

  1. 如果开启hash,umi.server.js内部的html中不会加hash,可以先关闭hash

您好,我现在的页面出来了,但是样式、图片什么的都没有,我发现是对于所有的文件请求响应头的Content-type都是text/html,然后我自己写了一个简单的判断,设置不同文件用不同的响应头,但是也不起作用,图片、样式文件的加载状态码都是200,但是内容不对,我的umi配置如下:

image

我的部署是按照官方文档说的,用一个Node服务,引用打包之后生成的umi.server.js文件,如下图:

image

请帮我看一下,感谢您!

@CassielLee
Copy link

请问下部署的具体步骤是什么呢?我copy的官方的代码,但是访问不到页面,难受……

贴下你的配置,和部署步骤,我看下能不能帮忙解决,目前umi存在一些问题:

  1. 如果开启hash,umi.server.js内部的html中不会加hash,可以先关闭hash

我的配置是:umi:3.2.3,node: 11.14.0,系统是:win10,刚刚忘记说了,不好意思!

@SilentFlute
Copy link
Author

解决了,是umi的bug,你把hash去掉就好了。

你说的是.umirc.js中的hash配置吗?这就尴尬了, 我没有使用hash....

@CassielLee
Copy link

解决了,是umi的bug,你把hash去掉就好了。

你说的是.umirc.js中的hash配置吗?这就尴尬了, 我没有使用hash....

大哥,你解决了吗?我也没有用hash,我们也是想从nextjs换过来……

@williamnie
Copy link
Contributor

请问下部署的具体步骤是什么呢?我copy的官方的代码,但是访问不到页面,难受……

贴下你的配置,和部署步骤,我看下能不能帮忙解决,目前umi存在一些问题:

  1. 如果开启hash,umi.server.js内部的html中不会加hash,可以先关闭hash

我的配置是:umi:3.2.3,node: 11.14.0,系统是:win10,刚刚忘记说了,不好意思!

你的publicPath配置是什么?打包输出到哪里了?是否能通过连接直接访问到umi.js和umi.css?

@williamnie
Copy link
Contributor

解决了,是umi的bug,你把hash去掉就好了。

你说的是.umirc.js中的hash配置吗?这就尴尬了, 我没有使用hash....

你是用的egg还是express?遇到的和@CassielLee是同样的问题么?

@CassielLee
Copy link

请问下部署的具体步骤是什么呢?我copy的官方的代码,但是访问不到页面,难受……

贴下你的配置,和部署步骤,我看下能不能帮忙解决,目前umi存在一些问题:

  1. 如果开启hash,umi.server.js内部的html中不会加hash,可以先关闭hash

我的配置是:umi:3.2.3,node: 11.14.0,系统是:win10,刚刚忘记说了,不好意思!

你的publicPath配置是什么?打包输出到哪里了?是否能通过连接直接访问到umi.js和umi.css?

publicPath我没有配置,就是默认的配置,打包文件都输出到dist文件夹下了,我和楼主的问题一样的

@williamnie
Copy link
Contributor

请问下部署的具体步骤是什么呢?我copy的官方的代码,但是访问不到页面,难受……

贴下你的配置,和部署步骤,我看下能不能帮忙解决,目前umi存在一些问题:

  1. 如果开启hash,umi.server.js内部的html中不会加hash,可以先关闭hash

我的配置是:umi:3.2.3,node: 11.14.0,系统是:win10,刚刚忘记说了,不好意思!

你的publicPath配置是什么?打包输出到哪里了?是否能通过连接直接访问到umi.js和umi.css?

publicPath我没有配置,就是默认的配置,打包文件都输出到dist文件夹下了,我和楼主的问题一样的

稍微改了一下你贴出来的git的复现地址,已经能出来了,我贴下代码,主要是服务端的代码写的不对,
问题出在express的服务端没做路由判断,也没设置静态目录,导致无法在127.0.0.1:3000/umi.js链接下找到umi.js文件,我的代码不建议直接用在生产环境,生产环境解决方案是用nginx配置静态目录,能让127.0.0.1:3000/umi.js访问到。下面贴出改的express代码

const express = require('express');
const app = express();
const render = require('./dist/umi.server');
const fs = require('fs');
// 这里简单的用fs读取一下文件,后面直接 扔给前端
const umijs = fs.readFileSync('./dist/umi.js');
const umicss = fs.readFileSync('./dist/umi.css');


const port = 3000;

const domain = 'http://localhost';

// Express
app.use(async (req, res) => {
  // 或者从 CDN 上下载到 server 端
  // const serverPath = await downloadServerBundle('http://cdn.com/bar/umi.server.js');
  /*
      这里做了路由判断,更好的方案是用nginx配置静态目录(指向build好的目录,如dist)
      或者通过express设置静态目录,umi加入publicPath配置
*/
  if (req && req.url === '/umi.css') {
    res.setHeader('Content-Type', 'text/css');
    res.send(umicss);
  } else if (req && req.url === '/umi.js') {
    res.setHeader('Content-Type', 'text/js');
    res.send(umijs);
  } else {
    res.setHeader('Content-Type', 'text/html');
    const context = {};
    const { html, error, rootContainer } = await render({
      // 有需要可带上 query
      path: req.url,
      context
    });

    res.send(html);
  }


});

app.listen(port, err => {
  if (err) {
    throw err;
  }
  console.log(`> Ready on port ${port}, ${domain}:${port}`);
});

@williamnie
Copy link
Contributor

解决了,是umi的bug,你把hash去掉就好了。

你说的是.umirc.js中的hash配置吗?这就尴尬了, 我没有使用hash....

看下我上面的回复,我在你的git复现仓库上改的,已经没问题了,主要是server.js的问题

@CassielLee
Copy link

CassielLee commented Jun 11, 2020

请问下部署的具体步骤是什么呢?我copy的官方的代码,但是访问不到页面,难受……

贴下你的配置,和部署步骤,我看下能不能帮忙解决,目前umi存在一些问题:

  1. 如果开启hash,umi.server.js内部的html中不会加hash,可以先关闭hash

我的配置是:umi:3.2.3,node: 11.14.0,系统是:win10,刚刚忘记说了,不好意思!

你的publicPath配置是什么?打包输出到哪里了?是否能通过连接直接访问到umi.js和umi.css?

publicPath我没有配置,就是默认的配置,打包文件都输出到dist文件夹下了,我和楼主的问题一样的

稍微改了一下你贴出来的git的复现地址,已经能出来了,我贴下代码,主要是服务端的代码写的不对,
问题出在express的服务端没做路由判断,也没设置静态目录,导致无法在127.0.0.1:3000/umi.js链接下找到umi.js文件,我的代码不建议直接用在生产环境,生产环境解决方案是用nginx配置静态目录,能让127.0.0.1:3000/umi.js访问到。下面贴出改的express代码

const express = require('express');
const app = express();
const render = require('./dist/umi.server');
const fs = require('fs');
// 这里简单的用fs读取一下文件,后面直接 扔给前端
const umijs = fs.readFileSync('./dist/umi.js');
const umicss = fs.readFileSync('./dist/umi.css');


const port = 3000;

const domain = 'http://localhost';

// Express
app.use(async (req, res) => {
  // 或者从 CDN 上下载到 server 端
  // const serverPath = await downloadServerBundle('http://cdn.com/bar/umi.server.js');
  /*
      这里做了路由判断,更好的方案是用nginx配置静态目录(指向build好的目录,如dist)
      或者通过express设置静态目录,umi加入publicPath配置
*/
  if (req && req.url === '/umi.css') {
    res.setHeader('Content-Type', 'text/css');
    res.send(umicss);
  } else if (req && req.url === '/umi.js') {
    res.setHeader('Content-Type', 'text/js');
    res.send(umijs);
  } else {
    res.setHeader('Content-Type', 'text/html');
    const context = {};
    const { html, error, rootContainer } = await render({
      // 有需要可带上 query
      path: req.url,
      context
    });

    res.send(html);
  }


});

app.listen(port, err => {
  if (err) {
    throw err;
  }
  console.log(`> Ready on port ${port}, ${domain}:${port}`);
});

感谢大佬指点,现在页面出来了,我试了一下nginx也可以,但是使用nginx的话那是CSR?使用express配置静态目录这个方法我还没有试,这块我不太了解,
另外还有2个小问题:1、图片显示问题,我在您之前路由判断的基础上又加了图片的判断,可以显示了,但是之后那些不同类型的文件是都要加一个这样的判断吗?
2、我使用geiInitialProps方法返回的数据取不到,是undefined,我的代码也是按照官方文档来的,如下图所示:
image
如果您有时间的还希望您能继续帮忙看一下~十分感谢!

@williamnie
Copy link
Contributor

请问下部署的具体步骤是什么呢?我copy的官方的代码,但是访问不到页面,难受……

贴下你的配置,和部署步骤,我看下能不能帮忙解决,目前umi存在一些问题:

  1. 如果开启hash,umi.server.js内部的html中不会加hash,可以先关闭hash

我的配置是:umi:3.2.3,node: 11.14.0,系统是:win10,刚刚忘记说了,不好意思!

你的publicPath配置是什么?打包输出到哪里了?是否能通过连接直接访问到umi.js和umi.css?

publicPath我没有配置,就是默认的配置,打包文件都输出到dist文件夹下了,我和楼主的问题一样的

稍微改了一下你贴出来的git的复现地址,已经能出来了,我贴下代码,主要是服务端的代码写的不对,
问题出在express的服务端没做路由判断,也没设置静态目录,导致无法在127.0.0.1:3000/umi.js链接下找到umi.js文件,我的代码不建议直接用在生产环境,生产环境解决方案是用nginx配置静态目录,能让127.0.0.1:3000/umi.js访问到。下面贴出改的express代码

const express = require('express');
const app = express();
const render = require('./dist/umi.server');
const fs = require('fs');
// 这里简单的用fs读取一下文件,后面直接 扔给前端
const umijs = fs.readFileSync('./dist/umi.js');
const umicss = fs.readFileSync('./dist/umi.css');


const port = 3000;

const domain = 'http://localhost';

// Express
app.use(async (req, res) => {
  // 或者从 CDN 上下载到 server 端
  // const serverPath = await downloadServerBundle('http://cdn.com/bar/umi.server.js');
  /*
      这里做了路由判断,更好的方案是用nginx配置静态目录(指向build好的目录,如dist)
      或者通过express设置静态目录,umi加入publicPath配置
*/
  if (req && req.url === '/umi.css') {
    res.setHeader('Content-Type', 'text/css');
    res.send(umicss);
  } else if (req && req.url === '/umi.js') {
    res.setHeader('Content-Type', 'text/js');
    res.send(umijs);
  } else {
    res.setHeader('Content-Type', 'text/html');
    const context = {};
    const { html, error, rootContainer } = await render({
      // 有需要可带上 query
      path: req.url,
      context
    });

    res.send(html);
  }


});

app.listen(port, err => {
  if (err) {
    throw err;
  }
  console.log(`> Ready on port ${port}, ${domain}:${port}`);
});

感谢大佬指点,现在页面出来了,我试了一下nginx也可以,但是使用nginx的话那是CSR?使用express配置静态目录这个方法我还没有试,这块我不太了解,
另外还有2个小问题:1、图片显示问题,我在您之前路由判断的基础上又加了图片的判断,可以显示了,但是之后那些不同类型的文件是都要加一个这样的判断吗?
2、我使用geiInitialProps方法返回的数据取不到,是undefined,我的代码也是按照官方文档来的,如下图所示:
image
如果您有时间的还希望您能继续帮忙看一下~十分感谢!

不是使用ngxinx就是csr,建议部署方式是,加入publicPath,比如是dist,可以配置反向代理,所有非/dist/*路由,都由nginx转发到express服务器,而dist目录则由nginx直接指向静态目录。
1.问题1用我上面的方法可以解决。
2.是否打开ssr选项?在开发模式下是否可以获取数据?检查源代码里是否能看到数据?

@CassielLee
Copy link

CassielLee commented Jun 11, 2020

请问下部署的具体步骤是什么呢?我copy的官方的代码,但是访问不到页面,难受……

贴下你的配置,和部署步骤,我看下能不能帮忙解决,目前umi存在一些问题:

  1. 如果开启hash,umi.server.js内部的html中不会加hash,可以先关闭hash

我的配置是:umi:3.2.3,node: 11.14.0,系统是:win10,刚刚忘记说了,不好意思!

你的publicPath配置是什么?打包输出到哪里了?是否能通过连接直接访问到umi.js和umi.css?

publicPath我没有配置,就是默认的配置,打包文件都输出到dist文件夹下了,我和楼主的问题一样的

稍微改了一下你贴出来的git的复现地址,已经能出来了,我贴下代码,主要是服务端的代码写的不对,
问题出在express的服务端没做路由判断,也没设置静态目录,导致无法在127.0.0.1:3000/umi.js链接下找到umi.js文件,我的代码不建议直接用在生产环境,生产环境解决方案是用nginx配置静态目录,能让127.0.0.1:3000/umi.js访问到。下面贴出改的express代码

const express = require('express');
const app = express();
const render = require('./dist/umi.server');
const fs = require('fs');
// 这里简单的用fs读取一下文件,后面直接 扔给前端
const umijs = fs.readFileSync('./dist/umi.js');
const umicss = fs.readFileSync('./dist/umi.css');


const port = 3000;

const domain = 'http://localhost';

// Express
app.use(async (req, res) => {
  // 或者从 CDN 上下载到 server 端
  // const serverPath = await downloadServerBundle('http://cdn.com/bar/umi.server.js');
  /*
      这里做了路由判断,更好的方案是用nginx配置静态目录(指向build好的目录,如dist)
      或者通过express设置静态目录,umi加入publicPath配置
*/
  if (req && req.url === '/umi.css') {
    res.setHeader('Content-Type', 'text/css');
    res.send(umicss);
  } else if (req && req.url === '/umi.js') {
    res.setHeader('Content-Type', 'text/js');
    res.send(umijs);
  } else {
    res.setHeader('Content-Type', 'text/html');
    const context = {};
    const { html, error, rootContainer } = await render({
      // 有需要可带上 query
      path: req.url,
      context
    });

    res.send(html);
  }


});

app.listen(port, err => {
  if (err) {
    throw err;
  }
  console.log(`> Ready on port ${port}, ${domain}:${port}`);
});

感谢大佬指点,现在页面出来了,我试了一下nginx也可以,但是使用nginx的话那是CSR?使用express配置静态目录这个方法我还没有试,这块我不太了解,
另外还有2个小问题:1、图片显示问题,我在您之前路由判断的基础上又加了图片的判断,可以显示了,但是之后那些不同类型的文件是都要加一个这样的判断吗?
2、我使用geiInitialProps方法返回的数据取不到,是undefined,我的代码也是按照官方文档来的,如下图所示:
image
如果您有时间的还希望您能继续帮忙看一下~十分感谢!

不是使用ngxinx就是csr,建议部署方式是,加入publicPath,比如是dist,可以配置反向代理,所有非/dist/*路由,都由nginx转发到express服务器,而dist目录则由nginx直接指向静态目录。
1.问题1用我上面的方法可以解决。
2.是否打开ssr选项?在开发模式下是否可以获取数据?检查源代码里是否能看到数据?

好的,问题1的方法我再研究一下,感谢!关于问题2,我有打开ssr选项,但是在开发模式和源代码里面都看不到数据,代码也没有报错

@williamnie
Copy link
Contributor

请问下部署的具体步骤是什么呢?我copy的官方的代码,但是访问不到页面,难受……

贴下你的配置,和部署步骤,我看下能不能帮忙解决,目前umi存在一些问题:

  1. 如果开启hash,umi.server.js内部的html中不会加hash,可以先关闭hash

我的配置是:umi:3.2.3,node: 11.14.0,系统是:win10,刚刚忘记说了,不好意思!

你的publicPath配置是什么?打包输出到哪里了?是否能通过连接直接访问到umi.js和umi.css?

publicPath我没有配置,就是默认的配置,打包文件都输出到dist文件夹下了,我和楼主的问题一样的

稍微改了一下你贴出来的git的复现地址,已经能出来了,我贴下代码,主要是服务端的代码写的不对,
问题出在express的服务端没做路由判断,也没设置静态目录,导致无法在127.0.0.1:3000/umi.js链接下找到umi.js文件,我的代码不建议直接用在生产环境,生产环境解决方案是用nginx配置静态目录,能让127.0.0.1:3000/umi.js访问到。下面贴出改的express代码

const express = require('express');
const app = express();
const render = require('./dist/umi.server');
const fs = require('fs');
// 这里简单的用fs读取一下文件,后面直接 扔给前端
const umijs = fs.readFileSync('./dist/umi.js');
const umicss = fs.readFileSync('./dist/umi.css');


const port = 3000;

const domain = 'http://localhost';

// Express
app.use(async (req, res) => {
  // 或者从 CDN 上下载到 server 端
  // const serverPath = await downloadServerBundle('http://cdn.com/bar/umi.server.js');
  /*
      这里做了路由判断,更好的方案是用nginx配置静态目录(指向build好的目录,如dist)
      或者通过express设置静态目录,umi加入publicPath配置
*/
  if (req && req.url === '/umi.css') {
    res.setHeader('Content-Type', 'text/css');
    res.send(umicss);
  } else if (req && req.url === '/umi.js') {
    res.setHeader('Content-Type', 'text/js');
    res.send(umijs);
  } else {
    res.setHeader('Content-Type', 'text/html');
    const context = {};
    const { html, error, rootContainer } = await render({
      // 有需要可带上 query
      path: req.url,
      context
    });

    res.send(html);
  }


});

app.listen(port, err => {
  if (err) {
    throw err;
  }
  console.log(`> Ready on port ${port}, ${domain}:${port}`);
});

感谢大佬指点,现在页面出来了,我试了一下nginx也可以,但是使用nginx的话那是CSR?使用express配置静态目录这个方法我还没有试,这块我不太了解,
另外还有2个小问题:1、图片显示问题,我在您之前路由判断的基础上又加了图片的判断,可以显示了,但是之后那些不同类型的文件是都要加一个这样的判断吗?
2、我使用geiInitialProps方法返回的数据取不到,是undefined,我的代码也是按照官方文档来的,如下图所示:
image
如果您有时间的还希望您能继续帮忙看一下~十分感谢!

不是使用ngxinx就是csr,建议部署方式是,加入publicPath,比如是dist,可以配置反向代理,所有非/dist/*路由,都由nginx转发到express服务器,而dist目录则由nginx直接指向静态目录。
1.问题1用我上面的方法可以解决。
2.是否打开ssr选项?在开发模式下是否可以获取数据?检查源代码里是否能看到数据?
好的,问题1的方法我再研究一下,感谢!关于问题2,我有打开ssr选项,但是在开发模式和源代码里面都看不到数据,代码也没有报错

有最小复现么?可能是部分代码有问题,导致自动降级了?得看下代码,才能确定

@CassielLee
Copy link

CassielLee commented Jun 11, 2020

请问下部署的具体步骤是什么呢?我copy的官方的代码,但是访问不到页面,难受……

贴下你的配置,和部署步骤,我看下能不能帮忙解决,目前umi存在一些问题:

  1. 如果开启hash,umi.server.js内部的html中不会加hash,可以先关闭hash

我的配置是:umi:3.2.3,node: 11.14.0,系统是:win10,刚刚忘记说了,不好意思!

你的publicPath配置是什么?打包输出到哪里了?是否能通过连接直接访问到umi.js和umi.css?

publicPath我没有配置,就是默认的配置,打包文件都输出到dist文件夹下了,我和楼主的问题一样的

稍微改了一下你贴出来的git的复现地址,已经能出来了,我贴下代码,主要是服务端的代码写的不对,
问题出在express的服务端没做路由判断,也没设置静态目录,导致无法在127.0.0.1:3000/umi.js链接下找到umi.js文件,我的代码不建议直接用在生产环境,生产环境解决方案是用nginx配置静态目录,能让127.0.0.1:3000/umi.js访问到。下面贴出改的express代码

const express = require('express');
const app = express();
const render = require('./dist/umi.server');
const fs = require('fs');
// 这里简单的用fs读取一下文件,后面直接 扔给前端
const umijs = fs.readFileSync('./dist/umi.js');
const umicss = fs.readFileSync('./dist/umi.css');


const port = 3000;

const domain = 'http://localhost';

// Express
app.use(async (req, res) => {
  // 或者从 CDN 上下载到 server 端
  // const serverPath = await downloadServerBundle('http://cdn.com/bar/umi.server.js');
  /*
      这里做了路由判断,更好的方案是用nginx配置静态目录(指向build好的目录,如dist)
      或者通过express设置静态目录,umi加入publicPath配置
*/
  if (req && req.url === '/umi.css') {
    res.setHeader('Content-Type', 'text/css');
    res.send(umicss);
  } else if (req && req.url === '/umi.js') {
    res.setHeader('Content-Type', 'text/js');
    res.send(umijs);
  } else {
    res.setHeader('Content-Type', 'text/html');
    const context = {};
    const { html, error, rootContainer } = await render({
      // 有需要可带上 query
      path: req.url,
      context
    });

    res.send(html);
  }


});

app.listen(port, err => {
  if (err) {
    throw err;
  }
  console.log(`> Ready on port ${port}, ${domain}:${port}`);
});

感谢大佬指点,现在页面出来了,我试了一下nginx也可以,但是使用nginx的话那是CSR?使用express配置静态目录这个方法我还没有试,这块我不太了解,
另外还有2个小问题:1、图片显示问题,我在您之前路由判断的基础上又加了图片的判断,可以显示了,但是之后那些不同类型的文件是都要加一个这样的判断吗?
2、我使用geiInitialProps方法返回的数据取不到,是undefined,我的代码也是按照官方文档来的,如下图所示:
image
如果您有时间的还希望您能继续帮忙看一下~十分感谢!

不是使用ngxinx就是csr,建议部署方式是,加入publicPath,比如是dist,可以配置反向代理,所有非/dist/*路由,都由nginx转发到express服务器,而dist目录则由nginx直接指向静态目录。
1.问题1用我上面的方法可以解决。
2.是否打开ssr选项?在开发模式下是否可以获取数据?检查源代码里是否能看到数据?
好的,问题1的方法我再研究一下,感谢!关于问题2,我有打开ssr选项,但是在开发模式和源代码里面都看不到数据,代码也没有报错

有最小复现么?可能是部分代码有问题,导致自动降级了?得看下代码,才能确定

https://github.com/CassielLee/umi3-ssr-demo.git

这个是我的代码,您看下,感谢~

@williamnie
Copy link
Contributor

请问下部署的具体步骤是什么呢?我copy的官方的代码,但是访问不到页面,难受……

贴下你的配置,和部署步骤,我看下能不能帮忙解决,目前umi存在一些问题:

  1. 如果开启hash,umi.server.js内部的html中不会加hash,可以先关闭hash

我的配置是:umi:3.2.3,node: 11.14.0,系统是:win10,刚刚忘记说了,不好意思!

你的publicPath配置是什么?打包输出到哪里了?是否能通过连接直接访问到umi.js和umi.css?

publicPath我没有配置,就是默认的配置,打包文件都输出到dist文件夹下了,我和楼主的问题一样的

稍微改了一下你贴出来的git的复现地址,已经能出来了,我贴下代码,主要是服务端的代码写的不对,
问题出在express的服务端没做路由判断,也没设置静态目录,导致无法在127.0.0.1:3000/umi.js链接下找到umi.js文件,我的代码不建议直接用在生产环境,生产环境解决方案是用nginx配置静态目录,能让127.0.0.1:3000/umi.js访问到。下面贴出改的express代码

const express = require('express');
const app = express();
const render = require('./dist/umi.server');
const fs = require('fs');
// 这里简单的用fs读取一下文件,后面直接 扔给前端
const umijs = fs.readFileSync('./dist/umi.js');
const umicss = fs.readFileSync('./dist/umi.css');


const port = 3000;

const domain = 'http://localhost';

// Express
app.use(async (req, res) => {
  // 或者从 CDN 上下载到 server 端
  // const serverPath = await downloadServerBundle('http://cdn.com/bar/umi.server.js');
  /*
      这里做了路由判断,更好的方案是用nginx配置静态目录(指向build好的目录,如dist)
      或者通过express设置静态目录,umi加入publicPath配置
*/
  if (req && req.url === '/umi.css') {
    res.setHeader('Content-Type', 'text/css');
    res.send(umicss);
  } else if (req && req.url === '/umi.js') {
    res.setHeader('Content-Type', 'text/js');
    res.send(umijs);
  } else {
    res.setHeader('Content-Type', 'text/html');
    const context = {};
    const { html, error, rootContainer } = await render({
      // 有需要可带上 query
      path: req.url,
      context
    });

    res.send(html);
  }


});

app.listen(port, err => {
  if (err) {
    throw err;
  }
  console.log(`> Ready on port ${port}, ${domain}:${port}`);
});

感谢大佬指点,现在页面出来了,我试了一下nginx也可以,但是使用nginx的话那是CSR?使用express配置静态目录这个方法我还没有试,这块我不太了解,
另外还有2个小问题:1、图片显示问题,我在您之前路由判断的基础上又加了图片的判断,可以显示了,但是之后那些不同类型的文件是都要加一个这样的判断吗?
2、我使用geiInitialProps方法返回的数据取不到,是undefined,我的代码也是按照官方文档来的,如下图所示:
image
如果您有时间的还希望您能继续帮忙看一下~十分感谢!

不是使用ngxinx就是csr,建议部署方式是,加入publicPath,比如是dist,可以配置反向代理,所有非/dist/*路由,都由nginx转发到express服务器,而dist目录则由nginx直接指向静态目录。
1.问题1用我上面的方法可以解决。
2.是否打开ssr选项?在开发模式下是否可以获取数据?检查源代码里是否能看到数据?
好的,问题1的方法我再研究一下,感谢!关于问题2,我有打开ssr选项,但是在开发模式和源代码里面都看不到数据,代码也没有报错

有最小复现么?可能是部分代码有问题,导致自动降级了?得看下代码,才能确定

https://github.com/CassielLee/umi3-ssr-demo.git

这个是我的代码,您看下,感谢~

看了一下,是withLayout的高阶组件的问题,加上它以后就不行了,还没具体看,暂时可以通过直接饮用Layout组件加在页面或者是通过路由来fix这个问题。

    {
      path: '/',
      component: '@/layouts/Layout/layout',
      routes: [
        { path: '/', component: '@/pages/index' },
        { path: '/error', component: '@/pages/error' },
      ],
    },

@CassielLee
Copy link

请问下部署的具体步骤是什么呢?我copy的官方的代码,但是访问不到页面,难受……

贴下你的配置,和部署步骤,我看下能不能帮忙解决,目前umi存在一些问题:

  1. 如果开启hash,umi.server.js内部的html中不会加hash,可以先关闭hash

我的配置是:umi:3.2.3,node: 11.14.0,系统是:win10,刚刚忘记说了,不好意思!

你的publicPath配置是什么?打包输出到哪里了?是否能通过连接直接访问到umi.js和umi.css?

publicPath我没有配置,就是默认的配置,打包文件都输出到dist文件夹下了,我和楼主的问题一样的

稍微改了一下你贴出来的git的复现地址,已经能出来了,我贴下代码,主要是服务端的代码写的不对,
问题出在express的服务端没做路由判断,也没设置静态目录,导致无法在127.0.0.1:3000/umi.js链接下找到umi.js文件,我的代码不建议直接用在生产环境,生产环境解决方案是用nginx配置静态目录,能让127.0.0.1:3000/umi.js访问到。下面贴出改的express代码

const express = require('express');
const app = express();
const render = require('./dist/umi.server');
const fs = require('fs');
// 这里简单的用fs读取一下文件,后面直接 扔给前端
const umijs = fs.readFileSync('./dist/umi.js');
const umicss = fs.readFileSync('./dist/umi.css');


const port = 3000;

const domain = 'http://localhost';

// Express
app.use(async (req, res) => {
  // 或者从 CDN 上下载到 server 端
  // const serverPath = await downloadServerBundle('http://cdn.com/bar/umi.server.js');
  /*
      这里做了路由判断,更好的方案是用nginx配置静态目录(指向build好的目录,如dist)
      或者通过express设置静态目录,umi加入publicPath配置
*/
  if (req && req.url === '/umi.css') {
    res.setHeader('Content-Type', 'text/css');
    res.send(umicss);
  } else if (req && req.url === '/umi.js') {
    res.setHeader('Content-Type', 'text/js');
    res.send(umijs);
  } else {
    res.setHeader('Content-Type', 'text/html');
    const context = {};
    const { html, error, rootContainer } = await render({
      // 有需要可带上 query
      path: req.url,
      context
    });

    res.send(html);
  }


});

app.listen(port, err => {
  if (err) {
    throw err;
  }
  console.log(`> Ready on port ${port}, ${domain}:${port}`);
});

感谢大佬指点,现在页面出来了,我试了一下nginx也可以,但是使用nginx的话那是CSR?使用express配置静态目录这个方法我还没有试,这块我不太了解,
另外还有2个小问题:1、图片显示问题,我在您之前路由判断的基础上又加了图片的判断,可以显示了,但是之后那些不同类型的文件是都要加一个这样的判断吗?
2、我使用geiInitialProps方法返回的数据取不到,是undefined,我的代码也是按照官方文档来的,如下图所示:
image
如果您有时间的还希望您能继续帮忙看一下~十分感谢!

不是使用ngxinx就是csr,建议部署方式是,加入publicPath,比如是dist,可以配置反向代理,所有非/dist/*路由,都由nginx转发到express服务器,而dist目录则由nginx直接指向静态目录。
1.问题1用我上面的方法可以解决。
2.是否打开ssr选项?在开发模式下是否可以获取数据?检查源代码里是否能看到数据?
好的,问题1的方法我再研究一下,感谢!关于问题2,我有打开ssr选项,但是在开发模式和源代码里面都看不到数据,代码也没有报错

有最小复现么?可能是部分代码有问题,导致自动降级了?得看下代码,才能确定

https://github.com/CassielLee/umi3-ssr-demo.git
这个是我的代码,您看下,感谢~

看了一下,是withLayout的高阶组件的问题,加上它以后就不行了,还没具体看,暂时可以通过直接饮用Layout组件加在页面或者是通过路由来fix这个问题。

    {
      path: '/',
      component: '@/layouts/Layout/layout',
      routes: [
        { path: '/', component: '@/pages/index' },
        { path: '/error', component: '@/pages/error' },
      ],
    },

好的。感谢您!

@SilentFlute
Copy link
Author

@williamnie 大家互相引用导致回答好长, 看起来好累, 哈哈
我对服务端的东西了解的不多, 看了你贴出来的express的代码, 以及后面你给另一个哥们@CassielLee 的回复:
加入publicPath,比如是dist,可以配置反向代理,所有非/dist/*路由,都由nginx转发到express服务器,而dist目录则由nginx直接指向静态目录
这段话意思是不是:

  1. 非/dist/*路由, 就是将业务路由, 或者说页面转发到我们的express服务器, 就是我们的业务交由我们的umi.server.js来处理对吧?
  2. 而dist目录则由nginx直接指向静态目录, 这步是为了让xxx.com/umi.js能正常访问对吧, 访问到的是/dist/umi.js, 毕竟静态目录就是干这个的, 是这样的吗?
  3. 结合1和2, 那xxx.com/umi.js是不是也和业务路由一起被转发或者说反代到了express服务器?
  4. 那综上1-3, 判断路由并设置相应的content-type这步, 例如xxx.com/umi.js我们需要设置content-type为text/js, 依旧还是我们的express来做? 那就像那个哥们说的, 比如图片, 就依旧需要加判断设置相应的content-type头喽?那这样的话我们是不是只需要用nginx将所有路由都反代到express, 然后express自己设置静态路径为dist目录, 这样xxx.com/umi.js就能访问到/dist/umi.js, 此时express再设置一波content-type为text/js就好了?总结一下就是: 判断路由设置content-type始终由express来做, 静态目录可以通过nginx或者express来做
    对这块不是太了解, 求解答, 谢谢

@williamnie
Copy link
Contributor

是的,如果都交给express来做,就需要配置express的静态目录,让资源直接走静态,而页面的路由走到umi.server进行render页面。如果对服务端了解不多,建议使用egg,方便,都是配置好的,最后直接用nginx将所有路由都转发给egg就行了

@SilentFlute
Copy link
Author

@williamnie 哦哦, 好的, 了解, 再次感谢!
仓库会保留, 问题就先关闭了, 我司目前使用nextjs+apollo-client来做react ssr的项目, 之前我用过nextjs, 以及nextjs官方有结合apollo-client的例子, 上手相对容易, 后续有问题再打开

@fikyair
Copy link

fikyair commented Jan 15, 2022

解决了,是umi的bug,你把hash去掉就好了。
可不可以提供最小的demo

@Zhang-haohua
Copy link

Zhang-haohua commented Jun 9, 2022

是的,如果都交给express来做,就需要配置express的静态目录,让资源直接走静态,而页面的路由走到umi.server进行render页面。如果对服务端了解不多,建议使用egg,方便,都是配置好的,最后直接用nginx将所有路由都转发给egg就行了

@williamnie
请问egg下怎么处理呢,我用egg+umi开发的项目,egg运行在7001端口,静态资源运行在8000端口,egg页面打不开,发现问题是它的静态资源路径指向的是7001端口,导致我拿不到8000端口的资源,请问怎么处理呢

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type(ssr) UmiJS SSR
Projects
None yet
Development

No branches or pull requests

7 participants