Closed manivannan-mp closed 2 years ago
We will have a way to "add" electron to a cli solution in the future.
I have an Electron app to write and I'm going to use Aurelia. If this in't yet in the CLI what should be my starting point. Go with the CLI or start with a Skeleton?
From my experience, the Skeleton will save you a lot of sweat. CLI is great but not ready for your app. You will have problems with manual plugin settings. But maybe it's already made easier to use plugins so I'm doing this to subscribe.
@MMJM You could use the cli to set up the basic Aurelia project but you would need to add some new tasks to handle pushing the source into the Electron app structure.
@EisenbergEffect I've managed to add task to build electron app on "au build" command. But now require js conflicts with electron (node) require function and gives following warning: "Unhandled rejection AssertionError: path must be a string".
The code which throws error:
if (typeof window.require === 'function') {
return new Promise(function (resolve, reject) {
return require(['aurelia-loader-default'], function (m) {
return resolve(new m.DefaultLoader());
}, reject);
});
}
Is there anyway to resolve this?
Yes, you need to patch electron itself. I think there's some docs on how to do this in the electron docs.
@EisenbergEffect Thanks, finally managed to get it running.
@nripendra Any chance you could share what you have done as I need to do the same thing.
@MMJM
I added script provided in electron docs (in FAQs page). Basic idea is to remove require, exports and module functions from window object.
<!DOCTYPE html>
<html>
<head>
<title>Aurelia</title>
</head>
<body aurelia-app="main">
<script>
window.nodeRequire = require;
delete window.require;
delete window.exports;
delete window.module;
</script>
<script src="scripts/vendor-bundle.js" data-main="aurelia-bootstrapper"></script>
</body>
</html>
If you are asking about build process. I have changed build.ts file in aurelia_project/tasks folder (generated by au new command).
import * as gulp from 'gulp';
import transpile from './transpile';
import processMarkup from './process-markup';
import processCSS from './process-css';
import {build} from 'aurelia-cli';
import * as project from '../aurelia.json';
var electron = require('gulp-electron');
var packageJson = require('../../package.json');
export default gulp.series(
readProjectConfiguration,
gulp.parallel(
transpile,
processMarkup,
processCSS
),
writeBundles,
gulp.parallel(
transpile,
processMarkup,
processCSS
),
gulp.parallel(
copyScripts,
copyOthers
),
buildElectron
);
function readProjectConfiguration() {
return build.src(project);
}
function writeBundles() {
return build.dest();
}
function copyScripts(){
return gulp.src(["scripts/**/*.*"]).pipe(gulp.dest("./electron-build/src/scripts"));
}
function copyOthers(){
return gulp.src(["./index.html", "./index.js", "./package.json", "./favicon.ico"]).pipe(gulp.dest("./electron-build/src"));
}
function buildElectron() {
return gulp.src("electron-build/src/*")
.pipe(electron({
src: './electron-build/src',
packageJson: "./package.json",
release: './electron-build/release',
cache: './electron-build/cache',
version: 'v1.3.1',
packaging: true,
platforms: ['win32-x64'],
platformResources: {
darwin: {
CFBundleDisplayName: packageJson.name,
CFBundleIdentifier: packageJson.name,
CFBundleName: packageJson.name,
CFBundleVersion: packageJson.version,
icon: 'gulp-electron.icns'
},
win: {
"version-string": packageJson.version,
"file-version": packageJson.version,
"product-version": packageJson.version,
"icon": 'favicon.ico'
}
}
}))
.pipe(gulp.dest("electron-build/release"));;
}
Here copyScripts, copyOthers and buildElectron are my custom functions. I'm using gulp-electron for creating electron app.
With these changes in place, au build builds electron app after bundling has been done.
Hope this helps.
One more thing:
In .vscode/settings.json file, I have following entries:
{
"typescript.tsdk": "node_modules/typescript/lib",
"files.exclude": {
"**/.git": true,
"**/.svn": true,
"**/.DS_Store": true,
"**/electron-build":true
}
}
Asar files gets locked by vscode, so I had to close vscode every time I wanted to build. Excluding electron-build folder seems to have helped.
@nripendra Fantastic. Thanks for all that information.
@nripendra I'm getting Gulp issues with the tasks. What versions of Gulp dependencies do you have in your package.json
@MMJM This is the entry in package.json, added by aurelia-cli "gulp": "github:gulpjs/gulp#4.0",
@nripendra
Hi, I have that version of Gulp in my package.json file too
"gulp": "github:gulpjs/gulp#4.0", "gulp-babel": "^6.1.2", "gulp-changed-in-place": "^2.0.3", "gulp-electron": "^0.1.3", "gulp-eslint": "^2.0.0", "gulp-notify": "^2.2.0", "gulp-plumber": "^1.1.0", "gulp-rename": "^1.2.2", "gulp-sourcemaps": "^2.0.0-alpha",
but I am still getting the error below. Do you have any ideas?
Starting 'copyOthers'... { uid: 16, name: 'copyScripts', branch: false, error: { TypeError: gulp.src is not a function at copyScripts (build.js:39:17) at bound (domain.js:280:14) at runBound (domain.js:293:12) at asyncRunner (F:\Research\test1\node_modules\async-done\index.js:36:18) at _combinedTickCallback (internal/process/next_tick.js:67:7) at process._tickDomainCallback (internal/process/next_tick.js:122:9)
@MMJM No idea. Are you using exact same code that is pasted above?
Error points out to "gulp.src", which I'm confused about. Looks like some how gulp object is being replaced??
I may be able to check, if you can post the exact code in build.js
@nripendra Ahhh silly me I named the build.ts file with a js extension. Doh. Thanks works a treat now
if you want imports and and typings you can do the following:
add script to index.html before aurelia loaded
<script>
window.nodeRequire = require;
delete window.require;
delete window.exports;
delete window.module;
</script>
create electron-fix.js
in root
define("electron", ['exports'], function (exports) {
if (window.nodeRequire) {
const electron = window.nodeRequire("electron");
exports["default"] = electron;
for (let key in electron) {
exports[key] = electron[key];
}
}
});
add to bundles dependencies:
{
"name": "electron",
"path": "../electron-fix"
},
typings:
npm install @types/electron
then you can use it like this:
import { remote } from 'electron';
export class App {
message = 'Hello World!';
sayHello() {
remote.dialog.showMessageBox({
message: "Hello",
buttons: ["OK"]
});
}
}
and if its of use: https://github.com/MeirionHughes/aurelia-cli-electron-app
npm install
au run -w
should load up an electron app, with custom frame and auto refresh when you change anything
@MeirionHughes Thanks for the information and link
just subscribing to this
Hi guys, after trying for a couple of days I found another approach using vs code task system based on the @nripendra reply.
create a new aurelia app using the cli, just like usual
add electron to the project using the command npm install electron --save-dev
add this script in the index.html file
<script>
window.nodeRequire = require;
delete window.require;
delete window.exports;
delete window.module;
</script>
edit package.json adding the line "main": "main.electron.js"
"name": "electronau",
"description": "An Aurelia client application.",
"version": "0.1.0",
"repository": {
"type": "???",
"url": "???"
},
"main": "main.electron.js",
"license": "MIT",
"dependencies": {
"aurelia-bootstrapper": "^1.0.0",
"aurelia-animator-css": "^1.0.0",
"bluebird": "^3.4.1",
"requirejs": "^2.3.2",
"text": "github:requirejs/text#latest"
}
create a file main.electron.js with the default code from electron documentation
configure the vs code to use the build task of aurelia cli
{
"version": "0.1.0",
"command": "cmd",
"isShellCommand": true,
"args": [
"/C"
],
"showOutput": "always",
"suppressTaskName": true,
"tasks": [
{
"taskName": "build",
"args": [
"au build"
]
}
]
}
configure vs code to launch electron (note the preLaunchTask property "preLaunchTask": "build"
)
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch",
"type": "node",
"request": "launch",
"program": "${workspaceRoot}/main.electron.js",
"stopOnEntry": false,
"args": [],
"cwd": "${workspaceRoot}",
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron",
"runtimeArgs": [
".",
"--enable-logging"
],
"env": {},
"console": "integratedTerminal",
"sourceMaps": false,
"preLaunchTask": "build"
},
{
"name": "Attach",
"type": "node",
"request": "attach",
"port": 5858,
"sourceMaps": false
}
]
}
press F5
:smile:
This works well, but i can make the auto refresh .. if someone have a idea how to do that please tell me ...
@MCorzo see https://github.com/MeirionHughes/aurelia-cli-electron-app
vscode:
npm install
au watch
(optional)that will give you debugging (of the client-side) plus auto-refresh when you change source files.
requires "msjsdiag.debugger-for-chrome"
extension for debugging; it should ask if you want to install it.
Any updates here on adding electron support? Seems like a gross oversight.
It's not an oversight. It's a feature on the list that no one from the community has contributed yet. We'd love you to submit a PR :)
Haha! Fair enough. Still stuck on getting routing working but I will plow one.
Interesting use case: some packages use nodejs specific packages. While this will likely not work in a browser environment, in electron these nodejs packages are available
electron-forge is the simplest way to get electron up and running with your favorite framework.
I can't help but notice that Aurelia is missing from the list of available frameworks and it looks like it could be as simple as submitting a pull request 😆 https://github.com/electron-userland/electron-forge-templates/
I'm happy to have a go at this. electron-forge automatically transpiles, so webpack or systemjs would be overkill. I'll see what might be suitable from the starter kits. Any idea how the bootstrapping would work? Along the lines of how the cli works?
@timfish If you can look into this, that would be great. Let us know what you find out.
https://github.com/starr0stealer/aurelia-electron-forge
Here is a project I tossed together using Electron Forge and the Aurelia Skeleton Navigation project. So far everything is working correctly that I have tested, and you are able to use electron packages
within Aurelia ViewModels, in the Welcome
ViewModel I added a Print To PDF feature to test it out.
@starr0stealer Thank you, i'm sure it will be of help
@starr0stealer I just gave it a test run unmodified it's working all so far, what I always have problems with is integrating things like materialize (with the bridge) (in other setups not the one you mention) and other css frameworks I'll give it a further test on the weekend to check and give you some feedback.
PD: This is motivating 😃
In the last few days doing some analysis on how to migrate an existing Electron Typescript application to Aurelia I created a poc project on my Github account aurelia-electron-app.
The main difference from all other project I found is that this fully compile all the code (main aka browser and renderer) and also allow shared code between the two.
It's still not completed (eg. testing framework, path constants and packaging) and some naming (eg. p_*) should be revised but it's fully functional.
To archieve it I made some changes in the cli:
More details can be found in the README file.
If you consider that these changes can be merged into the cli and the project structure (obviously without all the demo pages) is compliant with your cli template system I can provide some pull requests.
Any help is appreciated mostly if you want also support ESNext and WebPack.
@DarkHarlock I've got both build targets and added features in the pipeline for the CLI and once those foundations are in place I'll look into adding the Cordova and Electron platforms. Help would be greatly appreciated. :)
@jwx I don't know what changes have you done, but yes, I can help you in my spare time. Have you changed something about where files are loaded? My major problem was that all not bundled files are loaded from the source folder instead that from the target, so I have patched it with this. This is not a perfect solution because also files that will never loaded by RequireJs/SystemJs are put in paths (but this could be handled by replacing the flag with an object that contains some glob matching).
Changes here are about the possibility to have some files compiled (at this time Typescript, but i think should be the same for javascript/esnext) but not bundled. I think this is a must, Electron is based on NodeJs and so not all the sources should be loaded/bundled as amd modules by the cli.
What I would like to know is if it is acceptable to manage externally (through task customization) files that are not included in the bundles or if they should be copied, eg. with a directive inside the aurelia.json
, in the output folder.
In my case (from transpile.ts) I do an As Is
copy with a little patch on sourcemaps:
return eventStream.merge(dts, src)
.pipe(plumber({ errorHandler: notify.onError('Error: <%= error.message %>') }))
.pipe(sourcemaps.init())
.pipe(typescriptCompiler())
.pipe(sourcemaps.write({ sourceRoot: "src", addComment: false }))
.pipe(build.bundle())
.pipe(sourcemaps.write({ //all not bundled files are piped here. Those files are umd modules so can be shared between DOM and NodeJs
sourceRoot: (file) => {
let filePathSrc = path.normalize(file.path);
let filePathDest = filePathSrc.replace(sourceFolder, destinationFolder);
let mapSourceRoot = path.relative(
path.dirname(filePathDest),
sourceFolder
);
let ret = mapSourceRoot.replace(/[\\\/]+/g, '/');;
return ret;
}
}))
.pipe(gulp.dest(project.platform.output))
I really need to avoid 2 build steps (the first one for NodeJs - CommonJs modules, and the second one for the DOM - amd/bundle modules).
I created a boilerplate Electron Aurelia app where both processes bundle with webpack.
The app uses a native node module to list attached USB devices.
I'm doubting that this configuration will split shared code between entry points.
@timfish do you mind stuffing your setup into aurelia-contrib org and maintaining it there?
@Alexander-Taran can do.
I still want to simplify the config.
It's also possible to get Aurelia + Electron working without Webpack with a much simpler setup but it would lack bundling of node_modules
. I'm tempted to see what the new cli bundler can do but I'm guessing it can only target the browser which won't work for the Electron main process.
Yes, the new cli bundler only targets browser.
@zewa666 could you share some inside on how did you use cli bundler to build an electron app?
It's a very specific scenario in my case so not sure if its worth to share the exact approach. What I'll gonna do though is create a new sample with the new cli requirejs bundler approach and share it via discourse.
actually instead of supporting electron directly, it might be more interesting to add support for capacitor, which seems to have made electron very easy.
@xenoterracide does capacitor support desktop applicatons? As far as I have seen only iOS, Andoid and PWAs. Electron can be used for windows and linux applications too...
@3cp maybe maybe..
BTW, easiest way to avoid global require()
issue for using Requirejs and electron together is to use global requirejs()
instead.
The skeleton files are now in https://github.com/aurelia/v1 now. Please create an issue or PR there for adding electron/capacitor skeleton.
Personally I have no experience with them (I prefer native apps), so I'm unlikely to work on this feature. But surely any contribution from the community is welcome.
or How can we have custom build task to support electrol.