Idea
Handle dart scripts so they get compiled to js for browsers without dart support. Currently there's only the Dartium
browser from the development-kit that supports dart natively.
For a working sample check m0gg/dart-rails-sample.
Attention
If you're upgrading from versions prior 0.4.2
and use sprockets >= 3.0.0
you need to replace your dart_app.js.dart2js
or dart_app.js
(depends form which version you're upgrading) with a symlink pointing to your dart_app.dart
as sprockets >= 3.0.0
no longer supports the //= include
directive.
If you're using rails 5, ignore the deprecation warning, sprockets is using the same method internally and just silences the warning...
example ls app/assets/dart/
$ ls app/assets/dart/dart_app.*
app/assets/dart/dart_app.dart app/assets/dart/dart_app.js.dart2js
Setup
-
Gemfile
gem 'ruby-dart2js' gem 'dart-rails'
-
$ rails generate dart:assets
rails g dart:assets create app/assets/dart create app/assets/dart/dart_app.dart create app/assets/dart/dart_app.js.dart2js create app/assets/dart/pubspec.yaml
-
app/assets/dart/dart_app.dart
Your dartmain()
goes in here -
app/assets/dart/dart_app.js.dart2js
you don't want to touch this file unless you know exactly what you're doing -
app/assets/dart/pubspec.yaml
the pubspec for your dart-code used to gather dependencies, etc.
for those who are interested in the
app/assets/dart/dart_app.js.dart2js
This file is crucial for the conversion of dart to js through the sprockets pipeline.
.dart2js
gets registered as a js template (just like.coffee
) and runs through dart2js before beeing delivered as js. So if you request/assets/dart_app.js
sprockets recognizes this file and passes it to dart2js. You could put dart code in here, but requests to/assets/dart_app.dart
would deliver something different or nothing at all, that's why it should be a symlink to your actualdart_app.dart
or, if you're on sprockets prior3.0.0
and prefer that way, should contain//= include dart_app.dart
. Note thatsprockets >= 3.0.0
does not support the//= include
directive an you're pinned to the symlink-method. -
-
asset links
Note: scripts in html get executed after they are loaded, that's why scripts that interact with the html and are loaded in the
<head>
will wait for theready
event. This is a quite unusual in dart applications but does not affect most of them because the<script>
tag is located at the bottom of the body and thus gets loaded when the document is close enough toready
. Make sure your dart app waits for theready
event or put the corresponding tags at the bottom of the body. This applies for all 3 variants.Now it's up to you wether you want to serve your
.dart
files and it's compiled.js
variant side-by-side or only one of those variants.-
.dart
and.js
You'll need to add following to the bottom of your body in the layout
layout.html.erb
(for instance)<%= dart_include_tag 'dart_app' %> <%= javascript_include_tag 'dart' %>
-
dart_include_tag 'dart_app'
adds yourdart_app.dart
-
javascript_include_tag 'dart'
adds thedart.js
from the gem for compatibility
As of rails 4 you'll need to turn asset digesting off, append
config.assets.digest = false
to the environment you like to use.for those who are interested in the
javascript_include_tag 'dart'
The
dart.js
will replace the<script>
tags of the typeapplication/dart
to ones with typeapplication/javascript
and substitute the.dart
extension of the src attribute with.js
if the browser is not Dartium. This ensures that you are able to deliver native dart to Dartium and js to all others. Because we only have digested asset names in rails 4, you'll need to turn it off completely to ensure your renamed dart script will point to a non-digested js script. I know this is stupid but we don't have any browser besides Dartium that would support native dart anyways... -
-
.js
onlysimply add this to your
application.js
//= require dart_app
While this would enable you to add several dart programs, there is no guarantee it will work out. (untested) Please pay attention to the former note about placement of the
<script>
tags in your layout. If in doubt move the default<%= javascript_include_tag 'application' %>
to the bottom of the layouts body. -
.dart
onlyYou just need to add the
dart_include_tag
to the bottom of your body in the layoutlayout.html.erb
(for instance)<%= dart_include_tag 'dart_app' %>
-
-
rake pub:get
Run
rake pub:get
to respect the dependencies in yourpubspec.yaml
. Initially the pubspec containsrails_ujs
as dependency, this is just basic for now, so you probably want to omit it if you're still using JQuery. -
ruby-dart2js
See ruby-dart2js on github for setup.
Compatibility
UglifyJs
Don't worry if you're experiencing a
ExecJS::ProgramError: RangeError: Maximum call stack size exceeded
This is exactly what it means, a stackoverflow of UglifyJs. According to RangeError: Maximum call stack size exceeded #414 UglifyJs is massivly recursive and your dart2js file might have blown it. This happened to me with an AngluarDart application. You may simply disable UglifyJs in the environment file.
...
# Compress JavaScripts and CSS.
# config.assets.js_compressor = :uglifier
...
assets:precompile + native .dart files
This is no longer relevant as there are no browsers that support native dart and should be used for production.
Attention currently not working with rails >= 4.2
As of rails 4 we are facing a problem for the productive environments.
See Inability to compile nondigest and digest assets breaks compatibility with bad gems #49
You may optionally add this to your Gemfile
gem 'non-stupid-digest-assets', '>= 1.1', github: 'm0gg/non-stupid-digest-assets'
this will enable a workaround for digesting the assets while precompiling dart files as
seen in non-stupid-digest-assets and
additionally rewrite the manifests to use the non-digest files.
Changelog
v0.5.0:
- fix version to allow Rails 5
v0.4.4 - WIP:
- fix
append_path
injs_compat_engine.rb
- extend README
v0.4.3 - 17. Dec 2015:
- including several README updates
- remove section for non-stupid-digest-assets
v0.4.2 - 16. Dec 2015:
- full compat with sprockets 2 & 3 by switching to symlinked dart_app.js.dart2js
- fixed dart2js compilation by data
- requires
dart2js ~> 0.3.0
v0.4.0 - 4. Dec. 2015:
- you now need a dart_app.js.dart2js template with following content:
app/assets/dart/dart_app.js.dart2js
//= include dart_app.dart
v0.3.3 - 9. Nov. 2015:
- support for sprockets-rails > 2.3.0
v0.3.2-p1 - 9. Nov. 2015:
- remain support for sprockets-rails prior 2.3.0
v0.3.0 - 21. Jan. 2015:
- with v0.2.0 of ruby-dart2js, minifying is supported and will bump the feature version of dart-rails with updated dependencies
v0.2.5 - 14. Jan. 2015:
- fixed a misplaced initializer for non-stupid-digest-assets that caused every asset to be non-digested
v0.2.4 - 13. Dec. 2014 - update:
- corrected
pubspec.yml
to assign validdart_app
as name
v0.2.3 - 13. Dec. 2014:
- fix 2 issues documented as Fix the generated pubspec.yml #13 and Generators run each time rails g runs #12
- generators no longer try to run
rails g dart:assets
as javascript_engine - generated
pubspec.yml
now staticly assignsdart-app
as name - railtie restructured and split into two engines
v0.2.2 - 12. Dec. 2014 - update:
- dart-rails is now available via rubygems, it's first published with version 0.2.2
v0.2.2 - 04. Dec. 2014:
- due to sprockets digest method, we are forced to use a workaround to allow
"precompilation" of .dart files, see non-stupid-digest-assets
and Inability to compile nondigest and digest assets breaks compatibility with bad gems #49
it is optionally (and automatically) available by adding
gem 'non-stupid-digest-assets', '>= 1.1', github: 'm0gg/non-stupid-digest-assets'
to your Gemfile - added dart_app.js to precompile list
- faced an issue with UglifyJs stackoverflowing with too large dart2js files
v0.2.1 - 18. Oct. 2014:
- dart2js compilation no longer recurses to infinity and further, this problem came uo to me while working with angularDart, which now compiles fine (takes some time though)
- sorry for dev-gap, been quite busy in university
v0.2.0 - 08. Oct. 2014:
- dart-rails can now detect changes in dart code and its dependencies
- RailsUjs call is now in the initial dart_app.dart template
- fixed pathname to touch for change recognition
- renamed relevant constants to Dart2Js
- bumped ruby-dart2js version to 0.1.0
v0.1.2 - 27. Sep. 2014:
- slightly different dart2js output directory-tree, now based on md5-hashed timestamps
v0.1.1 - 29. Aug. 2014:
- dart-rails will no longer break assets:precompile
v0.1.0 - 29. Aug. 2014:
- Note that
.dart2js
templates are no longer needed. Sprockets DirectiveProcessor for Javascript ist now capable of including dart2js-compiled scripts via a//= dart dart_app
directive. See updated sample application on github. - Errors during dart2js compilation will now be handled by Sprockets and thus the exception message will be thrown in the created js file. For now there will be also an output on the console.
- As for newest SprocketsRails there is no longer the need of manually
adding
dart.js
to the precompilation list. - Compiled scripts will reside in the
#{Rails.root}/tmp/cache/
directory.