Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
loader-utils/lib/interpolateName.js /
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
151 lines (119 sloc)
3.69 KB
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
| 'use strict'; | |
| const path = require('path'); | |
| const emojisList = require('emojis-list'); | |
| const getHashDigest = require('./getHashDigest'); | |
| const emojiRegex = /[\uD800-\uDFFF]./; | |
| const emojiList = emojisList.filter((emoji) => emojiRegex.test(emoji)); | |
| const emojiCache = {}; | |
| function encodeStringToEmoji(content, length) { | |
| if (emojiCache[content]) { | |
| return emojiCache[content]; | |
| } | |
| length = length || 1; | |
| const emojis = []; | |
| do { | |
| if (!emojiList.length) { | |
| throw new Error('Ran out of emoji'); | |
| } | |
| const index = Math.floor(Math.random() * emojiList.length); | |
| emojis.push(emojiList[index]); | |
| emojiList.splice(index, 1); | |
| } while (--length > 0); | |
| const emojiEncoding = emojis.join(''); | |
| emojiCache[content] = emojiEncoding; | |
| return emojiEncoding; | |
| } | |
| function interpolateName(loaderContext, name, options) { | |
| let filename; | |
| const hasQuery = | |
| loaderContext.resourceQuery && loaderContext.resourceQuery.length > 1; | |
| if (typeof name === 'function') { | |
| filename = name( | |
| loaderContext.resourcePath, | |
| hasQuery ? loaderContext.resourceQuery : undefined | |
| ); | |
| } else { | |
| filename = name || '[hash].[ext]'; | |
| } | |
| const context = options.context; | |
| const content = options.content; | |
| const regExp = options.regExp; | |
| let ext = 'bin'; | |
| let basename = 'file'; | |
| let directory = ''; | |
| let folder = ''; | |
| let query = ''; | |
| if (loaderContext.resourcePath) { | |
| const parsed = path.parse(loaderContext.resourcePath); | |
| let resourcePath = loaderContext.resourcePath; | |
| if (parsed.ext) { | |
| ext = parsed.ext.substr(1); | |
| } | |
| if (parsed.dir) { | |
| basename = parsed.name; | |
| resourcePath = parsed.dir + path.sep; | |
| } | |
| if (typeof context !== 'undefined') { | |
| directory = path | |
| .relative(context, resourcePath + '_') | |
| .replace(/\\/g, '/') | |
| .replace(/\.\.(\/)?/g, '_$1'); | |
| directory = directory.substr(0, directory.length - 1); | |
| } else { | |
| directory = resourcePath.replace(/\\/g, '/').replace(/\.\.(\/)?/g, '_$1'); | |
| } | |
| if (directory.length === 1) { | |
| directory = ''; | |
| } else if (directory.length > 1) { | |
| folder = path.basename(directory); | |
| } | |
| } | |
| if (loaderContext.resourceQuery && loaderContext.resourceQuery.length > 1) { | |
| query = loaderContext.resourceQuery; | |
| const hashIdx = query.indexOf('#'); | |
| if (hashIdx >= 0) { | |
| query = query.substr(0, hashIdx); | |
| } | |
| } | |
| let url = filename; | |
| if (content) { | |
| // Match hash template | |
| url = url | |
| // `hash` and `contenthash` are same in `loader-utils` context | |
| // let's keep `hash` for backward compatibility | |
| .replace( | |
| /\[(?:([^:\]]+):)?(?:hash|contenthash)(?::([a-z]+\d*))?(?::(\d+))?\]/gi, | |
| (all, hashType, digestType, maxLength) => | |
| getHashDigest(content, hashType, digestType, parseInt(maxLength, 10)) | |
| ) | |
| .replace(/\[emoji(?::(\d+))?\]/gi, (all, length) => | |
| encodeStringToEmoji(content, parseInt(length, 10)) | |
| ); | |
| } | |
| url = url | |
| .replace(/\[ext\]/gi, () => ext) | |
| .replace(/\[name\]/gi, () => basename) | |
| .replace(/\[path\]/gi, () => directory) | |
| .replace(/\[folder\]/gi, () => folder) | |
| .replace(/\[query\]/gi, () => query); | |
| if (regExp && loaderContext.resourcePath) { | |
| const match = loaderContext.resourcePath.match(new RegExp(regExp)); | |
| match && | |
| match.forEach((matched, i) => { | |
| url = url.replace(new RegExp('\\[' + i + '\\]', 'ig'), matched); | |
| }); | |
| } | |
| if ( | |
| typeof loaderContext.options === 'object' && | |
| typeof loaderContext.options.customInterpolateName === 'function' | |
| ) { | |
| url = loaderContext.options.customInterpolateName.call( | |
| loaderContext, | |
| url, | |
| name, | |
| options | |
| ); | |
| } | |
| return url; | |
| } | |
| module.exports = interpolateName; |