PatrickJS/NG6-starter

How to have inline assets working in production bundling?

FarhadG opened this issue · 7 comments

I've tried several times to configure Webpack to be able to bundle inline assets, such as <img src="path/images/xyz.jpg" />, however, the paths do not get updated within the dist bundle and I don't believe the assets are there either.

Any ideas?

The things I had to do to make it work:

npm install file-loader --save-dev
npm install image-webpack-loader --save-dev

Inside webpack.config.js add resolve url to stylus, this is for css loaded images (e.g. background url('../assets/images/bg.jpg'))

{ test: /\.styl$/, loader: 'style!css!stylus?resolve url' },

Now add the image loader to the loaders array (you can remove any other image loaders in case you have any to avoid overrides)

{ 
   test: /\.(gif|png|jpg|jpeg|svg)$/i,
   loaders: ['file-loader?hash=sha512&digest=hex&name=[hash].[ext]', 'image-webpack-loader']
}

Make sure the path to image is always relative to the path your .html or .styl is in. For example my asset is in client/assets/images/bg.jpg so from inside client/app/app.html I refer it like <img src="../assets/images/bg.jpg"/>

Thank you for the answer, @vivaPQ. I had to run a very similar configuration to get assets to load within my styles files as those loaders are targeting them and able to parse the import statement. However, I'm running into this issue within my template files. For example, the <img src="path/images/xyz.jpg" /> sits within my HTML file and those loaders you mentioned above are not triggered, since it's a different file type.

In short, how do we go about importing assets within template files?

Thanks, in advance, for the help.

Ah.. I see.. so the issue here is also when you want to distribute the app.. the dist does not have the assets, only the hashed ones loaded via the image resolver form .styl files but not the ones form img tags.

In the end I had to just follow what #139 @jvalen recommends. Remove all of above suggestions so that you don't get duplicates in assets (some hashed some in assets/ folder) and then based on @jvalen suggestions:

npm install --save-dev copy-webpack-plugin

//webpack.dist.config.js

var CopyWebpackPlugin = require('copy-webpack-plugin');
...
config.plugins = config.plugins.concat([
  new CopyWebpackPlugin([
    { from: 'client/assets', to: 'assets' }
  ]),
...
]);

Like this in .styl files works for me with url('/assets/images/bg.jpg') while in img tags <img class="logo" src="./assets/images/logo.png"/> (notice ./ at start)

The assets get copied in dist folder so they are accessible.

Awesome! That's the type of workflow I implemented, @vivaPQ, but with a gulp process for moving the assets into the fist directory.

  1. Any advantages of doing this within Webpack?
  2. How did you mean by removing the duplicates that are generated via the image and style loaders and the copying of the assets over? As in, all of the images that are referenced inside of my styles are hashed and carried over to the dist as you mentioned, however, with the approach of copying over the entire assets directory, you're getting those same images carried over, as well. I guess it's not that big of a deal, but was curious...

Thanks, again, for the help.

Cool

  1. I don't really think it makes any difference as long as the files are there for you (runtime and deploy time);
  2. I didn't find a solution for not duplicating it.. just by removing the loaders: ['file-loader?hash=sha512&digest=hex&name=[hash].[ext]', 'image-webpack-loader'] but then it might break the .styl url

Yeah, good point.

I noticed we could also leverage the html-loader to be able to require assets within html templates.