I'm using Webpack to process my CSS files. I want to rewrite url()s in CSS files to keep referencing the original assets, just changing the URL.
For example this file:
/* src/main.css */
body {
background-image: url('image.png');
}
should compile to this
/* bundle/main.css */
body {
background-image: url('../src/image.png');
}
I found the rewrite-url-loader but this just does not work at all for me, it does nothing.
I've got the feeling that file-loader may be able to do just what I want to do but I can't figure out how.
Anyone got an idea?
That was actually really easy.
I had to set Webpack's context option to point to my project root.
Then I could easily just use file-loader like this: file?emitFile=false&name=[path][name].[ext]&publicPath=../.
For Webpack 2 and Webpack 3:
use: [{
loader: 'file-loader',
options: {
context: path.resolve(__dirname, 'src')
name: '[path][name].[ext]'
},
},
For a full answer with example and explanation: https://stackoverflow.com/a/46931670/1049693
Related
I created a react setup for a little project and decided to add tailwind. It was successful but when I add the class to the components, I don't see any change.
This is the link to the repository
Everything seems fine. Once delete the node modules and package.lock.json file and install node modules then start the server.
Also, there is no need to import tailwind.css in App.js.
Just main.css is enough as we are already appending all the styles to main.css (check scripts in package.json)
I found the problem. It was from my webpack config for CSS loader. I noticed when I added my own stylesheet, not all the rules were applied.
{
loader: "css-loader",
options: {
modules: true,
importLoaders: 1,
sourceMap: true
}
}
I had to remove all the options. I don't even know why I added it at first. Tailwind CSS now works.
If you know that you've configured Tailwind and added the right settings and presets, maybe you need to add this:
module.exports = {
content: [
'./public/index.html', <-
],
}
or this, if you're using ReactJS:
module.exports = {
content: [
'./pages/**/*.{html,js}',
'./components/**/*.{html,js}'
],
// ...
}
Within your tailwind.config.js file.
You also can learn/read more about it on: https://tailwindcss.com/docs/content-configuration, that worked perfectly for me!
At the moment i'am currently re-factoring my code . So that means more clearness and higher maintance . I have an idea in my head , but unfortunately i don't know how this can be realeased.
In order to be more clean and effecient i want to create an isolated _colors.scss file that will contain all of my colors for the app . In other words i want it to look something like this
$colorPrimary: branding.colorPrimary,
$colorSecondary: branding.colorSecondary
...
At the moment is pretty messy because the color styling is maintened at the component level , but i want to do this seperately .
Ex:
<button style={
color: branding.colorPrimary,
background: branding.colorSecondary>
Hello
</button>
The colors are stored on the BE side so if i want to react them i have to do a call . I will be glad if someone can give me a hand with this mindf****. Thank you .
to acheive this behavior you have two main way to do it. the first one describe are not compatible with Internet Explorer.
On last CSS version describe on W3C we are able to have variable directly on CSS.
Like this backend can do something like this :
<head>
<style type="text/css">
:root {
--primary-color: #cecece;
--secondary-color: #fefefe;
}
</style>
</head>
then on your scss (or css) you can do something like :
.mySelector {
color: var(--primary-color, black);
}
which will be basically interpret as :
.mySelector {
color: #cecece;
}
Or fallback in color black if --primary-color is not defined.
As you can imagine, is very easy for backend to prepare the configuration for frontend. And from your side (as front end) you can simply use what is already available on CSS API tools.
But if you are looking for something which are compatible with IE. You probably need more complex infrastructure.
Goal is to spawn webpack sass compilation, on each User color change,
to build css output with relevant variable configuration.
for that you will need SaSS ressource loader which automatically inject sass file on all other file. Is like adding #import "_colors" automatically.
then backend server will have to :
Write _color.scss file somewhere (let say /user/123/_color.scss)
Ask for compilation like webpack client 123
read the output webpack folder for client 123 and detect if specific CSS exist
Inject on your head HTML.
For webpack configuration
on your webpack you will have something like :
const argv = require("yargs").argv;
entry: {
[...]
},
output: {
// Take the argument as clientId and craft dedicated output folder.
path: helpers.root(`public/themes/front/${argv.client}`),
filename: "[name].[contenthash].js",
chunkFilename: "[name].[contenthash].js"
}
Like this base on the client id you will store the outputed CSS on specific folder.
Finally the SaSS rules will looks like :
{
test: /\.scss$/,
use: [
'style-loader',
'css-loader',
'postcss-loader',
'sass-loader',
{
loader: 'sass-resources-loader',
options: {
resources: (argv.client) ? `/user/${ argv.client }/_color.scss` : `/user/default/_color.scss`,
},
},
],
}
I am trying to generate a static website out of my (minimal) code with Nuxt. In that code, I integrate in particular the tailwindcss toolkit as well as vue2-leaflet. Upon
nuxt generate
I get two css files, one for the tailwindcss css and the other for the leaflet css. While the former file is fine and contains everything I need, the latter is pretty sparse:
.leaflet-tile-pane{z-index:200}#-webkit-keyframes leaflet-gestures-fadein{to{opacity:1}}#keyframes leaflet-gestures-fadein{0%{opacity:0}to{opacity:1}}
Of course, that makes my map render in a pretty strange way, because most of the css is missing. Here's my current nuxt.config.js:
module.exports = {
mode: 'universal',
head: {
title: pkg.name,
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: pkg.description }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
]
},
css: [
],
plugins: [
{ src: '~plugins/leaflet.js', mode: 'client' }
],
buildModules: [
'#nuxtjs/tailwindcss'
],
modules: ['#nuxtjs/apollo', 'nuxt-purgecss', ['nuxt-i18n', i18n]],
[...]
build: {
extractCSS: true,
}
}
Getting rid of the extractCSS ends up incorporating all the relevant css into the index.html. It works, but then I get the following error:
ERROR Webpack mode only works with build.extractCSS set to *true*. Either extract your CSS or use 'postcss' mode
I'm not sure I understand how that whole css extraction works. Could someone enlighten me? Why is it not working with extractCSS: true? How can I make it work? Why is it working in SPA mode but not in static mode?
You are using nuxt-purgecss which is using purgecss to strip unused CSS.
purgecss do scan HTML (or vue) files for CSS classes in use and then strip unused classes from final CSS bundle.
You can take a look at default purgecss configuration used by nuxt-purgecss here. The paths lists the paths purgecss will scan for CSS usage.
Because you are not using most of the leaflet css directly (in your components), its is necessary to configure purgecss to don't remove leaflet's css.
You can do that by whitelisting (btw not sure if "comment" method will work in Vue\Nuxt)
You can read more here and here
Not tested!!
// nuxt.config.js
{
purgeCSS: {
whitelistPatterns: [/leaflet/, /marker/]
}
}
Regarding the error message
Error message is from nuxt-purgecss module - it is clearly documented here
I don't have deep knowledge of Nuxt build process. So I just assume from the docs that extractCSS: true will use extract-css-chunks-webpack-plugin to extract all CSS to separate CSS file, while (default) extractCSS: false will use PostCSS to extract all CSS and put it directly into the <style> tag of rendered page.
All of that doesn't matter IMHO because the root problem is the use of purgecss and the solution is to configure it correctly to whitelist leaflet CSS classes....
I'm having a lot of trouble working with SVG in my webpack workflow. I'm trying to get it to display with the background: url(sample.svg) property in CSS. Using this alone did not work, so I figured I had use a loader. Here are the steps I used.
I used svg-url-loader to load the SVG.
1.
I installed svg-url-loader via npm and added this to my module.exports:
{
test: /\.svg/,
use: {
loader: 'svg-url-loader'
}
},
2.
I added this to the top of my index.js file:
require('svg-url-loader!./images/topography.svg');
3.
I added background-image with the SVG path to my CSS:
body {
background-image: url("../images/topography.svg");
background-size: 340px, auto;
min-height: calc(100vh - 100px);
margin: 50px;
background-attachment: fixed;
letter-spacing: -1px;
}
4. The SVG is not being rendered to the page. When I inspect the body in browser, I find this:
background: url(data:image/svg+xml,module.exports = __webpack_public_path__ + '8dccca4….svg';);
I don't know too much about data-uri, so maybe I am running into the issue there.
Also, I've tried this using different SVG files, and none of them worked.
I met the same exact error. After some investigation I found I added another svg loader which caused this problem, so I fixed it by deleting the other svg loader:
{
test: /\.svg/,
use: {
loader: 'svg-url-loader'
}
},
{
test: /\.svg$/,
use: [
"babel-loader",
{
loader: "react-svg-loader",
options: {
svgo: {
plugins: [{ removeTitle: false }],
floatPrecision: 2
},
jsx: true
}
}
]
}
So you maybe also added some extra loaders to handle the svg files at the same time, please check.
You can:
a) set up loaders in webpack.config.js:
example.js:
import ExampleIcon from 'assets/icons/example-icon.svg';
...
<ExampleIcon className={styles.exampleIcon} />
webpack.config.js:
{
test: /\.svg$/,
use: [
{
loader: 'babel-loader',
},
{
loader: 'react-svg-loader',
options: {
svgo: {
plugins: [{ removeTitle: false }],
floatPrecision: 2
},
jsx: true
}
}
]
},
b) or set up loaders in the import string:
import ExampleIcon from '!babel-loader!react-svg-loader!assets/icons/example-icon.svg';
...
<ExampleIcon className={styles.exampleIcon} />
I met the same problem too. We have a custom url-loader which is based on url-loader and file-loader. When the size of svg is limited to 10Kb, it will call the url-loader to process the svg,otherwise it will call the file-loader to process. It seems ok,but the bundled file shows that it was processed twice by different loaders. The base64 encoded string was exported through module.exports, but in the page the path was not replaced. This is because I used vue-cli to create project, and the svg was processed by the file-loader. When I deleted the default configuration of file-loader, it worked as expected.
I had the same problem as you. Updating my file-loader from 2.x.x to the latest version fixed the issue.
I am using webpack to transpile my reactjs code. When I run it locally on webpack dev server, I can see my background image. However when I deploy it to the server the image doesn't show. I figure it must be some kind of path issue.
css
.centerbg {
background: url(/images/centerbg.jpg) no-repeat;
}
jsx
<div className="centerbg">
</div>
webpack loader
{
test: /\.(woff|ttf|eot|svg|png|jpg)(\?v=[a-z0-9]\.[a-z0-9]\.[a-z0-9])?$/,
loader: 'url-loader',
options: {
limit: 10000
}
}
File paths
build/main.js
images/centerbg.jpg
index.html
This is a bug usually dued to output.publicPath config not being explicitely declared.
Set it to the path where your assets will be served from. For basic scenarios this is enough:
output: {
publicPath: '/',
//...
},