Skip to content

Commit

Permalink
ENH: add never-cache and command options
Browse files Browse the repository at this point in the history
- `--never-cache`, `-n` option allows to specify patterns to match
files that will never be included in the cache. Even if the files were
in the cache already they will be ignored if the file matches the
provided pattern. Multiple patterns can be specified by specifying this
parameter multiple times.

- `command` option can be used to pass the cli command used to execute
persistify. If that command changes then the cache will be also be
ignored
  • Loading branch information
royriojas committed Sep 22, 2015
1 parent 17cfb9d commit b81307d
Show file tree
Hide file tree
Showing 9 changed files with 174 additions and 38 deletions.
69 changes: 62 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Standard Options:
shell command, and the output will be piped to it (not available on
Windows).

--verbose, -v [default: false]
--verbose, -v [default: false]

Show when a file was written and how long the bundling took (in
seconds).
Expand All @@ -48,6 +48,15 @@ Standard Options:
--recreate [default: false]

if set will recreate the cache. Useful when transforms and cached files refuse to cooperate

--never-cache, -n [default: null]

a string that will be converted to a regula expression. If a file matches the returned regExp
will never be saved in the cache. Even if the file is in the cache already it will be ignored.

More than one pattern to be ignored can be specified by repeating this option with other regex
value to ignore

