TypeScript: Unexpected reserved word - node.js

I have a project in WebStorm IDE & Node.js. I created a file named "mongo-manager.ts" which I used in the routes\index.js file. It worked seamlessly.
Then I did 2 things:
WebStorm had always asked me whether or not to compile TypeScript to JavaScript and I had always ignored it, but then once I clicked on "yes" and since then after solving some errors it's compiling now ts files successfully to js.
I converted index.js into index.ts and now I still have index.js which is an output of the compilation.
Ever since then, when I try to run my app (using the triangular green button in WebStorm which in turn uses the command line: "C:\Program Files (x86)\JetBrains\WebStorm 11.0.1\bin\runnerw.exe" "C:\Program Files\nodejs\node.exe" bin\www), I get this error:
import mongodb = require('mongodb');
^^^^^^
SyntaxError: Unexpected reserved word
Now, there's no specific problem with the "import" statement because if I omit it, the next non JavaScript statement throws the same exception. It just tries to treat TypeScript like it was JavaScript.
I've found these questions:
Typescript: unexpected reserved word in PHPStorm,
Unable to import in typescript file in nodejs
They suggest either to use "tsc" rather than node.exe, or to make sure that I run with node.exe the js file rather than the ts file.
Now the thing is that the file that node.exe runs directly is "www" which is a JavaScript file and in turn calls app.js which is still JavaScript, but later the files index.ts and mongo-manager.ts are called, so I have a hybrid of both js and ts.
And another and most important thing is that my code has already worked seamlessly even though it's hybrid and without taking any of the suggestions in these questions, until I answered WebStorm "yes" to the question whether to compile TypeScript to JavaScript, which had always appeared.
Anyway, I only want my app working again, no matter how.
Any help will be profoundly appreciated!

You need to know differences between compilation error and runtime error. It seems that what you've experiencing is a runtime error. Please check out the JavaScript file being executed by Node.js.
Currently Node.js does not yet support ES6 module syntax, you need to have your module field in tsconfig.json to be commonjs. Ideally in your output JavaScript file, import mongodb = require('mongodb'); should be emitted as const mongodb = require('mongodb'); when targeting ES6 or var mongodb = require('mongodb'); when targeting ES5.

Related

Webpack + TS: Can't make Node.js happy with 'module' or 'commonjs' type

This is my first time setting up Webpack manually, and Typescript is in the mix.
The project builds successfully, but when running the build with yarn start there's the following error:
Error [ERR_REQUIRE_ESM]: require() of ES Module C:\Users\karlo\Projects\reports_server\node_modules\openai\dist\index.js from C:\Users\karlo\Projects\reports_server\dist\server.js not supported.
The error is thrown by this line module.exports = require("openai"); in the output server file. The original .ts files use ES6 imports, but it seems TS or Webpack automatically convert these to CommonJS. Pressing on, let's follow the advice seen online for this error:
Modify package.json to include "type": "module"
Oh boy. Now the following error pops up:
ReferenceError: require is not defined in ES module scope, you can use import instead
That's being thrown by this line: module.exports = require("apollo-server");
The same syntax as the line causing the previous error, and actually just above it in the code.
I'm feeling quite stuck in the middle and kicking myself for not using boilerplate... but at the same time really want to understand where things have gone wrong. If you feel you might know and need more info, please say so.
UPDATE
If anyone has an issue with the openai module in the future, switching to openai-api immediately fixed things. Why exactly openai breaks so spectacularly is still unknown, so this question remains open.

require() resolution in React Native

