Node-Webkit sharing data in node via exports - node.js

I'm experimenting with Node-Webkit lately, if I call sth like that;
exports.name = function() {
console.log('My name is Uğur');
};
Node-WebKit renderer throws a error:
"Uncaught ReferenceError: exports is not defined"
I couldn't understand, Is it caused by node-webkit or node.js itself. Since; 'node test.js'
works without problem.

You need to run this in the Node's context (not WebKit's context). To do that, specify the script in 'node-main' in the manifest.
Here is an example:
index.js:
exports.callback0 = function (win) {
}
index.html:
<body onload="process.mainModule.exports.callback0(window)">
package.json:
{
"name": "nw-demo",
"node-main": "index.js",
"main": "index.html"
}
HTH

Related

Problem with compile PKG to exe: Babel parse has failed: 'await' is only allowed within async functions and at the top levels of modules

I wrote a script that works with puppeteer and with async/await. I specified the type as a module because it supports async/await without problems. But when compiling to exe with PKG I get an error:
pkg#5.8.0
Warning Babel parse has failed: 'await' is only allowed within async functions and at the top levels of modules. (6:8)
Warning Failed to make bytecode node16-x64 for file C:\snapshot\my-script\main.js
Tried solutions from the links:
topLevelAwait invalid with babel-loader: 'await' is only allowed within async functions
And a few more...
Basically, everyone advises using promises, but firstly, I'm new to node js and secondly, I need to do it with "crutches" in the whole script
I even tried to do it on different computers) The result is the same.
I just don't understand what I'm doing wrong. I wrote a small script for the test, it also gives this error when trying to compile..
main.js
async function Sum(x, y)
{
return x + y;
}
let x = await Sum(1, 3);
console.log(x);
package.json
{
"name": "Test",
"type": "module",
"main": "main.js",
"devDependencies": {
"#babel/plugin-syntax-top-level-await": "^7.14.5"
}
}

ElectronJS crashes on dialog.showOpenDialog(...)

