Reputation: 125
In a Rails project, I am trying switch from using the old Sprockets asset pipeline to using webpacker. I have set up these test files:
app/javascript/lib/foo.js
function foo() {
console.log('foo')
}
console.log('bar')
app/javascript/packs/application.js
// some standard Rails JS requires
// ...
require('lib/foo')
app/views/test/index.html
<script>
foo()
</script>
And in my layouts/application.html.erb I have
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
When I go to that page in my browser, I see "bar" logged to my console, followed by
"ReferenceError: foo is not defined"
I have tried a few different approaches to setting up my files, like using import instead of require or setting module.exports = foo
or export default foo
in my js file, but I haven't had any luck getting around the above error message.
So in short, how do I move javascript files from sprockets to webpacker? And if possible, how do I do so without changing my existing javascript code?
Upvotes: 3
Views: 1774
Reputation: 11504
You'll want to export functions and modules as a named export from your application.js
pack and extend the Webpack config output
to designate the library name and target var
(or window
will also work).
// config/webpack/environment.js
environment.config.merge({
output: {
library: ['Packs', '[name]'], // exports to "Packs.application" from application pack
libraryTarget: 'var',
}
})
// app/javascript/packs/application.js
import foo from '../lib/foo'
export {
foo
}
<script>
$(document).ready(function(){
Packs.application.foo();
});
</script>
The library
name is arbitrary. Using the [name]
placeholder is optional but allows you to export to separate modules if you're using multiple "packs".
Upvotes: 3