thinkjs 插件,在 thinkjs 中使用 react 来构建同构的 webpage
npm install think-react-page --save
-
编辑 src/common/bootstrap/plugins.js (如果没有则创建),引入插件
import reactPlugin from 'think-react-page'; reactPlugin.init();
-
在 view 目录下创建 base.html 模板文件,例如
<!doctype html> <html> <head> <title>DEMO</title> </head> <body> <div id="react-wraper">{{html}}</div> <script src="/static/js/lib/react.js"></script> <script src="/static/js/lib/react-dom.js"></script> <script> window.G = {{GStr}}; </script> <script src="{{pageScript}}"></script> </html>
-
在 view/home 中创建相应的视图文件,例如 IndexIndexPage.js
-
命名规则 [Controller][Action]Page.js 首字母大写
-
在视图中导出命名为 Page 的 Component,例如
import React, {Component} from 'react' export class Page extends Component { render() { return 'React Demo'; } }
-
-
在 www/static/js/index 中创建浏览器端执行脚本 index.jsx,例如
import React from 'react'; import ReactDOM from 'react-dom'; import provideContext from 'think-react-page/lib/provideContext'; import {Page} from 'HomePage/IndexIndexPage'; // HomePage 为 webpack 中定义的别名,即 /view/home const ContextProvider = provideContext(G.context)(Page); ReactDOM.render(<ContextProvider location={location} />, document.getElementById('react-wraper'));
然后使用 webpack 编译 index.jsx => index.js
-
在 controller 中 assign('pageScript', '/static/js/index/index.js'), 或者在 view 的配置中指定 getPageScript 方法来返回页面对应的浏览器端脚本路径
-
在 node 端,渲染 Page 时会在 props 中传入 location ,会设置 context。
- location 为 url.parse(http.req.url) 的结果
- context 中为 controller 中 assgin 传入的参数 ( context 的使用参见:https://facebook.github.io/react/docs/context.html )
-
处理 base.html 模板时
- 使用 Page 渲染成的字符串替换 {{html}}
- 将全局变量 G JSON.stringify 后,替换 {{GStr}}
- 使用浏览器端脚本路径替换 {{pageScript}}
import path from 'path'
// 自定义的映射表,用于静态资源构建后名称改变的情况
try {
var map = require(path.join(think.ROOT_PATH, './page_map.json'));
} catch(e){
var map = { res: {} };
}
// 我的项目中获取浏览器端脚本url的规则,根据项目情况自定义
function getPageScript(templateFile, options) {
let dirname = path.dirname(templateFile).split(options.root_path)[1];
let basename = path.basename(templateFile).replace(/^[A-Z]/, function(w){
return w.toLowerCase();
}).replace(/[A-Z]/, function(w){
return '/'+w.toLowerCase();
});
let pageName = dirname + '/' + basename;
let pagePath = "/static/js/" + pageName;
if (map.res['webpack/' + pageName]) {
pagePath = map.res['webpack/' + pageName].uri
}
return pagePath;
}
export default {
type: 'react',
content_type: 'text/html',
file_ext: 'Page.js',
file_depr: '_',
root_path: path.join(think.ROOT_PATH, 'view/'),
adapter: {
react: {
getPageScript, // 浏览器端脚本url的获取方法
globalVarName: 'DEMO', // 要使用的全局变量的名称,默认为 G
server_render: true // 是否开启服务端渲染
}
}
};