LoginSignup
4
9

More than 3 years have passed since last update.

Electron + Webアプリ(Nuxt.js)でMonorepoな環境を作る

Posted at

はじめに

Nuxt.jsとElectronでWebとデスクトップアプリを両立させる方法として、Monorepoとして開発していくのがいいのではないかと思い、環境構築をしてみました。
その手順を残しておきたいと思います。

この記事も参考になると思うので、是非合わせて読んでみてください!
Electron + Nuxt.js + TypeScriptの環境構築

この記事のコードのリポジトリはこちらです。

ディレクトリ構成

以下のようなディレクトリ構成で構築するため、最初に設定を行います。

.
├── packages
│   ├── app
│   │   └── App(Electron)のプロジェクト
│   └── web
│       └── Web(Nuxt.js)のプロジェクト
├── package.json
└── yarn.lock

まずは、プロジェクトのディレクトリを作ります。

$ midir nuxt-electron-monorepo-example
$ cd nuxt-electron-monorepo-example
$ mkdir packages
$ mkdir packages/app
$ mkdir packages/web

yarn initをしてpackage.jsonを生成し、package.jsonにmonorepo用のコンフィグを書き足します。

$ yarn init
package.json
{
  ...
  "workspaces": {
    "packages": [
      "packages/app",
      "packages/web"
    ],
    "nohoist": [
      "**"
    ]
  }
}

この設定の意味は、packages/apppackages/webをそれぞれ別のプロジェクトとして扱い、nohoist"**"に設定することで、node_modulesを巻き上げないようにしています。
本来、node_modulesはルートディレクトリに巻き上げられてそれぞれのプロジェクトではそれを参照するようになるのですが、問題が起こりやすい(ように感じる)ので今回はこのような設定にしています。
本来、monorepoではhoistが働くことでnode_modulesが削減されるなどのメリットがあります。

Nuxt.jsのプロジェクトを作る

新しくNuxtのプロジェクトを作る場合は、create-nuxt-appを使って作ってください。
今回は、以下のような設定でプロジェクトを作っているものとして、進めていきますが、必要に合わせて読み替えながら進めてください。

既にあるプロジェクトをElectronに移植する場合は、プロジェクトの中身を全てpackages/webディレクトリの中に移動してください。
.gitディレクトリや、.githubディレクトリ、CI/CD用の設定ファイルなどは移動しないように注意してください。

$ cd packages/web
$ yarn create nuxt-app .
create-nuxt-app v3.3.0
✨  Generating Nuxt.js project in .
? Project name: web
? Programming language: TypeScript
? Package manager: Yarn
? UI framework: (Use arrow keys)
? UI framework: 
? UI framework: Vuetify.js
? Nuxt.js modules: (Press <space> to select, <a> to toggle all, <i>
 to invert selection)
? Linting tools: ESLint, Prettier, Lint staged files, StyleLint
? Testing framework: Jest
? Rendering mode: Single Page App
? Deployment target: Static (Static/JAMStack hosting)
? Development tools: (Press <space> to select, <a> to toggle all, <
i> to invert selection)
? Version control system: None

この時に、package.jsonnameプロパティがパッケージ名(web)と同じになるようにしてください。
また、Version control systemはNoneを選んでおきましょう。

Electronのプロジェクトを作る

packages/appのなかにElectronのプロジェクトを作っていきます。

$ cd packages/app

Electron関係のパッケージを追加する

必要なパッケージを追加していきます。

$ yarn add --dev \
  electron  \
  electron-builder \
  electron-devtools-installer \
  typescript \
  @types/electron-devtools-installer

ビルド時に使うのでtypescriptcross-envを入れておきます。

$ yarn add --dev \
  typescript \
  cross-env

ついでにeslinthusky, lint-stagedも入れておきましょう

$ yarn add --dev \
  eslint \
  @typescript-eslint/eslint-plugin \
  prettier \
  eslint-config-prettier \
  eslint-plugin-prettier \
  husky \
  lint-staged

後で使うので、npm-run-allも入れておきます。

$ yarn add --dev npm-run-all

Electronのスクリプトを用意する

長くなるので、ここは省略します。
pacages/app/src/mainのスクリプトを参考にして実装してください。

tsconfig.jsonの設定で../../distに成果物を出力するようにしているのがポイントです。

rendererのシンボリックリンクを貼ってビルドできるようにする

packages/app/rendererpackages/webを指すようにシンボリックリンクを貼ります。

$ cd packages/app/src
$ ln -s ../../web renderer

Nuxtのプロジェクトのコンフィグを修正する

cross-evnでコンフィグを書き換えるためにenvの設定を作ります。

packages/web/env

そして、nuxt.config.jsをapp用のコンフィグとweb用のコンフィグをenvの値によって変えられるように記述します。

packages/web/nuxt.config.js
const appConfig = {
  ...baseConfig,
  // ssr: false,
  // target: 'static',
  dev: isDev,
  server: {
    host: env.NUXT_HOST,
    port: env.NUXT_PORT,
  },
  /*
   ** Electronではhashモードじゃないとだめ
   ** https://nklayman.github.io/vue-cli-plugin-electron-builder/guide/commonIssues.html#blank-screen-on-builds-but-works-fine-on-serve
   */
  router: {
    ...baseConfig.router,
    base: undefined,
    mode: 'hash',
  },
  build: {
    ...baseConfig.build,
    extend(config, ctx) {
      baseConfig.build?.extend && baseConfig.build?.extend(config, ctx)
      if (!isDev) {
        // absolute path to files on production (default value: '/_nuxt/')
        // @ts-ignore
        config.output.publicPath = '_nuxt/'
      }
      config.target = 'web'
      config.node = {
        // eslint-disable-next-line @typescript-eslint/naming-convention
        __dirname: !isProduction,
        // eslint-disable-next-line @typescript-eslint/naming-convention
        __filename: !isProduction,
      }
    },
  },
  loaders: {
    ts: {
      loaderOptions: {
        compileOptions: {
          target: 'es5',
          module: 'commonjs',
        },
      },
    },
  },
  generate: {
    ...baseConfig.generate,
    dir: '../../packages/app/dist/nuxt-build',
  },
  telemetry: false,
}

const config = isApp ? appConfig : baseConfig

export default config

packages/web/nuxt.config.js

このように、ビルド時のenvによってコンフィグを切り替えられるようにします。

scriptsを修正する

そして、ビルドできるようにwebとappのpackage.jsonを編集します。
packages/app/package.jsonpackages/web/package.jsonを参考にしてください。

webの方でもcross-envを使うので、忘れずに追加しておいてください。

$ cd packages/web
$ yarn add --dev cross-env

ルートのpackage.jsonを編集する

ルートから簡単にdevやbuildを実行できるようにscriptsを編集します。

package.json
{
  ...
  "scripts": {
    "dev:app": "yarn workspace app dev",
    "dev:web": "yarn workspace web dev",
    "build:app": "yarn workspace app build",
    "build:web": "yarn workspace web build"
  },
  ...
}

これで環境構築は終了です!

まとめ

今回、Nuxt.jsで作成したプロジェクトをElectronに移植するニーズがあり、試行錯誤しながら環境構築をしていました。
せっかく苦労して作り上げたので、もし同じ問題で困っている人がいれば助けになれば良いかなぁと思います!

もっといい方法があるよって人は是非コメントで教えてください!
最後まで読んでいただきありがとうございました!!

4
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
9