Common JS

8151 ワード

モジュール化
2009年に米国のプログラマーRyan DahlはNode.jsプロジェクトを作成し、JavaScript言語をサービス端末のプログラミングに使用します.これはJavaScriptモジュール化プログラミングが正式に誕生したことを示しています.
モジュール化は、システムを独立した機能モジュールに分割し、必要に応じてロードすることを実現し、各モジュールは独立しています.良好な設計のモジュールは、外部コードとの関係をできるだけ明確にして、独立して修正とメンテナンスを行います.また、モジュールは繰り返し使用して、冗長コードの問題を解決します.モジュール化は主に二つの問題を解決します.それぞれ命名衝突とファイル依存です.
モジュールがない場合は、直ちに関数とクローズドを実行して、ネーミング競合の問題を解決します.直ちに関数内部に独自の作用領域がありますが、外部は自分が露出したメンバーにしかアクセスできず、内部のプライベートメンバーを読み込めません.
//      
let module = (function(){
  let privateVar = "private";//    
  let privateFun = function(){};//    
  //       
  return {publicVar:"public", publicFun:function()};
})();
モジュールを使用すると、モジュール内のすべてのメンバーが露出します.モジュールの内部状態は外部で書き換えられます.
let module = {
  varname:"varname",
  fun:function(){
    console.log(this.varname);
  }
};
Common JS
JavaScriptモジュール化規範は、Common JS、AMD、CMD、ED 6のモジュールシステムの4つに分けられます.
Common JSは、2つのCommunJS 1とCommon JS 2に分けられています.違いは、Common JS 1はexports.xxx = xxxを通じてしか導き出せないことです.Common JS 2はCommon JS 1にmodule.exports = xxxの導出方式を加えました.ここのCommon JSとはCommunJ 2のことです.
Node.jsアプリケーションはモジュールで構成され、CommunJSモジュール仕様を採用しています.つまり、各ファイルはモジュールであり、独自の作用領域、変数、方法などを持っています.また、他のモジュールには見えません.Node.jsはCommon JS仕様の実装で、クライアントには適していないので、ESはmodule機能を発売しました.
  • Common JS仕様ロードモジュールは同期しています.ロードが完了したら後続のプロセスが実行できます.Node.jsは主にサーバープログラミングに使われています.モジュールは一般的にはローカルディスクに存在しています.同期ローディングが速いです.
  • Common JSモジュールのコードはすべてモジュールの機能領域で実行されますので、グローバルスコープを汚染しません.
  • Common JSモジュールは複数回にわたってロードされますが、最初のロード時に一回だけ実行されます.結果はキャッシュされます.後続の再読み込みはキャッシュから直接読み取ります.モジュールを再起動するにはキャッシュをクリアする必要があります.
  • Common JSモジュールのローディング順序はコードに現れる順序で
  • です.
  • Common JSの欠点は、モジュールを並列にロードできない上、ブラウザのローディングをブロックすることです.また、コードはブラウザ環境で直接実行できません.ツールを通じて標準のES 5に変換しなければなりません.
  • Common JSモジュール
    Common JSモジュールは、モジュール定義exports、モジュール識別module、モジュール参照requireの3つの部分に分けられます.
  • moduleオブジェクト代表モジュール自体
  • exportsオブジェクトは、現在のモジュールの方法または変数
  • を導出するために使用される.
  • require方法は、外部モジュール
  • を導入するためのものである.
    Common JSのコア思想は、require方法によって同期して依存するモジュールをロードし、module.exportsを使用して露出を必要とするインターフェースを導き出す.
    module
    CommonJS仕様では、各モジュール内でmodule変数を使用して現在のモジュールを表し、module変数はオブジェクトであり、外部にインタフェースを提供するためのexports属性を有する.
    $ vim module.ms
    console.log(module);
    
    $ node module.js
    Module {
      id: '.',
      exports: {},
      parent: null,
      filename: 'D:\
    odejs\\workspace\\test.js', loaded: false, children: [], paths: [ 'D:\
    odejs\\workspace\
    ode_modules', 'D:\
    odejs\
    ode_modules', 'D:\
    ode_modules' ] }
    属性
    説明
    id
    モジュール識別子は、通常、絶対パスを有するモジュールファイル名である.
    filename
    モジュールのファイル名には、絶対パスがあります.
    loaded
    モジュールのロードが完了しましたか?
    parent
    このモジュールの親モジュールを呼び出します.
    チルドレン
    モジュールで使用する他のモジュール
    exports
    モジュール対外出力の値
    //    
    $ vim module.js
    module.exports = {
      varname:"varname",
      fn:function(){
        console.log(varname);
      }
    }
    
    CommunJSのmoduleオブジェクトのexports属性は、現在のモジュールの対外出力のインターフェースを表し、他のファイルにrequireを使用してモジュールをロードすると、実際にはmodule.exports変数を読み出す.
    //    
    $ vim test.js
    const module = require("./module");
    module.fn();//varname
    
    module.exports属性は、現在のモジュールが外部に出力するインターフェースを表し、他のファイルがrequireを使用してモジュールをロードすると、実際にはmodule.exportsオブジェクトを読み取る.
    exports
    ノード.jsは、各モジュールにexports変数(オブジェクト)を提供し、module.exports属性を指す.各モジュールのヘッダが存在するに相当する.
    //CommonJS           
    var exports = module.exports;
    
    $ vim module.js
    console.log(exports);
    
    $ node module.js
    {}
    
    このようにする利点は、外部出力モジュールインターフェースの場合、exportsオブジェクトに方法を追加して露出することができることである.
    $ vim module.js
    exports.varname = "hello world";
    exports.fn = function(){
      console.log(exports.varname);
    };
    console.log(module.exports);
    
    $ node module.js
    { varname: 'hello world', fn: [Function] }
    
    モジュールが外部に出力する場合、exportsに方法を追加することができるが、exports変数を直接値に向けることはできず、これはexportsmodule.exportsとの間の関係を切断することに相当する.
  • module.exportsは、単独で1つのデータタイプに戻り、exportsは1つのオブジェクトに戻るしかない.
  • exportsオブジェクトは最終的にmodule.exportsを介して伝達され実行され、正確にはexportsに属性および方法を追加する.
  • module.exportsexportsの参照であり、module.exportsmodule.exportsの具体的な実施形態である.
  • exportsを変更したいが、module.exportの方式でインターフェースを暴露したいなら、自分で書くしかない.
    //     
    exports = module.exports = something;
    
    requireexports.xxx方法は、指定されたJavaScriptファイルの読み込みと実行を同期させるために使用され、モジュールのexports = module.exportsオブジェクトに戻り、対象モジュールが見つからないとエラーが発生する.
    パッケージ
    例えば、オブジェクトのインスタンスをエクスポートする
    $ vim /config/mysql.json
    
    {
        "development":{
            "host":"127.0.0.1",
            "port":3306,
            "user": "root",
            "password": "root",
            "database": "pomelo",
            "charset": "utf8mb4",
            "connectionLimit": 10
        },
        "production":{
            "host":"127.0.0.1",
            "port":3306,
            "user": "root",
            "password": "root",
            "database": "pomelo",
            "charset": "utf8mb4",
            "connectionLimit": 10
        }
    }
    
    $ vim /utils/mysql.js
    
    //     
    let Module = function(){
        const env = process.env.NODE_ENV || "development";
        const config = require("../config/mysql")[env];
        const mysql = require("mysql2");
        this.pool = mysql.createPool(config);
    };
    
    Module.prototype.query = function (sql, values){
        return new Promise((resolve, reject)=>{
           this.pool.getConnection((error, connection)=>{
              if(error){
                  reject(error);
              }else{
                  if(values){
                      connection.query(sql, values, (err, result)=>{
                          if(err){
                              reject(err);
                          }else{
                              if(result.length === 1){
                                  result = result[0];
                              }
                              resolve(result);
                          }
                      });
                  }else{
                      connection.query(sql, (err, result)=>{
                          if(err){
                              reject(err);
                          }else{
                              if(result.length === 1){
                                  result = result[0];
                              }
                              resolve(result);
                          }
                      });
                  }
                  connection.release();
              }
           });
        });
    };
    
    module.exports = new Module();
    
    
    //            
    process.on("exit", async (code)=>{
        try{
            await this.pool.end();//TypeError: Cannot read property 'end' of undefined
        }catch(e){
            console.error(e);
        }
    });
    
    process.on('unhandledRejection', error => {
        console.error('unhandledRejection', error);
        process.exit(1) // To exit with a 'failure' code
    });
    
    Expressで使用します
    $ vim route.js
    
    const router = require("express").Router();
    const mysql = require("../utils/mysql");
    
    router.get('/index',async (req, res, next)=>{
        let json = {};
        json.title = "default index page";
        json.message = "hello world";
    
        let sql = "SELECT * FROM game_user WHERE 1=1";
        let result = await mysql.query(sql);
        console.log(result);
        res.render("index/index.html", json);
    });
    
    module.exports = router;