基于umi的seo预编译

1、介绍

基于SPA的项目,打包出来的文件中只有一个index.html做为入口,再根据页面的路由加载对应页面的js。html

当项目须要支持SEO时,在条件容许的状况下能够选择node做为同构方案,根据url匹配routes中的components,再经过rendersToString方法打印出内容,放到html模板中。此方案的优势是能够支持动态路由、后端获取数据。缺点是每次访问都要生成一次、引进了node服务。node

若是在网站被访问以前就把html预编译好,多个路由对应多个html。后端

在umi项目中配置预编译很是简单
umirc.js浏览器

plugins: [['@umijs/plugin-prerender']],
ssr: true,

2、ssr

把umirc.js中ssr设置成true后,dist文件夹下就多生成了一个umi.server.js文件,它是以/src/pages/.umi文件为入口、囊括了其余全部dist/*.js生成的大文件,而且通过了一些环境上的处理。网站

1.__IS_BROWSER

/src/pages/.umi是每次打包后都会生成的中间结果,查看代码会发现它是以__IS_BROWSER变量区分浏览器、node环境,而umi.server.js则是把__IS_BROWSER变量替换成boolean的结果,所以在业务代码中,能够直接使用__IS_BROWSER这一变量区分你的逻辑。例如,页面中一开始有loading等待缓冲的效果,可使用__IS_BROWSER将loading取消,避免编译出来的内容无效。url

2.getInitialProps

在预编译以前,想要给html中放入一些内容,但这些内容又不须要在实际业务中展现。这时能够选择给routes下定义的component添加getInitialProps方法插件

function Index(props){
    return props.nodeContent || 'hello world'
}

Index.getInitialProps = ()=>({
  nodeContent: '个人seo内容'
})

export defalut Index

将不常常更新的内容放到getInitialProps中写死,生成的内容供seo抓取,不过在js执行后会将其刷新掉。ssr

3.mockWindow

umi-server在调用umi.server.js时会给global变量附加mock过的window对象,例如,在业务代码中访问window.location.url时,获取到的是浏览器环境同样的结果。code

3、pre-render

pre-render插件在umi打包结束后,按照routes里的url一个个访问ssr,相似于构造虚拟访问来生成html。component

routes除非指定了黑白名单,不然将生成全部html
umirc.js

[
      '@umijs/plugin-prerender',
      { 
      include: ['/'],
      exclude: ['/help']
      },
]

4、拓展

1.图片

umi默认给图片加了阈值,当小于这个值时生成的图片使用base64。但在预编译时生成的html中会产生大量的base64字符,使得html变大。
这里能够设置图片的阈值,减少html的包袱
umirc.js

chainWebpack(config) {
    config.module
      .rule('exclude')
      .use('url-loader')
      .tap((options) => {
        return {
          ...options,
          limit: 1,
        };
      });
  }

2.动态路由

最新的umi版本已经解决了动态路由的问题,例如/:id的路由会生成[id].html。若是项目中的动态路由可枚举,将动态路由改形成一个个写死的路由,这样再生成多个html。这样作的目的是生成更多的html让seo引擎抓取。若是项目中的动态路由没法枚举,或访问方式有太多种,则须要借助后端动态实时生成。

相关文章
相关标签/搜索