Loading local images with webpack - image

Hi I am trying to load local images with webpack, it compiles successfully however I get the following error (and no image)
GET http://192.168.1.196:3000/b09d0fa90cacadcad6ce1679aea3d2ee.png 404 (Not Found)
Here is my webpack.config.js file:
const path = require('path')
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'public/scripts'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['env']
}
}
},
{ test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192' }
]
},
devServer: {
contentBase: path.resolve(__dirname, 'public'),
publicPath: '/scripts/'
},
devtool: 'source-map'
}
Here is how I am importing the image
import goku from '../public/images/goku.png'
I am trying also with require in the img directly with the same result.
<img src =${require('../public/images/goku.png')}>
<img src =${goku}>

Your problem is actually that you missed a publicPath on output:
output: {
path: path.resolve(__dirname, 'public/scripts'),
filename: 'bundle.js',
publicPath: '/scripts/'
},
devServer: {
contentBase: path.resolve(__dirname, 'public'),
publicPath: '/scripts/'
},
The property publicPath on output has to match the publicPath on devServer.

Related

Webpack add query string to bundle for cache-busting

so in my index.html, I have this line to include the webpack bundle
<script src="/dist/bundle.js"></script>
And my webpack config looks like this:
const path = require("path");
const webpack = require("webpack");
module.exports = {
entry: "./src/main.js",
mode: "development",
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules|bower_components)/,
loader: "babel-loader",
options: { presets: ["#babel/env"] }
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
}
]
},
resolve: { extensions: ["*", ".js", ".jsx"] },
output: {
path: path.resolve(__dirname, "dist/"),
publicPath: "/dist/",
filename: "bundle.js"
},
devServer: {
contentBase: path.join(__dirname, "public/"),
port: 3000,
publicPath: "http://localhost:3000/dist/",
hotOnly: true
},
plugins: [new webpack.HotModuleReplacementPlugin()]
};
How could I modify this, to add a query string (?v=some_nr) to the bundle when I run webpack --mode production. I can copy the index.html to dist/index.html or some other location, if needed, I'll be moving it to the webroot automatically anyway afterwards.

Webpack generates wrong url for images that were included using file-loader

