Skip to content
This repository has been archived by the owner on Feb 25, 2022. It is now read-only.
/ think-react-app Public archive

thinkjs 插件,在 thinkjs 中使用 react和react-router 来构建同构的 webapp

License

Notifications You must be signed in to change notification settings

snadn/think-react-app

Repository files navigation

think-react-app

thinkjs 插件,在 thinkjs 中使用 react 和 react-router 来构建同构的 webapp

安装

npm install think-react-app --save

使用

  1. 编辑 src/common/bootstrap/plugins.js (如果没有则创建),引入插件

    import reactPlugin from 'think-react-app';
    reactPlugin.init();
  2. 让 base controller 继承于 'think-react-app/lib/base',然后使用 this.display() 进行渲染

  3. 修改 config/view 的 type 为 react

  4. 在 view/home 中放入基于 react-router 的 webapp 代码

    此处入口 html 文件为 routes.html , routes 配置为 routes.js

    html 中通过 window.G = JSON.parse('{{GStr}}'); 将服务器端的数据同步到浏览器端, 通过 <div id="react-wraper">{{html}}</div> 作为服务端渲染的占位符

  5. 在 www/static/js/ 中创建浏览器端执行脚本 app.js,例如

    import React from 'react'
    import { render } from 'react-dom'
    import { match, Router, useRouterHistory } from 'react-router'
    import createBrowserHistory from 'history/lib/createBrowserHistory'
    
    import rootRoute from 'view/mobile/routes'
    
    const history = useRouterHistory(createBrowserHistory)({
    	basename: G.root
    });
    
    
    const lazyRender = (history, routes) => {
    
    	const { pathname, search, hash } = window.location
    
    	match({
    		routes,
    		history
    	}, (error, redirectLocation, renderProps) => {
    
    		if (redirectLocation) {
    			history.replace(redirectLocation);
    			// redirect and re render
    			lazyRender(history, routes)
    		} else {
    			render(
    				<Router {...renderProps} />,
    				document.getElementById('react-wraper')
    			)
    		}
    	})
    }
    
    lazyRender(history, rootRoute);

ps:可以参考demo进行相关配置

潜规则

  1. 在 node 端

    • 可以通过 this.assign('getCreateElement', getCreateElement); 自定义 react-router 渲染时的 createElement 参数, 若有使用 redux 等框架,可以在里面处理。
    • 可以通过 this.assign('getRoutes', getRoutes); 自定义 routes配置的获取
  2. 处理 routes.html 模板时

    • 使用服务端渲染的字符串替换 {{html}}
    • 将全局变量 G JSON.stringify 后,替换 {{GStr}}。 全局变量 G 中会加入 context, context 中为 controller 中 assgin 传入的参数(除 getCreateElement 和 getRoutes),浏览器中可以通过 G.context 来获取单个请求相关的信息。

配置

export default {
	type: 'react',
	content_type: 'text/html',
	file_ext: '.html',
	file_depr: '_',
	root_path: think.ROOT_PATH + '/view',
	file_name: 'routes.js', // routes 配置文件名,node端渲染时会取其同名的 .html 文件进行渲染
	server_render: true, // 是否启用服务器端渲染
	globalVarName: 'G' // 自定义全局变量的名称
};

react-router v4

采用 react-loadable 的方案实现,具体参考:https://github.com/thejameskyle/react-loadable

  1. 需在 view 配置参数
bundlesInfo: {}, // 资源信息,有webpack插件生成
publicPath: '', // 静态资源前缀
  1. 需配置 babelwebpack 使用 react-loadable 的插件
  2. 需在模板 html 中添加 {{css}}{{js}} 占位符

About

thinkjs 插件,在 thinkjs 中使用 react和react-router 来构建同构的 webapp

Resources

License

Stars

Watchers

Forks

Packages

No packages published