I'm trying to load background image in React project from custom css file. I am using Webpack 4.
.bgimage {
height: 100vh;
background: url('../images/header.jpg');
}
But my image is not shown and I have this error in console:
ERROR in ./src/app/assets/images/header.jpg
Module build failed: SyntaxError: Unexpected character '�' (1:0)
I have tried to add url-loader to my webpack.config.js
{
test: /\.(png|jpg|gif)$/,
loader: "url-loader",
query: { mimetype: "image/png" }
}
But still image is not shown.
Solution:
I have found the solution that have worked for me. I have also installed file-loader and my background image was displayed.
File-loader installation:
https://www.npmjs.com/package/file-loader
Hope somebody will find it useful.
Related
I'm using Flowbite (both JS and CSS) in my application. JS was inserted and works (using Webpack and import 'flowbite' in the entry point JS).
For the CSS, I'm using this in the tailwind.config.js file as the documentation tells you to do.
module.exports = {
content: ['./src/**/*.{html,js}'],
theme: {
extend: {}
},
plugins: [
require('flowbite/plugin')
]
}
However when compiling everything (npx tailwind build) the CSS doesn't seem to be included in the final CSS file.
I can tell because the FlowBite modal should have a dark background (making everything except the modal darker), but that background does not appear when creating the compiled CSS.
When I do include the flowbite.css manually though, it does render correctly. So the current working solution I have is (in my HTML):
<!-- TODO: Adding the plugin in tailwind.config.js does not work -->
<link rel="stylesheet" href="https://unpkg.com/flowbite#latest/dist/flowbite.min.css" />
But I'd like to have it compiled automatically from the Tailwind build command.
Someone in the Discord community answered to me directly. I had to include this:
module.exports = {
content: ['./src/**/*.html', './node_modules/flowbite/**/*.js'],
plugins: [
require('flowbite/plugin')
]
}
The './node_modules/flowbite/**/*.js' in content was missing.
Tried many way doesn't work.
So I have quick fix, add this css:
.h-modal{
background-color: rgba(0,0,0,0.3);
}
Question
How can I globally import variables.scss 1. without importing them in every file and 2. by referencing instead of duplicating them in my build?
Setup
I use Vue2 and laravel-mix and I have index.scss imported in my main.js
variables.scss
$--test: #ff0000;
index.scss
#import 'variables';
.dashboard-title {
color: $--test;
}
This colors the title red. But when I try to do the same thing inside of the component, it doesnt work:
<style scoped lang="scss">
.dashboard-title {
color: $--test;
}
</style>
This doesn't work, but I proved that index.scss is global in my first example. How is
variables.scss not global, when I import it in my global index.scss?
I can fix the error by importing the variables file in the component, but by doing this, I essentially duplicate the whole variables.scss file every time I import it in a vue component.
I found this out by analyzing my bundle with a webpack bundle analyzer, this is the output:
webpack bundle analysis image (all blue crossed parts are increased in size because the variables file is imported, this isn't a big problem now, but this will exponentially increase my bundle size with time)
It would reduce my bundle size by atleast 20% right now...
How can I reference the variables.scss file instead of duplicating its content?
What I've tried:
https://css-tricks.com/how-to-import-a-sass-file-into-every-vue-component-in-an-app/ (I wasn't able to "migrate" this to a laravel-mix config)
I've also tried using purgeCss to remove duplicate css, this just completely messed up my styles but reduced the bundle size by 50% lol
Adding this to the webpack.mix.js
mix.webpackConfig({
module: {
rules: [
{
test: /\.scss$/,
use: [
{
loader: 'sass-loader',
options: {
//this might be "data" or "prependData" depening on your version
additionalData: `#import "./resources/js/styles/variables.scss";`
}
}
]
}
]
}
})
This does make the variables global, but imports(duplicates) them for every vue component, even if they aren't being used.
Edit: This only is an issue, when the imported file is relatively big. In my project, the imported file itsself imported a theme scss (to get access to the themes variables), which ultimately copied this whole thing everywhere I needed the variables.
I fixed this by defining my custom variables in a seperate file and using those variables in the "overwriting-variables" file, something like this:
custom-variables.scss
$red: #ff0000;
overwriting-variables.scss
import 'theme.scss'; //this bloated my project
import 'custom-variables';
$--theme-red: $red
And when I needed this theme color in my vue components I just imported the custom-variables.scss instead of overwriting-variables.scss.
This does fix my bloating issue, but doesn't fully solve the problem, I still have multiple instances of the custom-variables.scss in my project, it just doesn't matter (yet) because its really small. So I'd be still happy to hear about other solutions!
If you import every .scss in your index.scss, then every variable should work. Try this in your vue.config
css: {
loaderOptions: {
// by default the `sass` option will apply to both syntaxes
// because `scss` syntax is also processed by sass-loader underlyingly
// but when configuring the `data` option
// `scss` syntax requires an semicolon at the end of a statement, while `sass` syntax requires none
// in that case, we can target the `scss` syntax separately using the `scss` option
scss: {
prependData: `#import "#/style/index.scss"`
}
}
},
So I got it working with laravel-mix like this:
mix.webpackConfig({
module: {
rules: [
{
test: /\.scss$/,
use: [
{
loader: 'sass-loader',
options: {
//this might be "data" or "prependData" depening on your version
additionalData: `#import "./resources/js/styles/variables.scss";`
}
}
]
}
]
}
})
Not sure yet if this prevents the duplication though
Edit: It does not prevent duplication, it does increase the bundle size in every vue component. So I now have a 150% bigger bundle, because the variables file is imported in every single vue component. Even if the variable isn't even used.
I added all files for template I should use in my Nuxt app (css, js, images etc.) into assets/theme folder. There is assets folder structure:
Inside assets/theme/sass/layout/_menu.scss I have this line:
background-image: url('../../css/images/close.svg');
Inside assets/theme/sass/layout/_main.scss I have this line:
#include vendor('background-image', (
'linear-gradient(to top, #{$overlay}, #{$overlay})',
'url("../../images/banner.jpg")',
It is correct path to svg file (also autocomplete works fine) but when I run app, I get error:
These relative modules were not found:
* ../../css/images/close.svg in ./node_modules/css-loader/dist/cjs.js??ref--9-oneOf-1-1!./node_modules/postcss-loader/src??ref--9-oneOf-1-2!./node_modules/sass-loader/lib/loader.js??ref--9-oneOf-1-3!./assets/scss/main.scss
* ../../images/banner.jpg in ./node_modules/css-loader/dist/cjs.js??ref--9-oneOf-1-1!./node_modules/postcss-loader/src??ref--9-oneOf-1-2!./node_modules/sass-loader/lib/loader.js??ref--9-oneOf-1-3!./assets/scss/main.scss
In assets/scss/ I have main.scss file that is my global file to import all other css, scss etc:
#import '../theme/css/main.css';
#import '../theme/sass/main';
Does anyone know what is the problem?
According to the offical documentation:
Inside your css files, if you need to reference your assets
directory, use ~assets/your_image.png(without a slash)
In your case i presume this will work:
background-image: url(~assets/theme/css/images/close.svg);
https://nuxtjs.org/docs/2.x/directory-structure/assets#images
did you solved it?
this works for me:
1. I added #nuxtjs/style-resources dependency to project
2. This is part of my nuxt.config.js:
css: ['~assets/css/styles.less'],
modules: [
['#nuxtjs/style-resources'],
],
styleResources: {
less: './assets/css/modules/*.less'
},
In css-loader v0.28, I used root option ,but In css-loader v1.0.0,the option was removed,I checked the changelog(https://github.com/webpack-contrib/css-loader/blob/master/CHANGELOG.md) and Found this:
remove root option, use postcss-loader with postcss-url plugin
but I could not integrate postcss-url very well.
for example,my previous css-loader option was:
{
loader: 'css-loader',
options: {
root: 'static',
minimize: true
}
}
So when I wrote some css snippet like that :
background-image: url("/mobile/img/logo-new.png");
after css-loader parsed,it would changed to:
background-image: url("/static/mobile/img/logo-new.png");
I like previous style but maybe we should upgrade css-loader,so should use postcss-url.I could not use it very well,the docs also could not give me more info,so I came here and hope someone could help me.
what postcss-url option should I use to get the correct answer?
I'm having problems getting css background images showing when using webpack.
I have the following css class:
.fb {
display: block;
width:30px;
height: 30px;
background-color: red;
background-image: url('../images/icons/facebook.png');
}
Usage (Using React so className not class):
<div className="fb"></div>
Below is an image of my 'web_build' folder where webpack bundles all my files into. Highlighted is the culprit image.
The following is the bundles SCSS files which I see in the Network tab of chrome dev tools. No images files show on the 'Img' tab.
.fb {
display: block;
width: 30px;
height: 30px;
background-color: red;
background-image: url(1b725f86d1e04faadfad0cda2ac6ee89.png);
}
All I see rendered is a 30x30px red square.
NOTES:
If I directly reference the image using an <img> tag, the image shows.
I'm using webpack-dev-server
I'm using image-webpack-loader with the following configuration
{
test: /\.(jpe?g|png|gif|svg|ttf|eot|svg|woff(2)?)$/i,
loaders: [
'file?hash=sha512&digest=hex&name=[hash].[ext]',
'image-webpack?bypassOnDebug&optimizationLevel=7&interlaced=false'
]
},
Let me know if any other information is needed.
Thanks.
After some more searching around it turns out that including sourceMap in my CSS/SASS bundling breaks relative image URLs in CSS.
Solution: Turn sourcemaps off or specify a fully qualified publicPath URL.
The following worked for me.
publicPath: 'http://localhost:8080'
More information here
https://github.com/webpack/style-loader/issues/55
The image-webpack-loader only compresses the images using imagemin.
Use url-loader or file-loader to load the file into your css.