syko syko - 2 months ago 33
HTML Question

Webpack: Loading images from html templates

I'm trying to set up an angular project using Webpack but I can't figure out how to reference images from within html templates and have them included in the build.

My project tree is as follows:

package.json
app/
- images/
- foo.png
- scripts/
- styles/
- templates/


I'm trying to user
html-loader
along with
url-loader
and
file-loader
but it's just not happening.

This is an example template
app/templates/foo.html
.

<img src="../images/foo.png" />


Problem #1: I would like to be able to reference images relative to
app/
. Right now the paths need to be relative to the template file and this will get ugly very quickly (
../../../images/foo.png
).

Problem #2: Even if I specify the relative path as I have done above, the build is successful but nothing really happens. The paths are left as-is and no images appear in
dist/
.

Here is my webpack config:

var path = require('path');
var webpack = require('webpack');
var ngminPlugin = require('ngmin-webpack-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var ngAnnotatePlugin = require('ng-annotate-webpack-plugin');
module.exports = function(config, env) {
var appRoot = path.join(__dirname, 'app/')
if(!env) env = 'development';
var webpackConfig = {
cache: true,
debug: true,
contentBase: appRoot,
entry: {
app: path.join(appRoot, '/scripts/app.coffee')
},

output: {
path: path.join(__dirname, 'dist/),
publicPath: '/',
libraryTarget: 'var',
filename: 'scripts/[name].[hash].js',
chunkFilename: '[name].[chunkhash].js'
},

module: {
loaders: [
{
test: /\.css$/,
loader: ExtractTextPlugin.extract("style-loader", "css-loader")
},
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader!sass-loader?outputStyle=expanded&includePaths[]=./node_modules/foundation/scss/')
},
{
test: /\.coffee$/,
loader: 'coffee-loader'
},
{
loader: 'ngtemplate?relativeTo=' + (path.resolve(__dirname, './app')) + '/!html'
},
{
test: /\.png$/, loader: "url-loader?limit=100000&mimetype=image/png&name=[path][name].[hash].[ext]"
},
{
test: /\.jpg$/, loader: "file-loader?name=[path][name].[hash].[ext]"
},
{
test: /\.(woff|woff2)(\?(.*))?$/,
loader: 'url?prefix=factorynts/&limit=5000&mimetype=application/font-woff'
},
{
test: /\.ttf(\?(.*))?$/,
loader: 'file?prefix=fonts/'
},
{
test: /\.eot(\?(.*))?$/,
loader: 'file?prefix=fonts/'
},
{
test: /\.svg(\?(.*))?$/,
loader: 'file?prefix=fonts/'
},
{
test: /\.json$/,
loader: 'json'
}
]
},

resolve: {
extensions: [
'',
'.js',
'.coffee',
'.scss',
'.css'
],
root: [appRoot],
},

singleRun: true,
plugins: [
new webpack.ContextReplacementPlugin(/.*$/, /a^/),
new webpack.ProvidePlugin({
'_': 'lodash'
}),
new ExtractTextPlugin("styles/[name].[chunkhash].css", {allChunks: true}),
new HtmlWebpackPlugin({
template: appRoot + '/app.html',
filename: 'app.html',
inject: 'body',
chunks: ['app']
})
],
devtool: 'eval'
}

if(env === 'production') {
webpackConfig.plugins = webpackConfig.plugins.concat(
new ngAnnotatePlugin(),
new webpack.optimize.UglifyJsPlugin(),
new webpack.DefinePlugin({
'process-env': {
'NODE_ENV': JSON.stringify('production')
}
}),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin()
);
webpackConfig.devtool = false;
webpackConfig.debug = false;
}
return webpackConfig;


}

A_J A_J
Answer
  1. Yes, you will have to do so for loading images from different path.
  2. I had similar issue and I resolved this using file loader:

.

loaders: [{
  // JS LOADER
  test: /\.js$/,
  loader: 'babel?optional[]=runtime',
  exclude: /node_modules/
}, {
  // ASSET LOADER
  test: /\.(woff|woff2|ttf|eot)$/,
  loader: 'file'
},
{
  //IMAGE LOADER
  test: /\.(jpe?g|png|gif|svg)$/i,
  loader:'file'
},
{
  // HTML LOADER
  test: /\.html$/,
  loader: 'html-loader'
},
{
  //SCSS LOADER
  test: /\.scss$/,
  loaders: ["style", "css", "sass?indentedSyntax"]
}
]

Good Luck