rake-pipeline or requirejs - javascript

I am about to start a new emberjs project and I cannot decide whether to use requirejs or rake-pipeline.
The ember advice seems to be to use the rake-pipeline.
Anybody any thoughts on either side of the argument?

If you want to load the dependencies dynamically after page load on an as-and-when-required basis then requirejs is the preferred option.
However if loading all the script when the page loads is not an issue for you (amount of javascript is small, or lot of javascript is required just for the rendering of content) then rails asset pipeline reduces a lot of boilerplate for you because even if you use require js you will eventually have to use r.js compiler to bundle all the dependencies into a single script. Rails does all of this concatanation and minification transparently behind the scenes without you having to do anything at all. Using the rails asset pipeline eases rolling deployment for you because in development scripts are all served as individual files without minification and in production scripts are served as minified and concatenated. This does not require you to run any build script or optimizer upon every change and you don't even have to modify anything in your HTML files. As long as you follow the sprockets specifications and specify the dependencies (which you have to do in case of requirejs too) everything works out of the box.
Also, Rails asset pipeline does not tie your client application to rails platform as sprockets (the dependency manager used behind in the rails pipeline) can be used independently without rails.
If however AMD compatibility is important for you (for example you are planning on using the same code on a NodeJS server as well as client, or are creating a distributable library) then requirejs is a great option.
You can also take a look at https://github.com/jwhitley/requirejs-rails/ which attempts to integrate requirejs into the rails pipeline. Please make sure that you have a reasonable level of familiarity with both requirejs and rails before you adopt this approach.

Related

Rails 5.2+: why still use assets pipeline with webpacker?

I was reading the Rails webpacker gem documentation where it says:
Webpacker makes it easy to use the JavaScript pre-processor and bundler webpack 4.x.x+ to manage application-like JavaScript in Rails. It coexists with the asset pipeline, as the primary purpose for webpack is app-like JavaScript, not images, CSS, or even JavaScript Sprinkles (that all continues to live in app/assets).
However, it is possible to use Webpacker for CSS, images and fonts assets as well, in which case you may not even need the asset pipeline. This is mostly relevant when exclusively using component-based JavaScript frameworks.
I'm trying to understand the rationale behind using both the older assets pipeline for CSS/images/JS-sprinkles if webpacker is capable of handling all of this?
I've read some other articles that walk me through using webpacker for all of this, but I don't understand the reasoning behind this decision.
Is this just to support legacy applications and eventually the older assets pipeline will go away and webpacker will be used for everything in Rails apps?
As a maintainer of an app that existed before Webpacker, I can give you one reason:
It's hard to migrate an existing frontend from Sprockets to Webpack.
Sprockets builds all JS into one big file with shared scope. Webpack isolates the scope of every JS module. To migrate to Webpack, you need to make sure your code still works with the scope isolation.
Which is often problematic, because in the Sprockets times you didn't have proper JS requires, either, and had to rely on globals or top-scope variables to share code and data between your JS source files.
Rails doesn't offer a painless transition path from Sprockets compilation to Webpack. So, it must support both.
But to answer your other question - going forward, you should use Webpacker if you have enough JS to make it worthwhile.
If your frontend is simple, you will skip some JS nuisances if you use Sprockets. Like if you want to add 10 lines of JS to your app, you might not want to setup a whole JS environment with dependency management and node_modules etc - which is the price of using Webpack/Webpacker. It would be even more senseless to manage a JS environment if all you want is to compile CSS and add digests to your image filenames - which Sprockets is perfectly capable of, without a package.json and anything else JS related.
Therefore, there's a second reason:
Webpacker is good for apps that have a significant frontend codebase. Sprockets is good for adding a bit of JavaScript to a traditional server-rendered app, and for apps with no JavaScript at all.

Load external libraries from CDN with angular-cli

