How can we conditionally load a vendor css with webpack? - javascript

For example, if we have a vendor scss file named vendor.scss with the following content:
$color: green;
h1 {
background-color: $color;
}
How can we write the rules to achieve to following result? (Or similar)
let vendor = true; // this will be configured outside
if (vendor) {
let style = require('style-loader/useable!css-loader!./vendor.scss');
style.use(); //loads just if I call `use`, otherwise not
}
require('my-other-file.scss'); // loads normally, without `use`.
Because vendor.scss is a vendor scss/css we cannot or should not rename it to, for example, vendor.useable.scss.
And for maintaining purposes we would like to not create a new one like my-vendor-wrapper.scss that could wrap it with an #import inside of it.
In webpack, for now, I have this rule:
const ExtractTextPlugin = require('extract-text-webpack-plugin')
module.exports = {
// test: /\.(scss|sass|css)$/i,
test: /^(?!.*style-loader\/useable!).*\.(sass|scss|css)$/i,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader', 'postcss-loader', 'sass-loader']
})
}
I tried several things, like creating additional rules.
If I use an custom extension like lscss (for lazy scss) I can put it to work.
But the expected behavior that I would like is load all css/scss normally but if it have style-loader/useable! in front of it just loads if I call use.
How can we do this?

Related

CSS into JS using webpack

