How to implement javascript modularity on a webpage? - javascript

Greetings I am learning javascript now and I want to know how to implement modularity in it. I googled some but didn't fully understood the method.
So I kindly ask for help. How to make this work?
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test Modularity</title>
</head>
<body>
<button id="buttonFoo" type="button" onclick="foo()">Foo</button>
<button id="buttonBar" type="button" onclick="bar()">Bar</button>
<script src="main.js"></script>
</body>
</html>
main.js
import { foo } from './foo.js'
import { bar } from './bar.js'
foo.js
export function foo()
{
alert("FOO!");
}
bar.js
export function bar()
{
alert("BAR!");
}
When I click on the buttons I get this error in debug.
Uncaught ReferenceError: foo is not defined
Uncaught ReferenceError: bar is not defined
Thanks in advance for your time.

In short, you can't just throw module-using code into the browser and expect it to work, because the web was built before modules existed, and so its "default module system" is to have none at all.
The longer answer is that you need to follow certain steps, detailed here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules
Most importantly, you need to use a type of "module" on your script tags:
<script type="module">/* ... your code */ </script>
or:
<script type="module" src="index.js"></script>

Related

How do I nest this React component in another React component?

Kind of embarrassing, since I worked as a React developer for over a year. But the system was set up when I came in, and when I created new components I just followed the syntax for the existing components and everything worked. But trying to do even simple React stuff on my home system has been really challenging. I'm not sure the problem is in my syntax, but maybe in my javascript environment.
Here is a simple thing that works:
react-test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>react-test-2</title>
<script type="text/javascript" src="../jquery-1.3.2.min.js"></script>
<script src="https://unpkg.com/react#18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom#18/umd/react-dom.development.js" crossorigin></script>
<script src="React_Components/AAA.js"></script>
<script>
$(document).ready(function() {
const domContainer = document.querySelector('#react-container');
const root = ReactDOM.createRoot(domContainer);
root.render(React.createElement(AAA));
});
</script>
</head>
<body>
<div id="react-container"></div>
</body>
</html>
AAA.jsx
function AAA(){
return (<div>AAA</div>);
}
The .jsx files are in React_Components_JSX, which is watched by the Babel preprocessor, which makes analogous .js files in React_Components. When I navigate to the html page, it renders the expected "AAA" on the page.
Now I'm just trying to nest another component inside the AAA component. So I update the file AAA.jsx and create a file BBB.jsx, something like the following (although I have tried various syntaxes hoping to make this work). I am expecting to see a webpage that renders "AAABBB".
AAA.jsx
import BBB from '../React_Components_JSX/BBB.jsx';
function AAA(){
return (<div>AAA<BBB/></div>);
}
BBB.jsx
export default function BBB(){
return (<div>BBB</div>);
}
The main error I am getting is "Cannot use import statement outside a module". Which I know explains the problem, but I don't really understand what that means on a fundamental level, as far as how I have to set my application up.

Learning how to use ES6 import and modules getting Reference Error

I am just beginning to learn ES6 imports, with the hopes to transition an application to modular ES6. My current project has the following directory structure:
index.html
-scripts\
--function1.js
--function2.js
--globals.js
--main.js
My index.html file code is as follows:
<!DOCTYPE html>
<html lang="en">
<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>Modular JS Example</title>
</head>
<body>
<button onclick="changevar1()">Change Var 1</button>
<button onclick="changevar2()">Change Var 2</button>
<script src="scripts/main.js" type="module"></script>
</body>
</html>
As you can see, I have two buttons which have onclick triggers assigned to them. These functions namely, changevar1() and changevar2() are found in files function1.js and function2.js respectively. And my entry point is main.js.
My main.js is as follows:
import {globalvar1 as globalvar1,
globalvar2 as globalvar2} from "./globals.js";
import {changevar1 as changevar1} from "./function1.js";
import {changevar2 as changevar2} from "./function2.js";
console.log(globalvar1, globalvar2,changevar1,changevar2);
My globals.js is where I declare some global variables which will be used by functions in either functions1.js or functions2.js and is as follows:
export let globalvar1 = "I am globalvar1";
export let globalvar2 = "I am globalvar2";
My function1.js has the function for the first button and is as follows:
import { globalvar1 } from "./globals.js" //do I need to import here?
export function changevar1() {
globalvar1 = "Now changed globalvar1"
console.log(globalvar1);
}
In the case above, I am importing the globalvar1 from globals.js and I am not sure if that is required, or if it will all come together in main.js?
My function2.js has the function for the second button and is as follows:
export function changevar2() {
globalvar2 = "Now changed globalvar2"
console.log(globalvar2);
}
In this case, I was not importing the globalvar2, just to see if it was not required.
Now the question is simply when you press the button how can you trigger either changevar1() or changevar2() to change the globalvar1 or globalvar2? I keep getting "Reference errors".
I have read several online documents and watched a few video tutorials online too to try to understand modular js.
Please excuse my lack of knowledge about modules and any help even if very basic knowledge is helpful.

