4

Seems like my web-days are too long away. When I started programming we referenced a script using a <script>-tag:

<html>
<head>
  <script src="lealet.js"></script> <!-- I know the path isn´t correct, I just reference leaflet -->
  <script src="myscript.js"></script>
</head>
<body><script>myFunction()</script></body>
</html>

where myScript is this:

function myFunction() { var map = new L.Map(...); }

which just creates a leaflet-map. Now I wanted to migrate this to some statically-typed TypScript. Instead of referencing leaflet from within my HTML-file, I used this in mScript.ts:

import * as L from 'leafet';
function myFunction() { var map = L.Map(...); }

I compiled that to JS. However when running my site in the browser using the HTML from above I get this:

Uncaught SyntaxError: Cannot use import statement outside a module

I´m targeting ES6 with modulekind ES6.

2
  • You cannot just reference a TS file. You have to compile TS to JS, then rederence that. Commented Mar 1, 2020 at 11:51
  • @JonasWilms I´m aware of that. The JS-file already was compiled. It contains this line: import * as L from 'leaflet';. which seems what my browser is complaining about Commented Mar 1, 2020 at 11:53

1 Answer 1

2

You can either try to use your compiled JavaScript as a native ESM module, or use a module bundling solution.

Modern browsers support JavaScript imports out of the box, if you specify type="module" on the script tag.

// main.mjs
import * as L from 'https://unpkg.com/browse/[email protected]/dist/leaflet-src.esm.js';

function myFunction() {
  const map = new L.Map(...);
}

// if you need to access myFunction from an inline script tag, export it to window :
window.myFunction = myFunction;
// index.html
<script type="module" src="main.mjs"></script>

To get this working, you should specify a target newer than ES5 in your tsconfig.json. ES6 should work. Use something newer like ES2020 if you need more recent JavaScript features.

Something to keep in mind with this approach is that ancient browsers like IE11 will not load any module type JavaScript at all. Also, the library you want to use needs to use the ESM module syntax, importing CommonJS style libraries don't work out of the box without any module bundling solution. In my example, I used the .esm.js version of Leaflet. Also, the esm.js of leaflet currently has no default import, so you have to use the * as syntax.

Another option is to use a module bundler that transpiles your code plus your used libraries into a single bundle.js file. Popular bundlers are

If the above options don't work for your project, a third approach is to remove the library import from your main TypeScript file, load the library via a separate <script src="leaflet.js"></script> and then use the globally exported window.L object.

Sign up to request clarification or add additional context in comments.

7 Comments

And do I really need two such files? The one that defines the Library and the other one that uses is? Can´t I use it directly in my HTML?
@HimBromBeere the Library file was just an example for the library to be used in the project.
I don´t have NodeJS. It´s a pure client-application.
Can´t I call my function directly within my HTML? So define the dependecy within my head-tag and call one of its function within the body?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.