mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-10-01 01:38:07 +08:00
131 lines
3.6 KiB
JavaScript
131 lines
3.6 KiB
JavaScript
'use strict'
|
|
|
|
const fs = require('graceful-fs')
|
|
const mm = require('minimatch')
|
|
const isBinaryFile = require('isbinaryfile')
|
|
const _ = require('lodash')
|
|
const CryptoUtils = require('./utils/crypto-utils')
|
|
|
|
const log = require('./logger').create('preprocess')
|
|
|
|
function createNextProcessor (preprocessors, file, done) {
|
|
return function nextPreprocessor (error, content) {
|
|
// normalize B-C
|
|
if (arguments.length === 1 && typeof error === 'string') {
|
|
content = error
|
|
error = null
|
|
}
|
|
|
|
if (error) {
|
|
file.content = null
|
|
file.contentPath = null
|
|
return done(error)
|
|
}
|
|
|
|
if (!preprocessors.length) {
|
|
file.contentPath = null
|
|
file.content = content
|
|
file.sha = CryptoUtils.sha1(content)
|
|
return done()
|
|
}
|
|
|
|
preprocessors.shift()(content, file, nextPreprocessor)
|
|
}
|
|
}
|
|
|
|
function createPreprocessor (config, basePath, injector) {
|
|
const emitter = injector.get('emitter')
|
|
const alreadyDisplayedErrors = {}
|
|
const instances = {}
|
|
let patterns = Object.keys(config)
|
|
|
|
function instantiatePreprocessor (name) {
|
|
if (alreadyDisplayedErrors[name]) {
|
|
return
|
|
}
|
|
|
|
let p
|
|
|
|
try {
|
|
p = injector.get('preprocessor:' + name)
|
|
} catch (e) {
|
|
if (e.message.includes(`No provider for "preprocessor:${name}"`)) {
|
|
log.error(`Can not load "${name}", it is not registered!\n Perhaps you are missing some plugin?`)
|
|
} else {
|
|
log.error(`Can not load "${name}"!\n ` + e.stack)
|
|
}
|
|
alreadyDisplayedErrors[name] = true
|
|
emitter.emit('load_error', 'preprocessor', name)
|
|
}
|
|
|
|
return p
|
|
}
|
|
|
|
let allPreprocessors = []
|
|
patterns.forEach((pattern) => {
|
|
allPreprocessors = _.union(allPreprocessors, config[pattern])
|
|
})
|
|
allPreprocessors.forEach(instantiatePreprocessor)
|
|
|
|
return function preprocess (file, done) {
|
|
patterns = Object.keys(config)
|
|
let retryCount = 0
|
|
let maxRetries = 3
|
|
function readFileCallback (err, buffer) {
|
|
if (err) {
|
|
log.warn(err)
|
|
if (retryCount < maxRetries) {
|
|
retryCount++
|
|
log.warn('retrying ' + retryCount)
|
|
fs.readFile(file.originalPath, readFileCallback)
|
|
return
|
|
} else {
|
|
throw err
|
|
}
|
|
}
|
|
|
|
isBinaryFile(buffer, buffer.length, function (err, isBinary) {
|
|
if (err) {
|
|
throw err
|
|
}
|
|
|
|
let preprocessorNames = []
|
|
patterns.forEach((pattern) => {
|
|
if (mm(file.originalPath, pattern, { dot: true })) {
|
|
preprocessorNames = _.union(preprocessorNames, config[pattern])
|
|
}
|
|
})
|
|
|
|
let preprocessors = []
|
|
const nextPreprocessor = createNextProcessor(preprocessors, file, done)
|
|
preprocessorNames.forEach((name) => {
|
|
const p = instances[name] || instantiatePreprocessor(name)
|
|
|
|
if (p == null) {
|
|
if (!alreadyDisplayedErrors[name]) {
|
|
alreadyDisplayedErrors[name] = true
|
|
log.error(`Failed to instantiate preprocessor ${name}`)
|
|
emitter.emit('load_error', 'preprocessor', name)
|
|
}
|
|
return
|
|
}
|
|
|
|
instances[name] = p
|
|
if (!isBinary || p.handleBinaryFiles) {
|
|
preprocessors.push(p)
|
|
} else {
|
|
log.warn(`Ignored preprocessing ${file.originalPath} because ${name} has handleBinaryFiles=false.`)
|
|
}
|
|
})
|
|
|
|
nextPreprocessor(null, isBinary ? buffer : buffer.toString())
|
|
})
|
|
}
|
|
return fs.readFile(file.originalPath, readFileCallback)
|
|
}
|
|
}
|
|
|
|
createPreprocessor.$inject = ['config.preprocessors', 'config.basePath', 'injector']
|
|
|
|
exports.createPreprocessor = createPreprocessor
|