JavaScript Imports

I am trying to call the function popup from within index.html. When I view this code below in the browser I get this error ReferenceError: popup is not defined. The reason why I am trying to do this is to better organize my code when I have many functions, I thought it might be easier to import them all into one file and then import that file into my index.html file. I don't know if this is best practice or not, but I thought it would help.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>title</title>
<link rel="stylesheet" href="style.scss">
<script type="module" src="main.js"></script>
</head>
<body>
<script>popup("testing")</script>
</body>
</html>
main.js
import { popup } from './main/popup.js';
popup.js
export function popup(x) {
alert(x);
}
Your main.js runs in a module, not on the top level. If you want to be able to reference it outside, from a non-module script, either explicitly put it onto the window to make it global:
import { popup } from './main/popup.js';
window.popup = popup;
(though, that kind of defeats the purpose of using modules at all)
Or put the script that calls popup into a module as well (rather than in an inline script):
<body>
<script type="module" src='bodyScript.js'></script>
</body>
// bodyScript.js
import { popup } from './main/popup.js';
popup("testing");

In browser JS code that imports from ES6 module is not executed

I have an ES6 module (mymodule) and HTML page that has JS code that must be executed when a user opens the page. This is my module:
//mymodule.js
class TestClass {
getString() {
return "TestString";
}
}
export {TestClass}
And this is my page:
//page.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Page</title>
<script src="./mymodule.js" type="module"></script>
</head>
<body>
<h1>Hello World!</h1>
<script type="module">
import {TestClass} from "./mymodule";
let test = new TestClass();
console.log("OUTPUT: " + test.getString());
</script>
</body>
</html>
Page.html and mymodule.js are in the same folder, however, when I open page.html in browser I have nothing on console (no error, no output) - I use FF 62.0.3. How to fix it?
<script src="./mymodule.js" type="module"></script>
The above is not needed. You can remove it.
import {TestClass} from "./mymodule";
Browsers don't do file extension resolution the way Node.js does. (They can't, because they deal in URLs and not file systems, so there is no way to get a list of files in a directory).
You need to be explicit with the URL:
import {TestClass} from "./mymodule.js";
NB: You also need to load page.html over HTTP and not from the local file system.
You can export your class to default keyword.
class TestClass {
getString() {
return "TestString";
}
}
export default {TestClass}

Standalone Babel and using arrow functions plugin?

I'm building an App in a non-node environment but I want to make use of Babel's ES6 transpiling so that I can write somewhat nicer code and still support IE11.
So I went ahead and included the standalone file found here:
https://github.com/babel/babel/tree/master/packages/babel-standalone
But it seems like you also need an additional plugin to actually transpile arrow function syntax, but of course because I don't have access to the import/export module features I'm not sure if it is even possible to include these plugins.
Does anyone know a way around this?
As you have shown ZERO code in the question, and you're going on about setting this preset or that preset (blah blah blah), I can only assume you're doing something wrong
This HTML works in IE
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Home</title>
<script src="https://unpkg.com/#babel/polyfill/browser.js"></script>
<script src="https://unpkg.com/#babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="output"></div>
<script type="text/babel">
const getMessage = () => "Hello World";
document.getElementById('output').innerHTML = getMessage();
</script>
</body>
</html>
How does it compare with what you are doing?

Categories