ContextReplacementPlugin.js (4720B)
1 /* 2 MIT License http://www.opensource.org/licenses/mit-license.php 3 Author Tobias Koppers @sokra 4 */ 5 6 "use strict"; 7 8 const ContextElementDependency = require("./dependencies/ContextElementDependency"); 9 const { join } = require("./util/fs"); 10 11 class ContextReplacementPlugin { 12 constructor( 13 resourceRegExp, 14 newContentResource, 15 newContentRecursive, 16 newContentRegExp 17 ) { 18 this.resourceRegExp = resourceRegExp; 19 20 if (typeof newContentResource === "function") { 21 this.newContentCallback = newContentResource; 22 } else if ( 23 typeof newContentResource === "string" && 24 typeof newContentRecursive === "object" 25 ) { 26 this.newContentResource = newContentResource; 27 this.newContentCreateContextMap = (fs, callback) => { 28 callback(null, newContentRecursive); 29 }; 30 } else if ( 31 typeof newContentResource === "string" && 32 typeof newContentRecursive === "function" 33 ) { 34 this.newContentResource = newContentResource; 35 this.newContentCreateContextMap = newContentRecursive; 36 } else { 37 if (typeof newContentResource !== "string") { 38 newContentRegExp = newContentRecursive; 39 newContentRecursive = newContentResource; 40 newContentResource = undefined; 41 } 42 if (typeof newContentRecursive !== "boolean") { 43 newContentRegExp = newContentRecursive; 44 newContentRecursive = undefined; 45 } 46 this.newContentResource = newContentResource; 47 this.newContentRecursive = newContentRecursive; 48 this.newContentRegExp = newContentRegExp; 49 } 50 } 51 52 apply(compiler) { 53 const resourceRegExp = this.resourceRegExp; 54 const newContentCallback = this.newContentCallback; 55 const newContentResource = this.newContentResource; 56 const newContentRecursive = this.newContentRecursive; 57 const newContentRegExp = this.newContentRegExp; 58 const newContentCreateContextMap = this.newContentCreateContextMap; 59 60 compiler.hooks.contextModuleFactory.tap("ContextReplacementPlugin", cmf => { 61 cmf.hooks.beforeResolve.tap("ContextReplacementPlugin", result => { 62 if (!result) return; 63 if (resourceRegExp.test(result.request)) { 64 if (newContentResource !== undefined) { 65 result.request = newContentResource; 66 } 67 if (newContentRecursive !== undefined) { 68 result.recursive = newContentRecursive; 69 } 70 if (newContentRegExp !== undefined) { 71 result.regExp = newContentRegExp; 72 } 73 if (typeof newContentCallback === "function") { 74 newContentCallback(result); 75 } else { 76 for (const d of result.dependencies) { 77 if (d.critical) d.critical = false; 78 } 79 } 80 } 81 return result; 82 }); 83 cmf.hooks.afterResolve.tap("ContextReplacementPlugin", result => { 84 if (!result) return; 85 if (resourceRegExp.test(result.resource)) { 86 if (newContentResource !== undefined) { 87 if ( 88 newContentResource.startsWith("/") || 89 (newContentResource.length > 1 && newContentResource[1] === ":") 90 ) { 91 result.resource = newContentResource; 92 } else { 93 result.resource = join( 94 compiler.inputFileSystem, 95 result.resource, 96 newContentResource 97 ); 98 } 99 } 100 if (newContentRecursive !== undefined) { 101 result.recursive = newContentRecursive; 102 } 103 if (newContentRegExp !== undefined) { 104 result.regExp = newContentRegExp; 105 } 106 if (typeof newContentCreateContextMap === "function") { 107 result.resolveDependencies = 108 createResolveDependenciesFromContextMap( 109 newContentCreateContextMap 110 ); 111 } 112 if (typeof newContentCallback === "function") { 113 const origResource = result.resource; 114 newContentCallback(result); 115 if ( 116 result.resource !== origResource && 117 !result.resource.startsWith("/") && 118 (result.resource.length <= 1 || result.resource[1] !== ":") 119 ) { 120 // When the function changed it to an relative path 121 result.resource = join( 122 compiler.inputFileSystem, 123 origResource, 124 result.resource 125 ); 126 } 127 } else { 128 for (const d of result.dependencies) { 129 if (d.critical) d.critical = false; 130 } 131 } 132 } 133 return result; 134 }); 135 }); 136 } 137 } 138 139 const createResolveDependenciesFromContextMap = createContextMap => { 140 const resolveDependenciesFromContextMap = (fs, options, callback) => { 141 createContextMap(fs, (err, map) => { 142 if (err) return callback(err); 143 const dependencies = Object.keys(map).map(key => { 144 return new ContextElementDependency( 145 map[key] + options.resourceQuery + options.resourceFragment, 146 key, 147 options.category, 148 options.referencedExports 149 ); 150 }); 151 callback(null, dependencies); 152 }); 153 }; 154 return resolveDependenciesFromContextMap; 155 }; 156 157 module.exports = ContextReplacementPlugin;