Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate electron plugin #108

Closed

Conversation

gwleuverink
Copy link
Contributor

@gwleuverink gwleuverink commented Sep 23, 2024

Summary

This PR pulls the electron plugin into this repo.

I've landed on the tarball approach @simonhamp proposed in https://github.com/orgs/NativePHP/discussions/348

A couple of changes had to be made in order to make it work. Because a lot of files changed I've listed the steps I took below. I've also commented the changes that might need some more clarification in the diff.

Couple things I did:

  1. pulled in the plugin into resources/js/electron-plugin
  2. some light cleanup, removed duplicate security.md & moved CI script to this repo (needs testing!)
  3. updated package.json to point to the local dependency
  4. updated the native:serve command to do a clean install (so changes in electron-plugin come through)
  5. updated the native:build command to pack the electron plugin as a tarball & do a clean install of the tarball after running npm update. Clean install is needed because the tarball is not versioned, it will not update otherwise.

Note that this packing step is only needed when running native:build.

For your consideration

  1. I noticed I get a lot of linting squigglies in the electron plugin after moving it to this project. Probably a configuration issue. Would you like me to check that out in this PR or separately?

  2. When making changes to the electron-plugin while running build:watch you still need to restart the native:serve command to see your changes. Might be good to add that to the docs Docs laravel#364

  3. When running the native:build & native:serve command the electron plugin is not built, You have to do so beforehand if any changes where made. This makes sense, since a composer install will come with the latest compiled js. But might be confusing for contributors. Maybe something to consider for the docs.

Closing

As before, feel free to disregard or use only as a reference if you're not up for merging. I realise there was no concrete ask to work on this. I was experimenting a little & figured I might as well finish it 😅 If you need me to make changes and I'll do so as soon as I can.

