eggjs 是一个优秀的 Node.js 框架

概述:为什么标题上说 eggjs 是一个优秀的 Node.js 框架(可跳过)?

换言之,我们为什么选择 eggjs 进行开发而不是之前初学时使用的 Express 框架呢?

  Express 是最著名的 Node.js 框架,它甚至是官方唯一推荐过的(目前)

  但是根据实际开发,我觉得它的配置相当冗长,比方说:它可以一句 app.use() 布满长达数十行

  这一点,我没法继续使用下去,所以就停止对它的学习。

就配置方面来说: eggjs 做得很好,它通过开发约束,将所有的配置文件放置在 config 文件中。

起初加载时便进行逐一对服务器进行设置,后设置的将会覆盖之前的。配置则是基于 类似 json 一样的写法,这使得我们容易定位某一处配置并进行修改(因为 key 不能重复,检索一下就知道在哪了)

同样的,eggjs 拥有大量的插件,开发者需要怎样的功能,在官方插件上几乎都可以找到。

如果没有找到所需插件,eggjs 也支持定制。

在这里可以找到官方 API 以及使用文档:https://eggjs.org/zh-cn/

不再进行多说了,让我们开始进行一个 eggjs 框架工程吧(跟官方的有些不同,按照官方的快速入门,总是遇到莫名其妙的错误)

官方的错误,配置让我耗费了三四个小时才得以真正明白框架的使用方法,希望你看完这篇文章,只需半小时就能写出一个高质量的项目

1.1 使用 脚手架 进行初步的工程目录建立

这一步也是所有基于 Node.js 工程所必备的环节之一:当然,你也可以手动创建。

打开 DOS / 终端 ,使用以下命令转到你需要存放的项目位置(这里是我的项目存放位置):

cd C:\Users\chong\Documents\NodeJS

我是在 Windows 系统下的 “文档” 中创建了一个 NodeJS 目录,它将是我用于所有 Node 项目的根目录。

创建一个项目文件夹并进入( project 是项目名称,可更改):

mkdir project && cd project

在这里,开始进行 脚手架 的初始化和安装依赖并进行启动:

# 初始化目录(会创建必备的文件夹和JS,package.json 文件)
npm init egg --type=simple
# 安装依赖
npm i

执行初始化目录的时候,需要你填写一些信息,这些信息最终都会导入 package.json 配置文件中。

红框是 eggjs 初始化时创建的文件以及文件夹,后续我们再来了解它们的作用【重要】

而箭头所指的则是需要填写的信息,例如项目名称,描述信息,作者以及 Cookie 密钥

现在,你已经得到了一个较为完整的目录结构(我已经运行过几次,比刚创建的还多了一些文件,不必在意):

好了,再启动项目,这里有几种启动方式:

# 启动项目
npm run dev npm start

npm start 属于生产环境中使用,使用这种方式的话,需要打印信息输出到控制台就看不到了。

而 npm run dev 是开发中所推荐的启动方式,当你修改代码时,则不必手动重启服务器,eggjs 会自己重启,你只需要等待一会就可以在浏览器看到相对应的修改。

重要的是:你随时可以在代码中写上 console.log ,控制台也会有相应的显示。

下方是多种启动或测试的命令( package.json ),均在前方加入 npm 即可使用。

也可以修改它们,如果你需要换个端口,例如 dev,修改为 egg-bin dev --port 8081 (注意:两个 - 符号)

启动完成后,在浏览器中访问 DOS / 终端 显示的路径(红色箭头):

黄色部分是被修改的文件,在这里不必理会。

到这里,你的初始化工作已经做完,不妨休息会,再继续往下阅读。

1.2 了解各个目录、文件的作用以及 eggjs 如何处理它们

相信你已经成功初始化了吧,现在让我们来了解 eggjs 的目录结构,各个文件的作用:

重新回到之前的一张图,我们可以清晰地看见 eggjs 到底创建了什么。

前一些以 . 开头的文件我们不必理会,从 package.json 文件开始(我们已经知道这是配置文件),往下看:

它创建了两个文件夹,分别是: app、config (test 属于测试,如单元测试等,我们也不必理会)

app 是网站处理用户请求,以及浏览器请求服务器资源的应用文件夹

它包含:router(路由文件)、controller(处理器)

是的,初始化就这么两个,所以我建议在 app 目录下再手动创建以下几个文件夹:

public(存放静态资源,如 css、js、img)

view (存放视图文件)

service(处理数据等业务操作)

先来详细说说路由文件,所有的网站都会有一个访问地址,路由则是客户端首先进入位置:

客户端(浏览器)会发送一个请求,这个请求将会首先进入路由分发文件,匹配成功到某一个 处理器(Controller)后

这个处理器将会去进行相关业务操作(Service)拿到数据,之后 view 渲染一个页面成功后一层层返还回去。

