TypeScript cannot find namespace - javascript

I am trying to create a web game using webGL, TypeScript and node.
I have a file structure that currently looks like this
> node_modules
> src
engine.ts
webgl.ts
index.ts
index.html
package.json
engine.ts looks like this:
namespace EngineSpace {
export class Engine {
// ....
}
}
and webgl.js:
namespace EngineSpace {
export class WebGLUtil {
// ....
}
}
and index.js
window.onload = function() {
let engine = new EngineSpace.Engine();
engine.start();
}
However when I run npm start, I get that src/index.ts:5:22 - error TS2304: Cannot find name 'EngineSpace'..
I am not sure why it cannot resolve this namespace. Given that I am trying to create a game, how should I have this set up / what would be best practices?
below is the package.json: file
{
"name": "typescript-engine",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"start": "npm run build:live",
"build": "tsc -p .",
"build:live": "nodemon --watch 'src/**/*.ts' --exec 'ts-node' src/index.ts"
},
"repository": {
"type": "git",
"url": ""
},
"keywords": [],
"author": "",
"license": "ISC",
"bugs": {
"url": ""
},
"homepage": "",
"devDependencies": {
"#types/node": "^12.11.1",
"nodemon": "^1.19.4",
"ts-node": "^8.4.1",
"typescript": "^3.6.4"
}
}
here is the tsconfig:
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"lib": ["es6","dom"],
"outDir": "lib",
"rootDir": "src",
"strict": false,
"esModuleInterop": true,
"resolveJsonModule": true
}
}

If you want to use namespace in nodejs side you need to export it also to use it in another module. Becuase namespace will be converted like this
engine.ts
namespace EngineSpace {
export class Engine {
public start() {
console.log('hello');
}
}
}
enigne.js
var EngineSpace;
(function (EngineSpace) {
class Engine {
start() {
console.log('hello');
}
}
EngineSpace.Engine = Engine;
})(EngineSpace || (EngineSpace = {}));
And if you want to use some property of another module in nodejs you need to export it and need to require it in another module.
Refer this for nodejs namespace
For the browser setup with typescript please refer this
Hope it helps you

Related

How do I utilize this javascript library in node.js?