Process::path(__DIR__.'/../../resources/js')
->env($this->getEnvironmentVariables())
->forever()
->run('npm ci ./electron-plugin/nativephp-electron-plugin-tarball.tgz', function (string $type, string $output) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to do a clean install here, because the tarball version was locked. It won't update when changes where made to the electron-plugin otherwise

@@ -45,7 +45,7 @@ protected function getCommandArrays(string $type = 'install'): array
{
$commands = [
'install' => [
'npm' => 'npm install',
'npm' => 'npm ci',
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to do a clean install here as well. Otherwise changes to electron-plugin wont come through.

For example when running npm run build:watch from the plugin directory & running artisan native:serve in a different terminal session.

Having to clean install all dependencies might slow things down a little bit. This is a tradeoff but it could be that the cache negates this. Did not benchmark this yet

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great if we didn't have to ci but could rather just force the electron-plugin to be reinstalled from scratch...

@@ -0,0 +1,65 @@
{
"name": "@nativephp/electron-plugin",
"version": "tarball",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might seem weird. I removed the version at first, but npm pack requires a package name and version.
the created taball then includes that version in the filename: nativephp-electron-plugin-tarball.tgz.

In our case we need the tarball to have the same name, hence this string. The filename of the tarball is referenced in the Build command here:

->run('npm ci ./electron-plugin/nativephp-electron-plugin-tarball.tgz', function (string $type, string $output) {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we randomised the version at runtime and injected this into the package.json, would that negate the need for ci?

Does the version need to be anything specific (incrementing/increasing?) or can it just be random?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it can be random, but we'll have to store the latest version name so we can refer to it in the build script by name.

Can't think of any benefits for that approach from the top of my head. The end result will be the same with some extra overhead. Unless I'm missing something.

In the build script we're only doing a clean install of the plugin. The rest of the dependencies are updated as normal

Copy link
Contributor Author

@gwleuverink gwleuverink Sep 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The serve command does do a clean install for everything. I'm not super happy with that yet.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, that feels very wasteful

@gwleuverink gwleuverink changed the title [RFC-348] Integrate electron plugin Integrate electron plugin Sep 24, 2024
@gwleuverink gwleuverink marked this pull request as ready for review September 24, 2024 07:03
@simonhamp
Copy link
Member

I'll need to take a good look through this when I'm back from vacation, but this is really promising! Thanks so much 🙏🏼

@RobertWesner
Copy link
Contributor

I am not that familiar with how NodeJS handles it internally but would a Subpath Import mitigate the need for the whole tarball process? It most likely requires you to change the imports inside the plugin, but does not seem to use symbolic links. Seems to me to be the cleanest way to integrate the plugin without restructuring the entire project.

@simonhamp
Copy link
Member

@RobertWesner this is the first time I've come across imports in a package.json file... I think you're right, it may be a much cleaner approach, but it would need some working through.

@gwleuverink have you ever used that before?

@RobertWesner
Copy link
Contributor

RobertWesner commented Oct 2, 2024

To check whether we can use subpath imports in place of the tarball I integrated the plugin here. Was more straightforward than expected and worked mostly out of the box, just had to change the plugin export to ES6. It does run without issue while using native:serve. Yet when I try native:build linux x64 the resulting .AppImage causes this error:

(node:97146) UnhandledPromiseRejectionWarning: Error: spawn /tmp/.mount_Larave5gKNJn/resources/app.asar.unpacked/resources/php/php ENOENT
    at ChildProcess._handle.onexit (node:internal/child_process:286:19)
    at onErrorNT (node:internal/child_process:484:16)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
(Use `laravel --trace-warnings ...` to show where the warning was created)
(node:97146) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)

Full log with --trace-warnings:

Error: spawn /tmp/.mount_LaraveMZrpw2/resources/app.asar.unpacked/resources/php/php ENOENT
    at ChildProcess._handle.onexit (node:internal/child_process:286:19)
    at onErrorNT (node:internal/child_process:484:16)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
  errno: -2,
  code: 'ENOENT',
  syscall: 'spawn /tmp/.mount_LaraveMZrpw2/resources/app.asar.unpacked/resources/php/php',
  path: '/tmp/.mount_LaraveMZrpw2/resources/app.asar.unpacked/resources/php/php',
  spawnargs: [ 'artisan', 'native:config' ],
  cmd: '/tmp/.mount_LaraveMZrpw2/resources/app.asar.unpacked/resources/php/php artisan native:config',
  stdout: '',
  stderr: ''
}
Electron API server started on port 4019
Error: spawn /tmp/.mount_LaraveMZrpw2/resources/app.asar.unpacked/resources/php/php ENOENT
    at ChildProcess._handle.onexit (node:internal/child_process:286:19)
    at onErrorNT (node:internal/child_process:484:16)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
  errno: -2,
  code: 'ENOENT',
  syscall: 'spawn /tmp/.mount_LaraveMZrpw2/resources/app.asar.unpacked/resources/php/php',
  path: '/tmp/.mount_LaraveMZrpw2/resources/app.asar.unpacked/resources/php/php',
  spawnargs: [ 'artisan', 'native:php-ini' ],
  cmd: '/tmp/.mount_LaraveMZrpw2/resources/app.asar.unpacked/resources/php/php artisan native:php-ini',
  stdout: '',
  stderr: ''
}
Starting PHP server... /tmp/.mount_LaraveMZrpw2/resources/app.asar.unpacked/resources/php/php artisan serve /tmp/resources/app/ {}
Making sure app folders are available
(node:97265) UnhandledPromiseRejectionWarning: Error: spawn /tmp/.mount_LaraveMZrpw2/resources/app.asar.unpacked/resources/php/php ENOENT
    at ChildProcess._handle.onexit (node:internal/child_process:286:19)
    at onErrorNT (node:internal/child_process:484:16)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
    at emitUnhandledRejectionWarning (node:internal/process/promises:298:15)
    at warnWithErrorCodeUnhandledRejectionsMode (node:internal/process/promises:406:5)
    at processPromiseRejections (node:internal/process/promises:470:17)
    at process.processTicksAndRejections (node:internal/process/task_queues:96:32)
(node:97265) Error: spawn /tmp/.mount_LaraveMZrpw2/resources/app.asar.unpacked/resources/php/php ENOENT
    at ChildProcess._handle.onexit (node:internal/child_process:286:19)
    at onErrorNT (node:internal/child_process:484:16)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)

The confusing part here is resources/php/php exists.
Does someone have an idea on what could cause it? I spent around 2h debugging... Any clues on where to look since the issue seems to be with the build process specifically?

@simonhamp, @gwleuverink, got any thoughts on this?

@gwleuverink
Copy link
Contributor Author

@RobertWesner this is the first time I've come across imports in a package.json file... I think you're right, it may be a much cleaner approach, but it would need some working through.

@gwleuverink have you ever used that before?

No this is the first I hear of it. It looks promising 👀 Thanks for pitching in @RobertWesner!

@simonhamp, @gwleuverink, got any thoughts on this?

The error is unfamiliar to me. Do you have a php executable in that path? nativephp-electron/resources/js/resources/php?

@RobertWesner
Copy link
Contributor

RobertWesner commented Oct 3, 2024

@gwleuverink yes, the php executable exists and ./php -v works.

@RobertWesner RobertWesner mentioned this pull request Oct 5, 2024
@RobertWesner
Copy link
Contributor

Finally managed to find the issue, getAppPath() needed to be modified from

let appPath = join(__dirname, '../../../../../resources/app/').replace('app.asar', 'app.asar.unpacked');

to

let appPath = join(__dirname, '../../resources/app/').replace('app.asar', 'app.asar.unpacked');

I opened #109 with my changes.

@simonhamp
Copy link
Member

Closing in favour of #109

@simonhamp simonhamp closed this Oct 14, 2024
@gwleuverink gwleuverink deleted the integrate-electron-plugin branch October 14, 2024 19:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants