test or prevent some relative path imports / requires - node.js

I have a folder structure like so:
.
└── client
├── components
└── routes
├── index.js
├── Login
│ ├── index.js
│ ├── assets
│ ├── components
│ ├── container
│ └── modules
└── UpdatePassword
├── index.js
├── assets
├── components
├── container
└── modules
I would like to see if anyone is importing files from the UpdatePassword folder to the Login folder and vice versa.
Basically I'm following a fractal project structure where I want components that are related to the UpdatePassword or Login route to only exist in their respective folders. Shared components would exist in the client/components subdirectory. To maintain a structure like this, I would like to write a test that fails when an 'unacceptable' imports or require is used. I.e. if a file in UpdatePassword imports from Login/components.
Is there a way to test or check whether an import is coming from specific folders?

Try madge: I usually run it as madge --image /path-to-folder/dependencies.png routes (There is also a exclude option if you need it)
You'll get a visual graph which shows you dependencies between files.

I have no idea about native way to do it.But you can wrap "require" function:
function myRequire(fromPath, requiredPath) {
//code to judge whether or not can load requiredPath from fromPath
var can = ...
if(can) {
return require(requiredPath);
}
else {
throw new Error(`you can not load ${requiredPath} from ${fromPath}`);
}
}

Related

Unable to serve react app using actix files crate

