UI for Zipcoin Blue

ContextModuleFactory.js 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const asyncLib = require("async");
  7. const path = require("path");
  8. const Tapable = require("tapable");
  9. const ContextModule = require("./ContextModule");
  10. const ContextElementDependency = require("./dependencies/ContextElementDependency");
  11. module.exports = class ContextModuleFactory extends Tapable {
  12. constructor(resolvers) {
  13. super();
  14. this.resolvers = resolvers;
  15. }
  16. create(data, callback) {
  17. const context = data.context;
  18. const dependencies = data.dependencies;
  19. const dependency = dependencies[0];
  20. this.applyPluginsAsyncWaterfall("before-resolve", {
  21. context: context,
  22. request: dependency.request,
  23. recursive: dependency.recursive,
  24. regExp: dependency.regExp,
  25. async: dependency.async,
  26. dependencies: dependencies
  27. }, (err, result) => {
  28. if(err) return callback(err);
  29. // Ignored
  30. if(!result) return callback();
  31. const context = result.context;
  32. const request = result.request;
  33. const recursive = result.recursive;
  34. const regExp = result.regExp;
  35. const asyncContext = result.async;
  36. const dependencies = result.dependencies;
  37. let loaders, resource, loadersPrefix = "";
  38. const idx = request.lastIndexOf("!");
  39. if(idx >= 0) {
  40. loaders = request.substr(0, idx + 1);
  41. let i;
  42. for(i = 0; i < loaders.length && loaders[i] === "!"; i++) {
  43. loadersPrefix += "!";
  44. }
  45. loaders = loaders.substr(i).replace(/!+$/, "").replace(/!!+/g, "!");
  46. if(loaders === "") loaders = [];
  47. else loaders = loaders.split("!");
  48. resource = request.substr(idx + 1);
  49. } else {
  50. loaders = [];
  51. resource = request;
  52. }
  53. const resolvers = this.resolvers;
  54. asyncLib.parallel([
  55. function(callback) {
  56. resolvers.context.resolve({}, context, resource, function(err, result) {
  57. if(err) return callback(err);
  58. callback(null, result);
  59. });
  60. },
  61. function(callback) {
  62. asyncLib.map(loaders, function(loader, callback) {
  63. resolvers.loader.resolve({}, context, loader, function(err, result) {
  64. if(err) return callback(err);
  65. callback(null, result);
  66. });
  67. }, callback);
  68. }
  69. ], (err, result) => {
  70. if(err) return callback(err);
  71. this.applyPluginsAsyncWaterfall("after-resolve", {
  72. loaders: loadersPrefix + result[1].join("!") + (result[1].length > 0 ? "!" : ""),
  73. resource: result[0],
  74. recursive: recursive,
  75. regExp: regExp,
  76. async: asyncContext,
  77. dependencies: dependencies,
  78. resolveDependencies: this.resolveDependencies.bind(this)
  79. }, function(err, result) {
  80. if(err) return callback(err);
  81. // Ignored
  82. if(!result) return callback();
  83. return callback(null, new ContextModule(result.resolveDependencies, result.resource, result.recursive, result.regExp, result.loaders, result.async, dependency.chunkName));
  84. });
  85. });
  86. });
  87. }
  88. resolveDependencies(fs, resource, recursive, regExp, callback) {
  89. const cmf = this;
  90. if(!regExp || !resource)
  91. return callback(null, []);
  92. (function addDirectory(directory, callback) {
  93. fs.readdir(directory, (err, files) => {
  94. if(err) return callback(err);
  95. files = cmf.applyPluginsWaterfall("context-module-files", files);
  96. if(!files || files.length === 0) return callback(null, []);
  97. asyncLib.map(files.filter(function(p) {
  98. return p.indexOf(".") !== 0;
  99. }), (seqment, callback) => {
  100. const subResource = path.join(directory, seqment);
  101. fs.stat(subResource, (err, stat) => {
  102. if(err) {
  103. if(err.code === "ENOENT") {
  104. // ENOENT is ok here because the file may have been deleted between
  105. // the readdir and stat calls.
  106. return callback();
  107. } else {
  108. return callback(err);
  109. }
  110. }
  111. if(stat.isDirectory()) {
  112. if(!recursive) return callback();
  113. addDirectory.call(this, subResource, callback);
  114. } else if(stat.isFile()) {
  115. const obj = {
  116. context: resource,
  117. request: "." + subResource.substr(resource.length).replace(/\\/g, "/")
  118. };
  119. this.applyPluginsAsyncWaterfall("alternatives", [obj], (err, alternatives) => {
  120. if(err) return callback(err);
  121. alternatives = alternatives.filter(function(obj) {
  122. return regExp.test(obj.request);
  123. }).map(function(obj) {
  124. const dep = new ContextElementDependency(obj.request);
  125. dep.optional = true;
  126. return dep;
  127. });
  128. callback(null, alternatives);
  129. });
  130. } else callback();
  131. });
  132. }, (err, result) => {
  133. if(err) return callback(err);
  134. if(!result) return callback(null, []);
  135. callback(null, result.filter(function(i) {
  136. return !!i;
  137. }).reduce(function(a, i) {
  138. return a.concat(i);
  139. }, []));
  140. });
  141. });
  142. }.call(this, resource, callback));
  143. }
  144. };