url in scss files using raw in Webpack not working - javascript

I am currently working on an Angular 2 project, using webpack.
I am using the same kind of configuration as
https://angular.io/docs/ts/latest/guide/webpack.html#!#loaders
I have an application-wide file scss (styles.scss), located in ./public/scss/styles.scss which is correctly linked in my index.html after webpacking.
<link href="/app.27a803de076ae294258e.css" rel="stylesheet">
Other scss files (located in src/app) are component-scoped styles, they are loaded as string via raw loader, and inlined in "style" tag.
SVG files are managed via file-loader, they are copied into an "assets" output folder, and renamed with a hash.
For an unknown reason, all svg files mentioned in component-scoped styles via 'url()' are not found by the application, as if they were not required during the webpack step. They do not appear in the output assets folder. The 'url()' statement is not modified.
I would expect these lines would be replaced by a "require ..." and that require would trigger the file loader used for svg.
Here are my loaders from the webpack.config.js :
loaders: [
{
test: /\.ts$/,
loaders: ['awesome-typescript-loader', 'angular2-template-loader']
},
{
test: /\.html$/,
loader: 'html'
},
{
test: /\.scss$/,
exclude: helpers.root('src', 'app'),
loader: ExtractTextPlugin.extract('style', 'css?sourceMap!sass?sourceMap')
},
{
test: /\.scss$/,
include: helpers.root('src', 'app'),
loaders: ['raw', 'sass?sourceMap']
},
{
test: /\.css$/,
include: helpers.root('src', 'app'),
loader: 'raw'
},
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico|otf)$/,
loader: 'file-loader?name=assets/[name].[hash].[ext]'
}
]
Here is an example of one component scss files :
.back-button {
background: url(public/images/back.svg) no-repeat left;
width: 16px;
height: 19px;
background-size: contain;
margin-left: 15px;
}
If I move the content of this .scss in the main file styles.scss, the image is correctly added to the assets folder, and the content of the url() is correctly replaced :
.back-button {
background: url(/assets/back.be6884cba01794a64105228e8e25ce66.svg) no-repeat 0;
width: 16px;
height: 19px;
background-size: contain;
margin-left: 15px;
}
I supposed it has something to do with the fact that component scss are loaded inline in the style tag.
Thanks in advance :)

Related

Webpack loader configuration to load css and sass files for React JS

I have installed react-h5-audio-player in a React app made with create-react-app and it worked fine.
I did same to customized React project and I am being asked to configure webpack to load the css files.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
}
};
I have attached screenshot of error log and code section where error happened
The error (
ERROR in ./node_modules/react-h5-audio-player/lib/styles.css 1:0
Module parse failed: Unexpected token (1:0)
) happened in the below css file, these css files are made by installed audio player (which is made with typescript)
.rhap_container {
box-sizing: border-box;
display: flex;
flex-direction: column;
line-height: 1;
font-family: inherit;
width: 100%;
padding: 10px 15px;
background-color: #fff;
box-shadow: 0 0 3px 0 rgba(0, 0, 0, 0.2);
}
.rhap_container:focus:not(:focus-visible) {
outline: 0;
}
You need to add css-loader and style-loader to enable your webpack to bundle CSS files:
Install the loaders:
npm install css-loader style-loader --save-dev
npm install sass-loader node-sass --save-dev
Set the rules in webpack config:
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.css$/,
loader: ["style-loader", "css-loader"],
},
{
test: /\.s[ac]ss$/i,
use: [
// Creates `style` nodes from JS strings
'style-loader',
// Translates CSS into CommonJS
'css-loader',
// Compiles Sass to CSS
'sass-loader',
],
},
]
}
};
Check css-loader, style-loader and sass-loader

How do I circumvent a file loader?

