NestJs Microservice - Which location do I read files from? - nestjs

Wondering if anyone can help? I am trying to learn how to use NestJS microservices. I have managed to succesfully get a microservice with MQTT transport setup to receive events from an API. I am trying to use pug to merge the event information with a html template file. However pug cannot find the template file...
this.logger.info(`Running from dir ${__dirname}`); // /usr/src/app/dist/apps/microservice
const template = pug.compileFile('../templates/email.pug');
I have used a logger to display __dirname which refers to the dist directory. This has the single file main.js inside. How do I bundle and read a template pug file from nestjs microservice?
This post has a similar question, however it is for a nestjs app.

First we need to configure the express instance
// main.ts
const app = await NestFactory.create<NestExpressApplication>(
AppModule,
);
app.setViewEngine('hbs');
Put templates folder in root with the neighborhood src folder
but you must find it not in dist folder because Typescript compiler dont copy non-typescript files to dist folder for that approach you can use copy-webpack-plugin
but i just advise you change this url( ../templates/email.pug) so that to find folder located in root not find it in dist
hope it will help you! if not please provide your file structure.
https://docs.nestjs.com/techniques/mvc

Related

How do you name test files with unit tests in NodeJS project?

I have a NodeJS backend app using express framework.
I want to put my tests into a dedicated folder, say test in the root of the project.
And inside that folder I am going to have two sub-folders: unit for unit tests and integration for endpoint tests.
My question is what is the common practice around naming the unit-test files when they are not co-located with the source code file that they test?
I am considering to simply reflect the file path in the test-file name by joining the path with dots, e.g. controller.products.test.js for a products.js controller code that lives under the controller folder.
But is there any common way/convention that people of NodeJS normally follow?
Here is the structure:
/
/models
/controllers/
product.js
category.js
/middleware/
auth.js
validation.js
/test/
/unit/
controllers.product.test.js
middleware.auth.test.js
/integration/
products.test.js
index.js
package.json

Read files from folder before start

I want to get an array of file names from my project public/logos folder. I am using create-react-app template and as you guess, I can not use const fs = require('fs') in browser after project start.
So, is there any way to fill an array right after npm start command and getting file names array from folder or am I out of context?
const fs = require('fs')
const path = require('path')
const appRoot = require('app-root-path').path
const getNames = () => {
fs.readdir(path.join(appRoot, "public", "logos"), (err, files) => {
return files
})
}
Although the Sathishkumar is correct, it's not the only way: having an application server just for reading static images can be too much in many situations.
What you can do is to handle this by change the webpack configuration (this requires you eject first so be really careful).
From webpack you have all of the Nodejs features available but you must make those changes static for the webapp.
An idea:
manually copy with html-copy-plugin every image in the dist folder
read every image file in that folder from node and generate a list of image names
put the list of images as a global variable in your bundle by using webpack DefinePlugin
Now you will be able to read images names from this new global.
Note: this will not be a dynamic read of resources in a folder. If add/remove images you will be forced to repeat the build process of the app.
Yes. It is out of context. Not possible in browser-based JS application. You can't access the file system using Javascript in the browser.
You can use a NodeJS(or any other language for the same) to create a REST API as you mentioned which will return the files list and then can consume it(APIs like fetch or package - axios) in the frontend. This is the preferred way of doing.
If you need to read the files from file system you need to start server, like express, and then read this files on the server by request from frontend or by the link you pasted in your browser address field.

Node.js app structure, "folder by features" routing

