import packages in CoffeeScript [duplicate] - javascript

I'm using ArcGIS JSAPI 4.12 and wish to use Spatial Illusions to draw military symbols on a map.
When I add milsymbol.js to the script, the console returns error
Uncaught SyntaxError: Cannot use import statement outside a module`
so I add type="module" to the script, and then it returns
Uncaught ReferenceError: ms is not defined
Here's my code:
<link rel="stylesheet" href="https://js.arcgis.com/4.12/esri/css/main.css">
<script src="https://js.arcgis.com/4.12/"></script>
<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/MapImageLayer",
"esri/layers/FeatureLayer"
], function (Map, MapView, MapImageLayer, FeatureLayer) {
var symbol = new ms.Symbol("SFG-UCI----D", { size: 30 }).asCanvas(3);
var map = new Map({
basemap: "topo-vector"
});
var view = new MapView({
container: "viewDiv",
map: map,
center: [121, 23],
zoom: 7
});
});
</script>
So, whether I add type="module" or not, there are always errors. However, in the official document of Spatial Illusions, there isn't any type="module" in the script. I'm now really confused. How do they manage to get it work without adding the type?
File milsymbol.js
import { ms } from "./ms.js";
import Symbol from "./ms/symbol.js";
ms.Symbol = Symbol;
export { ms };

Update For Node.js / NPM
Add "type": "module" to your package.json file.
{
// ...
"type": "module",
// ...
}
Note: When using modules, if you get ReferenceError: require is not defined, you'll need to use the import syntax instead of require. You can't natively mix and match between them, so you'll need to pick one or use a bundler if you need to use both.

I got this error because I forgot the type="module" inside the script tag:
<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>

It looks like the cause of the errors are:
You're currently loading the source file in the src directory instead of the built file in the dist directory (you can see what the intended distributed file is here). This means that you're using the native source code in an unaltered/unbundled state, leading to the following error: Uncaught SyntaxError: Cannot use import statement outside a module. This should be fixed by using the bundled version since the package is using rollup to create a bundle.
The reason you're getting the Uncaught ReferenceError: ms is not defined error is because modules are scoped, and since you're loading the library using native modules, ms is not in the global scope and is therefore not accessible in the following script tag.
It looks like you should be able to load the dist version of this file to have ms defined on the window. Check out this example from the library author to see an example of how this can be done.

I resolved my case by replacing "import" by "require".
// import { parse } from 'node-html-parser';
const parse = require('node-html-parser');

I was also facing the same issue until I added the type="module" to the script.
Before it was like this
<script src="../src/main.js"></script>
And after changing it to
<script type="module" src="../src/main.js"></script>
It worked perfectly.

There are several common ways to resolve the conflict associated with the above issue
1. The first: In the script, include type=module
<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>
2. The second: In node.js, into your package.json file
{
"type": "module",
}
Restart the project npm start
3. The third: replace import by required
Try this
import { parse } from 'node-html-parser';
parse = require('node-html-parser');
Else try this
//import { parse } from 'node-html-parser';
parse = require('node-html-parser');

Applicable for node 12. This answer is no longer maintained for new node versions. Feel free to comment solutions for more recent versions.
I solved this issue by doing the following:
When using ECMAScript 6 modules from the browser, use the .js extension in your files, and in the script tag add type = "module".
When using ECMAScript 6 modules from a Node.js environment, use the extension .mjs in your files and use this command to run the file:
node --experimental-modules filename.mjs
Edit: This was written when node12 was the latest LTS, this does not apply to node 14 LTS.

I don't know whether this has appeared obvious here. I would like to point out that as far as client-side (browser) JavaScript is concerned, you can add type="module" to both external as well as internal js scripts.
Say, you have a file 'module.js':
var a = 10;
export {a};
You can use it in an external script, in which you do the import, eg.:
<!DOCTYPE html><html><body>
<script type="module" src="test.js"></script><!-- Here use type="module" rather than type="text/javascript" -->
</body></html>
test.js:
import {a} from "./module.js";
alert(a);
You can also use it in an internal script, eg.:
<!DOCTYPE html><html><body>
<script type="module">
import {a} from "./module.js";
alert(a);
</script>
</body></html>
It is worthwhile mentioning that for relative paths, you must not omit the "./" characters, ie.:
import {a} from "module.js"; // this won't work

For me, it was caused by not referencing a library (specifically typeORM, using the ormconfig.js file, under the entities key) to the src folder, instead of the dist folder...
"entities": [
"src/db/entity/**/*.ts", // Pay attention to "src" and "ts" (this is wrong)
],
instead of
"entities": [
"dist/db/entity/**/*.js", // Pay attention to "dist" and "js" (this is the correct way)
],

If you want to use import instead of require() for modules, change or add the value of type to module in package.json file
Example:
package.json file
{
"name": "appsample",
"version": "1.0.0",
"type": "module",
"description": "Learning Node",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Chikeluba Anusionwu",
"license": "ISC"
}
import http from 'http';
var host = '127.0.0.1',
port = 1992,
server = http.createServer();
server.on('request', (req, res) => {
res.writeHead(200, {"Content-Type": "text/plain"});
res.end("I am using type module in package.json file in this application.");
});
server.listen(port, () => console.log(
'Listening to server ${port}. Connection has been established.'));

I got this error in React and fixed it with the following steps:
Go to the project root directory, and open the Package.json file for editing.
Add "type":"module";
Save it and restart the server.

Add "type": "module", to your package.json file.
And restart your application:
npm start
Then your problem is solved.

I'm coding on vanilla JavaScript. If you're doing same, simply add a type="module" to your script tag.
That is, previous code:
<script src="./index.js"></script>
Updated code:
<script type="module" src="./index.js"></script>`

Why this occurs and more possible causes:
A lot of interfaces still do not understand ES6 JavaScript syntax/features. Hence there is need for ES6 to be compiled to ES5 whenever it is used in any file or project.
The possible reasons for the SyntaxError: Cannot use import statement outside a module error is you are trying to run the file independently. You are yet to install and set up an ES6 compiler such as Babel or the path of the file in your runscript is wrong/not the compiled file.
If you will want to continue without a compiler, the best possible solution is to use ES5 syntax, which in your case would be var ms = require(./ms.js);. This can later be updated as appropriate or better still set up your compiler and ensure your file/project is compiled before running and also ensure your run script is running the compiled file usually named dist, build or whatever you named it and the path to the compiled file in your runscript is correct.

For me this helped:
In the .ts file I used: import prompts from "prompts";
And used "module": "commonjs" in file tsconfig.json

The error is triggered because the file you're linking to in your HTML file is the unbundled version of the file.
To get the full bundled version you'll have to install it with npm:
npm install --save milsymbol
This downloads the full package to your node_modules folder.
You can then access the standalone minified JavaScript file at node_modules/milsymbol/dist/milsymbol.js
You can do this in any directory, and then just copy the below file to your /src directory.

Use this code. It worked well for me:
Add this script tag to file index.html:
<script type="module">
import { ms } from "./ms.js";
import Symbol from "./ms/symbol.js";
</script>

I ran into this error while trying to use import Express.js.
Instead of   import express from 'express';
I used   const express = require('express');

I have faced the same error by EXPO.
Mainly the solution is that to add "type": "module", in the package.json file.
However, you have to check that which is your correct package.json.
In my case, there are two package.json files, then you should add that to the server file.
To identify which is correct package.json, find "scripts": { "test": "echo \"Error: no test specified\" && exit 1" },
Below ↑ this line, add "type": "module",

None of the provided answers worked for me, but I found a different solution from: How to enable ECMAScript 6 imports in Node.js
Install ESM:
npm install --save esm
Run with ESM:
node -r esm server.js

In my case, I updated
"lib": [
"es2020",
"dom"
]
with
"lib": [
"es2016",
"dom"
]
in my tsconfig.json file.

I had to import some data from an external file (JavaScript file), to my script.js file present in my HTML file.
File data.js
const data = {a: 1, b: 2}
By adding type=module I got CORS error.
I found out that I can import file data.js into my script.js file just by including file data.js inside my HTML file.
For example, previously my HTML file consists of
<script src="assets/script.js"></script>
As I required some data from file data.js, I just changed my HTML file to:
<script src="assets/data.js"></script>
<script src="assets/script.js"></script>
I.e., include file data.js before file script.js, giving access to my data variable inside file script.js.

I just added "type": "module" to my Package.json file and it worked for me.

