Webpack doesn't load images from css after build - css

When I run npm run build "build": "webpack" webpack produces dist folder for me with main.css, index.html and index.js but the images from CSS or from HTML don't work and they are not there.
In CSS in dist folder they are referenced like so
background-image: url("../../../assets/img/works/works-3.jpg");
And in HTML
<img src="./assets/img/logo.png">
I'm not sure what to fix so my images are working.
I have this webpack config
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const SpritesmithPlugin = require('webpack-spritesmith');
var path = require('path');
module.exports = {
mode: 'development',
entry: './src/app.js',
module: {
rules: [
{
test: /\.css$|\.sass$|\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader?url=false'
},
{ loader: 'sass-loader' }
]
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
},
{test: /\.png$|jpg|jpeg/, use: [
'file-loader?name=i/[hash].[ext]'
]}
]
},
resolve: {
extensions: ['.js', '.es6'],
modules: ['node_modules', 'spritesmith-generated']
},
output: {
path: __dirname + '/dist',
filename: 'index.js'
},
devServer: {
port: 8080,
contentBase: './src',
watchContentBase: true
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css'
}),
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new SpritesmithPlugin({
src: {
cwd: path.resolve(__dirname, 'src/assets/img/icons'),
glob: '*.png'
},
target: {
image: path.resolve(__dirname, 'src/spritesmith-generated/sprite.png'),
css: path.resolve(__dirname, 'src/spritesmith-generated/sprite.scss')
},
apiOptions: {
cssImageRef: '../spritesmith-generated/sprite.png'
}
})
]
};
UPD installed Copy Webpack Plugin and copied assets folder to dist folder. Images in HTML are working fine, but images in CSS do not.

After using CopyWebpackPlugin you need to need to change your background-url to /dist/images/imageName . But it depends how are structuring your build folder. This plugin copy all assets to your build folder so you need to import them from your dist folder.

Related

Correct way to transpile SCSS files but not CSS files in Webpack 5

I have two entrypoints for stylesheets.
src/css/preprocess.scss
src/css/skippreprocessing.css
I want my Webpack 5 project to preprocess the SCSS file, but NOT the CSS file--I want the CSS file to just be published to the dist folder as-is.
I've included my best guess below. Something is wrong with it though; it breaks hot-reloading. Or rather, hot-reloading only works for the non-preprocessed file. It's like the two rules become linked somehow (I'm guessing because of the shared MiniCssExtractPlugin).
So I'm wondering, what's the correct way to make those two rules (handling CSS files and SCSS files) be considered completely separate things.
(Note: In my actual case I'm compiling JS files too, but I've removed those below for the sake of brevity.)
My Best Guess
const webpack = require('webpack');
const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
target: 'web',
entry: {
preprocess: [
'./src/css/preprocess.scss',
],
skippreprocessing: [
'./src/css/skippreprocessing.css',
]
},
output: {
path: path.resolve(__dirname, './dist'),
filename: '[name].min.js',
},
module: {
rules: [
{
test: /\.css$/,
exclude: /node_modules/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
],
},
{
test: /\.scss$/,
exclude: /node_modules/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
'sass-loader'
],
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, './src/index.html'),
filename: 'index.html',
minify: false,
}),
],
devServer: {
static: {
directory: path.resolve(__dirname, './dist'),
},
hot: true,
port: 8080,
},
};

CSS doesn't render on `npm run start` command

When I run npm run start for my project, my HTML and JS work great, but my CSS does not render. Screenshot below.
I bundled using webpack. I'm absolutely certain (and double checked) that my style.css file is linked in my index.html file.
My webpack.config.js file is below - could the issue lay there?
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: ['babel-polyfill', './src/js/index.js'],
output: {
path: path.resolve(__dirname, 'src'),
filename: 'js/bundle.js'
},
devServer: {
contentBase: './dist'
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: './src/index.html'
})
],
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader:'babel-loader'
}
}
]
}
};
File Path:

Cannot resolve relative URL

When I use a relative url in an SCSS file (I am trying to set the background-image property to a local file), I receive the following error:
Any idea how what is going wrong?
I have a project with the following structure:
public/
dist/
images/
wave.png
index.html
src/
components/
MyComponent.js
app.js
styles/
base/
components/
_my-component.scss
styles.scss
webpack.config.js
In MyComponent.js I render <div className="bg"></div>.
In _my-component.scss I have:
.bg {
background-image: url("/images/wave.png");
}
And in webpack.config.js I have:
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = (env) => {
const isProduction = env === "production";
return {
entry: ["./src/app.js"],
output: {
path: path.join(__dirname, "public", "dist"),
filename: "bundle.js"
},
module: {
rules: [
{
test: /\.js$/,
loader: "babel-loader",
exclude: /node_modules/
},
{
test: /\.s?css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
sourceMap: true
}
},
{
loader: "sass-loader",
options: {
sourceMap: true
}
}
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: "styles.css"
})
],
devtool: isProduction ? "source-map" : "inline-source-map",
devServer: {
contentBase: path.join(__dirname, "public"),
historyApiFallback: true,
publicPath: "/dist/"
}
};
};
In _my-component.scss, directories are only relative to this file. According to your directory tree, you would need to go up 2 directories, which is essentially back to the root/home directory, and then one directory down to the public folder.
Try this path in your script: ../../public/images/wave.png

