gulp-sourcemaps Keep Intermediate Files - javascript

When I use the gulp-sourcemaps plugin, I typically have both the comment and content removed so the sourcemap header is used instead. This makes it much easier to show the original files in the browser debugger in development and staging, then remove it in production. We also try to load sourcemaps wherever possible, mostly for vendor libraries.
This works fine for the most part. However, intermediate files seem to be lost. I am guessing the loadMaps option to sourcemaps.init(), which allows for loading existing maps, removes the intermediate files when it gets their maps. This is likely fine for most cases, as the original files are there, but too often libraries only include the output file with maps added as a comment, but don't include those original files. This means we don't have access to the original files, and the browser does not have access to the built library file.
For example, angular-ui-router is written with TypeScript, then output to JavaScript when built. This means the end developer does not have to compile with TypeScript in his/her build process, as this is already done in the ui-router build process. Now, the output JavaScript file is accessible at <server root>/node_modules/#uirouter/angularjs/release/angular-ui-router.js, and the original TypeScript files were, according to the built file's sourcemap comment, in the <server root>/node_modules/#uirouter/angularjs/node_modules/#uirouter/core/src and <server root>node_modules/#uirouter/angularjs/src folders.
When I include the angular-ui-router file into a vendor.js or vendor.min.js file using my favorite tool, it bundles the angular-ui-router maps into the resulting .map file, but does not include the <server root>/node_modules/#uirouter/angularjs/release/angular-ui-router.js file as a source. This means we can't see either that file, or the TypeScript files, which makes debugging pretty much impossible using only the browser. To make matters worse, any errors we get are sourcemapped all the way back to the TypeScript files. We don't have the TypeScript files, so we can't look there, and now we don't know where in the JavaScript the error is, either! Thankfully, angular-ui-router doesn't have many complex errors, and the ones it does have are nicely documented, but other libraries are not so helpful.
Is there a way to include intermediate files as sources in the output sourcemap? Otherwise, is there an easy way to load some sourcemaps with something like loadMaps, but not others?

Related

Is there any performance gain from renaming a minified file to have the *.min.js extension?

I have a minified angular-ui-bootstrap file that I'm including inside my angular application. Right now it's named foo.js even though the contents of the file itself is minified javascript. If I rename the file to foo.min.js, does that make any difference? Does the server see the min.js extension and somehow serve the file faster or is renaming the file simply a matter of semantics so other programmers know it's a minified file without opening it?
It's for semantics. It can make troubleshooting or build process analysis easier. It also helps with build tools like Grunt or Gulp which read in a file and output a file.
There is no performance benefit based on the file name. The performance benefit comes from the fact that the minified file is smaller. That's all.

Javascript bundling and module loading

I've recently been thrown in to clean up a project which has like 45-50 individual .js javascript files. I wonder what the best approach would be to decrease the loading size of them all. Just concatenate all files into one with npm or gulp? Install some module loader? webpack?
If you're already concatenating, minifying, and uglifying and you don't want all the files to be loaded on all the pages due to a monolithic bundle, you might be looking for something like Webpack's Commons Chunk Plugin.
This plugin walks down the tree of dependencies for each endpoint defined in your Webpack.config file and determines which modules are required across all pages. It then breaks the code into two bundles, a "common" bundle containing the modules that every page requires, which you must load with a script tag on each page:
<script src="commons.js" charset="utf-8"></script>
And an endpoint bundle for each individual page that you reference normally in a script tag placed after the commons script tag:
<script src="specificpage.bundle.js" charset="utf-8"></script>
The result is that an individual page will not have to load modules that will only ever be used on other pages.
Again, this is a Webpack plugin. I don't know if this functionality is available as a Gulp plugin, because it must have knowledge of all endpoints in order to determine which dependencies are common to them all.
I redirect you to the very good https://github.com/thedaviddias/Front-End-Checklist
In particular the following advises:
JavaScript Inline: High You don't have any JavaScript code inline
(mixed with your HTML code).
Concatenation: High JavaScript files
are concatenated.
Minification: High JavaScript files are minified (you can add the .min suffix).
You can accomplish this with a package manager such as gulp, grunt or webpack (for the most famous ones). You just need to choose what you prefer to use.
If you consider webpack, You can start with my very simple (but understanding) starter: https://github.com/dfa1234/snippets-starter
There's no much thing that you can do, basically is:
Concatenation - https://www.npmjs.com/package/gulp-concat
Minification - https://www.npmjs.com/package/gulp-minify
Instead of creating all those scripts, you can get something to re-use on yeoman, f.e. the Fountain, so it will reduce a lot of time just typing procedural code for doing the concatenation/minification.
Also if you can use some lazy load (like RequireJS or some frameworks have support to lazy load the module, like Angular) that will improve the performance of your aplication
EDIT:
If you want even more performance, you can install some compression tool in your server, for example this one for NodeJS https://www.npmjs.com/package/compression
I'm my personal opinion, if you have time, the best approach would be to read and understand the purpose of the project. Then plan a proper refactor. You are not fixing anything with concatenating, this is just a deployment step.
You should analyze which technologies are being used and if you want to maintain this code, in the long run, make a proper refactor into a much more modern stack, maybe you can take a seed project with ES6, webpack, Babel... and create a proper repository well maintained with proper modularity and dependencies resolution.
Once you have that, decreasing the load its just about adding proper tools in build time (babel, webpack, etc).
You would like to add some unit tests and continue working properly :)

