前言
这两天在学react-router, 之前有了解过, 但没有系统地学, 觉得比较简单, 会用就行. 但当昨天知道react-router结合webpack可以做到按需加载时(点击查看例子), 顿时来了兴趣, 于是就跟着react-router-tutorial上的教程敲了一遍(代码在这里, 还是有不少收获的, 下面我将说明我教程中较重要的点.
温馨提示
教程一共14个lesson, 每一个lesson里面都会有readme.md, 记得要看着readme.md来做.
如果想直接看源码. 那么要注意: 除了第1个lesson以外, 每个lesson的代码其实在下一个lesson文件夹中. 也就是说, 第2个lesson的完整代码, 在第3个lesson中, 需要你看READEME.md自己实现. 一开始我不知道, 还以为教程里的文档与代码不一致, 囧…
嵌套路由
以下是嵌套的路由
|
|
则父组件可以通过使用{this.props.children}
来显示子路由里的组件, 子组件之间的切换对页面而言是局部刷新, 不用重载整个页面.
|
|
browserHistory
教程里一开始是使用hashHistory
的, 后来有一章内容专门把它替换成browserHistory
, 二者的区别主要如下:
hashHistory
url以#开头, 后面带有一大串奇怪的符号, 用于存储location state
,browserHistory
则是平时浏览器浏览网页的urlhashHistory
不需要对服务器作额外的配置, 可用于快速上手或演示demo,browserHistory
需要修改服务器配置browserHistory
是基于HTML5 History API的, 在IE8/IE9等不支持API的浏览器中,browserHistory
局部刷新的能力将消失, 退化成整个页面重载(full page reload), 但hashHistory
仍拥有局部刷新的能力browserHistory
支持服务端渲染(server-side rendering)
下面是使用browserHistory
时, 需要的配置:
- 如果是
webpack-dev-server
, 命令行后面要加选项--history-api-fallback
, 如package.json
里这样写:
|
|
- 如果是使用
express
, 需要设置服务器接收到任何正常请求, 都返回index.html
:
|
|
<! –
index.html
中引用资源需要变使用绝对路径
|
|
–>
对于路径, 最好在
Route
,Link
等组件中定义的路径都是绝对url, 也即斜杠(/)开头, 不然有可能会出现bug. 具体可以查看代码:
路径不是斜杠开头产生的bug
发布生产
1. npm script
生产脚本一般要传环境变量: NODE_ENV='production'
- 教程是直接是使用if-env, 在
npm script
内部区分生产与开发:
|
|
这种方案的缺点在于, 环境变量需要运行脚本时手动设置, 最终运行命令为:
|
|
- 考虑到不想手动设置环境变量, 且想跨平台的话, 可以使用cross-env, 上面的
npm script
可变成:
|
|
相应shell命令为:
|
|
- 但对我而言, 程序开发好了, 只是为了写脚本, 又需要下载依赖包, 我有点不愿意. 而且, 我觉得根本不用照顾Windows用户, 因为服务器一定是Unix-like的, Windows机跑生产脚本机率并不大. 所以我的
npm script
是这样子的:
|
|
// 或下面更简洁的写法
|
|
2. webpack.config.js
使用优化插件. 最常用的当然是UglifyJsPlugin
, 可以混淆代码并减小输出的js的体积
其他插件, 请看官方文档
|
|
3. express
express可以开启gzip压缩选项
|
|
Server Rendering
如何判断一个基于react的webapp是否进行了服务端渲染呢? 方法很简单, 打开网页, 右键->显示网页源码.
也可以命令行
|
|
如果显示的是下面那样, 说明是客户端渲染, 服务端只返回最初的DOM结构, #app
的子节点都由react在客户端生成:
|
|
如果是是服务端渲染, 则返回是完整的html, 如下面的例子:
|
|
在这个章节, 我遇到了很奇怪的问题. 直到博客写到这里, 看到上面代码, 我才知道问题在哪里, 并把它解决了. 哈哈,看来写博客还是有用的.
这个问题就是: 我发现按照官网的例子实现后, 访问根路径时, 页面是由客户端渲染的, 而别的路径的页面才是服务端渲染的.
为什么会这样呢?
注意到上面客户端渲染的例子是有head
的, 那是我自己建的index.html
; 而服务端渲染的例子是没有head
的, 那是教程里的代码. 我再去对比教程里的源码, 发现它的public
目录下是没有html文件的. 于是乎, 我把自己建的index.html
删除掉, 问题就解决了, 访问根路径时呈现的页面, 也是服务端渲染的了. 也就是说, 如果静态文件夹里有相应的静态文件(index.html), 则express就直接返回该文件(index.html), 不会再去动态生成了.
则要注意的是, 想开启服务端渲染, 项目下面不能有index.html
所以说, 站在岸上学不会游泳. 学习新技术, 就算觉得简单, 仍要动手实践一下才行.
教程到此就终止了.
它指出: server rendering 是最前沿的技术, 目前还没有所谓的”最佳实践”, 因此剩下的路需要自己去探索