JSプラグインの作り方 *

なでしこ3には、JavaScriptで開発する「JSプラグイン」となでしこ自身で開発する「NAKO3プラグイン」の二種類があります。

ただし、JSプラグインは、【ブラウザ版】と【PC版(Node.js)】でプラグインの作り方が異なります。

ブラウザ版 - JSプラグインの使い方 *

ブラウザ版のJSプラグインを利用するには、(1)「取り込む構文」を使う方法と、(2)HTMLの<script>タグを使う方法の二種類があります。

# (1) なでしこのプログラム内で「取り込む」文を使う
!「xxx.js」を取り込む
<!-- (2) HTMLファイル内で<script>タグを記述する -->
<script src="xxx.js"></script>

ブラウザ版 > (1)取り込む文を使う場合 *

最初に、「取り込む構文」を使う方法を紹介します。貯蔵庫にJSプラグインを保存した場合には、下記のように「貯蔵庫:プラグイン名.js」を取り込むと記述するとプラグインを利用できる状態になります。

   v3.7.3

そして、貯蔵庫に下記のようなJSプラグインを作成します。

// プラグインを表すオブジェクトを定義
const pluginHello = {
  'meta': {
    type: 'const',
    value: { // プラグインに関する情報を指定する
      pluginName: 'nadesiko3-hello', // プラグインの名前
      description: 'プラグインのひな形', // プラグインの説明
      pluginVersion: '3.6.15', // プラグインのバージョン
      nakoRuntime: ['wnako'], // 対象ランタイム
      nakoVersion: '3.6.15' // 要求なでしこバージョン
    }
  },
  // 関数を定義
  '掛算テスト': { // @掛け算をするだけのテスト関数 // @かけざんてすと
    type: 'func', // 関数であれば func にする
    josi: [['と'],['を']], // 助詞を配列で宣言する
    fn: function (a, b) {
        return a * b
    }
  }
}
// なでしこにプラグインを登録
if (typeof (navigator) === 'object') {
  navigator.nako3.addPluginObject("pluginHello", pluginHello)
} else {
  module.exports = pluginHello
}
  • こちらに完全な「nadesiko3-hello.js」というプラグインがあります。

プラグイン作成の書式 *

以下のようにプラグインを記述します。プラグインを記述した後で、なでしこ本体(navigator.nako3)にプラグインを登録する処理が必要になります。

// --- なでしこプラグインのオブジェクトを宣言 ---
const pluginObj = {
  '関数名': { 定義 },
  '定数名': { 定義 },
}
// --- なでしこ3の本体に関数を登録する ---
if (typeof (navigator) === 'object') {
  navigator.nako3.addPluginObject("プラグイン名", pluginObj)
} else {
  module.exports = pluginObj
}

ブラウザ版 > (2)HTMLで<script>タグを使う場合 *

HTMLの<script>タグでプラグインを読み込む場合も手順はほぼ同じです。下記のように、<script>タグを記述します。ここでは『nadesiko3-hello.js』を使う方法を記述します。

wnako3.jsを取り込んだ後で、下記のような<script>タグを記述します。

<!-- HTMLファイル内で<script>タグを記述する -->
<script src="https://n3s.nadesi.com/plain/nadesiko3-hello.js"></script>

すると「!「...」を取り込む」を書かなくても、プラグイン内で宣言した関数が使えます。

3と5を掛算テストして表示。

ただし、<script src=".../wnako3.js">の後で、プラグインを取り込みます。

PC(Node.js)版を使う場合 *

プラグインの実体は、JavaScriptのオブジェクトです。なでしこv3.3以降、なでしこは、ESModuleを採用しています。そのため、下記のようにオブジェクトの宣言でexport default { ... }のように記述してください。

// ESModule方式
export default {
  '関数名': { 定義 },
  '定数名': { 定義 },
}

具体的には、下記のようなJSファイルを作成します。

const pluginHello = {
  'meta': {
    type: 'const',
    value: { // プラグインに関する情報を指定する
      pluginName: 'nadesiko3-hello', // プラグインの名前
      description: 'プラグインのひな形', // プラグインの説明
      pluginVersion: '3.6.15', // プラグインのバージョン
      nakoRuntime: ['wnako'], // 対象ランタイム
      nakoVersion: '3.6.15' // 要求なでしこバージョン
    }
  },
  '掛算テスト': { // @掛け算をするだけのテスト関数 // @かけざんてすと
    type: 'func', // 関数であれば func にする
    josi: [['と'],['を']], // 助詞を配列で宣言する
    fn: function (a, b) {
        return a * b
    }
  }
}
export default pluginHello

