Heim >Web-Frontend >js-Tutorial >Detaillierte Erläuterung des Front-End-Frameworks ThinkJS-Framework
In diesem Artikel wird hauptsächlich das Front-End-Framework ThinkJS erläutert. Thinkjs ist ein schnelles und einfaches, leichtes Node.js-Entwicklungsframework, das auf MVC basiert und objektorientiert ist und unter der MIT-Lizenz veröffentlicht wird. Unter Einhaltung des Designprinzips der Einfachheit und Benutzerfreundlichkeit bei gleichzeitiger Beibehaltung hervorragender Leistung und minimalem Code konzentriert es sich auf Entwicklungserfahrung und Benutzerfreundlichkeit und bietet starke Unterstützung für die Entwicklung von WEB-Anwendungen.
Viele Funktionen in Thinkjs sind von ThinkPHP abgeleitet. Gleichzeitig werden Promise, WebSocket und andere Funktionen verwendet, um den Code prägnanter und eleganter zu gestalten. Das größte Merkmal ist, dass es derzeit beliebte Grammatikfunktionen wie es6, es7, Typescript usw. hervorragend unterstützt. Damit werden auch Funktionen wie aysnc/await unterstützt, was den Code modischer macht.
Installieren Sie das Befehlszeilentool:
$ npm install -g thinkjs
Erstellen Sie dann ein neues Projekt mit der neuen Demo von thinkjs. Um sicherzustellen, dass vorhandene Dateien aufgrund von Benutzerfehlern überschrieben werden, gilt der Befehl thinkjs new nur für Ordner, die nicht vorhanden oder leer sind. Andernfalls wird der folgende Fehler gemeldet:
path `/data/www/demo` is already a thinkjs project.
Die Implementierung dieser Funktion basiert tatsächlich auf einer versteckten Datei .thinkjsrc im Stammverzeichnis des Projekts. Verwenden Sie ls -a, um die versteckte Datei anzuzeigen Wenn Sie diese Datei öffnen, können Sie den folgenden Inhalt sehen:
{ "createAt": "2017-02-12 19:08:38", "mode": "module", "es": true}
Nach Verwendung des Befehls beginnt das System mit dem Erstellen des Projekts:
$ thinkjs new demo create : demo create : demo/package.json create : demo/.babelrc create : demo/.thinkjsrc create : demo/nginx.conf create : demo/pm2.json create : demo/.gitignore create : demo/README.md create : demo/www create : demo/www/development.js create : demo/www/production.js create : demo/www/testing.js create : demo/www/README.md create : demo/www/static create : demo/www/static/js create : demo/www/static/css create : demo/www/static/img create : demo/src create : demo/src/common/bootstrap create : demo/src/common/bootstrap/middleware.js create : demo/src/common/bootstrap/global.js create : demo/src/common/config create : demo/src/common/config/config.js create : demo/src/common/config/view.js create : demo/src/common/config/db.js create : demo/src/common/config/hook.js create : demo/src/common/config/session.js create : demo/src/common/config/error.js create : demo/src/common/config/env create : demo/src/common/config/env/development.js create : demo/src/common/config/env/testing.js create : demo/src/common/config/env/production.js create : demo/src/common/config/locale create : demo/src/common/config/locale/en.js create : demo/src/common/controller create : demo/src/common/controller/error.js create : demo/view/common create : demo/view/common/error_400.html create : demo/view/common/error_403.html create : demo/view/common/error_404.html create : demo/view/common/error_500.html create : demo/view/common/error_503.html create : demo/src/home/config create : demo/src/home/config/config.js create : demo/src/home/controller create : demo/src/home/controller/base.js create : demo/src/home/controller/index.js create : demo/src/home/logic create : demo/src/home/logic/index.js create : demo/src/home/model create : demo/src/home/model/index.js create : demo/view/home create : demo/view/home/index_index.html enter path: $ cd demo install dependencies: $ npm install run the app: $ npm start
Beim Erstellen ist darauf zu achten Bei einem neuen Projekt ist viel Babel erforderlich, sodass der Projektaufbau langsamer wird. Zu den abhängigen Paketen gehören hauptsächlich:
"dependencies": { "thinkjs": "2.2.x", "babel-runtime": "6.x.x", "source-map-support": "0.4.0" },
.├── README.md ├── app │ ├── common │ │ ├── bootstrap │ │ ├── config │ │ └── controller │ └── home │ ├── config │ ├── controller │ ├── logic │ └── model ├── nginx.conf ├── package.json ├── pm2.json ├── src │ ├── common │ │ ├── bootstrap │ │ ├── config │ │ └── controller │ └── home │ ├── config │ ├── controller │ ├── logic │ └── model ├── tree.txt ├── view │ ├── common │ │ ├── error_400.html │ │ ├── error_403.html │ │ ├── error_404.html │ │ ├── error_500.html │ │ └── error_503.html │ └── home │ └── index_index.html └── www ├── README.md ├── development.js ├── production.js ├── static │ ├── css │ ├── img │ └── js └── testing.js388 directories, 1381 files
1) Startbefehl
npm start
Dann verwenden Sie „Was hat das System nach dem Start gemacht?“
"scripts": { "start": "node www/development.js", "compile": "babel src/ --out-dir app/", "watch-compile": "node -e \"console.log('<npm run watch-compile> no longer need, use <npm start> command direct.');console.log();\"", "watch": "npm run watch-compile" },
Verwenden Sie Node, um www/development.js auszuführen. Thinkjs verwendet 3 Umgebungen:
Entwicklung Modus
Produktion Online-Modus
Testen Testmodus
thinkjs behandelt www als das Knotenprojekt Verzeichnis, und static unter www ist das statische Ressourcendateiverzeichnis. Das Verzeichnis www/development.js lautet wie folgt:
var instance = new thinkjs({ APP_PATH: rootPath + path.sep + 'app', RUNTIME_PATH: rootPath + path.sep + 'runtime', ROOT_PATH: rootPath, RESOURCE_PATH: __dirname, env: 'development'});
Natürlich können Sie den Befehl „tree src -L 3“ verwenden, um das Projektverzeichnis anzuzeigen:
$ tree src -L 3 src ├── common │ ├── bootstrap │ │ ├── global.js │ │ └── middleware.js │ ├── config │ │ ├── config.js │ │ ├── db.js │ │ ├── env │ │ ├── error.js │ │ ├── hook.js │ │ ├── locale │ │ ├── session.js │ │ └── view.js │ └── controller │ └── error.js ├── home │ ├── config │ │ └── config.js │ ├── controller │ │ ├── base.js │ │ └── index.js │ ├── logic │ │ └── index.js │ └── model │ └── index.js16 directories, 19 files
Die allgemeine Modulkonfiguration (später) wird speziell berücksichtigt):
$ thinkjs module topic(能创建不能删除,略遗憾) create : src/topic/config create : src/topic/config/config.js create : src/topic/controller create : src/topic/controller/base.js create : src/topic/controller/index.js create : src/topic/logic create : src/topic/logic/index.js create : src/topic/model create : src/topic/model/index.js exist : /Users/sang/workspace/github/nodewebframework/demo/view/topic/index_index.html
Zu diesem Zeitpunkt ist die Verzeichnisstruktur wie folgt:
src ├── common ├── home └── topic
3) Geschäftsmodulverzeichnis
├── home │ ├── config │ │ └── config.js │ ├── controller │ │ ├── base.js │ │ └── index.js │ ├── logic │ │ └── index.js │ └── model │ └── index.js
4) Routing und Ansichtsidentifikation Die Routenidentifikation basiert standardmäßig auf Modul/Controller/Betrieb/Parameter 1/Parameter 1-Wert/Parameter 2/Parameter 2-Wert. Es handelt sich eigentlich um eine Konvention.
Zum Beispiel/geparst als:
Das Standardmodul ist Home
Das Steuerelement ist Index
Die Operation ist indexAction
Was ist, wenn es noch eine gibt?
'use strict';import Base from './base.js';export default class extends Base { /** * index action * @return {Promise} [] */ indexAction(){ //auto render template file index_index.html return this.display(); } myAction(){ //auto render template file index_index.html return this.display(); }}
myAction hinzufügen und einen Fehler melden [Fehler] Fehler: Vorlagendatei /Users/sang/workspace/github/nodewebframework/demo/view/home/index_my.html kann nicht gefunden werden
Kopieren Sie view/home/index_index.html nach view/home/index_my.html. Das Prinzip ist, dass my dem Modul index_my.html entsprechen sollte. Das heißt, der Index ist der Controller und mein Wert ist die Aktion.
Nachdem Sie dies verstanden haben, werden Sie denken, dass die Benennung von index_index nicht sehr seltsam ist. Der Rest ist das Schreiben von Ansichten usw., was hier nicht beschrieben wird.
Wie bereits erwähnt, ist die Entwicklungsphase in Babel geschrieben, sodass die Effizienz nicht sehr hoch sein wird.
$ autocannon -c 100 -d 5 -p 10 localhost:8360Running 5s test @ http://localhost:8360100 connections with 10 pipelining factor Stat Avg Stdev Max Latency (ms) 108.9 201.32 866 Req/Sec 891.8 148.37 1000 Bytes/Sec 417.79 kB 50.76 kB 458.75 kB 4k requests in 5s, 2.09 MB read
Es ist ein bisschen elend, nicht wahr? Dies ist jedoch der Entwicklungsmodus, und wir müssen ihn im Online-Produktionsmodus testen.
$ npm run compile $ node www/production.js $ autocannon -c 100 -d 5 -p 10 localhost:8360Running 5s test @ http://localhost:8360100 connections with 10 pipelining factor Stat Avg Stdev Max Latency (ms) 61.76 124.71 763 Req/Sec 1567.2 734.94 1993 Bytes/Sec 679.12 kB 242.25 kB 884.74 kB 8k requests in 5s, 3.4 MB read $ autocannon -c 100 -d 5 -p 10 localhost:8360Running 5s test @ http://localhost:8360100 connections with 10 pipelining factor Stat Avg Stdev Max Latency (ms) 54.65 105.47 707 Req/Sec 1813.4 368.21 1999 Bytes/Sec 807.73 kB 156.09 kB 917.5 kB 9k requests in 5s, 4.09 MB read $ autocannon -c 100 -d 5 -p 10 localhost:8360Running 5s test @ http://localhost:8360100 connections with 10 pipelining factor Stat Avg Stdev Max Latency (ms) 54.14 89.81 465 Req/Sec 1816.4 319.14 2000 Bytes/Sec 914.23 kB 145.96 kB 1.05 MB 9k requests in 5s, 4.55 MB read
Die gleiche Funktion wird unten in Form einer Express + EJS-Vorlage ausgedrückt.
$ autocannon -c 100 -d 5 -p 10 localhost:3000Running 5s test @ http://localhost:3000100 connections with 10 pipelining factor Stat Avg Stdev Max Latency (ms) 53.85 177.72 1309 Req/Sec 1728 385.85 2075 Bytes/Sec 702.87 kB 159.56 kB 851.97 kB 9k requests in 5s, 3.53 MB read $ autocannon -c 100 -d 5 -p 10 localhost:3000Running 5s test @ http://localhost:3000100 connections with 10 pipelining factor Stat Avg Stdev Max Latency (ms) 46.06 141.52 739 Req/Sec 2061.2 320.53 2275 Bytes/Sec 842.14 kB 134.95 kB 950.27 kB 10k requests in 5s, 4.2 MB read $ autocannon -c 100 -d 5 -p 10 localhost:3000Running 5s test @ http://localhost:3000100 connections with 10 pipelining factor Stat Avg Stdev Max Latency (ms) 45.97 139.58 620 Req/Sec 2059.4 122.93 2167 Bytes/Sec 829.03 kB 52.43 kB 884.74 kB 10k requests in 5s, 4.2 MB read
Nach dem Erstellen des Projekts wurde das grundlegende Code-Framework eingerichtet, und das Standard-Home und Common können die Anforderungen definitiv nicht erfüllen. Wir müssen eine relevante hierarchische Struktur für unsere Projekte etablieren. Hier sind einige gängige Modulklassifizierungsmethoden. Nur als Referenz.
Offizielle Website, Blog, Community usw. Diese Art von Systemstruktur ist relativ einfach und normalerweise kann ein Front-End- und ein Back-End-Management die Anforderungen erfüllen. Normalerweise muss es die folgenden Module umfassen:
src/src/common/ # 通用模块,放置主配置参数、boostrap adapter middleware service 等相关组件 src/home/ # 前端默认模块 src/backend/ # 后端管理模块 src/util/ # 系统工具类
Das E-Commerce-Plattformsystem berücksichtigt hauptsächlich die Benutzer von ansässigen Händlern, registrierten Kunden, Managern und Betreibern usw. Es muss auch die Segmentierung größerer Funktionsmodule in Betracht gezogen werden (wenn es groß genug ist, um ein System ähnlich JD.com und Tmall zu sein, muss es nach Daten, Funktionen, Diensten, Standorten usw. segmentiert werden).
src/src/common/src/home/src/sso/ # 单点登录、令牌管理等 src/rest/ # 针对Wap、App等多客户端的 rest api src/goods/ # 商品管理及服务 src/storage/ # 库存管理及服务 src/cart/ # 购物车 src/order/ # 订单 src/delivery/ # 快递 src/pay/ # 在线支付、空中支付 src/member/ # src/coupon/ # 电子券 src/promotion/ # 促销 src/points/ # 积分 src/merchant/ # 入驻商户 src/shop/ # 商户门店 src/finance/ # 财务核算及款项清算 src/stat/src/log/src/monitor/src/util/src/task/src/message/ # 消息队列
Die Echtzeit-Push-Plattform verwaltet nicht nur WebSocket-Verbindungen sowie das Horten und Senden von Nachrichten, sondern auch den Mehrbenutzerkauf entsprechender Servicepakete, zählt Verbindungen, zählt den Downstream-Verkehr, führt eine Verbindungsauthentifizierung durch usw. Die in der Regel enthaltenen Module sind wie folgt:
src/src/common/src/home/src/rest/src/storage/src/websocket/ # ws 或者 wss 服务 src/webhook/ # 钩子服务 src/middleware/ # 搭载中间件运行 src/pay/src/member/src/stat/src/log/src/monitor/src/util/src/message/ # 消息队列
Online-Bildung oder Live-Übertragungsplattformen stellen normalerweise strenge Anforderungen wie das Hochladen von Audio- und Videoinhalten in Echtzeit und die Transkodierung , Speicherung und Übertragung, sodass das System nicht nur die zugehörigen Kursmaterialien, Studenten, Lehrer, Kursauswahlen usw. verwaltet, sondern auch für die Verarbeitung der zugehörigen Mediendateien verantwortlich ist.
src/src/common/src/home/src/rest/src/sso/ # 单点登录、令牌管理等 src/media/ # 课件、音视频等媒体文件 src/bulk/ # 流媒体 src/process/ # 编解码处理 src/storage/src/live/ # 直播 src/pay/src/student/src/teacher/src/schedule/src/stat/src/log/src/monitor/src/util/src/task/src/message/ # 消息队列
Die offizielle Website beschreibt die Ladesequenz der Konfigurationsdatei wie folgt: Framework-Standardkonfiguration-> Framework-Konfiguration im Projektmodus-> Projekt Modus Öffentliche Konfiguration unter -> Konfiguration unter Modul.
第三个和第四个则是在不同的项目创建模式下的默认 config 配置文件夹,位置在:
# normal mode thinkjs_normal/src/config/* # module mode thinkjs_module/src/common/config/*
最后一个是指的在 module mode 下的项目,每个 module 自己的 config,位置在:
thinkjs_module/src/home/config/*
明白了多个地方多个配置文件的玩法之后,你可以创建多个 module,并给每个 module 配置自身独特的配置参数。
需要注意的是:thinkjs 加载配置文件是有顺序的!!!多个配置文件最终会在 thinkjs 运行时被全部加载,并合并在一起。所以当存在多个配置文件时,需要注意配置参数的 key(即属性名)尽量不要重复,因为按照加载顺序,后加载的 key 的值会覆盖先加载的 key 的值,导致出现不希望的结果。
举例来说,有两个配置文件 src/common/config/assets.js 和 src/home/config/assets.js,
// src/common/config/assets.jsexport default { "site_title": "my site"};// src/home/config/assets.jsexport default { "site_title": "my test"};// src/home/controller/index.jslet assets = this.config('assets');let siteTitle = assets['site_title'];console.log('siteTitle is: ', siteTitle); // my test
开发时的工作代码都在 src 下面,运行时才会编译到 app 下面成为运行脚本(经过 Babel 编译),如果不想自己写的各种注释也出现在 app 下面的代码中,可以修改项目目录下的一个隐藏文件 .babelrc 增加相应 comments 参数。
{ "presets": [ ["es2015", {"loose": true}], "stage-1" ], "plugins": ["transform-runtime"], "sourceMaps": true, "comments": false # <-- 就是这个参数}
目前,thinkJs支持两种控制器:普通的控制器和多级控制器。 支持__before和__after这样的回调钩子,对于app和controller控制来说是非常实用的。使用co来实现也是可圈可点,此处如果使用koa可以更加优雅。例如:
class PathController extends BaseController { constructor(app, ctx, next) { super(app, ctx, next) this.path = '/c' // this.global_filter.push('custom_filter') this.post_filter = [this.log] } before() { } log(ctx, next) { ctx.someText = 'some' // console.log('before') return next().then(function(){ // console.log('after') }) } post(req, res) { console.log(this.ctx.someText) var a = this.reqbody.a return res.body = this.ctx.someText } after() { }}
pm2 (官网 http://pm2.keymetrics.io)是一个优秀的 Node.js 进程管理器。thinkjs 推荐使用 pm2 来管理项目运行,并自动生成了 pm2 的配置文件 pm2.json 。
它的强大之处在于不仅可以作为 Node.js 项目的守护进程,还具备可配置化启动、分布式支持、内存监控、热重载(优雅重载)、支持数据统计、运行日志记录、实时运行监控、API 和脚本支持等强大的特性。
默认生成的 pm2 配置文件不含日志记录部分,如果不单独配置,pm2 的日志将会保存在安装目录中,查找起来很不方便。普遍的做法是:在项目目录下建立 logs 文件夹,用来放置 pm2 以及其他(诸如 log4js 等等)日志,打开 pm2.json ,给 apps[0] 增加如下几行配置参数:
{ "apps": [{ "error_file" : "/data/www/thinkjs_module/logs/pm2-err.log", "out_file" : "/data/www/thinkjs_module/logs/pm2-out.log", "log_date_format" : "YYYY-MM-DD HH:mm:ss Z", "merge_logs" : false }]}
error_file pm2 捕捉到的致命错误记录在这里
out_file pm2 接收到的 console 输出记录在这里
log_date_format 日期和时间格式
merge_logs 是否给日志文件增加进程id的后缀
主要优势:
完全自己实现,对已有框架很少借鉴
内置各种adapter,db,中间件,hook,插件,非常丰富,all in one 比组装更适合新手
遵循mvc和coc
使用最潮的es6/es7/ts特性,对aysnc函数,exports等都非常好的支持
支持i18n等实用功能
内置pm2和nginx集成,部署方便
有自己的脚手架,稍弱
性能不错,虽然比express稍弱,但功能强大许多
测试丰富,代码质量有保障
文档健全,是经过设计的,支持多语言
背后有75团和李成银支持,最近一周内有更新,代码提交2600+,35人贡献,整体来说算健康
Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des Front-End-Frameworks ThinkJS-Framework. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!