I thought I would add this note because it was not apparently obvious to me. You need to add type="module" to all script includes, not just the one you want to use for your utility file.
index.html:
<script type="module" src="js/controllers/utils.js"></script>
<script type="module" src="js/controllers/main.js"></script>`
main.js:
import myFunction from './utils.js
utils.js:
export default myFunction

if you want to import functions from module.
let's say, main.js has func1 and func2 defined, and you want to import those to function to a new module say, test.js
Below will solve the problem.
main.js:
const func1 = () => {console.log('do sth in func1')};
const func2 = () => {console.log('do sth in func2')};
//at the end of module
//export specific functions here
module.exports = { func1, func2 };
test.js :
// import them here
const{ func1, func2} = require('./main.js');
func1();
func2();

Well, in my case, I didn't want to update my package.json file and change the file type to mjs.
So I was looking around and found out that changing the module in file tsconfig.json affected the result. My ts.config file was:
{
"compilerOptions": {
"target": "es2020",
"module": "es2020",
"lib": [
"es2020",
],
"skipLibCheck": true,
"sourceMap": true,
"outDir": "./dist",
"moduleResolution": "node",
"removeComments": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"resolveJsonModule": true,
"baseUrl": "."
},
"exclude": [
"node_modules"
],
"include": [
"./src/**/*.ts"
]
}
Like this and changing the module from "module": "es2020" to "module" : "commonjs" solved my issue.
I was using MikroORM and thought maybe it doesn't support any module above CommonJS.

It's because you haven't exported. The .ts file requires an export class format, whereas in a .js file we would use the exports function.
So, we have to use var_name = require("<pathfile>") to use those file functions.

Use
<script type="module" src="/src/moduleA.js"></script>
instead of
<script>System.import("/src/moduleA.js")</script>

For me it was a compilation problem. I've added
"devDependencies": {
...
"#babel/cli": "^7.7.5",
"#babel/core": "^7.7.5",
"#babel/node": "^7.7.4",
"#babel/plugin-proposal-class-properties": "^7.7.4",
"#babel/plugin-transform-instanceof": "^7.8.3",
"#babel/plugin-transform-runtime": "^7.7.6",
"#babel/preset-env": "^7.7.5",
"#babel/register": "^7.7.4",
"#babel/runtime": "^7.9.6"
},
"dependencies": {
...
"#babel/plugin-transform-classes": "^7.15.4"
},
added .babelrc file
{
"plugins": [
"#babel/plugin-proposal-class-properties",
"#babel/plugin-transform-instanceof",
"#babel/plugin-transform-classes"
],
"presets": ["#babel/preset-env"],
"env": {
"test": {
"plugins": ["#babel/plugin-transform-runtime"]
}
}
}

Just add .pack between the name and the extension in the <script> tag in src.
I.e.:
<script src="name.pack.js">
// Code here
</script>

Related

Uncaught SyntaxError: Cannot use import statement outside a module in Google Chrome [duplicate]

I'm using ArcGIS JSAPI 4.12 and wish to use Spatial Illusions to draw military symbols on a map.
When I add milsymbol.js to the script, the console returns error
Uncaught SyntaxError: Cannot use import statement outside a module`
so I add type="module" to the script, and then it returns
Uncaught ReferenceError: ms is not defined
Here's my code:
<link rel="stylesheet" href="https://js.arcgis.com/4.12/esri/css/main.css">
<script src="https://js.arcgis.com/4.12/"></script>
<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/MapImageLayer",
"esri/layers/FeatureLayer"
], function (Map, MapView, MapImageLayer, FeatureLayer) {
var symbol = new ms.Symbol("SFG-UCI----D", { size: 30 }).asCanvas(3);
var map = new Map({
basemap: "topo-vector"
});
var view = new MapView({
container: "viewDiv",
map: map,
center: [121, 23],
zoom: 7
});
});
</script>
So, whether I add type="module" or not, there are always errors. However, in the official document of Spatial Illusions, there isn't any type="module" in the script. I'm now really confused. How do they manage to get it work without adding the type?
File milsymbol.js
import { ms } from "./ms.js";
import Symbol from "./ms/symbol.js";
ms.Symbol = Symbol;
export { ms };
Update For Node.js / NPM
Add "type": "module" to your package.json file.
{
// ...
"type": "module",
// ...
}
Note: When using modules, if you get ReferenceError: require is not defined, you'll need to use the import syntax instead of require. You can't natively mix and match between them, so you'll need to pick one or use a bundler if you need to use both.
I got this error because I forgot the type="module" inside the script tag:
<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>
It looks like the cause of the errors are:
You're currently loading the source file in the src directory instead of the built file in the dist directory (you can see what the intended distributed file is here). This means that you're using the native source code in an unaltered/unbundled state, leading to the following error: Uncaught SyntaxError: Cannot use import statement outside a module. This should be fixed by using the bundled version since the package is using rollup to create a bundle.
The reason you're getting the Uncaught ReferenceError: ms is not defined error is because modules are scoped, and since you're loading the library using native modules, ms is not in the global scope and is therefore not accessible in the following script tag.
It looks like you should be able to load the dist version of this file to have ms defined on the window. Check out this example from the library author to see an example of how this can be done.
I resolved my case by replacing "import" by "require".
// import { parse } from 'node-html-parser';
const parse = require('node-html-parser');
I was also facing the same issue until I added the type="module" to the script.
Before it was like this
<script src="../src/main.js"></script>
And after changing it to
<script type="module" src="../src/main.js"></script>
It worked perfectly.
There are several common ways to resolve the conflict associated with the above issue
1. The first: In the script, include type=module
<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>
2. The second: In node.js, into your package.json file
{
"type": "module",
}
Restart the project npm start
3. The third: replace import by required
Try this
import { parse } from 'node-html-parser';
parse = require('node-html-parser');
Else try this
//import { parse } from 'node-html-parser';
parse = require('node-html-parser');
Applicable for node 12. This answer is no longer maintained for new node versions. Feel free to comment solutions for more recent versions.
I solved this issue by doing the following:
When using ECMAScript 6 modules from the browser, use the .js extension in your files, and in the script tag add type = "module".
When using ECMAScript 6 modules from a Node.js environment, use the extension .mjs in your files and use this command to run the file:
node --experimental-modules filename.mjs
Edit: This was written when node12 was the latest LTS, this does not apply to node 14 LTS.
I don't know whether this has appeared obvious here. I would like to point out that as far as client-side (browser) JavaScript is concerned, you can add type="module" to both external as well as internal js scripts.
Say, you have a file 'module.js':
var a = 10;
export {a};
You can use it in an external script, in which you do the import, eg.:
<!DOCTYPE html><html><body>
<script type="module" src="test.js"></script><!-- Here use type="module" rather than type="text/javascript" -->
</body></html>
test.js:
import {a} from "./module.js";
alert(a);
You can also use it in an internal script, eg.:
<!DOCTYPE html><html><body>
<script type="module">
import {a} from "./module.js";
alert(a);
</script>
</body></html>
It is worthwhile mentioning that for relative paths, you must not omit the "./" characters, ie.:
import {a} from "module.js"; // this won't work
For me, it was caused by not referencing a library (specifically typeORM, using the ormconfig.js file, under the entities key) to the src folder, instead of the dist folder...
"entities": [
"src/db/entity/**/*.ts", // Pay attention to "src" and "ts" (this is wrong)
],
instead of
"entities": [
"dist/db/entity/**/*.js", // Pay attention to "dist" and "js" (this is the correct way)
],
If you want to use import instead of require() for modules, change or add the value of type to module in package.json file
Example:
package.json file
{
"name": "appsample",
"version": "1.0.0",
"type": "module",
"description": "Learning Node",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Chikeluba Anusionwu",
"license": "ISC"
}
import http from 'http';
var host = '127.0.0.1',
port = 1992,
server = http.createServer();
server.on('request', (req, res) => {
res.writeHead(200, {"Content-Type": "text/plain"});
res.end("I am using type module in package.json file in this application.");
});
server.listen(port, () => console.log(
'Listening to server ${port}. Connection has been established.'));
I got this error in React and fixed it with the following steps:
Go to the project root directory, and open the Package.json file for editing.
Add "type":"module";
Save it and restart the server.
Add "type": "module", to your package.json file.
And restart your application:
npm start
Then your problem is solved.
I'm coding on vanilla JavaScript. If you're doing same, simply add a type="module" to your script tag.
That is, previous code:
<script src="./index.js"></script>
Updated code:
<script type="module" src="./index.js"></script>`
Why this occurs and more possible causes:
A lot of interfaces still do not understand ES6 JavaScript syntax/features. Hence there is need for ES6 to be compiled to ES5 whenever it is used in any file or project.
The possible reasons for the SyntaxError: Cannot use import statement outside a module error is you are trying to run the file independently. You are yet to install and set up an ES6 compiler such as Babel or the path of the file in your runscript is wrong/not the compiled file.
If you will want to continue without a compiler, the best possible solution is to use ES5 syntax, which in your case would be var ms = require(./ms.js);. This can later be updated as appropriate or better still set up your compiler and ensure your file/project is compiled before running and also ensure your run script is running the compiled file usually named dist, build or whatever you named it and the path to the compiled file in your runscript is correct.
For me this helped:
In the .ts file I used: import prompts from "prompts";
And used "module": "commonjs" in file tsconfig.json
The error is triggered because the file you're linking to in your HTML file is the unbundled version of the file.
To get the full bundled version you'll have to install it with npm:
npm install --save milsymbol
This downloads the full package to your node_modules folder.
You can then access the standalone minified JavaScript file at node_modules/milsymbol/dist/milsymbol.js
You can do this in any directory, and then just copy the below file to your /src directory.
Use this code. It worked well for me:
Add this script tag to file index.html:
<script type="module">
import { ms } from "./ms.js";
import Symbol from "./ms/symbol.js";
</script>
I ran into this error while trying to use import Express.js.
Instead of   import express from 'express';
I used   const express = require('express');
I have faced the same error by EXPO.
Mainly the solution is that to add "type": "module", in the package.json file.
However, you have to check that which is your correct package.json.
In my case, there are two package.json files, then you should add that to the server file.
To identify which is correct package.json, find "scripts": { "test": "echo \"Error: no test specified\" && exit 1" },
Below ↑ this line, add "type": "module",
None of the provided answers worked for me, but I found a different solution from: How to enable ECMAScript 6 imports in Node.js
Install ESM:
npm install --save esm
Run with ESM:
node -r esm server.js
In my case, I updated
"lib": [
"es2020",
"dom"
]
with
"lib": [
"es2016",
"dom"
]
in my tsconfig.json file.
I had to import some data from an external file (JavaScript file), to my script.js file present in my HTML file.
File data.js
const data = {a: 1, b: 2}
By adding type=module I got CORS error.
I found out that I can import file data.js into my script.js file just by including file data.js inside my HTML file.
For example, previously my HTML file consists of
<script src="assets/script.js"></script>
As I required some data from file data.js, I just changed my HTML file to:
<script src="assets/data.js"></script>
<script src="assets/script.js"></script>
I.e., include file data.js before file script.js, giving access to my data variable inside file script.js.
I just added "type": "module" to my Package.json file and it worked for me.
I thought I would add this note because it was not apparently obvious to me. You need to add type="module" to all script includes, not just the one you want to use for your utility file.
index.html:
<script type="module" src="js/controllers/utils.js"></script>
<script type="module" src="js/controllers/main.js"></script>`
main.js:
import myFunction from './utils.js
utils.js:
export default myFunction
if you want to import functions from module.
let's say, main.js has func1 and func2 defined, and you want to import those to function to a new module say, test.js
Below will solve the problem.
main.js:
const func1 = () => {console.log('do sth in func1')};
const func2 = () => {console.log('do sth in func2')};
//at the end of module
//export specific functions here
module.exports = { func1, func2 };
test.js :
// import them here
const{ func1, func2} = require('./main.js');
func1();
func2();
Well, in my case, I didn't want to update my package.json file and change the file type to mjs.
So I was looking around and found out that changing the module in file tsconfig.json affected the result. My ts.config file was:
{
"compilerOptions": {
"target": "es2020",
"module": "es2020",
"lib": [
"es2020",
],
"skipLibCheck": true,
"sourceMap": true,
"outDir": "./dist",
"moduleResolution": "node",
"removeComments": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"resolveJsonModule": true,
"baseUrl": "."
},
"exclude": [
"node_modules"
],
"include": [
"./src/**/*.ts"
]
}
Like this and changing the module from "module": "es2020" to "module" : "commonjs" solved my issue.
I was using MikroORM and thought maybe it doesn't support any module above CommonJS.
It's because you haven't exported. The .ts file requires an export class format, whereas in a .js file we would use the exports function.
So, we have to use var_name = require("<pathfile>") to use those file functions.
Use
<script type="module" src="/src/moduleA.js"></script>
instead of
<script>System.import("/src/moduleA.js")</script>
For me it was a compilation problem. I've added
"devDependencies": {
...
"#babel/cli": "^7.7.5",
"#babel/core": "^7.7.5",
"#babel/node": "^7.7.4",
"#babel/plugin-proposal-class-properties": "^7.7.4",
"#babel/plugin-transform-instanceof": "^7.8.3",
"#babel/plugin-transform-runtime": "^7.7.6",
"#babel/preset-env": "^7.7.5",
"#babel/register": "^7.7.4",
"#babel/runtime": "^7.9.6"
},
"dependencies": {
...
"#babel/plugin-transform-classes": "^7.15.4"
},
added .babelrc file
{
"plugins": [
"#babel/plugin-proposal-class-properties",
"#babel/plugin-transform-instanceof",
"#babel/plugin-transform-classes"
],
"presets": ["#babel/preset-env"],
"env": {
"test": {
"plugins": ["#babel/plugin-transform-runtime"]
}
}
}
Just add .pack between the name and the extension in the <script> tag in src.
I.e.:
<script src="name.pack.js">
// Code here
</script>

Importing leaflet into module from cdn with typescript support