webpack build css img url cant get reletive path

I am using webpack with reactJs.
I am trying, with css, to set background-image.
when I build my project I always get the same path for img url no matter what I try.
'http://localhost:8080/images/img1.png '
instead of - 'http://localhost:8080/dist/images/img1.png'
Folder structure:
src/
App/
app.jsx
app.html
app.css
public/
images/
img1.png
img2.png
index.jsx
index.html
dist/
images/
img1.png
img2.png
bundle.js
main.bundle.css
index.html
webpack.config.js
webpack.config.js
var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
// HTML plugin options
let htmlOptions = {
template: './src/index.html',
filename: 'index.html',
inject: 'body',
}
module.exports = {
entry: './src/index.jsx',
output: {
path: path.resolve('dist'),
filename: 'bundle.js',
},
resolve: {
extensions: ['.js', '.jsx', '.css']
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015', 'stage-3']
},
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.jpe?g$|\.ico$|\.gif$|\.png$|\.svg$|\.wav$|\.mp3$/,
loader: 'file-loader',
options: {
outputPath: 'img/',
name: '[name].[ext]',
publicPath: '/dist'
}
},
{
test: /\.(ttf|eot|woff|woff2)$/,
use: {
loader: "file-loader",
options: {
name: "fonts/[name].[ext]",
},
},
},
]
},
devtool: 'source-map',
plugins: [
new HtmlWebpackPlugin(htmlOptions),
new CleanWebpackPlugin(['dist']),
new CopyWebpackPlugin([{ from: __dirname + '/src/public' }])
],
devServer: {
historyApiFallback: true
}
}
app.css
body{
background-image: url('/images/loginImageBg.png');
}
**I have tried **
plugins : new ExtractTextPlugin - for some resone Conflicts with cleanWebpackPlugin.
url-loader
query: {outputPath: './data/'}
publicPath , outputPath
nothing I do seems to work
Please help !

Wrong url addresses in CSS after bundling

When I bundling CSS from packages in node_modules, I get trouble with relativity of paths.
In original stylesheets images are requested from child folder. After bundling through Webpack folder names are right, but there is no ../ before path to image.
Attaching all, what I can provide, including project folder structure and webpack's config.
vendor.scss
#import "~leaflet/dist/leaflet.css";
#import "~leaflet-draw/dist/leaflet.draw.css";
#import "~leaflet-easybutton/src/easy-button.css";
Image imports in original leaflet.draw (css and html are in one folder)
url('images/[filename].[ext]')
Image imports after bundling (css is in child folder)
url('img/[filename].[ext]')
Folders structure
node_modules/
- leaflet-draw/
- - dist/
- - - leaflet-draw.css
- - - images/
- - - - [images]
src/
- scss/
- - vendor.scss
- index.html
dist/
- css/
- - vendor.css
- img/
- - [images from imported css]
- index.html
webpack.cofing.js
const path = require('path');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const HtmlWebPackPlugin = require("html-webpack-plugin");
module.exports = {
mode: 'development',
entry: {
'vendor': [
'./src/js/vendor.js',
'./src/scss/vendor.scss'
],
'fa': './src/js/fa.js',
'sanAndreas': [
'./src/js/sa.js',
'./src/scss/sa.scss'
]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'js/[name].js',
sourceMapFilename: '[file].map'
},
module: {
rules: [{
test: /\.js$/,
include: path.resolve(__dirname, 'src/js'),
use: {
loader: 'babel-loader',
options: {
presets: 'env'
}
}
},
{
test: /\.(png|jpg|gif|svg)$/,
use: [
{
loader: 'file-loader',
options: {name: 'img/[name].[ext]'}
},
]
},
{
test: /\.(sass|scss)$/,
include: path.resolve(__dirname, 'src/scss'),
use: ExtractTextPlugin.extract({
use: [{
loader: "css-loader",
options: {
sourceMap: true,
minimize: true
}
},
{
loader: 'resolve-url-loader'
},
{
loader: "sass-loader",
options: {
sourceMap: true
}
},
]
})
},
{
test: /\.html$/,
use: [
{
loader: "html-loader",
options: { minimize: true }
}
]
},
]
},
devtool: "source-map",
plugins: [
new CleanWebpackPlugin(['dist']),
new ExtractTextPlugin({
filename: './css/[name].css',
allChunks: true
}),
new HtmlWebPackPlugin({
template: "./src/index.html",
filename: "./index.html",
inject: false
}),
new HtmlWebPackPlugin({
template: "./src/sa.html",
filename: "./sa.html",
chunks: ['vendor', 'sanAndreas', 'fa']
}),
new HtmlWebPackPlugin({
template: "./src/five.html",
filename: "./five.html",
chunks: []
})
]
}

Resources