Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Initial Commit

  • Loading branch information...
commit ceaec0853c391a588c3dd72ccf93d007af97a572 0 parents
Tim Caswell authored
Showing with 132 additions and 0 deletions.
  1. +25 −0 README.markdown
  2. +66 −0 embedder.js
  3. +27 −0 module.js
  4. +14 −0 package.json
25 README.markdown
@@ -0,0 +1,25 @@
+This is a simple tool that takes several node modules and combines them into a single file.
+
+This is done by implementing a mini require/define system.
+
+## Sample Usage
+
+The best way to explain this is to show a sample usage. Suppose that I have a node script (with dependencies) that I want to run in some node sandbox. I can embed my script and all it's dependencies into a single script and then run that.
+
+ var embedder = require('embedder');
+ var runInNewContext = require('vm').runInNewContext;
+
+ embedder({
+ "client": "./node_modules/client.js",
+ "protocol": "./node_modules/protocol.js",
+ "msgpack-js": "./node_modules/msgpack-js/msgpack.js",
+ }, function (err, code) {
+ if (err) throw err;
+ code += "\nrequire('client');\n";
+ runInNewContext(code, {
+ require: require,
+ process: process,
+ Buffer: Buffer,
+ console: console
+ }, "generated.js");
+ });
66 embedder.js
@@ -0,0 +1,66 @@
+var FS = require('fs');
+// Takes a dependencies map and generates a single js file.
+module.exports = function embedder(dependencies, callback) {
+ var files = {};
+ var isDone = false;
+ var module;
+ function error(err) {
+ if (isDone) return;
+ isDone = true;
+ callback(err);
+ }
+
+ var left = 1;
+ FS.readFile(__dirname + "/module.js", 'utf8', function (err, file) {
+ if (err) return error(err);
+ left--;
+ module = file;
+ if (left === 0) {
+ finish();
+ }
+ });
+
+ // Load all the dependencies in parallel
+ Object.keys(dependencies).forEach(function (name) {
+ left++;
+ FS.readFile(dependencies[name], 'utf8', function (err, file) {
+ if (isDone) return;
+ if (err) return error(err);
+ files[name] = file;
+ left--;
+ if (left === 0) {
+ finish();
+ }
+ });
+ });
+
+ function finish() {
+ var parts = [module];
+
+ Object.keys(files).forEach(function (name) {
+ var content = files[name];
+ try {
+ new Function(content);
+ } catch (err) {
+ err.file = dependencies[name];
+ console.error("Syntax error in %s", err.file);
+ return error(err);
+ }
+ parts.push("\ndefine('" + name + "', function (module, exports) {\n\n" + content + "\n});\n");
+ });
+
+ var code = parts.join("\n");
+ // Syntax check
+ try {
+ new Function(code);
+ } catch (err) {
+ console.error("Syntax error in generated code");
+ err.js = code;
+ return error(err);
+ }
+ isDone = true;
+ callback(null, code);
+ }
+
+}
+
27 module.js
@@ -0,0 +1,27 @@
+// Super simple require system
+(function () {
+
+// Store our repository in private variables in this closure.
+var defs = {},
+ modules = {};
+
+// When the user defines a module's setup function, store it here.
+define = function define(name, fn) {
+ defs[name] = fn;
+}
+
+var realRequire = require;
+// The first time a module is used, it's description is executed and cached.
+require = function require(name) {
+ if (modules.hasOwnProperty(name)) return modules[name];
+ if (defs.hasOwnProperty(name)) {
+ var exports = modules[name] = {};
+ var module = {exports:exports};
+ var fn = defs[name];
+ fn(module, exports);
+ return modules[name] = module.exports;
+ }
+ return realRequire(name);
+}
+
+}());
14 package.json
@@ -0,0 +1,14 @@
+{
+ "author": "Tim Caswell <tim@creationix.com>",
+ "name": "embedder",
+ "description": "A simple tool to combine several node modules into a single script.",
+ "version": "0.0.1",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/creationix/embedder.git"
+ },
+ "main": "embedder.js",
+ "engines": {
+ "node": "~0.6.0"
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.