Open SilentCicero opened 8 years ago
I've tried making such a loader. I even made it work with extract-text-webpack-plugin. Mostly the code you need is
// csjs-loader.js
var requireFromString = require('require-from-string');
var getCss = require('csjs').getCss;
module.exports = function(source) {
return getCss(requireFromString(source));
}
The problem is that you'd be interpreting all .csjs.js
files, through css!csjs!babel
. This disables the compose feature:
//simple_button.csjs.js
export default csjs`
.simple-button {
// styles ...
}
`;
//custom_button.csjs.js
import s from './simple_button.csjs' // <-- this is actually translated into css
export default csjs `
.primary-button extends `${s['simple-button']}` { // <-- you cannot extend it
// style
}
`;
@rtsao Does this work well with csjs-extractify?
@codrin-iftimie why does this disable the compose feature?
And can you provide the code you used for webpack for extract-text? Would like to take a look.
I've created a gist.
When importing a csjs.js
file inside another csjs.js
file the import gets translated into css.
The import is undefined
, so when you are extending the imported styles you are calling accessing undefined['simple-button']
.
I'm doing it using a little different approach. To be compatible with css modules, I'm setting locals
to the loader exports object. This way I can use style-loader
out of the box to add css to page and re-export locals object. So I simply do:
styles.csjs.js
module.exports = csjs`.myClass { ... }`
app.js
import { myClass } from './styles.csjs';
import { classFromCss } from './someCss.css';
webpack.config.js
loaders: [
{
test: /\.csjs\.js?$/,
loader: 'style!csjs!val!babel',
}, {
test: /\.css$/,
loader: 'style!csjs!css!postcss',
},
],
csjs
loader:
const csjs = require('csjs');
const csjsify = (source) => (
typeof source === 'string'
? csjs`${source}`
: source
);
const stringify = (styles) => {
const result = Object.assign(styles, {});
Object.keys(result).forEach((k) => (result[k] = result[k].className));
return JSON.stringify(result);
};
module.exports = (source, map) => {
const styles = csjsify(source);
return `
module.exports = [[module.id, \`${csjs.getCss(styles)}\`, ${map}]];
module.exports.locals = ${stringify(styles)};
`;
};
I still didn't figure out how to enable sourcemaps using this approach. val-loader
doesn't seem to provide those.
interesting, yes more thought is needed @mkazlauskas
@SilentCicero I updated my previous comment, added support to pipe plain css files over csjs loader. This way we can keep external classes of dependencies scoped.
"I still didn't figure out how to enable sourcemaps using this approach."
"added support to pipe plain css files over csjs loader"
That's sounds so amazingly great that we definitely should support source maps generation for csjs
.
I've been studying the csjs-extractify, but I don't know how I could approach it with the webpack loader model.
Thoughts? @rtsao