Somehow in development environment my coffeeScript files compile correctly. But when I compile them for production I get something like this
CoffeeScript:
$->
alert "hello world"
Compiled to Javascript
(function() {
$(function(){
alert("hello world");
})
}).call(this)
I have checked for miss indentations and spacing errors, or for a mix of tabs and spaces but there are not any. The weird thing is that when I converted the with the compiler from coffeescript.org it compiles correctly, its just in the production environment. Any ideas?
by the way: I am using rails 4
It's a coffeescript setting.
(function() {
# Code here
}).call(this)
Is a closure generated by coffeescript by default (can be disabled, but you shouldn't), used to avoid global namespace pollution.
It doesn't affect the script execution, your jQuery code will still be run once document is loaded.
Important note
The only issue you may find with that closure is that you actually have hard time declaring global variables. This can be solved in this way:
window.yourvar = 'something'
There is also a suggestion here on how you can disable it anyway: How can I use option "--bare" in Rails 3.1 for CoffeeScript?
Related
Context
I try to move assets in our application to webpack using Webpacker gem. Application is very big, so I need to do it partially.
What did so far...
I successfully managed to call the script using javascript_pack_tag
I export a super simple module:
# javascript/src/javascript/test.js'
const Direction = {
log_to_console: function(){
console.log('test');
}
};
export default Direction;
Then import it in the application entry point
# javascript/packs/application.js
import Test from '../src/javascript/test.js'
Test.log_to_console();
Finally rendering it in the layout:
# app/views/application.slim
= javascript_include_tag 'application'
The result is: "Test" string visible in the browser console.
The problem
Currently in the whole application we use Modules in views like this:
# app/views/assets/javascripts/test.coffee
log_to_console = ->
console.log('test');
#Test = { log_to_console }
# app/views/some/template.slim
javascript:
Test.log_to_console()
But after moving module to webpack I can't access the Test module anymore.
So my question is:
How to configure webpacker gem OR refactor the code above to make the log_to_console() method available in views/browser inspector?
Ideally it would be if we could also access them in old javascript files compiled by sprockets.
I figured out that solution for now. May be helpful for anyone that encounters that problem.
If anyone finds better solution, I would be glad to see it here ;).
For now all our modules/libraries that are needed to be visible in views/other coffee files, I just set as globally available via the window object.
import Foo from '../src/javascript/foo.js
window.Foo = Foo
I know it's ugly anti pattern, but works well as temporary solution until we update our scripts behave more like independent packs.
Let's say I have a file called foobar.js.erb.coffee.
I'm confused how this file is interpreted when rails application is compiled. My understanding is like following:
1) Coffeescript preprocessor engine interprets from coffeescript to ruby(erb).
2) ERB preprocessor engine converts ruby to javscript.
Am I understanding this correctly?
For example, foobar.js.erb.coffee
The extension of the file will be composed of two parts: the format (foobar.js) followed by the handler (.erb.coffee).
A handler is a preprocessor for the template, or a templating language. There are a number of handlers built in, and many more can be added by using extra gems.
The order of conversion is from right to left.
In your case, the CoffeeScript engine try to convert CoffeeScript into JavaScript (Error may occur because of existing ERB may cause CoffeeScript has invalid syntax) and then the ERB handlers will replace all the Ruby code to what the output value should be.
I always put .erb at last for these kind of situation. For example, main.css.scss.erb or app.js.es6.erb.
I have a Rails + AngularJS project that doesn't use the inline annotation injection and using gulp-ngcompile to compile my scripts. But now I would like to replace gulp with asset pipeline. Is there's any asset pipeline plugins act just like gulp-ngcompile?
There are too many scripts looks like the following and thus hard to covert them to inline annotation:
myApp.controller('SomeCtrl', function($scope, $http) {...});
// inline annotation:
myApp.controller('SomeCtrl', ['$scope', '$http', function($scope, $http) {...}]);
There are two solutions you might want to give them a try:
https://github.com/kikonen/ngannotate-rails
ngannotate-rails uses https://github.com/olov/ng-annotate to deal with the inline annotations, so you can keep your code clean. However, somehow it doesn't work for me in the development mode, but it does work in production mode. (I'm not really sure why, but you may want to try it)
If you're using the default uglifier, you can turn off the name mangling as suggested by thoughtbot in http://robots.thoughtbot.com/avoid-angularjs-dependency-annotation-with-rails
The caveat is that you loss the optimal minimized javascripts ... JavaScript will still be minified – whitespace stripped out and code nicely compacted – but the variable and parameter names will remain the same.
With Ruby on Rails, is there a configuration I can set that requires the JS code to pass the Closure Linter or JSHint?
You know how when you have a syntax error in your SCSS, an error shows up in dev. I'd like to require something similar with JSHint.
Can you set up an IDE to trigger JShint checker, check out http://jshint.com/install/
A basic task: evaluate field's value and show warning if results are not satisfying. The actual code doesn't matter, since it works perfectly until I actually change sample warning's test to the one, which should actually be there, which throws this accursed error at me:
Error: Encoding::UndefinedConversionError: U+0417 from UTF-8 to ISO-8859-1
In any other case I would've used i18n or magic comment, but neither seem to work here, since apparently you can't mix ruby into .coffee file. Is there any way to avoid this without resorting to putting unnecessary javascript into views?
You can use ruby in coffeescript assets. Just rename the file to .js.erb.coffee and use good old <%= ruby_code %>.