Import JavaScript module if exists - javascript

I have a directory of JavaScript files each acting as a plugin for my app. Now in the parent directory I have a main js file in which I import those plugins. But I want to check if the plugin exists before importing them. Is it possible to do that? The directory structure looks like this:
main.js
plugins/
plugin_1.js
plugin_2.js

You can use the dyncamic import function in js which returns a promise which is rejected if the file does not exist :
import { a, b } from 'plugins/plugin_1.js'
becomes
try {
const { a, b } = await import('plugins/plugin_1.js')
} catch (error) {
// the file does not exist or couldn't be loaded
}
Notice the use of top level await here, you should so mark your script tag inside of your html async.
Hope it helped !

Related

Problem with Include JavaScript from another JavaScript in the browser

I am importing in my main JS another JS from a CDN conditionally like this:
if (('standalone' in navigator) && (!navigator.standalone)) {
import('https://unpkg.com/pwacompat');
}
But I'd like to self-host it and include this JS file into my main JS file with JavaScript in the browser method. Like this:
pwacompact.js:
function pwacompact() {
console.log("pwacompact");
}
export { logpwacompact };
// here goes the js I want to import...
main.js:
// ... other functions preceding the conditional import statement, and then:
if (('standalone' in navigator) && (!navigator.standalone)) {
import { pwacompact } from "pwacompact.min.js";
logpwacompact();
}
The problem in main.js is that I want to place this import at the bottom of the script, but I can't because I get a Parse error: The import statement may only appear at the top level.
Please, how can I solve this? How can I include the second JS into the main JS and load it conditionally?
Thanks!

How to import a file using ES6 modules, and read its content as a string?

In my standard React app, I need to achieve the following: import a file that sits within my src folder, in order to simply read its content as a string. For example, let's say I have the following code in a file:
alert('hey')
then in some other file, I would like to do something like this, in pseudo code:
import * as string from './someFile.js'
console.log(string)
The output of the console.log should be the JS code, as a string:
alert('hey')
If I could place the file within my public folder, I'd be able to perform an http request and read it as I wish. But the problem is of course, that the file is part of the build process(inside the src folder)
Can this be done?
i can think about:
define constants.js file with following code:
export default "alert('vasia')";
import this file from some react file:
import vasia from "./constants";
const App = () => {
console.log(eval(vasia));
}
is that what you r searching for?
But, must warn you: "eval" is evil!
I wanted to do the very same thing but unfortunately found out it is not possible in pure JS as at 2022.
There's a stage 3 TC39 proposal for Import Assertions which is available in Chromium-based browsers but only allows to import JSON files so it certainly would not help in this particular case.
I believe your best bet for now is to use Fetch API to get the content of your file asynchronously.
async function getSampleText() {
const response = await fetch('someFile.js');
console.log(
await response.text()
);
}

Referencing vanilla js file in TypeScript getting file is not a module

I'm trying to import a file into TypeScript that's basically just a js file that you'd put into a tag. I've tried a few different things.
// global.d.ts
declare module 'myfile.js'
Inside of the react file:
// component.tsx
import { foo } from '../lib/myFile.js' // This is saying it is not a module
Inside of the js file, it looks like this a few times so not sure how I need to reference the file:
(function( something ) {
something.Foo = function (){}
}(window.something = window.something || {}));
Any thoughts on how I could use this file? Do I need to go through and declare typings for everything in it?
EDIT: I've added allowJS to my tsconfig but it still doesn't work.
You can only import what is exported from the file.
If your file contains only immediately invoked functions, or top level code, you only need to import the file itself like this:
import '../lib/myFile.js'
This is a little weird, however. I would suggest wrapping everything with a function and exporting then importing that function instead.

How to use Vue-plugin-load-script

I am trying to load a custom JS file into my vue and I recently came across vue-plugin-load-script and installed it. I configured it as below:
In my main.js I have
Vue.loadScript("file.js").then(() => {
console.log("SUCESS")
}).catch(() => {
console.log("FAILED")
})
however, the npm page does not show how to use your functions in your views. For instances, lets say the file.js had a function called calculateTime(), and I have a view called Home.vue. How would I call the calculateTime() function from my
<script>
export default {
methods : {
** Trying to put function here **
}
}
</script>
If you have you JS File local, you can import it, like:
import * as localA from "./../../theFile.js"; /*put your path to file.js*/
And after that you can use all methods from theFile.js by writting in a method from your vue Component
methodVue: function (...) {
localA.theMethod(param); /*the Method is declared in theFile.js*/
return;
}
And in your theFile.js your method that you want to use need to be written like that
export function theMethod(param) {
...
}
Do you have a specific reason to use this library? Looking at the function all it does is add a script tag to the DOM if it is not already there and resolve the promise when it loads GitHub link. You could just as well use import * from 'file.js' at the top of the vue file. Then use the functions from that file as usual. The bundler should be able to figure out if the file is imported in multiple places and add it only once.

Is there a way to create a module that can read the directory that it is used in? (TypeScript/JavaScript)

What I'm trying do is make a handler that will read a folder that it is in. However, this handler is a module that will be imported into multiple folders.
For example, if given the current directory:
->Main
->folder a
->languages
a.js
->folder b
->languages
b.js
->folder c
->languages
c.js
d.js
d.js - handler used in a.js, b.js and c.js
var Translate = ((lang) => {
// this line below is what I want to know how to do.
import { lang } from "./languages/"+lang;
// do stuff with lang
}
export { Translate }
With the d.js handler, it should be able to be used in a.js/b.js/c.js. However I want to know how to read the directory (in this case the language folder) it is being imported in rather than from the handler. I'm doing this to handle multiple languages for an app, and I figure this way its a lot easier to manage.
If you are executing the code in NodeJS environment, you can use this to get the current directory name:
import path from "path";
const dirName = path.basename(path.dirname(filename));
The dirName variable will contain the folder name as a string.
Then you can dynamically import using ES6 template literal.
import { lang } from `./languages/${dirname}`

Categories