Brunch not picking up vendor CSS as expected - css

I'm trying to use Pure.css in my application. I've installed it using npm and have my brunch-config.js configured like so:
stylesheets: {
joinTo: {
'app.css': /^app/,
'vendor.css': /^(?!app)/
}
}
I expect vendor.css to be generated at this point, but it's not. However, if in my JavaScript, I say require('purecss');, then I get vendor.css generated...but I also get the JavaScript error Cannot find module 'purecss' from '<filename>'. I've also tried various permutations of #import 'purecss' in my CSS without success.
How does one consume vendor CSS from npm modules?

You should use npm config section, for example when I wanted to include node_modules/bootstrap/dist/css/bootstrap.css I had to put the following in my brunch-config.js:
npm: {
styles: {
bootstrap: ['dist/css/bootstrap.css']
}
}
That, combined with your section in files makes it write bootstrap's css into vendor.css.
Full brunch-config.js that works for me:
module.exports = {
files: {
javascripts: {
joinTo: {
'app.js': /^app/,
'vendor.js': /^(?!app)/
}
},
stylesheets: {
joinTo: {
'app.css': /^app/,
'vendor.css': /^(?!app)/
}
}
},
plugins: {
babel: { presets: ['es2015'] }
},
npm: {
styles: {
bootstrap: ['dist/css/bootstrap.css']
}
}
};

Related

postcss-conditionals with mixins (vite + postcss.config.js)

I'm having an issue converting my postcss conditionals to css. I'm using vite to process the files and output a css file. Everything seems to be working up until the point that I try to convert the conditionals (see below).
Here is my vite file:
import { defineConfig } from 'vite';
import postcss from './postcss.config.js';
import dns from 'dns';
dns.setDefaultResultOrder('verbatim');
export default defineConfig({
root: 'src',
build: {
manifest: 'vite-manifest.json',
rollupOptions: {
input: {
main: './src/scripts/main.js',
},
},
outDir: '../dist',
emptyOutDir: true,
},
css: {
postcss,
devSourcemap: true,
},
server: {
hmr: {
protocol: 'ws',
},
},
});
Here is a simplified version of my postcss file:
import atImport from 'postcss-import';
import atMixins from 'postcss-mixins';
import atIf from 'postcss-conditionals';
import nested from 'postcss-nested';
export default {
plugins: [
atImport,
atMixins,
atIf,
nested,
],
};
The mixin I'm trying to parse:
#define-mixin center-x $position, $distance {
position: absolute;
left: 50%;
transform: translateX(-50%);
#if $position == top {
top: $distance;
bottom: auto;
} #else {
top: auto;
bottom: $distance;
}
}
This gives me this error: [vite:css] postcss-conditionals: src\styles\base\mixins.css:6:5: Failed to parse expression file: src/styles/main.css error during build: CssSyntaxError: postcss-conditionals: src\styles\base\mixins.css:10:5: Failed to parse expression
Furthermore replacing the if else inside the mixin with:
#if 3 < 5 {
background: green;
}
doesn't give me that error.
Maybe the mixin variables aren't resolved yet before the conditionals can use them but I don't know how to get those resolved first. Really hope someone knows how to fix this.
Gave this another try today, still can't fix it so I replaced the following plugins:
postcss-for
postcss-each
postcss-each-variables
postcss-mixins
postcss-conditionals
for postcss-advanced-variables where combining conditionals and mixins works out of the box, the downside is that I have to use SASS syntax instead of postcss syntax but that's ok I guess.

TypeError: Cannot read property 'forEach' of undefined after upgrade to Nextjs 11

Have upgraded my project to nextjs 11 and unfortunately some of my code is erroring out.
I have equally upgraded React from 16.0.0 version to 17.0.0 so I could then upgrade to next.js.
This is the code snippet that is erroring out and its located in my next.config.js file:
config.module.rules[1].oneOf.forEach((moduleLoader, i) => {
Array.isArray(moduleLoader.use) && moduleLoader.use.forEach((l) => {
if (l.loader.includes("css-loader") && l.options.modules && l.options.modules.exportLocalsConvention) {
l.options = {
...l.options,
modules: {
...l.options.modules,
exportLocalsConvention: "camelCase",
}
}
}
});
});
If I remove the code entirely a different error pops up related to svg config on the same file :
webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
// svg to react component loader
config.module.rules.push({
test: /\.svg$/,
use: [{
loader: '#svgr/webpack',
options: {
"svgoConfig": {
"plugins": [{ "cleanupIDs": false }]
}
}
}],
})
Any ideas on what is happening?
I know they have new related features but not entirely sure how to go about it and ensure my project runs similarly.
Thanks
Next.js 11 now uses webpack 5 under the hood so you need to update your webpack config accordingly.
There is a small migration guide here, but it does not cover all the changes obviously.
I think you can also opt-out of webpack 5 for now, if you want to update Next.js but don't want to mess with webpack config for now:
// add this key in your next.config
module.exports = {
webpack5: false,
}