controller 文件夹下则放置着我们所有核心的网站代码(后续解释)

任何一个网站都需要进行配置,而所有的 Web服务器 都应该自身有创建环境的能力,而不是人为去为这个服务器配置好环境。

那么 config 文件夹就是为此而生。

由前面得知:eggjs 有着丰富的插件,所以必然有一个插件的管理、配置文件,它就是 plugin.js

后续我们将知道一个插件应该怎样启用,关闭,安装,这里先不说明;

eggjs 最重要的配置文件则是 :config.default.js,它管理着整个 Node服务器 的所有配置,包括插件、Cookie安全密钥、视图渲染等等配置。

好了,看到这里你已经对生成的 eggjs 项目工程有了一个大致的了解(我昨天才接触 node.js ,若有不对,望在评论中指出,我会进行修改,多谢)

1.3  了解一个请求是如何被处理的【重要】

读完前面,你已经明白:eggjs 工程中的目录,文件的作用(只介绍了部分),现在让我们来深入了解代码层次上,eggjs 如何处理用户请求(不解析源码,从生成的文件来看):

先来了解路由文件怎样工作(建议所有的路由设计都放在一个文件中):

'use strict';

/**
* @param {Egg.Application} app - egg application
*/
module.exports = app => { const { router, controller } = app; router.get('/', controller.main.index);
};

router.get() 方法指的是 GET 请求。

第一个参数表示 URL,例如 www.cnblogs.com 是域名,那么 www.cnblogs.com/index 中的  / 开始,则都是该网站下的‘路由’

第二个参数表示 controller 文件夹下的 main.js 中的 index 方法【重要】,如下:

'use strict';

const Controller = require('egg').Controller;

class MainController extends Controller {
async index() {
this.ctx.body = '<h1>Hello world</h1>';
}
} module.exports = MainController;

所以,你会在浏览器的窗口中看见:

看,你已经知道它的请求过程了!先在 router.js 文件中找到用户请求的位置,而网站进入默认是 /

所以我们已经捕获到了这次请求,之后根据路由文件的描述找到 controller 文件夹下的 main 文件,在从中检索到 index 方法

这个方法设置了body,让它输出一个 h1 标签,写上 Hello world 。

即 router -> controller.main.index()

但是这样的网站根本不具备使用能力,留不住用户,我们还需要根据不同用户数据,渲染一个好看的页面给用户。

这时,我们就可以知道 eggjs 插件的强大之处了(再缓缓,梳理下阅读到的知识,准备好了再继续了解吧)。

1.4 通过模板引擎渲染页面

eggjs 强大的插件足以使你在 Node服务器 上做到与其它Web服务器不同的体验

先述说模板引擎,之后,让我们了解一下网站多语言一键配置。

以 Nunjucks 模板引擎为例:

首先引入两个插件:egg-view、egg-view-nunjucks

npm i egg-view -save

npm i egg-view-nunjucks -save

之后打开 config/config.default.js 文件:

'use strict';

const path = require('path');

module.exports = appInfo => {
return {
// Cookie 安全密钥
keys: "_skfhj8546542354.16554",
// 项目日志存放文件夹
logger: {
dir: path.join(appInfo.baseDir, 'logs'),
},
// 渲染模板配置
view: {
// 配置视图根路径
root: path.join(appInfo.baseDir, 'app/view'),
// 是否缓存路径
cache: true,
// 配置文件默认扩展名
defaultExtension: '.nj',
// 默认渲染模板引擎
defaultViewEngine: 'nunjucks',
// 文件映射配置
mapping: {
'.nj': 'nunjucks'
}
}
};
};

我已经注明了各个属性的作用,可复制到你的文件中。

之后启用插件:egg-view-nunjucks,打开 config/plugin.js 文件

'use strict';

/**
* 模板引擎:用于渲染页面数据
*/
exports.nunjucks = {
enable: true,
package: 'egg-view-nunjucks',
};

配置方面已经准备完毕,之后需要在 app/view 目录下创建一个 index.nj 模板文件

<html>
<head>
<title>{{ page_title }}</title>
</head>
<body>
<h1>{{ page_content }}</h1>
</body>
</html>

双括号是模板引擎的语法之一,还有循环等(是不是觉得跟 jsp 差不多)

好了,让我们修改 controller/main.js 文件

'use strict';

const Controller = require('egg').Controller;

class MainController extends Controller {
async index() {
const { ctx } = this; await ctx.render('index',{
page_title : "标题",
page_content : "模板引擎所渲染的页面"
});
}
} module.exports = MainController;

注意:请加上 await 关键字,它表示等待一个 Promise 对象,如果不加上,会出现 404 错误,

因为在渲染过程中,处理器却返回了结果(没数据的结果),自然客户端也会认为服务器没有找到资源。

