Refactor multiple, similar requires (using Browserify) - node.js

I've got a very crude implementation working:
var screens = {
a: require('./../react_components/screens/a.jsx'),
b: require('./../react_components/screens/b.jsx'),
c: require('./../react_components/screens/c.jsx'),
d: require('./../react_components/screens/d.jsx'),
e: require('./../react_components/screens/e.jsx')
};
Which works fine, however, I'd like to make it a little more scalable, so that when I change a filename, or add a new file to the /screens folder, I don't really have to keep updating this list of require statements.
I'm using Browserify, so I do have a build step I can hook into if need be (this will be ran in the browser)

So for node/commonjs itself there are modules such as requireindex that will automate this kind of thing. However, the fact that these approaches determine the dependencies at runtime by looking at the filesystem defeats browserify's static analysis so I'm not aware of any of them that are browserify-compatible. Therefore, I'd suggest a code generation route where you use a module such as glob to discover the files you want to export, but then write out a full .js file with the exports all statically coded, and point browserify at that file, which you can regenerate every time during your build step.

Related

Making nodejs "require" path-independent?

I write a fairly complicated node.js project, and the need to write the relative path in the "require" is driving me insane and is error prune.
Is there any way to avoid stuff like this
logger = require('../../modules/logger');
and be path-independent without turning every module into a full blown npm module?
I often use an "app symlink" where I create a symlink at node_modules/app that points to ../app. Then in my code I can require modules without relative paths: require('app/logger'). It avoids lots of ../../.. paths and having to change them when you move a file around. However, since it relies on symlinks and Windows does not support symlinks, it won't work on Windows. Thus I only use it in apps I know only need to work on posix systems.
Depending on how your directory structure is laid out for your project, it might be best to pass things like your logger to your other modules from the main app (and farther from there).
var logger = require('./helpers/logger');
var someModule = require ('./controllers/someModule')({ logger: logger });
Passing other things that way help too, like the db connection (or connection pool). Again, depends on how you have your project laid out.

Where do I put modular logic?

I'm using Node and Express and I have a very beginner question. In fact it's so basic that I'm having trouble coming up with a title for it. I'm writing a modular piece of logic. It involves a few javascript files and I'd like to keep them together in one directory. When I person goes to my web app, this code is to be accessed from routes/index.js. I want to have something like
var foo = require('???/logic');
and then when somebody loads the page I will call
foo.getBar();
and then assign what it returns to a variable used in the jade template
So my questions are 1. Where should I put my directory of modular code? node_modules? and 2. Does this, generally, sound like the right way to design an express app?
Choose from the structure below based on the amount of code we are talking about.
A: single CommonJS module in a single .js file
You can export functions, constructor functions, properties
if you have 30 properties exported or more than X lines of code (for me X is 300ish, for others they are OK with 500ish), graduate to the next option
B: CommonJS module directory consisting of a my-module/index.js and other supporting .js files
other modules can require this with require('./my-module') and not know or care whether my-module is 1 .js file or many in a directory
Use this variant as your logic grows
loose coupling. High cohesion.
C: Put your logic in it's own npm module
This makes it shareable with the community and across your internal projects as well
The better you get at this and more comfortable with the process and tools, the more likely you are to skip A and B and just make standalone npm modules

How to break the build into several files?

