UNPKG

plumber-requirejs

Version:

RequireJS (r.js) operation for Plumber pipelines

109 lines (93 loc) 3.85 kB
var operation = require('plumber').operation; var Rx = require('plumber').Rx; var SourceMap = require('mercator').SourceMap; var requirejs = require('requirejs'); var extend = require('extend'); var path = require('path'); // wrap requirejs.optimize as a promise function optimize(options) { return Rx.Observable.create(function(observer) { // FIXME: error reject? requirejs.optimize(extend(options, { // never minimise source in here; it's the job of // another operation optimize: 'none', // always generate a sourcemap generateSourceMaps: true, out: function(compiledData, sourceMapData) { observer.onNext({ data: compiledData, sourceMapData: sourceMapData }); observer.onCompleted(); } })); }); } // Delete any plugin prefix from the path, // e.g. 'text!foo/bar.html' => 'foo/bar.html' function stripPluginsPrefix(path) { return path.replace(/^.*!/, ''); } function resolvePathsRelativeTo(baseDir) { return function(relPath) { return path.resolve(baseDir, relPath); }; } // Unwanted requirejs options (don't make sense with the nature of // Plumber and this operation) var illegalOptions = ['baseUrl' , 'name', 'out']; module.exports = function(baseOptions) { baseOptions = baseOptions || {}; // Abort if any illegal option provided illegalOptions.forEach(function(key) { if (key in baseOptions) { throw new Error("'" + key + "' option should not be used with plumber-requirejs, see documentation"); } }); // FIXME: why does it need to run serially?? // FIXME: supervisor return operation.serialFlatMap(function(resource) { // TODO: accept directory as input resource if (resource.path().isDirectory()) { // TODO: optimize whole directory throw new Error('RequireJS does not support optimising directories yet'); } else { var filename = resource.path().filename(); var pathNoExt = filename.replace(/\.js$/, ''); var basePath = resource.path().dirname(); var rootDir = process.cwd(); // FIXME: re-reads data from disk :-( var options = extend(baseOptions, { // FIXME: do we always want to use baseUrl? // or as explicit argument? baseUrl: basePath, name: pathNoExt }); return optimize(options).map(function(out) { var data = out.data; var sourceMap = SourceMap.fromMapData(out.sourceMapData). mapSourcePaths(stripPluginsPrefix). mapSourcePaths(resolvePathsRelativeTo(basePath)). rebaseSourcePaths(rootDir); // Record all other sources found in the source map in // the supervisor var resourcePath = resource.path() && resource.path().absolute(); var dependencies = sourceMap.sources.filter(function(path) { return path !== resourcePath; }); // FIXME: must re-introduce supervisor in plumber 0.3? // if (dependencies.length > 0) { // supervisor.dependOn(dependencies); // } // If the source had a sourcemap, rebase the LESS // sourcemap based on that original map var originalMapData = resource.sourceMap(); if (originalMapData) { sourceMap = originalMapData.apply(sourceMap); } return resource.withData(data, sourceMap); }); } }); };