I'm trying to import leaflet into a javascript module with typescript support but can't get it to work.
I've installed #types/leaflet and have tried to following:
import 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.8.0/leaflet.js'
This works fine in the browser but typescript gives the following error:
'L' refers to a UMD global, but the current file is a module. Consider adding an import instead.ts(2686)
(I call L.map() in my code)
I've also tried:
import * as L from 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.8.0/leaflet.js'
This works fine in typescript, but gives the following error in chrome:
Uncaught TypeError: L.map is not a function
Anyone know how to fix this?
I don't want to use a bundler.
Edit
As jsejcksn suggested in the comments, importing a ES module version of leaflet and adding a path alias to typescript fixed this.
I'm now using the following import:
import * as L from 'https://unpkg.com/leaflet#1.8.0/dist/leaflet-src.esm.js'
The problem with this though, as stated on Leaflet's Download page, is that this imports Leaflet's source files including unit tests, files for debugging, build scripts, etc. This doesn't seem very efficient to me.
Any other ideas?
Edit 2
It seems like Leaflet 1.9 will solve my problem when it will be released. This pull request adds an ES module entrypoint to Leaflet meaning you can do this:
import L from 'leaflet'
or in our case:
import L from 'cdn.com/link/to/leaflet/1.9/esm'
In the mean time, jsejcksn's answer provides a good alternative so I will accept that answer.
Preface
I've already written an answer about how to do this with ES modules at the question How to include modules in client side in typescript projects?. Be sure to read through that question and answer for context here.
You said:
I don't want to use a bundler.
and also:
The problem with this though, as stated on Leaflet's Download page, is that this imports Leaflet's source files including unit tests, files for debugging, build scripts, etc. This doesn't seem very efficient to me.
These ideas seem at odds to me. Without more information, I can only assume that by "not very efficient" you mean that the byte size of the presumably not-tree-shaken ES module is larger than the UMD module. If that's the case, why not just import Leaflet into your bundle and tree-shake away all of the parts that you don't use during build, resulting in even fewer bytes than the UMD?
Ignoring that for now, and responding purely to your stated criteria, below I will provide a self-contained, reproducible example demonstrating how you can use a CDN-hosted UMD module that has a corresponding #types package in a TypeScript ES module without augmenting the definition of globalThis.window in the compiler and without bundling.
Note that some of what I show will be purely ceremonial, but the technique will allow for you to later swap out the shim module URL in the import map with a CDN ES module URL if/when you find one that suits you.
Download the files in this example
I'm going to provide a complete reproducible example here, including all the content of each file in a code block. If you want to use this example to reproduce it and don't want to copy + paste every individual code block into a new file with a matching name on your device, then you can copy + paste the following script and run it in your browser console to download the repo as a zip archive file:
function download (data, fileName, mediaType) {
const a = document.createElement('a');
const blob = new Blob([data], mediaType ? {type: mediaType} : undefined);
const url = URL.createObjectURL(blob);
a.href = url;
a.download = fileName;
a.click();
a.remove();
// URL.revokeObjectURL(url);
}
download(
new Uint8Array([80,75,3,4,20,0,0,0,8,0,173,178,247,84,63,79,13,255,254,0,0,0,4,24,0,0,9,0,28,0,46,68,83,95,83,116,111,114,101,85,84,9,0,3,182,186,220,98,78,194,220,98,117,120,11,0,1,4,245,1,0,0,4,20,0,0,0,237,152,49,78,196,48,16,69,255,132,72,88,162,113,73,233,43,236,13,204,42,112,129,109,232,64,75,34,40,178,202,22,32,218,92,135,123,112,27,46,65,140,255,66,68,130,4,5,218,21,252,39,89,47,146,199,246,164,177,61,6,96,203,135,122,1,120,0,14,217,150,62,102,112,108,19,10,186,76,131,223,230,104,112,143,166,189,93,172,110,186,249,185,14,142,148,251,49,174,80,15,185,183,227,252,55,219,81,212,167,136,77,87,85,235,182,91,15,61,238,165,121,186,124,188,120,62,155,139,170,191,17,181,189,155,172,38,132,16,66,252,38,150,229,78,246,155,134,16,226,0,73,251,67,160,35,221,103,27,251,11,186,28,141,241,116,160,35,221,103,27,227,10,186,164,29,237,233,64,71,186,207,230,166,101,44,62,140,43,239,138,23,243,116,160,227,143,126,89,136,127,195,81,150,79,231,255,249,215,245,191,16,226,15,99,101,181,170,150,120,47,8,38,164,179,54,12,237,122,55,0,60,205,49,189,4,20,249,177,240,20,31,253,129,142,116,159,173,139,128,16,251,226,21,80,75,3,4,10,0,0,0,0,0,135,182,247,84,0,0,0,0,0,0,0,0,0,0,0,0,18,0,28,0,46,109,101,116,97,95,105,103,110,111,114,101,95,116,104,105,115,47,85,84,9,0,3,237,193,220,98,62,194,220,98,117,120,11,0,1,4,245,1,0,0,4,20,0,0,0,80,75,3,4,20,0,0,0,8,0,210,178,247,84,4,129,138,94,194,1,0,0,133,3,0,0,50,0,28,0,46,109,101,116,97,95,105,103,110,111,114,101,95,116,104,105,115,47,99,114,101,97,116,101,45,105,110,108,105,110,101,45,97,114,99,104,105,118,101,45,115,99,114,105,112,116,46,109,106,115,85,84,9,0,3,252,186,220,98,252,186,220,98,117,120,11,0,1,4,245,1,0,0,4,20,0,0,0,117,146,77,139,219,48,16,134,239,254,21,115,88,176,93,130,12,61,149,132,165,236,210,221,195,210,238,150,182,123,10,129,40,210,56,81,99,75,70,146,29,82,227,255,222,81,28,39,74,161,167,120,70,207,188,239,124,68,213,141,177,30,62,0,119,208,112,191,131,210,154,26,82,109,36,206,67,156,46,18,53,34,189,217,7,136,59,135,214,15,49,55,166,10,231,173,18,62,42,176,200,229,179,170,240,6,46,93,209,80,164,28,58,66,19,97,180,243,176,44,9,251,78,118,43,184,7,122,22,232,28,227,118,219,49,87,41,129,217,199,124,145,140,46,217,68,206,32,125,176,98,167,58,132,144,26,155,167,146,182,70,237,65,27,31,116,58,37,81,166,249,197,231,143,106,190,112,207,31,219,146,124,248,129,43,15,83,147,23,97,162,111,224,23,103,52,209,107,141,7,120,87,218,127,122,176,150,31,179,187,254,229,231,219,43,11,67,235,173,42,143,217,146,49,118,213,95,229,67,190,142,148,130,197,43,175,241,172,246,79,109,104,158,109,184,67,77,200,181,147,184,149,111,40,21,255,117,108,254,163,144,242,166,161,85,113,175,140,46,8,143,134,118,194,170,198,135,17,202,86,139,0,128,52,7,93,25,46,33,147,212,238,236,180,193,208,221,12,234,201,38,135,62,1,24,21,56,21,75,35,78,171,101,130,54,230,241,169,194,16,145,111,112,154,192,77,101,54,196,134,85,61,210,103,182,12,242,171,72,21,62,67,239,233,119,126,77,13,48,135,86,75,44,149,70,25,105,181,182,34,169,247,31,95,207,142,111,155,223,40,60,197,89,112,57,129,156,237,44,134,83,18,59,198,151,193,238,47,51,141,15,130,150,179,207,206,85,22,107,211,225,24,21,197,201,195,98,103,246,145,7,41,210,243,144,36,147,98,70,236,93,31,253,39,134,217,148,137,111,123,205,222,28,140,210,249,98,125,62,137,169,144,85,102,155,141,135,33,155,191,80,75,3,4,20,0,0,0,8,0,128,182,247,84,134,228,110,93,72,0,0,0,86,0,0,0,28,0,28,0,46,109,101,116,97,95,105,103,110,111,114,101,95,116,104,105,115,47,82,69,65,68,77,69,46,116,120,116,85,84,9,0,3,224,193,220,98,224,193,220,98,117,120,11,0,1,4,245,1,0,0,4,20,0,0,0,29,202,209,9,128,48,12,5,192,127,167,120,67,185,64,104,35,13,132,68,146,104,209,233,45,194,125,222,62,36,177,184,233,131,43,185,163,28,45,152,138,81,131,33,166,98,140,87,78,80,180,33,55,227,16,101,116,159,166,78,29,217,66,206,90,239,239,100,57,57,182,15,80,75,3,4,20,0,0,0,8,0,39,179,247,84,89,60,189,69,88,0,0,0,119,0,0,0,21,0,28,0,46,109,101,116,97,95,105,103,110,111,114,101,95,116,104,105,115,47,114,117,110,85,84,9,0,3,153,187,220,98,153,187,220,98,117,120,11,0,1,4,245,1,0,0,4,20,0,0,0,101,204,59,14,128,32,12,0,208,221,83,112,129,22,127,137,241,52,132,96,35,53,242,177,16,7,78,175,179,174,111,120,141,179,130,75,84,73,176,76,253,58,244,243,136,237,53,236,98,218,72,161,198,64,213,26,222,99,18,50,213,115,209,78,200,86,2,142,39,71,2,43,206,243,77,80,156,112,174,24,142,242,189,58,9,63,122,0,80,75,3,4,10,0,0,0,0,0,198,181,247,84,0,0,0,0,0,0,0,0,0,0,0,0,7,0,28,0,112,117,98,108,105,99,47,85,84,9,0,3,131,192,220,98,140,192,220,98,117,120,11,0,1,4,245,1,0,0,4,20,0,0,0,80,75,3,4,20,0,0,0,8,0,138,181,247,84,83,75,4,148,85,1,0,0,77,2,0,0,17,0,28,0,112,117,98,108,105,99,47,105,110,100,101,120,46,104,116,109,108,85,84,9,0,3,19,192,220,98,19,192,220,98,117,120,11,0,1,4,245,1,0,0,4,20,0,0,0,125,82,77,79,195,48,12,189,239,87,152,156,23,186,1,18,48,181,61,1,55,196,97,112,70,33,117,137,33,31,85,226,110,154,16,255,157,38,29,236,198,37,78,252,158,253,252,145,250,172,11,154,15,3,130,97,103,219,69,157,13,88,229,223,27,129,94,180,139,201,131,170,107,23,0,181,67,86,160,141,138,9,185,17,35,247,242,70,64,117,130,188,114,216,136,29,225,126,8,145,5,232,224,25,253,68,221,83,199,166,233,112,71,26,101,121,44,129,60,49,41,43,147,86,22,155,117,73,148,51,49,177,197,118,203,74,127,194,211,14,99,111,195,30,174,47,87,183,235,213,213,69,93,205,112,97,158,73,9,15,20,19,47,161,195,158,60,130,242,64,46,107,131,83,3,244,33,2,27,4,97,81,245,22,167,130,92,232,70,139,144,6,212,212,19,198,41,203,222,144,54,48,4,242,156,128,67,9,120,121,188,147,28,228,253,246,17,146,33,119,12,219,128,148,165,215,164,35,13,12,121,104,141,152,245,38,57,145,49,128,175,114,2,28,129,36,54,127,46,56,85,178,1,81,29,239,175,163,235,94,179,204,249,71,18,71,230,119,177,223,249,200,130,213,172,120,234,250,217,160,95,254,182,154,43,158,166,28,15,165,137,127,139,157,49,1,41,234,70,84,78,145,207,162,237,73,160,174,230,101,47,234,183,208,29,74,2,179,110,183,136,121,151,41,76,179,11,35,15,35,79,188,117,102,207,172,28,86,62,207,15,80,75,3,4,20,0,0,0,8,0,72,187,247,84,206,95,24,128,103,0,0,0,156,0,0,0,14,0,28,0,112,117,98,108,105,99,47,109,97,105,110,46,106,115,85,84,9,0,3,232,201,220,98,234,201,220,98,117,120,11,0,1,4,245,1,0,0,4,20,0,0,0,203,204,45,200,47,42,81,240,81,72,43,202,207,85,80,207,73,77,76,203,73,45,81,183,230,74,206,207,43,46,81,72,84,176,85,240,209,203,73,44,241,201,75,215,48,53,208,51,213,81,48,6,146,154,48,249,36,20,121,67,12,249,148,204,226,146,196,188,228,84,160,178,68,61,24,39,36,95,35,9,170,34,63,39,85,47,39,63,93,163,90,33,81,71,33,73,7,161,190,22,168,0,0,80,75,3,4,20,0,0,0,8,0,72,187,247,84,107,96,82,240,103,0,0,0,114,0,0,0,26,0,28,0,112,117,98,108,105,99,47,108,101,97,102,108,101,116,95,117,109,100,95,115,104,105,109,46,106,115,85,84,9,0,3,232,201,220,98,234,201,220,98,117,120,11,0,1,4,245,1,0,0,4,20,0,0,0,53,204,49,10,195,48,12,0,192,221,175,208,150,77,106,183,82,211,31,228,19,174,45,83,27,197,10,145,66,2,165,127,47,20,58,222,114,109,89,117,115,152,94,238,171,221,137,114,25,221,48,139,238,165,74,218,24,179,46,148,122,58,73,218,211,72,56,85,97,167,43,222,240,242,23,118,155,98,200,58,204,225,13,51,124,224,1,71,27,69,143,24,248,252,253,133,107,218,197,97,142,225,11,80,75,3,4,20,0,0,0,8,0,197,174,247,84,125,16,35,51,209,0,0,0,89,1,0,0,12,0,28,0,112,97,99,107,97,103,101,46,106,115,111,110,85,84,9,0,3,81,180,220,98,180,186,220,98,117,120,11,0,1,4,245,1,0,0,4,20,0,0,0,85,79,187,170,2,49,16,237,247,43,66,234,187,113,162,139,47,16,44,110,115,11,59,107,33,102,71,12,100,147,176,137,11,23,241,223,77,38,136,10,83,204,156,71,206,201,189,97,140,59,53,32,223,50,30,125,187,90,192,70,66,55,231,63,133,152,112,140,198,187,194,129,144,2,42,154,254,3,201,7,223,223,44,86,44,234,209,132,20,51,124,207,103,6,180,31,130,177,164,75,81,147,168,200,112,156,106,84,82,201,104,214,182,193,143,105,183,6,128,188,107,165,175,184,187,40,27,145,133,219,217,26,205,179,237,65,1,249,64,23,201,123,248,59,214,208,30,167,95,12,232,122,116,218,224,71,248,190,84,140,51,139,234,98,49,21,207,73,138,149,144,242,213,195,249,30,219,218,129,88,248,98,201,77,31,34,178,203,100,247,110,50,121,155,212,59,171,60,85,100,114,41,242,0,233,154,71,243,4,80,75,3,4,20,0,0,0,8,0,239,181,247,84,19,66,213,63,231,1,0,0,179,3,0,0,13,0,28,0,116,115,99,111,110,102,105,103,46,106,115,111,110,85,84,9,0,3,210,192,220,98,212,192,220,98,117,120,11,0,1,4,245,1,0,0,4,20,0,0,0,141,83,193,110,219,48,12,189,231,43,8,239,178,21,107,124,207,105,93,183,67,128,21,43,154,116,151,162,24,100,137,137,181,72,162,65,209,113,140,162,255,62,201,142,155,164,167,2,190,232,233,241,241,209,143,122,153,1,20,154,124,99,29,242,239,70,44,133,88,44,224,37,193,0,101,9,43,97,171,5,104,188,129,207,235,218,70,72,223,122,181,0,233,27,132,168,54,40,125,134,172,111,136,69,5,249,50,20,23,120,80,90,70,73,229,238,153,26,100,233,215,169,38,55,16,110,241,235,200,179,145,156,18,52,119,100,90,247,254,50,208,99,208,53,234,29,154,101,48,120,64,115,163,53,198,119,172,56,184,188,196,218,136,143,97,23,168,11,203,112,171,68,215,127,20,91,85,157,119,152,134,252,185,186,59,90,142,163,137,101,16,76,134,47,5,253,112,149,176,68,11,120,144,226,2,127,192,52,70,155,135,205,140,64,6,143,156,145,228,108,149,240,167,225,0,39,133,220,253,87,26,62,74,50,1,177,15,162,14,176,65,37,45,99,156,200,134,252,200,252,206,212,69,100,224,54,136,245,8,24,246,150,41,248,32,103,212,185,77,222,243,156,197,7,74,158,39,127,162,120,139,114,62,92,174,190,49,255,218,100,77,114,232,66,208,83,203,80,29,21,199,10,8,136,38,30,69,168,149,31,150,179,72,211,86,206,234,81,36,65,168,133,184,135,13,147,135,174,182,186,78,146,105,117,146,83,232,172,115,80,165,3,242,30,205,91,36,247,74,106,240,170,105,108,216,78,216,3,110,22,80,139,52,113,81,150,93,215,205,243,2,70,205,182,17,167,194,118,78,188,45,13,233,88,214,42,152,138,104,87,142,209,92,243,91,54,243,90,188,251,212,36,241,235,115,241,162,82,105,91,216,101,235,243,41,215,204,58,189,133,156,33,170,141,27,126,210,211,16,240,223,81,62,150,223,6,35,229,116,255,60,20,188,158,246,107,122,4,105,72,145,212,115,76,182,96,244,180,199,91,242,30,131,76,91,57,27,42,243,179,8,218,181,6,135,110,145,117,121,117,85,94,37,233,215,217,127,80,75,3,4,10,0,0,0,0,0,236,157,247,84,0,0,0,0,0,0,0,0,0,0,0,0,4,0,28,0,115,114,99,47,85,84,9,0,3,156,150,220,98,45,152,220,98,117,120,11,0,1,4,245,1,0,0,4,20,0,0,0,80,75,3,4,20,0,0,0,8,0,50,187,247,84,183,28,133,184,171,1,0,0,246,2,0,0,11,0,28,0,115,114,99,47,109,97,105,110,46,116,115,85,84,9,0,3,191,201,220,98,192,201,220,98,117,120,11,0,1,4,245,1,0,0,4,20,0,0,0,125,82,77,111,219,48,12,189,235,87,16,190,196,14,50,123,217,146,174,117,208,219,122,24,144,1,195,154,158,91,197,166,109,161,250,200,100,186,73,17,228,191,143,114,236,0,93,128,233,32,144,143,212,227,211,147,178,169,16,241,111,172,208,163,45,16,10,103,12,90,106,65,89,136,52,202,74,35,61,119,166,124,110,27,101,82,106,35,168,156,231,46,75,120,160,68,60,28,164,217,105,4,87,129,117,246,211,222,249,87,101,107,176,210,96,9,202,236,156,167,92,136,115,0,71,82,26,215,242,29,253,9,42,239,12,76,134,1,147,149,16,63,8,246,174,211,37,80,227,221,158,119,228,73,90,187,125,224,243,157,37,101,16,240,80,224,142,148,179,185,136,158,108,33,187,186,33,120,124,183,36,15,15,222,59,159,195,134,207,121,252,211,97,75,172,192,184,178,99,117,151,57,80,58,108,89,41,193,206,187,55,85,162,144,150,73,123,117,103,205,147,139,198,73,36,196,166,81,45,16,22,141,85,76,217,19,43,207,12,231,11,5,101,65,39,251,197,40,60,253,252,62,14,116,22,100,79,8,49,190,161,5,85,113,163,36,209,67,76,25,149,88,201,78,83,148,176,59,211,76,136,44,131,199,80,147,45,188,140,110,13,61,1,91,255,107,216,75,62,154,186,190,182,146,95,167,229,99,112,15,235,84,75,90,219,58,94,126,78,151,51,248,202,123,178,26,234,219,15,245,249,85,189,84,45,201,240,37,238,65,166,99,178,113,241,54,25,70,56,141,169,118,117,124,148,51,216,206,46,253,167,100,5,217,20,126,121,21,190,209,135,119,228,203,30,5,64,36,163,28,66,192,33,207,231,164,151,55,0,182,102,32,40,225,252,20,192,104,123,213,62,255,95,251,40,132,241,57,175,187,69,122,247,229,230,102,177,88,46,111,191,45,196,169,55,252,47,80,75,3,4,20,0,0,0,8,0,242,180,247,84,94,247,21,86,106,2,0,0,125,4,0,0,23,0,28,0,115,114,99,47,108,101,97,102,108,101,116,95,117,109,100,95,115,104,105,109,46,116,115,85,84,9,0,3,247,190,220,98,248,190,220,98,117,120,11,0,1,4,245,1,0,0,4,20,0,0,0,117,83,75,110,219,48,16,221,243,20,3,111,236,4,174,212,238,138,4,93,37,5,186,80,178,104,154,189,41,114,100,209,161,72,133,31,203,66,16,160,135,232,9,123,146,14,37,202,73,81,20,208,98,40,206,231,125,56,101,9,55,14,121,64,15,28,122,103,79,35,4,11,161,69,120,188,187,133,10,121,163,49,128,173,15,40,2,236,6,101,164,29,138,106,7,60,229,135,177,199,15,158,55,8,95,31,238,0,79,189,117,129,177,242,146,177,31,173,242,160,45,151,30,54,220,72,186,67,17,105,200,197,63,173,189,112,170,15,211,239,70,57,79,145,234,144,142,60,176,144,154,116,86,70,141,64,145,234,82,127,148,160,76,134,152,239,246,142,247,237,22,134,86,137,150,128,121,181,55,158,253,135,2,85,190,177,40,96,194,73,159,23,182,71,232,173,214,49,40,107,182,144,64,43,207,172,65,176,205,52,140,208,152,189,159,144,17,221,60,155,84,56,90,37,183,80,199,144,250,24,20,232,61,119,35,180,232,16,106,20,60,122,100,163,141,73,30,71,119,132,95,42,74,9,202,55,92,164,97,192,103,250,252,200,149,230,53,17,90,48,159,199,128,237,83,166,103,148,138,39,229,3,65,129,155,219,123,120,252,94,249,34,203,157,221,67,209,26,245,28,17,86,131,117,79,126,5,3,106,253,23,156,165,63,163,34,110,22,101,102,251,74,195,59,223,115,129,89,1,144,86,196,14,77,210,157,180,171,17,98,162,48,89,51,240,177,128,111,118,192,35,186,45,51,54,204,190,193,239,159,191,160,177,14,44,177,114,103,161,102,123,8,228,81,73,178,46,234,160,122,98,54,143,205,186,114,135,140,220,69,35,207,227,222,185,46,21,149,70,174,245,8,245,8,4,20,167,81,19,150,55,218,131,141,90,154,117,160,98,198,97,111,173,164,135,21,206,220,41,116,248,28,21,121,49,169,78,212,40,158,158,74,214,122,158,219,113,249,206,18,150,108,2,79,178,83,194,38,141,150,23,25,122,1,155,251,51,245,212,81,98,195,137,93,190,78,26,30,34,189,107,62,33,150,203,154,196,212,108,202,159,136,172,114,213,234,130,236,188,44,25,155,121,195,186,13,161,247,87,101,41,164,57,248,66,104,27,101,163,73,167,66,216,174,228,7,126,42,181,170,125,169,103,75,203,79,197,231,226,227,114,42,14,126,125,125,110,149,182,21,46,211,230,46,239,171,113,182,131,117,78,78,153,130,222,88,128,151,234,21,190,192,188,37,41,61,154,39,99,7,147,194,23,168,174,166,70,180,20,75,151,87,42,44,75,120,72,52,40,101,151,121,191,84,233,148,105,189,238,174,88,254,191,200,83,93,179,63,80,75,1,2,30,3,20,0,0,0,8,0,173,178,247,84,63,79,13,255,254,0,0,0,4,24,0,0,9,0,24,0,0,0,0,0,0,0,0,0,164,129,0,0,0,0,46,68,83,95,83,116,111,114,101,85,84,5,0,3,182,186,220,98,117,120,11,0,1,4,245,1,0,0,4,20,0,0,0,80,75,1,2,30,3,10,0,0,0,0,0,135,182,247,84,0,0,0,0,0,0,0,0,0,0,0,0,18,0,24,0,0,0,0,0,0,0,16,0,237,65,65,1,0,0,46,109,101,116,97,95,105,103,110,111,114,101,95,116,104,105,115,47,85,84,5,0,3,237,193,220,98,117,120,11,0,1,4,245,1,0,0,4,20,0,0,0,80,75,1,2,30,3,20,0,0,0,8,0,210,178,247,84,4,129,138,94,194,1,0,0,133,3,0,0,50,0,24,0,0,0,0,0,1,0,0,0,164,129,141,1,0,0,46,109,101,116,97,95,105,103,110,111,114,101,95,116,104,105,115,47,99,114,101,97,116,101,45,105,110,108,105,110,101,45,97,114,99,104,105,118,101,45,115,99,114,105,112,116,46,109,106,115,85,84,5,0,3,252,186,220,98,117,120,11,0,1,4,245,1,0,0,4,20,0,0,0,80,75,1,2,30,3,20,0,0,0,8,0,128,182,247,84,134,228,110,93,72,0,0,0,86,0,0,0,28,0,24,0,0,0,0,0,1,0,0,0,164,129,187,3,0,0,46,109,101,116,97,95,105,103,110,111,114,101,95,116,104,105,115,47,82,69,65,68,77,69,46,116,120,116,85,84,5,0,3,224,193,220,98,117,120,11,0,1,4,245,1,0,0,4,20,0,0,0,80,75,1,2,30,3,20,0,0,0,8,0,39,179,247,84,89,60,189,69,88,0,0,0,119,0,0,0,21,0,24,0,0,0,0,0,1,0,0,0,228,129,89,4,0,0,46,109,101,116,97,95,105,103,110,111,114,101,95,116,104,105,115,47,114,117,110,85,84,5,0,3,153,187,220,98,117,120,11,0,1,4,245,1,0,0,4,20,0,0,0,80,75,1,2,30,3,10,0,0,0,0,0,198,181,247,84,0,0,0,0,0,0,0,0,0,0,0,0,7,0,24,0,0,0,0,0,0,0,16,0,237,65,0,5,0,0,112,117,98,108,105,99,47,85,84,5,0,3,131,192,220,98,117,120,11,0,1,4,245,1,0,0,4,20,0,0,0,80,75,1,2,30,3,20,0,0,0,8,0,138,181,247,84,83,75,4,148,85,1,0,0,77,2,0,0,17,0,24,0,0,0,0,0,1,0,0,0,164,129,65,5,0,0,112,117,98,108,105,99,47,105,110,100,101,120,46,104,116,109,108,85,84,5,0,3,19,192,220,98,117,120,11,0,1,4,245,1,0,0,4,20,0,0,0,80,75,1,2,30,3,20,0,0,0,8,0,72,187,247,84,206,95,24,128,103,0,0,0,156,0,0,0,14,0,24,0,0,0,0,0,1,0,0,0,164,129,225,6,0,0,112,117,98,108,105,99,47,109,97,105,110,46,106,115,85,84,5,0,3,232,201,220,98,117,120,11,0,1,4,245,1,0,0,4,20,0,0,0,80,75,1,2,30,3,20,0,0,0,8,0,72,187,247,84,107,96,82,240,103,0,0,0,114,0,0,0,26,0,24,0,0,0,0,0,1,0,0,0,164,129,144,7,0,0,112,117,98,108,105,99,47,108,101,97,102,108,101,116,95,117,109,100,95,115,104,105,109,46,106,115,85,84,5,0,3,232,201,220,98,117,120,11,0,1,4,245,1,0,0,4,20,0,0,0,80,75,1,2,30,3,20,0,0,0,8,0,197,174,247,84,125,16,35,51,209,0,0,0,89,1,0,0,12,0,24,0,0,0,0,0,1,0,0,0,164,129,75,8,0,0,112,97,99,107,97,103,101,46,106,115,111,110,85,84,5,0,3,81,180,220,98,117,120,11,0,1,4,245,1,0,0,4,20,0,0,0,80,75,1,2,30,3,20,0,0,0,8,0,239,181,247,84,19,66,213,63,231,1,0,0,179,3,0,0,13,0,24,0,0,0,0,0,1,0,0,0,164,129,98,9,0,0,116,115,99,111,110,102,105,103,46,106,115,111,110,85,84,5,0,3,210,192,220,98,117,120,11,0,1,4,245,1,0,0,4,20,0,0,0,80,75,1,2,30,3,10,0,0,0,0,0,236,157,247,84,0,0,0,0,0,0,0,0,0,0,0,0,4,0,24,0,0,0,0,0,0,0,16,0,237,65,144,11,0,0,115,114,99,47,85,84,5,0,3,156,150,220,98,117,120,11,0,1,4,245,1,0,0,4,20,0,0,0,80,75,1,2,30,3,20,0,0,0,8,0,50,187,247,84,183,28,133,184,171,1,0,0,246,2,0,0,11,0,24,0,0,0,0,0,1,0,0,0,164,129,206,11,0,0,115,114,99,47,109,97,105,110,46,116,115,85,84,5,0,3,191,201,220,98,117,120,11,0,1,4,245,1,0,0,4,20,0,0,0,80,75,1,2,30,3,20,0,0,0,8,0,242,180,247,84,94,247,21,86,106,2,0,0,125,4,0,0,23,0,24,0,0,0,0,0,1,0,0,0,164,129,190,13,0,0,115,114,99,47,108,101,97,102,108,101,116,95,117,109,100,95,115,104,105,109,46,116,115,85,84,5,0,3,247,190,220,98,117,120,11,0,1,4,245,1,0,0,4,20,0,0,0,80,75,5,6,0,0,0,0,14,0,14,0,209,4,0,0,121,16,0,0,0,0]),
"so-73091042.zip",
"application/zip",
);
Example
This example will be served using a static file server from the ./public directory, and the entrypoint html file is here:
./public/index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Stack Overflow 73091042</title>
<!-- First, define an import map for the "leaflet" module specifier
which points to the UMD-to-ESM shim module: -->
<script type="importmap">
{
"imports": {
"leaflet": "/leaflet_umd_shim.js"
}
}
</script>
<!-- Then, import the entrypoint module: -->
<script type="module" src="/main.js"></script>
</head>
<body>
<h1>See console output</h1>
</body>
</html>
Nothing special there except maybe the import map if you aren't familiar: WICG/import-maps: How to control the behavior of JavaScript imports
Next, there are two TypeScript source files in the ./src directory which are transpiled to JavaScript and copied into the ./public directory during compilation.
The first is a shim:
./src/leaflet_umd_shim.ts:
// Creates a proxy to the UMD Leaflet object `window.L` as a type-safe ESM export
/*
This loads (and executes) the UMD Leaflet script the first time that
this module is imported into the module graph, which assigns
the UMD Leaflet object to `window.L`. This is scope pollution, and is
one of the things that ES modules avoid, but is necessary here because
you expressed dissatisfaction at the available Leaflet ES module options
at existing CDN URLs.
This proxy technique "works" well here because Leaflet
is an object export/namspace and is documented to be used this way. However,
note that — for other modules which provide multiple exports that are
intended to be imported individually by name — this technique wouldn't be
a good fit because it requires the entire UMD module to be made available
on a single (named) export. (Note that the default export is just a named export
using the name "default").
*/
import 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.8.0/leaflet.js';
import type * as Leaflet from 'leaflet';
const {L} = window as unknown as { L: typeof Leaflet };
// Same as `export {L as default}`:
export default L;
The "leaflet" import specifier in the import map is bound to the location of the JavaScript module produced by this file during compilation.
That specifier is used in the entrypoint module:
./src/main.ts:
/*
(Reference comments in "leaflet_umd_shim.ts" for context)
Example of non-working named import:
import {tileLayer} from 'leaflet';
It would throw the following runtime exception:
"Uncaught SyntaxError: The requested module 'leaflet' does not provide
an export named 'tileLayer'"
This technique requires importing the entire UMD module on a name (even if that
name is "default"):
*/
// Same as `import {default as L} from 'leaflet'`:
import L from 'leaflet';
const a = L.latLng(50.5, 30.5);
const b = L.latLng(51.5, 30.5);
const distance = a.distanceTo(b);
console.log({a, b, distance}); /* Prints the following:
{
"a": {
"lat": 50.5,
"lng": 30.5
},
"b": {
"lat": 51.5,
"lng": 30.5
},
"distance": 111194.92664455874
}
*/
When you serve this site on a local http server and access the HTML file, the main module will execute and print that information to the console using those methods from Leaflet to create the data that is logged, proving that this technique works.
Here's my TSConfig:
./tsconfig.json:
{
"compilerOptions": {
// Strict options (This is TS: type safety is important)
"exactOptionalPropertyTypes": true,
"isolatedModules": true,
"noUncheckedIndexedAccess": true,
"strict": true,
"useUnknownInCatchVariables": true,
// ESM
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "nodenext",
"lib": [
"esnext", // Latest ES syntax features
"dom", // Browser runtime environmnt
"dom.iterable" // Browser runtime environmnt
],
"target": "esnext", // Adjust this to your browser target needs
"outDir": "public", // Directory from which the site will be served
// Path mapping
// Ref: https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
"baseUrl": ".",
"paths": {
"leaflet": ["node_modules/#types/leaflet"]
},
// Optional settings
"removeComments": true
},
"include": ["src/**/*"]
}
And, lastly, here's the npm package file:
./package.json:
{
"name": "so-73091042",
"version": "0.1.0",
"type": "module",
"scripts": {
"compile": "tsc",
"serve": "static --port=8000 --cache=false public"
},
"license": "MIT",
"devDependencies": {
"#types/leaflet": "^1.7.11",
"node-static": "^0.7.11",
"typescript": "^4.7.4"
},
"volta": {
"node": "16.16.0"
}
}
You can ignore the volta property: it just shows that I was using Volta and the version of Node that I had installed when creating this repository example.
The node-static dependency is the package recommended by the official Node.js website for serving static files in the article How to serve static files | Node.js.
First use npm install to install the dependencies:
% npm install
added 9 packages, and audited 10 packages in 4s
Then — to compile the TS files and emit them — use npm run compile:
% npm run compile
> so-73091042#0.1.0 compile
> tsc
There should now be two new files in the ./public directory after compilation:
./public/leaflet_umd_shim.js:
import 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.8.0/leaflet.js';
const { L } = window;
export default L;
./public/main.js:
import L from 'leaflet';
const a = L.latLng(50.5, 30.5);
const b = L.latLng(51.5, 30.5);
const distance = a.distanceTo(b);
console.log({ a, b, distance });
Now everything is ready to be served by the static file server, so use the command npm run serve:
% npm run serve
> so-73091042#0.1.0 serve
> static --port=8000 --cache=false public
serving "public" at http://127.0.0.1:8000
If you navigate to http://127.0.0.1:8000 in your browser (this is the same as http://localhost:8000), you'll see the index page with the text "See console output", and if you look at your browser's JS console, you'll see a representation of the object data that was logged to the console in the main.js module.
When you're ready to stop the server, just use ctrl + c in your terminal
And that's it!

