Reputation: 10926
I'm trying to move assets (images and fonts) used in one of my .scss
files, but it seems that they get ignored:
This is my .scss file:
@font-face {
font-family: 'myfont';
src: url('../../assets/fonts/myfont.ttf') format('truetype');
font-weight: 600;
font-style: normal;
}
body {
color: red;
font-family: 'myfont';
background: url('../../assets/images/bg.jpg');
}
And this is my webpack.config.js:
const path = require('path');
const { CheckerPlugin } = require('awesome-typescript-loader');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
target: 'node',
entry: path.resolve(__dirname, 'server.tsx'),
output: {
filename: 'server_bundle.js',
path: path.resolve(__dirname, 'build'),
publicPath: '/build'
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.jsx']
},
module: {
rules: [{
test: /\.(tsx|ts)?$/,
loader: 'awesome-typescript-loader',
options: {
jsx: 'react'
}
},
{
test: /\.(scss|sass|css)$/,
use: [
MiniCssExtractPlugin.loader,
{ loader: 'css-loader', options: { url: false, sourceMap: true } },
{ loader: 'sass-loader', options: { sourceMap: true } },
]
},
{
test: /\.(png|svg|jpg|jpeg|gif)$/,
loader: 'file-loader',
options: { outputPath: 'public/images' }
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
loader: 'file-loader',
options: { outputPath: 'public/fonts' }
}
]
},
plugins: [
new CheckerPlugin(),
new MiniCssExtractPlugin({
filename: 'public/styles_bundle.css',
chunkFilename: "public/styles/[id].css"
})
]
}
I'm getting this .css file in my browser as the output (Note the name of the image):
body {
color: red;
background: url("../../assets/images/myimage.jpg");
}
And in my public
directory I get this:
public/
styles_bundle.css
There are two problems here:
I've been trying everything, but I don't know what may be happening here... Any Ideas?
Upvotes: 14
Views: 17916
Reputation: 991
Had the exact problem with webpack 5. The answer is in Asset Modules
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
assetModuleFilename: 'images/[hash][ext][query]' //set the pattern for your filename here
},
module: {
rules: [
{
test: /\.png/,
type: 'asset/resource' //replaces file-loader, url-loader etc
}
]
},
};
Upvotes: 0
Reputation: 1697
The mini-css-extract-plugin
has a 'publicPath' option (see here). It basically tells the generated css where the external resources like fonts, images, etc are to be found. In my case, setting it to '../' and configuring all the file loaders to their proper directories, this worked perfectly.
Basically looks like:
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '/public/path/to/', // <-- This is what was helping.
},
},
'css-loader',
],
},
],
Upvotes: 1
Reputation: 1278
I had this issue too. I was using the following versions:
package.json
"mini-css-extract-plugin": "^0.10.1",
"webpack": "^5.3.1",
For me everything was compiling just fine until I added the following into a scss file:
.xmas {
background-image: url("./img/Xmas2020/SurveyBanner.png");
height: 150px;
}
The backgound-image url was the problem. When I changed it to an absolute path it worked:
.xmas {
background-image: url("/img/Xmas2020/SurveyBanner.png");
height: 150px;
}
webpack.config.js
This is just to show how I was putting images into the output directory. I guess there are different ways to do this, but I was using CopyWebpackPlugin.
plugins: [
new CopyWebpackPlugin({
patterns: [
{ from: './src/static/img', to: './img', force: true },
]
}),
]
This link helped me https://github.com/webpack-contrib/mini-css-extract-plugin/issues/286#issuecomment-455917803
Upvotes: 0
Reputation: 348
try the below configuration
{
test: /\.s[ac]ss$/i,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: ''
}
},
{
loader: "css-loader",
options: { sourceMap: true}
},{
loader: "sass-loader",
options: { sourceMap: true }
}
]
},
{
test: /\.(png|jpg|jpeg|gif)$/i,
loader: 'file-loader',
options: { outputPath: 'assets/images', publicPath: '../images', useRelativePaths: true }
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
loader: 'file-loader',
options: { outputPath: 'assets/fonts', publicPath: '../fonts', useRelativePaths: true }
}
After this my scss file started accepting the relative URL and the compiled files also mapped accordingly using relative path.
Upvotes: 2
Reputation: 658
you need url-loader
{
test: /\.(jpg|png|gif|woff|eot|ttf|svg)/,
use: {
loader: 'url-loader', // this need file-loader
options: {
limit: 50000
}
}
}
Upvotes: 4
Reputation: 834
I have just fixed a similar issue. If you change the url option to true, you might see failed image URL references.
{ loader: 'css-loader', options: { url: false, sourceMap: true } },
Or you can manual check whether the path reference is correct.
url('../../assets/images/bg.jpg')
I think the images folder doesn't get created because all the image resource links are incorrect.
For the problem I was fixing, the references were all wrong and I couldn't fix them so I just used this webpack copy plugin to copy files to the right dist folder location.
Upvotes: 8