How to Require N-api from electron - javascript

I am currently trying to build a native C++ add-on for an electron app.
I have successfully built and ran a testaddon.node from the index.js file as specified in the following link (really is a fantastic guide, very worth a read).
https://medium.com/#atulanand94/beginners-guide-to-writing-nodejs-addons-using-c-and-n-api-node-addon-api-9b3b718a9a7f
I am currently including the addon I made in my package.json folder, and running my electron app via npm start.
However, I cannot seem to get at the require('./test-addon/build/Release/testaddon.node');
My best guess is that the folder is simply not making it into my .asar. I have tried every conceivable combination of electron-rebuilder, electron packager, etc.
From what I see, electron.asar only triggers when I modify the node_modules folder through node. However, I don't see how to do this if I am making my own C++ module.

Try the bindings module,
https://github.com/TooTallNate/node-bindings
, it finds and loads your native .node file. Works for me as follows:
const B2 = require('bindings')('b2')
This line has been taken from here

After considerable smashing my head into a wall, I used these tutorials. Please note that some of the C++ code is now out of date, particularly with the later examples. However, the first 3 or 4 examples build and run fine.
https://github.com/nodejs/abi-stable-node-addon-examples
1) Make sure your example works as advertised in the node addon example link.
2) Bring it into your electron build.
3) Make sure that you run .\node_modules.bin\electron-rebuild.cmd after install
The require will be the same from the electron renderer as it is from the example file.

Related

Fundamental Understanding of Node JS in the front end

