Rails 5/6: How to include JS functions with webpacker?

浪尽此生 提交于 2020-02-03 09:22:27

问题


I am trying to update a Rails 3 app to Rails 6 and I have problems with the now default webpacker since my Javascript functions are not accessible.

I get: ReferenceError: Can't find variable: functionName for all js function triggers.

What I did is:

  • create an app_directory in /app/javascript
  • copied my development javascript file into the app_directory and renamed it to index.js
  • added console.log('Hello World from Webpacker'); to index.js
  • added import "app_directory"; to /app/javascript/packs/application.js
  • added to /config/initializers/content_security_policy.rb:

    Rails.application.config.content_security_policy do |policy|
      policy.connect_src :self, :https, "http://localhost:3035", "ws://localhost:3035" if Rails.env.development?
    end
    

I get 'Hello World from Webpacker' logged to console, but when trying to access a simple JS function through <div id="x" onclick="functionX()"></div> in the browser I get the reference error.

I understand that the asset pipeline has been substituted by webpacker, which should be great for including modules, but how should I include simple JS functions? What am I missing?

Thanks in advance?


回答1:


From the official rails app guide:

Where to Stick Your JavaScript

Whether you use the Rails asset pipeline or add a tag directly to a view, you have to make a choice about where to put any local JavaScript file.

We have a choice of three locations for a local JavaScript file:

The app/assets/javascripts folder,the lib/assets/javascripts folder and the vendor/assets/javascripts folder

Here are guidelines for selecting a location for your scripts:

Use app/assets/javascripts for JavaScript you create for your application.

Use lib/assets/javascripts for scripts that are shared by many applications (but use a gem if you can).

Use vendor/assets/javascripts for copies of jQuery plugins, etc., from other developers. In the simplest case, when all your JavaScript files are in the app/assets/javascripts folder, there’s nothing more you need to do.

Add JavaScript files anywhere else and you will need to understand how to modify a manifest file.

More reading: http://railsapps.github.io/rails-javascript-include-external.html




回答2:


Looking at how webpacker "packs" js files and functions:

/***/ "./app/javascript/dashboard/project.js":
/*! no static exports found */
/***/ (function(module, exports) {

  function myFunction() {...}

So webpacker stores these functions within another function, making them inaccessible. Not sure why that is, or how to work around it properly.

There IS a workaround, though. You can:

1) change the function signatures from:

function myFunction() { ... }

to:

window.myFunction = function() { ... }

2) keep the function signatures as is, but you would still need to add a reference to them as shown here: window.myFunction = myFunction

This will make your functions globally accessible from the "window" object.




回答3:


For instructions on moving from the old asset pipeline to the new webpacker way of doing things, you can see here:

https://www.calleerlandsson.com/replacing-sprockets-with-webpacker-for-javascript-in-rails-5-2/

This is a howto for moving from the asset pipeline to webpacker in Rails 5.2, and it gives you an idea of how things are different in Rails 6 now that webpacker is the default for javascript. In particular:

Now it’s time to move all of your application JavaScript code from app/assets/javascripts/ to app/javascript/.

To include them in the JavaScript pack, make sure to require them in app/javascript/pack/application.js:

require('your_js_file')

So, create a file in app/javascript/hello.js like this:

console.log("Hello from hello.js");

Then, in app/javascript/packs/application.js, add this line:

require("hello")

(note that the extension isn't needed)

Now, you can load up a page with the browser console open and see the "Hello!" message in the console. Just add whatever you need in the app/javascript directory, or better yet create subdirectories to keep your code organized.



来源:https://stackoverflow.com/questions/54501241/rails-5-6-how-to-include-js-functions-with-webpacker

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