I`m trying to paste a CSS Code into a JS File using webpack
My flux is the following
SASS file > CSS content > PostCSS > css file
{
test: /\.(sass|scss)$/,
exclude: /node_modules/,
use: [
MiniCSSExtractPlugin.loader,
'css-loader',
'postcss-loader',
{
loader: 'sass-loader',
options: {
sourceMap: true,
sassOptions: {
outputStyle: 'compressed'
}
}
}
]
}
But the MiniCSSExtractPlugin gets me the content into a css file.
I'm use Lit Element so the styles should be declare with css function part of lit-element on the following way
import {css} from 'lit-element';
export default css`
:host {
display: inline;
}
`;
Is there any way to generate css code as a string and paste it into js file?
To import a CSS file into JS (w/webpack) you need to configure webpack with the following loaders:
css-loader
style-loader
Both available with NPM:
$ npm i css-loader style-loader --save-dev
And add this entry to the module.rules array in your webpack configuration:
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
}
The result
Both of this loaders correctly configured will allow you to do the following sentence in JavaScript:
import myStyles from './your-css-file.css';
And then, you can just paste them into literal templates as follows:
static get styles() {
return css`${myStyles}`;
}
Additionally:
With a deep knowledge into what you might be talking about, you might need to take a look around #cells/cells-cli files and add those loaders into webpack configuration. Otherwise, you may need to create a webpack.config.js file in every lit-element component, which might not be the best for the current architecture.
Nice to see you around here, ¡saludos!;)
#k3llydev, I tried your suggestion and couldn't get it to work. Do you have any suggestions, specifically when you say "both of these loaders correctly configured will allow you to do the following"? I'd like to be able to import the CSS and then use it directly in the styles getter like you show in your example, but I had to do this as a workaround:
import MyImportedStyle from './some.css';
static get styles () {
return [
css`${unsafeCSS(MyImportedStyle.toString())}`
];
}
While using the 'to-string-loader' in webpack:
{
test: /\.css$/i,
use: ['to-string-loader', 'css-loader'],
}
This worked out for me and did what I wanted, but if I could avoid using the to-string-loader and could use the imported object directly, that would be idea. Any suggestions?
This way should do what the original poster asked for, a way to get the CSS as a string and use it in your LitElement.

How can I recompile LESS manually in reactjs?

I have a ReactJs project which uses Webpack and Redux. I am using less for my stylesheets. In this project, I have colors.less file which looks like this -
//colors.less
#color1: red;
....
This file is imported to all the less files who are using this variable.
What I want is change this #color1 variable according to some API data and then the stylesheets should update with the new color. I have access to the this variable in my JS file, but on changing this color I want to reload the stylesheets as well.
Accessing the variable like below -
//utils/less-var-loader.js
const lessToJs = require('less-vars-to-js')
module.exports = function(content) {
return `module.exports = ${JSON.stringify(lessToJs(content))}`
}
//some.js which wants to modify the color
import * as styles from '!!../utils/less-var-loader!./common/colors.less'
styles['#color1'] = blue;
First add the below dependencies for webpack.
Add the less dependencies
webpack.config.js
,{
test: /\.less$/,
loaders: ['style', 'css', 'less']
}
Require it at your entry point.

Compiling SCSS into CSS and transpiling ES6 to ES5 simultaneously

So I have a SCSS file called style.scss. And I have an ES6 file called script.js. Both these files are in a ./src/ directory.
I want to use Webpack to take the style.scss, convert it to CSS and stick it into a folder called ./dist/ with the filename style.css. I can actually make that happen.
I also want Webpack to take the script.js, transpile to ES5, and put that in to the same ./dist/ folder with a file called script.js. I can also make that happen.
What I cannot do, is make both happen simultaneously. Is this something that Webpack can even do? In this instance I don't want all my styles putting into my JS, I specifically want them to be kept in separate files like a standard website (as that's what this is, really).
The closest I have got is this:
const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
entry: {
script: './src/script.js',
style: './src/style.scss'
},
output: {
path: './dist',
filename: '[name].js'
},
module: {
rules: [
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: ['css-loader', 'sass-loader']
})
}
]
},
plugins: [
new ExtractTextPlugin('style.css')
] }
But this gives me a script.js file, a style.css file and ALSO a style.js file which is a mess.
Any suggestions?
You don't want to create a separate entry point for the CSS. You can either import the style.scss in your script.js or you can add it to the same entry. An entry can also be an array and webpack will include them in the same bundle, well the CSS is extracted anyway so there won't really be any additional JavaScript. Your entry would be as follows:
entry: {
script: ['./src/script.js', './src/style.scss']
},

Multiple extract-text-webpack-plugin instances

Multiple extract-text-webpack-plugin instances
I want to do the following thing:
Merge many SVGs in a single sprite (done via svg-sprite-loader).
Extract sprite as separate file (done via svg-sprite-loader/lib/extract-svg-plugin, tiny wrapper over the extract-text-webpack-plugin which just wraps result with tags to get valid svg markup).
Return path to extracted SVG with fragment identifier which refers to specific sprite symbol, e.g. sprite.svg#image. This doable unless you want to refer SVG image (which extracts via extract plugin) in CSS which also extracts via second extract plugin instance.
Example (full example on GitHub):
webpack.config.js
var TextExtractPlugin = require('extract-text-webpack-plugin');
var CSSExtractor = new TextExtractPlugin('[name].css');
var SVGExtractor = new TextExtractPlugin('[name].svg');
module: {
loaders: [
{
test: /\.css$/,
loader: CSSExtractor.extract('css')
},
{
test: /\.svg$/,
loader: SVGExtractor.extract('raw') // emulate svg-sprite-loader
}
]
}
styles.css
.img {
background-image: url('./image.svg');
}
CSS will be compiled to
.img {
background-image: url([object Object]);
}
I think it's because in first (SVG) extract compilation all image source was removed by extract-plugin, and in the second (CSS) extract compilation get's cached module result from webpack with empty content. I trying to patch extract plugin loader and return some result instead of // // removed by extract-text-webpack-plugin, but has no success. In second extract compilation image module still has empty content.
Is it possible to implement desired behaviour with extract plugin?
I've created GitHub repo with example.

webpack - how to stop the loader running twice?

All of my text imports in a big project are in the form:
var template = require('text!./foo.html');
I'd like to set webpack to automatically use text-loader, so I added the following to my config:
{ test: /\.html$/, loader: 'text-loader' }
Only problem is now my templates are being run through the loader twice, and I'm getting something like this in my bundle...
module.exports = 'module.exports = "<section class=\\"foobar\\" ...
How can I set the loader to only run once without removing all of the text! callouts from every one of my files? This isn't an option as I'm trying to migrate incrementally...
require('text!./foo.html') applies text-loader to the foo.html
{ test: /\.html$/, loader: 'text-loader' } applies text-loader to every html
Hence,your loader is applied twice.
You should remove text-loader from either of two and it will work fine

Categories

Resources