Koa 2ゼロから完全工事①

5576 ワード

前に書く
廖大神のJavaScript教程を見終わって、特に0から1つの完全なkoa 2工事を構築することを記録して、主に含みます:
  • 静的リソース
  • の処理
  • テンプレートレンダリング処理
  • データベースORM処理
  • REST API処理
  • 動的解析controllers
  • 目次
  • koa-basicエンジニアリング
  • の作成
  • 応答時間を計算するミドルウェア
  • 静的資源処理のミドルウェア
  • koa-bodyparserミドルウェア
  • を取り付ける
  • テンプレートレンダリングミドルウェア
  • …続き
  • koa-basicエンジニアリングの作成
  • フォルダkoa-basicを新規作成し、vscodeを使用して
  • を開きます.
  • コマンドラインの下でnpm init初期化エンジニアリング
  • を使用する
  • npm i koa-Sを使用してkoa依存パッケージをインストール(iはinstallに等価、-Sはdependenciesに自動的に追加)
  • 小さな修正package.jsonファイル
  • {
      ...
      "scripts": {
        "start": "node app.js",//       npm start      app.js
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      ...
    }
    
  • app.jsファイル
  • を新規作成
    //   koa, koa 1.x  , koa2 ,        class,      Koa  :
    const Koa = require('koa');
    
    //     Koa    web app  :
    const app = new Koa();
    
    //       ,app            :
    app.use(async (ctx, next) => {
        //         (           )
        await next();
        //   response Content-Type:
        ctx.response.type = 'text/html';
        //   response   :
        ctx.response.body = '

    Hello, Koa2!

    '; }); // 3000 : app.listen(3000); console.log('app started at port 3000...');
  • npm startを使用してこのwebプログラムを走り出し、ブラウザにhttp://localhost:3000を入力すると
  • に正常にアクセスできる.
    応答時間のかかるミドルウェアの計算
    これは最も基礎的で、最も簡単な中間部品なので、非同期関数でできます.
    //   1:      
    app.use(async (ctx, next) => {
        console.log(`Precess ${ctx.request.method} ${ctx.request.url}...`);
        var
            start = Date.now(),
            ms;
        await next();//         (           )
        ms = Date.now() - start;
        ctx.response.set('X-Response-Time', `${ms}ms`);
        console.log(`Response Time: ${ms}ms`);
    });
    

    静的リソース処理のミドルウェアmimemzモジュールを先に取り付ける
    npm i -S mime
    npm i -S mz
    

    新しいstaticフォルダ静的リソースを保存するための新しいstatic-files.jsファイル
    const path = require('path');
    const mime = require('mime');
    //mz     API   Node.js   fs       ,  fs       ,  mz     fs      ,    Promise,              await    mz    ,        。
    const fs = require('mz/fs');
    
    //         
    module.exports = (pathPrefix, dir) => {
        //       ,    static
        pathPrefix = pathPrefix || '/static/';
        //        ,    static
        dir = dir || __dirname + '/static/';
        //      ,     app.use()       
        return async (ctx, next) => {
            //    
            var rpath = ctx.request.path;
            //            ,          
            if (rpath.startsWith(pathPrefix)) {
                //          
                var fp = path.join(dir, rpath.substring(pathPrefix.length));
                //      ,       
                if (await fs.exists(fp)) {
                    ctx.response.type = mime.getType(rpath);
                    ctx.response.body = await fs.readFile(fp);
                } else {
                    ctx.response.status = 404;
                }
            } else {
                await next();
            }
        };
    };
    

    このミドルウェアはapp.jsで使用される
    //   2:      ,        
    if (!isProduction) {
        //   static-files    ,            
        app.use(require('./static-files')());
    }
    

    koa-bodyparserミドルウェアのインストール
    モジュールを先にインストール
    npm i -S koa-bodyparser
    

    このミドルウェアはapp.jsで使用される
    ...
    //        
    const bodyparser = require('koa-bodyparser');
    ...
    //   3:     request    body,    ctx.request.body
    app.use(bodyparser());
    ...
    

    テンプレートレンダリングミドルウェア
    まずnunjucksモジュールを取り付ける
    npm i -S nunjucks
    

    新規viewsフォルダテンプレートファイルを格納する新規templating.jsファイル
    const nunjucks = require('nunjucks');
    
    //  nunjucks
    function createEnv(path, opts) {
        var
            autoescape = opts.autoescape === undefined ? true : opts.autoescape,
            noCache = opts.noCache || false,
            watch = opts.watch || false,
            throwOnUndefined = opts.throwOnUndefined || false,
            env = new nunjucks.Environment(
                new nunjucks.FileSystemLoader(path, {
                    noCache: noCache,
                    watch: watch
                })
                , {
                    autoescape: autoescape,
                    throwOnUndefined: throwOnUndefined
                }
            );
    
        if (opts.filters) {
            for (var f of opts.filters) {
                env.addFilter(f, opts.filters[f]);
            }
        }
        return env;
    }
    
    //          path     
    module.exports = function (path, opts) {
        //      
        if (arguments.length === 1) {
            opts = path;//    opts
            path = null;
        }
        //      ,    views
        path = path || 'views';
        var env = createEnv(path, opts);
        //   app.use()       
        return async (ctx, next) => {
            //  ctx    render   
            ctx.render = (view, model) => {
                ctx.response.type = 'text/html';
                //Object.assign()                            。      ctx.state || {},                  ctx.state   View。
                ctx.response.body = env.render(view, Object.assign({}, ctx.state || {}, model || {}));
            };
            await next();
        };
    };
    

    このミドルウェアはapp.jsで使用される
    ...
    //        
    const templating = require('./templating');
    ...
    //   4:      
    app.use(templating({
        noCache: !isProduction,
        watch: !isProduction
    }));
    ...
    

    続編