Traverse directory structure in Javascript with callback for each hit - javascript

There are a number of options for traversing a directory tree in Javascript (node-dir, fs.readdir, ...) and most supports asynchronous execution with a callback when finished.
But is there a framework that supports callbacks on each found file? I want to build a loader for audio files that incrementally adds the files as they are found.
Plain Javascript (or Typescript) solutions are also accepted.

I was thinking that traversing the structure was costly, and wanted to do the work for each file as it was found by the traversal, instead of collecting a list first. But experiments show that this is not the case, traversal is in fact very cheap compared to just opening a file, let alone parsing content. So I'll go with the suggestion from #Joseph and just use one of the options listed and call the function for each file.
I'll make this incremental by doing this asynchronously and update the UI reactively.
Thanks, for straightening out my thinking.

Related

copyFileSync vs writeFileSync

I am working on file manipulations and came across this.
Tried to look for an answer online but havent encountered any good, precise answer.
Which of these is a more optimized way of copying a file?
readFileSync() -> writeFileSync()?
Or directly
copyFileSync()?
Also noticed that copyFileSync uses the original file's timestamp. If copyFileSync() is more optimized, is there a way for it to use the "copy time timestamp"?
Thanks!
Well first you need to know that reading file content then writing it to another file is not the same as copying a file, a file is more than just its raw content, almost all files have meta data associated with them, and when you read a file content and write it to a destination, you lose that meta data. So if you want to copy a file, use the copyFile method, else you will have to handle meta data yourself.
Second, the two methods in theory should have the same performance signature, in practice though there might be differences between them under different conditions (different operating systems, different file sizes), however worrying about that is more of a premature optimisation. However for performance sake, its better to use the async versions of these methods.
The copyFileSync does not allow you to directly change the creation date of the file, but you can do that using fs.stat

Calling JS function multiple times from node addon

Edit: apparently it's not clear, guess I'll make it more concise.
Node application is built, uses a native addon. I need to pass in a Javascript function from this project through node-addon-api into my C++ addon. Then, I need to be able to call that function from C++ multiple times. The issue arose when I found out I am unable to save the reference to the Javascript function due to the napi_env (required for calling the function) being protected from caching.
Could not find any clear answers or examples on the internet regarding how to do this, looking for tips.
Original:
as the title describes, I need to figure out a way to call a JS function multiple times in my addon. Generic use case is that my addon does some long running commands and needs to periodically push a status update back to the javascript.
I thought the best approach would be to have the user pass in a function (which just appends to a text block) for my addon to call (so it can write the updates), this way the javascript side can decide where it gets displayed.
I have experimented to get this working. Found out that my original way of saving the function in a persistent napi_value doesn't work since you cannot save napi_env as well.
I found this thread, which I think is the closest to what I need, but I can't manage to translate the Nan to napi_ so it would work with what I'm using. Callback NodeJS Javascript function from multithreaded C++ addon
Also attempted passing in an EventEmitter, but similar problem as above.
Can anyone give some pointers on if I am heading in the right direction? Perhaps help me dig up a few examples on how to accomplish this?
Your question is not clear. Assuming you are using Javascript in Node, have a look at FFI which allows one to loading and calling dynamic libraries using Javascript.
Alternatively one can just execute a function as follows from the command line:
/usr/bin/node yourjsfunctionfilehere.js
You can also pass command line parameters to the called JS function.

Possible to serialize node.js vm.script?

I'm experimenting with ways to pre-compile a large number of JS functions using node.js vm.script, so that I can call the functions multiple times without the overhead of recompiling each time. Note that I can't just include the functions in a module, because they are architecturally completely separate from the "core" code. That works fine--each compiled script is stored in an object and can be run as-needed.
What I'm trying to figure out is how to use this same model with multiple fork'ed child processes, so any child process can be used to run the compiled script. The question is how to serialize it, so I can pass it to the child. And more importantly, is there anything inherent in the script variable that would "tie" it to the process it was created in?
I'm afraid is not possible. The first hint is that the Script object doesn't have any method to retrieve the compiled code. Looking further inside the source code of node here and here, it seems that the compiled object is stored inside a native C object. Therefore there's no means to serialize it from JS.

ES6 exports/imports use-case, compared to traditional namespacing

