Noodl react library ガイド(和訳)


この記事は、Noodl公式のSlackコミュニティー上でMathias L氏が2019年9月に公開した「Noodl react library guide」の和訳になります。

※注:和訳は意訳+注釈を追加しています。


Noodl Reactライブラリガイド(和訳)

このガイドではReact LibraryをNoodlワークスペースに追加する方法を紹介します

ワークスペースフォルダが適切に設定されていることを確認してください

まずはNoodl CLI toolがインストールされていることを確認してください。
ツールはnpmを使ってインストールできます。

$ npm install -g noodl-lab-cli

次に、空のワークスペースフォルダを作成します。
このフォルダにすべてのカスタムコンポーネントとモジュールを含めます。

$ mkdir my-workspace-folder
$ cd my-workspace-folder

すべてをゼロから開始する必要はありません。
Noodlスターターラボのテンプレートが使⽤できます。

$ curl -O https://s3.amazonaws.com/updates.noodlcloud.com/lab
s/noodl-starter-lab.zip
$ unzip noodl-starter-lab.zip

ワークスペースフォルダーではじめ、このワークスペースをNoodlクラウドワークスペースに接続します。
initコマンドを実⾏できます。下記のXXXをあなたが取得したアクセスキーに置き換え、提供されているワークスペース名に置換えるてください。

$ noodl-lab init --accessKey "XXX" --name "your-workspace-nam
e"

アクセスキーはワークスペースの管理ページにあります(labとワークスペースどちらも使用でき、同じものを参照します)。

※訳注: このアクセスキーはNoodlワークスペースの管理者にしか公開されていません。残念ながら、ベータテスタ権限ではアクセスキーを確認することができません。

⻭⾞をクリックして管理ページに⼊ります。ラボ名がユーザ名の下に表⽰されます

アクセスキーは管理ページの下部にあります

ワークスペースのコンテンツを変更するたびにpushする必要があります。
また、pushすることでコンテンツフォルダが適切に設定されていることをテストできます。

$ noodl-lab push

上記のコマンドが正常に実⾏されると、ワークスペースフォルダーが正しく設定されます。Noodlモジュールの共同作業ができるので、このフォルダをバージョン管理下に置いておくとよいでしょう。

訳注:Noodl管理者ではないので、このガイドで紹介されている「noodl-lab」コマンドを使いNoodlクラウドワークスペースへ追加することはできません。
ですが、下記のReactモジュールを作成しNoodlプロジェクトに追加することはできます。

新しいReactライブラリモジュールを作成する

ここでワークスペースフォルダタイプに新しいライブラリモジュールを追加します。

$ cd library
$ curl -O https://s3.amazonaws.com/updates.noodlcloud.com/lab
s/react-module-template.zip
$ unzip react-module-template.zip

これでワークスペースライブラリフォルダに2つのフォルダーと1つのアイコンファイルが追加されます。

feed
library/
newmodule-project
newmodule
newmodule-icon.png

作成しているライブラリモジュールに合わせて、2つのフォルダとアイコン名を変更します。
例えば「mymodule-project」と「mymodule」のように。

$ mv newmodule mymodule
$ mv newmodule-project mymodule-project
$ mv newmodule-icon.png mymodule-icon.png

まずは「mymodule」フォルダを⾒てみましょう。
ここにはモジュールのソースコードを含めます。
たとえばすべてのReactコードとNoodlを結合するコード、webpackを使⽤するビルドスクリプトなど。
まずpackage.jsonファイルのモジュール名を変更します。

{
"name"︓ "com-your-domain-module-name"
...
}

名前をモジュールの代表的な名前に変更しビルドを進めると。
すべての依存関係あるモジュールがインストールされます。
訳注:「mymodule」フォルダでnpm installを実行すると、「node_modules」フォルダが作成され、package.jsonに書かれている依存関係のあるモジュールが自動でダウンロードされます。

$ npm install