I'm making a scalable REST-API, but I barely find articles on advanced node.js application structures in terms of a big application, since most of them are using simple starter projects.
I'm using the "folder-by-feature" structure, based on this article and this answer.
My question: what is the better structure of the solutions bellow?
1. Keep the routes in a separate folder:
src
product
index.js
product.spec.js
routes
index.js
product.js
user.js
user
index.js
user.spec.js
2. Put the route into its corresponding folder:
src
product
index.js
product.route.js
product.spec.js
user
index.js
user.route.js
user.spec.js
Using the routes in the index.js files.
Are there any better solutions?
Any article about advanced, scalable node project structures would be appreciated!
Since this is an opinion question here is mine:
My build migrates everything from src to dist. Some is compiled and some is just copied. I then run directly from the dist folder.
src
api
<api files/folders>
lib
<common lib files/folders>
routes
<Route files (app.use, app.get, etc.)>
static
<static css, images, script, etc.>
<I do not include src code that is compiled in any way>
ui
<LESS, SASS, JS, etc that will be compiled, combined, packed, etc>
views
<ejs files>
app.js
Things in src/ui/** get compiled and placed into dist/static/**.

Auto loading routes in HapiJS

I was wondering if anyone has a way to automatically and programmatically load HapiJS routes automatically. I was looking for a way that would be something like the routes that fall under a specific resource all go in a js file named after that resource.
For example, if I had a file src/routes/account.js, which would have the routes /login and /register, which would create the API routes /account/login and /login/register.. Or something that would let me have a programmatic way of automatically loading the routes.
I use Actin to load my controllers, and I was hoping to use something similar to that. I didn't see any plugins that could accomplish this, so I thought id ask if someone has a method for this already
Thanks!
I couldn't find anything that would load routes programmatically, using a folder structure to help with the route hierarchy, so I created my own.
It's not a full HapiJS plugin yet, but heres the code if anyone wants to use it.
Basic Details
Load the routes.js file as a HapiJS plugin (from the /dist folder, for ES5 transpiled version)
You can load it any way you want, I use Confidence to load it in the configuration file
Create a *Routes folder to contain your routes, make sure it's in the same folder as the routes.js file (Ill make an option so you can specify the routes folder later)
Create some js files that export some HapiJS routes (like so).
Keep in mind that the path in the route files will be appended to the path from the routes folder. Meaning if you have a file at src/routes/users.js, and it has a route with the path /list, then the real path will be /users/list
To define a Root Resource, then define the rootResource in the settings (Value should be the file name without the .js extension)
Take a look at hapi-auto-route. This package loads routes automatically and add prefix to the route path

What is index.js used for in node.js projects?

Other than a nice way to require all files in a directory (node.js require all files in a folder?), what is index.js used for mainly?
When you pass a folder to Node's require(), it will check for a package.json for an endpoint. If that isn't defined, it checks for index.js, and finally index.node (a c++ extension format). So the index.js is most likely the entry point for requiring a module.
See the official Docs here: http://nodejs.org/api/modules.html#modules_folders_as_modules.
Also, you ask how to require all the files in a directory. Usually, you require a directory with an index.js that exposes some encapsulated interface to those files; the way to do this will be different for ever module. But suppose you wanted to include a folder's contents when you include the folder (note, this is not a best practice and comes up less often than you would think). Then, you could use an index.js that loads all the files in the directory synchronously (setting exports asynchronously is usually asking for terrible bugs) and attaches them to module.exports like so:
var path = require('path'),
dir = require('fs').readdirSync(__dirname + path.sep);
dir.forEach(function(filename){
if(path.extname(filename) === '.js' && filename !== 'index.js'){
var exportAsName = path.basename(filename);
module.exports[exportAsName] = require( path.join( __dirname, filename) );
}
});
I hardly ever see people wanting to use that pattern though - most of the time you want your index.js to go something like
var part1 = require('./something-in-the-directory'),
part2 = require('./something-else');
....
module.exports = myCoolInterfaceThatUsesPart1AndPart2UnderTheHood;
Typically in other languages the web server looks for certain files to load first when visiting a directory like / in priority, traditionally this is either: index or default. In php it would be index.php or just plain HTML it would be index.html
In Node.js, Node itself is the web server so you don't need to name anything index.js but it's easier for people to understand which file to run first.
index.js typically handles your app startup, routing and other functions of your application and does require other modules to add functionality. If you're running a website or web app it would also handle become a basic HTTP web server replacing the role of something more traditional like Apache.
Here is a good article explaining how Node.js looks for required module https://medium.freecodecamp.org/requiring-modules-in-node-js-everything-you-need-to-know-e7fbd119be8, with folder and index.js file
Modules don’t have to be files. We can also create a find-me folder
under node_modules and place an index.js file in there. The same
require('find-me') line will use that folder’s index.js file:
~/learn-node $ mkdir -p node_modules/find-me
~/learn-node $ echo "console.log('Found again.');" > node_modules/find-me/index.js
~/learn-node $ node
> require('find-me');
Found again.
{}
>
Late to the party but the answer is simply to allow a developer to specify the public api of the folder!
When you have a bunch of JavaScript files in a folder, only a small subset of the functions and values exported from these files should exportable outside of the folder. These carefully selected functions are the public apis of the folder and should be explicitly exported (or re-exported) from the index.js file. Thus, it serves an architectural purpose.

Resources