Closed Darhagonable closed 3 years ago
The kremling-loader
project is a postcss plugin. You can run SASS as a postcss plugin as well - https://github.com/AleshaOleg/postcss-sass. You could try using them together - you'd want kremling-loader to run after SASS has finished.
Will that allow one to write scss within the JS file though? My understanding is that it's just for separate scss files?
Your understanding is correct - the approach I described above only works when putting the css in separate files.
The challenge with allowing sass within the js component is that SASS must be compiled at build-time. We created https://github.com/CanopyTax/kremling-babel-plugin a while back with the intent of allowing build-time compilation to occur within JS files. I think that would be the place to attempt an implementation. cc @geoctrl who worked on the babel plugin
the problem with the kremling-bable-plugin
is that babel runs synchronously, and a lot of postcss plugins are asynchronous - so there was absolutely no way of implementing this without running into lots of problems
however, I did create a work-around: kremling-inline-loader (npm link)
note: this is an experiment and should be used with a fair amount of caution (note the lack of docs for the project - I really need to get that updated...)
kremling-inline-loader
is a webpack loader that runs babel within it for each js
file looking for the k
template literal tag - once it finds one, it runs postcss or sass on it (depending on your config). Currently postcss and sass (scss) are the only ones supported.
for writing inline scss, your webpack config might look something like this:
module.exports = {
...
module: {
rules: [
{
test: /\.js/,
exclude: /node_modules/,
use: [
'babel-loader',
{
loader: 'kremling-inline-loader',
options: {
sass: { // this is a pass-through for your sass config
data: `@import "${path.resolve(
'./src/styles/globals/variables.scss'
)}";`
},
},
},
],
},
],
},
}
your inline styles can now look like this:
const css = k`
.fun-thing {
background-color: $primary-color;
.inside {
text-align: right;
}
}
`;
and just like the kremling-loader
, this is automatically scoped without having to write the ampersands before each rule 👍
babel is now parsing each file TWICE on every js file (assuming you're using babel-loader
)... which could make your project start up a bit slower (especially for large projects)
however, once the project is running, changes you make to each file very quick 🤷
one thing I forgot to mention - the babel parser running within the loader has hardcoded options plugins: jsx
and classProperties
- if your js file requires other babel plugins, then this loader will fail
the ultimate goal would be to use the babel config (.babelrc
or something) that lives in your project root dir - but I haven't gotten to that yet
Having it configured inside babel config instead would be great because then it could work with Parcel 2 as well
@geoctrl I also never got it working with webpack either for some reason
Seems great but i wish one could type scss