Normally I would have a .jsx.erb file with something like <img src="<%= asset_path('spinner.gif') %>", I know asset_path is not going to work with Webpack but I've tried everything I could find here and elsewhere but nothing works. I found this in your help section but I'm confused at how you reference those symbolic links in JS - https://github.com/shakacode/react_on_rails/blob/master/docs/additional-reading/rails-assets.md
Ideally I would like to keep our assets in the original Rails assets folder but if that's not possible then moving some over to the client folder is fine too.
You need to put the assets in the /client folder. Webpack will copy those to your bundles folder with fingerprints. The asset pipeline will then move them to your /public/assets folder, fingerprinting them again. React on Rails undoes the duplicate fingerprint with sym links.
BTW, webpack will only copy the assets if they are referenced. You need to either use background images or a require in your JS file.
BTW, webpack will only copy the assets if they are referenced. You need to either use background images or a require in your JS file.
This helped make it click for me, thank you. For anyone else coming behind me this is a simple example -
const spinner_URL = require('assets/images/spinner.gif');
const Foo = React.createClass({
render: function() {
return (
<div>
<h1>Hello</h1>
<img src={spinner_URL} />
</div>
)
}
});
export default Foo;
@ryangrush I am facing the same issue as you are. I can successfully get webpack to process the image and I get an "ok" URL after requiring it. However the image is not returned by the server later.
Could you share your webpack conf and image asset path where you are placing it?
Are you using a webpack image loader or file loader for this purpose?
My relevant conf:
module: {
loaders: [
... {
test: /.*\.(gif|png|jpe?g|svg)$/i,
loaders: ['file?hash=sha512&digest=hex&name=[name].[ext]', 'image-webpack']
}
]
},
Image located on client/app/assets/landing.jpg
After webpack process, I can effectively see it on rails_root/app/assets/webpack/landing.jpg
let img = require('../../../assets/landing.jpg'); // I've tried requiring in different ways, and it's being found with this ugly ../../ .... format. Can verify since using an incorrect name throws an error.
console.log('IMG is ' + img); // Returns a correct "landing.jpg" string
Here's what my webpack.config.js file looks like -
/* eslint comma-dangle: ["error",
{"functions": "never", "arrays": "only-multiline", "objects":
"only-multiline"} ] */
const webpack = require('webpack');
const path = require('path');
const devBuild = process.env.NODE_ENV !== 'production';
const nodeEnv = devBuild ? 'development' : 'production';
const glob = require('glob');
const isDebug = !process.argv.includes('--release');
const isVerbose = process.argv.includes('--verbose');
const config = {
entry: [
'es5-shim/es5-shim',
'es5-shim/es5-sham',
'babel-polyfill',
'./app/index.jsx',
].concat(glob.sync("./app/views/*/*/*", "./app/*/*/*")), // Allows you to use ReactOnRails.register({ }); in a components file rather than registering it in index.jsx
output: {
filename: 'webpack-bundle.js',
path: '../app/assets/webpack',
"publicPath": "/",
},
resolve: {
extensions: ['', '.js', '.jsx'],
alias: {
react: path.resolve('./node_modules/react'),
'react-dom': path.resolve('./node_modules/react-dom'),
'ui_elements': path.resolve('./app/ui_elements'),
'assets': path.resolve('./app/assets'),
'vendor': path.resolve('./vendor'),
},
},
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jquery: "jQuery",
"window.jQuery": "jquery"
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(nodeEnv),
},
}),
new webpack.ProvidePlugin({
"React": "react",
}),
],
module: {
loaders: [
{
test: require.resolve('react'),
loader: 'imports?shim=es5-shim/es5-shim&sham=es5-shim/es5-sham',
},
{
test: /\.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
},
{
test: /\.(ico|jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2)(\?.*)?$/,
loader: 'file-loader',
query: {
name: 'assets/[name].[ext]?[hash:8]',
},
},
{
test: /\.(mp4|webm|wav|mp3|m4a|aac|oga|png|gif)(\?.*)?$/,
loader: 'url-loader',
query: {
name: 'assets/[name].[ext]?[hash:8]',
limit: 10000,
},
},
],
},
};
module.exports = config;
if (devBuild) {
console.log('Webpack dev build for Rails'); // eslint-disable-line no-console
module.exports.devtool = 'eval-source-map';
}
else {
config.plugins.push(new webpack.optimize.DedupePlugin());
console.log('Webpack production build for Rails'); // eslint-disable-line no-console
}
I can't remember exactly what fixed it but I'm pretty sure its going to assume your base route is rails_root/app/ and not in relation to the rails_root/client folder. If you don't see the image in your rails_root/app/assets/images/ folder then you need to figure out why that is first.
Thanks @ryangrush. Looks like I only needed to add "publicPath": "/", I got the suggestion from this SO:

It's all working now!
@estebanbouza glad you were able to figure it out!
Maybe we should put this information in the /docs directory?
Also nice to include it in sample application. Since if you encapsulate styles in component, you want and need encapsulate images too. Otherwise you wouldn't get truly isolated package which you can reuse in several projects.
I've been trying to get this solution to work for days now. My images are client/app/bundles/assets/images, and Webpack seems to be generating valid URLs. The problem I'm running into is that although react_on_rails is apparently generating symlinks to the files, I can't prove it, nor can I see if Rails is publishing my images in the asset pipeline. Is there any way to get Rails to show me all the fingerprinted files, or even better, all the files being served, so I can ensure that the symlinks are where I think they should be.
@1simonfish You should test this out locally, by doing things like:
You can inspect the deployment files in /public/assets
This is all from memory...Actual details may differ.
Please get in touch with me if you want personalized help.
Hey @justin808 are you still looking for a doc PR for this? If so, and @ryangrush doesn't want dibs on this, I have a doc I wrote up about this that I could add.
That would be awesome. @tmobaird.
FWIW, I've typically used images in the Rails install as background images in the CSS. However, it's perfectly reasonable to use an image tag.
@justin808 that's definitely a good thing to note! I'll open a PR in a little bit with the doc for this
I am trying to precompile images to the public/assets directory but to no avail. Webpack works as intended and all my assets are copied to app/assets/webpack/webpack-assets folder.
The option on the initializers/react_on_rails config.symlink_non_digested_assets_regex is the default value. No symlinks are created for the images as i can see from the assets:precompile log and also using:
RAILS_ENV=production rake assets:clobber
and then
RAILS_ENV=production rake assets:precompile
public/assets do not include the images too.
Any reason why this is happening and how i can debug it?
@marinoszak Checkout the examples of
https://github.com/shakacode/react_on_rails/blob/master/spec/dummy/config/initializers/assets.rb#L14
@justin808 i managed to resolve the issue in the end.
I am using Rails 5.1.0.rc1.
My configuration inside initializers/assets.rb file is the same as with dummy.
The thing that i was missing is that i didn't include inside the Sprocket's manifest.js file under app/assets/config the directory where my webpack assets reside like so
//= link_tree ../webpack/webpack-assets
Most helpful comment
Here's what my
webpack.config.jsfile looks like -I can't remember exactly what fixed it but I'm pretty sure its going to assume your base route is
rails_root/app/and not in relation to therails_root/clientfolder. If you don't see the image in yourrails_root/app/assets/images/folder then you need to figure out why that is first.