結論
綺麗かどうかはさておき、以下のようにやると一応css-modulesifyでPostCSSのプラグインが問題なく使えました(ES2015, React環境)。来たストリームを加工してるだけの話ですが。
var fs = require('fs');
var through2 = require('through2');
var browserify = require('browserify');
var postcss = require('postcss');
var b = browserify('src/index.js');
b.transform("babelify", {presets: ["es2015", "react"]});
var cssProcessors = [
require('postcss-nested'),
require('cssnano')
];
b.plugin(require('css-modulesify'), {
rootDir: __dirname
});
b.on('css stream', function (css) {
var postcssStream = through2(
function transform(chunk, enc, next){
postcss(cssProcessors)
.process(chunk)
.then(function (result) {
next(null, result.css);
});
}
);
css
.pipe(postcssStream)
.pipe(fs.createWriteStream('dist/modules.min.css'));
});
var bundle = b.bundle();
bundle.pipe(fs.createWriteStream('dist/bundle.js'));
gulpなら以下。
var gulp = require('gulp');
var postcss = require('gulp-postcss');
var streamify = require('gulp-streamify');
var browserify = require('browserify');
var source = require('vinyl-source-stream');
var cssProcessors = [
require('postcss-nested'),
require('cssnano')
];
gulp.task('build', function(){
var browserified = function () {
var b = browserify('src/index.js');
b.transform("babelify", {presets: ["es2015", "react"]});
b.plugin(require('css-modulesify'), {
rootDir: __dirname
});
b.on('css stream', function (css) {
css
.pipe(source('modules.min.css'))
.pipe(streamify(postcss(cssProcessors)))
.pipe(gulp.dest('dist/'));
});
return b.bundle();
};
browserified()
.on("error", function (err) { console.log("Error : " + err.message); })
.pipe(source('bundle.js'))
.pipe(gulp.dest('dist/'));
});
そもそもの問題
CSS ModulesをBrowserifyで使うcss-modulesifyで、CSSを良い感じにminifyするプラグインcssnanoが使えませんでした。
css-modulesifyは、使いたいPostCSSプラグインを以下のようにuse
オプションで設定できます。
var b = require('browserify')();
var fs = require('fs');
b.add('./main.js');
b.plugin(require('css-modulesify'), {
rootDir: __dirname,
use: [
require('postcss-nested'),
require('cssnano')
]
});
var bundle = b.bundle();
bundle.on('css stream', function (css) {
css.pipe(fs.createWriteStream('mycss.css'));
});
ただこれだとデフォルトで使われているCSS Modules用のプラグイン(postcss-modules-local-by-default
, postcss-modules-extract-imports
, postcss-modules-scope
, postcss-modules-values
)を上書きしてしまいます。
なので、use
ではなくpostcssAfter
after
を使うと、デフォルトのプラグインが走ったあとに指定したプラグインを実行させることができるよ的なことが書いてありました。
...
b.plugin(require('css-modulesify'), {
rootDir: __dirname,
after: [
require('postcss-nested'),
require('cssnano')
]
});
...
ですが、言われた通りにやっても、プラグインにcssnano
を使っていると書き出されるファイルが空のCSSになっていた(エラーが出て処理が止まっていた?)、というのが問題でした(cssnext
も使えないっていうissueがたってました)。
なので冒頭のように、css-modulesify内ではプラグインは使わず、css-modulesifyから流れてきたCSSのストリームにPostCSSプラグインを当ててあげることで問題を回避しました。
そもそも、
Please note that this is still highly experimental.
って言われてるので問題は起こって当然なのと、これはあくまで回避策なので、状況が正確に把握でき次第issueに報告して改善に貢献しようかと思います(はやくhighly experimentalじゃなくなって欲しい...)。
※修正(2016-03-16):0.22.0の変更にあわせた