现在已经跟我们所想的一致,那么到这里,你已经具备了开发一个项目的能力;

之后会逐步介绍数据库连接,数据处理等方法。敬请期待。

1.4.1  多语言配置(将会引用一些官方例子)

多语言显示(按需配置),很简单,基于插件扩展能力,我们首先在 config.default.js 中增加配置,完整看起来是这个样子的:

'use strict';

const path = require('path');

module.exports = appInfo => {
return {
// Cookie 安全密钥
keys: "_tourism_2650159865482545.265",
// 项目日志存放文件夹
logger: {
dir: path.join(appInfo.baseDir, 'logs'),
},
// 渲染模板配置
view: {
// 配置视图根路径
root: path.join(appInfo.baseDir, 'app/view'),
// 是否缓存路径
cache: true,
// 配置文件默认扩展名
defaultExtension: '.qyml',
// 默认渲染模板引擎
defaultViewEngine: 'nunjucks',
// 文件映射配置
mapping: {
'.qyml': 'nunjucks'
}
},
// 多语言配置
i18n: {
// 默认语言,默认 "en_US"
defaultLocale: 'zh-CN',
// URL 参数,默认 "locale"
queryField: 'locale',
// Cookie 记录的 key, 默认:"locale"
cookieField: 'locale',
// Cookie 的 domain 配置,默认为空,代表当前域名有效
cookieDomain: '',
// Cookie 默认 `1y` 一年后过期, 如果设置为 Number,则单位为 ms
cookieMaxAge: '1y',
}
};
};

第二步:将 egg-i18n 插件进行安装,并写入项目配置文件中

npm i egg-i18n -save

最新版的 eggjs 中默认开启多语言插件,所以我们不必手动启用。

之后在 config 目录下创建一个 locale 文件夹【重要:拼写一定要正确】

在 locale 文件夹中创建所需配置的语言文件(图仅示例两种),可以是 JSON 文件,也可以是 JS 文件,大概是这样的(我的是 JS 格式):

所有的多语言开发都会基于一种语言,我以英语为例(国际化也都是英语):

zh-CN.js 是这样配置的(用官方的例子):

module.exports = {
"Email": "邮箱",
"Welcome back, %s!": "欢迎回来,%s!"
};

如果你是基于 JSON 文件,也就是 zh-CN.json ,那么编写是这个样子的:

{
"Email": "邮箱",
"Welcome back, %s!": "欢迎回来,%s!"
}

就算是英语也需要配置:

en_US.js 会是这样编写的:

module.exports = {
"Email": "Email",
"Welcome back, %s!": "Welcome back,%s!"
};

至于 %s %d 之类的 format 标识,它们的作用是这样的(引用官方例子):

// config/locale/zh-CN.js
module.exports = {
'Welcome back, %s!': '欢迎回来,%s!',
}; ctx.__('Welcome back, %s!', 'Shawn');
// zh-CN => 欢迎回来,Shawn!
// en-US => Welcome back, Shawn!

好了,一切准备就绪,如果需要在 Controller 中直接输出,需要调用 __ 方法进行转义,注意是两个下斜杠,不是让你填空...

class HomeController extends Controller {
async index() {
const ctx = this.ctx;
ctx.body = {
message: ctx.__('Welcome back, %s!', ctx.user.name)
// 或者使用 gettext,gettext 是 __ 函数的 alias
// message: ctx.gettext('Welcome back', ctx.user.name)
user: ctx.user,
};
}
}

在视图模板中这样使用,假设你是 nunjucks 模板引擎:

<html>
<head>
<title>{{ page_title }}</title>
</head>
<body>
<h1>{{ __('Welcome back, %s!', page_content) }}</h1>
</body>
</html>

经过处理后,我们将得到这样的页面效果:

现在你也可以开发一个支持多语言的网站了,我所示例的都是基础代码,关于多语言支持请参考以下网址:

https://eggjs.org/zh-cn/core/i18n.html

今天就到这里了,后续会出一些插件使用,或者是可以快速开发的方法。

2020-2-11 写于揭阳

转载请附上本博客地址:https://www.cnblogs.com/chongsaid/ 或当前文章链接,否则视为侵犯著作权。

