Reputation: 397
I have a react project in which I'm using webpack 3.10.0 with file loader 1.1.6 to move some images and json files into my distribution folder.
Webpack emits the files as expected, but react receives the wrong urls for my json and images assets
My markup looks like:
<img src="../images/helloworld_a49183cf48e4a0f12aa2124fe2ed9d3a.png"
alt="Hello World!!">
but should be:
<img src="/assets/images/helloworld_a49183cf48e4a0f12aa2124fe2ed9d3a.png"
alt="Hello World!!">
My folder structure looks like below:
C:.
├───dist
│ └───assets
│ ├───css
│ ├───data
│ ├───images
│ └───js
├───src
│ ├───css
│ ├───data
│ ├───images
│ └───js
│ ├───actions
│ ├───components
│ ├───containers
│ └───reducers
└───tests
I thought file-loader publicPath should take care of this, but it seems I'm either misunderstanding or something is wrong with my configuration. Can someone be so kind to help me out?
webpack.config.js
var path = require('path');
const ExtractCSS = require("extract-text-webpack-plugin");
module.exports = {
entry: [
'./src/js/index.js'
],
output: {
path: path.resolve(__dirname, 'dist/assets/js'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['env','react']
}
}
},
{
test: /\.scss$/,
loader: ExtractCSS.extract('css-loader!sass-loader')
},
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name (file) {
/*if (env === 'development') {
return '[path][name].[ext]'
}*/
return '[name]_[hash].[ext]'
},
publicPath: '/assets/images/',
outputPath: '../images/'
}
}
]
},
{
test: /\.json$/,
use: [
{
loader: 'file-loader',
options: {
name (file) {
/*if (env === 'development') {
return '[path][name].[ext]'
}*/
return '[name].[ext]'
},
publicPath: '/assets/data/',
outputPath: '../data/'
}
}
]
}
]
},
plugins: [
new ExtractCSS('../css/app.css', {
allChunks: true
})
],
resolve: {
extensions: ['.js', '.jsx']
},
//devtool: 'eval-source-map',
devServer: {
historyApiFallback: true,
contentBase: './dist/'
}
};
Upvotes: 5
Views: 17089
Reputation: 397
This morning after my machine had rebooted, the issue changed?!!? (caching issue??!)... Instead of ignoring publicPath it now concatenated publicPath with outputPath. Same issue as explained here: https://github.com/webpack-contrib/file-loader/issues/228
Reverting back to 0.10.1 resolves my issue.
Thanks for everyone who tried to help!
Upvotes: 1
Reputation: 4008
You can also configure your output object to be a level above and then specify only the name of your files:
output: {
path: path.resolve(__dirname, 'dist/assets'),
filename: 'js/bundle.js'
},
And for example for the json:
{
test: /\.json$/,
use: [
{
loader: 'file-loader',
options: {
name: 'data/[name].[ext]',
}
}
]
}
Upvotes: 1
Reputation: 2735
So, instead of
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name (file) {
/*if (env === 'development') {
return '[path][name].[ext]'
}*/
return '[name]_[hash].[ext]'
},
publicPath: '/assets/images/',
outputPath: '../images/'
}
}
]
},
You could try something like
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name (file) {
/*if (env === 'development') {
return '[path][name].[ext]'
}*/
return '[name]_[hash].[ext]'
},
publicPath: function(url) {
return url.replace(../, '/assets/')
},
}
}
]
},
Upvotes: 3