I'm trying to prompt an "open file" dialog box, and I found dialog.showOpenDialog(...) in the electron docs.
I've added this line to a few different projects now, with the result of crashing as soon as that line hits. I would see the file explorer dialog window open for a second, then it crashed. The console gives me no error message, the last thing it prints is Promise { <pending> }.
What I've tried:
Adding dialog.showOpenDialog(...) to the official vscode debugging example, to see if it picks up any errors. It always crashes as soon as it reaches that line, with no error message.
Removing my node_modules folder and reinstalling electron using npm install electron --save-dev
Running the app using a global electron command electron .
Uninstalling global electron using npm uninstall -g electron and using a local npm start
Checking if my node packages are out of date using `npm outdate
Running the app using --disable-gpu argument
I'm using Ubuntu 19.04, not a VM, but I also tested it on Ubuntu 18.04 in a VM.
One interesting note is that when I tried to use an html form button with a type = file to accomplish this same task, it also crashed as soon as the file explorer dialog box opened in the electron app. BUT it did work when I opened the html page in a regular web browser.
Here's my main.js
const { app, BrowserWindow } = require('electron')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
function createWindow() {
// Create the browser window.
win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
// and load the index.html of the app.
win.loadFile('index.html')
// Open the DevTools.
win.webContents.openDevTools()
// Emitted when the window is closed.
win.on('closed', () => {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
win = null
})
const { dialog } = require('electron')
console.log(dialog.showOpenDialog({ properties: ['openFile', 'multiSelections'] })) //*****THIS LINE HERE
}
app.on('ready', createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', () => {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (win === null) {
createWindow()
}
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
Here's my package.json
{
"name": "electron-demo",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"start": "electron .",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"electron": "^7.1.2"
}
}

Mocha testing path argument in package.json

Note: I'm a complete noob to nodejs. Please explain your answer in such a way somebody who has experience in other programming languages, but creates his very first nodejs application can understand =).
I'm trying to write a simple test application which should automate testing an external service against an OpenApi 3.0 specification.
I've pulled together some example code in order to attempt to automate testing the OpenApi spec against an external service which implements the API using mocha and chai.
My problem seems now that my mocha test modules cannot be found.
I get the following error message:
> client_test#1.0.0 test /Users/user1/dev/app/app-rt/client_test
> mocha ./test/**/*.test.js
/Users/user1/dev/app/app-rt/client_test/node_modules/yargs/yargs.js:1163
else throw err
^
Error: The "path" argument must be an absolute filepath
My package.json:
{
"name": "client_test",
"version": "1.0.0",
"description": "Client Tester",
"main": "index.js",
"scripts": {
"test": "mocha ./test/**/*.test.js"
},
"license": "UNLICENSED",
"dependencies": {
"chai-http": "^4.3.0",
"chai-openapi-response-validator": "^0.2.4",
"mocha": "^6.2.0",
"nock": "^11.3.2"
}
}
The little test application in test/client_all.test.js:
// Set up Chai
const chai = require('chai');
const expect = chai.expect;
// Import this plugin
const chaiResponseValidator = require('chai-openapi-response-validator');
const baseUrl = 'http://localhost:8081';
// Load an OpenAPI file (YAML or JSON) into this plugin
chai.use(chaiResponseValidator('./spec/app.json'));
// Get an HTTP response using chai-http
chai.use(require('chai-http'));
// Write your test (e.g. using Mocha)
describe('GET /zones', function() {
it('should satisfy OpenAPI spec', async function() {
const res = chai.request(baseUrl).get('/zones');
expect(res.status).to.equal(200);
// Assert that the HTTP response satisfies the OpenAPI spec
expect(res).to.satisfyApiSpec;
});
});
Can you help me figure out why the paths cannot resolved, and how to fix it? Feel free to comment on the test code as well, if you think I'm doing it wrong.
The problem is with the package chai-openapi-response-validator. Try something like this:
// Import this plugin
const chaiResponseValidator = require('chai-openapi-response-validator');
const baseUrl = 'http://localhost:8081';
// New code
const path = require('path')
const specPath = path.resolve('./spec/app.json')
// Load an OpenAPI file (YAML or JSON) into this plugin
chai.use(chaiResponseValidator(specPath));
Make sure the path to the app.json file is relative to the package.json file, or use another method to convert it to an absolute path.

Durandal optimization with Gulp and Gulp-Durandal not working

We are building an application with Durandal which is quite big at the moment and we currently looking into bundling all JS files located in the App folder into a main-built.js file. Pretty basic and usual stuff I guess.
I'm using Gulp with the Gulp-Durandal extension. Here our gulpfile :
var gulp = require('gulp');
var durandal = require('gulp-durandal');
gulp.task('build-portal', function () {
durandal({
baseDir: 'app',
main: 'main.js',
output: 'main-built.js',
almond: false,
minify: false
}).pipe(gulp.dest('app'));
});
And here's a snippet of our main.js file
require.config({
paths: {
'text': '../Scripts/text',
'durandal': '../Scripts/durandal',
'plugins': '../Scripts/durandal/plugins',
'transitions': '../Scripts/durandal/transitions'
},
shim: {
},
waitSeconds: 0
});
define('jquery', [], function () { return jQuery; });
define('knockout', [], function () { return ko; });
define('ga', function () { return ga; });
define(
["require", "exports", "durandal/app", "durandal/viewLocator", "durandal/system", "plugins/router", "services/logger", "modules/knockout.extensions", "modules/knockout.validation.custom"],
function (require, exports, __app__, __viewLocator__, __system__, __router__, __logger__, __koExtensions__, __koValidationCustom__) {
var app = __app__;
var viewLocator = __viewLocator__;
var system = __system__;
var router = __router__;
As you can see in the gulpfile, we do not want to use Almond but RequireJs instead, for some reasons almond isn't workin with our project and anyhow, we prefer RequireJs whether its bigger than almond at the end. That's where it look to brake. Running the command to build the main-built.js file took sometime but at the end I get the file built with everything in it.
The problem is that when I try to load the application, it is stuck to the loading screen. It doesn't go any further and there's no errors at all in the browser console.
I created a new project on the side to test if our code was somewhat faulty and found that it might not. You can found that project here :
https://github.com/maroy1986/DurandalGulpBundling
If I build that project with almond option to true, everything works fine but if I switch almound off to tell gulp to use RequireJs, I got the same behavior as our app. You got stuck at the loading screen, without any errors.
So here I am, I do read a lot on the subject but didn't found anything to solve this. Hope someone here already encounter these behavior and have a solution to share.
Thanks!
I had the same requirement and issue. It seems require.js wasn't calling the main module which will startup the Durandal app, that's why it's stuck in the loading screen. I was able to resolve it by implicitly calling the main module:
gulp.task("durandal", function() {
return durandal({
baseDir: "app",
main: "main.js",
output: "main-built.js",
almond: false,
minify: true,
rjsConfigAdapter: function(config) {
//Tell requirejs to load the "main" module
config.insertRequire = ["main"];
return config;
}
})
.pipe(gulp.dest("dist"));
});
I downloaded your project and tried building it with the latest versions of gulp and durandal. Initially it didn't build and gave me the following error:
TypeError: Cannot read property 'normalize' of undefined
This is a problem with the text-plugin of rjs and you can solve this by adding the following to your gulp-file (next to the almond, minify, output... properties):
rjsConfigAdapter : function(rjsConfig){
rjsConfig.deps = ['text'];
return rjsConfig;
}
Once I did that, the build finished and I could build with or without minify, almond and require and the application works fine.

How do I use Sails.js in Node-Webkit?

I tried to create an application with Node-Webkit and Sails.js. My API works fine, I get the JSON I need, but when integrated with Node-Webkit does not start the server.
My package.json contains:
{
   "name": "app-sails"
   "main": "front/index.html"
   "window": {
     "toolbar": true,
     "width": 1024,
     "height": 600,
     "title": "Test Application"
   },
   "scripts": {
     "start": "node server/app.js"
   }
}
The index.html is the main page you get when you use the generator angular.js yeoman and contains calls to the server that I have with sails.js. In the web running, but not with Node-Webkit.
When I run the .nw, I can see my index.html correctly; but without the data it throws the sails server.
I appreciate any help.
I recently wrote a small article on this, you can check it out here: https://medium.com/unhandled-exception/sailsjs-and-node-webkit-4ccb8f810add
Basically you just need to execute sails using require as soon as the node-webkit window is loaded. This goes in your app.js file:
exports.onLoad = function() {
var nwGUI = window.require('nw.gui');
nwGUI.Window.get(window).on('loaded', function() {
if (loaded) {
return;
}
window.location.href = "http://localhost:1337/";
loaded = true;
});
try {
sails = require('sails');
} catch (e) {
console.error('To run an app using `node app.js`, you usually need to have a version of `sails` installed in the same directory as your app.');
console.error('To do that, run `npm install sails`');
console.error('');
console.error('Alternatively, if you have sails installed globally (i.e. you did `npm install -g sails`), you can use `sails lift`.');
console.error('When you run `sails lift`, your app will still use a local `./node_modules/sails` dependency if it exists,');
console.error('but if it doesn\'t, the app will run with the global sails instead!');
return;
}
// Try to get `rc` dependency
try {
rc = require('rc');
} catch (e0) {
try {
rc = require('sails/node_modules/rc');
} catch (e1) {
console.error('Could not find dependency: `rc`.');
console.error('Your `.sailsrc` file(s) will be ignored.');
console.error('To resolve this, run:');
console.error('npm install rc --save');
rc = function() {
return {};
};
}
}
// Start server
sails.lift(rc('sails'));
}
and this on your .html entry point:
<html>
<head>
<title>Welcome!</title>
</head>
<body onload="process.mainModule.exports.onLoad();">
<h1>hi!</h1>
</body>
</html>
As you can see, most of that app.jss file is basically the same that comes out when you do a
sails new
I just wrapped everything up and executed that callback onload
If you want you can always check out the article and the full github repo for a more detailed version of the code.
Oh! And don't forget to update your package.json and add:
{
...
"node-main": "app.js",
...
}
You should load the Sails-Page not your index.html.
One thing you could do is (in your HTML)
window.location.href = "http://localhost:1337/";

Resources