Assets
Static assets like images and fonts support is enabled out-of-box and you can link them into your JavaScript app code and have them compiled automatically.
Import from node modules
You can also import styles from node_modules
using the following syntax.
Please note that your styles will always be extracted into [pack_name].css
:
// app/javascript/styles.sass
// ~ to tell webpack that this is not a relative import:
@import '~@material/animation/mdc-animation'
@import '~bootstrap/dist/css/bootstrap'
// Your main app pack
// app/javascript/packs/app.js
import '../styles'
<%# In your views %>
<%= javascript_pack_tag 'app' %>
<%= stylesheet_pack_tag 'app' %>
Import from Sprockets using helpers
It’s possible to link to assets that have been precompiled by Sprockets. Add the .erb
extension to your JavaScript file, then you can use Sprockets’ asset helpers:
<%# app/javascript/my_pack/example.js.erb %>
<% helpers = ActionController::Base.helpers %>
const railsImagePath = "<%= helpers.image_path('rails.png') %>"
This is enabled by the rails-erb-loader
loader rule in config/webpack/loaders/erb.js
.
Using babel module resolver
You can also use babel-plugin-module-resolver to reference assets directly from app/assets/**
yarn add babel-plugin-module-resolver
Specify the plugin in your babel.config.js
with the custom root or alias. Here’s an example:
{
plugins: [
[require("babel-plugin-module-resolver").default, {
"root": ["./app"],
"alias": {
"assets": "./assets"
}
}]
]
}
And then within your javascript app code:
// Note: we don't have to do any ../../ jazz
import FooImage from 'assets/images/foo-image.png'
import 'assets/stylesheets/bar'
Link in your Rails views
You can also link js|images|styles|fonts
used within your js app in rails views
using asset_pack_path
, asset_pack_url
, image_pack_path
, image_pack_url
and
image_pack_tag
helpers. These helpers are especially useful in cases where you
want to create a <link rel="prefetch">
or <img />
for an asset.
app/javascript:
- packs
- app.js
- images
- calendar.png
// app/javascript/packs/app.js (or any of your packs)
// import all image files in a folder:
require.context('../images', true)
<%# Rails view, for example app/views/layouts/application.html.erb %>
<img src="<%= asset_pack_path 'media/images/calendar.png' %>" />
<% # => <img src="/packs/media/images/calendar-k344a6d59eef8632c9d1.png" /> %>
<img src="<%= asset_pack_url 'media/images/calendar.png' %>" />
<% # => <img src="https://example.com/packs/media/images/calendar-k344a6d59eef8632c9d1.png" /> %>
<img src="<%= image_pack_path 'media/images/calendar.png' %>" />
<% # => <img src="/packs/media/images/calendar-k344a6d59eef8632c9d1.png" /> %>
<img src="<%= image_pack_url 'media/images/calendar.png' %>" />
<% # => <img src="https://example.com/packs/media/images/calendar-k344a6d59eef8632c9d1.png" /> %>
<%= image_pack_tag 'media/images/calendar.png' %>
<% # => <img src="/packs/media/images/calendar-k344a6d59eef8632c9d1.png" /> %>
<%# no path used in image helpers resolves to default 'images' folder: %>
<img src="<%= image_pack_path 'calendar.png' %>" />
<% # => <img src="/packs/media/images/calendar-k344a6d59eef8632c9d1.png" /> %>
<img src="<%= image_pack_url 'calendar.png' %>" />
<% # => <img src="https://example.com/packs/media/images/calendar-k344a6d59eef8632c9d1.png" /> %>
<%= image_pack_tag 'calendar.png' %>
<% # => <img src="/packs/media/images/calendar-k344a6d59eef8632c9d1.png" /> %>
Note you need to add a media/
prefix (not /media/
) to any subfolder structure you might have in app/javascript
. See more examples in the tests.