Rails 5.0.0.1
Ruby 2.3.1
I would of thought this would have been a presents issue but then again, it works for the person who created the tutorial Im following in conjunction with this. So, nothing fancy:
Application.js
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= cable
//= require_self
//= require react_ujs
window.$ = window.jQuery = global.$ = require('jquery');
var React = window.React = global.React = require('react');
var ReactDOM = window.ReactDOM = global.ReactDOM = require('react-dom');
require('./components');
Components.js
require( 'babel-polyfill' );
// Manually add components to window and global
// so that react_ujs and react-server can find them and render them.
window.Home = global.Home = require("./components/Home.js").default
// same issue if use *.es6.jsx
Home.js (or es6.jsx)
import React from 'react';
import ReactDOM from 'react-dom';
class Home extends React.Component {
render() {
return (
<div className="form-control">
Home baby
</div>
)
}
}
export default Home;
Gemfile
gem "browserify-rails"
gem 'react-rails
config/application.rb
# Configure Browserify to use babelify to compile ES6
config.browserify_rails.commandline_options = "-t [ babelify --presets [ es2015 ] ]"
unless Rails.env.production?
# Work around sprockets+teaspoon mismatch:
Rails.application.config.assets.precompile += %w(spec_helper.js)
# Make sure Browserify is triggered when
# asked to serve javascript spec files
config.browserify_rails.paths << lambda { |p|
p.start_with?(Rails.root.join("spec/javascripts").to_s)
}
end
npm
npm install browserify browserify-incremental babelify babel-preset-es2015 --save
The Unexpected token refers to the first <div>, why?
The JSX syntax is not being compiled, probably because you need to add the react babel preset to your browserify config.
install package:
npm install --save-dev babel-preset-react
config/application.rb
config.browserify_rails.commandline_options = "-t [ babelify --presets [ es2015 react ] ]"
Related
I'm trying to install toastr by using webpacker in Rails
Now, I'm using toastr by gem 'toastr-rails'
But replace it by using yarn add toastr
How I do setting app/javascript/packs/application.js?
This is application.js in my application
app/japascript/packs/application.js
import "jquery"
global.$ = require("jquery")
// JS-----
// install by yarn
import 'modaal/dist/js/modaal'
import 'flatpickr/dist/flatpickr'
require("jquery-ui-bundle")
// CSS ------
// install by yarn
import 'flatpickr/dist/flatpickr.min.css';
import 'font-awesome/css/font-awesome.min.css';
import 'jquery/dist/jquery';
import 'stylesheets/application';
import 'javascripts/application';
require.context('../images', true, /\.(png|jpg|jpeg|svg)$/);
$("#login-button").click(function(event){
event.preventDefault();
$('form').fadeOut(500);
$('.wrapper').addClass('form-success');
});
console.log('Hello World from Webpacker')
// Support component names relative to this directory:
var componentRequireContext = require.context("components", true)
var ReactRailsUJS = require("react_ujs")
ReactRailsUJS.useContext(componentRequireContext)
config/initializers/asset.rb
Do I have to add something in the asset.rb?
# Be sure to restart your server when you modify this file.
# Version of your assets, change this if you want to expire all your
assets.
Rails.application.config.assets.version = '1.0'
# Add additional assets to the asset load path.
# Rails.application.config.assets.paths << Emoji.images_path
# Add Yarn node_modules folder to the asset load path.
Rails.application.config.assets.paths <<
Rails.root.join('node_modules')
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in the app/assets
# folder are already added.
# Rails.application.config.assets.precompile += %w( admin.js admin.css
)
to use toastr in rails app with webpacker:
install toastr with yarn: yarn add toastr
load lib in your application.js:
import toastr from 'toastr';
toastr.options = {
"closeButton": true
.... add options here ...
};
global.toastr = toastr;
create helper method (for example in your application_helper.rb file):
def custom_bootstrap_flash
flash_messages = []
flash.each do |type, message|
type = 'success' if type == 'notice'
type = 'error' if type == 'alert'
text = "toastr.#{type}('#{message}');"
flash_messages << text.html_safe if message
end
flash_messages = flash_messages.join('\n')
"<script>$(document).ready(function() { #{ flash_messages } });</script>".html_safe
end
use it on the bottom of your layout file (app/views/layouts/application.html.erb):
<%= custom_bootstrap_flash %>
This advice assumes you have a node_modules folder at the root of your rails application.
If you installed toastr with the command...
yarn add toastr
Then yarn will automatically generate a node_modules folder in your application root. This folder gets created the first time you add a dependency with yarn add.
Its possible that you already have this node_modules folder and you just cant see it. This is because by default rails adds this folder to .gitignore which makes it invisible in some file systems.
You can check to see if you have a node_modules folder by temporarily removing node_modules line inside your .gitignore file then refreshing your file tree.
You should be able to see the node_modules folder at this time. Add node_modules back to your .gitignore after you've confirmed that this folder exists in your project.
Once this is done then open your config/initializers/assets.rb file and add the following lines
Rails.application.config.assets.paths << Rails.root.join('node_modules')
Rails.application.config.assets.precompile += ['node_modules/toastr/build/toastr.min.js']
Rails.application.config.assets.precompile += ['node_modules/toastr/build/toastr.min.css']
Then add the following require statement to your application.js file
//= require toastr/build/toastr.min
And assuming your using .scss extensions on your css files then you should add the following to your application.scss file
#import 'toastr/build/toastr.min';
This works in my environment.
Note that toastr requires jquery be loaded before it is loaded.
As such you should make sure that you include the jquery script before your <%= javascript_include_tag 'application' %> tag inside your application.html.erb layout.
any idea how to deal with that ? I mean jquery-ui seems not to be amd and I don't know how to manage that , any idea ?
jquery-ui-dist and jquery-ui-bundle do not seem to be maintained by the jquery-ui team. After jquery-ui v1.12 Its possible to use the official jquery-ui package from npm with webpack.
Update jquery-ui to 1.12 by updating package.json and npm install.
Then you can require each widget like this.
require("jquery-ui/ui/widgets/autocomplete");
require("jquery-ui/ui/widgets/draggable");
If you have used require("jquery-ui") before you need to replace it with separate imports for each widget. I think the new way is better because it will bundle only the code for the widget we need to use.
See documentation on using the 1.12 official npm package.
For some reason jquery-ui didn't play nice with webpack. I had to require jquery-ui-bundle instead.
npm i -S jquery-ui-bundle
and then require it after jquery e.g.
require('jquery');
require('jquery-ui-bundle');
youre in luck I did this just that yesterday, it's rather easy.
npm install --save jquery jquery-ui
Make sure that you have jquery aliased to resolve with the plugin in the webpack.config.js
...
plugins: [
new webpack.ProvidePlugin({
"$":"jquery",
"jQuery":"jquery",
"window.jQuery":"jquery"
}),
...
Then include two aliases in the webpack.config.js
The node_modules folder
The jquery-ui folder
``````
resolve : {
alias: {
// bind version of jquery-ui
"jquery-ui": "jquery-ui/jquery-ui.js",
// bind to modules;
modules: path.join(__dirname, "node_modules"),
Make sure that jquery gets loaded first in your app startup file.
var $ = require("jquery"),
require("jquery-ui");
If you need to use a theme configure the css-loader and the file-loader. Don't forget to npm install those loaders.
module: {
loaders: [
{ test: /\.css$/, loader: "style!css" },
{ test: /\.(jpe?g|png|gif)$/i, loader:"file" },
And use in your app startup file.
require("modules/jquery-ui/themes/black-tie/jquery-ui.css");
require("modules/jquery-ui/themes/black-tie/jquery-ui.theme.css");
webpack-jquery-ui
webpack-jquery-ui
- use this plugin, e.g. if you use Rails 5, run
yarn add webpack-jquery-ui
When jQuery UI plugin starts, it checks if jquery provided, so
Add this code to your webpacker configuration file (shared.js - if you use it with Rails 5)
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery'",
"window.$": "jquery"
})
]
Add these lines into your app code.
require('webpack-jquery-ui');
require('webpack-jquery-ui/css');
to fix ActionController::InvalidAuthenticityToken in jquery.ajax
You have to pass an authenticity_token parameter with all your PUT, POST and DELETE requests.
To do that you can usually fetch it from the header with $('[name="csrf-token"]')[0].content
So your request would look something like:
var that = this;
$.ajax({
url: navigator_item.url,
data: { authenticity_token: $('[name="csrf-token"]')[0].content},
method: 'DELETE',
success: function(res) {
...
}
});
I include jQuery into my application in another way
Instead of using:
plugins: [
new webpack.ProvidePlugin({...
You should add 'jquery': 'jquery/src/jquery' to aliases in the webpack config file:
module.exports = {
resolve: {
alias: {
'jquery': 'jquery/src/jquery'
}
}
It will provide module name 'jquery'. jQuery UI checks this name on init.
Then in you app.js file you write:
import $ from 'jquery'
import 'webpack-jquery-ui/css'
import 'webpack-jquery-ui/sortable' // if you need only sortable widget.
window.jQuery = $;
window.$ = $; // lazy fix if you want to use jQuery in your inline scripts.
The accepted answer doesn't work for me as the jQuery-ui package on NPM isn't pre-built and therefore doesn't contain jquery-ui.js; the package will either need built before use or all the widgets included/used individually.
Quickest way I got the whole package working was by first downloading the distributable version:
npm install jquery-ui-dist --save
I needed to add an alias for jquery-ui-dist to avoid a 'Cannot find module' error (using just require('jquery-ui-dist') won't work, because the .js filename is different), by adding this to webpack.config.js:
resolve: {
alias: {
'jquery-ui': 'jquery-ui-dist/jquery-ui.js'
}
},
Finally, you can use this in the .js file where the modules are loaded:
var jQuery = require('jquery');
require('jquery-ui');
Alternatively, you can avoid having to require the scripts when loading the modules, and having to declare jQuery as a variable, by using ProvidePlugin in your webpack.config.js:
plugins: [
new webpack.ProvidePlugin({
'jQuery': 'jquery',
'$': 'jquery',
'global.jQuery': 'jquery'
})
],
The steps that worked for me (in a Rails 5.1.6 project) aren't identical to any of the above:
Install jquery and jquery-ui: yarn add jquery and yarn add jquery-ui
Add the following to the webpack config (i.e. in /config/webpack/environment.js) to globally set $ and jquery and jQuery:
environment.plugins.prepend(
'Provide',
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
jquery: 'jquery'
})
)
Require whichever individual jquery-ui package(s) you want, at the top of your pack (e.g at the top of /javascript/packs/application.js:
require("jquery-ui/ui/widgets/sortable")
Then you can call, for example, $('.selector').sortable() anywhere in your pack.
add jquery in your node_modules using;
npm install --save jquery jquery-ui
and add externals in your webpack.config.js like;
...
externals: {
// require("jquery") is external and available
// on the global var jQuery
"jquery": "jQuery",
"jquery-ui": "jquery-ui/jquery-ui.js",
}
it worked for me
You should import all of these and check which ones you really need.
require('jquery-ui/ui/core.js');
require('jquery-ui/ui/data.js');
require('jquery-ui/ui/form.js');
require('jquery-ui/ui/form-reset-mixin.js');
require('jquery-ui/ui/focusable.js');
require('jquery-ui/ui/disable-selection.js');
require('jquery-ui/ui/plugin.js');
require('jquery-ui/ui/labels.js');
require('jquery-ui/ui/position.js');
require('jquery-ui/ui/scroll-parent.js');
require('jquery-ui/ui/tabbable.js');
require('jquery-ui/ui/unique-id.js');
require('jquery-ui/ui/widget.js');
require('jquery-ui/ui/widgets/accordion.js');
require('jquery-ui/ui/widgets/autocomplete.js');
require('jquery-ui/ui/widgets/button.js');
require('jquery-ui/ui/widgets/checkboxradio.js');
require('jquery-ui/ui/widgets/controlgroup.js');
require('jquery-ui/ui/widgets/datepicker.js');
require('jquery-ui/ui/widgets/dialog.js');
require('jquery-ui/ui/widgets/draggable.js');
require('jquery-ui/ui/widgets/droppable.js');
require('jquery-ui/ui/widgets/menu.js');
require('jquery-ui/ui/widgets/mouse.js');
require('jquery-ui/ui/widgets/progressbar.js');
require('jquery-ui/ui/widgets/resizable.js');
require('jquery-ui/ui/widgets/selectable.js');
require('jquery-ui/ui/widgets/selectmenu.js');
require('jquery-ui/ui/widgets/slider.js');
require('jquery-ui/ui/widgets/sortable.js');
require('jquery-ui/ui/widgets/spinner.js');
require('jquery-ui/ui/widgets/tabs.js');
require('jquery-ui/ui/widgets/tooltip.js');
require('jquery-ui/ui/effect.js');
require('jquery-ui/ui/effects/effect-blind.js');
require('jquery-ui/ui/effects/effect-bounce.js');
require('jquery-ui/ui/effects/effect-clip.js');
require('jquery-ui/ui/effects/effect-drop.js');
require('jquery-ui/ui/effects/effect-explode.js');
require('jquery-ui/ui/effects/effect-fade.js');
require('jquery-ui/ui/effects/effect-fold.js');
require('jquery-ui/ui/effects/effect-highlight.js');
require('jquery-ui/ui/effects/effect-puff.js');
require('jquery-ui/ui/effects/effect-pulsate.js');
require('jquery-ui/ui/effects/effect-scale.js');
require('jquery-ui/ui/effects/effect-shake.js');
require('jquery-ui/ui/effects/effect-size.js');
require('jquery-ui/ui/effects/effect-slide.js');
require('jquery-ui/ui/effects/effect-transfer.js');
require('jquery-ui/ui/vendor/jquery-color/jquery.color.js');
I have recently updated my Grails app to 2.4.4 and am now using the asset-pipeline plugin. I am also using the CKEditor text editor plugin.
CKEditor loads its configuration from a Javascript file, ckconfig.js, which I have stored in /assets/javascripts/ckconfig.js. Loading of this file is declared in Config.groovy:
// CKeditor basic configuration
ckeditor {
config = "ckconfig.js"
skipAllowedItemsCheck = false
defaultFileBrowser = "ofm"
}
Unfortunately, my configuration is not being loaded and I get a Javascript console error "TypeError: d is undefined".
How do I refer to a Javascript file in the asset pipeline from within Config.groovy?
config = "assets/javascripts/ckconfig.js"
does not work. Is there a fixed path or URL? Or something cleverer?
For reference, I'm using ckeditor 4.4.1.0 plugin and application.js contains:
//= require jquery
//= require js/jquery-ui-1.10.3.custom
//= require cinnabar.js
//= require ckeditor/ckeditor
//= require ckconfig.js
//= require_tree .
//= require_self
This works for me in same environment:
ckeditor {
config = "/assets/ckconfig.js"
...
I placed the file in grails-app\assets\javascripts\ckconfig.js
I installed textAngular with Bower. But I'm having a hard time getting it to work. Anyone tried to add it with Rails and Bower?
$ rake bower:install && find . -name "*textAngular*" -print
./lib/assets/bower_components/textAngular
./lib/assets/bower_components/textAngular/dist/textAngular-sanitize.min.js
./lib/assets/bower_components/textAngular/dist/textAngular.min.js
./lib/assets/bower_components/textAngular/src/textAngular-sanitize.js
./lib/assets/bower_components/textAngular/src/textAngular.js
./lib/assets/bower_components/textAngular/src/textAngularSetup.js
Adding textAngular to application.js works. But adding textAngular-sanitize failes. A bit weird as I can see the source file next to textAngular.
// [snipp...]
//= require textAngular => No complaining here.
//= require textAngular-sanitize => couldn't find file 'textAngular-sanitize'
//= require_tree .
And added to app.js
angular
.module('app', ['ngRoute', 'restangular', 'textAngular'])
.config(['$routeProvider', 'RestangularProvider', function($routeProvider, RestangularProvider) {
The important line is
./lib/assets/bower_components/textAngular/dist/textAngular-sanitize.min.js
Your require should look like:
//= require textAngular/dist/textAngular-sanitize
For some reason, after running rake assets:precompile, require statements in application.js are left untouched. Here is how compiled application.js looks like:
//
//= require jquery
//= require jquery_ujs
//= require_directory .
//= require twitter/bootstrap
//= require rails.validations
$(document).on("click", '.show', function(e) {
var value = $(this).attr('data-big-url');
$('.image_container img').attr('src', value);
return false;
});
That //= require statements should be substituted!
Any ideas?..
THanks!
EDIT: uncompiled application.js:
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
// GO AFTER THE REQUIRES BELOW.
//
//= require jquery
//= require jquery_ujs
//= require_directory .
//= require twitter/bootstrap
//= require rails.validations
$(document).on("click", '.show', function(e) {
var value = $(this).attr('data-big-url');
$('.image_container img').attr('src', value);
return false;
});
// $(window).load(function() {
// $('#featured').orbit();
// // $('#featured-bg').orbit();
...
It looks exactly the same!
Here is my production.rb:
config.serve_static_assets = true
config.assets.compress = false
config.assets.compile = false
config.assets.digest = false
I may be wrong, but I don't believe you'd want require ____ in a precompiled JS file
The reason is the require lines are called directives which guide
the creation of a manifest.json file for your assets. The
manifest basically tells Rails which files make up your assets,
allowing it to compile them effectively
You can see the precompiling documenation from the Rails guide here - basically says that the files you get from precompilation are "standalone" files. They are meant to be loaded as static files, without any preprocessors or directives
I would try this:
$ rake assets:precompile RAILS_ENV=production
This will compile the files as if it were the production environment, and storing them in /public/assets as a naked JS / CSS file
Finally, I solve the issue:
I had to downgrade to Ruby 1.9.3.
Unfortunately, I still don't know what was the reason of the issue, but now I have my assets compiling correctly.