Blame view

node_modules/loader-utils/lib/interpolateName.js 2.76 KB
aaac7fed   liuqimichale   add
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
  "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 {
  		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;
  	if(typeof name === "function") {
  		filename = name(loaderContext.resourcePath);
  	} 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 = "";
  	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);
  		}
  	}
  	let url = filename;
  	if(content) {
  		// Match hash template
  		url = url
  			.replace(
  				/\[(?:(\w+):)?hash(?::([a-z]+\d*))?(?::(\d+))?\]/ig,
  				(all, hashType, digestType, maxLength) => getHashDigest(content, hashType, digestType, parseInt(maxLength, 10))
  			)
  			.replace(
  				/\[emoji(?::(\d+))?\]/ig,
  				(all, length) => encodeStringToEmoji(content, length)
  			);
  	}
  	url = url
  		.replace(/\[ext\]/ig, () => ext)
  		.replace(/\[name\]/ig, () => basename)
  		.replace(/\[path\]/ig, () => directory)
  		.replace(/\[folder\]/ig, () => folder);
  	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;