How to import javascript file to qml worker script - javascript

I'm creating an application in me where I want to download data from the internet. To avoid blocking of main thread I created a WorkerScript file. This works fine, but I need to abstract certain parts (like authorization, proper header, etc) to general-purpose functions.
Unfortunately, I haven't found a way to import the js file to the js file that serves as a worker thread. ".import" causes syntax error.
How can I achieve this?
Thank you.
Edit:
This is the relevant part from qml file:
Page {
WorkerScript {
id: myWorker
source: Qt.resolvedUrl("loadDetails.js")
onMessage: {}
}
}
And this is loadDetails.js:
.import "jsonrpc.js" as Jrpc
WorkerScript.onMessage = function(message) {
// This is where I want to call functions from included file
}

See documentation provided by Oleg:
Worker script can not use .import syntax.

I guess you have missed a qualifier in the import statement. The proper syntax is:
.import "filename.js" as Qualifier
See Qt Documentation for your case.

This is more of a meta answer, as it is also addressed to the other answerers.
The Qt Documentation can at times be ambiguous. In the WorkerScript Documentation it states that:
Worker scripts that are plain JavaScript sources can not use .import syntax. Scripts that are ECMAScript modules can freely use import and export statements.
Except that doesn't seem to be the case. I have tried all different kinds of imports:
// example.mjs
.import "test.mjs" as Test
.import * as Test from "test.mjs";
import "test.mjs" as Test
import * as Test from "test.mjs";
import { test } from "test.mjs"
So it's obvious that it doesn't work, but the documentations states that it does - and that it doesn't...

Related

dynamic import of cross origin script files

I want to use javascripts dynamic import function.
However, when I specify a whole url to import I get an error:
Cannot find module 'https://....
tho I know the resource is available. Is import restricted to same-origin script files (therefor all modules start with ./)?
On the other hand, I can dynamically create a script element and set the source to anything, and when its loaded all its functions (not a module) are in the global scope.
I would like to have the benefits of both :) loading script from cross origins but keep them in module structure.
since there are 2 comments thanks to the tips I found it seemed to be a problem with how parcel bundles, imports...
I could not find a way how to do it with parcel 2.7.0.
So is there a way to load a module, from a script tag that I create, set the type as a module and the src, to what I need.
Something slightly nicer then: const importPromise = eval("import(scriptUri)") which actually does the job
I believe this may be due to a lot of bundlers not being able to run dynamic imports:
https://discourse.threejs.org/t/importing-three-dynamically/28751
https://medium.com/front-end-weekly/webpack-and-dynamic-imports-doing-it-right-72549ff49234
https://github.com/parcel-bundler/parcel/issues/112
https://github.com/rollup/rollup/issues/2463
How to dynamically import a module which name is defined by a param with rollupjs?
Well, the issue isn't the bundlers not supporting them, but the usage of them is somewhat confusing to many, evident by the amount of tickets open in the various repos.
There are a few work arounds, but I think you may need to post a detail setup for us to help.
For now, I'd suggest (if possible), using defined strings in if conditions to get started. It's not ideal, but you may find yourself going in circles otherwise. If you provide the exact urls, that may help, but this is a good example:
function localeDynamicImport (locale) {
if (lang === 'en') {
return import('./locales/en.js');
}
if (lang === 'zh') {
return import('./locales/zh.js');
}
}
Other options include:
Pure ES6 module without a bundler
<script type="module">
import * as THREE from 'https://cdn.skypack.dev/three#0.130.0'
</script>
Webpack magic comments:
import(/* webpackIgnore: true */ 'http://example.com/some-module/some-module.bundle.js').then(module => console.log(module.default));

Script from “http://127.0.0.1:5500/assets/platform.png” was blocked because of a disallowed MIME type (“image/png”)

Apologies if this is a repetitive question however I have looked all over and found no suitable solution for my particular issue.
I am attempting to build a simple JavaScript game but am having issues with importing images.
For reference, here is my relevant code:
index.html
<canvas id="gameScreen" width="1420" height="965"></canvas>
<script src="src/index.js" type="module"></script>
And from my index.js file:
import platform from "../assets/platform.png";
I am receiving the following error when trying to import this image:
Script from “http://127.0.0.1:5500/assets/platform.png” was blocked because of a disallowed MIME type (“image/png”).
I have tried changing the 'type' specified in the script tag, to no avail.
Also, I should note I am using the Live Server extension.
Any help is much appreciated.
In JavaScript, the ES6 import statement can't be used to import anything except JavaScript modules.
Tools like Webpack — which pre-process import statements to convert JS programs using ES6 modules into a format that browsers which doesn't support modules can use — can do things with non-JS resources.
They aren't executing the JavaScript, so the rules for them are different.
At the simple end of the scale, this involves copying the non-JS file to the build directory and replacing the import with a variable declaration and assigning a URL (in a string) to that variable.
Since you aren't using a bundler, you need to do that yourself.
Replace:
import platform from "../assets/platform.png";
with something like
const platform = "/path/to/platform.png";

