摘要:单页博客应用编写总结很久之前就想写一个博客应用在一开始想要直接用和模板直接写但是暑假一开始的时候不小心入了的坑所以就一不做二不休直接用写那既然用了不写个单页应用也过意不去了不前前后后写了将近两个星期现在看来这其实是一个很容易的应用但是鉴于
React-Express单页博客应用编写总结
很久之前就想写一个博客应用.
在一开始想要直接用express和ejs模板直接写, 但是暑假一开始的时候不小心入了react的坑, 所以就一不做二不休直接用react写. 那既然用了react, 不写个单页应用也过意不去了...(不
前前后后写了将近两个星期, 现在看来这其实是一个很容易的应用. 但是鉴于是第一次用react, 对于nodejs也不是特别熟悉, 所以走了不少冤枉路. 其中也有很多次觉得想放弃, 不过最终还是写下来了. 虽然还是有不少瑕疵, 不过也算给自己一个交代吧.
个人博客网站的地址为: harryfyodor.tk
下面会从几个方面把我整个编写的过程的一些经验记录下来, 主要是记录自己的学习过程, 编写中遇到的困难以及解决, 以及一些学习/复习资料的整理分享. 也希望给各位和我一样的初学者一点点借鉴的经验.
(个人感觉比较好的学习方式就是自己看资料(文档和博客)然后写自己的一个小应用, 而不是跟着某一个教程从头到尾过一遍, 虽然不得不承认, 后者学起来的感觉很爽, 而且也更清晰. 但是不好的地方就是技术栈不完全匹配的时候就会很头疼...)
下面是目录:
前端 (包括react, redux, css-module等)
后端 (包括express, mongodb)
前后端 (包括fetch, jwt)
其他 (包括webpack, 优化等)
下面直接进入正题.
第一部分 前端 1, reactreact的学习根据官方文档, 主要是理解一下几个方面的内容:
构建模块的方法. 用了推荐es6的class的方法而非createClass.
如何导入导出模块. es6的import和export.
jsx的编写. 不是必要的, 官网推荐. 感觉其中用上es6模板字符串, map方法会很方便很多~
props, state, refs的相关概念以及使用. 单向数据流中, 父组件给子组件传递数据通过props, 子组件给父组件传递数据用回调函数. 后者的实现是通过父组件把一个函数传到子组件中, 这个函数里面有可以有this.setState(收到子组件的数据后立刻渲染), 然后子组件调用传进来的函数, 通过这个函数把参数传给父组件.
掌握connect组件的使用方法. 把state数据和dispatch传进组件中.
生命周期. 在这个博客SPA应用里用了componentDidMount和componentWillReceiveProps, 前者可用于初始化的渲染以及异步请求的发起, 后者用于接收到新的数据时的再次渲染, 把异步的结果渲染出来. 因此一个组件(涉及到异步)是这样工作的: 调用组件 -> 组件渲染之前发起异步请求 -> 第一次渲染,没有数据的页面 -> 接收到异步发回来的数据 -> 重新渲染, 有数据的页面. 代码如下, 基本也是按照这种数据流向的方法来的(不知道是不是最好的方案, 但是感觉很方便).
class Archive extends React.Component { constructor(props) { super(props); this.displayName = "Archive"; this.state = { articles: [] } } componentDidMount() { this.props.actions.getTitles({ type: "ARCHIVE" }) } componentWillReceiveProps(nextProps) { this.setState({ articles: nextProps.getTitles.articles }) } render() { return ({/*这里是相关的渲染articles的操作, 注意要把[]的情况也考虑到*/}) }
}
export default Archive
配合好setState和生命周期, 运用好父子组件之间的数据传递能够很好地完成各种异步渲染.
2, redux理解redux主要是要理解action, reducer, middleware等概念. 个人感觉redux的官方文档简直精彩, 例子也很丰富, 非常值得学习. 这个SPA博客里的action大部分是为了ajax获取后端数据服务的. 下面选取了其中的一组, 功能是获取多带带的文章. 对应不同相应状态有不同的action. 这样就可以把异步的每一个状态记录下来, 使得数据的流向更加清晰. 具体有关异步请求的相关的内容可以看我的上一篇文章.
export const singleRequest = () => { return { type: SINGLE_REQUEST } } export const singleSuccess = (article) => { return { type: SINGLE_SUCCESS, article: article } } export const singleFailure = () => { return { type: SINGLE_FAILURE } } export const getSingle = (day, title) => { return dispatch => { dispatch(singleRequest()) return fetch("/api/single", { method: "POST", headers: { "Content-Type": "application/json", "Accept": "application/json" }, body: JSON.stringify({ day: day, title: title }) }) .then(checkHttpStatus) .then(res => res.json()) .then(res => { if(res.ok) { dispatch(singleSuccess(res.article)) } else { dispatch(singleFailure()) } }) } }
至于在reducer中, 初始化state用了几个标识. 比如下面的例子中, 初始化的reducer state 包含了isFetching, isFetched, fetchFailure这些标志异步进行的当前状态的信息. 传入props之后可以很方便地进行异步请求先后的设置. 比方说一个异步要在另一个异步之后, 就可以通过读取这几个数值完成. (第二个异步一定要在第一个的isFetched为true的时候才能发起)
const initialState = { isFetching: false, isFetched: false, fetchFailure: false, articles: [], count: 1 }
在整个应用中需要用到中间件, 在应用中用了thunk还有logger.
3, css-modules在博客应用中css的引入用的是css-modules, 阮一峰大神的这篇文章讲得算是完整了, 感兴趣可以看一下~ 当然有些部分也还是用了css in js的方法, 直接把css写到js里面, 主要是考虑到一些操作的方便, 比如点击之后某一个标签display改变之类的.
第二部分 后端说来惭愧, 后端大部分都是"抄"的, 之前看的一个教程是用express和ejs写的博客应用, 而后端的操作大部分都比较接近. 主要就是根据接口路由处理数据, 发送数据, 通过数据库api(这里是mongodb)读取数据库数据. 所以最后写出来的和我原本看的那个教程有很大的相似之处. 我看的教程是这一个, 非常棒, 感谢作者!!>o 1, express (nodejs)
关于express个人感觉比较重要的是处理配置以及路由两个方面的问题.
前者需要靠自己慢慢摸索, 比如要处理json需要用到bodyParser模块, webpack一些中间件的配置等等, 可以拿redux官网还有上面提到的教程来参考一下.
后者主要是要了解express提供的各种方法, 以及一些有关res和req的相关操作等等.
有关数据库的操作我也是参考上面的教程的...(oh..)基本对数据库的增删查改要掌握. 更多有关mongo的api原理等可以去看官网介绍.
3, 不足之处由于目标不是专业后端, 所以后端做得比较粗糙. 不足之处有很多, 比如没有拥抱es6(明明前端已经拥抱), 比如还在若无其事地写着臭名昭著的回调金字塔等等等. nodejs需要加强.
第三部分 前后端 1, 登录 (JSON Web Token)有关登录和登出开始找了很多相关的实现方法, 在这篇文章的推荐下看了JWT实现方式. 简单来说就是前端把密码post到后端, 后端生成一个token然后发送到前端去. 前端把收到的token保存在localStorage中. 每次需要获取一些保密的信息或者需要做一些修改的时候, 把这个token写在请求的headers里. 后端收到数据之后就会先验证一下token是否正确, 正确才允许操作.
headers: { "Content-Type": "application/json", "Accept": "application/json", "Authorization": `Bearer ${token}` }2,fetch (获取数据)
关于前后端交互这一点可以参考我写的上一篇文章. 后端把api暴露出来给前端, 前端通过ajax进行数据的交互, 并把获取到的数据渲染出来. 操作上没有难度, 只是要注意异步操作中redux要用中间件.
有关中间件还要去看点高阶函数的基础知识, 不然无法正确理解.
没有怎么认真地看webpack的东西, 都是顺手操起来直接用的...
说实话, 第一次开始看chrome的devtool的network的时候, 我被吓得不轻...一个bundle文件5m大, PC端打开之后真的是不忍直视. 后来上网找了一些webpack打包优化的方向, 在这里记录一下:
webpack的config文件里面不能有cheap-module-eval-source-map之类的devtool, 真的很大很大...
plugin如果不是必要的话也请删去吧. 不过有两个plugin可以在生产环境中用一下, 第一个是UglifyJsPlugin, 用于压缩文件. 第二个是CommonsChunkPlugin, 这个具体下一点解释.
适当分块. CommonsChunkPlugin用于把bundle分块, 把可以放在缓存的, 常用的, 体积比较大的压缩到vendor里面(比如react等). 后来又把babel-polyfill分开另外加载了. 之前有看到code split, 就是直到需要用到该ui组件的时候才去加载, 想法好像不错, 不过感觉改动会比较大所以最后没有做.
最后的文件大小其实也还是不小, 但是有了很好的改善. 关于前端优化也是一个重要的话题.
2,markdown博客应用写作用的是markdown. 原本想找一个现成的, 但是死活找不到合适的...最后直接用marked强行伪装markdown编辑器...其实这很不安全, 但目前也没有什么办法...(draft.js貌似可以?)
总结总体来说, 这个博客其实实现起来没有特别高的难度, 但是对于初学者来说感觉真的挺不容易的. 之前听过这样一句话--不要同时学几样东西, 其实还真的有点道理...但是对于一些最佳实践, 本身就要结合在一起才能发挥其最大的作用, 不一起学又怎么能行呢?(因此就陷入了大坑).
这个博客不完善的地方太多了, 特别是有关安全方面的问题.不过现在还是先关注着前端吧.
希望这篇文章能够给你一点点帮助.
最后上代码博客代码
(本人是初学者, 如果有什么说得不对, 不好的地方欢迎指出来, 感激不尽!~互相学习!~)
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/86441.html
摘要:前言月份开始出没社区,现在差不多月了,按照工作的说法,就是差不多过了三个月的试用期,准备转正了一般来说,差不多到了转正的时候,会进行总结或者分享会议那么今天我就把看过的一些学习资源主要是博客,博文推荐分享给大家。 1.前言 6月份开始出没社区,现在差不多9月了,按照工作的说法,就是差不多过了三个月的试用期,准备转正了!一般来说,差不多到了转正的时候,会进行总结或者分享会议!那么今天我就...
摘要:特意对前端学习资源做一个汇总,方便自己学习查阅参考,和好友们共同进步。 特意对前端学习资源做一个汇总,方便自己学习查阅参考,和好友们共同进步。 本以为自己收藏的站点多,可以很快搞定,没想到一入汇总深似海。还有很多不足&遗漏的地方,欢迎补充。有错误的地方,还请斧正... 托管: welcome to git,欢迎交流,感谢star 有好友反应和斧正,会及时更新,平时业务工作时也会不定期更...
摘要:另外,单页应用因为数据前置到了前端,不利于搜索引擎的抓取。所以我们需要对自己的单页应用进行一些优化。 前言 最近秋招之余空出时间来按自己的兴趣动手做了一个项目,一个基于vue-cli3.0, vue,typescript的移动端pwa,现在趁热打铁,将这个项目从开发到部署整个过程记录下来,并将从这个项目中学习到的东西分享出来,如果大家有什么意见或补充也可以在评论区提出。先介绍一下这个项...
阅读 1441·2021-10-18 13:29
阅读 2625·2021-10-12 10:18
阅读 3563·2021-09-22 15:06
阅读 2584·2019-08-29 17:09
阅读 2762·2019-08-29 16:41
阅读 1473·2019-08-29 13:48
阅读 3212·2019-08-26 13:49
阅读 3294·2019-08-26 13:34