I am using webpack file-loader to include images in my build. Webpack compiles fine and copies images from dev/assets to dist/images
BUT the tag in the generated HTML is wrong:
<img src="/dist/images/triangle.svg">
It should be:
<img src="./images/triangle.svg">
Is my webpack config wrong for file-loader?
.vue file:
<div>
<img src='./images/thing.png'>
</div>
.style {
background: url('./images/anotherthing.png');
}
Webpack config (simplified)
module.exports = {
entry: './src/index.ts',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'build.js'
},
module: {
rules: [
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'images/'
}
}
]
}
webpack config (complete)
var path = require('path')
var webpack = require('webpack')
module.exports = {
entry: './src/index.ts',
output: {
path: path.resolve(__dirname, './dist/'),
publicPath: './',
filename: 'js/build.js'
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
'scss': 'vue-style-loader!css-loader!sass-loader',
'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax',
}
}
},
{
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/,
options: {
appendTsSuffixTo: [/\.vue$/],
}
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath:'./images/'
}
},
{
test: /\.(json)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: './data/'
}
}
]
},
resolve: {
extensions: ['.ts', '.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},
devServer: {
contentBase: './dist',
historyApiFallback: true,
noInfo: true
},
performance: {
hints: false
},
devtool: '#eval-source-map'
}
if (process.env.NODE_ENV === 'production') {
module.exports.devtool = '#source-map'
// http://vue-loader.vuejs.org/en/workflow/production.html
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
])
}
You probably just want to set publicPath: '/'.
Think of publicPath as the directory of your assets relative to the root of the public facing domain. If your server is serving files from /dist to example.com, that would mean that assets in /dist/images are publicly accessible at example.com/images (file-loader already adds the /images bit as you've witnessed).

Browser debugger not working with Webpack 2 and webpack-dev-server

I've spent last few hours to set up a new project utilizing Webpack 2 and Babel 6.
The problem I have is non working debugger (any browser). Breakpoints are simply ignored. Using debugger; works fine but browser does not breaks execution exactly in that line.
webpack.config.js:
const path = require("path");
module.exports = {
entry: path.resolve(__dirname, "src", "index.js"),
output: {
filename: "app.js",
path: path.resolve(__dirname, "dist")
},
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
}]
},
devServer: {
contentBase: path.resolve(__dirname, "dist")
}
};
.babel.rc:
{
"presets": [
"latest"
]
}
I'm running the whole thing with webpack-dev-server -d
devtool: "source-map", option in webpack config should solve your problem.
entry: ['babel-polyfill', './src/index.jsx'],
output: {
filename: 'js/bundle.[hash].js',
path: path.resolve(__dirname, 'build'),
publicPath: '/'
},
resolve: {
extensions: ['.js', '.jsx'],
alias: {
config: path.join(__dirname, `config/${env}.configuration.js`)
}
},
**devtool: "source-map",**
module: {
rules: [
{
test: require.resolve('jquery'),
use: [
{
loader: 'expose-loader',
options: 'jQuery'
}
]
},

Is it possible to load SASS in Webpack without bundling fonts BUT with source maps?

I don't want to bundle fonts and images but i need sourceMaps
I have this config (irrelevant parts ommited):
output: {
path: './build/',
publicPath: 'http://localhost:3000/',
filename: '[name].js'
},
module: {
loaders: [
{ test: /\.scss$/, loaders: ['style','css?-url,sourceMap', 'sass?sourceMap'] }
]
}
With this config I get multiple errors in Chrome:
Failed to decode downloaded font: http://localhost:3000/
(index):1 OTS parsing error: invalid version tag
I read a lot of answers and some solutions for similar problem:
1. get rid off 'sourceMap' - it works, and fonts are correctly displayed BUT ... no sourceMaps
2. change publicPath to URL - done it
I cannot find any solution that allows me load fonts outside bundle AND have CSS with sourceMaps...
I just figured it out. The key to solution is ExtractTextPlugin that makes normal link tags instead of 'blobs' and all fonts work super, css are external (even better when they are large), source maps work. Here is my full config if anyone interested:
var path = require('path');
var webpack = require('webpack')
var ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
entry: {
demo: ['./demo/index.ts', 'webpack-dev-server/client?http://localhost:3000'],
lib: ['./src/js/index.js']
},
output: {
path: './build/',
publicPath: '/',
filename: '[name].js'
},
debug: true,
devtool: 'source-map',
resolve: {
extensions: ['', '.ts', '.js']
},
module: {
loaders: [
{ test: /\.tsx?$/, loader: 'ts' },
{ test: /\.coffee$/, loader: 'coffee' },
{ test: /\.(png|jpg)$/, loader: 'url' },
{ test: /\.jsx?$/, loader: 'babel', query: { presets: ['es2015'] }, exclude: /node_modules/, },
{ test: /\.scss$/, loader: ExtractTextPlugin.extract('style', 'css?sourceMap!sass?sourceMap') },
{ test: /\.css$/, loader: ExtractTextPlugin.extract('style', 'css?sourceMap') },
{ test: /\.(ttf|eot|svg|woff(2)?)(\?[\s\S]+)?$/, loader: 'url' }
]
},
devServer: {
contentBase: './demo'
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery'
}),
new ExtractTextPlugin("[name].css", { allChunks: true })
]
};

Webpack, "hot-reload" or "live-reload" sass?

Is there a way to get webpack to "recompile" sass and reload your page on the fly?
I've been searching around but have not found an example.
Here is what I've got:
My folder structure
-app
---public
------dist
---------index.html
---------sass
------------webpack.scss
It seems like my sass only recompiles when I run webpack but it doesn't recompile when I am running the webpack-dev-server
var path = require('path');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var webpack = require('webpack');
module.exports = {
entry: {
app: './app/main.js',
//All 3rd party source
vendor: ['react', 'redux', 'lodash']
},
output: {
path: path.join(__dirname, 'app', 'public', 'dist'),
publicPath: '/app/public/dist/',
filename: 'app.js'
},
module: {
loaders: [
{ test: /\.js$/, loaders: ['react-hot', 'babel'], exclude: /node_modules/ },
{ test: /.jsx?$/, loader: 'babel-loader', exclude: /node_modules/ },
{ test: /\.css/, loader: ExtractTextPlugin.extract('css') },
{ test: /\.scss$/, loader: ExtractTextPlugin.extract('!css!sass?sourceMap') }
]
},
sassLoader: {
includePaths: [ path.resolve(__dirname, './app/public/sass/')]
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new webpack.optimize.CommonsChunkPlugin("vendor", "vendor.js", Infinity),
new ExtractTextPlugin('./css/style.css',{
allChunks: true
})
],
debug: true,
//watch: true
};

Resources