I have a huge script with messy dependencies to other js files.
My problem is, I need to include the script on various pages but not the other js files. and it stucks when some of variables are there which are defined in other files, I can handle them one by one but just have not enough time to do so.
I want to know is there any mechanism just like php autoloaders in javascript so whenever it gets something undefined, I can hook a chunk of code to handle that.
This is probably not the actual concrete answer you're looking for, but it seems to me like you'd be better of spending some time refactoring the code, and in the process of that you might want to look at some modular JavaScript patterns. I myself use RequireJS to handle dependencies etc.
I would recommend reading the following article: Writing Modular JavaScript With AMD, CommonJS & ES Harmony
I know you said that you haven't got the time, but consider taking the time anyways - it will help you to have the architecture in place when needing to maintain the code in the future.
Related
I am working on an old enterprise solution with these properties:
The solution has a MVC web application
The solution has a WCF service layer
The solution has javascript in the database, in the form of functions in a database column
The web application retrieves said javascript through the service layer and plugs it into certain pages
My team cannot modify the web application, nor the service layer
My team must write javascript by inserting functions into said database columns
This architecture leads to:
A very inefficient development loop
Very poor source control
I'd like to propose a solution for them, how to upgrade this, but here's where I fall a bit short on experience. My suggestion would be:
Migrate the javascript from the database to javascript files
Make some sort of hook in the web application for other teams' javascript files
My questions are:
Has anyone had this kind of problem and how did they solve it?
Is there an effective way to do this kind of javascript migration into files? My idea would be to write a small console program to do the migration
How would they make a hook to import our javascript files? My idea is to make a script bundle with some naming convention, so we can add scripts without them needing to change their code. Are there problems with this approach?
Any kind of input would be invaluable.
Edit:
Additional explanation:
The mechanism maps the javascript function names to a certain DOM elements' event attributes and inlines the code right after the element
The functions are standalone functions, depending only on libraries already in the web application
The functions are grouped by a common form
So I suppose it would be better to group them into files bearing the form names.
If these are just simple, static function definitions being inlined into the web page, then I suppose it might be possible to serialize/aggregate them all into a giant file and run something like prettier on it to make it readable.
That wouldn't be ideal to gain traction in your proposed migration, though. If the code has any volume to it at all, it would be nice to give some structure and order to maintain it.
It's already kind of a huge assumption that this javascript is just pure functions without any complex dependencies on each other, but it's possible that these pieces of Javascript work in isolation already if they are being pulled out of a database. It's hard to know without knowing more context. It seems unlikely that your life will be that easy.
If you managed to extract this monolithic Javascript file, the easiest thing to do would be include it in a script tag for the entire site and be done with it. This could be a bad idea if the file is getting to the ~MB size and slows your initial page load time.
Then again, the point at which you have a bunch of functions in one file, you could probably do a lot there to optimize and reduce duplication of code.
This is still all conjecture because I don't know the mechanism by which your web application imports the javascript once it retrieves it from the database.
I have recently started looking into webpack, because of cool features that enable writing true CSS modules, and smart bundling and stuff, and there is HMR, thats why I am here. I have seen examples of React Redux projects that made it possible to update javascript code without reloading browser. WOW, I thought it is impossible.
I wanted to know more, especially how it works under the hood, to make it work with my current project which is Vanilla JS.
In the mean time, my interest in functional programming languages brought me to Emacs. I have found out that there is a skewer-mode available in emacs editor that do update javascript and HTML! in real-time without realoding browser.
I know that they both use local server to push the changes to the browser and some script on client that somehow updates the code. But how do they preserve the state of application. In terms of React projects its kind of imaginable, because of component based nature of apps, you can just replace component with new one, but I am not sure how do they search for variables and reassign new values to them. Maybe they do use some eval magic. But I am not sure.
So how do they exactly work? Maybe I am looking from the wrong angle, I just don't have a clear picture.
Emacs has live update of HTML too, can webpack HMR do that?
(I don't care much about HTML because I do it in JS. But I think it can explain difference between these two.)
Which is better in doing so?
What is the pros and cons of each or are they just different parts of the world and can be integrated to become something even better?
Maybe there is a even better options without the need of middleware like local webserver, but just editor plugin communicating with some browser extension?
P.S.: I don't mind learning tools that can optimize my work, because it always pays off.
So how do they exactly work?
From the Webpack HMR documentation,
In general the module developer writes handlers that are called when a dependency of this module is updated. He can also write a handler that are called when this module is updated.
Each module type needs update logic written for it.
From the skewer-mode repository,
Expressions are sent on-the-fly from an editing buffer to be evaluated in the browser, just like Emacs does with an inferior Lisp process in Lisp modes.
Your code is sent to the browser as a string, and runs through a global eval.
Which is better in doing so? What is the pros and cons of each?
If you use libraries that have HMR plugins written for them, it might be worth using this feature. Libraries without HMR hooks will not benefit from it. Webpack's HMR seems extremely complex, and its documentation and its plugins warn about HMR's "experimental" state. Therefore, it is probably not reliable, and thus could be counter-productive to your development. For instance, the reloading modules need to correctly clean up the non-reloading ones. What if some script adds listeners to window or document and doesn't provide a way to remove them?
If you want your text editor to serve as an additional REPL for your browser, then you can use skewer-mode. To effect any change in your application, some part of it must be exposed via a global variable. Maybe you export one global object with a bunch of submodules attached to it, e.g. window.APP = {}, APP.Dialog, APP.Form... or, maybe you just release hundreds of implicit global variables and functions into your environment. You can see changes in your application by evaluating the definitions of these modules / functions / variables, and then evaluating some code that uses them, e.g. by calling a function APP.initialize() which bootstraps your app, or by triggering a redraw in a view library you use (usually by performing a user action like clicking an element).
If your application is not written such that it can be modified in a browser console (e.g. if you use a module compiler like Browserify or Webpack, which wraps your code in one big closure), then you won't be able to do much with skewer-mode. Also, consider whether it would be faster to manually eval code snippets / files and re-run initialization code (and potentially create impossible application state that you will waste time debugging), or to just refresh the page and recreate your previous state.
The benefit you gain from either of these tools is heavily reliant on the way your application is structured. I can see them creating pleasant development workflows under exactly the right conditions (what I describe above). Otherwise, they seem too likely to cause harm to be worthwhile.
I have some html files that I need to do automated processing on, basically regex replaces, but also some more complex actions like copying select blocks of text from one file to another.
I want to create a series of scripts that will let me do this processing (it will need to be done more than once on different batches of files). It would be trivial to use Go for this (read the file into memory, regex, save to disk) but I am the only member of the project that's familiar with Go.
Javascript is a tad more ubiquitous, and I do have project members who are familiar with the language, so it's a better fit in that respect. If I'm not around later, someone else could edit the scripts.
Is there a simple way to write some JS scripts to do on-disk text processing? I'm looking for a cross-platform solution (OSX, Windows). Ideally, once the scripts are written, they can be executed by double-clicking an icon--there will be "not computer people" involved at some point.
Also, I'd like to be able to do some kind of alert/message box to inform the user of the success/failure of the script. (This may be a tall order, and is of secondary importance.)
What I've looked at:
Node.js was the first thing that popped into my head, because I know that it has file system access tools, and obviously regex capacity. But I've never used Node before, and based on the tutorials I've read, it seems like overkill for something this simple.
There's a whole slew of "javascript compiling" tools that you can find by googling around. Some are not cross-platform, some seem old or not actively maintained, etc. None of them caught my eye as easy to pick up and just write some JS scripts with.
Any thoughts?
Node.js is a simple solution and with it's framework you can create or later modify your script to your needs. This way you will not be locked down by someone else's code. And it is not that difficult to to use.
Here is a quick tutorial on accesing files using node.js
http://www.sitepoint.com/accessing-the-file-system-in-node-js/
And here is a quick tutorial on using a node module called Cheerio. It allow you to access html files using "jquery like syntax". You don't need to use regex.
http://maxogden.com/scraping-with-node.html
I worked on a project for a client once and it required parsing thru hundreds of html files to check and replace certain image files based on certain criterias. I wasn't familiar with node at the time so I read some tutorials and wrote the script in about an hour.
And as long as Nodejs' path is set, you can run it on the command line.
Some tips:
You need any kind of DOM HTML parser, not only JS nor specifically JS.
You can do that thing with Java with use of jTidy or jSoup libraries (I've used second one few times). It's pretty simple language to learn if you know JS and IDE like Netbeans helps a lot. So can be made quickly with that.
You can use PhantomJS to create some job files and create shell/batch code to run them on some files. You might need to write a generator for job files (like taking a list of files, creating job files for each and running them).
You can use Node.js which isn't much overkill, I'm sure any solution won't be trivial.
You can create an ETL for processing with for example Pentaho ETL (which has JS embedded as one of two scripting languages... but without DOM parser - for that one you would need to use a bit of Java there and some library in way similar to this article).
You can also do that with PHP with Simple HTML DOM Parser - so you can make a service online (or on local server) that takes those html files and throws out processed ones.
First I think you underestimate the complexity. The statement
"It would be trivial to use Go for this (read the file into memory,
regex, save to disk) but I am the only member of the project that's
familiar with Go."
is probably false. Parsing HTML with RegExp is just a bad idea. (Google it and you will see why)
Second, if you can trivially write the code using RegExps in Go, you can just as easily write the same thing in Javascript. They both support RegExp and file operations. If you are unsure about the Javascript/Node.js details, I suggest writing the trivial solution in Go and then translate the thing into Javascript with a colleague.
Since Javascript is a script language, writing command line utilities in Node.js is straight forward.
Some pointers to get you started
RegExp in Javascript
Building command line apps in Node.js
I have a javascript file that is about 5000 lines long and may grow bigger in the future.
I have been going through it by myself to try to figure out how to break it up and make it more modular / object oriented.
however, I would really appreciate a tool of some kind that can help me find problems more quickly.
I have heard of google closure and I downloaded it. However, when I feed my large javascript file into the compiler I get a lot of stuff changed and returned to me.
I don't want to make SO much change that I can't understand the code. How do I approach this problem? Should I only feed into the compiler small portions at a time ?
The best way to do this would be to use RequireJS and then use the AMD optimizer (r.js) to combine and optimize your code. You can also use the Closure compiler along with r.js to optimize your code further. I did this exact thing recently for a personal project, where I was working with a large JavaScript file. I was able to successfully modularize it and optimize it using RequireJS, r.js, and Closure.
Expect to spend sometime bringing yourself up to speed with RequireJS concepts. It took me a little while to figure out what I needed to be doing.
Closure compiler won't make a program more maintainable. Your code becomes input to Closure Compiler which spits out JavaScript for your browser. It can improve the efficiency (both in terms of size as well as removing utilized variables) and making your code compatible with the "advanced" mode can have the side benefit of forcing you to write more modular code which is by its nature more maintainable.
I've been doing research on this:
Using Rails 3.1, where do you put your "page specific" javascript code?
But I have yet to see a satisfactory answer, which also makes me question whether I'm doing something wrong.
Here's my mental model: for different views, I'm going to have different
$(document).ready(....)
blocks, that obviously reference elements that are very specific to that page. I don't want to pollute things by loading that code for every single page and somehow trying to figure out how to only execute it when on specific pages; that seems pretty ugly.
My intuition, admittedly not backed up by any preliminary experiments, is that the ideal thing would be to:
Load application wide code from application.js.
Load shared controller code from something like assets/controller_name/shared.js
Load view-specific code from something like assets/controller_name/show.js
Off the top of my head. The helper would, the first time it ran, check if the file exists and, if so, do a javascript_include for it.
Perhaps this has some performance issues compared to the "let's just wrap the whole thing up in a big sticky ball and send it all" approach, but seems like a better approach to compartmentalizing code.
However, as above, I get the feeling I'm missing something. Is $(document).ready on a per-page basis a bad idea? Should that just be in the template and call a page specific bit of JS from application.js? The linked article above comes to that conclusion, but I don't like the image I'm getting in my head of one huge $(document).ready riddled with if this, if that, if the other thing.
What you propose is sound, but not the rails 3.1 way.
They say to divide the JS into many files, but serve as a whole single piece to the user. This allows better performance and scalability, so is a good thing if the final big piece of mud is not so big. Really 3 http requests give worse performance than 1 http request.
So you have already dipartimentized your code, because you have different Coffeescript files, which have different scopes.
To load in your app, just standardize a way to initialize the single piece of code, like calling a "myapp.users.init()" method-.
You could even automatize that peace of code using an helper, so it will be transparent for the controller.
Background
(Why Use The Asset Pipeline At All?)
One of the basic premises behind the Rails asset pipeline is the idea that it is preferable to load all the JS and CSS for a site up front once, and then cache them indefinitely (at least until the site is updated). The Asset Pipeline allows you to do this relatively automatically while still organizing your JS and CSS src files in a logical fashion.
This of course carries an upfront load cost, at the promise of saving time on additional roundtrips loading individual files. If that premise doesn't sit well then the asset pipeline is probably not for you.
The Nut Of The Problem
Ok, so we want to combine all our JS into one file to load it more efficiently. Just because we are going to load all of our JS doesn't mean we want to run all of our JS.
In the reality of a complex webapp you will probably have lots of page specific functionality that you won't want to spend resources executing when the user is not viewing the corresponding page. What we need is a uniform strategy for executing only the portion of our big monolithic JS file that is applicable to the current page.
Convention To The Rescue
I'm not aware of an official Rails strategy to deal with this, but there are some great solutions that establish and then leverage a good convention (which makes things feel "railsy"). The general idea is to define all your page specific JS code into an object literal, and then run only the code relevant to the current page on load.
For the specifics great strategy on how to organize and conditionally execute your JS code, see the answer by #welldan97 on this question:
Using Rails 3.1, where do you put your "page specific" javascript code?
which in turn is based on this article by Jason Garber:
http://viget.com/inspire/extending-paul-irishs-comprehensive-dom-ready-execution