電子の局所データ蓄積


This post is also published in my blog


Electron クロスプラットフォームアプリケーションを構築するための素晴らしいフレームワークです.電子では、簡単にWeb技術を使用してデスクトップアプリケーションを構築することができます.
電子を使用することで、Web技術の上でクロスプラットフォームアプリケーションを簡単に作成することができます.電子アプリはまだWebアプリケーションの一種であるので、データを格納することについて話すとき、我々はHTTPリクエストを送ることによってリモートサーバにデータを保存するのに使用されます.
どのようなデータをローカルに保存する場合は?
この記事では、永続的なローカルデータストレージを使用して電子アプリケーションを構築する私の経験を共有します.

電子の局所データ蓄積


簡易ユースケース


簡単なユースケースでは、次の2つのオプションがあります.
  • ブラウザLocalStorage:電子はクロムに組み込まれています.ブラウザのLocalStorageはよくサポートされています.

  • electron-store : 簡単なシナリオでは、電子ストアのためだけに行く.APIは使いやすいです
  • 複雑使用事例


    SQLやNOSQLのようなデータベースにデータを格納することを考慮すると、ユースケースが少し複雑になると、より良いアイデアになるでしょう.
    いくつかの研究を行い、SQLとNOSQLの間で電子を使用した後、NoSQLソリューションに行きます.
    私は、統合する方法を導入するつもりですnedb あなたの電子アプリで.
    NDB Docが言ったように、NDBは

    Embedded persistent or in memory database for Node.js, nw.js, Electron and browsers, 100% JavaScript, no binary dependency. API is a subset of MongoDB's and it's plenty fast.


    私はNEDBを使用して生産性の高い製品を構築するためにかなりの喜びです.

    nedbを使用してToDoリスト電子アプリを構築する


    あなたがアイデアを得るのを助けるためにTodo list Electron app with NoSQL storage .

    電子をインストール


    あなたはすぐにアイデアを理解するためにelectron-quick-start テンプレートと迅速な経験を持って
    インストール手順に従います.
    # Clone this repository
    $ git clone https://github.com/electron/electron-quick-start
    # Go into the repository
    $ cd electron-quick-start
    # Install dependencies
    $ npm install
    # Run the app
    $ npm start
    

    フォルダの作成


    クリエイトアdb フォルダ.次に、schemas and stores フォルダ下db .
    repoは次のようになります.
    .
    ├── LICENSE.md
    ├── README.md
    ├── db
    │   ├── schemas
    │   └── stores
    ├── index.html
    ├── main.js
    ├── package-lock.json
    ├── package.json
    ├── preload.js
    └── renderer.js
    

    約束をインストール


    nedb-promises ラッパアラウンドnedb . 約束では、コールバックを処理するために時間のトンを保存することができます.
    $ yarn add nedb-promises
    

    インストール


    ajv JSONスキーマバリデータライブラリです.Schema ValidatorはNOSQLデータベースを構築するために任意ですが、よく定義されたスキーマとバリデータがより良い保守性をもたらすことができるので、私はそれを使用することをお勧めします.
    nit :また、置換できますajv あなたの好みスキーマバリデータ
    $ yarn add ajv
    

    スキーマリストの作成


    ToDoリストのアプリのコンポーネントを破壊しましょう.
    ToDoリストのアプリはToDo項目のリストが必要です.シンプルなToDoアイテムが含まれますtodo content , is it finished?スキーマは次のようになります.
    DB/スキーマ/ToDoItem.js
    const todoItemSchema = {
      type: 'object',
      properties: {
        content: {
          type: 'string',
        },
        isDone: {
          type: 'boolean',
          default: false
        }
      },
    };
    
    module.exports = todoItemSchema;
    

    トドストストア


    ストアにはインターフェイスが含まれますCreate / Update / Delete NEDDB
    Main thread このストアをインポートし、レンダラスレッドがこれらのメソッドを呼び出します.
    最初にinit nedb、コンストラクタのバリデータ
    DB/ストア/ToDoItem.js
    const Datastore = require('nedb-promises');
    const Ajv = require('ajv');
    const todoItemSchema = require('../schemas/todoItem');
    
    class TodoItemStore {
        constructor() {
            const ajv = new Ajv({
                allErrors: true,
                useDefaults: true
            });
    
            this.schemaValidator = ajv.compile(todoItemSchema);
            const dbPath = `${process.cwd()}/todolist.db`;
            this.db = Datastore.create({
                filename: dbPath,
                timestampData: true,
            });
        }
    }
    
    次に、データを制御するメソッドを追加します.
    DB/ストア/ToDoItem.js
    const Datastore = require('nedb-promises');
    const Ajv = require('ajv');
    const todoItemSchema = require('../schemas/todoItem');
    
    class TodoItemStore {
        constructor() {
            const ajv = new Ajv({
                allErrors: true,
                useDefaults: true
            });
    
            this.schemaValidator = ajv.compile(todoItemSchema);
            const dbPath = `${process.cwd()}/todolist.db`;
            this.db = Datastore.create({
                filename: dbPath,
                timestampData: true,
            });
        }
    
        validate(data) {
            return this.schemaValidator(data);
        }
    
        create(data) {
            const isValid = this.validate(data);
            if (isValid) {
                return this.db.insert(data);
            }
        }
    
        read(_id) {
            return this.db.findOne({_id}).exec()
        }
    
        readAll() {
            return this.db.find()
        }
    
        readActive() {
            return this.db.find({isDone: false}).exec();
        }
    
        archive({_id}) {
            return this.db.update({_id}, {$set: {isDone: true}})
        }
    }
    
    module.exports = new TodoItemStore();
    
    記事のゴールがNEDBを電子と統合する方法を共有しているので、私はNEDbのAPIをあまり詳しく説明しません.あなたは最初のアイデアを得ることができますし、いくつかの時間を介してNEDBを介して行くに費やす.
    注目すべきは、モジュールのエクスポート時にクラスをinitすることです.この戦術は、アプリケーションの1つのストアインスタンスを維持するのに役立ちます.
    これは簡単な例ですので、1つだけの店です.実際の場合は、アプリケーションを拡張するために同じ構造を使用できます.

    インテグレート


    これまでのところ、我々はデータベースを制御するためのすべての作業を終えた.repoは次のようになります.
    .
    ├── LICENSE.md
    ├── README.md
    ├── db
    │   ├── schemas
    │   │   └── todoItem.js
    │   └── stores
    │       └── todoItem.js
    ├── index.html
    ├── main.js
    ├── package.json
    ├── preload.js
    ├── renderer.js
    └── yarn.lock
    
    さあ、包みましょう.

    更新メイン。js

    main.js は電子の主な糸です.更新main.js with
  • 必要./db/stores/todoItem
  • 代入todo store instance グローバル変数に
  • 有効化nodeIntegration インwebPreferences オプション.レンダラスレッドはrequire 電子法.これを行うには、レンダラスレッドがnodeIntegration
  • メイン.js
    // Modules to control application life and create native browser window
    const {app, BrowserWindow} = require('electron')
    const path = require('path')
    const db = require('./db/stores/todoItem');
    
    global.db = db;
    
    function createWindow () {
      // Create the browser window.
      const mainWindow = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
          nodeIntegration: true,
        }
      })
      mainWindow.loadFile('index.html')
    }
    
    ...the same...
    

    更新レンダラー。js


    まず、取得db メインスレッドからのインスタンス
    レンダラjs
    const {remote} = require('electron');
    const dbInstance = remote.getGlobal('db');
    
    With dbInstance , 定義されたメソッドを使用してDBを更新できます.
    私たちはすべてのToDoリストを読むことができます
    dbInstance.readAll()
        .then(allTodolists => {
            console.log(allTodolists)
        })
    
    または、我々はtodoアイテムを閉じることができます
    dbInstance.archive("really-fake-id")
        .then(() => {
                console.log('done')
            })
    
    それで、ビューロジックを追加し始めることができます.私はビュー層の説明をスキップします.
    最終実施

    立方 / 電子ネツト



    電子ネツト


    todoリストのデモアプリは電子とNEDBを統合
    View on GitHub
    私たちのNEDB +電子ToDoリストのようになります

    結論


    別の解決策を試した後、私はこの構造に満足しています.利益は

    メインスレッドとレンダラスレッドからのデータの分離


    電子はデータフローの厳しい制限を持たない.データをLocalStorageに格納したり、データをメインスレッドに格納したり、グローバルに公開したりできます.または、使用することもできますelectron-store 簡単なキー値保管のために.
    アプリケーションが大きく大きくなると、データの流れを維持するのが難しくなる.あなたはLocalStorageでコピーを持っているかもしれません、そして、あなたがReduxのようにクライアント州管理フレームワークを使用しているならば、クライアント側ももう一つのコピーをします.
    データフローは適切なデータフローなしで混乱になります.

    この構造を持つNEDBの導入は、明確なデータフローをもたらすだけでなく、より明確な境界を持つMain thread , Renderer thread and data storage . それは、導入するようですMVC 電子応用へのデザインパターンのように.

    もちろん、localstorageにデータを追加することもできます.しかし、データベースからのすべてのデータにアクセスする方法では、ほとんどの場合、localstorageにデータを保存する必要はありません.

    DBロジックは拡張可能です


    デモは簡単なケースです.実世界の場合は、cache パフォーマンスを向上させるには、またはDBアクセスを確保するためにより妥当な検証を追加します.
    さらに、NDBは常にデータをテキストファイルに格納します.したがって、データのインポート/エクスポートを実現するのは簡単です.

    テスト


    これは私にとって最も重要な利益です.上記の例として、各ストアクラスのライティングユニットテストは実現可能です.

    プラス:ビュー層


    任意のビューのフレームワークを使用することができます.あなたがウェブ要求を呼ぶ代わりに、反応+ Reduxを使っているならば、ちょっとdbInstance あなたのactions と異なるアクションでDBメソッドを呼び出します.
    読書ありがとう.これは電子dbとしてnedbを使用している私の個人的経験です.あなたがどのように考えるかについて知らせてください!