テンプレートモジュールにはサンプルコードが含まれているため、そのままでビルドができます。

$ npm run build

このステップではReactモジュールをビルドし、別フォルダのmymodule-projectにコピーします。このフォルダーはNoodlで開いて編集、テストできるNoodlプロジェクトが含まれています。
訳注:npm run bulidによってwebpackがproductionモードで実行されます。これで自作モジュールに必要なファイルをindex.jsにまとめます。
さらに、mymodule-projectフォルダにNoodlに必要な「noodl_modules」フォルダを作成します

Noodlを起動し、[Project]タブに移動して、ページ下部の[Import existing project]を選択します。

プロジェクトページの下部にある[Import existing project]ボタンをクリックします

重要 [Save local]チェックボックスがオンになっていることを確認してください。インポートするプロジェクトがローカルのコンピュータに保存され、
インポート元の場所で編集されます。例ではワークスペースフォルダ内のプロジェクトを編集します。

「ローカルに保存」がチェックされていることを確認してください︕

プロジェクトに名前を付けて(任意の名前でかまいません)、Pick project folderボタンを押してください。

プロジェクトに名前を付けて、「Pick project folder」をクリックします

ワークスペースディレクトリ(上記のテンプレートを解凍し作成されたディレクトリ)「mymodule-project」フォルダを探し、[開く]をクリックします。

開いたプロジェクトには、サードパーティのReactコンポーネントのようないくつかのカスタムReactコンポーネントが表⽰されます。このコンポーネントを使用したりプロパティを調べることができます。ではモジュールのコードを詳しく⾒てみましょう。

「mymodule」フォルダに戻ると、srcフォルダの下位にindex.jsが含まれているのがわかります

mymodule/
  assets/
  node_modules/
  src/
    index.js
  package.json
  package-lock.json
  webpack.config.json

これはReactコンポーネントをNoodlにインポートする、すべての結合用コードを含むファイルです。
もしモジュールに新しいコンポーネントを追加するなら、npmを介してパッケージをインストールするか、コードをモジュールフォルダーにコピーし結合用コードをindex.jsファイルに追加してください。

MyCustomReactComponentとサードパーティパーティコンポーネントFieldRangeの2つの例をご覧になり、これがどのように⾏われているか確認することをお勧めします。
訳注:サンプルプログラムもこの記事の下部に掲載しています。

モジュールのソースコードを変更した場合は再構築する必要があります。
開発モードでビルドステップを起動することができます。

$ npm run dev

これで変更が監視され、新しいモジュールが⾃動的にビルドされてNoodlプロジェクトにコピーされます。
変更を加えたら、Ctrl/Cmd-Rを使ってNoodlビューアを更新するだけです。

モジュールをライブラリに追加する

自作モジュールに満足したら、自分のワークスペースライブラリにモジュールを追加できるだけでなく、ほかのNoodlユーザープロジェクトにも含めることができます。

そのためには、ライブラリフォルダー内のindex.jsonファイルをモジュールに合わせて編集してください。

[
   {
      "label":"My React Module",
      "desc":"I made this myself!",
      "thumb":"mymodule-icon.png",
      "project":"mymodule-project"
 }
]
  • label:ライブラリモジュールのラベル
  • desc:簡単な説明
  • thumb:ライブラリパネルにアイコンとして表⽰される画像
  • project:プロジェクトフォルダの名前。プロジェクトの名前でなければなりません。モジュールフォルダではなくプロジェクトフォルダです。

これが完了したら、ワークスペースフォルダのルートに戻り、
新しいコンテンツをNoodlクラウドワークスペースにプッシュします。

$ noodl-lab push

プッシュ後、Noodlを再起動する必要があります。再起動するとエディター内のLIBRARYタブに新しいモジュールが表示されます
訳注:ここでもnoodl-labコマンドを使えないため、手動で追加していきます。
「noodl_module」フォルダごとNoodlプロジェクトのリソースフォルダ(左のバーからProjectSetting>Open Project folderボタンをクリックして表示されるフォルダ。Windowsでは「C:\Users\user\Documents\Noodl」にある各プロジェクトフォルダでした。)にコピーすることで、Noodlに自作モジュールを追加します。

