How to enable minified JavaScript files in Play 2.3.1 templates? - javascript

I was able to load the sbt-uglify 1.0.3 plugin in my Play Framework 2.3.1 app. Loading of the non-minified javascripts is pretty straightforward, but loading the minified versions seems to be impossible.
In my template I use <script> tags similar to this:
<script src="#routes.Assets.at("javascripts/app.js")"></script>
In dev mode, the non-minified javascript version is loaded, which is fine. In prod mode (using activator start) I see sbt-uglify generating the minified versions to the target/web/uglify/build folder, but because I didn't change the above <script> tag line in my templates, the non-minified versions of the javascripts files are loaded.
Is there a way to do a prod-only mapping of such routes to load the minified versions?

The issue Reverse Router should use minified assets in production automatically was fixed in Play 2.3.1 that exactly matches your requirement.
According to Play 2.3.1 Changelog:
The behaviour of the Assets reverse router has changed, if minified
versions of assets exist, it now returns a URL for those instead. To
disable this behaviour, set assets.checkForMinified=true in
application.conf.
NOTE It should rather read set assets.checkForMinified=false, but anyway...
What follows works in production mode only so start the application with activator start not run or use the generated start scripts (after stage).
The behaviour of using minified versions of assets in production should be enabled by default in the version of Play with #routes.Assets.versioned (not routes.Assets.at).
It does require that the appropriate route declaration in conf/routes is:
GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset)
What I found a bit unclear at first was the order of elements in pipelineStages as well as the requirement to include sbt-rjs in it.
And just after I'd written the sentence about the order I found in the section "RequireJS" in Play 2.3 Migration Guide:
The order of stages is significant. You first want to optimize the
files, produce digests of them and then produce gzip versions of all
resultant assets.
I've also found in Play 2.3 Migration Guide in the section "Closure Compiler":
UglifyJS 2 is presently provided via the RequireJS plugin (described
next). The intent in future is to provide a standalone UglifyJS 2
plugin also for situations where RequireJS is not used.
It all started with the answer to Play 2.3 sbt-web plugin Javascript minification.
So, the below pipelineStages is the working one - mind the order and rjs:
pipelineStages := Seq(rjs, uglify, digest, gzip)
project/plugins.sbt used was as follows:
resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.3.5")
addSbtPlugin("com.typesafe.sbt" % "sbt-digest" % "1.0.0")
addSbtPlugin("com.typesafe.sbt" % "sbt-uglify" % "1.0.3")
addSbtPlugin("com.typesafe.sbt" % "sbt-gzip" % "1.0.0")
addSbtPlugin("com.typesafe.sbt" % "sbt-rjs" % "1.0.6")
Don't forget to create an empty app/assets/javascripts/main.js file to let sbt-rjs do its job.
As a test, I created a Play application with activator new playApp play-scala and applied the above changes in the build as well as in app/views/main.scala.html that ultimately looked as follows (note #routes.Assets.versioned):
#(title: String)(content: Html)
<!DOCTYPE html>
<html>
<head>
<title>#title</title>
<link rel="stylesheet" media="screen" href="#routes.Assets.versioned("stylesheets/main.css")">
<link rel="shortcut icon" type="image/png" href="#routes.Assets.versioned("images/favicon.png")">
<script src="#routes.Assets.versioned("javascripts/hello.js")" type="text/javascript"></script>
</head>
<body>
#content
</body>
</html>
Executing activator start and calling curl http://localhost:9000 gives (formatting's mine for the sake of readability):
➜ play-uglify curl http://localhost:9000
<!DOCTYPE html>
<html>
<head>
<title>Welcome to Play</title>
<link rel="stylesheet" media="screen" href="/assets/stylesheets/d41d8cd98f00b204e9800998ecf8427e-main.css">
<link rel="shortcut icon" type="image/png" href="/assets/images/84a01dc6c53f0d2a58a2f7ff9e17a294-favicon.png">
<script src="/assets/javascripts/4302136334616ae0605d47a1932ee262-hello.min.js" type="text/javascript"></script>
</head>
<body>
<h1>Your new application is ready.</h1>
</body>
</html>
Note 4302136334616ae0605d47a1932ee262-hello.min.js and the non-JavaScript resources digested.

Related

Javascript: import error and can't non find variable

I downloaded this d3 JavaScript project from GitHub https://github.com/mcaule/d3-timeseries, and then I created an HTML page (index.html) to run the project. This is index.html:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="./d3_timeseries.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
<script type="text/javascript" src="./d3_timeseries.js"></script>
<script type="text/javascript" src="https://mcaule.github.io/d3-timeseries/dist/create-example-data.js"></script>
<body>
<div id="chart"></div>
<script>
var data = createRandomData(80,[0,1000],0.01)
var chart = d3_timeseries()
.addSerie(data,{x:'date',y:'n',diff:'n3'},{interpolate:'monotone',color:"#333"})
.width(820)
chart('#chart')
</script>
</body>
</html>
I have a problem in d3_timeseries.js with this two errors:
NOTE: I don't want to use min files
The exact file that you have linked, d3_timeseries.js, is not written in such a way that it can be used, without processing, in a browser.
Its very first line import * as d3 from "d3"; will fail, no matter what browser, because "d3" is not a URL that can be evaluated correctly from a browser context. It is not a relative URL, it is not a
It looks like it is intended to be utilized by webpack or some other script bundler. If you used this in a webpack context to bundle your code, it would load "d3" from node_modules.
I know that you said that you "don't want to use min files", so your options are either compile your own bundle or just use the min files in the /dist folder.
I'm assuming you used the file in the src directory. This isn't a regular javascript file, it's node. Luckily the author is buidling what looks to be a web safe version in the dist folder. That version is minified, uglified, and ran through babel.
You rarely want to include files from src or files that aren't uglified. That will cause your webpage to load extra white space data that it does not need.

How to setup the environment for Angular 2.0?

Taking my initial steps towards Angular 2.0.
First thing is to set up the right environment for the development.
My index.html
<!DOCTYPE HTML>
<html>
<head>
<title>Welcome to Angular 2.0</title>
<!--css-->
<link rel="stylesheet" type="text/css" href="css/bootstrap.css" />
</head>
<body>
<div class="container">
<h1> Hello Angular 2 </h1>
<my-app> Loading app component....<my-app>
</div>
<!--js-->
<!-- Polyfills for older browsers -->
<script src="https://unpkg.com/core-js/client/shim.min.js"></script>
<script src="https://unpkg.com/zone.js#0.7.4?main=browser"></script>
<script src="https://unpkg.com/reflect-metadata#0.1.8"></script>
<script src="https://unpkg.com/systemjs#0.19.39/dist/system.src.js"> </script>
<script> window.autoBootstrap = true; </script>
<script src="https://cdn.rawgit.com/angular/angular.io/b3c65a9/public/docs/_examples/_boilerplate/systemjs.config.web.js"></script>
<script>
System.import('app').catch(function (e) { console.log(e); });
</script>
<!--js-->
</body>
</html>
I have copied the content from https://angular.io/docs/ts/latest/guide/setup.html for the following files:-
app.component.ts
app.module.ts
main.ts
NPM is installed & running.
But in order to get the node_modules folders with the required dependencies for the app to run.
What commands do I need to run.
What are the commands that I need to run to set up the Angular 2 environment?
Please note I am new to NPM.
Thanks.
You have angular-cli wich is a good starter point. It will set you everything up according to best practices.
Simple way to set up your first Angular 2 Application.
Download the zip version here.firstAngular2App
Extract it to your destination folder. Assume D:
Open your command prompt(ensure that all required softwares are installed).
Navigate it to the folder. Use the command cd D:\firstAngular2App
Executre npm install
Once it is done use npm start
This way you have your first Angular2 appliction up and running.
npm install in the root project (it will create your node_modules from the dependencies mentioned in package.json file, should have those files as a start)
If you are already using Visual Studio Code as an IDE, you may want to explore how they recommend setting up Angular. I personally found their installation guide painless and feature-rich. I have never walked through an official Angular installation before due to being drenched in jQuery projects. This guide was simple enough to give me a good beginners understanding.

Javascript library not working on Device

I am using the BigNumber library of MikeMcl to handle my needs for big numbers. I use this library in an Ionic/Angular project.
As explained on Github, the way to install and use this library is to include a script tage in your html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<!-- compiled css output -->
<link href="css/ionic.app.min.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.min.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="lib/ngCordova/dist/ng-cordova.min.js"></script>
<script src="cordova.js"></script>
<!-- ********* BIGNUMBER library ********* -->
<script src='lib/bignumber.js/bignumber.min.js'></script>
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/services.js"></script>
</head>
<body ng-app="starter">
<ion-nav-view></ion-nav-view>
</body>
</html>
Now in my code, I can use this library as for instance:
x = new BigNumber(123.4567)
y = BigNumber('123456.7e-3')
z = new BigNumber(x)
x.equals(y) && y.equals(z) && x.equals(z) // true
I tested this and it works fine on Chrome and on Safari (even on device).
But when I install the app on my phone, using Phonegap Build, the app does not work anymore (I checked that this library is the cause by removing the BigNumber syntaxes from my code). Moreover, the Angular in the app just crashes and shows for instance {{variableName}} and nothing is working.
Because I develop in a cloud environment, I did try to debug the app using the Safari Developer Debug Console on a mac (by plugging my phone with an USB to the mac and then enabling Developer tools in Safari).
However, no errors were found with exception of one:
file not found: "path/to/ionic/lib/js/angular.min.js.map" 404
But this is not the cause of the problem.
What is going on? How can I still use this javascript library on my device?
I have just tested your code and it doesn't work because when you create the y variable you don't use the word new.
This is the code I've used and it works
x = new BigNumber(123.4567)
y = new BigNumber('123456.7e-3')
z = new BigNumber(x)
alert( x.equals(y) && y.equals(z) && x.equals(z));// I get true
#JohnAndrews,
If this is the extent of your code, it is missing the deviceready listener. On cordova/phonegap you typically cannot do stuff, until you get the deviceready event. So, this is the only thing I can think of, Can you add a function onDeviceReady() {} and see if that fixes your problem?
Oh and, of course, make sure you run your operations AFTER this event.
Found the solution. If you are also experiencing that a javascript library is not working on your device, but it does in the browser, then this answer might help you.
The problem occured that when I ran npm install to install the package, that it did not update my .git dependencies properly. What happened is that every time I packaged my app through Github and Phonegap Build, the folder of BigNumber was not taken into account. So basically, the file bignumber.js was not available in the app and thats why it did not work.
I solved it by copying all the files from the BigNumber folder to a new custom folder.
A related question is here: Git not pushing all files and folders

Loading jQuery on Jasmine on Rails 3.1 plugin before source files

I'm working Jasmine on a Rails plugin that would be included in a Rails app that loads jQuery from a CDN. However, I'm running into issues running Jasmine tests in my plugin. I need to load jQuery before my source javascript files in app/assets/javascripts, but if I include jQuery in my jasmine.yml it doesn't get loaded before the source files:
jasmine.yml contents:
src_dir: "app/assets/javascripts"
src_files:
- "my_rails_plugin_source_includer.js"
spec_dir: spec/javascripts
asset_paths:
- "vendor/assets/javascripts"
my_rails_plugin_source_includer.js requires my source javascripts:
//= require my_jquery_dependent_script.js
//= require my_other_jquery_dependent_script.js
I'm using
bundle exec jasmine-headless-webkit --color --keep ./spec/javascripts/specs.js
to run my tests. I get an error message like
ReferenceError: Can't find variable: jQuery
ReferenceError: Can't find variable: jQuery
Test ordering seed: --seed 1629
My tests pass if I explicitly require a jQuery javascript file (e.g., jquery-1.9.1-min.js) in my_rails_plugin_source_includer.js. However, I don't want to do that, as I want the actual Rails app, rather than this plugin. Any suggestions on how to require jQuery before my source files? Requiring it in my specs or my helpers doesn't work, as Jasmine seems to always load the source files first (which of course makes sense).
I was able to solve this issue by doing the following:
Downloading jquery-1.9.1.min.js from the official jQuery source and storing it in my spec/javascripts/support/helpers folder.
Creating a source.js file in my spec/javascripts/support/fixtures folder (can be an arbitrary folder) that has the following contents:
//= require ../helpers/jquery-1.9.1.min
//= require ../../../../app/assets/javascripts/application
where app/assets/javascripts/application.js is the manifest for my plugin's JavaScripts.
Editing my jasmine.yml file to use the following sources:
src_dir: "spec/javascripts/support/fixtures"
src_files:
- "source.js"
As a result, the jQuery-dependent source JavaScripts have jQuery preloaded only for Jasmine testing.
Thanks for your answer, Fares, it gave me the insight into what's happening with the jasmine config file.
There's a predictable order to how files are included in your jasmine page's <head> tag.
First, my setup deatils:
rails 4.0.1
jasmine 1.3.2
jquery-rails 3.0.4 (which provides jquery-1.10.2)
Here's my spec/javascripts/support/jasmine.yml. I have no helpers, I don't need css files to test my particular app, and I removed all the comments.
src_files:
- spec/javascripts/lib/jquery-1.10.2.js
- app/assets/javascripts/tools/dependency-parser.js
spec_dir: spec/javascripts
spec_files:
- '**/*[sS]pec.js'
The <head> of my jasmine page contains the following, in order:
jasmine core <link rel="shortcut icon" type="image/png" href="/__JASMINE_ROOT__/images/jasmine_favicon.png">
<link rel="stylesheet" href="/__jasmine__/jasmine.css" type="text/css" media="screen">
<script src="/__jasmine__/jasmine.js" type="text/javascript"></script>
<script src="/__jasmine__/jasmine-html.js" type="text/javascript"></script>
<script src="/__jasmine__/json2.js" type="text/javascript"></script>
src_files <script src="/spec/javascripts/lib/jquery-1.10.2.js" type="text/javascript"></script>
<script src="/app/assets/javascripts/tools/dependency-parser.js" type="text/javascript"></script>
helper_files <!-- I didn't have anything here -->
spec_files <script src="/__spec__/dependency-parser_spec.js" type="text/javascript"></script>
jasmine boot <script src="/__boot__/boot.js" type="text/javascript"></script>
My app uses the asset pipeline, and the jquery-rails gem, along with the typical includes in app/assets/application.js:
//=require jquery
//=require jquery-ujs
//=require tree .
Because I am using the jquery-rails gem, that means I don't actually have the jQuery JavaScript files anywhere to load directly - they should come from the asset pipeline if they come from anywhere. It also seemed that I couldn't include the app/assets/javascripts/application.js file for some reason. This turned out to be okay; I just want to test my custom JavaScript, which depends upon jQuery.
So, I simply downloaded the version of jQuery that my app is using (1.10.2), and put it in:
spec/javascripts/lib/ <= I created this folder
After that everything worked perfectly, because I could predictably load my .js files in the order in which I needed them. It's not perfect. I now manually have keep my jQuery version the same in my specs as whatever version of jquery-rails I use, but that's a rather minor thing for now...though it begs the question, "Why the hell do people package javascript file into a gem?" No other web framework does this kind of wacky stuff.
I also tried using the jasmine 2.0.0.rc5 gem (the current version as of this writing), because it was supposed to take care of asset pipeline issues like this, but it didn't work for me.
I also tried jumping to something more complex like using the jasmine-jquery or jasminerice gems, but found both of their implementations to be more complicated versions of what I did above. Once I understood how the config file was generating the contents of the <head> tag in my particular case, it was a relatively easy fix.
I may move to jasmine 2.0.0 when it's released, if I feel it's necessary (it supposedly has better Rails 4 support), but I'm pretty sure this solution is going to work out just fine.

How can I correct the Meteor base-url in a NginX reverse-proxy configuration?

I have installed both Apache and Meteor behind NginX through reverse-proxy (on an Ubuntu server). Apache is mapped directly as baseURL (www.mydomain.com/) and Meteor is mapped as a subfolder (www.mydomain.com/live/).
The problem I encounter is that my Meteor test (which works as expected at port 3000) stops working behind NginX since every single references (CSS, Javascript, template) are absolute to baseURL.
<html>
<head>
<link rel="stylesheet" href="/live.css?abc">
<script type="text/javascript" src="/packages/underscore/underscore.js?efg"></script>
...
<script type="text/javascript" src="/template.live.js?hij"></script>
<script type="text/javascript" src="/live.js?klm"></script>
</head>
Obviously, since Apache is mapped at baseURL, these files are not found when testing through NginX.
What would be the best way to resolve to problem? System Administration is not my forte, and Meteor is my first incursion at server-side javascript. So I don't even know if this can be fixed, and if so, if it's done through a server configuration, Meteor configuration or programmatically.
EDIT: The new "absolute-url" package in Meteor 0.4.0 fixed the problem!
http://docs.meteor.com/#absoluteurl
The new "absolute-url" package in Meteor 0.4.0 fixed the problem.
http://docs.meteor.com/#absoluteurl
Why are you including scripts and styles in your <head> with Meteor? Anything included within your meteor project directory, be it js, html or css, will get bundled up and served to the client without being included in your HTML with <link> and <script>.
If you must include things in your <head>, why not just use the absolute path including the subfolder?
<html>
<head>
<link rel="stylesheet" href="/live/live.css?abc">
<script type="text/javascript" src="/live/packages/underscore/underscore.js?efg"></script>
...
<script type="text/javascript" src="/live/template.live.js?hij"></script>
<script type="text/javascript" src="/live/live.js?klm"></script>
</head>
Forgive me if I'm misunderstanding the problem.

Categories

Resources