Exporting method from another JS file - javascript

I cannot import method from another JavaScript file.
I try both exporting single method or class from the file but still does not work. Basically i'm trying to learn Mocha so i try to create library so i can test the methods in Mocha but my exporting and importing dont seem to work. I run the script in Chrome browser.
file: myTest.js
function myTestClass(){
this.myTestText = "Welcome to myTestClass!";
this.mySum = function(a, b) {
return a + b;
}
this.mySubtraction = function(a,b) {
return a - b;
}
this.myMultiply = function(a, b) {
return a * b;
}
};
export default {myTestClass};
file: test.js
import myTestClass from 'myTest.js';
console.log("enter test.js file");
console.log("test.js finished importing myTest.js file");
file: index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset=utf-8">
<title>Mocha Tests</title>
<link href="https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.css" rel="stylesheet" />
</head>
<body>
<div id="mocha"></id>
<div id="messages"></div>
<script src="https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/4.2.0/chai.js"></script>
<script type="module" class="mocha-init">
mocha.setup('bdd');
</script>
<script src="test.js"></script>
<script type="module">
mocha.run();
</script>
</body>
</html>
when I open index.html in Chorme, none of my window.alert() functions get called so from that, the error must have occurred. Please note that all of my files are in the same directory.

You need to use relative referencing which starts with either "/", "./", or "../"
test.js
import myTestClass from './myTest.js';

This also depends if you're importing/exporting on the frontend or in Node. From what I remember, Node doesn't have import/export available so you would need to module.exports/require.
Export:
function myTestClass(){
this.myTestText = "Welcome to myTestClass!";
this.mySum = function(a, b) {
return a + b;
}
this.mySubtraction = function(a,b) {
return a - b;
}
this.myMultiply = function(a, b) {
return a * b;
}
};
export default myTestClass;
Import:
import myTestClass from './myTest.js'; // path to file that contains myTestClass
console.log("enter test.js file");
console.log("test.js finished importing myTest.js file");

Related

Emscripten triggers spurious function calls

I'm trying to get myself used to emscripten, and I have to admit that my JS is quite rusty. Anyway, as a start, I tried to compile
#include <vector>
extern "C" {
int add(int a, int b){
return a+b;
}
}
with emscripten: em++ test.cpp -sEXPORTED_FUNCTIONS=_add -sEXPORTED_RUNTIME_METHODS=ccall,cwrap. I wrote the following basic HTML page:
<!DOCTYPE html>
<html>
<head>
<script src="a.out.js"></script>
<script>
function run(){
alert("Run!");
var add = cwrap("add", "number", ["number"]);
var result = add(12, 13);
document.getElementById('output').value = result;
}
</script>
</head>
<body>
<button onclick="run();">Run!</button>
<input id="output">
</body>
</html>
The strange thing is than run() is called immediately on loading the page, which firefox unsurprisingly does not like:
Uncaught (in promise) RuntimeError: Aborted(Assertion failed: native function `add` called before runtime initialization)
and is not intended anyway. If I remove the line
<script src="a.out.js"></script>,
then the spurious call to run() disappears. Of course, this renders the page dysfunctional.
How to do it properly?
I am using Firefox 107.0.1 (MacOS) and em++ 3.1.28-git from Homebrew.
Emscripten creates hundreds of variable and function into the global namespace by default, and run is one of them.
MODULARIZE prevents namespace polution.
em++ test.cpp -sEXPORTED_FUNCTIONS=_add -sEXPORTED_RUNTIME_METHODS=ccall,cwrap -sMODULARIZE -s 'EXPORT_NAME="createModule"'
And use that module.
<!DOCTYPE html>
<html>
<head>
<script src="a.out.js"></script>
<script>
var module = null;
var add = null;
createModule().then(m => {
module = m;
add = module.cwrap("add", "number", ["number"]);
});
function run(){
alert("Run!");
var result = add(12, 13);
document.getElementById('output').value = result;
}
</script>
</head>
<body>
<button onclick="run();">Run!</button>
<input id="output">
</body>
</html>

