thabti / react-native-css

Style React-Native components with css
MIT License
769 stars 66 forks source link

watching multiple files? #32

Open minimaldesign opened 8 years ago

minimaldesign commented 8 years ago

Trying to use your awesome module as an npm script in my project, but when I do something like:

node_modules/react-native-css/bin/react-native-css -i src/styles/_scss/*.scss -o src/styles/*.styles.js -w

It looks like your script is taking the * literally… How can I watch multiple files?

Thanks a bunch. This is really cool!

thabti commented 8 years ago

@minimaldesign Hi, currently there is no support for this. We would be happy to accept a pull request from yourself. This sounds like an awesome idea, I cannot dedicate time right now, but hopefully in the coming weeks.

jspears commented 8 years ago

So... don't have time to create something real, but this might be a start. Obviously it needs some work to make it useful, and it uses fb-watchman instead of the other watcher chokidar

Basically it watches a styles dir, and creates an index file including all the files in that dir.

var watchman = require('fb-watchman');
var client = new watchman.Client();
var path = require('path');
var ReactNativeCss = require('react-native-css');
var css = new ReactNativeCss();
var fs = require('fs');
var rdir = path.join.bind(path, process.cwd());

var styles = rdir('src/styles');
console.log('watching', styles);
client.capabilityCheck({optional: [], required: ['relative_root']},
    function (error, resp) {
        if (error) {
            console.log(error);
            client.end();
            return;
        }

        // Initiate the watch
        client.command(['watch-project', styles],
            function (error, resp) {
                if (error) {
                    console.error('Error initiating watch:', error);
                    return;
                }

                // It is considered to be best practice to show any 'warning' or
                // 'error' information to the user, as it may suggest steps
                // for remediation
                if ('warning' in resp) {
                    console.log('warning: ', resp.warning);
                }

                // `watch-project` can consolidate the watch for your
                // dir_of_interest with another watch at a higher level in the
                // tree, so it is very important to record the `relative_path`
                // returned in resp

                console.log('watch established on ', resp.watch,
                    ' relative_path', resp.relative_path);

                var sub = {
                    // Match any `.js` file in the dir_of_interest
                    expression: ["anyof", ["match", "*.css"], ["match", "*.scss"]],
                    // Which fields we're interested in
                    fields: ["name", "size", "exists", "type"],
                };
                if (resp.relative_path) {
                    sub.relative_root = resp.relative_path;
                }
                client.command(['subscribe', resp.watch, 'style_subscription', sub],
                    function (error, resp) {
                        if (error) {
                            // Probably an error in the subscription criteria
                            console.error('failed to subscribe: ', error);
                            return;
                        }
                        console.log('subscription ' + resp.subscribe + ' established');
                    });

            });

        client.on('subscription', function (resp) {
            if (resp.subscription == 'style_subscription') {
                for (var i in resp.files) {
                    var f = resp.files[i];
                    console.log('file changed: ' + f.name, f);
                    if (/\.s?css/.test(f.name)) {
                        css.parse(path.join(styles, f.name), rdir('dist/styles', `${f.name.replace(/\.s?css$/, '')}.js`), true, false);
                    }
                }
                writeIndex();
            }
        });
    })
;
function writeIndex() {

    fs.writeFileSync(rdir('dist/styles.js'), `module.exports = ${writeObj(fs.readdirSync(rdir('./src/styles')))}`);
}
var repe = /(\.android|\.ios)?\.s?css$/;
function writeObj(files) {
    return (files.reduce(function (str, v) {
            if (repe.test(v)) {
                const req = JSON.stringify('./styles/' + v.replace(repe, ''));
                return `${str}${JSON.stringify(v.replace(repe, ''))}: require(${req}),\n`;
            }
            return v;
        }, '{\n')) + '};\n';
}
thabti commented 8 years ago

@jspears Thanks, I will look at this over the weekend and try to implement it.