This question already has answers here:
Node.js - SyntaxError: Unexpected token import
(16 answers)
Closed 3 years ago.
I'm experimenting with ECMAScript modules in Node.js 12 but I'm struggling with. Following the official docs just by adding the top-level field "type" with a value of "module" it should be enough to keep using the extension .js in this Node.js version but I can not find why is not working as expected. Am I missing something?
$ node --version
v12.14.1
$ cat package.json
{
"type": "module",
"scripts": {
"start": "node test.js"
}
}
$ npm start
> app# start /usr/src/app
> node test.js
/usr/src/app/test.js:1
import { myFunction } from './module.js';
^^^^^^
SyntaxError: Cannot use import statement outside a module
at Module._compile (internal/modules/cjs/loader.js:891:18)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10)
at Module.load (internal/modules/cjs/loader.js:811:32)
at Function.Module._load (internal/modules/cjs/loader.js:723:14)
at Function.Module.runMain (internal/modules/cjs/loader.js:1043:10)
at internal/main/run_main_module.js:17:11
$ cat test.js
import { myFunction } from './module.js';
myFunction();
$ cat module.js
function myFunction() {
console.log('hello from module');
}
export { myFunction };
https://nodejs.org/docs/latest-v12.x/api/esm.html#esm_code_import_code_statements
Version 12 docs for that import statement show that you can only import the default export via import ... from ...
So import myFunction from './module.js'; would work if you exported myFunction as export default myFunction;
Related
I have a folder structure as following
src
--/lib
----/errors
------/notFound.ts
in notFound.ts, I'm exporting this class
export abstract class HttpError extends Error {
abstract statusCode: number;
constructor(message: string) {
super(message);
Object.setPrototypeOf(this, HttpError.prototype);
}
abstract serializeErrors(): { message: string; field?: string }[];
}
export class NotFoundError extends HttpError {
statusCode = 404;
constructor() {
super('Route not found');
Object.setPrototypeOf(this, NotFoundError.prototype);
}
serializeErrors() {
return [{ message: 'The requested route is not Found' }];
}
}
Then in TSconfig.json, I have the path parameter set like this
"paths": {
"#/lib/*" : [
"src/lib/*"
],
"#/routes/*": [
"src/routes/*"
],
"*": [
"node_modules/*"
]
},
When i Import NotFoundError as follows, it results in error
import { NotFoundError } from '#/lib/errors/notFound';
Here's the error.
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:889:15)
at Function.Module._load (internal/modules/cjs/loader.js:745:27)
at Module.require (internal/modules/cjs/loader.js:961:19)
at require (internal/modules/cjs/helpers.js:92:18)
at Object.<anonymous> (/home/tuser/Projects/tpro/src/server/express.ts:5:1)
at Module._compile (internal/modules/cjs/loader.js:1072:14)
at Module._compile (/home/tuser/Projects/tpro/node_modules/source-map-support/source-map-support.js:568:25)
at Module.m._compile (/tmp/ts-node-dev-hook-07042914060113459.js:69:33)
at Module._extensions..js (internal/modules/cjs/loader.js:1101:10)
at require.extensions..jsx.require.extensions..js (/tmp/ts-node-dev-hook-07042914060113459.js:114:20)
[ERROR] 16:40:04 Error: Cannot find module '#/lib/errors/notFound'
I have also tried imports like these
const { NotFoundError } = require('#/lib/errors/notFound')
const NotFoundError = require('#/lib/errors/notFound')
Both result in same error
What am i missing ?
Sorry, I initially wanted to post a comment but I don't have enough rep; instead, I've expanded what I know into a full answer in hopes it helps.
I've recently gone about with setting up Node + TypeScript + Express. The repo I made and was playing around with initially is here, but note that it's undocumented and the auxiliary configs aren't necessarily up to scratch. Also, apologies if the formatting of this answer is really unorthodox, and I hope linking to personal repos is not looked down on.
I'm uncertain if the paths in the tsconfig.json have anything to do with your issue; I've never used them, so I don't know. I would remove them for now.
As a preface, this is an imperfect solution.
For my Node/TypeScript/Express setup I had to do the following:
Set "type": "module" in package.json
Install required packages: > npm install ts-node ts-loader (I'm unsure if both are necessary, I believe they are though)
Add node --es-module-specifier-resolution=node --loader ts-node/esm ./src/server/express.ts (Presuming that express.ts is your entrypoint) as a command to your package.json and check if it works.
With what I understand, this works by specifically invoking ts-node with esm support, and it seems to work on Node 14 LTS and v16.9.1.
The command is rather hacky and will give you warnings about it being an experimental feature. I couldn't find any other solution for myself when (very stubbornly) using ESModules.
I've also used this command to use Webpack with TypeScript and ESM (that is, having a webpack.ts file with ESM imports) to compile TypeScript src files with ESM, as below (in package.json, from here):
"webpack-examples": "node --es-module-specifier-resolution=node --loader ts-node/esm node_modules/webpack-cli/bin/cli.js --config webpack.examples.ts --mode production",
expressjs doesnt support import statements yet. use require for eg const http = require("http");
When exporting a function with more than 1 parameter (2 or more) it throws the following error, which basically says there is an issue with the way we import curry.js. I am attaching an example and package versions below.
Error:
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: path/to/node_modules/rescript/lib/es6/curry.js
require() of ES modules is not supported.
require() of /path/to/node_modules/rescript/lib/es6/curry.js from /path/to/src/demo.gen.ts is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename curry.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /path/to/node_modules/rescript/lib/es6/package.json.
at new NodeError (node:internal/errors:329:5)
at Module._extensions..js (node:internal/modules/cjs/loader:1109:13)
at Object.require.extensions.<computed> [as .js] (/path/to/node_modules/ts-node/src/index.ts:851:44)
at Module.load (node:internal/modules/cjs/loader:972:32)
at Function.Module._load (node:internal/modules/cjs/loader:813:14)
at Module.require (node:internal/modules/cjs/loader:996:19)
at require (node:internal/modules/cjs/helpers:92:18)
at Object.<anonymous> (/path/to/src/demo.gen.ts:6:1)
at Module._compile (node:internal/modules/cjs/loader:1092:14)
at Module.m._compile (/path/to/node_modules/ts-node/src/index.ts:858:23)
Example
demo.res
#genType
let helloWord = (firstName: string, lastName: string): unit => {
Js.log("Hello " ++ firstName ++ " " ++ lastName)
}
demo.bs.js
// Generated by ReScript, PLEASE EDIT WITH CARE
'use strict';
function helloWord(firstName, lastName) {
console.log("Hello " + firstName + " " + lastName);
}
exports.helloWord = helloWord;
/* No side effect */
demo.gen.ts
/* TypeScript file generated from demo.res by genType. */
/* eslint-disable import/first */
// #ts-ignore: Implicit any on import
import * as Curry__Es6Import from 'rescript/lib/es6/curry.js';
const Curry: any = Curry__Es6Import;
// #ts-ignore: Implicit any on import
import * as demoBS__Es6Import from './demo.bs';
const demoBS: any = demoBS__Es6Import;
export const helloWord: (firstName:string, lastName:string) => void = function (Arg1: any, Arg2: any) {
const result = Curry._2(demoBS.helloWord, Arg1, Arg2);
return result
};
package.json
{
"ts-node": "^10.2.1",
"gentype": "^4.1.0",
"rescript": "^9.1.4",
"typescript": "^3.9.6"
}
Node Version
$ node -v
v15.11.0
OS
Manjaro Linux
After taking a look at this file in genType: https://github.com/rescript-association/genType/blob/fb6201266558a64d62441f7ac0d8d6652456397a/src/Config_.ml
I found this option
{
"gentypeconfig": {
"module": "commonjs",
}
}
setting that solves the issue :D
I could not found it anywhere else in rescript docs unfortunately :(
I use Nuxt, and sometimes, when I want to use some npm packages, I have this error:
SyntaxError
Unexpected token '<'
The stack:
vm.js:102:7
new Script
internal/modules/cjs/loader.js:1114:10
Module._extensions..js
internal/modules/cjs/loader.js:950:32
Module.load
internal/modules/cjs/loader.js:790:14
Module._load
internal/modules/cjs/loader.js:974:19
Module.require
webpack:/external "vue-typeahead-bootstrap":1:
Object.vue-typeahead-bootstrap
webpack/bootstrap:25:
__webpack_require__
pages/account/tabs/addresses.js:693:81
Module../node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./components/address/form/country.vue?vue&type=script&lang=js&
webpack/bootstrap:25:
I have this error for example on this package: vue-typeahead-bootstrap
If I import the package:
import VueTypeaheadBootstrap from ['vue-typeahead-bootstrap'](https://github.com/mattzollinhofer/vue-typeahead-bootstrap)
export default {
components: { VueTypeaheadBootstrap },
}
It throws the error.
Is it because the package is not supported or something ?
You may try to transpile it. https://nuxtjs.org/docs/2.x/configuration-glossary/configuration-build#transpile
Add the package name like this
{
build: {
transpile: [
({ isServer }) => 'vue-typeahead-bootstrap'
]
}
}
As answered here: https://github.com/mattzollinhofer/vue-typeahead-bootstrap/issues/19#issuecomment-645510809
Using svelte-kit generator for the first time today generated a package.json with a "type": "module" in it.
Now I wanna call a postbuild script with:
"scripts": {
"postbuild": "node ./postbuild/index.js",
}
which contains:
const { tailwindExtractor } = require("tailwindcss/lib/lib/purgeUnusedStyles");
...
Because of the new error require is not defined I changed the ./postbuild/index.js file to this:
import { tailwindExtractor } from "tailwindcss/lib/lib/purgeUnusedStyles";
...
but I'm still getting an error calling that file from node:
internal/process/esm_loader.js:74
internalBinding('errors').triggerUncaughtException(
^
Error [ERR_MODULE_NOT_FOUND]: Cannot find module 'C:\kit\node_modules\tailwindcss\lib\lib\purgeUnusedStyles' imported from C:\kit\tools\postbuild\index.js
Did you mean to import tailwindcss/lib/lib/purgeUnusedStyles.js?
at finalizeResolution (internal/modules/esm/resolve.js:276:11)
at moduleResolve (internal/modules/esm/resolve.js:699:10)
at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:810:11)
at Loader.resolve (internal/modules/esm/loader.js:86:40)
at Loader.getModuleJob (internal/modules/esm/loader.js:230:28)
at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:56:40)
at link (internal/modules/esm/module_job.js:55:36) {
code: 'ERR_MODULE_NOT_FOUND'
}
What the heck is going on?
I'm using npm 7.8.0 and node v14.16.0.
I tried also with --experimental-modules: I get the same error!
This is the file I need to import: https://github.com/tailwindlabs/tailwindcss/blob/master/src/lib/purgeUnusedStyles.js
I am trying to import a Typescript class from one of my Node packages and I am getting the following error:
module.js:549
throw err;
^
Error: Cannot find module '#sap/api'
at Function.Module._resolveFilename (module.js:547:15)
at Function.Module._load (module.js:474:25)
In this file:
import { Plugin } from "#sap/api";
new Plugin();
Which imports from this index.ts file:
export { Plugin } from "./src/plugin";
Which refers to "src/plugin.ts":
export class Plugin {
constructor() {}
onLoad() {}
onUnload() {}
onReload() {}
}
When I shift click on the import in VSCode it takes me to the correct file.
What am I doing wrong? I am new to Typescript, so sorry if it is a nooby mistake.