Closed hipstersmoothie closed 5 years ago
There does not seem to be an easy way to convert a parsed mixin into a function...
It seem like with the recommended approach I'm basically rewriting what this plugin is already doing
Okay this seems to work with:
const mixinsPlugin = require('postcss-mixins');
const fs = require('fs');
const postcss = require('postcss');
const mixins = [
fs.readFileSync(require.resolve('@cgds/styles/elevation.css'), 'utf8'),
fs.readFileSync(require.resolve('@cgds/styles/typography.css'), 'utf8')
];
function makeMixinDefinition(file) {
const defs = {};
postcss.parse(file).walkAtRules('define-mixin', atrule => {
const name = atrule.params.split(/\s/, 1)[0];
defs[name] = atrule;
});
return defs;
}
module.exports = () => {
return {
plugins: [
mixinsPlugin({
mixins: mixins
.map(makeMixinDefinition)
.reduce((all, item) => ({ ...all, ...item }), {})
})
]
};
};
I get this error though:
(node:4723) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'length' of undefined
at /Users/alisowski/Documents/cgds/components/Card/src/Card.css:2:3
at insertMixin (/Users/alisowski/Documents/cgds/node_modules/postcss-mixins/index.js:66:31)
I have fixed this error here https://github.com/postcss/postcss-mixins/pull/98
You should have an object
not an array
require('postcss-mixins')({
mixins: {
clearfix: {
'&::after': {
content: '""',
display: 'table',
clear: 'both'
}
}
}
});
It gets reduced into and array.
mixins: mixins
.map(makeMixinDefinition)
.reduce((all, item) => ({ ...all, ...item }), {})
Can you give me more details about your use case? I remember that you can’t use sync methods because of the limit of the TS processor.
But what system are you creating? Do you need to create TS plugin with few build-in PostCSS mixins?
Can you show me the content of @cgds/styles/elevation.css
and @cgds/styles/typography.css
?
In the end what I'm trying to do (typescript or whatever) doesn't really matter. Basically its a custom typescript compiler that does some validation through postcss. Currently it chokes on this plugin.
This is what I want:
@define-mixin black { color: black }
postcss-mixins
synchronously. So far you told me:
You can create function, which will take string, parse it and create mixins object with functions
The current docs show how to do it as either an object or function but I do not want to rewrite anything. I want to keep all the mixins in CSS.
I interpreted your above statement as "use postcss.parse to parse all the mixins and load them into the plugin through the mixins
option." In doing that I encounter the error i fixed in #98. With that change everything works as expected.
Would you accept a PR if I added more tests to it? Or are you unwilling to accept any PR and I should try to solve my problem in a different way?
Why do you need to run postcss-mixins
if you do linter? Are you creating linter for CSS-in-JS?
in my system people can have mixins and I'm trying to validate css-modules usage. a mixin might add classes and i need those
So, you have TS scripts and CSS files with CSS Modules (which may contain mixins). Am I right that you need to compare classes in TS and CSS (after mixins will be applied)?
yes
Maybe we should not put PostCSS inside TS parser? We can use TS parser and collect folks and links to CSS Modules. After this step you can run PostCSS (this time with async support since you are working outside TS parser).
Will it work in your case?
On #96 when @ai was asked "Is there a way to just pass a string to mixins?" his response was "You can create function, which will take string, parse it and create mixins object with functions."
I have tried to do this on my own
But I cannot get it to work.
If this is the supported way to synchronously load mixins stored in CSS (as #73 #95 and #96 have all been closed) files, I think the method for this should be documented in a simple way.