1.单体应用框架项目介绍。打包文件中只有一个index.html作为入口,根据页面的路由加载对应页面的js。当项目需要支持SEO时,如果条件允许,可以选择node作为同构方案,配合react-router-config匹配routes中的组件,然后通过rendersToString方法打印出内容注入到html模板。这种方案的好处是可以支持动态路由,后端动态获取数据。缺点是每次访问需要生成一次,引入节点服务。如果在访问网站之前对html进行预编译,多个路由对应多个html,这就是下面要介绍的预编译解决方案。在umi项目umirc.jsplugins中配置预编译非常简单:[['@umijs/plugin-prerender']],ssr:true,2.预渲染插件在umi中打包后,按照url中的routes访问ssr类似于构造一个虚拟访问生成html。routes会生成所有htmlumirc.js['@umijs/plugin-prerender',{include:['/'],exclude:['/help']},]除非指定黑名单和白名单。三、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变量来区分你的逻辑。比如一开始页面有加载等待缓冲的效果,可以使用__IS_BROWSER取消加载,避免编译后的内容失效。上面提到的runInMockContext加载效果的区分,也可以通过配置中自定义环境变量来自定义['@umijs/plugin-prerender',{runInMockContext:{__isCustomEnv:true}}]2.mockWindowumi-server正在调用umi.server.js会将模拟窗口对象附加到全局变量。比如在业务代码中访问window.location.url,得到的结果和浏览器环境下是一样的。3.GetInitialProps想在预编译前的html中放入一些内容,但是实际业务中不需要展示这些内容。这时候可以选择在routes下定义的组件中添加getInitialProps方法(1)StaticcontentfunctionIndex(props){returnprops.nodeContent||'helloworld'}Index.getInitialProps=()=>({nodeContent:'我专门为seo添加的内容'})exportdefalutIndex将不经常更新的内容放入getInitialProps中硬编码,生成的内容是为了seo抓取的,但是它js执行后会刷新。(2)动态内容函数Index(props){returnprops.nodeContent||'你好世界'}Index.getInitialProps=()=>{returnAPI.getData();//promise==>{nodeContent:'dynamiccontent'}}exportdefalutIndex返回一个promise,也可以传递给组件的props,适用于内容不固定的场景。(3)动态路由在某些场景下,需要将路由信息传递给后端来获取动态内容。如果项目原来的动态路由配置如下{path:'/users/:id',component:'../pages/users'},新建一个文件枚举usersroute-users-下的所有idconfig.jsconstusersRoutes=[{path:'/users/10',component:'../pages/users'},{path:'/users/11',component:'../pages/users'},{路径:'/users/99',组件:'../pages/users'},...];exportdefalutusersRoutes会将userRoutes添加到umi的路由配置中,然后列出usersRoutes的路径并添加到pre-render的include中生成枚举动态路由html动态路由信息可以在props函数中获取Index(props){返回props.nodeContent||'你好世界'}Index.getInitialProps=({location})=>{returnAPI.getData(location.pathname);//promise==>{nodeContent:'dynamiccontent'}}exportdefalutIndex4.Dynamictitle,metaBaidusearchTDK需要,为每个页面生成不同的关键词,描述,标题,提高搜索引擎的索引权重。importHelmetfrom'react-helmet';
