New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

fuse

Package Overview
Dependencies
Maintainers
1
Versions
33
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fuse - npm Package Compare versions

Comparing version 0.3.0 to 0.4.0

lib/index.js

2

bin/fuse.js

@@ -22,3 +22,3 @@ #!/usr/bin/env node

fuser.on('unwatch', function (file) {
console.log('No longer watching' + colors.cyan(file) + ' for changes.');
console.log('No longer watching ' + colors.cyan(file) + ' for changes.');
});

@@ -25,0 +25,0 @@

@@ -16,33 +16,13 @@ (function () {

function Fuse (inputFile, outputFile) {
function Fuse () {
if (inputFile === undefined) {
throw new Error('You must define the input file.');
}
this.settings = {};
if (outputFile === undefined) {
throw new Error('You must define the output file.');
}
// setup the regular expressions
this.re = this.reJS = /\/\/ ?@(?:depends|import|include) (.+)\b/gi;
this.reHTML = /<!--\s?@(?:depends|import|include)\s(.+?)\s?-->/gi;
this.inputFile = inputFile;
this.outputFile = outputFile;
// what mode are we running in, HTML or JS?
// this needs to be improved, because it means it will only work if the file ext is 'html' || 'js'
this.mode = path.extname(this.inputFile).replace(/^\./, '');
// swtich the regular expression based on mode
this.regex = (this.mode === 'js') ? this.reJS : this.reHTML;
// not watching by default
this.watching = false;
// do we need to compress (js only)?
this.compress = (arguments.length > 2 && arguments[2] !== undefined) ? arguments[2] && this.mode === 'js' : false;
// do we need to mangle (js only)?
this.mangle = (arguments.length > 3 && arguments[3] !== undefined) ? arguments[3] && this.mode === 'js' : false;
// do we need to run the files through JSHint (js only)?
this.lint = (arguments.length > 4 && arguments[4] !== undefined) ? arguments[4] && this.mode === 'js' : false;
// create an array to hold the watches for this fuse

@@ -57,5 +37,37 @@ this.files = [];

Fuse.prototype.watch = function (fuseImmediately) {
Fuse.prototype.set = function (setting, val) {
this.settings[setting] = val;
return this;
};
Fuse.prototype.get = function (setting) {
return this.settings[setting];
};
Fuse.prototype.watch = function (inputFile, outputFile, fuseImmediately) {
var _this = this;
if (arguments.length === 1) {
fuseImmediately = inputFile;
inputFile = undefined;
}
if (inputFile) this.set('inputFile', inputFile);
if (outputFile) this.set('outputFile', outputFile);
if (this.get('inputFile') === undefined) throw new Error('You must define the input file.');
if (this.get('outputFile') === undefined) throw new Error('You must define the output file.');
// what mode are we running in, HTML or JS?
// this needs to be improved, because it means it will only work if the file ext is 'html' || 'js'
this.mode = path.extname(this.get('inputFile')).replace(/^\./, '');
// swtich the regular expression based on mode
this.regex = (this.mode === 'js') ? this.reJS : this.reHTML;
// define the watching mode
this.watching = true;

@@ -65,3 +77,3 @@

var aFiles = this.scanFiles();
var relativePath = path.dirname(this.inputFile) + '/';
var relativePath = path.dirname(this.get('inputFile')) + '/';

@@ -76,4 +88,4 @@ // loop through an setup a watch on each referenced file

// we also need to watch the input file
this.watchFile(this.inputFile);
this.files.push(this.inputFile);
this.watchFile(this.get('inputFile'));
this.files.push(this.get('inputFile'));

@@ -90,3 +102,3 @@ if (fuseImmediately) this.fuseFile();

return this.getReferencedFiles(this.getFileContent(this.inputFile), this.regex);
return this.getReferencedFiles(this.getFileContent(this.get('inputFile')), this.regex);

@@ -98,4 +110,5 @@ };

var _this = this,
files = [this.inputFile],
relativePath = path.dirname(this.inputFile) + '/';
files = [this.get('inputFile')],
relativePath = path.dirname(this.get('inputFile')) + '/',
unwatched = false;

@@ -106,3 +119,3 @@ // find references that are missing from files (these are files that need to be watched)

var found = _this.files.some(function (file) {
return path.resolve(file) === path.resolve(reference.path);
return path.resolve(file) === path.resolve(relativePath, reference.path);
});

@@ -122,11 +135,14 @@

// ignore the input file, we've already added this
if (file === _this.inputFile) return;
if (file === _this.get('inputFile')) return;
// search for this file in references
var found = references.some(function (reference) {
return path.resolve(file) === path.resolve(reference.path);
return path.resolve(file) === path.resolve(relativePath, reference.path);
});
// references is newer then file, so it may have been removed
if (!found) _this.unwatchSrcFile(file);
if (!found) {
_this.unwatchSrcFile(file);
unwatched = true;
}

@@ -138,2 +154,4 @@ });

return unwatched;
};

@@ -156,13 +174,34 @@

// core function for parsing and outputing a fused file
// optional arguments: compress, mangle, exit
Fuse.prototype.fuseFile = function () {
// uses fuseContent to do the heavy lifting
Fuse.prototype.fuseFile = function (inputFile, outputFile) {
if (inputFile !== undefined) this.set('inputFile', inputFile);
if (outputFile !== undefined) this.set('outputFile', outputFile);
if (this.get('inputFile') === undefined) throw new Error('You must define the input file.');
if (this.get('outputFile') === undefined) throw new Error('You must define the output file.');
// what mode are we running in, HTML or JS?
// this needs to be improved, because it means it will only work if the file ext is 'html' || 'js'
this.mode = path.extname(this.get('inputFile')).replace(/^\./, '');
// swtich the regular expression based on mode
this.regex = (this.mode === 'js') ? this.reJS : this.reHTML;
// work out the settings
// do we need to compress (js only)?
this.compress = (this.get('compress') !== undefined) ? this.get('compress') && this.mode === 'js' : false;
// do we need to mangle (js only)?
this.mangle = (this.get('mangle') !== undefined) ? this.get('mangle') && this.mode === 'js' : false;
// do we need to run the files through JSHint (js only)?
this.lint = (this.get('lint') !== undefined) ? this.get('lint') && this.mode === 'js' : false;
// grab the content of the input file
var content = this.getFileContent(this.inputFile);
var content = this.getFileContent(this.get('inputFile'));
// determine the relative path we need to work from
var relativePath = path.dirname(path.normalize(this.get('inputFile')));
// grab a list of the referenced files
var matches = this.getReferencedFiles(content, this.regex);
// determine the relative path we need to work from
var relativePath = path.dirname(path.normalize(this.inputFile));
// output is a version of the content that we'll update
var output = content;
// uglify-js2 variables

@@ -175,5 +214,6 @@ var ast = null;

var _this = this;
var unwatched = false;
// do we need to check the references?
if (this.watching) this.checkReferences(matches);
if (this.watching) unwatched = this.checkReferences(matches);

@@ -183,100 +223,176 @@ // are we linting?

if (this.lint) {
lintData[path.basename(this.inputFile)] = this.lintFile(content);
lintData[path.basename(this.get('inputFile'))] = this.lintFile(content);
}
// do we have anything to combine?
if (!matches.length) {
// if there is no matches, lint if required, emit nofuse event and stop processing
if (!matches.length && unwatched === false) {
// run the lint report if required
if (this.lint) this.lintReport(lintData);
// we still want to write to disk, but just the original content
fs.writeFile(_this.get('outputFile'), output, function (err) {
return this.emit('nofuse');
if (err) {
} else {
_this.emit('error', err);
// loop through each match, grab the file content
_.each(matches, function (match) {
} else {
// ok, determine the file name
var fileContent;
var filename = path.basename(match.path);
var filepath = path.join(relativePath,match.path);
var bFile = false;
// run the lint report
if (_this.lint) _this.lintReport(lintData);
try {
bFile = fs.statSync(filepath).isFile();
} catch (e) {
_this.emit('nofuse', {
updated: _this.get('outputFile'),
fused: matches
});
}
// if the file exists, load in the content and update the output
if (bFile) {
});
// let's load in the file
fileContent = fs.readFileSync(filepath, 'ascii');
} else {
// let's replace the match with the filecontent
output = output.replace(match.str, fileContent);
// do we need to need lint?
if (this.lint) {
// are we linting?
// if so, lint each dependancy file
if (_this.lint) {
lintData[filename] = _this.lintFile(fileContent);
_.each(matches, function (match) {
// we're loading the files twice now, which isn't good
// need to implement a quick cache per sweep so that we can have multiple passes
// of file content, without multiple loads
var fileContent;
var filename = path.basename(match.path);
var filepath = path.join(relativePath,match.path);
fileContent = _this.getFileContent(filepath);
lintData[filename] = _this.lintFile(fileContent);
});
}
this.fuse(content, matches, relativePath, function (err, results) {
if (err) return _this.emit('error', err);
var output = results;
// use uglify-js2 to minify the code if arguments are present
if (_this.compress || _this.mangle) {
// setup the compressor
compressor = ujs.Compressor({warnings: false});
// parse the output and create an AST
ast = ujs.parse(output);
// should we compress?
if (_this.compress) {
ast.figure_out_scope();
compressedAst = ast.transform(compressor);
}
// should we mangle?
if (_this.mangle) {
(compressedAst || ast).figure_out_scope();
(compressedAst || ast).compute_char_frequency();
(compressedAst || ast).mangle_names();
}
// generate the new code string
output = (compressedAst || ast).print_to_string();
}
// save the file to disk
fs.writeFile(_this.get('outputFile'), output, function (err) {
if (err) {
_this.emit('error', err);
} else {
_this.emit('fuse', {
updated: _this.get('outputFile'),
fused: matches.map(function (match) {
return match.path
})
});
}
// run the lint report
if (_this.lint) _this.lintReport(lintData);
});
});
// use uglify-js2 to minify the code if arguments are present
if (this.compress || this.mangle) {
}
// setup the compressor
compressor = ujs.Compressor({warnings: false});
};
// parse the output and create an AST
ast = ujs.parse(output);
// core function for parsing and generating output for a file
Fuse.prototype.fuseContent = function (content, relativePath, mode) {
// should we compress?
if (this.compress) {
ast.figure_out_scope();
compressedAst = ast.transform(compressor);
}
// what mode are we running in, HTML or JS?
// this needs to be improved, because it means it will only work if the file ext is 'html' || 'js'
this.mode = mode;
// swtich the regular expression based on mode
this.regex = (this.mode === 'js') ? this.reJS : this.reHTML;
// should we mangle?
if (this.mangle) {
(compressedAst || ast).figure_out_scope();
(compressedAst || ast).compute_char_frequency();
(compressedAst || ast).mangle_names();
}
// grab a list of the referenced files
var matches = this.getReferencedFiles(content, this.regex),
// output is a version of the content that we'll update
output = content,
_this = this;
// generate the new code string
output = (compressedAst || ast).print_to_string();
// do we have anything to combine?
if (!matches.length) {
return this.emit('nofuse', {
updated: content,
fused: matches
});
}
this.fuse(content, matches, relativePath, function (err, results) {
if (err) {
return _this.emit('error', err);
}
// save the file to disk
fs.writeFile(_this.outputFile, output, function (err) {
if (err) {
_this.emit('fuse', {
updated: results,
fused: matches.map(function (match) {
return match.path
})
});
_this.emit('error', err);
});
} else {
};
_this.emit('fuse', {
updated: _this.outputFile,
fused: matches.map(function (match) {
return match.path
})
});
// lower-level to simply fuse the content provided a bunch of matches
Fuse.prototype.fuse = function (content, matches, relativePath, callback) {
}
var output = content,
_this = this;
// run the lint report
if (_this.lint) _this.lintReport(lintData);
// loop through each match, grab the file content
_.each(matches, function (match) {
});
// ok, determine the file name
var fileContent;
var filename = path.basename(match.path);
var filepath = path.join(relativePath,match.path);
}
fileContent = _this.getFileContent(filepath);
// let's replace the match with the filecontent
output = output.replace(match.str, fileContent);
});
callback(null, output);
};

@@ -367,14 +483,14 @@

// read the file and grab the content
// because it's the input file, simple output any errors and quit
// we assume this file has been verified by loadFile
Fuse.prototype.getFileContent = function (inputFile) {
try {
return fs.readFileSync(inputFile, 'utf-8');
} catch (e) {
this.emit('err', e);
this.emit('error', e);
return '';
}
};
}
// get a list of the files to include, from the input file

@@ -385,3 +501,3 @@ Fuse.prototype.getReferencedFiles = function (content, regex) {

var matches = content.match(regex);
_.each(matches, function (match) {

@@ -410,27 +526,15 @@

// export a helper function to instantiate the Fuse class
exports.fuse = function (inputFile, outputFile) {
exports.fuse = function (inputFile, outputFile, compress, mangle, lint) {
if (inputFile === undefined) {
throw new Error('You must define the input file.');
}
var fuser = new Fuse();
if (inputFile) fuser.set('inputFile', inputFile);
if (outputFile) fuser.set('outputFile', outputFile);
if (compress) fuser.set('compress', compress);
if (mangle) fuser.set('mangle', compress);
if (lint) fuser.set('lint', lint);
if (outputFile === undefined) {
throw new Error('You must define the output file.');
}
return fuser;
// what mode are we running in, HTML or JS?
// this needs to be improved, because it means it will only work if the file ext is 'html' || 'js'
var mode = path.extname(inputFile).replace(/^\./, '');
// do we need to compress (js only)?
var compress = (arguments.length > 2) ? arguments[2] !== undefined && mode === 'js' : false;
// do we need to mangle (js only)?
var mangle = (arguments.length > 3) ? arguments[3] !== undefined && mode === 'js' : false;
// do we need to run the files through JSHint (js only)?
var lint = (arguments.length > 4) ? arguments[4] !== undefined && mode === 'js' : false;
return new Fuse(inputFile, outputFile, compress, mangle, lint);
};
}());
}());

@@ -10,7 +10,8 @@ {

"devDependencies" : { "mocha": "1.8.x"},
"main" : "./lib",
"bin" : { "fuse": "./bin/fuse.js" },
"scripts" : { "test": "make test" },
"directories" : { "bin": "./bin" },
"version" : "0.3.0",
"version" : "0.4.0",
"engines" : {"node": ">=0.8"}
}

@@ -1,17 +0,43 @@

# Fuse [![build status](https://secure.travis-ci.org/smebberson/fuse.png)][1]
# Fuse [![build status](https://secure.travis-ci.org/smebberson/fuse.png?branch=moduleintegration)][1]
> Fuse is a command line tool to fuse multiple JavaScript or HTML files into one. If you're fusing JavaScript you can optionally compress or mangle the JavaScript code.
> Fuse is a tool to fuse multiple JavaScript or HTML files into one. If you're fusing JavaScript you can optionally compress or mangle the JavaScript code.
You can use Fuse in three ways:
- on the command line
- as a Node.js module via require
- in express as middleware
## Introduction
Fuse is a simple cli tool to combine multiple JavaScript or HTML files into one. It also makes use of UglifyJS2 to either compress, or mangle or do both to the output of the JavaScript. It's designed to be simple, do less and be easy to use.
Fuse is a simple tool to combine multiple JavaScript or HTML files into one. It also makes use of UglifyJS2 to either compress, or mangle or do both to the output of the JavaScript. It's designed to be simple, do less and be easy to use.
## Installation (via NPM)
Compressing and mangling is only available to the commandline tool.
## Installation
There are two ways to install Fuse, depending on usage.
### Install as a command line tool
[sudo] npm install fuse -g
You need to install it globally, because it's not something that you can `require` in your nodejs code. It's only a command line program.
You need to install it globally, so that NPM will add it your bin path.
### Install as a module
[sudo] npm install fuse --save
`--save` will insert Fuse as a dependency in your package.json. Once you've installed it as a module, you can then use it via require in the following methods.
### Install for express
To use fuse within Express, you must install fuse-connect. fuse-connect is a connect middlware wrapper for Fuse.
[sudo] npm install fuse-connect --save
## Running tests (via NPM)
Make sure you're in the test directory within Fuse, then...
npm test

@@ -69,3 +95,38 @@

### As a node.js module
To fuse a file:
var fuse = require('fuse');
fuse.fuseFile(inputFile, outputFile, function (err, results) {
// do something with the results
// in this case a file has been generated, results.updated
});
To fuse some content:
var fuse = require('fuse');
fuse.fileContent(content, relativePath, mode, function (err, results) {
// do something with the results
// in this case, no file has been generated, but contents stored within results.updated
});
`content` is a string with some Fuse directives within it.
`relativePath` is a directory from which to load the directive referenced files.
`mode` tells Fuse if you're fusing HTML or JavaScript.
### With express
Make sure you've installed fuse-connect. You can then include fuse-connect to bind requests to particular files to fuse, so that they're automatically updated upon request.
var fuse = require('fuse-connect');
var filesToFuse = [
{src: '/path/to/src-file.js', dest: '/path/to/dest-file.js'},
{src: '/path/to/src-file.html', dest: '/path/to/dest-file.html'}
];
// add fuse-connect to the middleware
app.use(fuse.middleware(filesToFuse));
[1]: https://travis-ci.org/smebberson/fuse

@@ -72,0 +133,0 @@ [2]: http://visionmedia.github.com/mocha/

@@ -226,2 +226,108 @@ var assert = require('assert');

describe('as a module', function () {
describe('with html', function () {
before(function (done){
// make the directory first to hold the result content
fs.mkdir(process.cwd() + '/test/html/result/', done);
});
after(function (done) {
// remove the result directory
fs.rmdir(process.cwd() + '/test/html/result/', done);
});
describe('should fuse content', function () {
it('with <!-- @depends -->', function (done) {
var fuse = require('../lib');
var content = "<p>html first</p><!-- @depends depends.html --><p>html end</p>";
var expected = "<p>html first</p><p>content from depends.html</p><p>html end</p>";
fuse.fuseContent(content, path.resolve(__dirname, 'module', 'depends'), 'html', function (err, result) {
assert.equal(expected, result);
done(err);
});
});
it('without a directive', function (done) {
var fuse = require('../lib');
var content = "<p>html first</p><!-- @nodepend depends.html --><p>html end</p>";
var expected = "<p>html first</p><!-- @nodepend depends.html --><p>html end</p>";
fuse.fuseContent(content, path.resolve(__dirname, 'module', 'depends'), 'html', function (err, result) {
assert.equal(expected, result);
done(err);
});
});
});
describe('it should fuse two files', function () {
it('by <!-- @depends -->', function (done) {
// make the directory first to hold the result content
fs.mkdirSync(process.cwd() + '/test/html/result/depends/');
var fuse = require('../lib');
fuse.fuseFile(process.cwd() + '/test/html/src/depends/basic-depends.html', process.cwd() + '/test/html/result/depends/basic-depends-output.html', function (err, result) {
// check the output against the expected output
assert.equal(fs.readFileSync(process.cwd() + '/test/html/result/depends/basic-depends-output.html', 'utf-8'), fs.readFileSync(process.cwd() + '/test/html/expected/depends/basic-depends-result.html', 'utf-8'));
// delete the file
fs.unlinkSync(process.cwd() + '/test/html/result/depends/basic-depends-output.html');
fs.rmdirSync(process.cwd() + '/test/html/result/depends/');
// we're done
done();
});
});
it('without a directive', function (done) {
// make the directory first to hold the result content
fs.mkdirSync(process.cwd() + '/test/html/result/noDepends/');
var fuse = require('../lib');
fuse.fuseFile(process.cwd() + '/test/html/src/noDepends/no-depends.html', process.cwd() + '/test/html/result/noDepends/no-depends-output.html', function (err, result) {
assert.equal(result.updated, process.cwd() + '/test/html/result/noDepends/no-depends-output.html');
// check the output against the expected output
assert.equal(fs.readFileSync(process.cwd() + '/test/html/result/noDepends/no-depends-output.html', 'utf-8'), fs.readFileSync(process.cwd() + '/test/html/expected/noDepends/no-depends-result.html', 'utf-8'));
// delete the file
fs.unlinkSync(process.cwd() + '/test/html/result/noDepends/no-depends-output.html');
fs.rmdirSync(process.cwd() + '/test/html/result/noDepends/');
// we're done
done();
});
});
});
});
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc