问题
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