左のバーからLIBRARYタブを選択すると、新しいモジュールが表示されます。

これで、ユーザーは[ADD]ボタンをクリックしてプロジェクトにモジュールを追加できます。

 (追加)サンプルコード

最後に上記例で説明されているカスタムReactコンポーネントのサンプルコードがISCライセンス(GNU GPLと両立する自由ライセンス)で提供されているので和訳化して掲載します

index.js
import FieldRange from '@atlaskit/range'; // https://atlaskit.atlassian.com/packages/core/range

//サードパーティReactコンポーネントの例
//Third party react component example

const AtlasKitRange = {
    //ノード名、Noodlで呼ばれるもの。必須
    name: 'Atlas Range', //name of the node, this is what it'll be called in Noodl. Mandatory
    //カテゴリも必須
    category: 'Atlas', //A category is also mandatory.

    //ここでReactコンポーネントを返す必要があります
    //Here we need to return the React Component.
    getReactComponent() {
        return FieldRange;
    },

    //Reactコンポーネントに転送されるすべての入力リスト
    //A list of all inputs that will be forwarded to the react component
    inputProps: {
        isDisabled: {type: 'boolean', default: false},
        max: {type: 'number', default: 100},
        min: {type: 'number', default: 0},
        value: {type: 'number'}
    },
    //出力プロパティはNoodlノードの出力で生成される以外、inputPropsと非常に似ています
    //これらは通常Reactのコールバックで、Noodlは値をキャッチして出力として送信します
    //these props are very similar to the inputProps, except that they will generate outputs on the Noodl node
    //these are typically callbacks in React, and Noodl will catch the value and and send it as an output
    outputProps: {
        onChange: {
            type: 'number',
            displayName: 'New Value',
            // Reactコンポーネントに送信されるカスタムコールバックを定義できます。Noodlはここで出力で送信する値が返ってくることを期待しています
            // この例は非常に単純なので、カスタムの「getValue」関数を定義する必要はありません。
            // Noodlが自動的に判断しgetValu関数を補完します 
            // You can define a custom callback that's sent to the React component. Noodl expect you to return a value here
            // that Noodl will send on the output. In this case its so simple that we don't need to define a custom 'getValue' function.
            // Noodl will automatically figure it out 
            // getValue: sliderValue => sliderValue
        }
    }
}

//カスタムReactコンポーネントの例
//Custom react component example

function MyCustomReactComponent(props) {
    const style = {
        color: props.textColor,
        backgroundColor: props.backgroundColor,
        borderRadius: '10px',
        padding: '20px',
        marginBottom: props.marginBottom
    };

    return <div style={style} onClick={props.onClick} >{props.children}</div>
}

const MyCustomReactComponentNode = {
    name: 'Custom React Component',
    category: 'Tutorial',
    getReactComponent() {
        return MyCustomReactComponent;
    },
    inputProps: {
        backgroundColor: {type: 'color', default: 'white'},
        marginBottom: {type: {name: 'number', units: ['px'], defaultUnit: 'px'}, default: 10}
    },
    outputProps: {
        onClick: {type: 'signal', displayName: 'Click'}
    }
}


Noodl.defineModule({
    reactNodes: [
        AtlasKitRange,
        MyCustomReactComponentNode
    ],
    nodes:[
    ],
    setup() {
        //起動時に一度呼び出されます
        //this is called once on startup
    }
});

図Noodl上に取込まれた自作ノード

まとめ

Noodl向けにReactコンポーネントを自作し、Noodlノードとして登録したかったので、一連の流れを調べてみました。
自作や外部のReactコンポーネントをNoodノード化できると、Noodlの可能性がまた広がりますね。