In my webpack.config.js I have this:
module: {
loaders: [
{
test: /\.css$/,
include: APP_DIR,
loader: 'style-loader!css-loader',
},
{
test: /\.scss$/,
include: APP_DIR,
loaders: ['style-loader', 'css-loader', 'sass-loader'],
},
{
test: /\.svg$/,
loader: 'babel-loader!react-svg-loader',
},
],
},
Which I am using to import some svg files directly in Components.
However now I want to show a svg file that resides inside my React App folder via scss only. But the babel-loader!react-svg-loader is preventing it from happening. I am loading the scss via React.
This:
background-image: url('../assets/icons/pattern/size_35.svg');
Becomes
background-image: url([object Object]);
I can do this but it feels hackish:
background-image: url('[FULL_PATH_FROM_ROOT]/assets/icons/pattern/size_35.svg');
From my understanding is that for this case I should not have any file loader but because I already have one it's preventing this from working.
I do want to resolve the relative url from the React App though. So that this:
background-image: url('../assets/icons/pattern/size_35.svg');
becomes this
background-image: url('[FULL_PATH_FROM_ROOT]/assets/icons/pattern/size_35.svg');
in frontend.
If you only want to circumvent your react-svg-loader once, you can write the loaders inline:
background-image: url('!!file-loader!../assets/icons/pattern/size_35.svg');
If this will be a common occurrence, you can use a resourceQuery for the svgs you want to treat as files:
{
test: /\.svg$/,
oneOf: [
{
resourceQuery: /file/, // size_35.svg?file
use: 'file-loader'
},
{
use: 'babel-loader!react-svg-loader'
}
]
}

nextJS/webpack: How to handle SASS files with font

I'm trying to configure webpack of my nextJS application to handle some SASS files, which looks like this:
#font-face
font-family: 'Marcellus'
font-style: normal
font-weight: 400
src: local('Marcellus-Regular'), url('/fonts/marcellus/Marcellus-Regular.ttf') format('truetype')
The # gives me an unexpected token error. So I tried to add some custom webpack configuration:
module.exports = {
webpack: function (config) {
config.module = {
rules: [
{ test: /(\.sass$)/, loaders: ['sass-loader'] },
{ test: /(\.css$)/, loaders: ['style-loader', 'css-loader', 'postcss-loader'] },
{ test: /\.(png|woff|woff2|eot|ttf|svg)$/, loader: 'url-loader?limit=100000' }
]
}
return config
}
}
With this the *.js files aren't recognized anymore and I'm not quite sure if the SASS files are loaded correctly. I'm very unexperienced with webpack.
You need to add multiple loaders for the SASS file:
test: /\.sass$/,
use: [{
loader: 'style-loader', // creates style nodes from JS strings
}, {
loader: 'css-loader', // translates CSS into CommonJS
}, {
loader: 'sass-loader', // compiles Sass to CSS
}],
Source: Sass-loader

How to include images from CSS (backgrounds and etc.) to build folder using webpack?

I'm trying to use file loader to process images and include them into my build folder.
Images which are inside html files appear in build but images from styles not.
I keep my webpack config splitted into 2 files and use webpack merge module to merge them.
This is how i configure css processing:
exports.loadCSS = function (paths) {
return {
module: {
rules: [{
test: /\.scss$/,
include: paths.app,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
root: paths.root
}
},
'postcss-loader',
'sass-loader'
]
}]
}
};
};
And this is file loader configuration:
{
test: /\.(jpg|png|svg)$/,
loader: 'file-loader?name=[path][name].[hash].[ext]'
}
Piece of scss:
.img-from-styles {
width: 100px;
height: 100px;
background: url('/imgs/imgInStyles.jpg');
}
Here is project itself containing full configuration
You need to use url-loader
Install it
npm install url-loader --save-dev
How use it
{
test: /\.(png|jpg|jpeg|gif)$/,
loader: 'url-loader?limit=10000'
}
Now webpack will be able to resolve your url from your styles
Update
Webpack (css-loader) need exact file path so it can resolve the file or url for you.

using webpack dev server with css loader

I have error of http://localhost:8080/images/app.jpg not found error. I suspect it's because css-loader simply ignore the path when I try to do this in my css file
.section-a{
background-color: #red500;
background-image: url(/images/app.jpg);
background-position: center;
}
I don't have problem in my production config as I don't need to use localhost:8080 as root.
Any clue what else I need to do? I have my css loader config like below
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader']
})
},
{
test: /\.(png|jpg|jpeg|gif|svg|woff|woff2)$/,
loader: 'url-loader?limit=8192'
}

Categories

Resources