node入門からシリーズ放棄まで(11)優雅なコードで私達のkoa 2プロジェクトを武装します.
42225 ワード
コードをお送りします.nodeサービスdemoコード=>koa 2-serverプロジェクトコード;vueフロントエンドdemoコード=>vue-clientプロジェクトコード.ギトが登れないならギtee=>koa 2-serverプロジェクトコードに変えられます.vueフロントエンドdemoコード=>vue-clientプロジェクトコード
本文は参考にします.優雅なコードで私達のkoa 2プロジェクトを武装します.その中の部分を修正して統合しました.
優雅なコードで私達のkoa 2プロジェクトを武装します.ルートの自動ローディング 開発環境と生産環境の区分 統一インターフェースは、フォーマット に戻る.グローバル異常処理ミドル JWTを使用して認証を完了する . nodejs requireパス別名 ルートの自動読み込み
以前は私のルートはいつもマニュアルで登録されていました.
この時は使いやすい依存が必要です.
開発環境と生産環境の区分
時には、2つの異なる環境の下で、私達は異なった処理をしなければならなくて、この時に私達は前倒しで全体の局面の中で相応するパラメーターを注ぎ込む必要があります.
まずプロジェクトのルートディレクトリでconfigフォルダを作成します.
でもこのように問題があります.あなたが生産環境を配置する時、マニュアルでconfig.jsのenvironment配置を修正します.
統一インターフェースを返します.
統一した戻りフォーマットは、先端の処理効率を向上させ、コンポーネント化が開発された今日においても、統一した戻りフォーマットは、先端をより良いパッケージにすることができます.もし一つのプロジェクトの中に同じ返送フォーマットがないなら、このプロジェクトのコードの品質は大体どこに行けばいいですか?
成功と失敗の戻りフォーマットを先に定義します.
サービス端末アプリの作成中、異常処理は非常に重要な一環であり、各関数の結果は私たちが望むものではないからです.文法の誤りであろうと、やはり業務の論理の上の誤りであろうと、すべて異常を投げ出させなければならなくて、問題を最も直観的な方式で暴露させて、直接無視するのではありません.コードのスタイルについては、「コード大全」でも強調されていますが、一つの関数が異常に遭遇した場合、一番いい方法は直接return false/nullではなく、異常を直接に投げ出すことです.異常を直接先端に投げてしまうと、このバックエンドの本当の料理を感じさせます.必ず包装します.
設計異常処理中間件
現在のinit.jsの中ではこうです.
JWTを使って認証を完了します.
これは前シリーズ(7)で専門的に書きましたが、ここでは書きません.本稿で参考にした文章の中で紹介したようにもできます.しかし、リフレッシュtokenの使用が足りないので、空きがあります.
nodejs requireパスの別名
開発の過程で、プロジェクトのディレクトリがますます複雑になると、パッケージの参照経路もますます面倒になります.以前からこのようなインポートパスがありました.
module-aliasを使って経路を別名でいいです.
下一篇:nodeは入門からシリーズの(10)図形の検証の機能を放棄しますまで下一篇:未完は続きます!
本文は参考にします.優雅なコードで私達のkoa 2プロジェクトを武装します.その中の部分を修正して統合しました.
優雅なコードで私達のkoa 2プロジェクトを武装します.
以前は私のルートはいつもマニュアルで登録されていました.
//app.js
const Koa = require('koa');
const app = new Koa();
//
const index = require('./routes/index');
const commom = require('./routes/commom'); //
app.use(index.routes(), index.allowedMethods());
app.use(commom.routes(), commom.allowedMethods());
長い間ルートを開発してきたので、ファイルの数が多くなりました.このようにアメリカ式を導入すると、煩わしいです.これらのファイルが自動的に導入され、自動的にロードされるようにする方法がありますか?この時は使いやすい依存が必要です.
npm install require-directory --save
ルートディレクトリの下にフォルダレコードを作って、後でいくつかの共通コードはここに預けます.//core/init.js
const requireDirectory = require('require-directory');
const Router = require('koa-router');
class InitManager {
static initCore(app) {
// app.js koa
InitManager.app = app;
InitManager.initLoadRouters();
}
static initLoadRouters() {
//
// module ,apiDirectory ( ), visit
//
const apiDirectory = `${
process.cwd()}/routes`
const modules = requireDirectory(module, apiDirectory, {
visit: whenLoadModule
});
function whenLoadModule(obj) {
if(obj instanceof Router) {
// FIXME
const blackList = ['/image'];
const prefix = obj.opts.prefix;
if (!blackList.includes(prefix)) {
InitManager.app.use(obj.routes());
}
}
}
}
}
module.exports = InitManager;
// app.js
const Koa = require('koa');
const app = new Koa();
const InitManager = require('./core/init');
// ...
//
InitManager.initCore(app);
コードはすっきりしていますが、機能の実現は大丈夫です.開発環境と生産環境の区分
時には、2つの異なる環境の下で、私達は異なった処理をしなければならなくて、この時に私達は前倒しで全体の局面の中で相応するパラメーターを注ぎ込む必要があります.
まずプロジェクトのルートディレクトリでconfigフォルダを作成します.
// config/config.js
module.exports = {
environment: 'dev'
}
//core/init.js initManager
static loadConfig() {
const configPath = process.cwd() + '/config/config.js';
const config = require(configPath);
global.config = config;
}
// app.js
const Koa = require('koa');
const app = new Koa();
const InitManager = require('./core/init');
InitManager.loadConfig(); // , ,
// ...
//
InitManager.initCore(app);
//
global.config.environment=== 'dev' ? dev : pro;
グローバルグローバルグローバルのグローバル変数から現在の環境を取り込むことができます.でもこのように問題があります.あなたが生産環境を配置する時、マニュアルでconfig.jsのenvironment配置を修正します.
統一インターフェースを返します.
統一した戻りフォーマットは、先端の処理効率を向上させ、コンポーネント化が開発された今日においても、統一した戻りフォーマットは、先端をより良いパッケージにすることができます.もし一つのプロジェクトの中に同じ返送フォーマットがないなら、このプロジェクトのコードの品質は大体どこに行けばいいですか?
成功と失敗の戻りフォーマットを先に定義します.
// middleware/response/response.js
/**
* response
* @param ctx
* @param data
* @param code || [ , ]
* @param message
*/
exports.response = (ctx, data, code, message) => {
if (typeof code == 'object') {
message = code[1];
code = code[0];
}
ctx.body = {
code,
data,
message
};
};
/**
* response
* @param ctx
* @param data
* @param code || [ , ]
* @param message
*/
exports.success = (ctx, data, code = 1, message = ' ') => {
if (typeof code === 'string') {
message = code;
}
this.response(ctx, data, code, message);
};
/**
* response
* @param ctx
* @param code || [ , ]
* @param message
*/
exports.error = (ctx, code = 0, data = '', message = ' ') => {
if (typeof code === 'object') {
message = code[1];
code = code[0];
}
ctx.errorLog(ctx, message, 0); //
this.response(ctx, data, code, message);
};
//
// middleware/response/index.js
const {
success, error } = require('./response');
module.exports = async (ctx, next) => {
ctx.success = success.bind(null, ctx);
ctx.error = error.bind(null, ctx);
await next();
};
// app.js
// ...
const response = require('./middleware/response');
app.use(response); //
// ...
このように帰る時はそのまま使えばいいです.フォーマットが統一されていて、見た目が楽です.ctx.error([0, ' ']);
// or
ctx.success(xxx);
グローバル異常処理ミドル件サービス端末アプリの作成中、異常処理は非常に重要な一環であり、各関数の結果は私たちが望むものではないからです.文法の誤りであろうと、やはり業務の論理の上の誤りであろうと、すべて異常を投げ出させなければならなくて、問題を最も直観的な方式で暴露させて、直接無視するのではありません.コードのスタイルについては、「コード大全」でも強調されていますが、一つの関数が異常に遭遇した場合、一番いい方法は直接return false/nullではなく、異常を直接に投げ出すことです.異常を直接先端に投げてしまうと、このバックエンドの本当の料理を感じさせます.必ず包装します.
設計異常処理中間件
// middleware/errorHandler.js
//
const catchError = async (ctx, next) => {
try {
await next();
} catch (error) {
// console.log(error);
if (error.errno) {
// FIXME sql
ctx.error([0, 'sql '], error.sqlMessage);
} else if (error.code) {
ctx.error([error.code, error.msg]);
} else {
// ,
ctx.errorLog(ctx, error, 'we made a mistake'); //
ctx.error([-1, ' ']);
}
}
};
module.exports = catchError;
入り口の書類にこの中間部品を使います.// app.js
//
const errorHandler = require('./middleware/errorHandler');
app.use(errorHandler);
次に、HttpExceptionを例に特定のタイプの異常を生成します.// core/http-exception.js
class HttpException extends Error {
constructor(msg = ' ', code = 400) {
super();
this.code = code;
this.msg = msg;
}
}
class ParamError extends HttpException {
constructor(msg) {
super();
this.code = 400;
this.msg = msg || ' ';
}
}
class NotFound extends HttpException {
constructor(msg) {
super();
this.msg = msg || ' ';
this.code = 404;
}
}
class AuthFailed extends HttpException {
constructor(msg) {
super();
this.msg = msg || ' ';
this.code = 404;
}
}
class Forbidden extends HttpException {
constructor(msg) {
super();
this.msg = msg || ' ';
this.code = 404;
}
}
module.exports = {
HttpException,
ParamError,
NotFound,
AuthFailed,
Forbidden
};
このような頻繁に呼び出されるエラー処理のコードは、毎回導入する必要がないグローバルに置く必要があります.現在のinit.jsの中ではこうです.
const requireDirectory = require('require-directory');
const Router = require('koa-router');
class InitManager {
static initCore(app) {
// app.js koa
InitManager.app = app;
InitManager.initLoadRouters();
InitManager.loadHttpException(); // Exception
}
static initLoadRouters() {
//
//
const apiDirectory = `${
process.cwd()}/routes`;
const modules = requireDirectory(module, apiDirectory, {
visit: whenLoadModule
});
function whenLoadModule(obj) {
if (obj instanceof Router) {
// FIXME
const blackList = ['/image'];
const prefix = obj.opts.prefix;
if (!blackList.includes(prefix)) {
InitManager.app.use(obj.routes());
}
}
}
}
static loadConfig(path = '') {
const configPath = path || process.cwd() + '/config/config.js';
const config = require(configPath);
global.config = config;
}
static loadHttpException() {
const errors = require('./http-exception');
global.err = errors;
}
}
module.exports = InitManager;
これで全体的に使うことができます.//
if (xxx) throw new global.err.ParamError(xxx);
でもthrowの方法でしか投げられないようです.また、クラスなので、newを実例化して、後から見て最適化してもいいですか?JWTを使って認証を完了します.
これは前シリーズ(7)で専門的に書きましたが、ここでは書きません.本稿で参考にした文章の中で紹介したようにもできます.しかし、リフレッシュtokenの使用が足りないので、空きがあります.
nodejs requireパスの別名
開発の過程で、プロジェクトのディレクトリがますます複雑になると、パッケージの参照経路もますます面倒になります.以前からこのようなインポートパスがありました.
const Favor = require('../../../models/favor');
これより長い導入方法もあります.コード潔癖症のプログラマーとして見ていて、とても不快です.このような問題は絶対パスprocess.cwd()によって解決できますが、カタログがある程度深いと、導入されたコードも非常に煩雑です.もっといい解決方法がありますか?module-aliasを使って経路を別名でいいです.
npm install module-alias --save
//package.json
"_moduleAliases": {
"@root": ".", //
"@models": "app/models",
},
ポイント:このライブラリをap.jsに導入する://
require('module-alias/register');
コードを導入するとこうなります.const Favor = require('@models/favor');
このようにエイリアスを使ったら、vscodeの中でF 12は関数の定義位置が見つけられなくなります.ちょっと足りません.下一篇:nodeは入門からシリーズの(10)図形の検証の機能を放棄しますまで下一篇:未完は続きます!