How to use the file on the backend and frontend at the same time? - node.js

I am using nodejs server.
I have a file with a class in which the functionality is written.
The functionality of this class is the same for the backend and for the frontend.
I do not want to create two files with the same functionality.
A file with a class has dependencies - other classes in other files.
How to connect files on the backend and frontend?
What should the classes look like for this?
nodejs back-end app.js:
let player = new Player();
player.goTo(10,20);
front-end index.js:
let player = new Player();
player.goTo(10,20);
It's files need include to frontend and backend:
Player.js:
Class Player
{
goTo(x,y){
Path.pathFinding()
}
}
Path.js:
Class Path
{
pathFinding(){
//doing something
}
}

You are going to want to put this .js file in the folder from where you are hosting static files to serve to the frontend. Whether this be /public or /views or whatever name you called this folder. And in the file next to your class you type in the keyword export: export class {...}. I'm sure you have already done this but no assumptions. Then in your server file simply import it into your server file like this:
import myClass from "/public/js/myjsfile.js";
Example:
public/js/dog.js:
export class dog {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
server.js:
import dog from "/public/js/dog.js";
The dependencies that are used in dog.js or the client side file will come along with it when you import the file on the backend.

Related

How to export Javascript class which can be shared by NodeJS and ES6?

I have an Electron app integrated with Flask server. The app has both HTML loaded by Flask server (flask-page.html ES6) and Electron renderer (render-page.html NodeJS).
I want to share a class defined in a file for Flask and Renderer to avoid duplicated code, as class is exactly the same, but with different export/import.
Now, it's defined in 2 files as followings:
sharedclass-nodejs.js
class sharedClass {
sameMethod() {
}
}
module.exports = {sharedClass}
sharedclass-es6.js
export class sharedClass {
sameMethod() {
}
}
load-flask.js
import {sharedClass} from "sharedclass-es6.js"
flask-page.html (Flask server)
<script type="module" src="sharedclass-es6.js"></script>
<script type="module" src="load-flask.js"></script>
load-render.js
const {sharedClass} = require("sharedclass-nodejs.js")
render-page.html (Electron render UI)
<script src="sharedclass-nodejs.js"></script>
Is it possible to define 1 copy of "class sharedClass" in 1 file, such as NodeJS style export, and use it in ES6?

How to declare variable of type Express in TypeScript without importing express?

I have main file called main.ts where I imported express with
import express from 'express';
Then I have another class in separate file where I want to create method "init" which has one parameter named "app" of type Express. But somehow i can't say app:Express without importing express.
My goal is to import express only once and keep it in a main.ts file, and then in a main.ts file I will call "init" method ( from a separate file) where I will pass that imported express.
Main.ts file
import express from 'express';
import { FriendsRouter } from './routes/friends.router';
const app = express();
FriendsRouter.init(app);
const PORT:number = 3000;
app.listen(PORT,()=>{
console.log('Listening at '+PORT);
})
Spearete file (friends router in my case)
export class FriendsRouter {
private constructor(){
}
public static init(app:Express): void{
app.get('/friends',someMethod);
}
}
Problem is, in FriendsRouter file, I can't say app: Express.
How can I fix this ?
The usual thing is to import the type Express from the express package:
import { Express } from "express";
Note that that's just importing the type, not the function. The rest of your code is then fine as-is (including the type on app).
If you don't have that type, install the types for express like this:
npm install --save-dev #types/express
...but you've probably already done that.

TypeORM Connection "default" was not found when using a routes file and repository pattern

I have a TS project where I'm using TypeORM. I'm using Repository pattern so I have layers: Controller -> Service -> Repository.
The Controller constructor initialize the Service class which initialize Repository class, where the constructor is:
constructor(){
this.ormRepository = getRepository(TypeormEntity)
}
This works fine when I create the routes in the index.ts like this:
createConnection().then(() => {
const controller = new MyController()
app.get('/', controller.getSomething);
})
The connection is created and then I initialize the class using new MyController().
The problem is when I want to get the routes in another file. I want to get this structure folder:
src
|--> index.ts
|--> routes
|--> v1
|--> router.ts
|--> value
|--> value.route.ts
|--> v2
|--> ...
So, to achieve this, the index.ts import the routes. But the problem is, as the import is done, the MyController() constructor is executed and the execution fails.
So I want to have something like this in index.ts
import * as express from 'express'
import { createConnection } from "typeorm";
import Router from './routes/v1/router'
const app = express()
createConnection().then(() => {
app.use('/', Router)
app.listen(port)
})
Also, following the import call, the file router.ts in routes/v1 is:
import { json, Router } from 'express'
import valueRouter from './value/value.route'
const router = Router()
router.use(json())
router.use('/value', valueRouter)
export default router
This is to add a "prefix" to all routes depending the resource they call.
And value.route.ts is where the controller is initialized and fails.
import { Router } from "express";
import ValueController from '../../../controller/value.controller'
const router = Router()
const vc = new ValueController()
router.get('/',vc.getSomething)
export default router
I've tested deleting the constructor and the project intializes ok, so the problem is the repository initialization accross Controller & Service.
How can I achieve this?
Thanks in advance.
Finally I solved my own issue using dynamic imports.
Now my index.ts looks like this:
createConnection().then(() => {
import('./routes/v1/router').then((router: any) => {
app.use('/', router.default)
app.listen(port)
})
})
Which I think is much cleaner than having all routes added in this file. Calling routes in an external file I can manage a huge amount and maintain a clean structure.

Set "basedir" option for Pug in NestJS

I'm trying to use pug layouts in NestJS, however when extending a layout from an absolute path, pug requires the basedir option to be set.
In ExpressJS you would use app.locals.basedir = ..., what would be the equivalent in NestJS?
const server = await NestFactory.create<NestExpressApplication>(AppModule);
server.setViewEngine('pug');
server.setBaseViewsDir(join(__dirname, 'templates', 'views'));
await server.listen(config.server.port);
Using extends /layouts/index in a view would throw the following; the "basedir" option is required to use includes and extends with "absolute" paths.
I'm not looking to use relative paths, since this quickly becomes very messy. E.g. extends ../../../layouts/index
From what I can tell, you can achieve the same functionality as /layouts/index with just using layout/index so long as layout is a folder in your templates/views directory.
I've set up a git repo as a working example so you can test it out yourself and see if I need to go in more depth about anything.
EDIT 6/27/2019:
Thank you, I misunderstood your initial question.
With creating and express based application, you can send an express server to the NestFactory to use that server instance instead of having Nest create a plain instance for you. From here you can set up the express server as you normally would and get the desired functionality. I've modified the git repo to be able to test the scenario better and believe this is what you are looking for.
My main.ts
import { NestFactory } from '#nestjs/core';
import { NestExpressApplication, ExpressAdapter } from '#nestjs/platform-express';
import * as express from 'express';
import { AppModule } from './app.module';
import { join } from 'path';
async function bootstrap() {
// Creating and setting up the express instanced server
const server = express();
server.locals.basedir = join(__dirname, '..', 'views');
// Using the express server instance in the nest factory
const app = await NestFactory.create<NestExpressApplication>(AppModule, new ExpressAdapter(server));
app.useStaticAssets(join(__dirname, '..', 'public'));
app.setBaseViewsDir(join(__dirname, '..', 'views'));
app.setViewEngine('pug');
await app.listen(3000);
}
bootstrap();
Overall the folder set up is like so
src
|-app.controller.ts
|-app.module.ts
|-app.service.ts
|-main.ts
views
|-hello
|-home.pug
|-message
|-message.pug
|-templates
|-layout.pug
And the beginning of my home.pug and message.pug files is extends /templates/layout
After looking around through the documentation, NestJS uses an express under the hood, and gives you access to the underlying instance with getHttpAdapter().getInstance().
Keeping that in mind, we can set the basedir as follows;
const express = server.getHttpAdapter().getInstance();
express.locals.basedir = join(__dirname, 'templates');

Including Custom Modules in Node Express

I'm new to Node/Express and I'm not entirely sure where things go...
I want to have a little custom class - where do I put this custom code in my express app? I seem to have to put it inside "node_modules" for it to be picked up by require which isn't really what I want. Ideally I'd like to have it in a lib folder or the likes.
How can I do this?
Let's say you had a Person class like this in lib/person:
var Person = function (firstName) {
this.firstName = firstName;
};
You can export this using node's module.exports like this (in lib/person):
module.exports = Person;
To use the person class you would then do:
var Person = require('./lib/person');
var jim = new Person('jim');

Resources