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.dart2jsSetup
-
Gemfilegem 'ruby-dart2js' gem 'dart-rails'
-
$ rails generate dart:assetsrails 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.dartYour dartmain()goes in here -
app/assets/dart/dart_app.js.dart2jsyou don't want to touch this file unless you know exactly what you're doing -
app/assets/dart/pubspec.yamlthe pubspec for your dart-code used to gather dependencies, etc.
for those who are interested in the
app/assets/dart/dart_app.js.dart2jsThis file is crucial for the conversion of dart to js through the sprockets pipeline.
.dart2jsgets registered as a js template (just like.coffee) and runs through dart2js before beeing delivered as js. So if you request/assets/dart_app.jssprockets recognizes this file and passes it to dart2js. You could put dart code in here, but requests to/assets/dart_app.dartwould deliver something different or nothing at all, that's why it should be a symlink to your actualdart_app.dartor, if you're on sprockets prior3.0.0and prefer that way, should contain//= include dart_app.dart. Note thatsprockets >= 3.0.0does not support the//= includedirective 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 thereadyevent. 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 thereadyevent 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
.dartfiles and it's compiled.jsvariant side-by-side or only one of those variants.-
.dartand.jsYou'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.jsfrom the gem for compatibility
As of rails 4 you'll need to turn asset digesting off, append
config.assets.digest = falseto the environment you like to use.for those who are interested in the
javascript_include_tag 'dart'The
dart.jswill replace the<script>tags of the typeapplication/dartto ones with typeapplication/javascriptand substitute the.dartextension of the src attribute with.jsif 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... -
-
.jsonlysimply add this to your
application.js//= require dart_appWhile 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. -
.dartonlyYou just need to add the
dart_include_tagto the bottom of your body in the layoutlayout.html.erb(for instance)<%= dart_include_tag 'dart_app' %>
-
-
rake pub:getRun
rake pub:getto respect the dependencies in yourpubspec.yaml. Initially the pubspec containsrails_ujsas 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_pathinjs_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.dartv0.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.ymlto assign validdart_appas 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:assetsas javascript_engine - generated
pubspec.ymlnow staticly assignsdart-appas 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
.dart2jstemplates are no longer needed. Sprockets DirectiveProcessor for Javascript ist now capable of including dart2js-compiled scripts via a//= dart dart_appdirective. 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.jsto the precompilation list. - Compiled scripts will reside in the
#{Rails.root}/tmp/cache/directory.