はじめに
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
{
...
"workspaces": {
"packages": [
"packages/app",
"packages/web"
],
"nohoist": [
"**"
]
}
}
この設定の意味は、packages/app
とpackages/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.json
のname
プロパティがパッケージ名(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
ビルド時に使うのでtypescript
とcross-env
を入れておきます。
$ yarn add --dev \
typescript \
cross-env
ついでにeslint
とhusky
, 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/renderer
がpackages/web
を指すようにシンボリックリンクを貼ります。
$ cd packages/app/src
$ ln -s ../../web renderer
Nuxtのプロジェクトのコンフィグを修正する
cross-evnでコンフィグを書き換えるためにenvの設定を作ります。
そして、nuxt.config.js
をapp用のコンフィグとweb用のコンフィグをenvの値によって変えられるように記述します。
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
このように、ビルド時のenvによってコンフィグを切り替えられるようにします。
scripts
を修正する
そして、ビルドできるようにwebとappのpackage.json
を編集します。
packages/app/package.jsonとpackages/web/package.jsonを参考にしてください。
webの方でもcross-env
を使うので、忘れずに追加しておいてください。
$ cd packages/web
$ yarn add --dev cross-env
ルートのpackage.jsonを編集する
ルートから簡単にdevやbuildを実行できるようにscripts
を編集します。
{
...
"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に移植するニーズがあり、試行錯誤しながら環境構築をしていました。
せっかく苦労して作り上げたので、もし同じ問題で困っている人がいれば助けになれば良いかなぁと思います!
もっといい方法があるよって人は是非コメントで教えてください!
最後まで読んでいただきありがとうございました!!