| const fs = require('fs') | 
| const path = require('path') | 
| const { resolveCompiler } = require('./compiler') | 
|   | 
| const cache = new Map() | 
|   | 
| exports.setDescriptor = function setDescriptor(filename, entry) { | 
|   cache.set(cleanQuery(filename), entry) | 
| } | 
|   | 
| exports.getDescriptor = function getDescriptor( | 
|   filename, | 
|   options, | 
|   loaderContext | 
| ) { | 
|   filename = cleanQuery(filename) | 
|   if (cache.has(filename)) { | 
|     return cache.get(filename) | 
|   } | 
|   | 
|   // This function should only be called after the descriptor has been | 
|   // cached by the main loader. | 
|   // If this is somehow called without a cache hit, it's probably due to sub | 
|   // loaders being run in separate threads. The only way to deal with this is to | 
|   // read from disk directly... | 
|   const source = fs.readFileSync(filename, 'utf-8') | 
|   const sourceRoot = path.dirname( | 
|     path.relative(loaderContext.rootContext, loaderContext.resourcePath) | 
|   ) | 
|   const { compiler, templateCompiler } = resolveCompiler( | 
|     loaderContext.rootContext | 
|   ) | 
|   const descriptor = compiler.parse({ | 
|     source, | 
|     compiler: options.compiler || templateCompiler, | 
|     filename, | 
|     sourceRoot, | 
|     needMap: loaderContext.sourceMap | 
|   }) | 
|   cache.set(filename, descriptor) | 
|   return descriptor | 
| } | 
|   | 
| function cleanQuery(str) { | 
|   const i = str.indexOf('?') | 
|   return i > 0 ? str.slice(0, i) : str | 
| } |