dynamic import of cross origin script files - javascript

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));

Related

What is the difference between `import Anything from #anywhere` and no import

When using autoimport feature of nuxt3:
is there any impact (types, performance, bundle-size, tree-shaking, etc..) of using the # alias to import something rather than no import at all?
Or its only purpose is to make imports explicit and maybe help to fix some IDE/linter/ts issues?
Example:
// plugins/vuetify.ts
import { createVuetify, VuetifyOptions } from "vuetify";
import { defineNuxtPlugin, NuxtApp, Plugin } from "#app"; // this line should be optional
export const VuetifyPlugin: Plugin = defineNuxtPlugin((nuxtApp: NuxtApp) => {
const vuetify = createVuetify();
nuxtApp.vueApp.use(vuetify);
});
export default VuetifyPlugin;
I wasn't aware of the # import, do you have a reference for that specifc one?
As you kinda guessed it, there are no direct benefits of making the imports yourself. In the same way that Nuxt does the job for you regarding ref, computed, watch etc, it will try to import most of the other common stuff.
The compiler will scan your file, see what you are using in your template + script part and make the import himself on runtime. It may not guess fully dynamic imports (usually for components based on a dynamic variable for example).
Still, it should work in the exact same way performance-wise.
For the types I know that there could be some limitations (not a full coverage), but since I don't use TS, I'm not well aware of all the details.
Regarding IDEs/code editors, most of the time they will work fine but some of them may require a bit of configuration to work perfectly (since it's implicit, you still need to tell your editor what is happening), otherwise some Linters may complain a bit.
Nuxt's auto import feature is probably based on something really similar (if not identical) to this: https://github.com/antfu/unplugin-auto-import
Hence, you can see in details how this one works to get more explanation.

NodeJS - Dynamically import built in modules

I'd like to get a built in module (for example Math or path or fs), whether from the global object or require, I thought about doing something like this:
function getModuleByName(name) {
return global[name] || require(name);
}
Is there a way to check that it is indeed a module and not something else? Would this make a security problem?
Is there a way to check that it is indeed a module and not something else?
Other methods but here's an example:
function getModuleByName(name)
{
let module = null;
try {
module = require(name);
} catch (e) {
// Recommend Logging e Somewhere
}
return module;
}
This will graciously fail as null where the module does not exist, or return it.
Would this make a security problem?
Quite possibly, it depends on how it's used. I'd argue it is more of a general design issue however and would blanket say avoid doing it (without any context, you may have a very good reason).
You, like anyone, obviously have a finite amount of modules you could be loading. These modules have all been selected by yourself for your application for specific reasons, or are bundled into your node version natively and are expected parts of your environment.
What you are doing by introducing this functionality is adding the addition of unexpected elements in your environment. If you are using getModuleByName to access a third party library- you should know outright that library is available and as such there's no reason why you can't just require it directly.
--
If you do think your use case warrants this, please let me know what it is as I may never have encountered it before. I have used dynamic imports like the following:
https://javascript.info/modules-dynamic-imports
But that hasn't been for global packages/libraries, but for dynamic reference to modules built internally to the application (i.e. routing to different views, invokation of internal scripts).
These I have protected by ensuring filepaths can't be altered by whitelisting the target directories, making sure each script follows a strict interface per use case and graciously failing where a module doesn't exist (error output "this script does not exist" for the script usage and a 404 view for the routing example).

dynamically load modules in Meteor node.js

I'm trying to load multiple modules on the fly via chokidar (watchdog) using Meteor 1.6 beta, however after doing extensive research on the matter I just can't seem to get it to work.
From what I gather require by design will not take in anything other than static strings, i.e.
require("test/string/here")
Since if I try:
var path = "test/string/here"
require(path)
I just get Error: Cannot find module, even though the strings are identical.
Now the thing is I'm uncertain how to go on about this, am I really forced to either use import or static strings when using meteor or is there some workaround this?
watchdog(cmddir, (dir) => {
match = "." + regex_cmd.exec(dir);
match = dir;
loader.emit("loadcommand", match)
});
loader.on('loadcommand', (file) => {
require(file);
});
There is something intrinsically weird in what you describe.
chokidar is used to watch actual files and folders.
But Meteor compiles and bundles your code, resulting in an app folder after build that is totally different from your project structure.
Although Meteor now supports dynamic imports, the mechanism is internal to Meteor and does not rely on your actual project files, but on Meteor built ones.
If you want to dynamically require files like in Node, including with dynamically generated module path, you should avoid import and require statements, which are automatically replaced by Meteor built-in import mechanism. Instead you would have to make up your own loading function, taking care of the fact that your app built folder is different from your project folder.
That may work for example if your server is watching files and/or folders in a static location, different from where your app will be running.
In the end, I feel this is a sort of XY problem: you have not described your objective in the first place, and the above issue is trying to solve a weird solution that does not seem to fit how Meteor works, hence which may not be the most appropriate solution for your implicit objective.
#Sashko does a great job of explaining Meteor's dynamic imports here. There are also docs
A dynamic import is a function that returns a promise instead of just importing statically at build time. Example:
import('./component').then((MyComponent) => {
render(MyComponent);
});
The promise runs once the module has been loaded. If you try to load the module repeatedly then it only gets loaded once and is immediately available on subsequent requests.
afaict you can use a variable for the string to import.

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.

How to import javascript file to qml worker script

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...

Categories

Resources