Nuxt.js+Electronを試してみる


注意

本記事はElectronなどのバージョンが古いときのもののため新しく記事を書き直しました。
最新版はこちら

はじめに

electron-templateがあまりメンテされてない感じだったり、ビルド後もローカルでサーバーを立てて実行していたりだったので、一度自分で環境を作ってみようって感じの記事です。

この記事の手順で作ったものをいれたリポジトリ → クローズしました

セットアップ

Nuxt.jsの環境用意

とりあえずcreate-nuxt-appでNuxt.jsの環境を用意する

npx create-nuxt-app my-project

セットアップのときに選択した項目は下記

? Project name my-project
? Project description My badass Nuxt.js project
? Use a custom server framework none
? Use a custom UI framework none
? Choose rendering mode Single Page App
? Use axios module no
? Use eslint no
? Use prettier no
? Author name tamfoi
? Choose a package manager npm

Nuxt.jsの設定周りを変更する

pagesなどのディレクトリを変更

appディレクトリに全部いれるようにする

nuxt.config.js
module.exports = {
  ...
  srcDir: 'app',
  ...
}

buildした時にサーバー無しで実行できるようにする

nuxt.config.js
module.exports = {
  ...
  router: {
    mode: 'hash'
  },

  build: {
    extend(config, ctx) {
      config.output.publicPath = './_nuxt/'
    }
  },
  ...
}

electron周りの準備

electronとelectron-builderをインストール

npm install --save-dev electron
npm install --save-dev electron-builder

基本的にelectron-templateを参考にしながら設定を追加していく。
違うのはmain.jsでexe化後はローカルサーバーは建てずに起動するようにしたとかくらい

package.json
{
  "name": "my-project",
  "version": "1.0.0",
  "description": "My perfect Nuxt.js project",
  "author": "tamfoi",
  "private": true,
  "main": "main.js",
  "scripts": {
    "dev": "cross-env NODE_ENV=development electron .",
    "build": "nuxt build && electron-builder"
  },
  "build":{
    "appId": "my-project",
    "directories": {
      "output": "build"
    }
  },
  "dependencies": {
    "cross-env": "^5.2.0",
    "nuxt": "^2.0.0"
  },
  "devDependencies": {
    "electron": "^3.0.10",
    "electron-builder": "^20.38.0",
    "nodemon": "^1.11.0"
  }
}

nuxt.config.js
module.exports = {
  ...
  dev: process.env.NODE_ENV === 'development',
  ...
  build: {
    extend(config, ctx) {
      config.output.publicPath = './_nuxt/'
      config.target = 'electron-renderer'
    }
  }
}
main.js
/*
**  Nuxt
*/
const http = require('http')
const { Nuxt, Builder } = require('nuxt')
let config = require('./nuxt.config.js')
config.rootDir = __dirname // for electron-builder
// Init Nuxt.js
const nuxt = new Nuxt(config)
const builder = new Builder(nuxt)
const server = http.createServer(nuxt.render)
// Build only in dev mode
let _NUXT_URL_ = '';
if (config.dev) {
    builder.build().catch(err => {
        console.error(err) // eslint-disable-line no-console
        process.exit(1)
  })
  // Listen the server
  server.listen()
  _NUXT_URL_ = `http://localhost:${server.address().port}`
  console.log(`Nuxt working on ${_NUXT_URL_}`)
}else{

  _NUXT_URL_ = 'file://' + __dirname + '/dist/index.html';

}


/*
** Electron
*/
let win = null // Current window
const electron = require('electron')
const app = electron.app
const newWin = () => {
    win = new electron.BrowserWindow({})
    win.maximize()
    win.on('closed', () => win = null)
    if (config.dev) {
        // Wait for nuxt to build
        const pollServer = () => {

            http.get(_NUXT_URL_, (res) => {
                if (res.statusCode === 200) { 
                    win.loadURL(_NUXT_URL_) 
                } else { 
                    console.log("restart poolServer");
                    setTimeout(pollServer, 300) 
                }
            })
            .on('error', pollServer)

    }
        pollServer()
    } else { 
        return win.loadURL(_NUXT_URL_) 
    }
}
app.on('ready', newWin)
app.on('window-all-closed', () => app.quit())
app.on('activate', () => win === null && newWin())

最後に

とりあえず動いたので一旦記事化しました。
更新あればこの記事を編集する形にするか、別記事で書こうと思います。
特にmain.jsはまだ改良の余地がありそうな気がしてます。開発時の起動の遅さとかどうにかしたいです。

参考

nuxtでgenerateしたファイルをローカルで実行する。
How to run a nuxt generated website from filesystem?