Skip to content

Commit

Permalink
Initial Code
Browse files Browse the repository at this point in the history
  • Loading branch information
ForbesLindesay committed Mar 22, 2013
1 parent 96b6644 commit 1ef366d
Show file tree
Hide file tree
Showing 11 changed files with 263 additions and 3 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ logs
results

npm-debug.log

node_modules
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
language: node_js
node_js:
- 0.8
- 0.9
77 changes: 74 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,75 @@
rfileify
========
# rfileify

Convert any code using rfile and derivatives so that it supports browserify
Convert any code using rfile and derivatives so that it supports browserify.

This module is a plugin for [browserify](http://browserify.org/) to parse the AST for `rfile` calls so that you can inline the file contents into your bundles.

In addition to supporting `rfile`, you can also use modules which internally use `rfile` providing they meet the simple requirement of taking an object with `dirname` property as their second argument and are listed in the array of valid file names modules in index.js. Currently this is:

- [rfile](https://github.com/ForbesLindesay/rfile) - "require" static text files
- [ruglify](https://github.com/ForbesLindesay/ruglify) - "require" minified source code

Even though this module is intended for use with browserify, nothing about it is particularly specific to browserify so it should be generally useful in other projects.

## Example with Browserify

For a main.js

```javascript
var rfile = require('rfile');
var html = rfile('./robot.html');
console.log(html);
```

And a robot.html

```html
<b>beep boop</b>
```

first `npm install rfileify` into your project, then:

### on the command-line

```
$ browserify -t rfileify example/main.js > bundle.js
```

now in the bundle output file,

```javascript
var html = rfile('./robot.html');
```

turns into:

```javascript
var html = "<b>beep boop</b>";
```

(and `require('rfile')` turns into `undefined` so you're not loading code you're never going to use).

### or with the API

```javascript
var browserify = require('browserify');
var fs = require('fs');

var b = browserify('example/main.js');
b.transform('rfileify');

b.bundle().pipe(fs.createWriteStream('bundle.js'));
```

## Direct Usage

A tiny command-line program ships with this module for easier debugging and if you just want this without any of the rest of browserify.

```
npm install rfileify -g
rfileify --help
```

## License

MIT
21 changes: 21 additions & 0 deletions bin/rfileify
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env node
var fs = require('fs');
var path = require('path');
var rfileify = require('../');
var file = process.argv[2];

if (file === '-h' || file === '--help' || file === '-?' || file === '/?' || file === '/h') {
return fs.createReadStream(path.join(__dirname, 'usage.txt'))
.pipe(process.stdout)
;
}

var fromFile = file && file !== '-';
var rs = fromFile
? fs.createReadStream(file)
: process.stdin
;

var fpath = fromFile ? file : path.join(process.cwd(), '-');
rs.pipe(rfileify(fpath)).pipe(process.stdout);
rs.resume();
18 changes: 18 additions & 0 deletions bin/usage.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
usage:

rfileify file

Inline `rfile()` and `ruglify()` calls from `file`, printing the transformed file
contents to stdout.

rfileify
rfileify -

Inline `rfile()` and `ruglify()` calls from stdin, printing the transformed file
contents to stdout.

N.B.

You must have `rfile` and `ruglify` installed to use them:

npm install rfile ruglify -g
55 changes: 55 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
var path = require('path');

var through = require('through');
var falafel = require('falafel');
var unparse = require('escodegen').generate;

var rfileModules = ['rfile', 'ruglify'];

module.exports = function (file) {
var data = '';
var rfileNames = {};
var dirname = path.dirname(file);
var varNames = ['__filename', '__dirname', 'path', 'join'];
var vars = [file, dirname, path, path.join];

return through(write, end);

function write (buf) { data += buf }
function end () {
var tr = this;

var output = falafel(data, function (node) {
if (requireName(node) && rfileModules.indexOf(requireName(node)) != -1 && variableDeclarationName(node.parent)) {
rfileNames[variableDeclarationName(node.parent)] = requireName(node);
node.update('undefined');
}
if (node.type === 'CallExpression' && node.callee.type === 'Identifier' && rfileNames[node.callee.name]) {
var rfile = require(rfileNames[node.callee.name]);
var args = node.arguments;
for (var i = 0; i < args.length; i++) {
var t = 'return ' + unparse(args[i]);
args[i] = Function(varNames, t).apply(null, vars);
}
args[1] = args[1] || {};
args[1].basedir = args[1].basedir || dirname;
node.update(JSON.stringify(rfile.apply(null, args)));
}
});

tr.queue(String(output));
tr.queue(null);
}
};

function requireName(node) {
var c = node.callee;
if (c && node.type === 'CallExpression' && c.type === 'Identifier' && c.name === 'require') {
return node.arguments[0].value;
}
}
function variableDeclarationName(node) {
if (node && node.type === 'VariableDeclarator' && node.id.type === 'Identifier') {
return node.id.name;
}
}
46 changes: 46 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"name": "rfileify",
"version": "0.0.0",
"description": "Convert any code using rfile and derivatives so that it supports browserify",
"main": "index.js",
"bin": {
"rfileify": "./bin/rfileify"
},
"scripts": {
"test": "mocha -R spec"
},
"repository": {
"type": "git",
"url": "https://github.com/ForbesLindesay/rfileify.git"
},
"keywords": [
"browserify",
"fs",
"readFileSync",
"plugin",
"static",
"asset",
"bundle",
"base64",
"uglify",
"require",
"resolve",
"browser",
"rfile"
],
"author": "ForbesLindesay",
"license": "MIT",
"readmeFilename": "README.md",
"gitHead": "96b6644e686bfe5dde7d77536e6166e365df0681",
"dependencies": {
"through": "~2.2.7",
"escodegen": "0.0.19",
"falafel": "~0.2.0"
},
"devDependencies": {
"mocha": "~1.8.2",
"browserify": "~2.7.2",
"rfile": "~1.0.0",
"ruglify": "~1.0.0"
}
}
3 changes: 3 additions & 0 deletions test/files/answer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(function (computer) {
return computer(42);
}(function (value) { return value.toString(); }));
1 change: 1 addition & 0 deletions test/files/robot.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<b>beep boop</b>
7 changes: 7 additions & 0 deletions test/files/sample.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
var load = require('rfile');
var loadSRC = require('ruglify');

console.log(load('./robot.html'));
console.log(load('./robot', {extensions: ['.html']}));

console.dir(Function('return ' + loadSRC('./answer.js'))());
32 changes: 32 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
var browserify = require('browserify');

var vm = require('vm');
var fs = require('fs');
var path = require('path');
var assert = require('assert');

var html = fs.readFileSync(__dirname + '/files/robot.html', 'utf8');

describe('rfile(path)', function () {
it('inlines the text', function (done) {
var remaining = 3;

var b = browserify();
b.add(__dirname + '/files/sample.js');
b.transform(path.dirname(__dirname));

b.bundle(function (err, src) {
if (err) throw err;
vm.runInNewContext(src, { console: { log: log, dir: dir } });
});

function log (msg) {
assert.equal(msg, html);
if (0 === --remaining) done();
}
function dir (msg) {
assert.equal(msg, '42');
if (0 === --remaining) done();
}
})
});

0 comments on commit 1ef366d

Please sign in to comment.