Best way to evaluate javascript source code module with node.js

With node, I transpile a typescript tsx file int javascript. Then I need to call a function that is described in that javascript code. ES6 modules are used.
I use
writeFileSync('./temp/page1.js', js) // js is the module source code
import page from '../temp/page1.js'
page is here the default export which is a function that I want to call.
That works fine but I wonder if there is a better way to call the function inside the module source code? A way that avoids saving the source code into a temporary file.
eval would not be a security concern, but I think it would not give me the default export, modules are not considered in this old function.
Maybe something node related?
I found https://www.npmjs.com/package/node-eval which would avoid the file saving, although it still requires a filename, which causes some brittleness in my code.
node:module
node:vm
are maybe promising, looking at https://github.com/node-eval/node-eval/blob/master/index.js but I have not yet figured out if and how.
Similar, but more related to require: Load node.js module from string in memory
https://github.com/floatdrop/require-from-string
did not work either
all the variants with node:vm like
import vm from 'node:vm'
let context = vm.createContext({}, {name:"temp1.mjs"})
vm.runInContext(js, context, {filename: "temp2.mjs"})
result in "Cannot use import statement outside a module"
The best way would be nodes vm.Module class
https://nodejs.org/api/vm.html#vm_module_evaluate_options
but that is in draft stage and behind feature flags.

Why are package imports needed in Meteor

About a year ago I have used Meteor, and now I want to use it again, but many things have changed.
When I follow the Blaze tutorial on Meteor.com, they add imports on top of their files:
import { Meteor } from 'meteor/meteor';
import { Template } from 'meteor/templating';
import { ReactiveDict } from 'meteor/reactive-dict';
I got the app working. But when I comment the imports out, the app keeps working like it should work. Why are these imports needed?
I am still using the regular Javascript, not ES6.
Thanks!
The import statement is used to import functions, objects or primitives that have been exported from an external module, another script, etc.
The name parameter is the name of the object that will receive the exported members. The member parameters specify individual members, while the name parameter imports all of them. name may also be a function if the module exports a single default parameter rather than a series of members. Below are examples to clarify the syntax.
Import an entire module's contents. This inserts myModule into the current scope, containing all the exported bindings from "my-module.js".
For more detail about the different ways we can use import along with their usage, please check this.
They still use the old globals for backwards compatibility. However it is recommended to use the imports so if in some future release they remove the globals your code will still work. You can read more in the appropriate section of the guide.
Ok you know import is to import an exported object from another file already.
The point that you may have missed is that MDG heard the need to stop loading everything by default, or at least to provide a mean to control what is loaded in memory and what is not.
Look for the /imports special directory.
Files in that folder are no longer loaded automatically, but only through import statement.
As for the tutorial, I guess they did not explained this functionality, and because it imports only standard functionalities which are still loaded eagerly for backward compatibility, it does not change anything removing those statements.

Angular2 web workers with ES5

I have gone down a path of using Angular2 but writing ES5 code, which means that the examples and guidance I find usually must be translated from answers relevant to TypeScript.
Can someone help me with an ES5 version of:
Bootstrapping the application. In TypeScript I see it done as:
import {WORKER_APP_PLATFORM, WORKER_APP_APPLICATION} from "angular2/platform/worker_app";
import {platform} from "angular2/core";
platform([WORKER_APP_PLATFORM]).application([WORKER_APP_APPLICATION]).bootstrap(myApp)
Accessing the web_workers component:
import {Component} from 'angular2/web_worker/worker';
#Component({ ... ])
I assumed the latter would be achieved by calling
ng.web_worker.worker.Component({ ... })
But that seems to not be the case: ng.web_worker is undefined.
The problem might be that I seem to not be able to include web_worker/ui.js properly. When I include it instead of bundles/angular2-all.umd.js I only get error messages about require being undefined. When I explicitly include RequireJS in my project I get a bunch of other errors.
Any help will be greatly appreciated!
Can I ask, why do you want to do it with ES5? You can easily use SystemJS and ES6 if you don't like Typescript. Typescript would be almost identical to ES6.
In case you still want to do it with ES5, you need to change the imports to require calls:
var WORKER_APP_PLATFORM = require("angular2/platform/worker_app").WORKER_APP_PLATFORM;
var WORKER_APP_APPLICATION = require("angular2/platform/worker_app").WORKER_APP_APPLICATION;
var platform = require("angular2/core").platform;
platform([WORKER_APP_PLATFORM]).application([WORKER_APP_APPLICATION]).bootstrap(myApp)
Another example:
var Component = require('angular2/web_worker/worker').Component;
You get the idea. You also don't need RequireJS... You can use SystemJS. You should import the main file like this:
System.import("main")
SystemJS will resolve all the require calls async, but in the code, the require calls look sync.

Categories

Resources