I would like to use the angular-cli to build an app that bundles my app code but does not include the Angular2 framework or other large external JavaScript libraries in the bundled code. I would like to load these libraries from a CDN when the page loads. Is there a way to do this?
Also, is there a way to do this while preserving the benefits of a local build where only the parts of the Angular2 framework that I am using gets loaded?
I saw this question, but it was for SystemJS and I don't think it applies to Angular-cli: How to load angular2 using CDN and SystemJS
You simply need to add the appropriate <script src=""> tags pointing to the CDN to the index.html file.
Remember to remove the .js files from angular-cli.json so they don't get bundled with the app.
Currently, you can't do that for the Angular 2 js files itself, they are automatically bundled with your app. Though the latest updates enable the web servers and browsers to cache the vendor files, so they don't get redownloaded on every visist to your app but only when the hash changes.
When creating an application with Angular, version 2 or greater, uses a build system that only includes the portions of the Angular platform you use. Templates can be compiled at build time, allowing the build process to remove the template compiler from your bundled payload. Finally the build process does tree-shaking with the help of static analysis of your code, which further removes from the payload bundle unused portions of the platform.
If you provide Angular from a CDN, it would need to be the kitchen sink, the entire platform. This would be huge and a detriment to your application.
You are much better off allowing angular-cli bundle the portions of the platform that you need. As the WebPack treeshaking plugin improves your bundle sizes will get smaller.
I would add your whole app to a CDN such as Akamai. For example (depending on how your app is structured) you could cache files such as the ones in the below list...
index.html
List item
application.css
application.js
templates.js
vendors.css
vendors.js
This would give even better performance than just caching the Angular framework files on the CDN.

Rails upgrade to angular 2

I would like to upgrade my existing Rails and Angular 1.x application. I'm following the ng-upgrade documentation and seeing that there are many dependencies including systemjs, typescript, tsd and a few other javascript libraries. Ideally there would be a angular-2 gem that would have all the dependencies but I'm not able to find that. Next I looked for gem's for each dependency but there isn't one for tsd.
Does it make sense to switch over to a custom build strategy so I can use npm for javascript package management? I read this article that recommends gulp but I do like the convenience of the asset pipeline.
Can anyone point me to examples of successfully using ng-upgrade with a rails project? Does it use a custom build solution like gulp or does it use the asset pipeline?
My main suggestion is not upgrading yet to Angular2, is still heavily in development and you'll face a lot of this issues like not finding a gem for rails.
Anyway, currently, angular2 can't be compiled with sprockets (the default rails pipeline), so you really want a custom solution.
My main suggestion is go with webpack, other options are browserify or gulp (and others), that's mainly a matter of taste. Overall, configuring a pipeline for angular2 is complicated, you have to take care of .d.ts files through typings (which is the updated version of tsd which now is deprecated), you have to transpile your typescript through tsc and possibly through babel too if you want to use async/await (which are really cool). You'll lose the ability to reference to your files in rails like image_path and such, using a custom pipeline, so you want to take that into account too.
Typescript is much more complex to compile than simple coffeescript files, you depend on every other file it reference, since it needs to compile check against it, don't expect something straightforward.
That being said, if you really want to work with Rails and Angular (2 or not), the right way to handle it is to have two separate projects, one with only the Rails app and one with the AngularJS path. In this way you separate concern, you can have a custom pipeline for Angular2 without impacting Rails and you'll be forced to correctly code your Angular2 app by using Rails as a JSON API, as you should.
My solution was to keep it as simple as possible without using webpack or the asset pipeline. I put the ts files in public and configured rails to serve the npm assets through the pipeline.
I put up a starter project with this structure as an example: https://github.com/jonnysamps/rails-ng2-starter
In many ways it has the benefits of having separate backend/frontend projects but keeps all the code together.
use angularjs gem
gem 'angularjs-rails', '~> 1.4', '>= 1.4.8'
insert into application.js
//= require angular
You can use http://bower.io/#install-bower and you can add two files to your the rails app .bowerrc and bower.json which is like GemFile

Using Grunt/Gulp with PHP Framework