In case of a very lengthy built file, I would like to be able to break it into several parts. For instance, the vendors could be all minified into a vendor.built.js file and the rest into an app.built.js file.
How this can be done?
I have a proposed solution for this in my require-lazy project.
It accomplishes something a little different than what you ask though: It splits the application into lazy-loaded modules, as easy (from the developer's perspective) as writing (note the usage of the lazy! plugin):
define(["eager-module", "lazy!lazy-module"], function(eager, lazy) {...})
And then using it with through a promise:
lazy.get().then(function(real_module) {...});
The lazy-module will be loaded once, the first time .get() is called.
For the example above, the build process would produce 2 js files: On containing the main module, the eager-module and all their dependencies. And one containing the lazy-module and all its dependencies that were not included in the previous file/bundle.
The require-lazy project has a few examples that are very simple to setup, you only require Node.js.

How use dev and prod assets in NodeJS/Express/Jade properly

I have a NodeJS application with Express based structure and Jade module for a views. I need to use a full version my assets on a developer machine and min version in production machine.
Can you explain best practices of how should I do it properly?
EDIT: If you put a minus please describe the reason.
Not sure why there isn't an "official" way of doing this (compared to what Ruby on Rails does).
Here are a few suggestions:
DIY
Here's what I've been doing so far:
At server startup, I run uglify-js on all the js files (under .../js, and create the minified version under .../min) with something like so (leaving out the reading/writing of the files):
var jsp = require('uglify-js').parser;
var pro = require('uglify-js').uglify;
var ast = jsp.parse(code.toString('utf8')); // parse code and get the initial AST
ast = pro.ast_mangle(ast); // get a new AST with mangled names
ast = pro.ast_squeeze(ast); // get an AST with compression optimizations
var final_code = pro.gen_code(ast); // compressed code here
then in html templates, based on some environment variable to trigger production environment, I generate the path for the <script> tags to either point to .../js or .../min.
This leaves out quite a lot (where you would group all js files into one minimized one to reduce the number of browser queries and such), but hopefully this can help you craft your own strategy.
Piler
That said, I've been meaning to try piler (https://github.com/epeli/piler), which seems to be a better alternative to the DYI way.
Using Grunt
Grunt.js (http://gruntjs.com/) is also quite suitable to help preprocess files (html, js, css, ...)
Here are a few pointers:
grunt-recess: https://github.com/sindresorhus/grunt-recess (especially interesting if you use less)
how to config grunt.js to minify files separately
Grunt tasks to process HTML files and produce a deploy directory of optimized files (https://gist.github.com/necolas/3024891)
I view minification as a build step and prefer to not burden the application at runtime with it. Therefore, I would setup my HTML files to refer to file paths which are generated from the build tool and then use the build tool to figure out whether or not to minify.
I haven't actually needed to make it conditional myself because I haven't needed to have unminified code in the browser. With grunt setup to watch the source files and recompile automatically, I can edit a JavaScript source file and it automatically gets rebuilt and placed into the appropriate runtime location. However, I could see this being useful for stepping through code. IE 9 has a formatter in its dev console which is useful for debugging minified code, but I'm not sure how common that is across browsers.
If I were to skip minification in development, I would first check if I can make the grunt uglify task use a config setting like an environment variable or npm setting, etc. to decide whether to actually uglify or not. If that is not possible, I would make a separate grunt task called "devBuild" that does everything except uglify.

require() in large, multi-file Node projects

I'm working on a large Node project. Naturally, I want to break this into multiple source files. There are many modules from the standard lib that I use in a majority of my source files, and there are also quite a few of my own files that I want to use almost everywhere.
I've been making this work by including a huge require block at the beginning of each source file, but this feels awfully redundant. Is there a better way to do this? Or is this an intended consequence of Node's admirable module system?
You can use a container module to load a series of modules. For example, given the following project structure:
lib/
index.js
module1.js
module2.js
main.js
You can have index.js import the other modules in the library.
# index.js
module.exports.module1 = require('./module1');
module.exports.module2 = require('./module2');
Then main.js need only import a single module:
# main.js
var lib = require('./lib');
lib.module1.doSomething();
lib.module2.doSomethingElse();
This technique can be expanded, reducing redundant imports.
I'd say generally that a require block is better practice than using global in Node.
You need to remember that requires are cached so when you put them in all of your code modules, you will always get the same instance not a new one each time.
Doing it this way ensures that you get the appropriate code with the expected name spaces exactly where you want it whereas using global will include things you don't need. Doing it the Node way with require will also tend to make your code slightly more portable.
Well, a couple of things, here.
First, if so many of your files are requiring the same libraries over and over again, you might want to step back and determine if you're really breaking your code up in the proper way. Perhaps there's a better organization where certain libraries are only needed by subsets of your source files?
Second, remember that the global object is shared between all of your required files in your Node.js app. Your "root" source file, say index.js, can do things like global.fs = require('fs'); and then it's accessible from all of your various files. This would eliminate the need to require a file full of requires. (In Node.js, you have to explicitly state that you're accessing a global variable by prepending global., unlike in the browser.)
This can be a good idea for CRUD-type Express apps where you have lots of code for controllers that are all almost the same but have to be slightly different for each view and you just want to split them apart not for any particular organization structure, but just to make it easier to debug (error in this file, not that file). If the structure of the app is more complex than that, take the usual warnings against global variables to heart before using that trick.
Require more than one file without absolute path through require-file-directory.
1- Can require more than one file in single statement.
2- Can require files with only their name.
Visit for solution: https://www.npmjs.com/package/require-file-directory

Resources