Order of resolution with nodejs require module - node.js

Suppose I have all of foo.js, foo.coffee, and foo.jsonin the same directory, and I say require './foo' from another (coffeescript) file in that location, what rule governs which one will be loaded?
A short experiment (using require.resolve './foo') would seem to indicate that the javascript file wins over the other two.
Indeed, looking at require.extensions it looks like .js being mentioned there as the first item—but then, object attribute names are inherently unordered in javascript, right?, so any name added to that property could potentially re-order the entries—could that lead to another resolution order?
Just wondering, as i couldn't find any documentation. it does become relevant when you do (and maybe you shouldn't) coffee --compile route/to/directory.

.js is loaded first (this also means that it's better to use full name.json for your fixture instead of name as it could be shadowed by name.js)
From "modules" documentation:
If the exact filename is not found, then node will attempt to load the required filename with the added extension of .js, .json, and then .node.
Also, read name resolution algorithm in pseudo-code:
LOAD_AS_FILE(X)
1. If X is a file, load X as JavaScript text. STOP
2. If X.js is a file, load X.js as JavaScript text. STOP
3. If X.node is a file, load X.node as binary addon. STOP
After (1,2,3) extensions set in require.extensions are checked in the order they a set (for CoffeScript, require("coffe-script") installs .coffee handler).

The behavior in V8 is to iterate over named properties in the order they were originally assigned, so I would expect .js to always be first.
This post references that behavior

Related

Use node `fs` module on webpack compile

A bit about what I'm trying to achieve.
I'm building dev library that shows the list of files. And I want to set file color depending on when file was changed.
So, as a result of generation, I want an array like this:
[
{
lastChange: '2009-06-29T11:11:55Z',
fileContents: {name: 'VmSome'},
},
// ...
]
This is meant to work in browser environment. Meaning all file related information should be included into bundle.
Current progress
At the moment I'm not quite sure whether that's even possible.
I'm getting a list of files via webpack require.context:
require.context('./tree', true, /.js$/)
This gives me access to file content and path. But not to anything else.
Thanks for your attention.
I would first try modifying webpack-file-list-plugin. As of now, it creates a JSON that gives all files packed, their name and some more info... You could definitely add your code to fetch more information to the JSON.
https://github.com/object88/webpack-file-list-plugin/blob/master/src/index.js

Error of "encountered a second time" by find.pm

everyone,
when I deploy my package to a linux environment, I met this error:
.../Linux-2.6c2.5-i686/Ncurses/Ncurses-15766.0-0/lib/libncurses.so.5 is encountered a second time at /apollo/_env/FBAMerchantAutoRemovalDaemon-swit1na.1755067.237551097.1107633519/perl/lib/perl5.8-dist/File/Find.pm line 542.
though I read the perl script, I have no idea what is wrong. I suspect my environment is tainted. Does anyone have idea what is wrong and how can I debug this problem? Thanks a lot in advance!
Zhe
From perldoc File::Find
follow
Causes symbolic links to be followed. Since directory trees with symbolic links (followed) may contain files more than once and may even have cycles, a hash has to be built up with an entry for each file. This might be expensive both in space and time for a large directory tree. See "follow_fast" and "follow_skip" below. If either follow or follow_fast is in effect:
It is guaranteed that an lstat has been called before the user's wanted() function is called. This enables fast file checks involving _. Note that this guarantee no longer holds if follow or follow_fast are not set.
There is a variable $File::Find::fullname which holds the absolute pathname of the file with all symbolic links resolved. If the link is a dangling symbolic link, then fullname will be set to undef.
So, if, for the purposes of your application, if it is OK to follow symlinks, invoke find with the follow option set:
find({ wanted => \&process, follow => 1 }, $dir);
Or, consider if one of the other follow_skip behaviors is more appropriate for your application:
follow_skip
follow_skip==1, which is the default, causes all files which are neither directories nor symbolic links to be ignored if they are about to be processed a second time. If a directory or a symbolic link are about to be processed a second time, File::Find dies.
follow_skip==0 causes File::Find to die if any file is about to be processed a second time.
follow_skip==2 causes File::Find to ignore any duplicate files and directories but to proceed normally otherwise.
It may be that follow_skip => 2 is more appropriate for your application. Only you can make that decision.

How to know what path to specify in Node for require

All:
When I use Express.js(but I believe this is more of a Node question), if I want to import some modules, I need to use require(module path).
But I am a little confused what root path should be used for each require, are they all same to the path we execute the node command?
Sometime, It works when I use require("../modelname") while sometimes require("./modelname") even I did not change the modelname.js location.
Thanks
Node documentation provides a pseudo-code algorithm for how it resolves the path for require()
To sum up:
require(X) from module at path Y
If X begins with './' or '/' or '../'
a. LOAD_AS_FILE(Y + X)
b. LOAD_AS_DIRECTORY(Y + X)
LOAD_AS_FILE(X)
1. If X is a file, load X as JavaScript text. STOP
2. If X.js is a file, load X.js as JavaScript text. STOP
3. If X.json is a file, parse X.json to a JavaScript Object. STOP
4. If X.node is a file, load X.node as binary addon. STOP
LOAD_AS_DIRECTORY(X)
1. If X/package.json is a file,
a. Parse X/package.json, and look for "main" field.
b. let M = X + (json main field)
c. LOAD_AS_FILE(M)
2. If X/index.js is a file, load X/index.js as JavaScript text. STOP
3. If X/index.json is a file, parse X/index.json to a JavaScript object. STOP
4. If X/index.node is a file, load X/index.node as binary addon. STOP
If you are in a directory where you want to access modelname there are two scenarios given below
if modelname is in the same directory then you can use require("./modelname")
if calling directory is different and one level above to your modelname directory then you have to use require("../modelname").
When you do require( 'express' ), node will begin in your current folder, and step up the file tree until it locates a folder that has a package.json inside it.
Once it finds this file, it will check for a node_modules folder and look for node_modules/express. It will then follow the instructions in node_modules/express/package.json as to how to go about including the module.
If you want to require your own code that lacks a package.json, you'd do something like this.
require( './router' )
or
require( '../middleware/site-data' )
In the first example, the . refers to the folder the file doing the import is in, and will import either ./router.js or ./router/index.js, depending on which exists. In require, . is effectively translated into __dirname + '/'.
In the second example, the .. refers to the parent of the directory the importing file is in. In require, .. is effectively translated into __dirname + '/../'.
Good luck!
use webstorm tool where you have debugging facility like we have in eclipse, start your application in debug mode and put breakpoints.

Add a Timestamp to the End of Filenames with Grunt

During my Grunt tasks, add a unique string to the end of my filenames. I have tried grunt-contrib-copy and grunt-filerev. Neither have been able to do what I need them to...
Currently my LESS files are automatically compiled on 'save' in Sublime Text 3 (so this does not yet occur in my grunt tasks). Then, I open my terminal and run 'grunt', which concatenates (combines) my JS files. After this is done, then grunt should rename 'dist/css/main.css' and 'dist/js/main.js' with a "version" at the end of the filename.
I have tried:
grunt-contrib-copy ('clean:expired' deletes the concatenated JS before grunt-contrib-copy' can rename the file)
grunt-filerev ('This only worked on the CSS files for some reason, and it inserted the version number BEFORE the '.css'. Not sure why it didn't work on the JS files.')
Here's my Gruntfile.js
So, to be clear, I am not asking for "code review" I simply need to know how I can incorporate a "rename" process so that when the tasks are complete, I will have 'dist/css/main.css12345 & dist/js/main.js12345' with no 'dist/css/main.css' or 'dist/js/main.js' left in their respective directories.
Thanks in advance for any help!
UPDATE: After experimenting with this, I ended up using grunt-contrib-rename and it works great! I beleieve the same results can be achieved via grunt-contrib-copy, in fact I know it does the same thing. So either will work. As far as support for regex, not sure if both support it, so may be something else worth looking into before choosing one of these plugins :)
Your rename:dist looks like it should do what you want, you just need to move clean:dist to be the first task that runs (so it deletes things from the prior build rather than the current build). The order of tasks is defined by the array on this last line:
grunt.registerTask('default', ['jshint:dev', 'concat:dist', 'less:dist', 'csslint:dist', 'uglify:dist', 'cssmin:dist', 'clean:dist', 'rename:dist']);
That said, I'm not sure why you want this behavior. The more common thing to do is to insert a hash of the file into the filename before the file extension.
The difference between a hash and a timestamp is that the hash value will always be the same so long as the file contents don't change - so if you only change one file, the compiled output for just that file will be different and thus browsers only need to re-downloaded that one file while using cached versions of every other file.
The difference between putting this number before the file extension and after the extension is that a lot of tools (like your IDE) have behavior that changes based on the extension.
For this more standard goal, there are tons of ways to accomplish it but one of the more common is to combine grunt-filerev with grunt-usemin which will create properly named files and also update your HTML file(s) to reference these new file names
I'm not sure to understand completely what end you want, but if you add a var timestamp = new Date().getTime(); at the beginning of your gruntfile and concatenate to your dest param that should do the job.
dest: 'dist/js/main.min.js' + timestamp
Is it what your looking for?

ClassLoader.getSystemResource(...).getPath() seems to return wrong path

I'm trying to wrap code that requires two *.db4o data files for easy use. I've added the data files to my eclipse .classpath by placing the files in ${project_dir}/res/ and adding the line:
<classpathentry kind="src" path="res"/>
to my .classpath.
I then defined a default constructor to my wrapper class that takes no arguments but goes and finds the paths to the *.db4o files (the paths are required by the compiled code I'm using to set things up). My approach for getting the paths is:
String datapath = ClassLoader.getSystemResource("resource_name").getPath();
This works great when I debug/run my code in eclipse. However when I export it as a jar, I can see that the *.db4o files are in the jar, as well as my compiled code, but the path returned to "datapath" is of the form:
datapath = ${pwd}/file:${absolute_path_to_jar}!/{resource_name}
Is there something about the resource being inside of the jar that prevents an absolute path from working? Also, why is the behavior different simply because the code and resources live in a jar file? One last note is that while my application is intended for wider use (from PIG, python, etc. code) I'm testing it from Matlab which is where I'm getting the odd value assigned to "datapath".
Thanks in advance for any responses.
getSystemResource() returns URL to resource. If your resource is zipped in a jar file then the URL will point into it (with the "!" notation). getPath() returns the "path" part of the URL, not always an actual file path. URL can be one of many things, not just a file.

Resources