kintoneのカスタマイズ効率をあげよう4 – IE11対応

Photo by Goran Ivos on Unsplash

更新履歴

  • 2020/10/18 webpack5に対応

はじめに

kintoneのカスタマイズ効率をあげよう3 – 型補完の続きです。

本記事では新しいJavaScriptの機能を利用、かつkintoneのすべての動作環境でカスタマイズが動作するようにします。

例えば、IE11はアロー関数に対応していないので以下のプログラムを適用すると構文エラーが発生します。

(() => {
  "use strict";
  kintone.events.on("app.record.index.show", (event) => {
    console.log(event);
  });
})();

だからといって「function () {}」と書きたくはありません。asyncだって、awaitだって使いたい!

トランスパイルを試す(アロー関数)

トランスパイルとはプログラムを別のプログラムに変換することを意味します。今回の場合はTypeScriptをJavaScriptに、新しいJavaScriptの機能を古いJavaScriptの機能に置き換えることを意味します。

実は現在の設定でトランスパイルできる状態です。早速試してみましょう。前回のプログラムをアロー関数に書き換えます。

(() => { // ココ
  "use strict";

  interface IndexEvent {
    appId: number;
    viewType: string;
    viewId: number;
    viewName: string;
    records: kintone.types.SavedFields[];
    offset: number;
    size: number;
    date: null;
    type: string;
  }

  interface DetailEvent {
    appId: number;
    record: kintone.types.SavedFields;
    recordId: number;
    type: string;
  }

  kintone.events.on("app.record.index.show", (event: IndexEvent) => { // ココ
    console.log(event);
  });

  kintone.events.on("app.record.detail.show", (event: DetailEvent) => { // ココ
    console.log(event);
  });
})();

このコードを「Ctrl + Shift + B」でトランスパイルすると、以下のコードが生成されます。

"use strict";
(function () {
    "use strict";
    kintone.events.on("app.record.index.show", function (event) {
        console.log(event);
    });
    kintone.events.on("app.record.detail.show", function (event) {
        console.log(event);
    });
})();

「function() {}」になっていることが確認できます。

TypeScriptの設定の解説

TypeScriptがどうトランスパイルするかはtsconfig.jsonのtargetで指定できます。現在はes5が指定されています。これをes6にしてトランスパイルすると以下のコードが生成されます。

"use strict";
(() => {
    "use strict";
    kintone.events.on("app.record.index.show", (event) => {
        console.log(event);
    });
    kintone.events.on("app.record.detail.show", (event) => {
        console.log(event);
    });
})();

es6はアロー関数に対応しているのでそのまま出力された、というわけですね。

targetに指定できる内容が気になる人は以下をご確認ください。

トランスパイルを試す(Object.values())

では、次にES2017で追加されたObject.values()を試してみましょう。Object.values()はIE11では使えません。どのブラウザでどの機能が利用できるか、は以下のサイトが参考になります。

早速Object.values()をトランスパイルできるか試しましょう。以下のコードを入力して、トランスパイルすると・・・エラーが発生します。

console.log(Object.values(event));
error TS2339: Property ‘values’ does not exist on type ‘ObjectConstructor’.

これには2つ問題があります。

1つ目はTypeScriptがObjectのvaluesプロパティを理解できないことです。これはtsconfig.jsonのlibプロパティにes2017を指定することで解決します。consoleを理解させるのに必要なdomも指定します。

"lib": ["es2017", "dom"],  

targetがes5の場合、libの初期値にはdomが含まれています。
そのため、これまではエラーになっていませんでした。

これでトランスパイルされました。トランスパイルされたindex.jsを見ると・・・Object.values()はそのままで変換されていません。これではIE11でエラーになります。

IE11に対応する必要がない場合はこのlib設定のみで十分な可能性があります。しかし、kintoneはIE11も動作対象なので解決する必要があります。

これが2つ目の問題です。TypeScriptはObject.values()を理解できたのですが、トランスパイルする方法がわからないのです。

アロー関数やasync、awaitなどトランスパイルされるものもあります。

Polyfillの適用

Polyfillとはトランスパイルする方法のコード集です。今回はBabelcore-jsを利用します。core-jsがPolyfillでBabelがトランスパイルの実行役を担います。

以下のコマンドを実行してパッケージをインストールします。

> npm install --save-dev @babel/core @babel/cli @babel/plugin-proposal-class-properties @babel/preset-env @babel/preset-typescript core-js

.babelrc.js(Babelの設定ファイル)を作成します。

module.exports = {
  presets: [
    [
      "@babel/preset-env",
      {
        targets: {
          ie: "11",
        },
        useBuiltIns: "usage",
        corejs: { version: 3 },
      },
    ],
    "@babel/preset-typescript",
  ],
  plugins: ["@babel/plugin-proposal-class-properties"],
};

準備が整ったのでBabelを実行します。

> npx babel src --out-dir dist --extensions .ts

トランスパイルされたindex.jsを確認すると、以下の1行が増えています!

require("core-js/modules/es.object.values");

上手くいきそうな気配!IE11で確認すると・・・エラーが・・・

‘require’ は定義されていません。

webpackの利用

Babelによるトランスパイルではブラウザで実行できる形式にはなりません。今回はwebpackを使って解決します。

まずは必要なパッケージをインストールします。

> npm install --save-dev webpack webpack-cli babel-loader

webpack.config.js(webpackの設定ファイル)を作成します。

const path = require("path");

module.exports = {
  entry: "./src/index.ts",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "index.js",
  },
  resolve: {
    extensions: [".ts", ".js"],
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        exclude: /node_modules/,
        loader: "babel-loader",
      },
    ],
  },
  target: ["web", "es5"],
};

__dirnameをESLintがエラーとみなすのでnode環境だと教えてあげます。

module.exports = {
  extends: ["@cybozu/eslint-config/presets/typescript-prettier"],
  env: { node: true },
};

これまではsrcフォルダにトランスパイルしたファイルを生成していましたが、webpackの設定でdistに変更しました。manifestファイルもそれに合わせて更新します。

    "js": ["https://127.0.0.1:8000/dist/index.js"],
    "js": ["dist/index.js"],

webpackの実行

準備が整ったのでwebpackを実行します!

> npx webpack

トランスパイルされたindex.jsがdistフォルダに生成されています。kintoneアプリに適用すると・・・IE11でアクセスしてもエラーにならず、Object.values()が実行されます。

ここまでの設定

ここまでの設定は以下にあります。
https://github.com/potaracom/kintone-customize-template3

その5に続く

kintoneのカスタマイズ効率をあげよう5 – webpackのmodeオプション

この記事を書いた人