Relative path for data file in NodeJS module - node.js

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.

Related

How to include directories with Terragrunt

Is there a way to copy directories into the Terragrunt workspace?
I've come across the include_in_copy attritube, and I've tried something like this
terraform {
source = "git#gitlab.foo"
include_in_copy = [
"${get_parent_terragrunt_dir()}/foo-dir/"
]
}
But, it looks like this only copies content from whatever the source location is
However, in my case, I want to copy in an entire directory that's in the absolute path to the first terragrunt.hcl file, hence the use of the get_parent_terragrunt_dir() function.
This is what my file structure looks like.
├── deploy
│   └── bar
│   └── terragrunt.hcl
├── foo-dir
└── terragrunt.hcl
I'm calling terragrunt from inside the deploy/bar directory and I would like to include the foo-dir directory as well, but it looks like I'm doing something wrong.
Is there a function that might be able to do this?

React : how to load image outside src and public folders

My project as this kind of structure :
├── api
├── db
│ └── images
├── ui
│ └── public
│ └── src
│ | └── App.js
My app was created using create-react-app so I can't import files outside of src directory, and I do not want these images to be in the public folder : how can I have an img tag :
<img src="db/images/img_1.jpg">
with src getting images on db/images folder, completely outside of react app ?
Thank you for your replies
Another option is to put the image inside of your src and reference it in a react fashion. Consider the following:
├── ui
│ └── public
│ └── src
│ | └── App.js
└── img_1.jpg
app.js
import img from "./img_1.jpg";
then in your render img tag
<img src={img} />
Hoping this might work for you? iirc this will prevent someone from hotloading the image from your public folder.
If there's literally 0 way of moving the images into your react project, the only way I can think is to upload the images somewhere and reference them from a literal link, such as S3
If you just don't want it to reload when you upload a file, you can ignore the folder the files are uploaded to in you webpack config
devServer: {
...
watchOptions: {
ignored: './src/images/**/.*',
},
...
}
The create-react-app package uses a plugin for Webpack called ModuleScopePlugin that causes this behavior
You can use the package customize-cra for override the webpack configs.
The customize-cra has a method to resolve your problem.
removeModuleScopePlugin
or you can eject from create-react-app and remove this config manually at webpack

How to get the current path of the running Yeoman generator

I have my own Yeoman generator.
I created a sub-generator to create a new view folder.
Basically, the usage is:
open a new terminal
cd into the parent folder
run the yeoman command yo my-generator:view
follow the instructions
This view sub-generator prompt a folder name.
For example:
If I want to create the view authentication on the default views directory.
cd views
yo my-generator:view
The result should be:
views //- Already created by the main generator
├── authentication
│ ├── authentication.controller.js
│ ├── authentication.template.html
Now, if I want to create a sub-view login for the authentication view.
cd views/authentication
yo my-generator:view
The result should be:
views //- Already created by the main generator
├── authentication
│ ├── authentication.controller.js
│ ├── authentication.template.html
│ ├── login
│ │ ├── login.controller.js
│ │ ├── login.template.html
Instead, the current (wrong) result is:
views //- Already created by the main generator
├── authentication
│ ├── authentication.controller.js
│ ├── authentication.template.html
├── login
│ ├── login.controller.js
│ ├── login.template.html
My struggle here is that I don't know how to get the current path when I run the command.
Actually, I just create the new folder with a default prefix path which is app/views/.
This is why Authentication example works.
However when my current path is deeper in the views folder, it will add the new folder at the root of the views folder.
If I could get the current path (of the cmd), I should be able to add this path as the prefix instead of setting a default and not static one.
This is why Login example doesn't works.
Some code example:
$that is the current generator object
$that.viewNameCamel is the name of the folder set by the user
I use a .txt file as template and then create the controller.js file.
const filePrefix = 'app/views/' + $that.viewNameCamel + '/' + $that.viewNameCamel + '.';
const exampleData = {
controllerAlias: 'vm',
otherVar: 'example'
};
$that.fs.copyTpl(
$that.templatePath('controller.txt'),
filePrefix + 'controller.js',
exampleData
);
Tried:
$that.env.cwd
process.cwd()
__dirname
path.js library
Similar:
Issue 1037
Question 28481715
So guys, do you have a clue on how do I get the current folder path ?
Is there an alternative solution here ?
Thanks !
EDIT 1:
The problem here is the .yo-rc.json present on the root directory of the projet.
The file rewrite the path so I should delete it to fix the problem.
However if I delete this file, the user configuration will no longer be saved.
And I need it for later sub-generator usage.
Is there another way to save the user configuration ?
Or once again, is there another way to get the current real path ?
I know this is kinda old but for any one who comes later,
from the documentation https://yeoman.io/authoring/file-system.html
If you want to know from where the user is running yo, then you can get the path with this.contextRoot. This is the raw path where yo was invoked from; before we determine the project root with .yo-rc.json.
from my experience removing the .yo-rc.json would mean that you need to manually check if the path provided is ok, having a fixed root point is something helpful.
Just remove the .yo-rc.json file from your root directory. This is the file that is responsible for locating your root irrespective of where you are in the file system.
I am not sure about the repercussions of removing it but nothing seem to have happened to the generators I built.
Now you can use process.cwd() and it will get the correct working directory.
For your use case to have a prefix app/views, you probably need to write some Javascript to append or not append the prefix based on where you are, which should be trivial.

test or prevent some relative path imports / requires

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}`);
}
}

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

Resources