I'm learning laravel 5.5 and VueJs, my issue is when I export some functions from a js file and import it from a second js file it cannot be called from html body. Example:
A.js
function funA(){
}
export {funA};
B.js
import {funA} from './A.js';
At this point if I use the function funA inside the B.js it works, however if I use it on a html page it says funA is not defined. For example:
<!DOCTYPE html>
<html lang="en">
<body>
<button onClick="funA()"></button>
<script src="{{asset('js/B.js')}}"></script>
</body>
</html>
My webpack configuration is something like this:
mix.scripts('resources/assets/js/libs/materialize.js', 'public/js/libs/materialize.js')
.js('resources/assets/js/A.js', 'public/js/js/A.js')
.js('resources/assets/js/B.js', 'public/js/B.js');
Any help would be appreciated. Thank you in advanced.
I think your HTML expects the funA to be on the global window object. The new JavaScript module system doesn't add anything to the global namespace, to avoid namespace pollution.
If you just want to use is anyways on the button then, doing the below should get you working.
window.funA = funA
You can do this in your B.js. Though, I will not recommend this, as I see that you seem to be using Vue and there are better ways to do it. Let me know if this works, also try sharing your Vue code so that someone can help you do it the right way.
Related
I am new to Vite and want just one simple thing -> to reference a variable in my DOM that I declared in the main.js.
important code from main.js:
let getThis = 'Why does this not work';
important code from index.html:
<body>
<p id="test">not working</p>
<script type="module" src="/main.js"></script>
<script type="module">
document.getElementById('test').innerHTML = getThis;
</script>
Exmple: https://stackblitz.com/edit/vitejs-vite-urotp2?file=main.js,index.html,counter.js&terminal=dev I searched the Internet for 2 Days now:/
First I had a problem using Bootstrap in combination with Vite. I wanted to trigger a Modal via Javascript like in this example: https://stackblitz.com/edit/github-4akyeo?file=src%2Fjs%2Fmain.js,src%2Findex.html
important code from index.html:
<script>
const myModalAlternative = new bootstrap.Modal('#exampleModal');
myModalAlternative.show();
</script>
important code from main.js:
import * as bootstrap from 'bootstrap';
window.bootstrap = bootstrap;
But I always received Uncaught ReferenceError: bootstrap is not defined(look in the console ). I researched and found out that this is because the bootstrap variable is not linked to the window object but this didnĀ“t fix the issue. So I broke it down and realized this is a more general problem. I assume that it has something to do with the bundling of the files and now the variables aren't readable in the <script>.
Is this even possible or am I missing something here? Is this maybe a normal JavaScript scope issue? Thankful for any help.
Thanks to Arnaud from Vite I have solved the problem.
Here is What he told me:
Variables in ESM modules are scoped to the modules, you can only
access them in other modules by exporting them and using import in the
other module, like you did for the counter. More information here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules
If you want to bypass this, you can always set something on window
object to make it global, but that should be used only exceptionally
So I researched JS Modules and fixed both problems mentioned above.
Solving the main problem mentioned in the title
I had to export the variable from a file which is imported to my main.js and then import the variable in my .
code from custom.js:
export let getThis = 'Why does this not work';
important code from index.html:
import { getThis } from './custom.js';
see main problem solved
Fixing 'Uncaught ReferenceError: bootstrap is not defined'
I just had to add type="module" to <script> and bootstrap.Modal('#exampleModal'); is working now.
Keep in mind this works only if you first made bootstrap global like:
import * as bootstrap from 'bootstrap';
window.bootstrap = bootstrap; // <- add to window object to bypass the scope and make it global
see bootstrap problem solved - Stackblitz
I hope this helped someone.
I have a Javascript module called out.js
export default function out(str) {
//Some Code
console.log(str);
}
I ran the webpack bundler and created a bundle.js file.
And now I am Importing it to my index.html using a tag.
<!DOCTYPE html>
<html>
<head><script defer src="bundle.js"></script></head>
<body>
<script>
out("Hello")
</script>
</body>
</html>
But when I get the following error on the webpage.
index.html:6 Uncaught ReferenceError: out is not defined
I have tried named exports as well as default exports for the out.js, still I get the same error.
You can find a good explanation and the answer here
With my little knowledge of javascript and webpack, I spent hours looking for an answer. The short answer is you need to define your function globally to use this way. You can make out global by adding this block outside of your function.
window.out = out;
This is my first time actually posting a question here, so please go easy on me. I have been trying to create a really simple app in javascript/html and I have been writing javascript code and testing in jest up until now. Jest has been insisting that I export/import my javascript files with module.exports = {functionName} and const functionName = require('./someAddressHere');.
This has been working great so far for testing but now I want to hook up my javascript files in an index.js and start configuring my event listeners to the html. When I try the same import method I get a Uncaught ReferenceError: require is not defined. I'm pretty new to web development so is there something I'm missing here or am I going about this all wrong?
Use import and add type="module" in the script tag
Ex:
//./data.js
export const data = {
name: 'mydata'
};
//./main.js
import * as data from './data.js';
alert(JSON.stringify(data));
// html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Import</title>
</head>
<body>
<script type="module" src="main.js"></script>
</body>
</html>
So I ended up using webpack to package all my node modules and distribute to the front.
I am so confused about this. All I want to do is simply break up my javascript into modules, and include them in certain pages. Some pages may need my user-module.js , some pages may not.
I have Googled, read the tutorials, and it's still not working for me.
Here is a simple test case:
1. Include my script from my html
<script src="../js/login-view-model.js"></script>
Now, inside there...
2. TRY to include another module/js file
// LoginViewModel
// I NEED MY IMPORT HERE
import { userService } from '../js/viewModels/user-service.js'
var LoginViewModel = function () {
self = this;
userService.user.sayHello();
}; // End View Model
ko.applyBindings(new LoginViewModel());
Now, inside my user-service.js
user-service.js
let user = {
sayHello: function() { alert("hello") };
}
export {user};
I don't see what I am missing.
Do I need to use another JS library to get this simple example working? I am so lost...lol , please help!
Oh, as you can see I am using KnockoutJS. Not sure if that is the problem.
Thank you.
John
(There isn't really a good way to show how to do this in something like jsfiddle, so I appologize for the inline code)
Here is a very basic example of what you're trying to do (minus the knockout part)
One key here is that you need to tell the browser that your script is a module (type="module") (see ES6 in the browser: Uncaught SyntaxError: Unexpected token import for some other issues you can run into when not defining type as module)
The other key fix to your problem is that you're trying to invoke .sayHello() in the wrong way.
userService.user.sayHello(); // wrong
userService.sayHello(); // right
You exported user so you don't need to do .user, there is no property of user on your exported object. userService is already user
Working Example:
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script src="loginviewmodel.js" type="module"></script>
</body>
</html>
View Model
import { user } from "./userservice.js";
user.sayHello();
User Service
let user = {
sayHello: function() { alert("hello"); }
};
export {user};
you need a module bundler like webpack for example to take care of that
take your main file as an entry and generate a single JavaScript file based on your imports.
Example of a simple webpack configuration.
var path = require('path');
module.exports = {
entry: './main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'output.bundle.js'
}
};
I'm currently developing a web application and am in the process of refactoring my code so it's bundled by WebPack.
In my HTML I have a button that calls the sendMessage() function when clicked,
<button type="button" class="btn btn-default" onclick="sendMessage(document.getElementById('claim').value)">Submit</button>
In the first version of my code, the sendMessage() function was defined in a .js file that I imported directly in the HTML,
<script src="my_js/newsArticleScript.js"></script>
The sendMessage() function is directly declared in the file, it's not inside any class or module but it calls other functions defined on the same file, so I don't want to separate it.
But now it's being bundled by WebPack. Here is my config file (the homepageScript.js is for another page):
const path = require('path')
module.exports = {
entry: {
homepage: './src/homepageScript.js',
newspage: './src/newsArticleScript.js'
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist/my_js')
}
}
I changed the script import on the HTML to import the bundled version.
And now, when I press the button I get the error
[Error] ReferenceError: Can't find variable: sendMessage
I've read about it, and I learned that webpack does not expose the functions globally. I have tried to export the function, but kept getting the same error.
Can anyone help me with this? Essentially what I need is to understant how to configure webpack or change the JS so it can be accessed by the HTML.
I'm new to JS so I'm pretty sure the way my app is designed is not the best, so any tips on improvements (maybe I should use modules, or there are better ways of calling JS function upon clicking a button) would be welcome as well. Thank you :)
Generally using text-based event handlers isn't a good idea. That said, you have a few options, with increasing amounts of changes.
For texual onchange handlers to work, sendMessage would have to be a global. So the quickest fix would be to change your code to do that. If for instance you have
function sendMessage(arg){}
in your code, you'd add an additional
window.sendMessage = sendMessage;
after it to expose it as a global variable.
A more modern approach would be to remove the onchange from the button and have the button labeled with an ID in the HTML, e.g. id="some-button-id".
Then in your JS code, you could do
var button = document.querySelector("#some-button-id");
button.addEventListener("change", function(){
sendMessage(document.getElementById('claim').value);
});
to add the change handler function using JS code, instead of with HTML attributes.