【React初心者】React + Electron + VSCodeでデバックまでのHello World
ElectronとReactでアプリケーションを作成する際に、vscodeでブレークポイントを張ってデバックできるまでに結構手こずったので備忘録として。
環境
windows10
node.js:ver10.15.1
Visual Studio Code :ver1.36.0
最初に
まず空のフォルダを作成(React_Electron_VsCode_HelloWorldフォルダとする)
VsCodeを開き、React_Electron_VsCode_HelloWorldフォルダを開く
VsCodeの下からTERMINALを引っ張り出して、以下を実行
- npm init -y
(-yを付けない場合、いろいろ聞かれるのですべてENTER)
フォルダにpackage.jsonができる
最終的なフォルダ構成
.vscode (vscodeのデバックの設定)
┣ launch.json
dist (npm run buildでここにファイルが出力される)
┣ index.js
┣ index.js.map
node_modules (npm install できるフォルダ)
src
┣ hello.js
┣ index.js
index.html
main.js
package.json
package-lock.json
webpack.config.js
npm installでいろいろインストールする
まずelectron
- npm install --save-dev electron
次にBabel系
- npm install --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react
React系
- npm install --save-dev react react-dom
Webpack系
- npm install --save-dev webpack webpack-cli
"scripts" に"build"を追加
webpack4用のビルド用のコマンド
最終的にnpm run build でビルドできる
package.jsonが以下のようになる
{ "name": "react_electron_vscode_helloworld", "version": "1.0.0", "description": "", "main": "main.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack --mode development" }, "author": "", "license": "ISC", "dependencies": {}, "devDependencies": { "babel-core": "^6.26.3", "babel-loader": "^7.0.0", "babel-preset-es2015": "^6.24.1", "babel-preset-react": "^6.24.1", "electron": "^5.0.6", "react": "^16.8.6", "react-dom": "^16.8.6", "webpack": "^4.35.3", "webpack-cli": "^3.3.5" } }
index.html
<!DOCTYPE html> <html> <head> <meta charset='utf-8' /> </head> <body> <div id='root'></div> <script src='dist/index.js'></script> </body> </html>
src= dist/index.jsを指定しているが、最終的にnpm run buildしたときに生成されるもので、出力フォルダはwebpack.config.jsで指定している
main.js
// Electronの実行に必要なモジュールを取り込む const electron = require('electron') const path = require('path') const url = require('url') const app = electron.app const BrowserWindow = electron.BrowserWindow // Electronのライフサイクルを定義 let mainWindow // メインウィンドウを表す変数 app.on('ready', createWindow) app.on('window-all-closed', function () { if (process.platform !== 'darwin') app.quit() }) app.on('activate', function () { if (mainWindow === null) createWindow() }) // ウィンドウを作成してコンテンツを読み込む function createWindow() { mainWindow = new BrowserWindow({ width: 800, height: 600 }) mainWindow.loadURL(url.format({ // 読み込むコンテンツを指定 --- (※1) pathname: path.join(__dirname, 'index.html'), protocol: 'file:', slashes: true })) // //ディベロッパツールを開く // mainWindow.webContents.openDevTools() // ウィンドウが閉じるときの処理 mainWindow.on('closed', function () { mainWindow = null }) }
webpack.config.js
// Reactを変換するためのWebpackの設定ファイル const path = require('path') const webpack = require('webpack') // 変換対象から除外するモジュール --- (※1) const externalPlugins = new webpack.ExternalsPlugin('commonjs', [ 'app', 'auto-updater', 'browser-window', 'content-tracing', 'dialog', 'electron', 'global-shortcut', 'ipc', 'menu', 'menu-item', 'power-monitor', 'protocol', 'tray', 'remote', 'web-frame', 'clipboard', 'crash-reporter', 'screen', 'shell' ]) module.exports = { entry: { index: path.join(__dirname, 'src', 'index.js') }, output: { path: path.join(__dirname, 'dist'), filename: '[name].js' }, // devtool: 'cheap-module-eval-source-map', devtool: '--source-maps', //元のソースコードと紐づける。babelでトランスパイルしても、元のコードでブレイクを張れる target: 'node', module: { rules: [ { test: /.js$/, loader: 'babel-loader', options: { presets: ['es2015', 'react'] } }, { test: /\.css$/, loaders: ['style-loader', 'css-loader'] } ] }, plugins: [ externalPlugins ] }
npm run buildでビルドするinputファイルとoutputファイルを指定している
index.js
import React from 'react'; import ReactDOM from 'react-dom'; import Hello from './hello'; ReactDOM.render( <Hello />, document.getElementById('root') );
hello.js
import React, { Component } from 'react'; class Hello extends Component { constructor(props) { super(props) this.state = { count: 0 } } CountFunction() { this.setState({count: this.state.count + 1}) } render() { return ( <div className='HelloCount'> <div>{this.state.count}</div> <button onClick={(e) => this.CountFunction()}>Hello World</button> </div> ); } } export default Hello;
launch.json
{ "version": "0.2.0", "configurations": [ { "name": "Debug Renderer Process", "type": "chrome", "request": "launch", "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron", "windows": { "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd" }, "runtimeArgs": [ "${workspaceRoot}/main.js", "--remote-debugging-port=9222" ], "sourceMaps": true, "webRoot": "${workspaceRoot}" }, { "name": "Debug Main Process", "type": "node", "request": "launch", "cwd": "${workspaceRoot}", "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron", "windows": { "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd" }, "program": "${workspaceRoot}/main.js", "protocol": "inspector", } ] }
以上で、npm run buildすると、以下のようなエラーがでる
”babel-core” ver 6を使うなら、"babel-loader" ver7を使えと言われるので、package.jsonで
"babel-core": "^6.26.3",
"babel-loader": "^7.0.0"
などを指定して、npm install
もう一度、npm run buildでビルドが成功したら、Visal Studio Codeで"Debug Renderer Process"
でブレークポイントを張れるはず。
ちなみに、作業フォルダまでのパスに空白があるとエラーになります。
(onedriveなどで作業している場合は注意)
以上