I have a TS based / ViteJS project that build a small library.
I’d like to expose one of my object to the global window
(or equivalent), to be used outside of my modules, after the library has been builded.
Here is a simplified exemple, I want to use my Test()
function directly in my HTML page :
index.html (root of my project)
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script type="module" src="/src/main.ts"></script>
<script>
console.log("Hello vite...");
Test();
</script>
</body>
</html>
src/main.ts
console.log("Hello from main.ts");
function Test(){
console.log("Hello TEST !");
}
window.Test = Test;
the builded dist/index.html (no error during the build)
<!DOCTYPE html>
<html lang="en">
<head>
<script type="module" crossorigin src="/assets/index-3ba57d45.js"></script>
</head>
<body>
<script>
console.log("Hello vite...");
Test();
</script>
</body>
</html>
When I run the dist/index.html in the browser (from a local server), "Test" is not defined
Hello vite...
ERROR: Uncaught ReferenceError: Test is not defined
Hello from main.ts
How can I use my Test()
on my index.html scripts ?
Thanks!
2
Answers
Thanks to @dandavis to pointing it : The modules scripts
<script type="module" ...>
are loaded asynchronously.There is no issue on the
window.Test = ...
side (even ifglobalThis
seems more modern)So the simplest answer to that is to wait for the
DOMContentLoaded
event before using the globalTest()
method :Now the bonus question is How to NOT generate a script "module" with ViteJS?
As with doing this inside function scope, you can create a global in module scope by assigning to a property on
globalThis
(orwindow
in older environments):Properties on that object are global variables.
But, your example still won’t work because the module code isn’t executed until the HTML has been fully parsed. You could use it in an event handler (see below), but not inline as shown in the question, because you’re trying to use it before it’s been created.
Example (using function scope, but it works the same in module scope):