React : how to load image outside src and public folders - node.js

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

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

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

Runtime error when sharing code between client/server in Node.js app

I have a Node.js project with this basic folder structure:
├── project
├── client
├── app
   ├── assets
   │   └── css
   └── components
   ├── about
   ├── categories
   ├── home
   ├── navbar
   └── posts
├── common
├── model
└── util
├── server
├── api
├── model (deprecated for ../common/model)
├── conf
└── db
server is an Express API, client is an Angular2 App using this API. I use Gulp to build a dist folder which is being deployed to AWS Elastic Beanstalk.
Important: In dist, Client lives in app folder, while Server is in the root.
Everything was working fine until I decided to share some code between Server and Client (that's the point in Node.js I thought...). I've created a common folder in project's root with, among others, a post model (/project/common/model/post.ts)
In Server's /project/server/server.ts I replaced:
import {Post} from './model/post'
for:
import {Post} from '../common/model/post'
And it works.
But in Client's /project/client/app/components/posts/post-list.component.ts I replaced:
import {Post} from './post'; // Model was in the same folder here...
for:
import {Post} from '../../../../common/model/post';
and it compiles fine but then, when I try to reach Client in my browser, I get:
zone.js:101 GET http://127.0.0.1:3000/common/model/post 404 (Not Found)
(index):24 Error: Error: XHR error (404 Not Found) loading http://127.0.0.1:3000/common/model/post
I've checked and my Gulp's build task is correctly moving the compiled (transpiled) common files to dist/common.
Any hint on how to proceed to solve this? Thank you so much!
Presumably common has to be accessible from the browser, but is your webserver serving up files in the common folder?
In your express configuration you'll likely have something like this to serve up static content:
app.use(express.static(__dirname + '/public'));
But did you do the same for the new common folder you have?

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

Express.js Project Structure

I found that Express has an application generator, however the documentation does not explain the purpose of each directory and file. If someone could just give me a short explanation of which files I should be putting where, that would be much appreciated. Here's the generated app structure:
├── app.js
├── bin
│ └── www
├── package.json
├── public
│ ├── images
│ ├── javascripts
│ └── stylesheets
│ └── style.css
├── routes
│ ├── index.js
│ └── users.js
└── views
├── error.jade
├── index.jade
└── layout.jade
7 directories, 9 files
The app.js file is the entry-point of your application.
The package.json file contains all of your dependencies and various details regarding your project.
The bin folder should contain the various configuration startup scripts for your application.
For example, instead of applying all the Express middleware in the app.js file, you module.exports = {} them from their own configuration file and require them in app.js. [additional info LINK]
The views folder contains all of your server-side views.
The public folder contains all of your front-end code.
The routes folder contains all the routes that you have created for your application.
As stated in the official documentation, be aware that this is just one way to organize your code.
You should test it out and see if it fits your project.
This thread gives a deeper answer about the www file specifically: What does "./bin/www" do in Express 4.x?
Basically, running your app from the www file (which calls app.js) allows you to start your app with different configurations. You might have a "www" file representing the way the app should be run when on the web, a "dev" file that you, as the developer, would run, a "test" file you would run when running tests, etc. Read the thread linked above for more detail!
This structure is a standard organization for web-app
public contains all client static files (css, client javascript (ex. jQuery), images, fonts...)
routes contains the main back-end code (server side), which compute data before calling a template engine (see below) or respond to the client (via json of xml).
views contains each page template, see jade template. These files are used by scripts in "route"
app.js contains the express core, such as uri parser, modules, database...
package.json is the project descriptor file (used by npm for dependencies and sharing)
If the application generator provide a full example, don't hesitate to open each file (starting from app.js) to understand the project's organization.

Resources