Loading images with rails helpers
What is the recommended way of referencing images with webpack-rails?
Is it possible to use something like this?
= image_tag *webpack_asset_paths('my-image', extension: 'png')
I don't know, to be honest. I haven't played with images in webpack. Give it a go and see!
I think I understand the issue now. My images are not part of the assetsByChunkName attribute in the manifest.json file. This helper will not find my image assets: *webpack_asset_paths('file', extension: 'png')
manifest.json
"assetsByChunkName":{
"file":[
"file-554ffb8dcc2a3d701ac2.js",
"file.css"
]
},
There are two potential options:
- Figure out how to add images to the assetsByChunkName attribute in manifest.json
- Find out how to push my assets onto the path variable https://github.com/mipearson/webpack-rails/blob/5575507c1043de984b43f984eb59d5ad980f1b87/lib/webpack/rails/manifest.rb#L31
I found another work around by just making a css class for every image. I am also using the webpack url/file loader.
<div class="graphic" />
.graphic {
background-image: url('./file.png');
background-repeat: no-repeat;
background-size: contain;
width: 6rem;
height: 6rem;
}
Did anyone find a way to use image tags yet? I'm not sure using classes is really a viable solution.
I developed a fairly nice solution to this using Rails 4.1. (Should work on other Rails versions but the patches may vary.)
-
Install the asset-map-webpack-plugin and add it to your webpack config.
-
Somewhere in your JS,
requireall of the image assets that you want to reference in your Rails app withimage_tags. I used an image manifest JS file that I required in from the entry file. (I don't love this step but I haven't thought of a better way to do it yet.) -
Create an initializer (something like
config/initializers/image_assets.rb) and patch ActionView to reference the file generated by asset-map-webpack-plugin when resolving image paths. Here's what I wrote (may vary based on where you're putting your built assets):
module ActionView
module Helpers
module AssetUrlHelper
def compute_asset_path(source, options = {})
if options[:type] == :image
asset_map[source]
else
dir = ASSET_PUBLIC_DIRECTORIES[options[:type]] || ""
File.join(dir, source)
end
end
private
def asset_map
return @asset_map if @asset_map
translated = {}
asset_manifest['assets'].each do |asset, mapped|
# Only include image assets in the lookup hash.
next unless asset.include?('app/assets/images')
# Trim to ensure path matching is correct --
# if image is at `app/assets/images/path/to/image.png`,
# we want to use `image_tag('path/to/image.png') as expected.
asset_tail = asset.split('app/assets/images/').last
translated[asset_tail] = mapped
end
if Rails.env.development?
translated
else
@asset_map = translated
end
end
def asset_manifest
return @asset_manifest if @asset_manifest
if Rails.env.development?
host = ::Rails.configuration.webpack.dev_server.manifest_host
port = ::Rails.configuration.webpack.dev_server.manifest_port
http = Net::HTTP.new(host, port)
http.use_ssl = ::Rails.configuration.webpack.dev_server.https
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
JSON.parse(http.get('/assets/asset_map.json').body)
else
@asset_manifest = JSON.parse(File.read(Rails.root.join(Rails.configuration.webpack.output_dir, 'asset_map.json')))
end
end
end
end
end
I also had to patch asset-map-webpack-plugin to get it to work in development. The original version uses fs.writeFileSync to naively write out the asset json file, rather than adding it to the webpack output assets (and so in development it still tries to write out to the filesystem rather than storing/serving in memory from the dev server). I may send a PR to the original repo with my changes, or just publish my own package with more targeted configuration for this use case.
@mipearson, let me know if you think this approach is worth standardizing and including in webpack-rails itself. I can clean up my code and send a PR.
I have accomplished the same thing with already existing stats plugin here is my fork https://github.com/pavels/webpack-rails it needs more refinement, but works ok
Any progress on this? We are running into the same issue.
Try using the url-loader helper and using JS import/requires:
https://gist.github.com/alexkrolick/cb120d2e0f8450f1cd49d175f7a66dfe#file-webpack-config-js-L54-L57