-
-
Save satya164/37c6c541eead8e38439adf6413499e89 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* @flow */ | |
import utils from 'loader-utils'; | |
import size from 'image-size'; | |
import path from 'path'; | |
import hasha from 'hasha'; | |
import AssetResolver from './AssetResolver'; | |
import type { Loader } from 'webpack'; | |
type Config = { | |
platform: string, | |
root: string, | |
outputPath?: string | ((path: string) => string), | |
publicPath?: string | ((path: string) => string), | |
}; | |
async function assetLoader() { | |
(this: Loader); | |
this.cacheable(); | |
const callback = this.async(); | |
const query = utils.getOptions(this); | |
const options = this.options[query.config]; | |
const config: Config = Object.assign({}, options, query); | |
let info: ?{ width: number, height: number, type: string }; | |
try { | |
info = size(this.resourcePath); | |
} catch (e) { | |
// Asset is not an image | |
} | |
const filepath = this.resourcePath; | |
const dirname = path.dirname(filepath); | |
const url = path.relative(config.root, dirname); | |
const type = path.extname(filepath).replace(/^\./, ''); | |
const suffix = `(@\\d+(\\.\\d+)?x)?(\\.(${config.platform}|native))?\\.${type}$`; | |
const filename = path.basename(filepath).replace(new RegExp(suffix), ''); | |
const longname = `${`${url.replace(/\//g, '_')}_${filename}` | |
.toLowerCase() | |
.replace(/[^a-z0-9_]/g, '')}`; | |
const result = await new Promise((resolve, reject) => | |
this.fs.readdir(dirname, (err, res) => { | |
if (err) { | |
reject(err); | |
} else { | |
resolve(res); | |
} | |
}) | |
); | |
const map = AssetResolver.collect(result, { | |
name: filename, | |
type, | |
platform: config.platform, | |
}); | |
const scales = Object.keys(map) | |
.map(s => Number(s.replace(/[^\d.]/g, ''))) | |
.sort(); | |
const pairs = await Promise.all( | |
Object.keys(map).map(scale => { | |
this.addDependency(path.join(dirname, map[scale].name)); | |
return new Promise((resolve, reject) => | |
this.fs.readFile(path.join(dirname, map[scale].name), (err, res) => { | |
if (err) { | |
reject(err); | |
} else { | |
const name = `${longname}${scale === '@1x' ? '' : scale}.${type}`; | |
const dest = path.join('assets', name); | |
resolve({ | |
destination: dest, | |
content: res, | |
}); | |
} | |
}) | |
); | |
}) | |
); | |
pairs.forEach(item => { | |
let dest = item.destination; | |
if (config.outputPath) { | |
// support functions as outputPath to generate them dynamically | |
dest = | |
typeof config.outputPath === 'function' | |
? config.outputPath(dest) | |
: path.join(config.outputPath, dest); | |
} | |
this.emitFile(dest, item.content); | |
}); | |
const buffers = pairs.map(item => item.content); | |
const hashes = buffers.map(b => hasha(b, { algorithm: 'md5' })); | |
let publicPath = `__webpack_public_path__ + ${JSON.stringify(path.join('/', 'assets'))}`; | |
if (config.publicPath) { | |
// support functions as publicPath to generate them dynamically | |
publicPath = JSON.stringify( | |
typeof config.publicPath === 'function' | |
? config.publicPath(url) | |
: path.join(config.publicPath, url) | |
); | |
} | |
callback( | |
null, | |
` | |
var AssetRegistry = require('AssetRegistry'); | |
module.exports = AssetRegistry.registerAsset({ | |
httpServerLocation: ${publicPath}, | |
name: ${JSON.stringify(longname)}, | |
width: ${info ? info.width : JSON.stringify(null)}, | |
height: ${info ? info.height : JSON.stringify(null)}, | |
type: ${JSON.stringify(type)}, | |
hash: ${JSON.stringify(hashes.join())}, | |
fileHashes: ${JSON.stringify(hashes)}, | |
scales: ${JSON.stringify(scales)}, | |
}); | |
` | |
); | |
} | |
module.exports = assetLoader; | |
module.exports.raw = true; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment