mirror of
https://github.com/atom/atom.git
synced 2026-01-25 23:08:18 -05:00
Decaffeinate ModuleCache
This commit is contained in:
@@ -1,285 +0,0 @@
|
||||
Module = require 'module'
|
||||
path = require 'path'
|
||||
semver = require 'semver'
|
||||
|
||||
# Extend semver.Range to memoize matched versions for speed
|
||||
class Range extends semver.Range
|
||||
constructor: ->
|
||||
super
|
||||
@matchedVersions = new Set()
|
||||
@unmatchedVersions = new Set()
|
||||
|
||||
test: (version) ->
|
||||
return true if @matchedVersions.has(version)
|
||||
return false if @unmatchedVersions.has(version)
|
||||
|
||||
matches = super
|
||||
if matches
|
||||
@matchedVersions.add(version)
|
||||
else
|
||||
@unmatchedVersions.add(version)
|
||||
matches
|
||||
|
||||
nativeModules = null
|
||||
|
||||
cache =
|
||||
builtins: {}
|
||||
debug: false
|
||||
dependencies: {}
|
||||
extensions: {}
|
||||
folders: {}
|
||||
ranges: {}
|
||||
registered: false
|
||||
resourcePath: null
|
||||
resourcePathWithTrailingSlash: null
|
||||
|
||||
# isAbsolute is inlined from fs-plus so that fs-plus itself can be required
|
||||
# from this cache.
|
||||
if process.platform is 'win32'
|
||||
isAbsolute = (pathToCheck) ->
|
||||
pathToCheck and (pathToCheck[1] is ':' or (pathToCheck[0] is '\\' and pathToCheck[1] is '\\'))
|
||||
else
|
||||
isAbsolute = (pathToCheck) ->
|
||||
pathToCheck and pathToCheck[0] is '/'
|
||||
|
||||
isCorePath = (pathToCheck) ->
|
||||
pathToCheck.startsWith(cache.resourcePathWithTrailingSlash)
|
||||
|
||||
loadDependencies = (modulePath, rootPath, rootMetadata, moduleCache) ->
|
||||
fs = require 'fs-plus'
|
||||
|
||||
for childPath in fs.listSync(path.join(modulePath, 'node_modules'))
|
||||
continue if path.basename(childPath) is '.bin'
|
||||
continue if rootPath is modulePath and rootMetadata.packageDependencies?.hasOwnProperty(path.basename(childPath))
|
||||
|
||||
childMetadataPath = path.join(childPath, 'package.json')
|
||||
continue unless fs.isFileSync(childMetadataPath)
|
||||
|
||||
childMetadata = JSON.parse(fs.readFileSync(childMetadataPath))
|
||||
if childMetadata?.version
|
||||
try
|
||||
mainPath = require.resolve(childPath)
|
||||
catch error
|
||||
mainPath = null
|
||||
|
||||
if mainPath
|
||||
moduleCache.dependencies.push
|
||||
name: childMetadata.name
|
||||
version: childMetadata.version
|
||||
path: path.relative(rootPath, mainPath)
|
||||
|
||||
loadDependencies(childPath, rootPath, rootMetadata, moduleCache)
|
||||
|
||||
return
|
||||
|
||||
loadFolderCompatibility = (modulePath, rootPath, rootMetadata, moduleCache) ->
|
||||
fs = require 'fs-plus'
|
||||
|
||||
metadataPath = path.join(modulePath, 'package.json')
|
||||
return unless fs.isFileSync(metadataPath)
|
||||
|
||||
dependencies = JSON.parse(fs.readFileSync(metadataPath))?.dependencies ? {}
|
||||
|
||||
for name, version of dependencies
|
||||
try
|
||||
new Range(version)
|
||||
catch error
|
||||
delete dependencies[name]
|
||||
|
||||
onDirectory = (childPath) ->
|
||||
path.basename(childPath) isnt 'node_modules'
|
||||
|
||||
extensions = ['.js', '.coffee', '.json', '.node']
|
||||
paths = {}
|
||||
onFile = (childPath) ->
|
||||
if path.extname(childPath) in extensions
|
||||
relativePath = path.relative(rootPath, path.dirname(childPath))
|
||||
paths[relativePath] = true
|
||||
fs.traverseTreeSync(modulePath, onFile, onDirectory)
|
||||
|
||||
paths = Object.keys(paths)
|
||||
if paths.length > 0 and Object.keys(dependencies).length > 0
|
||||
moduleCache.folders.push({paths, dependencies})
|
||||
|
||||
for childPath in fs.listSync(path.join(modulePath, 'node_modules'))
|
||||
continue if path.basename(childPath) is '.bin'
|
||||
continue if rootPath is modulePath and rootMetadata.packageDependencies?.hasOwnProperty(path.basename(childPath))
|
||||
|
||||
loadFolderCompatibility(childPath, rootPath, rootMetadata, moduleCache)
|
||||
|
||||
return
|
||||
|
||||
loadExtensions = (modulePath, rootPath, rootMetadata, moduleCache) ->
|
||||
fs = require 'fs-plus'
|
||||
extensions = ['.js', '.coffee', '.json', '.node']
|
||||
nodeModulesPath = path.join(rootPath, 'node_modules')
|
||||
|
||||
onFile = (filePath) ->
|
||||
filePath = path.relative(rootPath, filePath)
|
||||
segments = filePath.split(path.sep)
|
||||
return if 'test' in segments
|
||||
return if 'tests' in segments
|
||||
return if 'spec' in segments
|
||||
return if 'specs' in segments
|
||||
return if segments.length > 1 and not (segments[0] in ['exports', 'lib', 'node_modules', 'src', 'static', 'vendor'])
|
||||
|
||||
extension = path.extname(filePath)
|
||||
if extension in extensions
|
||||
moduleCache.extensions[extension] ?= []
|
||||
moduleCache.extensions[extension].push(filePath)
|
||||
|
||||
onDirectory = (childPath) ->
|
||||
# Don't include extensions from bundled packages
|
||||
# These are generated and stored in the package's own metadata cache
|
||||
if rootMetadata.name is 'atom'
|
||||
parentPath = path.dirname(childPath)
|
||||
if parentPath is nodeModulesPath
|
||||
packageName = path.basename(childPath)
|
||||
return false if rootMetadata.packageDependencies?.hasOwnProperty(packageName)
|
||||
|
||||
true
|
||||
|
||||
fs.traverseTreeSync(rootPath, onFile, onDirectory)
|
||||
|
||||
return
|
||||
|
||||
satisfies = (version, rawRange) ->
|
||||
unless parsedRange = cache.ranges[rawRange]
|
||||
parsedRange = new Range(rawRange)
|
||||
cache.ranges[rawRange] = parsedRange
|
||||
parsedRange.test(version)
|
||||
|
||||
resolveFilePath = (relativePath, parentModule) ->
|
||||
return unless relativePath
|
||||
return unless parentModule?.filename
|
||||
return unless relativePath[0] is '.' or isAbsolute(relativePath)
|
||||
|
||||
resolvedPath = path.resolve(path.dirname(parentModule.filename), relativePath)
|
||||
return unless isCorePath(resolvedPath)
|
||||
|
||||
extension = path.extname(resolvedPath)
|
||||
if extension
|
||||
return resolvedPath if cache.extensions[extension]?.has(resolvedPath)
|
||||
else
|
||||
for extension, paths of cache.extensions
|
||||
resolvedPathWithExtension = "#{resolvedPath}#{extension}"
|
||||
return resolvedPathWithExtension if paths.has(resolvedPathWithExtension)
|
||||
|
||||
return
|
||||
|
||||
resolveModulePath = (relativePath, parentModule) ->
|
||||
return unless relativePath
|
||||
return unless parentModule?.filename
|
||||
|
||||
nativeModules ?= process.binding('natives')
|
||||
return if nativeModules.hasOwnProperty(relativePath)
|
||||
return if relativePath[0] is '.'
|
||||
return if isAbsolute(relativePath)
|
||||
|
||||
folderPath = path.dirname(parentModule.filename)
|
||||
|
||||
range = cache.folders[folderPath]?[relativePath]
|
||||
unless range?
|
||||
if builtinPath = cache.builtins[relativePath]
|
||||
return builtinPath
|
||||
else
|
||||
return
|
||||
|
||||
candidates = cache.dependencies[relativePath]
|
||||
return unless candidates?
|
||||
|
||||
for version, resolvedPath of candidates
|
||||
if Module._cache[resolvedPath] or isCorePath(resolvedPath)
|
||||
return resolvedPath if satisfies(version, range)
|
||||
|
||||
return
|
||||
|
||||
registerBuiltins = (devMode) ->
|
||||
if devMode or not cache.resourcePath.startsWith("#{process.resourcesPath}#{path.sep}")
|
||||
fs = require 'fs-plus'
|
||||
atomJsPath = path.join(cache.resourcePath, 'exports', 'atom.js')
|
||||
cache.builtins.atom = atomJsPath if fs.isFileSync(atomJsPath)
|
||||
cache.builtins.atom ?= path.join(cache.resourcePath, 'exports', 'atom.js')
|
||||
|
||||
electronAsarRoot = path.join(process.resourcesPath, 'electron.asar')
|
||||
|
||||
commonRoot = path.join(electronAsarRoot, 'common', 'api')
|
||||
commonBuiltins = ['callbacks-registry', 'clipboard', 'crash-reporter', 'shell']
|
||||
for builtin in commonBuiltins
|
||||
cache.builtins[builtin] = path.join(commonRoot, "#{builtin}.js")
|
||||
|
||||
rendererRoot = path.join(electronAsarRoot, 'renderer', 'api')
|
||||
rendererBuiltins = ['ipc-renderer', 'remote', 'screen']
|
||||
for builtin in rendererBuiltins
|
||||
cache.builtins[builtin] = path.join(rendererRoot, "#{builtin}.js")
|
||||
|
||||
exports.create = (modulePath) ->
|
||||
fs = require 'fs-plus'
|
||||
|
||||
modulePath = fs.realpathSync(modulePath)
|
||||
metadataPath = path.join(modulePath, 'package.json')
|
||||
metadata = JSON.parse(fs.readFileSync(metadataPath))
|
||||
|
||||
moduleCache =
|
||||
version: 1
|
||||
dependencies: []
|
||||
extensions: {}
|
||||
folders: []
|
||||
|
||||
loadDependencies(modulePath, modulePath, metadata, moduleCache)
|
||||
loadFolderCompatibility(modulePath, modulePath, metadata, moduleCache)
|
||||
loadExtensions(modulePath, modulePath, metadata, moduleCache)
|
||||
|
||||
metadata._atomModuleCache = moduleCache
|
||||
fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2))
|
||||
|
||||
return
|
||||
|
||||
exports.register = ({resourcePath, devMode}={}) ->
|
||||
return if cache.registered
|
||||
|
||||
originalResolveFilename = Module._resolveFilename
|
||||
Module._resolveFilename = (relativePath, parentModule) ->
|
||||
resolvedPath = resolveModulePath(relativePath, parentModule)
|
||||
resolvedPath ?= resolveFilePath(relativePath, parentModule)
|
||||
resolvedPath ? originalResolveFilename(relativePath, parentModule)
|
||||
|
||||
cache.registered = true
|
||||
cache.resourcePath = resourcePath
|
||||
cache.resourcePathWithTrailingSlash = "#{resourcePath}#{path.sep}"
|
||||
registerBuiltins(devMode)
|
||||
|
||||
return
|
||||
|
||||
exports.add = (directoryPath, metadata) ->
|
||||
# path.join isn't used in this function for speed since path.join calls
|
||||
# path.normalize and all the paths are already normalized here.
|
||||
|
||||
unless metadata?
|
||||
try
|
||||
metadata = require("#{directoryPath}#{path.sep}package.json")
|
||||
catch error
|
||||
return
|
||||
|
||||
cacheToAdd = metadata?._atomModuleCache
|
||||
return unless cacheToAdd?
|
||||
|
||||
for dependency in cacheToAdd.dependencies ? []
|
||||
cache.dependencies[dependency.name] ?= {}
|
||||
cache.dependencies[dependency.name][dependency.version] ?= "#{directoryPath}#{path.sep}#{dependency.path}"
|
||||
|
||||
for entry in cacheToAdd.folders ? []
|
||||
for folderPath in entry.paths
|
||||
if folderPath
|
||||
cache.folders["#{directoryPath}#{path.sep}#{folderPath}"] = entry.dependencies
|
||||
else
|
||||
cache.folders[directoryPath] = entry.dependencies
|
||||
|
||||
for extension, paths of cacheToAdd.extensions
|
||||
cache.extensions[extension] ?= new Set()
|
||||
for filePath in paths
|
||||
cache.extensions[extension].add("#{directoryPath}#{path.sep}#{filePath}")
|
||||
|
||||
return
|
||||
|
||||
exports.cache = cache
|
||||
337
src/module-cache.js
Normal file
337
src/module-cache.js
Normal file
@@ -0,0 +1,337 @@
|
||||
const Module = require('module')
|
||||
const path = require('path')
|
||||
const semver = require('semver')
|
||||
|
||||
// Extend semver.Range to memoize matched versions for speed
|
||||
class Range extends semver.Range {
|
||||
constructor () {
|
||||
super(...arguments)
|
||||
this.matchedVersions = new Set()
|
||||
this.unmatchedVersions = new Set()
|
||||
}
|
||||
|
||||
test (version) {
|
||||
if (this.matchedVersions.has(version)) return true
|
||||
if (this.unmatchedVersions.has(version)) return false
|
||||
|
||||
const matches = super.test(...arguments)
|
||||
if (matches) {
|
||||
this.matchedVersions.add(version)
|
||||
} else {
|
||||
this.unmatchedVersions.add(version)
|
||||
}
|
||||
return matches
|
||||
}
|
||||
}
|
||||
|
||||
let nativeModules = null
|
||||
|
||||
const cache = {
|
||||
builtins: {},
|
||||
debug: false,
|
||||
dependencies: {},
|
||||
extensions: {},
|
||||
folders: {},
|
||||
ranges: {},
|
||||
registered: false,
|
||||
resourcePath: null,
|
||||
resourcePathWithTrailingSlash: null
|
||||
}
|
||||
|
||||
// isAbsolute is inlined from fs-plus so that fs-plus itself can be required
|
||||
// from this cache.
|
||||
let isAbsolute
|
||||
if (process.platform === 'win32') {
|
||||
isAbsolute = pathToCheck => pathToCheck && ((pathToCheck[1] === ':') || ((pathToCheck[0] === '\\') && (pathToCheck[1] === '\\')))
|
||||
} else {
|
||||
isAbsolute = pathToCheck => pathToCheck && (pathToCheck[0] === '/')
|
||||
}
|
||||
|
||||
const isCorePath = pathToCheck => pathToCheck.startsWith(cache.resourcePathWithTrailingSlash)
|
||||
|
||||
function loadDependencies (modulePath, rootPath, rootMetadata, moduleCache) {
|
||||
const fs = require('fs-plus')
|
||||
|
||||
for (let childPath of fs.listSync(path.join(modulePath, 'node_modules'))) {
|
||||
if (path.basename(childPath) === '.bin') continue
|
||||
if (rootPath === modulePath && (rootMetadata.packageDependencies && rootMetadata.packageDependencies.hasOwnProperty(path.basename(childPath)))) {
|
||||
continue
|
||||
}
|
||||
|
||||
const childMetadataPath = path.join(childPath, 'package.json')
|
||||
if (!fs.isFileSync(childMetadataPath)) continue
|
||||
|
||||
const childMetadata = JSON.parse(fs.readFileSync(childMetadataPath))
|
||||
if (childMetadata && childMetadata.version) {
|
||||
var mainPath
|
||||
try {
|
||||
mainPath = require.resolve(childPath)
|
||||
} catch (error) {
|
||||
mainPath = null
|
||||
}
|
||||
|
||||
if (mainPath) {
|
||||
moduleCache.dependencies.push({
|
||||
name: childMetadata.name,
|
||||
version: childMetadata.version,
|
||||
path: path.relative(rootPath, mainPath)
|
||||
})
|
||||
}
|
||||
|
||||
loadDependencies(childPath, rootPath, rootMetadata, moduleCache)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function loadFolderCompatibility (modulePath, rootPath, rootMetadata, moduleCache) {
|
||||
const fs = require('fs-plus')
|
||||
|
||||
const metadataPath = path.join(modulePath, 'package.json')
|
||||
if (!fs.isFileSync(metadataPath)) return
|
||||
|
||||
const metadata = JSON.parse(fs.readFileSync(metadataPath))
|
||||
const dependencies = metadata.dependencies || {}
|
||||
|
||||
for (let name in dependencies) {
|
||||
if (!semver.validRange(dependencies[name])) {
|
||||
delete dependencies[name]
|
||||
}
|
||||
}
|
||||
|
||||
const onDirectory = childPath => path.basename(childPath) !== 'node_modules'
|
||||
|
||||
const extensions = ['.js', '.coffee', '.json', '.node']
|
||||
let paths = {}
|
||||
function onFile (childPath) {
|
||||
const needle = path.extname(childPath)
|
||||
if (extensions.includes(needle)) {
|
||||
const relativePath = path.relative(rootPath, path.dirname(childPath))
|
||||
paths[relativePath] = true
|
||||
}
|
||||
}
|
||||
fs.traverseTreeSync(modulePath, onFile, onDirectory)
|
||||
|
||||
paths = Object.keys(paths)
|
||||
if (paths.length > 0 && Object.keys(dependencies).length > 0) {
|
||||
moduleCache.folders.push({paths, dependencies})
|
||||
}
|
||||
|
||||
for (let childPath of fs.listSync(path.join(modulePath, 'node_modules'))) {
|
||||
if (path.basename(childPath) === '.bin') continue
|
||||
if (rootPath === modulePath && (rootMetadata.packageDependencies && rootMetadata.packageDependencies.hasOwnProperty(path.basename(childPath)))) {
|
||||
continue
|
||||
}
|
||||
loadFolderCompatibility(childPath, rootPath, rootMetadata, moduleCache)
|
||||
}
|
||||
}
|
||||
|
||||
function loadExtensions (modulePath, rootPath, rootMetadata, moduleCache) {
|
||||
const fs = require('fs-plus')
|
||||
const extensions = ['.js', '.coffee', '.json', '.node']
|
||||
const nodeModulesPath = path.join(rootPath, 'node_modules')
|
||||
|
||||
function onFile (filePath) {
|
||||
filePath = path.relative(rootPath, filePath)
|
||||
const segments = filePath.split(path.sep)
|
||||
if (segments.includes('test')) return
|
||||
if (segments.includes('tests')) return
|
||||
if (segments.includes('spec')) return
|
||||
if (segments.includes('specs')) return
|
||||
if (segments.length > 1 && !['exports', 'lib', 'node_modules', 'src', 'static', 'vendor'].includes(segments[0])) return
|
||||
|
||||
const extension = path.extname(filePath)
|
||||
if (extensions.includes(extension)) {
|
||||
if (moduleCache.extensions[extension] == null) { moduleCache.extensions[extension] = [] }
|
||||
moduleCache.extensions[extension].push(filePath)
|
||||
}
|
||||
}
|
||||
|
||||
function onDirectory (childPath) {
|
||||
// Don't include extensions from bundled packages
|
||||
// These are generated and stored in the package's own metadata cache
|
||||
if (rootMetadata.name === 'atom') {
|
||||
const parentPath = path.dirname(childPath)
|
||||
if (parentPath === nodeModulesPath) {
|
||||
const packageName = path.basename(childPath)
|
||||
if (rootMetadata.packageDependencies && rootMetadata.packageDependencies.hasOwnProperty(packageName)) return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
fs.traverseTreeSync(rootPath, onFile, onDirectory)
|
||||
}
|
||||
|
||||
function satisfies (version, rawRange) {
|
||||
let parsedRange
|
||||
if (!(parsedRange = cache.ranges[rawRange])) {
|
||||
parsedRange = new Range(rawRange)
|
||||
cache.ranges[rawRange] = parsedRange
|
||||
}
|
||||
return parsedRange.test(version)
|
||||
}
|
||||
|
||||
function resolveFilePath (relativePath, parentModule) {
|
||||
if (!relativePath) return
|
||||
if (!(parentModule && parentModule.filename)) return
|
||||
if (relativePath[0] !== '.' && !isAbsolute(relativePath)) return
|
||||
|
||||
const resolvedPath = path.resolve(path.dirname(parentModule.filename), relativePath)
|
||||
if (!isCorePath(resolvedPath)) return
|
||||
|
||||
let extension = path.extname(resolvedPath)
|
||||
if (extension) {
|
||||
if (cache.extensions[extension] && cache.extensions[extension].has(resolvedPath)) return resolvedPath
|
||||
} else {
|
||||
for (extension in cache.extensions) {
|
||||
const paths = cache.extensions[extension]
|
||||
const resolvedPathWithExtension = `${resolvedPath}${extension}`
|
||||
if (paths.has(resolvedPathWithExtension)) {
|
||||
return resolvedPathWithExtension
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function resolveModulePath (relativePath, parentModule) {
|
||||
if (!relativePath) return
|
||||
if (!(parentModule && parentModule.filename)) return
|
||||
|
||||
if (!nativeModules) nativeModules = process.binding('natives')
|
||||
if (nativeModules.hasOwnProperty(relativePath)) return
|
||||
if (relativePath[0] === '.') return
|
||||
if (isAbsolute(relativePath)) return
|
||||
|
||||
const folderPath = path.dirname(parentModule.filename)
|
||||
|
||||
const range = cache.folders[folderPath] && cache.folders[folderPath][relativePath]
|
||||
if (!range) {
|
||||
const builtinPath = cache.builtins[relativePath]
|
||||
if (builtinPath) {
|
||||
return builtinPath
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const candidates = cache.dependencies[relativePath]
|
||||
if (candidates == null) return
|
||||
|
||||
for (let version in candidates) {
|
||||
const resolvedPath = candidates[version]
|
||||
if (Module._cache[resolvedPath] || isCorePath(resolvedPath)) {
|
||||
if (satisfies(version, range)) return resolvedPath
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function registerBuiltins (devMode) {
|
||||
if (devMode || !cache.resourcePath.startsWith(`${process.resourcesPath}${path.sep}`)) {
|
||||
const fs = require('fs-plus')
|
||||
const atomJsPath = path.join(cache.resourcePath, 'exports', 'atom.js')
|
||||
if (fs.isFileSync(atomJsPath)) { cache.builtins.atom = atomJsPath }
|
||||
}
|
||||
if (cache.builtins.atom == null) { cache.builtins.atom = path.join(cache.resourcePath, 'exports', 'atom.js') }
|
||||
|
||||
const electronAsarRoot = path.join(process.resourcesPath, 'electron.asar')
|
||||
|
||||
const commonRoot = path.join(electronAsarRoot, 'common', 'api')
|
||||
const commonBuiltins = ['callbacks-registry', 'clipboard', 'crash-reporter', 'shell']
|
||||
for (const builtin of commonBuiltins) {
|
||||
cache.builtins[builtin] = path.join(commonRoot, `${builtin}.js`)
|
||||
}
|
||||
|
||||
const rendererRoot = path.join(electronAsarRoot, 'renderer', 'api')
|
||||
const rendererBuiltins = ['ipc-renderer', 'remote', 'screen']
|
||||
for (const builtin of rendererBuiltins) {
|
||||
cache.builtins[builtin] = path.join(rendererRoot, `${builtin}.js`)
|
||||
}
|
||||
}
|
||||
|
||||
exports.create = function (modulePath) {
|
||||
const fs = require('fs-plus')
|
||||
|
||||
modulePath = fs.realpathSync(modulePath)
|
||||
const metadataPath = path.join(modulePath, 'package.json')
|
||||
const metadata = JSON.parse(fs.readFileSync(metadataPath))
|
||||
|
||||
const moduleCache = {
|
||||
version: 1,
|
||||
dependencies: [],
|
||||
extensions: {},
|
||||
folders: []
|
||||
}
|
||||
|
||||
loadDependencies(modulePath, modulePath, metadata, moduleCache)
|
||||
loadFolderCompatibility(modulePath, modulePath, metadata, moduleCache)
|
||||
loadExtensions(modulePath, modulePath, metadata, moduleCache)
|
||||
|
||||
metadata._atomModuleCache = moduleCache
|
||||
fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2))
|
||||
}
|
||||
|
||||
exports.register = function ({resourcePath, devMode} = {}) {
|
||||
if (cache.registered) return
|
||||
|
||||
const originalResolveFilename = Module._resolveFilename
|
||||
Module._resolveFilename = function (relativePath, parentModule) {
|
||||
let resolvedPath = resolveModulePath(relativePath, parentModule)
|
||||
if (!resolvedPath) {
|
||||
resolvedPath = resolveFilePath(relativePath, parentModule)
|
||||
}
|
||||
return resolvedPath || originalResolveFilename(relativePath, parentModule)
|
||||
}
|
||||
|
||||
cache.registered = true
|
||||
cache.resourcePath = resourcePath
|
||||
cache.resourcePathWithTrailingSlash = `${resourcePath}${path.sep}`
|
||||
registerBuiltins(devMode)
|
||||
}
|
||||
|
||||
exports.add = function (directoryPath, metadata) {
|
||||
// path.join isn't used in this function for speed since path.join calls
|
||||
// path.normalize and all the paths are already normalized here.
|
||||
|
||||
if (metadata == null) {
|
||||
try {
|
||||
metadata = require(`${directoryPath}${path.sep}package.json`)
|
||||
} catch (error) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const cacheToAdd = metadata && metadata._atomModuleCache
|
||||
if (!cacheToAdd) return
|
||||
|
||||
for (const dependency of cacheToAdd.dependencies || []) {
|
||||
if (!cache.dependencies[dependency.name]) {
|
||||
cache.dependencies[dependency.name] = {}
|
||||
}
|
||||
if (!cache.dependencies[dependency.name][dependency.version]) {
|
||||
cache.dependencies[dependency.name][dependency.version] = `${directoryPath}${path.sep}${dependency.path}`
|
||||
}
|
||||
}
|
||||
|
||||
for (const entry of cacheToAdd.folders || []) {
|
||||
for (const folderPath of entry.paths) {
|
||||
if (folderPath) {
|
||||
cache.folders[`${directoryPath}${path.sep}${folderPath}`] = entry.dependencies
|
||||
} else {
|
||||
cache.folders[directoryPath] = entry.dependencies
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const extension in cacheToAdd.extensions) {
|
||||
const paths = cacheToAdd.extensions[extension]
|
||||
if (!cache.extensions[extension]) {
|
||||
cache.extensions[extension] = new Set()
|
||||
}
|
||||
for (let filePath of paths) {
|
||||
cache.extensions[extension].add(`${directoryPath}${path.sep}${filePath}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exports.cache = cache
|
||||
Reference in New Issue
Block a user