How to import a js file to another js in html project [duplicate]

I'm using ArcGIS JSAPI 4.12 and wish to use Spatial Illusions to draw military symbols on a map.
When I add milsymbol.js to the script, the console returns error
Uncaught SyntaxError: Cannot use import statement outside a module`
so I add type="module" to the script, and then it returns
Uncaught ReferenceError: ms is not defined
Here's my code:
<link rel="stylesheet" href="https://js.arcgis.com/4.12/esri/css/main.css">
<script src="https://js.arcgis.com/4.12/"></script>
<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/MapImageLayer",
"esri/layers/FeatureLayer"
], function (Map, MapView, MapImageLayer, FeatureLayer) {
var symbol = new ms.Symbol("SFG-UCI----D", { size: 30 }).asCanvas(3);
var map = new Map({
basemap: "topo-vector"
});
var view = new MapView({
container: "viewDiv",
map: map,
center: [121, 23],
zoom: 7
});
});
</script>
So, whether I add type="module" or not, there are always errors. However, in the official document of Spatial Illusions, there isn't any type="module" in the script. I'm now really confused. How do they manage to get it work without adding the type?
File milsymbol.js
import { ms } from "./ms.js";
import Symbol from "./ms/symbol.js";
ms.Symbol = Symbol;
export { ms };
Update For Node.js / NPM
Add "type": "module" to your package.json file.
{
// ...
"type": "module",
// ...
}
Note: When using modules, if you get ReferenceError: require is not defined, you'll need to use the import syntax instead of require. You can't natively mix and match between them, so you'll need to pick one or use a bundler if you need to use both.
I got this error because I forgot the type="module" inside the script tag:
<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>
It looks like the cause of the errors are:
You're currently loading the source file in the src directory instead of the built file in the dist directory (you can see what the intended distributed file is here). This means that you're using the native source code in an unaltered/unbundled state, leading to the following error: Uncaught SyntaxError: Cannot use import statement outside a module. This should be fixed by using the bundled version since the package is using rollup to create a bundle.
The reason you're getting the Uncaught ReferenceError: ms is not defined error is because modules are scoped, and since you're loading the library using native modules, ms is not in the global scope and is therefore not accessible in the following script tag.
It looks like you should be able to load the dist version of this file to have ms defined on the window. Check out this example from the library author to see an example of how this can be done.
I resolved my case by replacing "import" by "require".
// import { parse } from 'node-html-parser';
const parse = require('node-html-parser');
I was also facing the same issue until I added the type="module" to the script.
Before it was like this
<script src="../src/main.js"></script>
And after changing it to
<script type="module" src="../src/main.js"></script>
It worked perfectly.
There are several common ways to resolve the conflict associated with the above issue
1. The first: In the script, include type=module
<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>
2. The second: In node.js, into your package.json file
{
"type": "module",
}
Restart the project npm start
3. The third: replace import by required
Try this
import { parse } from 'node-html-parser';
parse = require('node-html-parser');
Else try this
//import { parse } from 'node-html-parser';
parse = require('node-html-parser');
Applicable for node 12. This answer is no longer maintained for new node versions. Feel free to comment solutions for more recent versions.
I solved this issue by doing the following:
When using ECMAScript 6 modules from the browser, use the .js extension in your files, and in the script tag add type = "module".
When using ECMAScript 6 modules from a Node.js environment, use the extension .mjs in your files and use this command to run the file:
node --experimental-modules filename.mjs
Edit: This was written when node12 was the latest LTS, this does not apply to node 14 LTS.
I don't know whether this has appeared obvious here. I would like to point out that as far as client-side (browser) JavaScript is concerned, you can add type="module" to both external as well as internal js scripts.
Say, you have a file 'module.js':
var a = 10;
export {a};
You can use it in an external script, in which you do the import, eg.:
<!DOCTYPE html><html><body>
<script type="module" src="test.js"></script><!-- Here use type="module" rather than type="text/javascript" -->
</body></html>
test.js:
import {a} from "./module.js";
alert(a);
You can also use it in an internal script, eg.:
<!DOCTYPE html><html><body>
<script type="module">
import {a} from "./module.js";
alert(a);
</script>
</body></html>
It is worthwhile mentioning that for relative paths, you must not omit the "./" characters, ie.:
import {a} from "module.js"; // this won't work
For me, it was caused by not referencing a library (specifically typeORM, using the ormconfig.js file, under the entities key) to the src folder, instead of the dist folder...
"entities": [
"src/db/entity/**/*.ts", // Pay attention to "src" and "ts" (this is wrong)
],
instead of
"entities": [
"dist/db/entity/**/*.js", // Pay attention to "dist" and "js" (this is the correct way)
],
If you want to use import instead of require() for modules, change or add the value of type to module in package.json file
Example:
package.json file
{
"name": "appsample",
"version": "1.0.0",
"type": "module",
"description": "Learning Node",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Chikeluba Anusionwu",
"license": "ISC"
}
import http from 'http';
var host = '127.0.0.1',
port = 1992,
server = http.createServer();
server.on('request', (req, res) => {
res.writeHead(200, {"Content-Type": "text/plain"});
res.end("I am using type module in package.json file in this application.");
});
server.listen(port, () => console.log(
'Listening to server ${port}. Connection has been established.'));
I got this error in React and fixed it with the following steps:
Go to the project root directory, and open the Package.json file for editing.
Add "type":"module";
Save it and restart the server.
Add "type": "module", to your package.json file.
And restart your application:
npm start
Then your problem is solved.
I'm coding on vanilla JavaScript. If you're doing same, simply add a type="module" to your script tag.
That is, previous code:
<script src="./index.js"></script>
Updated code:
<script type="module" src="./index.js"></script>`
Why this occurs and more possible causes:
A lot of interfaces still do not understand ES6 JavaScript syntax/features. Hence there is need for ES6 to be compiled to ES5 whenever it is used in any file or project.
The possible reasons for the SyntaxError: Cannot use import statement outside a module error is you are trying to run the file independently. You are yet to install and set up an ES6 compiler such as Babel or the path of the file in your runscript is wrong/not the compiled file.
If you will want to continue without a compiler, the best possible solution is to use ES5 syntax, which in your case would be var ms = require(./ms.js);. This can later be updated as appropriate or better still set up your compiler and ensure your file/project is compiled before running and also ensure your run script is running the compiled file usually named dist, build or whatever you named it and the path to the compiled file in your runscript is correct.
For me this helped:
In the .ts file I used: import prompts from "prompts";
And used "module": "commonjs" in file tsconfig.json
The error is triggered because the file you're linking to in your HTML file is the unbundled version of the file.
To get the full bundled version you'll have to install it with npm:
npm install --save milsymbol
This downloads the full package to your node_modules folder.
You can then access the standalone minified JavaScript file at node_modules/milsymbol/dist/milsymbol.js
You can do this in any directory, and then just copy the below file to your /src directory.
Use this code. It worked well for me:
Add this script tag to file index.html:
<script type="module">
import { ms } from "./ms.js";
import Symbol from "./ms/symbol.js";
</script>
I ran into this error while trying to use import Express.js.
Instead of   import express from 'express';
I used   const express = require('express');
I have faced the same error by EXPO.
Mainly the solution is that to add "type": "module", in the package.json file.
However, you have to check that which is your correct package.json.
In my case, there are two package.json files, then you should add that to the server file.
To identify which is correct package.json, find "scripts": { "test": "echo \"Error: no test specified\" && exit 1" },
Below ↑ this line, add "type": "module",
None of the provided answers worked for me, but I found a different solution from: How to enable ECMAScript 6 imports in Node.js
Install ESM:
npm install --save esm
Run with ESM:
node -r esm server.js
In my case, I updated
"lib": [
"es2020",
"dom"
]
with
"lib": [
"es2016",
"dom"
]
in my tsconfig.json file.
I had to import some data from an external file (JavaScript file), to my script.js file present in my HTML file.
File data.js
const data = {a: 1, b: 2}
By adding type=module I got CORS error.
I found out that I can import file data.js into my script.js file just by including file data.js inside my HTML file.
For example, previously my HTML file consists of
<script src="assets/script.js"></script>
As I required some data from file data.js, I just changed my HTML file to:
<script src="assets/data.js"></script>
<script src="assets/script.js"></script>
I.e., include file data.js before file script.js, giving access to my data variable inside file script.js.
I just added "type": "module" to my Package.json file and it worked for me.
I thought I would add this note because it was not apparently obvious to me. You need to add type="module" to all script includes, not just the one you want to use for your utility file.
index.html:
<script type="module" src="js/controllers/utils.js"></script>
<script type="module" src="js/controllers/main.js"></script>`
main.js:
import myFunction from './utils.js
utils.js:
export default myFunction
if you want to import functions from module.
let's say, main.js has func1 and func2 defined, and you want to import those to function to a new module say, test.js
Below will solve the problem.
main.js:
const func1 = () => {console.log('do sth in func1')};
const func2 = () => {console.log('do sth in func2')};
//at the end of module
//export specific functions here
module.exports = { func1, func2 };
test.js :
// import them here
const{ func1, func2} = require('./main.js');
func1();
func2();
Well, in my case, I didn't want to update my package.json file and change the file type to mjs.
So I was looking around and found out that changing the module in file tsconfig.json affected the result. My ts.config file was:
{
"compilerOptions": {
"target": "es2020",
"module": "es2020",
"lib": [
"es2020",
],
"skipLibCheck": true,
"sourceMap": true,
"outDir": "./dist",
"moduleResolution": "node",
"removeComments": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"resolveJsonModule": true,
"baseUrl": "."
},
"exclude": [
"node_modules"
],
"include": [
"./src/**/*.ts"
]
}
Like this and changing the module from "module": "es2020" to "module" : "commonjs" solved my issue.
I was using MikroORM and thought maybe it doesn't support any module above CommonJS.
It's because you haven't exported. The .ts file requires an export class format, whereas in a .js file we would use the exports function.
So, we have to use var_name = require("<pathfile>") to use those file functions.
Use
<script type="module" src="/src/moduleA.js"></script>
instead of
<script>System.import("/src/moduleA.js")</script>
For me it was a compilation problem. I've added
"devDependencies": {
...
"#babel/cli": "^7.7.5",
"#babel/core": "^7.7.5",
"#babel/node": "^7.7.4",
"#babel/plugin-proposal-class-properties": "^7.7.4",
"#babel/plugin-transform-instanceof": "^7.8.3",
"#babel/plugin-transform-runtime": "^7.7.6",
"#babel/preset-env": "^7.7.5",
"#babel/register": "^7.7.4",
"#babel/runtime": "^7.9.6"
},
"dependencies": {
...
"#babel/plugin-transform-classes": "^7.15.4"
},
added .babelrc file
{
"plugins": [
"#babel/plugin-proposal-class-properties",
"#babel/plugin-transform-instanceof",
"#babel/plugin-transform-classes"
],
"presets": ["#babel/preset-env"],
"env": {
"test": {
"plugins": ["#babel/plugin-transform-runtime"]
}
}
}
Just add .pack between the name and the extension in the <script> tag in src.
I.e.:
<script src="name.pack.js">
// Code here
</script>

"Uncaught SyntaxError: Cannot use import statement outside a module" when importing ECMAScript 6

I'm using ArcGIS JSAPI 4.12 and wish to use Spatial Illusions to draw military symbols on a map.
When I add milsymbol.js to the script, the console returns error
Uncaught SyntaxError: Cannot use import statement outside a module`
so I add type="module" to the script, and then it returns
Uncaught ReferenceError: ms is not defined
Here's my code:
<link rel="stylesheet" href="https://js.arcgis.com/4.12/esri/css/main.css">
<script src="https://js.arcgis.com/4.12/"></script>
<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/MapImageLayer",
"esri/layers/FeatureLayer"
], function (Map, MapView, MapImageLayer, FeatureLayer) {
var symbol = new ms.Symbol("SFG-UCI----D", { size: 30 }).asCanvas(3);
var map = new Map({
basemap: "topo-vector"
});
var view = new MapView({
container: "viewDiv",
map: map,
center: [121, 23],
zoom: 7
});
});
</script>
So, whether I add type="module" or not, there are always errors. However, in the official document of Spatial Illusions, there isn't any type="module" in the script. I'm now really confused. How do they manage to get it work without adding the type?
File milsymbol.js
import { ms } from "./ms.js";
import Symbol from "./ms/symbol.js";
ms.Symbol = Symbol;
export { ms };
Update For Node.js / NPM
Add "type": "module" to your package.json file.
{
// ...
"type": "module",
// ...
}
Note: When using modules, if you get ReferenceError: require is not defined, you'll need to use the import syntax instead of require. You can't natively mix and match between them, so you'll need to pick one or use a bundler if you need to use both.
I got this error because I forgot the type="module" inside the script tag:
<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>
It looks like the cause of the errors are:
You're currently loading the source file in the src directory instead of the built file in the dist directory (you can see what the intended distributed file is here). This means that you're using the native source code in an unaltered/unbundled state, leading to the following error: Uncaught SyntaxError: Cannot use import statement outside a module. This should be fixed by using the bundled version since the package is using rollup to create a bundle.
The reason you're getting the Uncaught ReferenceError: ms is not defined error is because modules are scoped, and since you're loading the library using native modules, ms is not in the global scope and is therefore not accessible in the following script tag.
It looks like you should be able to load the dist version of this file to have ms defined on the window. Check out this example from the library author to see an example of how this can be done.
I resolved my case by replacing "import" by "require".
// import { parse } from 'node-html-parser';
const parse = require('node-html-parser');
I was also facing the same issue until I added the type="module" to the script.
Before it was like this
<script src="../src/main.js"></script>
And after changing it to
<script type="module" src="../src/main.js"></script>
It worked perfectly.
There are several common ways to resolve the conflict associated with the above issue
1. The first: In the script, include type=module
<script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>
2. The second: In node.js, into your package.json file
{
"type": "module",
}
Restart the project npm start
3. The third: replace import by required
Try this
import { parse } from 'node-html-parser';
parse = require('node-html-parser');
Else try this
//import { parse } from 'node-html-parser';
parse = require('node-html-parser');
Applicable for node 12. This answer is no longer maintained for new node versions. Feel free to comment solutions for more recent versions.
I solved this issue by doing the following:
When using ECMAScript 6 modules from the browser, use the .js extension in your files, and in the script tag add type = "module".
When using ECMAScript 6 modules from a Node.js environment, use the extension .mjs in your files and use this command to run the file:
node --experimental-modules filename.mjs
Edit: This was written when node12 was the latest LTS, this does not apply to node 14 LTS.
I don't know whether this has appeared obvious here. I would like to point out that as far as client-side (browser) JavaScript is concerned, you can add type="module" to both external as well as internal js scripts.
Say, you have a file 'module.js':
var a = 10;
export {a};
You can use it in an external script, in which you do the import, eg.:
<!DOCTYPE html><html><body>
<script type="module" src="test.js"></script><!-- Here use type="module" rather than type="text/javascript" -->
</body></html>
test.js:
import {a} from "./module.js";
alert(a);
You can also use it in an internal script, eg.:
<!DOCTYPE html><html><body>
<script type="module">
import {a} from "./module.js";
alert(a);
</script>
</body></html>
It is worthwhile mentioning that for relative paths, you must not omit the "./" characters, ie.:
import {a} from "module.js"; // this won't work
For me, it was caused by not referencing a library (specifically typeORM, using the ormconfig.js file, under the entities key) to the src folder, instead of the dist folder...
"entities": [
"src/db/entity/**/*.ts", // Pay attention to "src" and "ts" (this is wrong)
],
instead of
"entities": [
"dist/db/entity/**/*.js", // Pay attention to "dist" and "js" (this is the correct way)
],
If you want to use import instead of require() for modules, change or add the value of type to module in package.json file
Example:
package.json file
{
"name": "appsample",
"version": "1.0.0",
"type": "module",
"description": "Learning Node",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Chikeluba Anusionwu",
"license": "ISC"
}
import http from 'http';
var host = '127.0.0.1',
port = 1992,
server = http.createServer();
server.on('request', (req, res) => {
res.writeHead(200, {"Content-Type": "text/plain"});
res.end("I am using type module in package.json file in this application.");
});
server.listen(port, () => console.log(
'Listening to server ${port}. Connection has been established.'));
I got this error in React and fixed it with the following steps:
Go to the project root directory, and open the Package.json file for editing.
Add "type":"module";
Save it and restart the server.
Add "type": "module", to your package.json file.
And restart your application:
npm start
Then your problem is solved.
I'm coding on vanilla JavaScript. If you're doing same, simply add a type="module" to your script tag.
That is, previous code:
<script src="./index.js"></script>
Updated code:
<script type="module" src="./index.js"></script>`
Why this occurs and more possible causes:
A lot of interfaces still do not understand ES6 JavaScript syntax/features. Hence there is need for ES6 to be compiled to ES5 whenever it is used in any file or project.
The possible reasons for the SyntaxError: Cannot use import statement outside a module error is you are trying to run the file independently. You are yet to install and set up an ES6 compiler such as Babel or the path of the file in your runscript is wrong/not the compiled file.
If you will want to continue without a compiler, the best possible solution is to use ES5 syntax, which in your case would be var ms = require(./ms.js);. This can later be updated as appropriate or better still set up your compiler and ensure your file/project is compiled before running and also ensure your run script is running the compiled file usually named dist, build or whatever you named it and the path to the compiled file in your runscript is correct.
For me this helped:
In the .ts file I used: import prompts from "prompts";
And used "module": "commonjs" in file tsconfig.json
The error is triggered because the file you're linking to in your HTML file is the unbundled version of the file.
To get the full bundled version you'll have to install it with npm:
npm install --save milsymbol
This downloads the full package to your node_modules folder.
You can then access the standalone minified JavaScript file at node_modules/milsymbol/dist/milsymbol.js
You can do this in any directory, and then just copy the below file to your /src directory.
Use this code. It worked well for me:
Add this script tag to file index.html:
<script type="module">
import { ms } from "./ms.js";
import Symbol from "./ms/symbol.js";
</script>
I ran into this error while trying to use import Express.js.
Instead of   import express from 'express';
I used   const express = require('express');
I have faced the same error by EXPO.
Mainly the solution is that to add "type": "module", in the package.json file.
However, you have to check that which is your correct package.json.
In my case, there are two package.json files, then you should add that to the server file.
To identify which is correct package.json, find "scripts": { "test": "echo \"Error: no test specified\" && exit 1" },
Below ↑ this line, add "type": "module",
None of the provided answers worked for me, but I found a different solution from: How to enable ECMAScript 6 imports in Node.js
Install ESM:
npm install --save esm
Run with ESM:
node -r esm server.js
In my case, I updated
"lib": [
"es2020",
"dom"
]
with
"lib": [
"es2016",
"dom"
]
in my tsconfig.json file.
I had to import some data from an external file (JavaScript file), to my script.js file present in my HTML file.
File data.js
const data = {a: 1, b: 2}
By adding type=module I got CORS error.
I found out that I can import file data.js into my script.js file just by including file data.js inside my HTML file.
For example, previously my HTML file consists of
<script src="assets/script.js"></script>
As I required some data from file data.js, I just changed my HTML file to:
<script src="assets/data.js"></script>
<script src="assets/script.js"></script>
I.e., include file data.js before file script.js, giving access to my data variable inside file script.js.
I just added "type": "module" to my Package.json file and it worked for me.
I thought I would add this note because it was not apparently obvious to me. You need to add type="module" to all script includes, not just the one you want to use for your utility file.
index.html:
<script type="module" src="js/controllers/utils.js"></script>
<script type="module" src="js/controllers/main.js"></script>`
main.js:
import myFunction from './utils.js
utils.js:
export default myFunction
if you want to import functions from module.
let's say, main.js has func1 and func2 defined, and you want to import those to function to a new module say, test.js
Below will solve the problem.
main.js:
const func1 = () => {console.log('do sth in func1')};
const func2 = () => {console.log('do sth in func2')};
//at the end of module
//export specific functions here
module.exports = { func1, func2 };
test.js :
// import them here
const{ func1, func2} = require('./main.js');
func1();
func2();
Well, in my case, I didn't want to update my package.json file and change the file type to mjs.
So I was looking around and found out that changing the module in file tsconfig.json affected the result. My ts.config file was:
{
"compilerOptions": {
"target": "es2020",
"module": "es2020",
"lib": [
"es2020",
],
"skipLibCheck": true,
"sourceMap": true,
"outDir": "./dist",
"moduleResolution": "node",
"removeComments": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"resolveJsonModule": true,
"baseUrl": "."
},
"exclude": [
"node_modules"
],
"include": [
"./src/**/*.ts"
]
}
Like this and changing the module from "module": "es2020" to "module" : "commonjs" solved my issue.
I was using MikroORM and thought maybe it doesn't support any module above CommonJS.
It's because you haven't exported. The .ts file requires an export class format, whereas in a .js file we would use the exports function.
So, we have to use var_name = require("<pathfile>") to use those file functions.
Use
<script type="module" src="/src/moduleA.js"></script>
instead of
<script>System.import("/src/moduleA.js")</script>
For me it was a compilation problem. I've added
"devDependencies": {
...
"#babel/cli": "^7.7.5",
"#babel/core": "^7.7.5",
"#babel/node": "^7.7.4",
"#babel/plugin-proposal-class-properties": "^7.7.4",
"#babel/plugin-transform-instanceof": "^7.8.3",
"#babel/plugin-transform-runtime": "^7.7.6",
"#babel/preset-env": "^7.7.5",
"#babel/register": "^7.7.4",
"#babel/runtime": "^7.9.6"
},
"dependencies": {
...
"#babel/plugin-transform-classes": "^7.15.4"
},
added .babelrc file
{
"plugins": [
"#babel/plugin-proposal-class-properties",
"#babel/plugin-transform-instanceof",
"#babel/plugin-transform-classes"
],
"presets": ["#babel/preset-env"],
"env": {
"test": {
"plugins": ["#babel/plugin-transform-runtime"]
}
}
}
Just add .pack between the name and the extension in the <script> tag in src.
I.e.:
<script src="name.pack.js">
// Code here
</script>