So I just started learning Laravel, and I want to build something cool with it. I've been working mostly with frontend development, particularly AngularJS, and started using RequireJS recently.
I like the way Yeoman generators set up front-end applications as far as the directory structure, (i.e. /app, /test, /dist) and would like to continue using this structure, but I want to pull it into the overall application. I also like that in most cases, the application uses unbuilt files (particularly JS) for development because it cuts down on waiting for processes.
How can I set up and structure my Laravel (or any other framework) application and templates to use a similar directory/build setup for files? The problem I keep getting stuck on is using unbuilt/uncompressed files for development, as well as a clean separation of my source vs. built front-end files.
Since starting with Laravel I have tried all sorts of Asset Management tools and methods. I ended up using Stolz/Assets, an ultra-simple-to-use assets management PHP library that can be installed with composer. It is not an ideal tool as there are some issues when minifying (particularly CSS.)
Like you though I really needed neatly compiled and minified js/css assets for production.
After much research I have ended up using Gulp.js after reading this blog post (http://www.abishek.me/using-gulpjs-with-your-laravel-application/). I immediately downloaded and installed Gulp.js and created a gulp file with my own directory structure in it. I was up and running within minutes. I have since gone on to modify my gulp file so it now compiles SASS, minifies and compresses both CSS and JS for production.
I continue to use Stolz/Assets (Asset Management Library for Laravel) for serving up my files but I do not rely on this for any compiling or minification.

Bundler for javascript, or how to source control external javascript files

I am in the process of converting an existing Rails 3.1 app I made for a client into a Backbone.js app with the Rails app only as a backend server extension. This is only a personal project of mine, to learn more about Backbone.js.
While setting up Backbone.js (using Backbone-on-Rails), I noticed I have some dependencies (like backbone-forms) that come from external sources and are frequently updated.
I've grown accustomed to using Bundler to manage my Ruby gems, but I haven't found anything similar for JavaScript files. I'm wondering if there is any way to do the same for Javascript (and possibly css) files.
Basically I can see three possibilities to solve this issue:
Simply write down all the sources for each JS file and check these sources from time to time to see what has changed.
Use some kind of existing "Bundler for Javascript" type of tool, I've been looking for something like this but have yet to find anything (good).
Since most of these JS files will be coming from Git anyway, use Git to get the files directly and use checkout to get the latest version from time to time.
I prefer the last option, but was hoping on some more input from other people who have gone this route or preferred some other way to tackle this issue (or is this even an issue?).
I figure the Git way seems easy, but I am not quite sure yet how I could make this work nicely with Rails 3.1 and Sprockets. I guess I'd try to checkout a single file using Git and have it be cloned in a directory that is accessible to Sprockets, but I haven't tried this yet.
Any thoughts?
You don't mention it in your alternatives, but ideally you should use something like Maven to manage your dependencies. Unfortunately, there are no public repositories for javascript files. This discussion lists some other options which might be of help to you: JQuery Availability on Maven Repositories
For now I've settled on using the Git solution combined with some guard-shell magic.
The steps I follow:
Create a dependencies directory somewhere on your local drive
Clone the repositories with javascript (or css) files you want to use in the app
Set up a custom guard-shell command to do the following:
group 'dependencies' do
guard 'shell' do
dependencies = '~/path/to/dependencies/'
watch(%r{backbone-forms/src/(backbone\-forms\.js)}) {|m| `cp #{dependencies + m[0]} vendor/assets/javascripts/#{m[1]}` }
end
end
Place the Guardfile at the root of the app directory
It takes some time to set things up, but after that, when you have the Guard running, and you pull changes into your dependencies, the required files are automatically copied to your application directory, which are then part of your repository.
It seems to work great, you need to do some work for each new file you want to include in the asset pipeline, but all that is required is cloning the repository in your dependencies directory and adding a single line to your Guardfile, for example for the backbone-form css:
watch(%r{backbone-forms/src/(backbone\-forms\.css)}) {|m| `cp #{dependencies + m[0]} vendor/assets/stylesheets/#{m[1]}` }
Also, the reason I added this Guard to a group is because I keep my dependencies outside the main application directory, which means guard normally doesn't check my dependencies directory. To make this work, I start up my main Guard processes using bundle exec guard -g main and use bundle exec guard -w ~/path/to/dependencies -g dependencies in a new terminal window/tab to specify the -w(atchdir).

Categories

Resources