I don't understand WHY and in what scenario this would be used..
My current web setup consists of lots of components, which are just functions or factory functions, each in their own file, and each function "rides" the app namespace, like : app.component.breadcrumbs = function(){... and so on.
Then GULP just combines all the files, and I end up with a single file, so a page controller (each "page" has a controller which loads the components the page needs) can just load it's components, like: app.component.breadcrumbs(data).
All the components can be easily accessed on demand, and the single javascript file is well cached and everything. This way of work seems extremely good, never saw any problem with this way of work. of course, this can (and is) be scaled nicely.
So how are ES6 imports for functions any better than what I described?
what's the deal with importing functions instead of just attaching them to the App's namespace? it makes much more sense for them to be "attached".
Files structure
/dist/app.js // web app namespace and so on
/dist/components/breadcrumbs.js // some component
/dist/components/header.js // some component
/dist/components/sidemenu.js // some component
/dist/pages/homepage.js // home page controller
// GULP concat all above to
/js/app.js // this file is what is downloaded
Then inside homepage.js it can look like this:
app.routes.homepage = function(){
"use strict";
var DOM = { page : $('#page') };
// append whatever components I want to this page
DOM.page.append(
app.component.header(),
app.component.sidemenu(),
app.component.breadcrumbs({a:1, b:2, c:3})
)
};
This is an extremely simplified code example but you get the point
Answers to this are probably a little subjective, but I'm going to do my best.
At the end of the day, both methods allow support creating a namespace for a piece of functionality so that it does not conflict with other things. Both work, but in my view, modules, ES6 or any other, provide a few extra benefits.
Explicit dependencies
Your example seems very bias toward a "load everything" approach, but you'll generally find that to be uncommon. If your components/header.js needs to use components/breadcrumbs.js, assumptions must be made. Has that file been bundled into the overall JS file? You have no way of knowing. You're two options are
Load everything
Maintain a file somewhere that explicitly lists what needs to be loaded.
The first option is easy and in the short term is probably fine. The second is complicated for maintainability because it would be maintained as an external list, it would be very easy to stop needing one of your component file but forget to remove it.
It also means that you are essentially defining your own syntax for dependencies when again, one has now been defined in the language/community.
What happens when you want to start splitting your application into pieces? Say you have an application that is a single large file that drives 5 pages on your site, because they started out simple and it wasn't big enough to matter. Now the application has grown and should be served with a separate JS file per-page. You have now lost the ability to use option #1, and some poor soul would need to build this new list of dependencies for each end file.
What if you start using a file in a new places? How do you know which JS target files actually need it? What if you have twenty target files?
What if you have a library of components that are used across your whole company, and one of they starts relying on something new? How would that information be propagated to any number of the developers using these?
Modules allow you to know with 100% certainty what is used where, with automated tooling. You only need to package the files you actually use.
Ordering
Related to dependency listing is dependency ordering. If your library needs to create a special subclass of your header.js component, you are no longer only accessing app.component.header() from app.routes.homepage(), which would presumable be running at DOMContentLoaded. Instead you need to access it during the initial application execution. Simple concatenation offers no guarantees that it will have run yet. If you are concatenating alphabetically and your new things is app.component.blueHeader() then it would fail.
This applies to anything that you might want to do immediately at execution time. If you have a module that immediately looks at the page when it runs, or sends an AJAX request or anything, what if it depends on some library to do that?
This is another argument agains #1 (Load everything) so you start having to maintain a list again. That list is again going to be a custom things you'll have come up with instead of a standardized system.
How do you train new employees to use all of this custom stuff you've built?
Modules execute files in order based on their dependencies, so you know for sure that the stuff you depend on will have executed and will be available.
Scoping
Your solution treats everything as a standard script file. That's fine, but it means that you need to be extremely careful to not accidentally create global variables by placing them in the top-level scope of a file. This can be solved by manually adding (function(){ ... })(); around file content, but again, it's one more things you need to know to do instead of having it provided for you by the language.
Conflicts
app.component.* is something you've chosen, but there is nothing special about it, and it is global. What if you wanted to pull in a new library from Github for instance, and it also used that same name? Do you refactor your whole application to avoid conflicts?
What if you need to load two versions of a library? That has obvious downsides if it's big, but there are plenty of cases where you'll still want to trade big for non-functional. If you rely on a global object, it is now up to that library to make sure it also exposes an API like jQuery's noConflict. What if it doesn't? Do you have to add it yourself?
Encouraging smaller modules
This one may be more debatable, but I've certainly observed it within my own codebase. With modules, and the lack of boilerplate necessary to write modular code with them, developers are encouraged to look closely on how things get grouped. It is very easy to end up making "utils" files that are giant bags of functions thousands of lines long because it is easier to add to an existing file that it is to make a new one.
Dependency webs
Having explicit imports and exports makes it very clear what depends on what, which is great, but the side-effect of that is that it is much easier to think critically about dependencies. If you have a giant file with 100 helper functions, that means that if any one of those helpers needs to depend on something from another file, it needs to be loaded, even if nothing is ever using that helper function at the moment. This can easily lead to a large web of unclear dependencies, and being aware of dependencies is a huge step toward thwarting that.
Standardization
There is a lot to be said for standardization. The JavaScript community has moved heavily in the direction of reusable modules. This means that if you hope into a new codebase, you don't need to start off by figuring out how things relate to eachother. Your first step, at least in the long run, won't be to wonder whether something is AMD, CommonJS, System.register or what. By having a syntax in the language, it's one less decision to have to make.
The long and short of it is, modules offer a standard way for code to interoperate, whether that be your own code, or third-party code.
Your current process is to concatenate everything always into a single large file, only ever execute things after the whole file has loaded and you have 100% control over all code that you are executing, then you've essentially defined your own module specification based on your own assumptions about your specific codebase. That is totally fine, and no-one is forcing you to change that.
No such assumptions can be made for the general case of JavaScript code however. It is precisely the objective of modules to provide a standard in such a way as to not break existing code, but to also provide the community with a way forward. What modules offer is another approach to that, which is one that is standardized, and one that offers clearer paths for interoperability between your own code and third-party code.

jQuery/JS for different pages - best way of doing this?

Apologies if this is a silly question, and I'm not even sure of the best way of wording it...
At the moment I have a site with maybe 20+ different uses of jQuery, all varying from page to page. I'm just wondering what the best way is to store this code?
Everything in one big jquery.myfunctions.js file? And check if the element exists for each statement?
Embed script tags into each individual page?
Use PHP to deliver different content into script tags kinda like the above?
Separate .js files per page? ims I don't like the sound of this at all
To be honest, I'm not even sure if jQuery does this for you, so it's okay to have multiple $('#whatever').function() loaded onto each page without any noticeable performance issues?
Any advice on this would be fantastic, probably a silly question but I want to do things the 'proper' way you know?
Thanks :-)
Personnally I like to have one file with all the things needed in it. It's better because once loaded, the browser can cache it and you don't care anymore.
As for coding, I may write pieces of code in different files, which I build as a single file for production.
This way, all your code is accessible anytime.
Nevertheless, you may include tags in your views/templates, so that you can trigger certain functions only on particular views/pages.
For example :
myObject = {
myFunctionForArticles : function(){ $('.article').each(...); },
myFunctionForCategories : function(){ ... }
};
And within the Article view :
<script type="text/javascript">
myObject.myFunctionForArticles();
</script>
Make sure your included javascript keeps very thin and general though. More than one liners calling a general function can lead to trouble. In theory it is not something you might call a best-practise. Choose what you feel is the right balance between tidyness and easiness to maintain (if you have few views, maybe you can make, along with the one big file containing all the heavy stuff, some short and specific js files, which are called only by the right view to trigger the right functions at load time ; if you have a lot of views, maybe including one-liner inline js tags will save you the burden to maintain a lot of short files).
I've recently grappled with this problem when re-starting development of a very involved web app. I decided on several patterns:
do not put inline javascript on pages in general - it prevents caching and defeats the point of separating functionality from presentation
create your own namespace - I like the DOD approach to it (http://www.dustindiaz.com/namespace-your-javascript/) So, my namespace is DG, thus all of my code is part of a single global variable called DG - which is an object, containing all of the subclasses
Create a class prototype structure, where if you're doing common things with a bit of difference between implementations
for example, logging into different sites - you're doing logins, but, some may do it differently than others - so, create a prototype class than handles generic functionality, and then implement site-specific login functionality in classes that inherit from the prototype)
Use the Yahoo Module pattern for singletons, but don't fall in love with it - it's not useful if you have more than one instance per page of a class (http://www.yuiblog.com/blog/2007/06/12/module-pattern/)
use a require/import function to do dynamic imports of javascript
this one is an optional but great. I really like doing dependencies for javascript, so I don't have to include a ton of script tags in my code, and, it really does help with performance, as most require/import frameworks load JS on demand, not at first.
My thoughts:
Never put anything on the individual
pages themselves, always use .js
files
One big file doesn't take advantage of the browser's ability to load a larger JS file as lets say 3 smaller files on 3 different concurrent connections during that critical initial page load when people enter your website
Logically group functions in
different files such as files for
validation, presentation and calculations as this makes it easier to maintain as file sizes increase
Use JSMIn (Javascript Minifier) to reduce file sizes http://www.crockford.com/javascript/jsmin.html

Categories