I'm playing with rails 5.1 and i'm having trouble using a custom class from webpacker in an asset pipeline js file.
My thought was that if I had some utility js class that I wanted to use everywhere I'd add it in packs and then be able to use it in anything on the webpacker side as well as everything on the pipeline side.
// app/javascript/packs/stuff.js
class Stuff {
constructor() {
console.log("*** building stuff! **")
}
}
export default Stuff
If I want to use that on the webpacker side I can with just adding this to
packs/application.js
import Stuff from "./stuff"
let s = new Stuff()
No issues there, but then I try to use that class on the pipeline side and I get
Uncaught ReferenceError: Stuff is not defined
I'm using it like this:
// assets/javascripts/users.js
new Stuff();
I've added to my layout file:
= javascript_pack_tag 'stuff'
And I also tried adding to the pipelines application.js
//= require stuff
//= require_tree .
stuff.js was compiled properly to public/packs/stuff.js and is in the manifest.json
{
"application.js": "http://0.0.0.0:8080/packs/application.js",
"hello_react.js": "http://0.0.0.0:8080/packs/hello_react.js",
"stuff.js": "http://0.0.0.0:8080/packs/stuff.js"
}
I've also added this to the assests.rb initializer:
Rails.application.config.assets.paths << Rails.root.join('public/packs')
I'm sure i'm missing something small and have just been looking at it for too long to see it.
----- UPDATE -----
There is a little noise in the original post as I was flailing trying to get stuff to work. In the end you just need the tip provided by the accepted answer.
In app/javascript/packs/application.js add:
import Stuff from "./stuff"
window.Stuff = Stuff
And in your layout make sure to have:
= javascript_pack_tag 'application'
I didn't need to //= require stuff in the pipeline application.js. I also didn't need to add the public directory in the assets.rb initializer.
To use in a pipeline js file like users.js just make sure you use it after everything has loaded like this:
$( document ).on('turbolinks:load', function() {
new Stuff();
})
Or if you want to inline it in your index.slim or something you can just do:
javascript:
new Stuff();
Once it is setup correctly you'll want to restart the webpack server:
./bin/webpack-dev-server
Now if you make changes to stuff.js they should be compile and available right away as you would expect.
My final stuff class looks like this:
export default class Stuff {
constructor() {
console.log("*** building stuff! **")
}
more() {
console.log("--- more stuff ---")
}
}
You have to declare your imported class in window
in order to use it in your front-end code (asset or in template). In your pack application.js
add the following :
import Stuff from "./stuff"
window.Stuff = Stuff
Then you can use it :
var foobar = new window.Stuff();
Full stack example here : https://gist.github.com/Aschen/f0a53b0d522688cc46ef77705074c1d2
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.