Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

enhanced-require

Package Overview
Dependencies
Maintainers
1
Versions
30
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

enhanced-require - npm Package Compare versions

Comparing version 0.4.0-beta3 to 0.4.0-beta4

bin/enhanced-require-hot-watch.js

28

lib/execLoaders.js

@@ -13,3 +13,4 @@ /*

* @param request {string} the compile request string
* @param loaders {string[]} the absolute filenames of the loaders
* @param loaders {{path: String, query: String, module: Boolean}[]}
* the absolute filenames of the loaders
* @param filenames {string[]} the filenames of "contents"

@@ -23,3 +24,3 @@ * @param contents {Buffer[]} read contents

function execLoaders(context, request, loaders, filenames, contents, loaderContextExtras, dependencyInfo, options, sync, callback) {
var loaderFunctions, cacheable = true;
var loaderCallObjects, cacheable = true;
if(loaders.length === 0) {

@@ -30,8 +31,10 @@ // if no loaders are used, the file content is the resulting code

// try to load all loaders
loaderFunctions = [];
loaderCallObjects = [];
try {
loaders.forEach(function(loaderFilename) {
var loader = require(loaderFilename);
loaderFunctions.push(loader);
loaders.forEach(function(l) {
loaderCallObjects.push({
fn: require(l.path),
path: l.path,
query: l.query
});
});

@@ -46,2 +49,3 @@ } catch(e) {

}
function nextLoader(/* err, paramBuffer1, paramBuffer2, ...*/) {

@@ -56,3 +60,3 @@ var args = Array.prototype.slice.apply(arguments);

// if loaders are remaining
if(loaderFunctions.length > 0) {
if(loaderCallObjects.length > 0) {
var loaderCacheable = false;

@@ -70,2 +74,3 @@ var async = false;

}
var loaderCallObject = loaderCallObjects.pop();
var loaderContext = {

@@ -124,4 +129,5 @@ context: context,

},
loaderIndex: loaderFunctions.length - 1,
currentLoaders: loaders,
loaderIndex: loaderCallObjects.length,
currentLoaders: loaders.map(resolve.stringify.part),
query: loaderCallObject.query,
web: true,

@@ -153,3 +159,3 @@ debug: options.debug,

// exec to loader
var retVal = loaderFunctions.pop().apply(loaderContext, params);
var retVal = loaderCallObject.fn.apply(loaderContext, params);

@@ -156,0 +162,0 @@ // if it isn't asynchron, use the return value

@@ -5,6 +5,3 @@ /*

*/
var Module = require("module");
var vm = require("vm");
var path = require("path");
var runInThisContext = require("vm").runInThisContext;

@@ -21,38 +18,19 @@ function stripBOM(content) {

var wrapper = ["(function (exports, require, define, module, __filename, __dirname) {", "})"];
module.exports = function(code, parent, request, filename, enhancedRequire, options, reqObj) {
module.exports = function(code, parent, request, filename, enhancedRequire, options, requireRoot) {
var m;
if(enhancedRequire) {
var m = {
id: request,
parent: parent,
filename: filename,
loaded: false,
children: [],
exports: {}
};
var req = require("./require").factory(m, reqObj);
var wrappedCode = wrapper[0] + stripBOM(code) + wrapper[1];
var wrappedFunction = runInThisContext(wrappedCode, request, request == filename);
var exec = function() {
wrappedFunction.call(m.exports, m.exports, req, req.define, m, filename, path.dirname(filename));
m.loaded = true;
return m.exports;
}
exec.module = m;
return exec;
var EnhancedModule = require("./Module");
m = new EnhancedModule(request, parent, requireRoot);
} else {
var m = new Module(request, parent);
m.filename = filename;
if(options && options.paths)
m.paths = options.paths;
else
m.paths = Module._nodeModulePaths(path.dirname(filename));
var exec = function() {
m._compile(code, filename);
return m.exports;
}
exec.module = m;
return exec;
var NodeModule = require("module");
m = new NodeModule(request, parent);
m.paths = NodeModule._nodeModulePaths(path.dirname(filename));
}
m.filename = filename;
var exec = function() {
m._compile(code, filename);
return m.exports;
}
exec.module = m;
return exec;
}

@@ -9,265 +9,13 @@ /*

var Hot = require("./Hot");
var execModule = require("./execModule");
var execLoaders = require("./execLoaders");
var resolve = require("enhanced-resolve");
var SELF_REQUIRE = "require = require(" + JSON.stringify(__filename) + ")(module);";
var natives = process.binding("natives");
function requireNativeModule(name) {
return require(name);
}
function existsNativeModule(name) {
return natives.hasOwnProperty(name);
}
function addToSet(set, item) {
if(!set) return [item];
if(set.indexOf(item) >= 0) return set;
set.push(item);
return set;
}
/**
* any require(string module) - sync require
* void require(array modules, function callback(modules...), [function errorCallback(err)]) - async require
* void require(array modules) - async require
*/
function theRequire(parent, context, modules, callback, errorCallback) {
if(Array.isArray(modules)) {
theEnsure.call(this, parent, context, modules, function(req, err) {
if(err && errorCallback) return errorCallback(err);
var reqModules = modules.map(function(n) { return req(n) });
if(callback) callback.apply(null, reqModules);
});
} else {
if(callback) throw new Error("require(string, callback) is not a valid signature. You may want to call require(array, function).");
// check native module
if(existsNativeModule(modules)) return requireNativeModule(modules);
// resolve filename
var filename = resolve.sync(context, modules, this.options.resolve);
// check in cache
var cache = this.cache;
if(cache[filename]) {
var m = cache[filename];
if(parent) {
m.parents = addToSet(m.parents, parent.id);
parent.children = addToSet(parent.children, m);
}
return m.exports;
}
// split loaders from resource
var filenameWithLoaders = filename;
var loaders = filename.split(/!/g);
filename = loaders.pop();
// check for resource cache
var content = this.contentCache[filename];
if(!content) {
content = this.contentCache[filename] = fs.readFileSync(filename);
}
// execute the loaders
var source = this.sourceCache[filenameWithLoaders];
if(!source) {
source =
this.sourceCache[filenameWithLoaders] =
execLoaders.sync(
context,
filenameWithLoaders,
loaders, [filename],
[content],
{
loaderType: "loader"
},
null,
this.options
)[0].toString("utf-8");
}
// load the source code
var exec = execModule(
source,
parent,
filenameWithLoaders,
filename,
loaders.length > 0 || this.options.recursive,
this.options,
this
);
// add to cache
cache[filenameWithLoaders] = exec.module;
// make dependency graph
if(parent) {
exec.module.parents = [parent.id];
parent.children.push(exec.module);
}
// execute
return exec();
}
}
function theResolve(parent, context, name, callback) {
if(callback) {
if(existsNativeModule(name)) return callback(null, name);
return resolve(context, name, this.options.resolve, callback);
} else {
if(existsNativeModule(name)) return name;
return resolve.sync(context, name, this.options.resolve);
}
}
function theEnsure(parent, context, modules, callback) {
var options = this.options;
var cache = this.cache;
var reqFn = this.require;
var contentCache = this.contentCache;
var sourceCache = this.sourceCache;
var loadingContent = this.loadingContent;
var loadingSource = this.loadingSource;
mapAsync(modules, function(name, callback) {
if(existsNativeModule(name)) return callback(null, name);
resolve(context, name, callback);
}, function(err, resolvedModules) {
if(err) return callback(err);
mapAsync(resolvedModules, function(resolvedModule, callback) {
if(existsNativeModule(resolvedModule)) return callback();
if(cache[resolvedModule]) return callback();
if(sourceCache[resolvedModule]) return callback();
// split loaders from resource
var filenameWithLoaders = resolvedModule;
var loaders = resolvedModule.split(/!/g);
var filename = loaders.pop();
if(contentCache[filename]) return makeSource(null, contentCache[filename]);
return loadContent();
function loadContent() {
if(!loadingContent[filename]) {
loadingContent[filename] = [makeSource];
fs.readFile(filename, applyToAll(loadingContent[filename], function(content) {
if(!contentCache[filename])
contentCache[filename] = content;
delete loadingContent[filename];
return contentCache[filename];
}));
} else
loadingContent[filename].push(makeSource);
}
function makeSource(err, content) {
if(err) return callback(err);
if(!loadingSource[filenameWithLoaders]) {
loadingSource[filenameWithLoaders] = [callback];
var finished = applyToAll(loadingSource[filenameWithLoaders], function(content) {
if(!sourceCache[filenameWithLoaders])
sourceCache[filenameWithLoaders] = content;
delete loadingSource[filenameWithLoaders];
return sourceCache[filenameWithLoaders];
});
execLoaders(
context,
filenameWithLoaders,
loaders, [filename],
[content],
null,
null,
options,
function(err, sources) {
if(err) return finished(err);
if(sources[0] instanceof Buffer || typeof sources[0] == "string")
finished(null, sources[0].toString("utf-8"));
else
callback(new Error("Loader result is not a Buffer or string"));
}
)
} else
loadingSource[filenameWithLoaders].push(callback);
}
}, function(err) {
return callback(reqFn, err);
})
});
}
function theDefine(parent, context, dependencies, fn, arg3) {
var withName = false;
if(typeof dependencies == "string") {
// pop name
dependencies = fn;
fn = arg3;
withName = true;
}
if(Array.isArray(dependencies)) {
theEnsure.call(this, parent, context, dependencies, function(req) {
parent.exports = fn.apply(null, dependencies.map(function(n) { return req(n) }));
});
} else if(withName) {
fn = dependencies;
if(typeof fn == "function")
parent.exports = fn();
else
parent.exports = fn;
} else {
fn = dependencies;
if(typeof fn == "function")
fn(require, parent.exports, parent);
else
parent.exports = fn;
}
}
function theContext(parent, context, contextName) {
return function(name) {
if(typeof name != "string" || name.substr(0, 2) != "./")
throw new Error("A function created by require.context must be called with a string beginning with './'");
return theRequire.call(this, parent, context, contextName + "/" + name);
}.bind(this);
}
/**
* create a require function from a filename
*/
function requireFactory(parent, reqObj) {
function requireFactory(parent, requireRoot) {
reqObj = Object.create(reqObj.base);
// get the directory
var context = parent ? path.dirname(parent.filename) : "";
// make require function
var require = reqObj.require = theRequire.bind(reqObj, parent, context);
require.options = reqObj.options;
require.cache = reqObj.cache;
require.sourceCache = reqObj.sourceCache;
require.contentCache = reqObj.contentCache;
require.resolve = theResolve.bind(reqObj, parent, context);
require.ensure = theEnsure.bind(reqObj, parent, context);
require.context = theContext.bind(reqObj, parent, context);
require.define = theDefine.bind(reqObj, parent, context);
require.enhanced = require.options.enhanced;
require.amd = require.options.amd;
// init hot
if(reqObj.options && reqObj.options.hot && parent) {
var hot = new Hot(parent, reqObj, require);
require.hot = hot;
if(reqObj.main !== parent) {
hot.data = reqObj.data[parent.id];
parent.hot = hot;
}
var requireContext = requireRoot.createContext(parent);
if(requireContext.require.hot && requireRoot.main !== parent) {
parent.hot = requireContext.require.hot;
}
return require;
return requireContext.require;
};

@@ -296,53 +44,11 @@

if(!options.loader) options.loader = {};
if(!options.watchDelay) options.watchDelay = 400;
if(options.watchDelay === undefined) options.watchDelay = 400;
if(options.recursive === undefined) options.recursive = options.hot;
var reqObj = {
options: options,
cache: {},
sourceCache: {},
contentCache: {},
loadingContent: {},
loadingSource: {},
data: {},
main: parent,
status: options.watch ? "watch" : "idle",
// watch:
updatedContents: [],
contentWatchers: {}
};
reqObj.base = reqObj;
if(options.hot && !options.recursive) throw new Error("hot option depends on recursive option");
return requireFactory(parent, reqObj);
var requireRoot = new (options.hot ? require("./HotRequireRoot") : require("./RequireRoot"))(parent, options);
return requireFactory(parent, requireRoot);
};
exports.factory = requireFactory;
// Helpers
function mapAsync(array, fn, callback) {
var count = array.length;
if(count == 0) return callback(null, array);
var results = array.slice(0);
array.forEach(function(item, idx) {
fn(item, function(err, result) {
if(count < 0) return;
if(err) {
count = -1;
return callback(err);
}
results[idx] = result;
count--;
if(count == 0) {
return callback(null, results);
}
});
});
}
function applyToAll(array, callback) {
return function(err, result) {
if(!err && callback) result = callback(result);
array.forEach(function(fn) {
fn(err, result);
});
}
}
{
"name": "enhanced-require",
"version": "0.4.0-beta3",
"version": "0.4.0-beta4",
"author": "Tobias Koppers @sokra",
"description": "Enhance the require function in node.js with support for loaders which preprocess files and really async require (AMD). Enables Hot Code Replacement.",
"dependencies": {
"enhanced-resolve": "0.3.x",
"enhanced-resolve": "0.4.x",
"clone": "0.0.x",

@@ -20,5 +20,7 @@ "buffer-equal": "0.0.x"

"should": "*",
"raw-loader": "0.2.x"
"raw-loader": "0.2.x",
"jade-loader": "0.2.x"
},
"main": "lib/require",
"bin": "bin/enhanced-require-hot-watch.js",
"engines": {

@@ -25,0 +27,0 @@ "node": ">=0.6"

@@ -34,4 +34,3 @@ var should = require("should");

if(err) throw err;
should.exist(updatedModules);
updatedModules.should.be.eql([]);
should.not.exist(updatedModules);
list.should.be.eql([1]);

@@ -47,4 +46,3 @@ writeCounter(2);

if(err) throw err;
should.exist(updatedModules);
updatedModules.should.be.eql([]);
should.not.exist(updatedModules);
list.should.be.eql([1, -1, 2]);

@@ -74,4 +72,3 @@ writeCounter(3);

if(err) throw err;
should.exist(updatedModules);
updatedModules.should.be.eql([]);
should.not.exist(updatedModules);
list.should.be.eql([1]);

@@ -87,4 +84,3 @@ writeCounter(2);

if(err) throw err;
should.exist(updatedModules);
updatedModules.should.be.eql([]);
should.not.exist(updatedModules);
list.should.be.eql([1, -1, 2]);

@@ -104,3 +100,3 @@ writeCounter(3);

it("should not accept a bubbling update by manual sync check", function(done) {
it("should not accept a bubbling update by manual check", function(done) {
var req = reqFactory(module, {

@@ -117,3 +113,3 @@ hot: true,

err.should.be.instanceOf(Error);
/bubble/.test(err.toString()).should.be.ok;
/bubbling/.test(err.toString()).should.be.ok;
done();

@@ -133,4 +129,3 @@ });

if(err) throw err;
should.exist(updatedModules);
updatedModules.should.be.eql([]);
should.not.exist(updatedModules);
list.should.be.eql(["module.exports = 1"]);

@@ -146,4 +141,3 @@ writeCounter(2);

if(err) throw err;
should.exist(updatedModules);
updatedModules.should.be.eql([]);
should.not.exist(updatedModules);
list.should.be.eql(["module.exports = 1", "MODULE.EXPORTS = 1", "module.exports = 2"]);

@@ -190,3 +184,45 @@ writeCounter(3);

it("should wait for apply if applyOnUpdate = false", function(done) {
var req = reqFactory(module, {
hot: true,
recursive: true,
watch: true,
watchDelay: 10
});
var list = req("./fixtures/hot/counter");
req.hot.setApplyOnUpdate(false);
list.should.be.eql([1]);
setTimeout(function() {
list.should.be.eql([1]);
writeCounter(2);
setTimeout(function() {
list.should.be.eql([1]);
req.hot.status().should.be.eql("ready");
req.hot.apply(function(err, outdatedModules) {
should.not.exist(err);
should.exist(outdatedModules);
outdatedModules.should.have.property("length").be.eql(1);
outdatedModules[0].id.should.be.eql(counterValuePath);
req.hot.status().should.be.eql("watch");
list.should.be.eql([1, -1, 2]);
writeCounter(3);
setTimeout(function() {
req.hot.status().should.be.eql("ready");
req.hot.apply(function(err, outdatedModules) {
should.not.exist(err);
should.exist(outdatedModules);
outdatedModules.should.have.property("length").be.eql(1);
outdatedModules[0].id.should.be.eql(counterValuePath);
req.hot.status().should.be.eql("watch");
list.should.be.eql([1, -1, 2, -2, 3]);
done();
});
}, 100);
});
}, 100);
}, 100);
});
});
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