问题
i just switched to Rails 6 (6.0.0.rc1) which uses the Webpacker gem by default for Javascript assets together with Rails-UJS. I want to use Rails UJS in some of my modules in order to submit forms from a function with:
const form = document.querySelector("form")
Rails.fire(form, "submit")
In former Rails versions with Webpacker installed, the Rails
reference seemed to be "globally" available in my modules, but now i get this when calling Rails.fire
…
ReferenceError: Rails is not defined
How can i make Rails
from @rails/ujs
available to a specific or to all of my modules?
Below my setup…
app/javascript/controllers/form_controller.js
import { Controller } from "stimulus"
export default class extends Controller {
// ...
submit() {
const form = this.element
Rails.fire(form, "submit")
}
// ...
}
app/javascript/controllers.js
// Load all the controllers within this directory and all subdirectories.
// Controller files must be named *_controller.js.
import { Application } from "stimulus"
import { definitionsFromContext } from "stimulus/webpack-helpers"
const application = Application.start()
const context = require.context("controllers", true, /_controller\.js$/)
application.load(definitionsFromContext(context))
app/javascript/packs/application.js
require("@rails/ujs").start()
import "controllers"
Thanks!
回答1:
in my app/javascript/packs/application.js
:
import Rails from '@rails/ujs';
Rails.start();
and then in whatever module, controller, component I'm writing:
import Rails from '@rails/ujs';
回答2:
Just add it to your environment.js file, here is mine (with bootstrap and jquery):
const {environment} = require('@rails/webpacker')
const webpack = require('webpack')
module.exports = environment
environment.plugins.prepend(
'Provide',
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
jquery: 'jquery',
'window.jQuery': 'jquery',
"window.$": "jquery",
Popper: ['popper.js', 'default'],
Rails: ['@rails/ujs']
})
)
回答3:
I am currently messing around on 6.0.0.rc2 but I think I got an answer for you.
So if you separate out the:
app/javascript/packs/application.js
require("@rails/ujs").start()
import "controllers"
To instead:
export const rails_ujs = require("@rails/ujs")
console.log(rails_ujs)
rails_ujs.start()
You can obviously remove that console.log was just trying to figure things out. Then in your stimulus controller you can simply do:
// Visit The Stimulus Handbook for more details
// https://stimulusjs.org/handbook/introduction
//
// This example controller works with specially annotated HTML like:
//
// <div data-controller="hello">
// <h1 data-target="hello.output"></h1>
// </div>
import { Controller } from "stimulus"
import { rails_ujs } from "packs/application.js"
export default class extends Controller {
static targets = [ "output" ]
connect() {
// this.outputTarget.textContent = 'Hello, Stimulus!'
console.log('hi')
console.log(rails_ujs)
}
}
Just using their little test controller here but I got it to console.log out and you can call rails_ujs.fire
so that should be what you want :)
Let me know if this works for you!
回答4:
First at all, using yarn add rails/ujs:
yarn add @rails/ujs
And add to config/webpack/environment.js
const webpack = require('webpack')
environment.plugins.prepend('Provide',
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
Popper: ['popper.js', 'default'],
toastr: 'toastr/toastr',
ApexCharts: ['apexcharts', 'default'],
underscore: ['underscore', 'm'],
Rails: ['@rails/ujs']
})
)
module.exports = environment
Config and load Rails js.
# pack/application.js
require("@rails/ujs").start()
global.Rails = Rails;
And Then: This is result ->
回答5:
I think the best way is to use the expose-loader and configure it the same way webpacker would if you ran bundle exec rails webpacker:install:erb
.
Install the expose-loader
$ yarn add expose-loader
Create a config file
- For loaders webpacker configures itself, it'll dump a config object in
config/webpack/loaders
. Create that folder if it doesn't exist. - Create a file called
config/webpack/loaders/expose.js
Add this to that file:
module.exports = { test: require.resolve('@rails/ujs'), use: [{ loader: 'expose-loader', options: 'Rails' }] }
Add that loader to environment.js
Add these two lines to config/webpack/environment.js
:
const expose = require('./loaders/expose')
environment.loaders.prepend('expose', expose)
The full file should look something like:
const { environment } = require('@rails/webpacker')
const expose = require('./loaders/expose')
environment.loaders.prepend('expose', expose)
module.exports = environment
That should give you access to the Rails
object globally again.
来源:https://stackoverflow.com/questions/56128114/using-rails-ujs-in-js-modules-rails-6-with-webpacker