Some things to know:
I understand how to make a HTML / CSS / JS website.
I understand how to make a Node JS app and host it on Heroku
I encountered a problem that was very confusing and I still working it out. I am making a firebase project using their latest tree-shaking V9 SDK
import { initializeApp } from 'firebase/app';
I understand Node JS is meant for backend (it can't be run in a browser) so how am I supposed to "build" this into something that I can reference in a script tag? I've heard of webpack but that requires you to run npm run build so how is that practical in any way? That would mean every change I make I would have to build it?
Developer Testing:
How would one live preview this Node JS app on a localhost if Node JS can't be run in a browser? I would live to be able to preview this Node JS app and quickly make changes if that's possible.
I've heard of webpack but that requires you to run npm run build so how is that practical in any way? That would mean every change I make I would have to build it?
Yes, that's the general idea. You make changes to script files on your local machine (or network), and then in order to see the changes take effect, you rebuild the app so that a new bundle is generated. This bundle can then be hosted on your web server or development server, and once it's there, you can refresh the page to see the differences.
But almost all of this can be automated, resulting in it not really being much of a chore at all.
Nodemon is a popular tool that watches a directory for changes and can run Node scripts when a change is detected. With it, you could, for example, make a change to a file, and then it'll automatically rebuild your app.
For Webpack in particular, there's webpack-dev-server, which can automatically refresh a page when the app gets rebuilt.
So, during development, the workflow can be as simple as - make a change, then alt-tab to your browser (hosting the app on localhost) to look at the changes.
Bundles built for the purpose of eventually hosting them on the front-end can easily incorporate Node modules - the build process can take the code from the module, and the bundle produced can include that code. This sort of thing is extraordinarily common.

Other way to share react ts components between projects

I have been looking for a way to mostly share some code between projects specifically for SPFX and fluent ui. We found 3 main ways to do that.
1.
Creating a component library is the way that seemed least complicated cause it uses the same infrastructure and do all building without the need to configure it.
But this adds some issues, we need to built and manually link the solution locally to make it work, this will also work if we put in a repo. so this is mitigated.
The second is that implicitly this will also require the fluent ui and react. Plus having to place it inside a SPFX component library project.
2.
I saw some promise using paths in ts and this works fine while using the ts compiler. It will go to the folder that your proj is referring and build it at calling time. which is great. But it did not work in SPFX.
3.
Another way was to have a post install to sync the folders which seems easy enough but I wonder how practical this is plus how people are doing it, if they are, how.
All I wanted to figure out now is a way to take my component code and share as if they were in a folder of my src or a simple extension of the code. No need to have extra dependencies or build steps, just the code that can be used as a ts/tsx file. ex:
shared lib:
//assuming I have react and fluentui already installed for the project.
import button from 'fluentui';
export const fancyCustomButtom = (props) => {
return (<Button text="Standard" />);
};
src project folder:
import {fancyCustomButtom} from 'shared-lib'
It is fine if it needs to build the files before we can use it but can we do it at build time or when the package is installed? also wouldn't it increase my bundle size by making both module dependent on things already available (react, fluentui)?
Given the way Microsoft have architected the loading of bundles in SharePoint and Teams - I believe an SPFX component library is the best way to share code between different solutions, particularly if you are looking to minimise bundle size...
Imagine you have a library for something re-usable: a form, a set of standard branded components - something of that nature. You could put your shared code in repos and add references to it - either by publishing your own repo publicly or using the npm install git+https://yourUrl syntax; but what effectively happens there is that your code is pulled down in to node_modules for each project, and any referenced module code is included in your bundles. If you have two, three, four or more webparts on the same page - using those same libraries, you're multiplying how many times that code is included on the page.
If you follow Microsoft's guide on setting up a component library project however, your npm link commands allow your types to be recognised in consuming projects without needing to actually include the bundled distribution code. You can deploy your library code once to the App Catalog, and if it's referenced in other solutions -- it's loaded on pages as needed: once.
I have found the development experience to be quite flaky at times, but it does work. When I run gulp clean on my library code, or come back to it after some time, I sometimes find that I need to run npm link and npm link my-project-name again as per the instructions in the above tutorial. Whenever you run gulp build on your library, you should also rebuild the project that consumes the library, either by using gulp build / bundle or by saving a file (if you're running gulp serve). This process works well for developing, and once it comes time to deploy, all you need to do is add a named reference to your library inside package.json and then deploy both .sppkg files to your App Catalog.
In terms of your last question re: bundle size - react is not actually included in the dependencies for an SPFX library project, but you will find it's available to use. When you build your library, if you take a look in the generated javascript in your dist folder, you will see it's listed as one of the dependencies for the webpacked content along with react-dom and ControlStrings. It's on line 1.
office-ui-fabric-react is included as a devDependency thanks to the #microsoft/sp-webpart-workbench package that gets scaffolded with all SPFX projects - and if you check your library's dist javascript, you will see that included components are being webpacked and included in your bundle. I'm not entirely sure if when you pull this code in to your consuming project, whether webpack then tree-shakes to de-duplicate and ensures only necessary code is included: I don't know. Someone else may be able to illuminate us there or provide a more accurate explanation of what's going on... I will update this response if anyone comments to let me know.
And finally, this is more of a personal way of working, but it may be worth consideration:
When developing a library, I sometimes reference it in other projects via a local npm install ../filepath command. This ensures that when I install the library as described, the consuming project installs any necessary dependencies. I'm able to tweak both projects if I need o. When it comes time to deploy, I commit my changes to both projects, deploy my library code to the App Catalog, and then npm uninstall the library from the consuming project and add a reference as described in the above tutorial. When I deploy projects that use my library, they just work.
I recently developed a library that uses pnpjs, in particular the #pnp/sp library that is used to talk to SharePoint. If you look at the Getting Started guide for that library, they expect you to pass a reference to your Application Customizer or Web Part context during setup, or explicitly set things up using a base URL and so forth - and of course, a library doesn't really have a page context of any sort - the whole point of this code is that it's reusable. So that poses a challenge. My solution was to do the setup in the consuming web part(s) and ensure that they pass a reference to the sp object (which is of type SPRest) to any code or components that exist in my library. My library has peerDependencies on those pnp libraries so that the code isn't duplicated in consuming projects. Sometimes you have to think about what your library needs to include in its bundle and what you expect consuming solutions to already have, and maybe find ways to ensure things aren't included that aren't needed.
For example, in the scenario you talk about, you may want to ensure fluentui or office-ui-fabric-react are only devDependencies or peerDependencies for your library. As long as your library and the project(s) consuming your library both use the right version(s) you shouldn't have any trouble, and you can document any pre-requisites with your library documentation. You can check which versions of these libraries are installed per the SPFX version you are currently using ie. SPFX v1.11 or v1.12 etc. Just run npm ls <packagename> to get a breakdown, or check your package.json file.

OpenCV.js is not working vue.js (electron-builder)

I am working on a project with electron and vuejs (i am using vue-cli-plugin-electron-builder) and I require real time face detection system the fastest and most effective solution so far is OpenCV.js (i have done my research).
The problem that i have been facing is according to the OpenCV.js Docs we need to add the script tag to the html file like,
<script async src="https://docs.opencv.org/master/opencv.js" onload="onOpenCvReady()" type="text/javascript"></script>
I have tested it and it works fine only if I turn off nodeIntegration in electron window. But this is not possible because the electron-builder plugin works only if the nodeIntegrations are turned on.
new BrowserWindow({
webPreferences: {
nodeIntegration: true // I need this but i also need opencv
// but opencv is not working if i turn it off.
}
})
Secondly, should I keep using electron or move to NW.js i have noted that the build size of electron.js are huge.
First of all, the following statement is not true:
electron-builder plugin works only if the nodeIntegrations are turned on.
In fact, nodeIntegration is going to be disabled in electron-builder v2.0 by default.
Now let's get to the point. Do not download anything using a <script> tag, if you do this, every time a user opens the app, it will download the script. What you should do is to install all the node modules during development, so that everything comes with the app.
To use opencv in Electron, you can simply Install this npm module. Check out the example on how to use it in Electron.
If that module doesn't work for you, try this npm module and follow the opencv docs if needed.
And to answer your question about NW.js, it depends on your needs. Google the differences between Electron and NW.js and decide what you want to use for your app. In short, Electron is more powerful and more secure, even if the app takes up 200mb more on the drive, it's still a better option. Besides, who cares if the build is 400mb in size? It's not 2010, nowadays most people who's going to use your app in the first place, most likely have half a terrabyte of free space on their drives.

What is the role of ios/build folder in React Native?

I'm troubleshooting a React Native app and one article suggested deleting the ios/build folder, but didn't explain why. Does anyone know, in as much detail as you can, what the role of this folder is, how it's created, and what the implications are of deleting it?
Thanks!
what the role of this build folder
Actually it's the code compiled into native. when you compile your code, for example react-native run-ios , this command compile and build code for ios and then run it on IOS simulator. its generated after compiling project.
how it's created
When you run the app, the compiler will build this folder.
and what the implications are of deleting it?
Then the compiler will build the whole project from start as the build folder for IOS or ANDROID is missing which is needed to run the native app.
I hope this helps in your understanding.
ios/build folder is updated when the app is built. It contains several subfolders, each having its own use:
Build/Products
Stores final build artifacts that are installed on Simulator or device.
Build/Intermediates.noindex
Stores additional files used while building the app. These are cached to speed up subsequent builds. Removing it will slow down the next build.
Index
Xcode performs indexing of project source code and stores the index in this folder. Index is used to speed up Xcode operation like search, quick navigation, refactoring. Removing this will trigger indexing next time Xcode is opened. However, Xcode index doesn't really affect React Native developer experience since you normally don't use Xcode much while developing RN apps.
Logs
Stores logs collected while performing various tasks like building, testing, debugging etc.
ModuleCache
Stores precompiled module files. Modules allow to reduce compile time of Xcode apps. Removing this will slow down the next build.
To summarize, ios/build folder contains final installation app files, auxiliary files and precompiled modules, various logs and source code index. The main implication of removing the build folder is that the next build will be slower than usual.

Electron (Atom-Shell) Run unix command from link in page

I am trying to learn Electron (Atom-Shell) but I am finding it pretty tough to find documentation for it...
I am simply trying to figure out how to create a link with in index.html, and have it open a terminal window or run some sort of program.
I learn languages by learning specific tasks as I need them in a program, so that is why I am asking so then I can utilize the technique used in other ways in my programs.
Thank you for helping.
Well, essentially Electron is just a customised version of a Chromium browser that comes packaged with Nodejs and some really cool packages that basically allow you to run the custom browser as if it was a native platform application. Because of that creating an Electron app is very similar to creating a web-app that has a Nodejs back-end.
So to get started with a simple "Hello World!" app, you can just run the following npm...
npm install electron-prebuilt --save-dev
Once the npm is installed you'll need three files to run an Electron app.
A package.json file
A javascript file (default is main.js)
An html file (default is index.html)
See this GitHub repo for a quick copy/paste version of each and more detailed instructions: https://github.com/mafintosh/electron-prebuilt
after that you're ready to simply run your app...
$ electron .
Finally, one way to open a terminal window would be to use an onclick attribute in your html to trigger a child_process, found here, in a function.
That's it! You should be able to edit your html and javascript files as you would for any web-app, and take advantage of the added features that Electron provides.
I'd also check out these resources for more info:
A Quick Start intro to how Electron works -- https://github.com/atom/electron/blob/master/docs/tutorial/quick-start.md
The Atom discussion forum (Because Atom was built with Electron, and is made to be hackable, the community is quite active) -- https://discuss.atom.io/c/electron
A cool repo to keep up with the latest info. It includes links for apps that currently use Electron, tutorials, videos, and more --
https://github.com/sindresorhus/awesome-electron
I hope that helps!

Categories

Resources