I'm relatively new to node.js and am attempting to utilize a javascript library without any success.
The library itself is psn-api.
To set up for usage I have:
Installed node.js locally
Created my project folder
Ran npm init and successfully created package.json
Ran npm install i -s psn-api which has successfully installed psn-api to my project folder in node-modules and updated the dependencies in package.json.
I've copied the sample code from the psn-api github (see below) and saved as index.ts file in my project folder.
I run npx tsc --init which generates my tsconfig.json file
I run npx tsc index.ts which compiles into index.js
I run node index.js
Sample code (index.ts):
import * as fs from "fs";
import type { Trophy } from "psn-api";
import {
exchangeCodeForAccessToken,
exchangeNpssoForCode,
getTitleTrophies,
getUserTitles,
getUserTrophiesEarnedForTitle,
makeUniversalSearch,
TrophyRarity
} from "psn-api";
async function main() {
// 1. Authenticate and become authorized with PSN.
// See the Authenticating Manually docs for how to get your NPSSO.
const npsso = "xxxxxxxx";
const accessCode = await exchangeNpssoForCode(npsso);
const authorization = await exchangeCodeForAccessToken(accessCode);
// 2. Get the user's `accountId` from the username.
const allAccountsSearchResults = await makeUniversalSearch(
authorization,
"xelnia",
"SocialAllAccounts"
);
const targetAccountId =
allAccountsSearchResults.domainResponses[0].results[0].socialMetadata
.accountId;
// 3. Get the user's list of titles (games).
const { trophyTitles } = await getUserTitles(authorization, targetAccountId);
const games: any[] = [];
for (const title of trophyTitles) {
// 4. Get the list of trophies for each of the user's titles.
const { trophies: titleTrophies } = await getTitleTrophies(
authorization,
title.npCommunicationId,
"all",
{
npServiceName:
title.trophyTitlePlatform !== "PS5" ? "trophy" : undefined
}
);
// 5. Get the list of _earned_ trophies for each of the user's titles.
const { trophies: earnedTrophies } = await getUserTrophiesEarnedForTitle(
authorization,
targetAccountId,
title.npCommunicationId,
"all",
{
npServiceName:
title.trophyTitlePlatform !== "PS5" ? "trophy" : undefined
}
);
// 6. Merge the two trophy lists.
const mergedTrophies = mergeTrophyLists(titleTrophies, earnedTrophies);
games.push({
gameName: title.trophyTitleName,
platform: title.trophyTitlePlatform,
trophyTypeCounts: title.definedTrophies,
earnedCounts: title.earnedTrophies,
trophyList: mergedTrophies
});
}
// 7. Write to a JSON file.
fs.writeFileSync("./games.json", JSON.stringify(games));
}
const mergeTrophyLists = (
titleTrophies: Trophy[],
earnedTrophies: Trophy[]
) => {
const mergedTrophies: any[] = [];
for (const earnedTrophy of earnedTrophies) {
const foundTitleTrophy = titleTrophies.find(
(t) => t.trophyId === earnedTrophy.trophyId
);
mergedTrophies.push(
normalizeTrophy({ ...earnedTrophy, ...foundTitleTrophy })
);
}
return mergedTrophies;
};
const normalizeTrophy = (trophy: Trophy) => {
return {
isEarned: trophy.earned ?? false,
earnedOn: trophy.earned ? trophy.earnedDateTime : "unearned",
type: trophy.trophyType,
rarity: rarityMap[trophy.trophyRare ?? 0],
earnedRate: Number(trophy.trophyEarnedRate),
trophyName: trophy.trophyName,
groupId: trophy.trophyGroupId
};
};
const rarityMap: Record<TrophyRarity, string> = {
[TrophyRarity.VeryRare]: "Very Rare",
[TrophyRarity.UltraRare]: "Ultra Rare",
[TrophyRarity.Rare]: "Rare",
[TrophyRarity.Common]: "Common"
};
I've run around in circles with possible fixes such as adding "type":"module" to the package.json, trying to import or otherwise define psn-api in my js file but I keep hitting error after error. I'm sure there's some fundamental misunderstanding I have. I'd really appreciate if someone could outline the direct steps I need to take to get the sample script running in the cmd line.
My package.json as it stands:
{
"name": "psnapitest",
"version": "1.0.0",
"description": "",
"main": "index3.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"#types/node": "^18.6.2",
"psn-api": "^2.7.0"
},
"type": "module",
"devDependencies": {
"#tsconfig/node16": "^1.0.3",
"typescript": "^4.7.4"
}
}
My tsconfig.json as it stands (after advice in comments):
{
"compilerOptions": {
"target": "es2016",
"module": "es6",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true
}
}
Current error when running compiled js:
Now compiles with no issues.
I run node index.js and get the following error
exports.__esModule = true;
^
ReferenceError: exports is not defined in ES module scope
I tried this locally and no error
when using node library you need to set "moduleResolution": "node" on your tsconfig.json
index.ts
import fs from 'fs'
package.json
{
"name": "psn-api-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "tsc index.ts",
"start": "node index.js"
},
"type": "module",
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"psn-api": "^2.7.0"
},
"devDependencies": {
"#types/node": "^18.6.2",
"typescript": "^4.7.4"
}
}
tsconfig.json
{
"compilerOptions": {
"target": "es2016",
"module": "es6",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true
}
}
Try instead of using import, use require:
const fs = require('fs')
const psn = require('psn-api')
type { Trophy } = psn
const { exchangeCodeForAccessToken } = psn
const { exchangeNpssoForCode } = psn
const { getTitleTrophies } = psn
const { getUserTitles } = psn
const { getUserTrophiesEarnedForTitle } = psn
const { makeUniversalSearch } = psn
const { TrophyRarity } = psn
Also, instead of compiling it to node.js, try using this library:
https://www.npmjs.com/package/ts-node
Its basicly node.js but for typescript

How to conditional exports from package.json

