Rendering js from a Rails controller with webpacker

孤人 提交于 2020-01-31 04:50:09

问题


Just replaced the js pipeline in my Rails app with webpacker.

Most things work correctly, however controllers that render js no longer work as expected.

def action
  format.js { render "javascript_partial" }
end

Normally, the above would execute a file in my view called javascript_partial.js.erb or action.js.erb if not specified in render.

The problem seems to be that these files have no connection to the webpacker pipeline and thus cannot access global libraries like jquery or explicitly manage their own imports.

This code now causes client-side syntax errors because it cannot access the jquery $ function:

$("#element").html(<= j render partial: 'partial', locals: { object: @object } %>

I have a related problem with in-line js in my views. Something like the following,

<%= form.collection_select ... onchange: 'Rails.fire(this.form, "submit")' %>

no longer works, because in-line js cannot access global objects such as Rails.

This seems to be a straightforward problem but I cannot find documentation anywhere.

Does anyone how to harmonize webpacker with historically expected Rails/js behavior? Do I need to bring back sprockets?


If it helps, my javascript/packs/application.js file looks something like,

import Rails from 'rails-ujs';
import Turbolinks from 'turbolinks';

Rails.start();
Turbolinks.start();

$(document).on("turbolinks:load", () => {
  // initial setup ...
});

The above works perfectly fine, and has access to jquery because I've exported it in config/webpack/environment.js,

environment.plugins.append('Provide', new webpack.ProvidePlugin({
  $: 'jquery',
  jQuery: 'jquery',
  jquery: 'jQuery'
}));

回答1:


Figured it out thanks to this wonderful article!

Use expose-loader to expose key libraries to vanilla JavaScript sprinkled throughout your app.

1) Install dependency,

yarn add expose-loader --dev

2) Configure config/webpack/environment.js,

const { environment } = require('@rails/webpacker');

environment.config.merge({
  module: {
    rules: [
      {
        test: require.resolve('jquery'),
        use: [{
          loader: 'expose-loader',
          options: '$'
        }, {
          loader: 'expose-loader',
          options: 'jQuery'
        }]
      },
      {
        test: require.resolve('rails-ujs'),
        use: [{
          loader: 'expose-loader',
          options: 'Rails'
        }]
      }
    ]
  }
});

module.exports = environment;



回答2:


I had a similar problem where I had undefined $ on the string $("#element").html(

My configuration is similar to yours I solved by exposing at the end of the file pack/application.js

windows.jQuery = jQuery
window.$ = $


来源:https://stackoverflow.com/questions/54758232/rendering-js-from-a-rails-controller-with-webpacker

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!