VS2013: Publish minified bundle created on files outside of the project

I use Visual Studio 2013 and .NET 4.5 for an MVC project.
I've learning to use AngularJS via several videos on Pluralsight and one of them walks through the process of using Grunt to clean the output directory, then use ngmin to min-safe the Javascript files.
My process is using a gruntfile.js to clean and run ngmin against the javascript files in my solution, then put them in a directory called app_built. This is executed via a batch file in the pre-build for the project and then I include it via a ScriptBundle with IncludeDirectory pointing to the app_built directory. My intent is to use the Bundling features of .NET 4.5 to do the rest of the minification and concatenation of the Javascript after all the files have been min-safed via Grunt.
I specify the path to the min-safed files with the following:
bundles.Add(new ScriptBundle("~/bundles/minSafed")
.IncludeDirectory("~/app_built/", "*.js", true));
If I run this on my local machine, it runs fine without a hitch. The Javascript is minified and bundled as I'd expect and the resulting web application runs fine as well.
If I publish the website to a remote server, I get a server error that the "Directory does not exist. Parameter name: directoryVirtualPath". I assume this error is saying that it's unable to find the directory populated with my many *.js files. I also assume this is because they weren't published since they aren't part of the solution, even though the folder they reside in is a part of the solution (it's just empty within the solution explorer in Visual Studio).
If my assumption is correct, what can I do to add these files to my solution so they'll be published with the rest of my web application with minimal effort on my end each time?
And if I'm incorrect in the assumption, what I can I do to resolve this otherwise?
Thanks!
I never did find a great way of going about this. I found information at http://sedodream.com/2010/05/01/WebDeploymentToolMSDeployBuildPackageIncludingExtraFilesOrExcludingSpecificFiles.aspx that seems related, but I was unable to make it work.
Rather, since I knew the name of the outputted file, I simply created such an empty file in my project and referenced that where I needed to. I then had the pre-build task replace the contents of that file with the externally minified version and it would be packaged with the project as necessary, so it works well enough.

How to get r.js optimizer to combine all modules in a project into one file?

From experimenting with the r.js optimizer, it seems that there is no way for your final index.html file to just reference a single script and never make any async calls to other scripts during the lifetime of a user's session (unless they reload the page of course). From my experience, it looks like it creates a bunch of combined groups of optimized files which can be referenced when needed? This seems counterintuitive to most combine scripts where you end up with just one combined/optimized js file that is in the correct order. Can anyone help explain my issue?
Yeah, that's how r.js works, it optimize your dependencies into one or multiple file (you'd use include option to get all your file togheter).
Although, this build will keep require.js script file out of the build. But, after the build, you can combine require.js (or minimal AMD implementation like almond.js) at the top of your builded file and it will all work mostly fine (some problem may occur depending on how you bootstrap your app, but most of the time those issues are pretty easy to resolve).
To combine the files easily, you can use tools like grunt.js (I really recommend it to you as it can do much more and is really a must have in frontend developpement workflow). If you work with backbone app, you can checkout (Backbone Boilerplate)[https://github.com/tbranyen/backbone-boilerplate] and their grunt implementation.

Javascript compiler / dependency manager?

I have many JS files. Some of them depend on each other. Many of them depend on jQuery.
I need tool that can accept one file as parameter, fetch all its dependencies transitively and compile them into one file in proper order (based on dependencies)
Dependency information not always available inside files itself, so it would be nice to have it somewhere outside (xml file? folder structure?)
I've heard about Yahoo JS compiler, closure and so on, but I am not sure they do what I need.
Look: I have module "CustomerPage". It sould include "validation.js" and "gui.js". Both require jquery.js. And "gui.js" also requires "myFunctions.js".
I want some ant task or some script that would generate "CustomerPage.js" as result of all that files.
Tool should check dependency order, prevent double including and so on.
My project could have around 500 js files, how could I live with out of this tool?
People says "use GWT", but I need plain JS.
You might want to look at one of the AMD-style module loaders, such as RequireJS. Some of these can do what you want for precompiling, and can run in a development mode which makes it easier to debug by including all the files directly.

Categories