keeping scope while using import statment

I have three scripts: main.js, helper.js and module1.js. I need to include module1.js in helper.js, buf if I do this I'm getting an error message. It seems like the moment I use the tpye="module" tag on helper.js it's scope shifts. So how do I achieve the following without an error: (I don't want to make helper.js a module, which would solve the problem, because than I have to manualy import everything.)
index.html
<html>
<head>
<title></title>
</head>
<body>
<script type="module" src='helper.js'></script>
<script type="module" src='main.js'></script>
</body>
</html>
module1.js
export { f1 }
function f1() {
/* DIFFERENT STUFF */
return 0;
}
main.js
// import THINGS from STUFF;
(() => {/*STUFF*/})();
let res = importantValue;
helper.js
import { f1 } from "./module1.js";
const importantValue = f1();
Error Message:
main.js: Uncaught ReferenceError: importantValue is not defined

Import and export issue Javascript (No node.js)

Hello !
I tried using import/exports for the first time, and I have this issue in my code :
The requested module '../Ajout/script.js' does not provide an export named 'flagMap'
I have these files Supprimer.js, containing at the first line :
import{flagMap, findUrl, createUrl,texteValide} from '../Ajout/script.js';
And in Ajout.js contained in another forlder in the parent folder:
var flagMap={/*really long map*/}
function findUrl(isoCode){/*long url finder*/}
function createUrl(svgUrl) {
return `https://upload.wikimedia.org/wikipedia/${svgUrl}`;
}
function texteValide(element){/*text validation for a form*/}
export{flagMap,findUrl,createUrl,texteValide};
/*
other non-exported functions
*/
There is the type="module" in my html when I'm importing the script, and my Ajout.js also contains other functions, maybe it's causing issues ?
Also : The issue is not only flagMap but every import, because it shows another file if I remove flagMap from the imports
This works fine for me:
<!-- index.html -->
<html>
<head> ... </head>
<body>
<script type="module" src="path/to/Supprimer.js"></script>
</body>
</html>
// Ajout.js
var flagMap = {
// ...
};
function findUrl(isoCode) {
// ...
}
function createUrl(svgUrl) {
// ...
}
function textValide(element) {
// ...
}
// Export functions and variables
export {
flagMap,
findUrl,
createUrl,
texteValide
};
// Supprimer.js
import { flagMap, findUrl } from "path/to/Ajouter.js";
console.log(flagMap); // Prints map
findUrl("EN"); // Can call function

Import functions from another js file. Javascript

I have a question about including a file in javascript.
I have a very simple example:
--> index.html
--> models
--> course.js
--> student.js
course.js:
function Course() {
this.id = '';
this.name = '';
}
A student has a course property. like this:
import './course';
function Student() {
this.firstName = '';
this.lastName = '';
this.course = new Course();
}
and the index.html is like:
<html>
<head>
<script src="./models/student.js" type="text/javascript"></script>
</head>
<body>
<div id="myDiv">
</div>
<script>
window.onload= function() {
var x = new Student();
x.course.id = 1;
document.getElementById('myDiv').innerHTML = x.course.id;
}
</script>
</body>
</html>
But I am getting an error on the line "var x = new Student();":
Student is not defined
When I remove the import from Student, I don't receive the error anymore.
I have tried to use (require, import, include, create a custom function, export) and none has worked for me.
Anybody knows why? and how to fix that?
P.S. the path is correct, it comes from the autocomplete in VS Code
The following works for me in Firefox and Chrome. In Firefox it even works from file:///
models/course.js
export function Course() {
this.id = '';
this.name = '';
};
models/student.js
import { Course } from './course.js';
export function Student() {
this.firstName = '';
this.lastName = '';
this.course = new Course();
};
index.html
<div id="myDiv">
</div>
<script type="module">
import { Student } from './models/student.js';
window.onload = function () {
var x = new Student();
x.course.id = 1;
document.getElementById('myDiv').innerHTML = x.course.id;
}
</script>
You can try as follows:
//------ js/functions.js ------
export function square(x) {
return x * x;
}
export function diag(x, y) {
return sqrt(square(x) + square(y));
}
//------ js/main.js ------
import { square, diag } from './functions.js';
console.log(square(11)); // 121
console.log(diag(4, 3)); // 5
You can also import completely:
//------ js/main.js ------
import * as lib from './functions.js';
console.log(lib.square(11)); // 121
console.log(lib.diag(4, 3)); // 5
Normally we use ./fileName.js for importing own js file/module and fileName.js is used for importing package/library module
When you will include the main.js file to your webpage you must set the type="module" attribute as follows:
<script type="module" src="js/main.js"></script>
For more details please check ES6 modules
By default, scripts can't handle imports like that directly. You're probably getting another error about not being able to get Course or not doing the import.
If you add type="module" to your <script> tag, and change the import to ./course.js (because browsers won't auto-append the .js portion), then the browser will pull down course for you and it'll probably work.
import './course.js';
function Student() {
this.firstName = '';
this.lastName = '';
this.course = new Course();
}
<html>
<head>
<script src="./models/student.js" type="module"></script>
</head>
<body>
<div id="myDiv">
</div>
<script>
window.onload= function() {
var x = new Student();
x.course.id = 1;
document.getElementById('myDiv').innerHTML = x.course.id;
}
</script>
</body>
</html>
If you're serving files over file://, it likely won't work. Some IDEs have a way to run a quick sever.
You can also write a quick express server to serve your files (install Node if you don't have it):
//package.json
{
"scripts": { "start": "node server" },
"dependencies": { "express": "latest" }
}
// server/index.js
const express = require('express');
const app = express();
app.use('/', express.static('PATH_TO_YOUR_FILES_HERE');
app.listen(8000);
With those two files, run npm install, then npm start and you'll have a server running over http://localhost:8000 which should point to your files.
//In module.js add below code
export function multiply() {
return 2 * 3;
}
// Consume the module in calc.js
import { multiply } from './modules.js';
const result = multiply();
console.log(`Result: ${result}`);
// Module.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Module</title>
</head>
<body>
<script type="module" src="./calc.js"></script>
</body>
</html>
Its a design pattern same code can be found below, please use a live server to test it else you will get CORS error
https://github.com/rohan12patil/JSDesignPatterns/tree/master/Structural%20Patterns/module

How to pass an object to an module in require.js?

I have these js files:
main.js:
requirejs(['app']);
app.js:
define(['messages'], function (messages) {
alert(messages.getHello());
});
messages.js:
define(['global'],function () {
var privateFn = global.getObj()
return {
getHello: function () {
if(privateFn.hello == "test!")
return 'Hello World';
}
};
});
global.js:
define(function () {
var stateObj = {hello:"test!"};
return {
getObj: function () { return stateObj; }
};
});
and index.html as:
<!DOCTYPE html>
<html>
<head>
<!-- Include the RequireJS library. We supply the "data-main" attribute to let
RequireJS know which file it should load. This file (scripts/main.js) can
be seen as the entry point (main) of the application. -->
<script data-main="scripts/main" src="lib/require.js"></script>
</head>
<body>
<h1>Example 2: load module using explicit dependency syntax</h1>
</body>
</html>
However when I open index.html, I get the below error in console:
Uncaught ReferenceError: global is not defined messages.js
where I'm making mistake?
You just need to set global as an argument to messages.js' function. requirejs will pass it in for you.
messages.js:
define(['global'],function (global) {
var privateFn = global.getObj()
return {
getHello: function () {
if(privateFn.hello == "test!")
return 'Hello World';
}
};
});
This has the neat side effect that it is impossible to reference a module without declaring it as a dependency.

Categories