初探 Node.js 框架:eggjs (环境搭配篇)的更多相关文章

  1. Node.js安装及环境配置之Windows篇

    Node.js安装及环境配置之Windows篇   一.安装环境 1.本机系统:Windows 10 Pro(64位)2.Node.js:v6.9.2LTS(64位) 二.安装Node.js步骤 1. ...

  2. Node.js安装及环境配置之Windows篇(转:https://www.cnblogs.com/zhouyu2017/p/6485265.html)

    Node.js安装及环境配置之Windows篇(原文地址:https://www.cnblogs.com/zhouyu2017/p/6485265.html)   一.安装环境 1.本机系统:Wind ...

  3. Node.js最新技术栈之Promise篇

    前言 大家好,我是桑世龙,github和cnodejs上的i5ting,目前在天津创业,公司目前使用技术主要是nodejs,算所谓的MEAN(mongodb + express + angular + ...

  4. Node.js 框架

    Node.js的是一个JavaScript平台,它允许你建立大型的Web应用程序.  Node.js的框架平台使用JavaScript作为它的脚本语言来构建可伸缩的应用. 当涉及到Web应用程序的开发 ...

  5. Ubuntu 14.04下搭建Node.js的开发环境

    最近想找一个轻量级且支持快速开发的服务开发平台,选来选去选择了Node.js,当时有几种选择: Python + Django(用过Django,虽然开发快速,但是感觉性能并不太好). Ruby + ...

  6. 不可错过的Node.js框架

    前言 Node.js是由Ryan Dahl于2009年创建的.它是一个开源的跨平台运行时环境,用于开发服务器端和网络应用程序,它是基于Google Chrome V8 JavaScript引擎构建的. ...

  7. 13 款惊艳的 Node.js 框架——第2部分

    [编者按]本文作者为 Peter Wayner,主要介绍13款至精至简的 Node.js 框架,帮助你简化高速网站.丰富 API 以及实时应用的开发流程.本文系国内 ITOM 管理平台 OneAPM ...

  8. 【转】node.js框架比较

    我偶然间看到这篇文章,转这个文章并没有什么含义,仅仅是感觉总结的不错,对于新学node的友友们来说希望这篇文章为大家对 Node.js 后端框架选型带来一些帮助,学习不再迷茫,也是让我有个保存,以后参 ...

  9. 《Node.js入门》CentOS 6.5下Node.js Web开发环境搭建笔记

    近期想尝试一下英特尔的基于WebRTC协同通信开发套件,所以须要在本地搭建Node.js Web的开发測试环境. 这里讲的是CentOS 下的搭建方法.使用Windows的小伙伴请參考: <No ...

随机推荐

  1. 「Poj1845」Sumdiv 解题报告

    题面戳这里 啥都别看,只是求 \(a^b\)所有的因数的和 思路: 真没想到! 其实我们可以先将\(a^b\)分解成质因数的 因为\(a^b\)的因数肯定是\(a^b\)的质因数在一定的条件下相乘而成 ...

  2. Elasticsearch调优篇-慢查询分析笔记

    前言 elasticsearch提供了非常灵活的搜索条件给我们使用,在使用复杂表达式的同时,如果使用不当,可能也会为我们带来了潜在的风险,因为影响查询性能的因素很多很多,这篇笔记主要记录一下慢查询可能 ...

  3. ASP.NET Core Web程序托管到Windows 服务

    前言 在 .NET Core 3.1和WorkerServices构建Windows服务 我们也看到了,如何将workerservices构建成服务,那么本篇文章我们再来看看如何将web应用程序托管到 ...

  4. Office系列(1)---将Office文件(Word、PPT、Excel)转换为PDF文件

    需求: 将Office文件作为文章并在网页上预览,主要为(Word.PPT.Excel)3种类型文件. 研究了一下,找到了两种解决方案 直接调用微软的在线预览功能实现(预览前提:预览资源必须可以直接通 ...

  5. JVM系列七(JIT 即时编译器).

    一.概述 即时编译器(Just In Time Compiler),也称为 JIT 编译器,它的主要工作是把热点代码编译成与本地平台相关的机器码,并进行各种层次的优化,从而提高代码执行的效率. 那么什 ...

  6. Milking Cows 挤牛奶 USACO 排序 模拟

    1005: 1.2.1 Milking Cows 挤牛奶 时间限制: 1 Sec  内存限制: 128 MB提交: 15  解决: 9[提交] [状态] [讨论版] [命题人:外部导入] 题目描述 1 ...

  7. 如何实施DevOps

    对于长期在孤立的架构下工作的组织来说,转移到协作式DevOps系统似乎是难以成功的.为了进一步提高效率,必须改变观念,并进行团队文化改变.例如:许多人认为只有自动化工具才能解决DevOps,其实这是不 ...

  8. 曹工说Spring Boot源码(12)-- Spring解析xml文件,到底从中得到了什么(context:component-scan完整解析)

    写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...

  9. 安装xpath helper

    1.下载 版本是:2.02的 链接:https://pan.baidu.com/s/1YdyTbWElL904EMQ-9Ougnw 提取码:bxxa 2.无效安装的解决方案 参考链接:https:// ...

  10. 部署Maven项目到tomcat报错:java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderLi

    Maven项目下update maven后Eclipse报错:java.lang.ClassNotFoundException: ContextLoaderL     严重: Error config ...