追記
Electronのv0.35からAPIが大幅に変更され、このような問題は発生しなくなりました
ElectronアプリをTypeScriptで書いてると
error TS2300: Duplicate identifier 'export='
というエラーがよく出ます。メインプロセスとレンダラプロセスの両方にipcという名前のモジュールがあるのが原因です。つらいのでなんとかしたいと思います。
はじめに
まず、dtsmでインストールした型定義ファイルをbundle.d.ts
から使わずにrenderer.d.ts
やmain.d.ts
に分けて、どちらか一方を参照するようにします。
/// <reference path="./github-electron/github-electron-main.d.ts"/>
/// <reference path="./github-electron/github-electron-renderer.d.ts"/>
この状態でプロジェクトを使ってコンパイル(tsc -p
)するとやはり例のエラーがでます。
レンダラプロセスとメインプロセスでプロジェクトを分けてもよかったのですが、今回は型定義ファイルをちょっといじってipc-mainとipc-rendererというローカルモジュールを作成して解決しました。
型定義ファイルの変更
Electronの型定義ファイルをなんらかの方法でプロジェクトのディレクトリに落としてきます。その後、
declare module 'ipc' {
var ipc: NodeJS.EventEmitter;
export = ipc;
}
declare module 'ipc' {
var inProcess: GitHubElectron.InProcess;
export = inProcess;
}
と書かれている部分を編集して
declare module 'ipc-main' {
var ipc: NodeJS.EventEmitter;
export = ipc;
}
declare module 'ipc-renderer' {
var inProcess: GitHubElectron.InProcess;
export = inProcess;
}
とします。
ローカルモジュールの作成
詳しくは npm 2.0.0でローカルモジュールを使ってrequire('../../../')を回避する を参考にしてください。(ちょっと古い記事ですがv3.4.0でもこの通り動きました)
適当なディレクトリを作りその中にipc-main、ipc-rendererという名前のディレクトリを作成し、それぞれのディレクトリの中に適切にjsファイルとpackage.jsonを作成します。
if (process.type !== "browser") {
throw new Error("This module can only load from main process");
}
module.exports = require("ipc");
if (process.type !== "renderer") {
throw new Error("This module can only load from renderer process");
}
module.exports = require("ipc");
あとはnpm install --save hoge/ipc-main hoge/ipc-renderer
を実行(モジュールを作成したパスに合わせてhogeの部分は変更してください)するだけで完成です。
使用例
/// <reference path="../typings/main.d.ts"/>
import ipc = require("ipc-main");
// あるいは
import * as ipc from "ipc-main";
import ipc = require("ipc-renderer");
// あるいは
import * as ipc from "ipc-renderer";