関数の定義 *

上記のObjectにて関数を定義するには、fnプロパティに行います。実際の関数の引数に加えて、システムを表すsysを定義します。

{
  '関数名': { // @関数の説明 // @よみがな
    type: 'func', // 関数であれば func にする
    josi: [['を', 'から'], ['まで']], // 助詞を配列で宣言する (可変長引数として扱いたい助詞は末尾で宣言する)
    isVariableJosi: false, // 末尾の助詞を可変長引数として扱う場合 true にする
    uses: [], // この関数から別の関数を呼ぶ場合に記述する // (TODO: #282)
    asyncFn: false, // async関数定義かPromiseを返す関数を定義する場合 true にする (参照: #1154)
    fn: function (aFrom, aTo, sys) { ... }, // 関数の実態
    return_none: false // 戻り値を返すかどうか
  },
  ...
}

変数や定数の定義 *

typeプロパティに「var」(変数)や「const」(定数)を指定して、valueプロパティに値を指定します。

{
    '変数名': { type: 'var', value: 100 }, // @よみがな
    '定数名': { type: 'const', value: 100 }, // @よみがな
....
}

なお、コメントを記述した場合『npm run build:command』を実行すると自動的にコマンドマニュアルが生成されます。

初期化メソッドについて *

以下のようなエントリを用意しておくと、プラグインを取り込み、初回実行するときに初期化メソッドが実行されます。 (ただし、プラグイン取り込み時に、 !{プラグイン名}:初期化 というメソッド名にリネームされます)

{
  '初期化': {
    type: 'func',
    josi: [],
    fn: function (sys) { ... }
  }
  ...
}

なお、初期化メソッドのほかに、以下のようなメタ情報を定義する必要があります。

  'meta': {
    type: 'const',
    value: {
      pluginName: 'plugin_***', // プラグインの名前
      description: '説明',
      pluginVersion: '3.6.0', // プラグインのバージョン
      nakoRuntime: ['wnako', 'cnako', 'phpnako'], // 対象ランタイム
      nakoVersion: '3.6.0' // 最小要求なでしこバージョン
    }
  },

クリアメソッド *

以下のようなエントリを用意しておくと、プログラム終了時(あるいはクリア時)にプラグインごとプログラムが実行されます。

{
  '!クリア': {
    type: 'func',
    josi: [],
    fn: function (sys) { ... }
  }
  ...
}

初期化とクリアメソッド *

これを利用する事で、現在なでしこが実行されているかどうかを判定できます。

   v3.7.3

プラグイン側からシステム変数へのアクセス *

関数を定義したとき、プラグイン関数側からシステムにアクセスしなければならない場合があります。 以下は引数のない関数を定義した例ですが、必ず必要とされる引数の末尾に実行したシステムのthisを保持するオブジェクトが渡されます。このオブジェクトを参照することで、システム変数にアクセスできます。

{
  type: 'func',
  josi: [],
  fn: function (sys) {
    console.log(sys)
  }
}

詳細は以下を参照 *

より詳しい機能については、以下を参照してください。

プラグインをnpmで公開しよう *

なでしこは、Node.jsのエコシステム上で動作するように配慮されています。
そのため、自分の作ったプラグインをnpm上で公開すると、みんなに使ってもらいやすくなります。

v3.6以降のプラグインへの対応 *

なでしこv3.6以降、なでしこ内部の変数管理の仕組みが変わりました。なでしこ内部の変数管理がObjectからMapに変更となり安全性が向上しました。

そのため、v3.5以前で可能だった次のような表現が使えなくなりました。

// 廃止されたシステム変数へのアクセス
const value1 = sys.__v0["変数名"]
sys.__v0["変数名"] = value1
const value2 = sys.__varslist[0]["変数名"]
sys.__varslist[0][変数名] = value2

こうした表現が、以下のようなメソッドを介したアクセスに変更されました。

// 今後、利用可能なシステム変数へのアクセス
sys.__setSysVar("変数名", 値) ... なでしこ変数の設定
sys.__getSysVar("変数名") ... 変数の値の取得

他にも、プラグイン関数で使えるメソッドやプロパティの一覧が以下にまとめられました。

  • core/src/plugin_api.mts --- プラグイン関数の引数sysで使えるメソッドやプロパティをまとめたもの