What is the recommended way to set up an Electron project for development using Parcel for bundling. I have seen a number of boilerplate repos that user the Parcel development server to serve and hot-reload assets for development, however, if you try to user a node/Electron module, you get an expected error with target=browser.
If you use target=electron, you don't get the development server starting up (per a previous issue cited below).
I can source directly from my output folder, but that seems inelegant and hacky. Detail below. I feel like I am missing some small insight around Parcel and bundling to get this working smoothly.
I ran through a few different setup to see what worked:
yarn start:html:browser
This loads, HMR works, however if you uncomment the import { remote } from 'electron' line in index.js it causes an expected fs.existsSync because its trying to use the node API with target=browser.
yarn start:html:electron
If I try to remedy this by setting target=electron, everything seems to work fine but the dev server does not start so I can't link to it from my render process -> index.html. I guess this is intentional per this issue, but in my user case this would be helpful.
https://github.com/parcel-bundler/parcel/issues/1005
Is there a way to force it on, or is there a better way to setup this type of Electron project in general?
build/ folder)start:js:electron:no-url
If I aim Parcel at just the render process index.js file, and source it directly from the output folder as ../build/index.js in the index.html file (you have to manually comment/uncomment the lines in index.html), the HTML renders, however, the import './App.css' in a JS file does not work for some reason. I have to link to it directly in the index.js file in the build folder (../build/index.css). This all seems hacky but it does work and HMR works as well.
I tried using creating bundle-script.js to for the dev server on while targeting a .js file (target=electron + running the local dev server via middleware) but the HTML seems to be bundled up in a .js file which causes it to fail (Uncaught SyntaxError: Unexpected token <).
Honestly, I have not idea what I'm doing wrt to the Express server here.
This is a very simple sample project which I used to do tests to get my real project working. The commands
https://github.com/rkpatel33/parcel-react-electron-example
| Software | Version(s) |
| ---------------- | ---------- |
| Parcel | 1.9.7
| Node | 10.6.0
| npm/Yarn | 1.7.0
| Operating System | OS High Sierra 10.13.6
So I seem to have stumbled into a solution using the API method above. I commented out the:
publicUrl: './', // The url to server on, defaults to dist
Line, and the below works with target=electron and the HMR/dev server running. However I still don't fully understand why that worked since I had left it as the default.
If someone has a non-API method of getting the same result or better way or setting up Electron, I would still love to hear it. Thx.
const Bundler = require('parcel-bundler');
const Path = require('path');
const app = require('express')();
// Entrypoint file location
const file = Path.join(__dirname, './src/index.html');
// Bundler options
const options = {
outDir: './build', // The out directory to put the build files in, defaults to dist
outFile: 'index.html', // The name of the outputFile
// publicUrl: './', // The url to server on, defaults to dist
watch: true, // whether to watch the files and rebuild them on change, defaults to process.env.NODE_ENV !== 'production'
cache: true, // Enabled or disables caching, defaults to true
cacheDir: '.cache', // The directory cache gets put in, defaults to .cache
contentHash: false, // Disable content hash from being included on the filename
minify: false, // Minify files, enabled if process.env.NODE_ENV === 'production'
scopeHoist: false, // turn on experimental scope hoisting/tree shaking flag, for smaller production bundles
target: 'electron', // browser/node/electron, defaults to browser
https: false, // Serve files over https or http, defaults to false
logLevel: 3, // 3 = log everything, 2 = log warnings & errors, 1 = log errors
hmrPort: 0, // The port the HMR socket runs on, defaults to a random free port (0 in node.js resolves to a random free port)
sourceMaps: true, // Enable or disable sourcemaps, defaults to enabled (not supported in minified builds yet)
hmrHostname: '', // A hostname for hot module reload, default to ''
detailedReport: false // Prints a detailed report of the bundles, assets, filesizes and times, defaults to false, reports are only printed if watch is disabled
};
async function runBundle() {
// Initializes a bundler using the entrypoint location and options provided
const bundler = new Bundler(file, options);
// Let express use the bundler middleware, this will let Parcel handle every request over your express server
app.use(bundler.middleware());
app.listen(1234);
// Run the bundler, this returns the main bundle
// Use the events if you're using watch mode as this promise will only trigger once and not for every rebuild
const bundle = await bundler.bundle();
}
runBundle();
Thanks for the sums up, I approve these issues since I've gone through all these steps too. I'd love to have a solution that just works, step #2 seems like the most intuitive way.
I have the same problem. I try to use parcel to build my electron app but without success. Could we just serve app on localhost when using the electron target? Is the electron target only used for the main process right now?
Same problem, don't know what to do... In setup #1 I noticed that replacing import {remote} from "electron" by const {remote} = window.require("electron"); actually works, but this is not a viable solution.
Looks like it's being addressed for Parcel 2 #2492
Although that still appears to be a while away.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs.
Most helpful comment
Same problem, don't know what to do... In setup #1 I noticed that replacing
import {remote} from "electron"byconst {remote} = window.require("electron");actually works, but this is not a viable solution.