node.js where to put util functions used by backend and frontend - node.js

Node.js is special because the backend and frontend use the same language. I wanted to take advantage of this and only write 1 set of util functions (universal functions like numToPercent) for backend and frontend. Here is how my (important) files are structured right now:
project
public
index.html
index.js
scripts
script1.js
index.js
otherScript.js
Where is the canonical location to put my util file?
Edit: to make this more specific, is there a "shared" folder or something to put this file? Because otherwise public seems like the best place to put this

You can package the shared code and add it as a dependency via npm.

Related

How to use ReactDOMServer.renderToStaticMarkup without nodejs server

I want to use ReactDOMServer.renderToStaticMarkup to create a static website, but I only want to generate the html string once during build instead of dynamically for every request
Here are the relevant docs, but they don't go into much detail on implementation https://reactjs.org/docs/react-dom-server.html#rendertostaticmarkup
What is the best practice for using react to generate html one time during build instead of dynamically on every page request? I am using webpack.
For anyone who comes here looking for answers, here's how I did it:
Create a separate webpack config file for your SSR react like webpack.ssr.js. This file will have the same config you'd normally have for react SSR.
In the index.js file where you'd usually have ReactDOM.render, run the ReactDOMServer.renderToStaticMarkup function.
In the index.js file, write the html string to a file:
const html = ReactDOMServer.renderToStaticMarkup(App);
fs.writeFile("index.html", html, (err) => {
if (err)
console.log(err);
else {
console.log("File written successfully\n");
}
});
After every build, execute the build file as a node script. For example node build.js. I'd recommend doing this in package.json as a postbuild script. For example:
postbuild: "node build.js"
The fs.writeFile will update the index.html file each time you build, so you'll just need to serve index.html like you would with any other static website.
For css modules, you'd use something like isomorphic-style-loader instead of the regular style-loader.
If you are using something like react-router, you'll need to iterate through all your routes and run ReactDOMServer.renderToStaticMarkup and fs.writeFile for every route. Then you'd serve the different html files with server side routing.
This will also work for normal SSR using ReactDOMServer.renderToString, especially if you don't need dynamic SSR based on something like an ID. For generating the loading screen server side, this is great and there's really no reason to generate html dynamically at runtime.

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

Webpack-dev-server and isomorphic react-node application

I've managed to properly use webpack dev server alongside with a node server (express), using the plugin section inside webpack's config.
It all works fine but now I'm trying to go isomorphic and use client-side components inside the express application.
So far the only problem I'm encountering is that without webpack 'parsing' my server-side code I get to a situation where I require components but the paths are not solved
I.E.
Inside a component
'use strict';
import React from 'react';
import { RouteHandler, Link } from 'react-router';
import Header from 'components/header/main'; // <-- This line causes the error because webpack is not working when parsing this JSX server-side
export default React.createClass({
displayName: 'App',
render() {
return ( // ... More code
Shall I configure webpack in another way or do I have to change all the imports to be valid server-side?
the codebase is here in case you want to see the actual state https://github.com/vshjxyz/es6-react-flux-node-quickstart
In order to be able to require components in a way such as require('components/Header.js'); and avoid using long relative paths such as require('../../../../../../Header.js'); you can add this code to your node app before any require() calls:
process.env.NODE_PATH = __dirname;
require('module').Module._initPaths();
However, since this relies on a private Node.js core method, this is
also a hack that might stop working on the previous or next version of
node.
Other possible solutions to this problem can be found at https://gist.github.com/branneman/8048520
I see 2 options:
Compile client code with webpack as well. If client's entry
point is in the same dir as server's - it should work with your
present code. This looks natural to me.
Use relative paths i.e.
import Header from './components/header/main'

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.

How do I prevent Node.js / Express serving up my application's source code?

I never thought this would be a problem with Node.js and Express, but on a crazy whim I decided to type into a browser the location of one of the source files in my Node.js Express project - something like:
http://www.mywebsite.com/mynodejsapp/app.js
To my extreme horror, my application's source code popped right up, publicly available for all to see.
So, that aside: how do I stop it in Node.js / Express?
My setup code is pretty straightforward:
var app = express();
app.configure(function() {
app.use(express.static('/home/prod/server/app/public'));
});
app.listen(8888);
To clarify, this is what my folder structure looks like:
/home/prod/server/
/home/prod/server/app.js
/home/prod/server/public/
All sorts of various files that are intended for public access live under /public. All of my server source code lives under /server/, and my understanding of Express's static folder configuration is that the static folder is the only place that Express happily serves up files from the filesystem from.
Any ideas?
From what you posted it really smells like the URL you entered is served by e.g. Apache/nginx/... and you did put your node app within the document root. The answer is simple in this (and any similar) case:
You never put any of your sourcecode files within the document root or another HTTP-accessible folder. In your case, /home/prod/server/app/public should contain only client-side stuff (HTML, CSS, Graphics, (minified) client-side JS) and nginx should not have anything above this folder as its document root.

Resources