入职第二天:使用koa搭建node server是种怎样的体验
今天是我入职第二天,leader跟我说,昨天配置好了服务端渲染的文件,今天就先研究研究如何使用koa来搭建一个node server吧!
按照惯例,我去koa官网查了一下什么是koa,结果官网很简单的一句话介绍:koa--基于node.js平台的下一代web开发框架。
个人感觉koa官方文档对于前端小白来说,写的不是很友好,建议上手之前先看看阮一峰的koa框架教程和廖雪峰写的关于koa入门文章。
然后引入项目第一步,安装koa:
npm i koa -S
安装完之后,首先在项目根目录下新建一个server文件夹,然后在此文件夹下新建一个server.js文件,然后在里面引入koa:
const Koa = require('koa') const app = new Koa() const isDev = process.env.NODE_ENV === 'development'
这里为什么要声明isDev呢?因为服务端渲染是分开发环境和生产环境两种不同的情况。
然后我们继续在server.js里面先写一个中间件来记录所有的请求和抓取的错误,这样可以很好的了解到在服务端渲染的过程中是否出现了一些错误,并及时排查掉错误。
先撸为敬:
app.use(async (ctx, next) => { try { console.log(`request with path ${ctx.path}`) await next() } catch (err) { console.log(err) ctx.status = if (isDev) { ctx.body = err.message } else { ctx.body = 'please try again later' } } })
简单解释一下:在函数前面加一个async,就代表异步处理函数,而参数next表示执行下一个 异步处理的函数。在try循环体内,console打印出请求的路径。如果是isDev为true的情况,可以直接将错误信息写到body里面,这样就可以在页面上直接看到错误信息。如果不是开发环境,可以写一个友善的提醒文字,例如:“please try again later”。
这就是最简单的一个koa中间件,用来记录所有的请求及出现的错误,并且返回一个错误信息。
接下来,聊一聊如何处理服务端渲染。
在处理服务端渲染之前,首先要在terminal里面安装一下koa-router:
npm i koa-router -S
这是koa提供的一个路由的工具。然后在server文件夹下面新建一个routers文件夹,紧接着在里面新建两个文件,一个是dev-ssr.js,另一个是ssr.js。前者是处理开发时服务端渲染的情况,后者是处理正式环境下的情况。
在dev-ssr.js文件中,首先要引入koa-router:
const Router = require('koa-router')
在这里,还需要使用到两个工具,需要安装下:
npm i axios -S npm i memory-fs -D
在node端发送请求的axios,当然也可以在浏览器端发送请求。在安装的时候记住后面跟的是-S,因为在业务代码中可以用到。
而memory-fs只有在开发的时候才会用到,所以后面跟的是-D。可能有童鞋要问了,这个memory-fs是用来干嘛的?别急,闰土给大家截一张官网图片看看便一目了然了:
大意是:一个简单的内存文件系统。将数据保存在JavaScript对象中。
然后,话不多说,先把这两个工具引入进来:
const axios = require('axios') const MemoryFS = require('memory-fs')
紧接着,再来引入两个工具:
const webpack = require('webpack') const VueServerRenderer = require('vue-server-renderer')
因为要在node开发环境中打包代码,并且需要服务端渲染。
接下来,要引入serverConfig,就是入职第一天写的那个配置文件webpack.config.server.js:
const serverConfig = require('../../build/webpack.config.server')
然后,如何能在node开发环境中让webpack跑起来呢?
答案是通过serverCompiler:
const serverCompiler = webpack(serverConfig)
然后去new一个mfs实例:
const mfs = new MemoryFS() serverCompiler.outputFileSystem = mfs
这样就指定了webpack的输出目录在MemoryFS里面。
有了这些配置之后,再去声明一个bundle:
let bundle
用来记录webpack每次打包生成的新的文件。
serverCompiler.watch({}, (err, stats) => { if (err) throw err stats = stats.toJson() stats.erros.forEach(err => console.log(err)) stats.hasWarnings.forEach(warn => console.warn(err)) const bundlePath = path.join( serverConfig.output.path, 'vue-ssr-server-bundle.json' ) bundle = JSON.parse(mfs.readFileSync(bundlePath, 'utf-8')) })
这里使用watch()的好处是:跟使用webpack-dev-server一样,在client目录下每次修改一个文件,它都会重新执行一次打包,然后就可以拿到新的文件了。
serverCompiler.watch()的第一个参数是空对象,第二个参数是一个回调。如果有err直接抛出。
然后stats这块我感觉有点晦涩难懂,leader告诉我说,先照着做,然后有空再去看webpack的文档。
接下来就可以读取生成的bundle文件了,拼接读取文件的路径,设置文件名字,并且制定编码为utf-8,最后通过JSON.parse()将字符串转成JSON。
执行完以上步骤之后,就可以将内容返回给HTML了。
在服务端渲染期间,使用ejs模板引擎生成HTML。通过VueServerRenderer的createBundleRenderer()方法帮助生成一个可以直接调用renderer的函数。在这里面接收几个参数,第一个是inject,设置为false,这样它就不会执行其他的注入的操作了。第二个是clientManifest,它会自动生成一个带有script标签的js文件引用的字符串,这样可以直接添加到ejs的内容里面。
最后,dev-ssr.js的完整代码如下:
const Router = require('koa-router') const axios = require('axios') const path = require('path') const fs = require('fs') const MemoryFS = require('memory-fs') const webpack = require('webpack') const VueServerRenderer = require('vue-server-renderer') const serverConfig = require('../../build/webpack.config.server') const serverCompiler = webpack(serverConfig) const mfs = new MemoryFS() serverCompiler.outputFileSystem = mfs let bundle serverCompiler.watch({}, (err, stats) => { if (err) throw err stats = stats.toJson() stats.erros.forEach(err => console.log(err)) stats.hasWarnings.forEach(warn => console.warn(err)) const bundlePath = path.join( serverConfig.output.path, 'vue-ssr-server-bundle.json' ) bundle = JSON.parse(mfs.readFileSync(bundlePath, 'utf-8')) }) const handleSSR = async (ctx) => { if (bundle) { ctx.body = 'wait a moment...' return } const clientManifestResp = await axios.get( 'http://127.0.0.1:8080/vue-ssr-client-manifest.json' ) const clientManifest = clientManifestResp.data const template = fs.readFileSync( path.join(__dirname, '../server.template.ejs') ) const renderer = VueServerRenderer .createBundleRenderer(bundle, { inject: false, clientManifest }) }
写在最后
这次使用koa搭建node server的体验只是聊到了renderer这一步,后面我会继续聊聊如何把bundle渲染成实际的HTML内容,并把它添加到template里面。最新的文章都会第一时间更新在我的公众号<闰土大叔>里面,欢迎关注。
入职第二天:使用koa搭建node server是种怎样的体验的更多相关文章
- ubuntu下搭建node server的几个坑
[ubuntu下搭建node server的几个坑] 1.环境变量 process.env.PORT需要使用 export PORT=80设置 windows下是set PORT=80 2.命令连结 ...
- GraphQL-- 使用Apollo Server搭建Node服务端
一.关于Apollo Server Apollo Server是一种使用JS创建GraphQL服务端的一个方案.它的兼容性比较好,可以很好地和GraphQL客户端进行兼容.同时它可以 独立作为服务端进 ...
- 分享 koa + mysql 的开发流程,构建 node server端,一次搭建个人博客
前言 由于一直在用 vue 写业务,为了熟悉下 react 开发模式,所以选择了 react.数据库一开始用的是 mongodb,后来换成 mysql 了,一套下来感觉 mysql 也挺好上手的.re ...
- Koa与Node.js开发实战(1)——Koa安装搭建(视频演示)
学习架构: 由于Koa2已经支持ES6及更高版本,包括支持async方法,所以请读者保证Node.js版本在7.6.0以上.如果需要在低于7.6的版本中应用Koa的async方法,建议使用Babel ...
- 【node】用koa搭建一个增删改服务(一)
前文,vue分类里有一个日志demo的练习,这篇文章就是介绍针对日志demo的服务是怎么写的 一.koa搭建项目 1. npm init 2. npm install koa 二.建数据库 下面是项目 ...
- 低代码开发LCDP,Power Apps系列 - 搭建入职选购电脑设备案例
低代码简介 上世纪八十年代,美国就有一些公司和实验室开始了可视化编程的研究,做出了4GL"第四代编程语言",到后来衍生成VPL"Visual Programming La ...
- 入职第一天:前端leader手把手教我入门Vue服务器端渲染(SSR)
继前段时间西安电面之后顺利拿到了OFFER,今天(5月2号)是我入职第一天,在简短的内部培训了一上午后,前端leader让我先了解下什么是vue的服务器端渲染(SSR). SSR,英文全称叫 Serv ...
- Oracle DBA从小白到入职实战应用
现如今Oracle依然是RDBMS的王者,在技术上和战略上,Oracle仍然一路高歌猛进,并且全面引领行业迈入了云时代,伴随着12cR2即将在2016年正式发布,学习Oracle之路依旧任重道远,目前 ...
- 如何在 Windows 10 中搭建 Node.js 环境?
[编者按]本文作者为 Szabolcs Kurdi,主要通过生动的实例介绍如何在 Windows 10 中搭建 Node.js 环境.文章系国内 ITOM 管理平台 OneAPM 编译呈现. 在本文中 ...
随机推荐
- UNIX网络编程——TCP长连接与短连接的区别
一.TCP短连接 我们模拟一下TCP短连接的情况,client向server发起连接请求,server接到请求,然后双方建立连接.client向server发送消息,server回应client,然后 ...
- smack4中文文档
smack4中文文档 基于samck官方最新文档翻译而成,适用于最新的Smack4.x 简介 6月毕业后来到帝都上班,找了一份Android开发的工作,公司开发的APP需要使用XMPP和Smack进行 ...
- printf函数压栈解惑
最近看到一些程序员的笔试题目,经常会考到printf函数的参数压栈问题,总体来讲就是参数从右向左依次压栈,再出栈,但是今天看到一个看似很简单的题目,却一直找不到头绪.题目如下: #include &l ...
- BIP Requests Are Failing With Error "OPP Error Oracle.apps.xdo.XDOException: Error Creating Lock Fil
In this Document Symptoms Cause Solution References Applies to: BI Publisher (formerly XML P ...
- 【翻译】Ext JS最新技巧——2015-1-2
原文:http://www.sencha.com/blog/top-support-tips-january-2015?mkt_tok=3RkMMJWWfF9wsRolvqvIZKXonjHpfsX7 ...
- (NO.00001)iOS游戏SpeedBoy Lite成形记(二十九):增加排行榜功能2
接下来回到Xcode中,首先在PopupLayer.m中添加justClose方法: -(void)justClose{ [self.gameScene removePopup]; } 然后在Game ...
- 使用Android Support Design 控件TabLayout 方便快捷实现选项卡功能
1.概述 TabLayout是在2015年的google大会上,google发布了新的Android Support Design库的新组件之一,以此来全面支持Material Design 设计风格 ...
- 如何让你的传输更安全--基于SSL协议的通信模式
之前发表在另一个平台的文章http://www.jointforce.com/jfperiodical/article/1218,现在发表到自己的博客上. 对于SSL/TLS协议,如果要每个开发者都自 ...
- React Native ios开发第一课
前言 本篇文章的作用在于帮助你快速上手使用React Native编写iOS应用.如果你现在还不太了解React Native是什么以及Facebook为什么要创建React Native,你可以先看 ...
- OC语言(二)
十.匿名对象 即不将对象赋给指针,而是直接使用 注意new对象的时候要用[ ]嵌套 例如:[[Car new] run]; 十一.枚举书写规范 注意空格 //注视 typedef enum { } X ...