I have section exports in my package.json:
"exports": {
"import": "./dist/a.es.js",
"require": "./dist/b.umd.js"
},
But for development, I would like to have different path:
"exports": {
"DEV": {
"import": "./src/a.es.js", // <---------- SRC
"require": "./src/b.umd.js" , // <---------- SRC
},
"PROD": {
"import": "./dist/a.es.js",
"require": "./dist/b.umd.js"
}
},
Is there any way how to use some env variable?
I was able to solve this using this setup
In the package that my program imports:
{
"name": "my-special-node-package",
"version": "1.0.0",
"license": "MIT",
"exports": {
".": {
"production": {
"require": "./prod/index.cjs.js",
"import": "./prod/index.esm.js"
},
"default": {
"require": "./index.cjs.js",
"import": "./index.esm.js"
}
},
}
}
And then in my program:
// index.js
const myPkg = require('my-special-node-package')
On production I use node --conditions=production index.js to execute the node program. Otherwise I use node index.js in dev mode.
Also, since I'm using TypeScript and since TypeScript is only really used during development time, I was able to change the default require/import values to point to a index.ts file.
{
// ....
"exports": {
".": {
"production": {
"require": "./dist/index.cjs.js",
"import": "./dist/index.esm.js"
},
"default": "./index.ts"
},
}
}
This setup allows for my local development to always TS files directly and not rely on each package to be built whenever it changes.

Property 'noise' does not exist on type 'typeof #types/p5/index"'

I was humming along in a TypeScript Data Viz project and thought I'd use the p5.js noise function to save some time. Instead I've encountered a problem that I can't fully understand. There seems to be something different with the p5 module compared to d3 and three.js I'm using in the project. Breaking it down to the very basic elements, I need some help interpreting what's going on with this module.
import * as p5 from "p5"
p5.noise()
// Returns the error:
// Property 'noise' does not exist on type 'typeof import("/Users/.../ts-node-server/node_modules/#types/p5/index.d.ts")'. ts(2339)
If I try to use the function directly I get a different error.
import { noise } from "p5"
// Returns the error:
// Module '"p5"' has no exported member 'noise'.ts(2305)
I dug down into the node_modules and confirmed everything is there. Researching the problem, I noticed other packages had this same error, but all the offered solutions were very specific to the package and project, and when applied did not fit my issue or resolve my problem. I suspect this has something to do with global.d.ts file but nothing looked out of place when I looked. If there are any suggestions on what is happening I will take them.
//Package.json
{
"name": "ts-node-server",
"version": "1.0.0",
"description": "project",
"main": "build/server.js",
"scripts": {
"compile": "tsc && node build/server.js",
"dev": "./node_modules/nodemon/bin/nodemon.js -e ts --exec \"npm run compile\""
},
"author": "..",
"license": "ISC",
"dependencies": {
"d3": "^6.6.2",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"p5": "^1.3.1",
"three": "^0.127.0"
},
"devDependencies": {
"#types/d3": "^6.3.0",
"#types/three": "^0.127.1",
"#types/express": "^4.17.11",
"#types/node": "^14.14.37",
"#types/p5": "^0.9.1",
"nodemon": "^2.0.7"
}
}
//tsconfig.json
{
"compilerOptions": {
"outDir": "./build",
"rootDir": "./src",
"module": "commonjs",
"moduleResolution": "node",
"noEmit": false,
"esModuleInterop": true,
"strict": true,
"target": "ES6"
},
"include": ["src/**/*"],
"exclude": ["**/node_modules", "**/config", "**/build", "**/*.md"]
}
If you must run p5.js functions in a Node.js application written in typescript, here's one way to do it:
Add npm dependencies: p5, window, canvas
Add npm devDependencies: #types/p5
Inject certain JSDOM window properties into the global scope: window, document, screen, navigator
Note: This works for the noise function, but I have no idea what the behavior of any functions that actually attempt to create or draw to a canvas would be.
Here's a working example in Repl.it.
Here's my package.json:
{
"name": "p5js-test",
"version": "1.0.0",
"description": "Test p5.js Node.js app.",
"scripts": {
"p5js-test": "ts-node --files src/main.ts",
"compile": "tsc"
},
"bin": {
"p5js-test": "./build/src/main.js"
},
"author": "Paul Wheeler",
"license": "MIT",
"dependencies": {
"canvas": "^2.7.0",
"p5": "^1.3.1",
"window": "^4.2.7"
},
"devDependencies": {
"#types/node": "^15.0.1",
"#types/p5": "^0.9.1",
"ts-node": "^9.1.1",
"typescript": "^4.2.4"
}
}
And here's my main.ts:
import Window from 'window';
// globals expected to exist by p5js (must come before the import)
// Note: doing this may not be entirely kosher according to the JSDOM documentation
// but it gets p5.js working
(<any> global).window = new Window();
(<any> global).document = global.window.document;
(<any> global).screen = global.window.screen;
(<any> global).navigator = global.window.navigator;
import p5 from 'p5';
const inst = new p5(p => {
// I'm not totally sure this is actually needed
p.setup = function() { };
});
console.log('using noise from instance: ' + inst.noise(1, 2, 3));