I am trying to serve a react frontend using actix server with the following service :
service(actix_files::Files::new("/app", "./react-front").index_file("./react-front/index.html")
And I have the following structure in react-front which is a react app build using npm run build:
react-front/
├── asset-manifest.json
├── favicon.ico
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
├── precache-manifest.70429bbe96a34ea56e1cb1a6570602b0.js
├── robots.txt
├── service-worker.js
└── static
├── css
│ ├── main.09af38e2.chunk.css
│ └── main.09af38e2.chunk.css.map
└── js
├── 1.e6893027.chunk.js
├── 1.e6893027.chunk.js.map
├── main.dc35c614.chunk.js
├── main.dc35c614.chunk.js.map
├── runtime~main.229c360f.js
└── runtime~main.229c360f.js.map
Visiting /app I am greeted with this, where "Your React App loaded successfully" is the actual text in my index.html and the rest of the files as you can see from the network tab, gets a 404. I have placed this service before any of the routers in my App configuration, and were I to put this service after my routers I would just get this text and a 204 No Content. No more 404 errors for the react js scripts whatsoever.
This leads me to two questions:
1. What effects result from the order in which service for file resources is written for App builder?
2. How can one serve a complete folder such that the browser can obtain all the relevant css and js files necessary to display the react app?
Currently here's how I am dealing with it: I use the crate actix-web-static-files and static-files to embed the contents react-front folder into the final executable and then run it
You can see that this works now. I want to achieve this without using these crates, just actix-files, if possible.
Here's the working code for this :
HttpServer::new(move || {
let generated = generate();
App::new()
.wrap(Cors::permissive())
.route("/book", web::get().to(get_phonebook_handler))
.route("/book/{id}", web::get().to(get_by_id))
.route("/{name}", web::get().to(get_by_name))
.route("/book/{id}", web::delete().to(delete_id))
.route("/book", web::post().to(post_phonebook_handler))
.route("/book/{id}", web::put().to(put_update))
.service(ResourceFiles::new("/", generated))
})
.listen(tcp)?
.run()
.await

Unable to inject a class-based provider in a function expression in nestjs

I have created the following project structure using NestJS
.
├── app.controller.ts
├── app.module.ts
├── app.service.ts
├── config
│   ├── config.controller.ts
│   ├── config.module.ts
│   └── config.service.ts
├── handlers
│   ├── handler1.ts
│   ├── handler2.ts
│   └── handlers.module.ts
├── main.ts
└── producer
└── producer.ts
Both the handler files wiz. handler1.ts & handler2.ts look something like this:
export const handler = async (args) {
...
...
}
I've ConfigModule in which I've registered ConfigService as a provider. What I want to do is I want to somehow use ConfigService in handler1.ts & handler2.ts. Now mind you, these handlers are not classes, but just normal function expressions. I know if they were classes, I could have injected ConfigService in the handler's constructor using Dependency Injection. But, unfortunately, declaring these handlers as classes is no more an option now. The reason behind that is that these handler files are being consumed by producer.ts and producer.ts reads the entire file and expects an exported function.
I went through the NestJS documentation and found about property-based injection, module-ref, but they were of no help. I also found this link which I think is very close to my problem, But after going through the comments I found out this is not possible.
I don't have much liberty in changing the existing code but I'd still like to know what options do I have here. A solution that would require fewer changes and solve my problem. Thanks!
Note: File handlers.module.ts is serving no purpose in this scenario.

Relative path for data file in NodeJS module

I created a NodeJS module, written in typescript (though it shouldn't change anything).
Here's how it's organized:
.
├── data/
│   └── MY_DATA_FILES.json
│
├── src/
│   ├── data/
│   │   └── data.ts
│   │
│   └── OTHER_TYPESCRIPT_FILES.ts
│
├── dist/
│   ├── data/
│   │   └── data.js
│   │
│   └── OTHER_JAVASCRIPT_FILES.ts
│
├── package.json
└── tsconfig.json
My goal is to read the data files from the data.ts file. When my current working directory in on the root of the module it's not a problem (then it would be ./data/...) but when I use this as a module, and it's placed in the nodes_modules/ directory, I'm not sure how to handle the situation.
I'm currently reading the files as follow:
import fs from 'fs';
const basePath = './data';
const filesPath = 'subdirectory/my_data.json';
export function getData(): any {
const fileFullPath = basePath + '/' + filesPath;
const contents = fs.readFileSync(fileFullPath);
// [...]
}
But here, my basePath is dependent on my working directory. I could set it as ./node_modules/my_module/data, but I know that's not the right approach..
Any help would be appreciated, thanks!
You would typically build a path for each location that is relative to the directory where your code is located and access the desired location in a relative way from that. The location of your code will be passed to the code's module as __dirname. You can then combine that relative path with __dirname to build a full path to the target location without making any assumptions about where or how the module is installed.
So, assuming your code is in the src directory, that would be where __dirname points to. To, get access to the data directory below the src directory, you would use:
let srcDataDir = path.join(__dirname, "data");
To get access to the dist/data directory, you would use:
let distDataDir = path.join(__dirname, '../dist/data');
To get access to the higher level data directory where MY_DATA_FILES.json is, you would use:
let topDataDir = path.join(__dirname, '../data');
As, you can see, the key is to build everything relative from the location you do know which is __dirname passed to the code as the location of the code's own directory.
In Javascript's modules, you don't ever want to make any assumptions about the current working directory because that can literally be anything. That's controlled by the top level program itself and how the program was started and is not anything the module itself can rely on or make assumptions about. But __dirname will always be the full path to the directory where your module's code is running from.

Cloud9 Node js Express jade IDE: file structure

In Cloud9 Express IDE example I see in folder/file routes/users.js - please tell me why this is in separate file -what is the intention of users.js as a distinct file? :
/*
GET users listing.
*/
exports.list = function(req, res){
res.send("respond with a resource");
};
ok Im trying to answer that one myself (feel free to chime in):
The basic Express set up folder structure according to Expressjs.com looks like this:
├── app.js
├── bin
│ └── www
├── package.json
├── public
│ ├── images
│ ├── javascripts
│ └── stylesheets
│ └── style.css
├── routes
│ ├── index.js
│ └── users.js
└── views
├── error.jade
├── index.jade
└── layout.jade
It is suggested and not obligatory. However for noobs like me this helpful website says:
If you are getting started with Express it is recommended that you use the structure from the generator.
Edited:
In the particular folder structure generated in Cloud9 Express the file /routes/users IS intrinsic to a typical Express-Jade setup.
Basic routing tutorial here answers what each of these files is doing

How to properly decouple MongoDB

I'm rather new to web development all together. I'm trying to get a node.js/express/mongo project off the ground. I'm coming from a C/C++ background, and the module organization paradigms seem a little strange to me.
Currently, in my server.js, I create, connect, and initialize my mongoDB object using mongoose, then pass around this object query, insert ect on it. Doesn't seem like something I should be doing inside server.js.
Is the proper way to loosely couple Mongo from my project by creating a separate module (ex. database) where I do all the initialization, options, ect, and return a mongodb instance through this new module?
I've never undertaken a project of this size (or type) before, and just don't know how to best organize everything..
Any advice from those people much more experienced than me would be appreciated
Many ways to do it. Here's some ideas.
Yes, you'll want to have a routing/handlers setup of some kind so that different modules have the ability to call different services and/or decouple.
Below is a fairly standard node.js / express structure:
├── server.js
├── config
│ ├── development
│ ├── production
│ └── staging
├── handlers
│ ├── customers.js
│ └── stores.js
├── node_modules
│ ├── assert
│ ├── ejs
│ ├── express
│ ├── forever
│ ├── mongodb
│ └── mongoskin
├── package.json
├── README.md
then in server.js, you can import your handlers like so:
// import route handlers
var customers = require('./handlers/customers'),
stores = require('./handlers/stores');
and then inside your handlers, you'll be able to declare functions:
exports.addCustomer = function(req, res) {
// ....
};
which in server.js you can use for routing:
app.post('/customers/add/:id, metrics.addCustomer);
so then you've got a basic framework. Just defining the database connections outside of the exports.XXX functions in the handler files is fine because those functions will have access, but not anything in server.js so you won't pollute your namespace.
var url = config.user +":"
+ config.pass +"#"
+ config.host +"/"
+ config.database;
var mongo = require('mongoskin').db(url);
where you might load the config object from a JSON file.
hope that helps.

Resources