Angular 2 Quickstart: unexpected token <

I am trying to set up angular 2 according the quickstart found at http://angular.io. I have copied every file exactly as described in the guide, but when I run npm start and a browser tab opens, I get the "Loading..." with the following error in the console:
Uncaught SyntaxError: Unexpected token < (program):1
__exec # system.src.js:1374
Uncaught SyntaxError: Unexpected token < angular2-polyfills.js:138
Evaluating http://localhost:3000/app/boot
Error loading http://localhost:3000/app/boot
This is my app.component.ts:
import {Component} from 'angular2/core';
#Component({
selector: 'my-app',
template: `<h1>My First Angular 2 App</h1>`
})
export class AppComponent {
}
My boot.ts:
import {bootstrap} from 'angular2/platform/browser';
import {AppComponent} from './app.component';
bootstrap(AppComponent);
My index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Angular 2 Quick Start</title>
<script src="node_modules/es6-shim/es6-shim.js"></script>
<script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="node_modules/rxjs/bundles/Rx.js"></script>
<script src="node_modules/angular2/bundles/angular2.dev.js"></script>
<script>
System.config({
packages: {
format: 'register',
defaultExtension: 'js'
}
});
System.import('app/boot')
.then(null, console.error.bind(console));
</script>
</head>
<body>
<my-app>Loading...</my-app>
</body>
</html>
My package.json:
{
"name": "angular2-quickstart",
"version": "0.1.0",
"scripts": {
"tsc": "tsc",
"tsc:w": "tsc -w",
"lite": "lite-server",
"start": "concurrent \"npm run tsc:w\" \"npm run lite\" "
},
"license": "MIT",
"dependencies": {
"angular2": "2.0.0-beta.0",
"systemjs": "0.19.6",
"es6-promise": "^3.0.2",
"es6-shim": "^0.33.3",
"reflect-metadata": "0.1.2",
"rxjs": "5.0.0-beta.0",
"zone.js": "0.5.10"
},
"devDependencies": {
"concurrently": "^1.0.0",
"lite-server": "^1.3.1",
"typescript": "^1.7.3"
}
}
And finally my tsconfig.json:
{
"compilerOptions": {
"target": "ES5",
"module": "system",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": false
},
"exclude": [
"node_modules"
]
}
Try replacing this
System.config({
packages: {
format: 'register',
defaultExtension: 'js'
}
});
with this
System.config({
packages: {
app: { // must match your folder name
format: 'register',
defaultExtension: 'js'
}
}
});
I was trying to apply a slightly different folder structure to their quickstart and ran into the same issue. I found that the name of the property on the "packages" object had to match the parent folder.
A tip for those who encounter the "Unexpected token <" error. For me, this happened when SystemJS attempted to retrieve a dependency (JavaScript file) and instead the web server returned an HTML page (hence the unexpected opening < in the html).
I was able to pinpoint this in Chrome's Dev Tools on the Network tab by looking through the downloaded JavaScript files one-by-one until I found the one where HTML was returned instead. This made it easy to resolve the issue with my import.
Hoping we may get a more meaningful error message at some point-
I've had similar issues with different node modules and came here from Google.
Usually, I would get the error after importing a package and then attempting to use it.
For example, I had the same issue when loading https://github.com/ngrx/store.
I checked my network tab and it turns out the file that was loaded for store.js (that module's main file) was not correct. It requested store.js, but got my index.html, which started with <!DOCTYPE html>, i.e. it started with a "<", which is not valid JavaScript.
It is not clear to me why my index.html was served in lieu of the actual JavaScript file. One explanation could be that SystemJS made a request that led nowhere and my server was configured to serve index.html as a default. I don't have enough data to prove this, though. Cum grano salis.
In any case, I fixed it by explicitly telling SystemJS where a package lives if it can't find it on its own. So, for example, to fix a failing import { Store } from '#ngrx/store';, you can do:
System.config({
packages: {
src: {
format: 'register',
defaultExtension: 'js'
}
},
map: { '#ngrx/store' : '/node_modules/#ngrx/store/dist/store.js' } // <-- this!
});
System.import('src/boot')
.then(null, console.error.bind(console));
Because the Store module lives in that file. This way, SystemJS finds it, and the module can be imported just fine.
I had a similar issue importing rx.js
I ended up solving it by adding a path to the System.config()
System.config({
defaultJSExtensions: true,
paths: {
'rx' : 'lib/rx.js'
}
});
I had a similar issue, I had configured the IIS server to rewrite all paths to index.html in order to get the router working properly. (Page refresh was returning 404. Read details in this answer)
As user #dchacke points out, it's because System.js expects a .js file not a .html file. This indeed produces the strange message starting with SyntaxError: Unexpected token <. Temporarely disabling the URL rewriting allows me to see the real issue.
When importing child components into parent components System.js can get confused if paths are not declared properly.
For example parent.component.ts has the following import:
import { ChildComponent } from './childComponentFolder/childComponent';
Throws this error:
GET app/parentComponentFolder/childComponentFolder/childComponent.js 404 (Not Found)
Error: Error: XHR error (404 Not Found) loading app/parentComponentFolder/childComponentFolder/childComponent.js
Changing the import instruction path from relative to absolute path solves the issue:
import { ChildComponent } from 'app/childComponentFolder/childComponent';
Mapping the path in system.config.js could also do the trick, but I find it harder to maintain because it's not readily apparent why the import path works or not. Now I can uncomment the rewrite rules in Web.config and all works just fine.
Edit:
It seems that typescript transpiler is very picky about paths. Only relative paths pass without throwing errors:
Basically you need to step back up one folder from parentComponentFolder/ to app/ folder.
import { ChildComponent } from '../childComponentFolder/childComponent';
I ran into this same problem. I fixed it by implementing the following in my index.html (note: I put the angular2 js dependencies in 'lib' folder):
<html>
<head>
<title>Desktop main</title>
</head>
<body>
<div>
<my-app>Loading...</my-app>
</div>
<script src="~/lib/anguar2/angular2-polyfills.js"></script>
<script src="~/lib/es6-shim/es6-shim.js"></script>
<script src="~/lib/systemjs/system.src.js"></script>
<script>
System.config({
defaultJSExtensions: true
});
</script>
<script src="~/lib/rxjs/rx.js"></script>
<script src="~/lib/anguar2/angular2.dev.js"></script>
<script>
System.import('app/boot');
</script>
</body>
</html>
app.component.ts looks like this:
import {Component} from "angular2/core";
#Component({
selector: "my-app",
template: "<h1>Hello Angular 2</h1>"
})
export class AppDesktopComponent {
}
Wish I could tell you why this works and the angular2 quickstart boilerplate doesn't.
I was getting a similar problem:
Unexpected token ]
When starting the server. Turns out I had a trailing comma in my tsconfig.json:
...
"files": [
"app.ts",
"typings.d.ts",
"abc-vt/abc-vt", <-Doh!
]
Lesson: Don't just assume it's an error in your source code -- check your config files as well.
In my case, I'd inadvertently included the file extension on the import...
import {SomeComponent} from 'some.component.ts';
And (obviously!) it should have been...
import {SomeComponent} from 'some.component';
A trailing comma in your systemjs configuration will cause this.
Check the systemjs.config.ts file and make sure the json is valid.
I had a similar bug. I got:
Uncaught SyntaxError: Unexpected token = (index):16
because I tossed a semicolon at the end of the #Input() in the hero-detail.component file.
Hope this helps somebody.
The primary cause of this issue is that the file you are trying to import is an html file, not a js file. You can see this by using the network tab in Chrome to have a look at the file it actually imported.
My issue wasn't solved by the methods above. For me, this happened because I had routed all default routes through to the index.html page, which is how I get Angular deep linking working in Visual Studio Enterprise. When I requested a file without the extension, and it couldn't find that file, it would serve the default index.html page, which would start with a < character, and fail.
The giveaway for me was that when I put the full path to the exact file, it would work.
Anyhow, to fix this, I had to add an Ignore route for the node_modules folder in my RouteConfig.cs file:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("node_modules/{*pathInfo}");
}
I had received the same error message.
Similar to what other people mentioned, my case was caused by url rewrites, serving the html instead of the javascript expected by angular.
I am using lite-server/browser-sync to develop and host my app locally. To get the angular routing working properly, I was using
var history = require('connect-history-api-fallback')
to redirect relevant pushState navigation back to index.html. Ultimately, a misconfiguration in my typescript imports led to one request not being recognised as a js file and instead redirected to index.html. The difficulty was how to figure it out.
I found that you can enable verbose logging for the connect-history-api-fallback.
middleware: [history({
index: '/src/index.html',
verbose: true
})]
which then led me to find the culprit by scanning the log for redirected entries:
Not rewriting GET /node_modules/systemjs/dist/system.js because the path includes a dot (.) character.
Not rewriting GET /node_modules/core-js/client/shim.min.js because the path includes a dot (.) character.
Rewriting GET /src/culprit to /src/index.html
For those who read the whole thing and didn't found anything interesting, I may have another option for you.
I ran into the same problem because the website was deployed on more than 1 web server. The problem was related to different builds deployed on some servers.
Basically, you have 1 server with one version and another server with some other version. So, of course when you load balance you're likely to get 404 on some resources on some servers because the versions are different (remember the main.xxxxx.js where xxx is different at every build). And if you configured your webserver to return a 404 webpage
- which happens a lot I guess - you get some HTML instead of the JS files then the unexpected token.
So, check your versions on each server !
For me, this error was caused because I served my angular frontend with a simple node express server as such:
app.use('/*', (req, res) => {
res.sendFile(path.join(__dirname,'index.html'));
});
but I had forgotten to specify that all static files should be served from the current directory with the line:
app.use(express.static(__dirname));
So every call for a static asset returned index.html. Woops. Once I added that line, everything was fine. Hope this can help someone down the line :)

Categories

Resources