Anybody used LabJs in conjunction with javascriptmvc steal? meaning looking for dependency loading in child level as well as taking advantage of LabJs async performance gains.
a.js
.....
steal(../b.js)
.then(../c.js) //c.js requires b.js and d.js to be loaded before it can load
b.js
.....
steal(../d.js) //(need to load d.js when b.js invoked, loading d.js for better classification and maintenance )
Any articles or experiences for labjs + steal will be great.
steal is going to build your production app into a single JS file. You can load that file however you want.
setting aside that steal builds a single file for you for the moment...
the concept of annotating dependencies nested inside each script means that, by itself, you cannot take full advantage of parallel loading, because the loader doesn't know what scripts that A depends on until it finishes loading A and can see that it needs B and C. Of course, once it knows about B and C, it can load those two in parallel, but it cannot load B and C in parallel with A.
the other issue is that LABjs (and most other dynamic script loaders) has, strictly speaking, non-blocking behavior, so if you load some scripts like this, you will have an issue:
A
-- depends on B and C
D
-- depends on A and E
When A finishes loading, and then you start loading B and C, you can't natively (without extra pre-effort) make D wait until B, and C (and thus A) are done.
The reasons behind this are quite complicated to explain, but suffice it to say, that scenario is problematic for dynamic loading with nested dependency annotation.
However, if you know about the dependency tree at the beginning (that is, you don't wait to load scripts to find out about their nested dependency annotations), you can easily take advantage of dynamic parallel loading while making sure order is preserved. You can easily do this:
B
C
A
E
D
and load all 5 of them in parallel, while still making sure they execute in that proper order as noted. The best way to figure out that dependency tree and the necessary order of execution is to have a build process that walks through all your scripts and figures out what the list is and its necessary order.
Using LABjs, that chain above would look like this:
$LAB.setOptions({AlwaysPreserveOrder:true}).script([B,C,A,E,D]);
Pretty simple and straightforward, assuming you know at the outset what that list/order is. Just have your build script drop that one line of code into your HTML page, and boom, you're good.
If you don't have such a build script to do that (I have my own that I've built for my various projects that need this type of thing), you have two choices:
Don't use nested dependency annotation. Manage your list of dependencies (the above list) yourself, and make sure it's in the right order. For a decade or more, that's how people using script-tags in browsers have worked just fine, so it's probably quite sufficient for the majority of sites. I have LABjs chains on many of my sites that I manage manually, and it's no problem at all, as do thousands of other sites which use LABjs.
Use a build script (like Steal) that just puts them all in one file (of course, it has to figure out the proper order too!). You don't get the parallel loading benefit. Bummer.
Hopefully this sheds some light on the issues at hand.
Related
I really like the way NodeJS (and it's browser-side counterparts) handle modules:
var $ = require('jquery');
var config = require('./config.json');
module.exports = function(){};
module.exports = {...}
I am actually rather disappointed by the ES2015 'import' spec which is very similar to the majority of languages.
Out of curiosity, I decided to look for other languages which implement or even support a similar export/import style, but to no avail.
Perhaps I'm missing something, or more likely, my Google Foo isn't up to scratch, but it would be really interesting to see which other languages work in a similar way.
Has anyone come across similar systems?
Or maybe someone can even provide reasons that it isn't used all that often.
It is nearly impossible to properly compare these features. One can only compare their implementation in specific languages. I collected my experience mostly with the language Java and nodejs.
I observed these differences:
You can use require for more than just making other modules available to your module. For example, you can use it to parse a JSON file.
You can use require everywhere in your code, while import is only available at the top of a file.
require actually executes the required module (if it was not yet executed), while import has a more declarative nature. This might not be true for all languages, but it is a tendency.
require can load private dependencies from sub directories, while import often uses one global namespace for all the code. Again, this is also not true in general, but merely a tendency.
Responsibilities
As you can see, the require method has multiple responsibilities: declaring module dependencies and reading data. This is better separated with the import approach, since import is supposed to only handle module dependencies. I guess, what you like about being able to use the require method for reading JSON is, that it provides a really easy interface to the programmer. I agree that it is nice to have this kind of easy JSON reading interface, however there is no need to mix it with the module dependency mechanism. There can just be another method, for example readJson(). This would separate the concerns, so the require method would only be needed for declaring module dependencies.
Location in the Code
Now, that we only use require for module dependencies, it is a bad practice to use it anywhere else than at the top of your module. It just makes it hard to see the module dependencies when you use it everywhere in your code. This is why you can use the import statement only on top of your code.
I don't see the point where import creates a global variable. It merely creates a consistent identifier for each dependency, which is limited to the current file. As I said above, I recommend doing the same with the require method by using it only at the top of the file. It really helps to increase the readability of the code.
How it works
Executing code when loading a module can also be a problem, especially in big programs. You might run into a loop where one module transitively requires itself. This can be really hard to resolve. To my knowledge, nodejs handles this situation like so: When A requires B and B requires A and you start by requiring A, then:
the module system remembers that it currently loads A
it executes the code in A
it remembers that is currently loads B
it executes the code in B
it tries to load A, but A is already loading
A is not yet finished loading
it returns the half loaded A to B
B does not expect A to be half loaded
This might be a problem. Now, one can argue that cyclic dependencies should really be avoided and I agree with this. However, cyclic dependencies should only be avoided between separate components of a program. Classes in a component often have cyclic dependencies. Now, the module system can be used for both abstraction layers: Classes and Components. This might be an issue.
Next, the require approach often leads to singleton modules, which cannot be used multiple times in the same program, because they store global state. However, this is not really the fault of the system but the programmers fault how uses the system in the wrong way. Still, my observation is that the require approach misleads especially new programmers to do this.
Dependency Management
The dependency management that underlays the different approaches is indeed an interesting point. For example Java still misses a proper module system in the current version. Again, it is announced for the next version, but who knows whether this will ever become true. Currently, you can only get modules using OSGi, which is far from easy to use.
The dependency management underlaying nodejs is very powerful. However, it is also not perfect. For example non-private dependencies, which are dependencies that are exposed via the modules API, are always a problem. However, this is a common problem for dependency management so it is not limited to nodejs.
Conclusion
I guess both are not that bad, since each is used successfully. However, in my opinion, import has some objective advantages over require, like the separation of responsibilities. It follows that import can be restricted to the top of the code, which means there is only one place to search for module dependencies. Also, import might be a better fit for compiled languages, since these do not need to execute code to load code.
From a performance/maintenance point of view, is it better to write my custom modules with netsuite all as one big JS, or multiple segmented script files.
If you compare it with a server side javascript language, say - Node.js the most popular, every module is written into separate file.
I generally take the approach of Object oriented javascript and put each class in a separate file which helps to organise the code.
One of the approach you can take is in development keep separate files and finally merge all files using js minifier tool like Google closure compiler when you deploy your code for production usage which can give you best of both worlds, if you are really bothered about every nano/mini seconds of performance.
If you see SuiteScript 2.0 architecture, it encourages module architecture which is easier to manage as load only those modules that you need, and it is easier to maintain multiple code files i.e. one per module considering future enhancements, bug fixes and code reuse.
Performance can never be judge by the line count of your module. We generally maintain modules for maintaining the readability and simplicity of the code. It is a good practice to put all generic functionalities in to an Utility script and use it as a library across all the modules. Again it depends on your code logic and programming style. So if you want to create multiple segments of your js file for more readability I dont think its a bad idea.
I tried fay-jquery and the included sample test.hs file results in whooping 150 kb of js file.
Even with closure compiling it is still 20 kb.
I understand that it must carry a runtime, stdlib and jquery wrappers with it.
I can tell fay not to generate stdlib (--no-stdlib and --no-builtins flags).
But i do not know how to tell it not to include jquery code.
So my question is, how can i split those static parts into a separate js file and only generate module specific code?
This way large parts of code will be loaded only once (and cached) and i can create many smaller js files for separate web pages.
Yes it's safe to split modules up, as of Fay 0.16 all modules can exist standalone (before that you could still have the runtime and fay-base separate). There are some flags for this, --print-runtime and --no-stdlib. Compile with optimizations (-O, this increases the output size, but closure will be able to minimize it even better).
Also remember that the web server should gzip this. That brings the code size down to 4.5kiB. That's pretty decent, right?
You might want to consider putting all of your javascript in one file, that means a slower initial load but then users will have it cached for future page loads.
The reason the file size is so big is that fay-jquery has a lot of FFI bindings which produce a lot of transcoding information. I think fay-jquery could be optimized a lot here to for instance use Ptr JQuery rather than just JQuery in the types, or by figuring out that a lot of this is unnecessary while compiling, or abstracting the conversions more in the compiler's output.
Another possible issue I realized a couple of days ago is that the output is now in the global scope rather than in a closure, which might mean that google closure can't remove redundant code as well as previously (haven't had time to investigate this yet). The modules generation should perhaps be changed to produce a closure for each module.
Also see Reducing output size on the wiki.
I would appreciate any reasonable explanation of the use of BundleConfig and Require.js together in a SPA. How do you choose which scripts should be loaded by BundleConfig when starting the app? Which scripts should NOT be called in BundleConfig and selectively loaded via AMD? Once loaded by BundleConfig, do they have to be called again in require.js' DEFINE statement?
Search as I might, I simply can't find a simple explanation for all this.
Thanks!
BundleConfig will help you get all the script sin the bundle to the client together, in 1 trip. This takes the burden or job off of require.js for that. I often do this for 3rd party scripts, since it is highly likely i need them all client side right away anyway.
Then I can choose to either use require.js to load my scripts as needed (thus AMD) or bundle them too, up front.
Require does not just load things asyncly, though. It also handles the dependency resolution. To me, this is the more important part. It makes sure before I use module A that if it depends on B, which depends on C, which depends on D is resolved first. So they get loaded and run in the proper order.
So whether you use bundling or not, the require.js dependency aspects as super valuable.
I'd like to use #Grape in my groovy program but my program consists of several files. The examples on the Groovy Grape page all seem to assume that your script will consist of one file. How can I do this? Should I just add it to one of the files and expect that the imports will work from the others? If so, then is it common to place all the #Grape calls in one file with no other code? Do I need to add the Grape call to all files that will import the package? Do I need to download the JAR and create a Gradle file, which I was getting away without at this point?
the grape engine and the #grab annotation were created as part of core groovy with single file scripts in mind, to allow a chunk of text to easily become a fully functional program.
for larger applications, gradle is an awesome build tool with lots of useful features.
but yes, you can manage all the application dependencies just with grape.
whether you annotate every file or a single one does not matter, just make sure the #grab annotated file is read before you try to use the external class.
annotating the main class is probably better as you will easily lose track of library versions if you have the annotations scattered.
and yes, you should consider gradle for any application with more than a dozen files or anything you might want to reuse elsewhere as a library.
In my opinion, it depends how your program is to be run...
If your program is to be run as a collection of standalone scripts, then I'd probably stick the #Grab required for each script at the top of each of them.
If your program is more of a standard style program with a single point of entry, then I'd go for using a build tool like Gradle (as you say), as you get a lot of easy wins by using it.
Firstly, it makes it easy to define your dependencies (and build a single large jar containing all of them)
Secondly, Gradle makes it really easy to start writing tests, include code coverage plugins, or useful tools like codenarc to suggest possible fixes or improvements to your code. These all become invaluable not only for improving your code (or knowing your code works), but also when refactoring your code, you know you've not broken anything that used to work.