```
## Examples
Expand All @@ -73,6 +82,12 @@ persistify src/foo.js -o dist/foo.js --watch
# (all the parameters are just passed to browserify
# so it should work with any transform)
persistify src/foo.js -t babelify -o dist/foo.js --watch

# this will just use the cache and use two transforms
# but will never add to the cache any files that match the `m.less` extension
# since those files can also require files and those files won't be cached
# this is the safer way to prevent those changes to be skipped because of the cache
persistify src/foo.js -t babelify -t simpless -o dist/foo.js -n '\.less$'
```
## As a node module
Expand Down Expand Up @@ -117,20 +132,60 @@ b.on( 'update', function () {
### My less files are not detected as changed when using a transformation like `lessify`. Why?
In short, because those files are not loaded thru browserify and the cache will ignore them. use `--recreate` to recreate the cache. **TODO**: Add an option to never cache certain type of files so at least this works for the javascript ones.
Because those files are not loaded thru browserify so the cache will ignore them. use `-n, --never-cache` to specify certain files (or file types) to never be cached.
**Example: Using the cli**
```bash
# the following will exclude files ending in `.less` from being kept in the cache
persistify src/foo.js -t lessify -o dist/foo.js -n '\.less$'
```
**Example: Using the node api**
```javascript
var persistify = require( 'persistify' );

var b = persistify( {
//browserify options here. e.g
// debug: true
}, {
neverCache: [/\.less$/] // using the node api
} );

b.add( './demo/dep1.js' );

// when a file is ignored from the cache
// a skip:cache event is fired on the bundle instance
b.on('skip:cache', function (file) {
console.log( 'skipping the cache for', file);
});

b.on( 'error', function ( err ) {
console.log( 'error', err );
} );

function doBundle() {
b.bundle( function ( err, buff ) {
if ( err ) {
throw err;
}
require( 'fs' ).writeFileSync( './dist/bundle.js', buff.toString() );
} );
}

Long answer below:
So far `persistify` will only save to disk the **browserify cache**, if some transform loads a file during the transformation
process the change to that will not be detected. Maybe we need to make the transforms to also be able to create entries in the browserify cache, at least to list the dependencies of the file being transformed (common case in transforms that handle `less`, `sass` or `jade` code).
doBundle();
```
### My build does not include the latest changes to my files! not detecting changed files?
Mmm... that's weird, but the option `--recreate` should destroy the cache and create it again which most of the times should fix your issue.
### I have added a new transform and the build is not using its magic!
Since persistify will only work on the files that have changed, and adding a transform
does not cause a file change it is better to just use `--recreate` after adding a new trasform or plugin
~Since persistify will only work on the files that have changed, and adding a transform
does not cause a file change it is better to just use `--recreate` after adding a new trasform or plugin~
Latest version of `persistify` will ignore the cache if the command used to execute it changes.
## Changelog
Expand Down
43 changes: 32 additions & 11 deletions bin/cmd.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,47 @@
var fs = require( 'fs' );
var path = require( 'path' );
var outpipe = require( 'outpipe' );
var subarg = require( 'subarg' );

var nodeConsole = console;

function run() {
var watch = process.argv.indexOf( '--watch' ) > -1;
var _argv = process.argv.slice( 2 );
var persistifyArgs = subarg( _argv, {
alias: {
'n': 'never-cache'
}
} );

var watch = persistifyArgs.watch;
var recreate = persistifyArgs.recreate;
var neverCache = persistifyArgs[ 'never-cache' ];

var w = require( '../' )( null, {
// TODO: use minimist
command: _argv.join( ' ' ),
neverCache: neverCache,
watch: watch,
recreate: process.argv.indexOf( '--recreate' ) > -1
recreate: recreate
}, process.argv.slice( 2 ) );

var outfile = w.argv.o || w.argv.outfile;
var verbose = w.argv.v || w.argv.verbose;

if ( w.argv.version ) {
console.error( 'persistify v' + require( '../package.json' ).version +
nodeConsole.error( 'persistify v' + require( '../package.json' ).version +
' (in ' + path.resolve( __dirname, '..' ) + ')'
);
console.error( 'watchify v' + require( 'watchify/package.json' ).version +
nodeConsole.error( 'watchify v' + require( 'watchify/package.json' ).version +
' (in ' + path.dirname( require.resolve( 'watchify' ) ) + ')'
);
console.error( 'browserify v' + require( 'browserify/package.json' ).version +
nodeConsole.error( 'browserify v' + require( 'browserify/package.json' ).version +
' (in ' + path.dirname( require.resolve( 'browserify' ) ) + ')'
);
return;
}

if ( !outfile ) {
console.error( 'You MUST specify an outfile with -o.' );
nodeConsole.error( 'You MUST specify an outfile with -o.' );
process.exit( 1 ); //eslint-disable-line
}

Expand All @@ -47,6 +61,13 @@ function run() {
} );
}

w.on( 'skip:cache', function ( file ) {
if ( !verbose ) {
return;
}
nodeConsole.error( 'skip file from cache:', file );
} );

function bundle() {
var didError = false;
var outStream = process.platform === 'win32'
Expand All @@ -55,23 +76,23 @@ function run() {

var wb = w.bundle();
wb.on( 'error', function ( err ) {
console.error( String( err ) );
nodeConsole.error( String( err ) );
didError = true;
outStream.end( 'console.error(' + JSON.stringify( String( err ) ) + ');' );
} );
wb.pipe( outStream );

outStream.on( 'error', function ( err ) {
console.error( err );
nodeConsole.error( err );
} );
outStream.on( 'close', function () {
if ( verbose && !didError ) {
if ( watch ) {
console.error( bytes + ' bytes written to ' + outfile
nodeConsole.error( bytes + ' bytes written to ' + outfile
+ ' (' + (time / 1000).toFixed( 2 ) + ' seconds)'
);
} else {
console.error( 'bundle done! '
nodeConsole.error( 'bundle done! '
+ ' (' + (time / 1000).toFixed( 2 ) + ' seconds)'
);
}
Expand Down
8 changes: 6 additions & 2 deletions demo/dep1.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
var abc = require('./dep2');
console.log('hello world!!!!');

console.log('another world');
abc.showMetal(require('./deps/dep-3'));

abc.on('update', (x) => x * 2);
abc.on('update', (x) => x * 2);

var demoM = require('./deps/demo.m.less');

console.log(demoM.t('some-class'));
1 change: 1 addition & 0 deletions demo/dep2.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module.exports = {
showMetal: function (dep) {
console.log(dep);
console.log('hello world');
}
}
5 changes: 5 additions & 0 deletions demo/deps/demo.m.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@import 'module1.less';

.some-class {
.someMixin();
}
2 changes: 1 addition & 1 deletion demo/deps/dep-3.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ var hashString = require('hash-string');
hashString('21313');

var react = require('react');
var trim = require('jq-trim');
var trim = require('jq-trim')
6 changes: 6 additions & 0 deletions demo/deps/module1.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.someMixin() {
color: red;
background: yellow;
font-size: 20px;
line-height: 40px;
}
62 changes: 52 additions & 10 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@ var through = require( 'through2' );
var watchify = require( 'watchify' );
var trim = require( 'jq-trim' );

var parseAsRegex = function parseAsRegex( regex ) {
if ( typeof regex === 'string' ) {
return new RegExp( regex );
}
return regex;
};

module.exports = function ( browserifyOpts, opts, argv ) {
browserifyOpts = browserifyOpts || { };
opts = opts || { };
Expand All @@ -26,21 +33,55 @@ module.exports = function ( browserifyOpts, opts, argv ) {
// one if the previous one doesn't exist
var depsCacheFile = fileEntryCache.create( depsCacheId );

var persistifyCache = cache.getKey( 'persistifyArgs' ) || {
cache: {}, packageCache: {}
};
var ignoreCache = false;

// if the command was specified this can be used
// as the cache buster
if ( opts.command ) {
var configHashPersisted = cache.getKey( 'configHash' );
var hashOfConfig = hash( opts.command );

//var browserify = require( 'browserify' );
ignoreCache = configHashPersisted !== hashOfConfig;

if ( ignoreCache ) {
cache.setKey( 'configHash', hashOfConfig );
}
}

var defaultCache = {
cache: {}, packageCache: {}
};

var persistifyCache = ignoreCache ? defaultCache : (cache.getKey( 'persistifyArgs' ) || defaultCache);

browserifyOpts.cache = persistifyCache.cache;
browserifyOpts.packageCache = persistifyCache.packageCache;

var fromArgs = require( 'browserify/bin/args' );

var b = argv ? fromArgs( argv, browserifyOpts ) : require( 'browserify' )( browserifyOpts );

function normalizeCache( removeDeletedOnly ) {
var cachedFiles = Object.keys( browserifyOpts.cache );

var neverCache = opts.neverCache;
if ( neverCache ) {
if ( !Array.isArray( neverCache ) ) {
neverCache = [ neverCache ];
}
cachedFiles.forEach( function ( file ) {
for (var i = 0; i < neverCache.length; i++) {
var regex = parseAsRegex( neverCache[ 0 ] );

if ( file.match( regex ) ) {
b.emit( 'skip:cache', file );
delete browserifyOpts.cache[ file ]; //esfmt-ignore-line
break;
}
}
} );
}

var res = depsCacheFile.analyzeFiles( cachedFiles );

var changedFiles = res.changedFiles;
Expand All @@ -50,7 +91,7 @@ module.exports = function ( browserifyOpts, opts, argv ) {

if ( changedOrNotFound.length > 0 ) {
changedOrNotFound.forEach( function ( file ) {
delete browserifyOpts.cache[ file ];
delete browserifyOpts.cache[ file ]; //esfmt-ignore-line
} );
}

Expand All @@ -69,26 +110,27 @@ module.exports = function ( browserifyOpts, opts, argv ) {
source: row.source,
deps: xtend( { }, row.deps )
};
b.emit( 'file', file ); // attempt to make latest watchify to work with persistify
this.push( row );
next();
} ) );
}

if ( opts.watch ) {
b = watchify( b );
} else {
collect();
b.on( 'reset', collect );
}

collect();
b.on( 'reset', collect );

var oldBundle = b.bundle;
b.bundle = function () {
var start = Date.now();
var stream;
try {
stream = oldBundle.apply( b, arguments );
stream.on( 'error', function ( err ) {
console.error( err );
console.error( err ); // eslint-disable-line
} );
stream.on( 'end', function () {
setTimeout( function () {
Expand All @@ -101,7 +143,7 @@ module.exports = function ( browserifyOpts, opts, argv ) {
b.emit( 'bundle:done', end );
} );
} catch (ex) {
console.error( ex );
console.error( ex ); // eslint-disable-line
}

return stream;
Expand Down
Loading

0 comments on commit b81307d

Please sign in to comment.