I'm trying to find out why require('foo/bar.png') works differently in two RN projects
In one project, foo is registered as root via metro.config.js
extraNodeModules: {
foo: path.join(__dirname, 'src/foo'),
}
In another project, foo lives in under app_root/node_modules
so foo is at app_root/node_modules/foo
So in both projects, I can do import something from 'foo/something'
But when it comes to require, two projects behave differently..
There is a line in foo/components/hello.js
require('foo/assets/image.png')
In the first project, the image file is correctly found,
But second project complains that it can't find with an error /path/to/root_project/node_modules/foo/component/node_modules/foo/assets/image.png
It seems as if require is assuming that where the require is called should be the project root or something.
Where should I look for or how do I debug this?
Can I print module.paths in ReactNative project ?
is path is same for both project ? If in first project require() works then it should be work on second project, one reason for not working that your path is not correct in second project. Therefore check it again.
Require is not a React statement - it is Node.js statement, use import instead.

how are #types, typescript and webpack related

To use an exported type in .ts file one has to add import it
import {jQuery} from 'jQuery'
Now when I use this I do not get intellisense, I still need to do npm install #types\jQuery to get that.
So without #types, above statement just infers that during typescript bundling include this file.
Now if I install #types then without adding any other code, I do start getting intellisense.
So is it like above statement is dual purpose.
During bundling using typescript/webpack, it tells to bundle these files as dependency and during compilation, it tells to include .d.ts rather than actual code file?
Why this question: I am trying to move angular1 to typescript and I can use angular.whatever in .ts file even without importing it? Not getting why this is happening. It should give me error asking me to import angular
Not sure I get your question 100% but I can try to explain a bit. The javascript runtime won't have a static check, it is just during the compilation time. If you tell typescript that your variable/function/etc. is of type 'any' then it will just allow you to do anything with it. Eventually the generated code is the same, whether it is checked or not. If you don't have corresponding variable during runtime, you will get an error. Typings are used to just "teach" ts compiler about the actual types of variable for static compilation.
So during compilation no .d.ts is included anywhere, this is just for static type check.
As to why you can access angular, I suppose it is because of d.ts contains the definition and by using #types/angular you let ts compiler know about it.
Check here. The .d.ts files includes global variable angular, that's why you can use it without importing I think.
P.S. Not sure 100%, but seems like it is this line:
declare var angular: angular.IAngularStatic;
You can try deleting this line and see if you get your error :)

How to use babel runtime with large nodejs/express app

I want to use babel runtime in a big/complex nodejs app. I don't want to use the babel require hook because the app is big and when I have tried to use it I get the following error:
RangeError: Maximum call stack size exceeded
And I only want to transpile a few JS files, at least for now.
The babel docs are a bit cryptic for the runtime support. After installing babel-runtime, they provide:
require("babel").transform("code", { optional: ["runtime"] });
Where does that code get included? And is "code" truly just a string? I have tried to add that to my main app.js file (express 3 app). Unfortunately, that doesn't work.
I cannot totally understand your questions, but I think I can answer part of it.
As explained in the babel api, transform() function takes a string that is supposed to be source code to be transpiled, and returns an object including three properties:
code the code generated
map the source map for the code
ast the syntax tree
This means, if you want to transpile your code in a folder, for each file you want to transpile, you should read the file with fs utility, give it to transform() function, and write the value of the code property in the object returned, to your output folder.
To simplify the step to read files, you could use the function transformFile provided by babel.
As for the problem you mention with your express app, I cannot help, unless you provide more information.

require 'coffee-script/register' - unexpected string

I'm using coffee-script 1.7.1 (or I want to use it). Can't make it work, though.
first line of my server.coffee file is require 'coffee-script/register' and I get the oh-so familiar error SyntaxError: Unexpected string. On version 1.6.3 all was well.
In a different project I've successfully used coffee 1.7.1 when the starting file was server.js, but don't want to do it here.
Has anyone made this work? Preferably without making some sort of weird workarounds.
I'm using coffescript 1.7.1 and require 'coffee-script/register' with server.coffee.
Not sure if this applies to your situation, but I spent many hours on a similar error before I realized that I was launching my app from the wrong instance. For example, /usr/bin/coffee instead of /usr/local/bin/coffee.
which coffee gave me the correct path.
I think that you only will need to require coffee-script/register when you are writing JS and want to load a coffeescript file.

Resources