Unable to extend: TailwindCSS variants:

I am looking to extend the margin style and add the variant ['even'] to it.
I can add the variant like so:
module.exports = {
variants: {
margin: ['even'],
},
theme: {
...
}
}
It is my understanding that the above will override the margin styles default variants.
The documentation here shows the ability to extend a variant as to not remove all the defaults when adding the new variant (discussed more here).
I have tried this and not been successful:
module.exports = {
variants: {
extend: {
margin: ['even'],
},
},
theme: {
...
}
}
I must be doing something wrong or have a typo?
The reason I was unable to do this was because of my tailwindcss version being below 2.0. As #Jon suggested. Thanks! 2.0 release notes.

How do I parse CSS to prefix CSS selectors

I have the following my-file.css:
.a [data-smth] { ... }
.b .c.d { ... }
.e { ... }
#f { ... }
and I want to do something like the following (pseudocode) in Node.js:
let css = readFile('my-file.css')
let prefixedCss = prefixClasses(css, 'prfx-')
writeFile(prefixedCss, 'my-prefixed-file.css')
to end up with my-prefixed-file.css:
.prfx-a [data-smth] { ... }
.prfx-b .prfx-c.prfx-d { ... }
.prfx-e { ... }
#f { ... }
I have found these npm modules:
https://github.com/vic/prefix-css (hasn't been updated in years and has issues)
https://pegjs.org/ (requires lots of low-level AST configuration)
But I was wondering whether there are better/safer solutions that have already been tested/become standard practice ?
NOTE: The above file contents was just an example. I'm looking for a way to achieve this for files whose content is completely unknown to me. So I'm looking for a "universal" solution.
Any help would be most welcome & thank you in advance! :-)
You might want to check https://github.com/marceloucker/postcss-prefixer#postcss-prefixer.
postcss-prefixer
PostCSS plugin to add a prefix to all css selectors classes and ids.
Usage
With PostCSS cli:
Install postcss-cli and postcss-prefixer on your project directory:
npm install postcss-cli postcss-prefixer --save-dev
and at your package.json
"scripts": {
"postcss": "postcss input.css -u postcss-prefixer -o output.css"
}
Others
postcss([ require('postcss-prefixer')({ /* options */ }) ])
Options
prefix
Type: `string`<br>
Default: none
String to be used as prefix
ignore
Type: `array`<br>
Default: `[]`
Array of selectors to be ignored by the plugin, accepts string and regex.
Example
Example of usage with results generated by the plugin.
Code
const postcss = require('postcss');
const prefixer = require('postcss-prefixer');
const input = fs.readFileSync('path/to/file.css', 'utf-8');
const output = postcss([
prefixer({
prefix: 'prefix-'
ignore: [ /selector-/, '.ignore', '#ignore' ]
})
]).process(input);
Input:
#selector-one .example {
/* content */
}
.selector-two .example2 {
/* content */
}
#ignore .ignore {
/* content */
}
#ignore .other {
/* content */
}
Output:
#selector-one .prefix-example {
/* content */
}
.selector-two .prefix-example2 {
/* content */
}
#ignore .ignore {
/* content */
}
#ignore .prefix-other {
/* content */
}
Credits
Plugin based on postcss-class-prefix create by thompsongl.

Grunt browserify transform ReactJS then bundle

In my project I am using Grunt to build the javascript files, I have ReactJS components which makes Grunt complain about Error: Parsing file in one of my javascript file, caused by the JSX syntax:
"use strict";
var $ = require('jquery');
var React = require('react');
require('app/comments/comment_box_react.js');
$.fn.comment_box = function(options){
var opts = $.extend({}, $.fn.comment_box.defaults, options);
var me = this;
React.render(<CommentBox url="comments.json" />, this);
return me;
}
$.fn.comment_box.defaults = {}
My browerify config in Grunt looks like this:
browserify: {
main: {
files: {
'<%= paths.js_built %>/bundle.js': ['<%=paths.js %>/project.js'],
}
},
transform: ['reactify'],
},
How do I perform transform first before the bundle?
The transform example in their docs has the transform array in an options object.
browserify: {
dist: {
files: {
'build/module.js': ['client/scripts/**/*.js', 'client/scripts/**/*.coffee'],
},
options: {
transform: ['coffeeify']
}
}
}
Also, looks like your transform definition is outside of your main definition. Not sure if that would be global or not, so you might have to move it inside of main. Something like this
browserify: {
main: {
files: {
'<%= paths.js_built %>/bundle.js': ['<%=paths.js %>/project.js'],
},
options: {
transform: ['reactify']
}
}
}
I ended up using gulp and transform globally before bundle:
https://github.com/andreypopp/reactify/issues/66
gulp.task('activitiesjs', function() {
browserify({
entries: [
paths.js+'/lib/activities/activities.js',
]
}).transform(reactify, {global:true}).bundle().pipe(source('bundle.js')).pipe(gulp.dest(paths.js_built+'/activities'));
});

Resources