-
Notifications
You must be signed in to change notification settings - Fork 170
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
Electron preload w/ Bytenode encoded renderer #134
Comments
This is an interesting question. Try this workaround: contextBridge.exposeInMainWorld(
'api',
{
view: (global) => {
const bytenode = require('bytenode');
return require('./path/to/my.jsc')(global); // you may have to change your my.js file accordingly
}
}
); and <script defer>
window.api.view(window);
</script> I'm not sure if this will work. Let me know the result after you test it. |
did not work, app started (as stated above) but no access to window object. I did get two additional log outputs now:
But maybe I did not use your example correctly. what do you mean by ?
Which parts would I have to change ? I assume you refer to using the passed in My app is an Angular app, so I'm not sure where to receive the passed in |
Can you please make a minimal app that I can test? |
OK, I have setup a hello-world project and tried to reflect your use case. What I have found is that your issue is not specific to The only workaround that I can think of is similar to what I have suggested in my previous comment, but with a fix (because we should have not altered the // main.js
// ... the usual main.js electron file, from Quick Start Guide
function createWindow() {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true
}
})
win.loadFile('index.html')
}
// ... the rest of main.js file <! -- index.html -->
<script>
function sayMyContext() {
console.log('index.html')
}
window.api.method1(window)
window.api.method2()
window.api.method3(window)
</script> // preload.js
const bytenode = require('bytenode')
const { contextBridge } = require('electron')
function sayMyContext() {
console.log('preload.js')
}
contextBridge.exposeInMainWorld('api', {
method1: (ctx) => {
return ctx.sayMyContext() // this should log 'index.html', if we pass `window` object to the function
},
method2: () => {
return sayMyContext() // this should log 'preload.js'
},
method3: (ctx) => {
return require('./protected.jsc').method(ctx)
}
}) // protected.js
exports.method = (ctx) => {
return ctx.sayMyContext() // this should log 'index.html'
} and I have compiled this file using the new This solution works as expected. Basically you pass your context to your |
@OsamaAbbas had to read this a couple of times, great stuff. ;-) Can't use this with Angular, because AFAIK there is no way to expose a method that would allow to pass in the Thanks again. |
So I'm closing this issue now. Let me know if you have any further questions. Also, if you have a bare minimum example of Angular + electron, please share it and I might find another way around. I tried to google [angular with electron], but all I can find are complex projects with unbelievable amount of moving parts, each one needs hours and hours to figure out how to deal with! |
yeah, the learning curve in the beginning is a bit steep re Electron + Ng project, but ultimately it's super simple: Ng is a modular JS framework that allows to build enterprise level JS apps via TS. Ultimately, it will be compiled to a JS app w/ an index.html and that will be placed inside the /app folder in Electron. So, when the renderer/main window is loaded, that index.html loads then the Ng app. This JS app is bootstrapped by Angular, loading all node_modules/dependencies etc for the various components and classes, it's a full fletched, large scale JS framework. And there is no way to pass any external data to it when it loads. Any data, can only be loaded after the app has been initialized either via http calls or from local storage. Electron's exposed preload api can be accessed through the But, in our scenario that I've looked into whether one can pass external data to Ng before app is loaded, it's not possible, other than storing the object in Thanks. |
Consider using NW.js instead of Electron. It's much much better and it has a dedicated tool ( |
yeah, switching the main platform to NW.js is a major step. I looked at NW.js before deciding to use Electron and one major factor was support and long-term life expectancy of the technology. Electron wins hands down in both regards. So, if we can't encode the renderer anymore w/ using strict security settings, then gotta push more sensitive logic into the main process, as we can still encode that. |
Good luck! |
@petef19 After some digging here and there, the reason why my workaround would work is not «we'd then be in the Also, as a bonus: Still thinking if we can protect |
not sure if I understand this correctly, but my Ng app (when NOT encoded via
So this avoids having to use Iow: can we ditch
As per my post in the other thread here, I opened up a ticket w/ |
In this case, how do you include the angular javascript files? Using In case of bytenode, we MUST As for why Angular changes the window object? Because it needs to define variables and objects ... etc. Keep in mind that window object IS the context. So when you define
I guess you will have to write your own launcher (in order to add
Yes, I saw your ticket there. I hope they implement it as you described. However, if they implemented it in a manner that depends on converting the function into its |
re Ng, I think I misunderstood this comment:
but later you then say
So I incorrectly hoped (I guess) that there is a workaround for Ng ;-)
do you mean it's breaking it in general or only when a function is converted via B/c I use
|
It breaks |
I edited my post there and quoted you, more precisely paraphrased one of your messages. lmk if this is not correct, see here: https://github.com/electron/electron/issues/28981#issuecomment-832395854 |
btw, I happened to stumble across your NW.js vs. Electron comparison on hackermoon from 2018 (appreciate the write up and comparison). I know this is off topic here, but since this is closed, maybe I can ask a couple of q's: ;-) (1) is there an updated version of this comparison ? is your opinion the same today ? Looking into other options again re our latest discussions. Appreciate the feedback and advise shared. |
I'm still leaning towards NW.js. If I have to choose between them I would go with NW.js for sure. But before taking this decision, I would also study the security vulnerabilities (an example here) in Electron and figure out their counterparts in NW.js and how to deal with them.
I have not. I have no experience with Electron so far other than trying to solve bytenode's issues. |
This problem come back with version 13.1.8. Please fix it and keep for new version! @OsamaAbbas. |
Can you please open a new issue with a clear example that works in 13.1.4 - 13.1.7 and reproduces your error with 13.1.8? |
comlplie terminal
then you coule get your exception
|
we're having a general discussion regarding the |
Running into issues using a
preload
script in Electron with Bytenode encoded renderer files.Contextisolation is enabled, hence
require
is not available in index.html in renderer, so the rendererjsc
files can't be decoded there (which is what I did before using preload).Moved this to my
preload
script:I can then trigger this via IPC from the renderer:
This does work (I see some of the app's console logs), but the problem is that the
jsc
file is now being executed in the context of thepreload
script and NOT in the browser window, hence all other calls to the preload'sapi
object (from the app) do NOT work, which is what my app needs.Any solution for this ?
I also tried using
bytenode.runBytecodeFile()
andbytenode.runBytecode()
, could not get this to work.Thanks.
The text was updated successfully, but these errors were encountered: