From bb40b781a219920dc2dd2d5a1eb0a7024dcef87b Mon Sep 17 00:00:00 2001 From: Ahmad Amireh Date: Sun, 27 Mar 2016 23:16:41 +0200 Subject: [PATCH] this.values and this.inputValues support --- lib/__tests__/applyLoaders.test.js | 34 ++++++++++++++++++++++-- lib/applyLoaders.js | 42 ++++++++++++++++++++++-------- 2 files changed, 63 insertions(+), 13 deletions(-) diff --git a/lib/__tests__/applyLoaders.test.js b/lib/__tests__/applyLoaders.test.js index 6862fd4..c668d78 100644 --- a/lib/__tests__/applyLoaders.test.js +++ b/lib/__tests__/applyLoaders.test.js @@ -107,10 +107,10 @@ describe("applyLoaders", function() { context('given multiple loaders', function() { const loaders = [ { - path: fixturePath('another_loader.js'), + path: fixturePath('identity_loader.js'), }, { - path: fixturePath('identity_loader.js'), + path: fixturePath('another_loader.js'), }, ]; @@ -148,5 +148,35 @@ describe("applyLoaders", function() { done(); }); }); + + it('passes down values from one loader to another as @inputValues', function(done) { + var inputValues = []; + + sandbox.stub(AnotherLoader, '__impl__', function(s) { + inputValues.push(this.inputValues); + + this.values = { foo: 'bar' }; + + return s; + }); + + sandbox.stub(IdentityLoader, '__impl__', function(s) { + inputValues.push(this.inputValues); + + return s; + }); + + Subject({ + loaders, + loaderContext: { resourcePath: './a.js' } + }, fixture('a.js'), null, function(err) { + if (err) { return done(err); } + + assert.deepEqual(inputValues[0], {}); + assert.deepEqual(inputValues[1], { foo: 'bar' }); + + done(); + }); + }); }); }); diff --git a/lib/applyLoaders.js b/lib/applyLoaders.js index 9777954..12a87f5 100644 --- a/lib/applyLoaders.js +++ b/lib/applyLoaders.js @@ -19,13 +19,14 @@ var HappyFakeLoaderContext = require('./HappyFakeLoaderContext'); * The directory of the resource, useful for resolving siblings. * * @param {String} runContext.loaderContext.resource - * The resource path without the loader chain. + * The resource path without the loader chain. This includes the file + * and the query fragment. * * @param {String} runContext.loaderContext.resourcePath - * The resource path without the query fragment. + * The resource file. * * @param {String} runContext.loaderContext.resourceQuery - * The query fragment of the resource path. + * The resource query. * * @param {Object} runContext.compilerOptions * @@ -33,20 +34,32 @@ var HappyFakeLoaderContext = require('./HappyFakeLoaderContext'); * @param {String} sourceMap * @param {Function} done */ -module.exports = function(runContext, sourceCode, sourceMap, done) { - var cursor = 0; +module.exports = applyLoaders; + +function applyLoaders(runContext, sourceCode, sourceMap, done) { + var loaders = runContext.loaders.map(function(x) { + return { + request: x.request, + path: x.path, + query: x.query, + module: require(x.path) + } + }); + + var cursor = loaders.length - 1; var result = { code: sourceCode, map: sourceMap }; + var lastLoaderValues = {}; if (process.env.VERBOSE) { console.log('applying %d loaders (%s) against %s', - runContext.loaders.length, + loaders.length, JSON.stringify(runContext.loaders), runContext.loaderContext.resourcePath ); } function apply() { - var loader = runContext.loaders[cursor++]; + var loader = loaders[cursor--]; if (!loader) { return done(null, result); @@ -55,7 +68,7 @@ module.exports = function(runContext, sourceCode, sourceMap, done) { // TODO: this is probably not the best place to create the context, and it // also should be cached at some layer var context = new HappyFakeLoaderContext(runContext.loaderContext.resourcePath); - var transform = require(loader.path); + var transform = loader.module; context._compiler = runContext.compiler; // for compiler RPCs context._remoteLoaderId = runContext.loaderContext.remoteLoaderId; // for loader RPCs @@ -68,14 +81,21 @@ module.exports = function(runContext, sourceCode, sourceMap, done) { context.resourceQuery = runContext.loaderContext.resourceQuery; context.context = runContext.loaderContext.context; - context.loaders = runContext.loaders; - context.loaderIndex = cursor - 1; + context.loaders = loaders; + context.loaderIndex = cursor + 1; + + context.inputValues = lastLoaderValues; if (transform.pitch) { throw new Error('pitch loaders are not supported!') } - applySyncOrAsync(transform, context, result, acceptResultAndApplyNext); + applySyncOrAsync(transform, context, result, function(err, code, map) { + // inject `this.values` as `this.inputValues` into the next loader + lastLoaderValues = context.values; + + acceptResultAndApplyNext(err, code, map); + }); } function acceptResultAndApplyNext(err, code, map) {