cant import module from webpack bundle.js in script tag HTML

I use webpack for make bundler my js file for use in my django project. I use moment js which i get from "npm i moment". I make webpack with this configuration.
var path = require('path');
module.exports = {
"mode" : "development",
"entry" : "./index.js",
"output" : {
"path" : path.resolve(__dirname, "tugas/assets"),
"filename" : "bundles.js",
"clean" : true,
},
};
and this is my index.js for configuration before.
import moment from 'moment';
console.log(moment().format('MMMM Do YYYY, h:mm:ss a'));
console.log("boma1");
This is my package.json.
{
"name": "Aplikasi-Database-Django",
"version": "1.0.0",
"description": "Tugas UAS Database Semester 7 2020",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --config webpack.config.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/simasona123/Aplikasi-Database-Django.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/simasona123/Aplikasi-Database-Django/issues"
},
"homepage": "https://github.com/simasona123/Aplikasi-Database-Django#readme",
"devDependencies": {
"webpack": "^5.31.2",
"webpack-cli": "^4.6.0"
},
"dependencies": {
"chart.js": "^3.1.0",
"moment": "^2.29.1"
}
}
as i know, webpack success to make bundle of moment.js because console can make output
but from above picture i cant import moment.js
this is my html code
This is my tree directory.
Thanks for your help... sorry for my bad question....
You should use require for moment.js, so replace what you have for the import with:
const moment = require('moment');
Alternatively, if you want to still use the import statement, this should work as well:
import * as moment from 'moment';
There's a discussion of this already here.

How could I refer typings to be included at runtime?

my question (in details) might have duplicates here but I couldn't be able to get answeres since I have spent 3 days searching for it.
I am new to typescript and want to run a TS project (and not any angular 2 thing in it) using 'npm start' command. Please have a look at below code:
My directory structure is:
myClass.ts (it is inside module directory)
export namespace Classes {
export class NewClass {
constructor(public msg:string){}
displayMessage ():string{
return this.msg;
}
};
};
greeter.html
<!DOCTYPE html>
<html>
<head><title> TypeScript Greeter </title></head>
<body>
<script src='greeter.js'></script>
</body>
</html>
greeter.ts
import {Classes} from 'module/myClass';
class Greeter extends Classes.NewClass {
constructor(public greeting: string) {
super('');
}
greet() {
return "<h1>" + this.greeting + "</h1>";
}
};
var greeter = new Greeter("Hello, world!");
var newClass = new Classes.NewClass("This is my message.");
document.body.innerHTML = greeter.greet() + newClass.displayMessage();
package.json
{
"name": "greeter",
"version": "1.0.0",
"description": "Sample TS app",
"main": "greeter.ts",
"scripts": {
"start": "tsc && http-server"
},
"keywords": [
"TS"
],
"author": "",
"license": "MIT",
"dependencies": {
}
}
tsconfig.json
{
"compilerOptions": {
"baseUrl": "./",
"sourceMap": true,
"module": "commonjs",
"outDir": "./out"
},
"files": [
"greeter.ts",
"module/myClass.ts"
]
}
typings.json
{
"globalDependencies": {
"node": "registry:dt/node#6.0.0+20160928143418"
}
}
My queries are:
I have included 'dt~node' typings after watching a few tutorials, but is it necessary here in this scenario ?
I am from javascript background, so I am not sure how to include the typings files in my project. Do I need to include reference path in greeter.html for typings files or something else. Please specify this.
I am unable to make it work as browser console displays this error after running 'npm start' in window's command:
Please help if anyone could guide me to resolve my queries. Thank you.

Categories

Resources