UNPKG

2.61 kBJavaScriptView Raw
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5"use strict";
6
7const path = require("path");
8const NORMALIZE_SLASH_DIRECTION_REGEXP = /\\/g;
9const PATH_CHARS_REGEXP = /[-[\]{}()*+?.,\\^$|#\s]/g;
10const SEPARATOR_REGEXP = /[/\\]$/;
11const FRONT_OR_BACK_BANG_REGEXP = /^!|!$/g;
12const INDEX_JS_REGEXP = /\/index.js(!|\?|\(query\))/g;
13const MATCH_RESOURCE_REGEXP = /!=!/;
14
15const normalizeBackSlashDirection = request => {
16 return request.replace(NORMALIZE_SLASH_DIRECTION_REGEXP, "/");
17};
18
19const createRegExpForPath = path => {
20 const regexpTypePartial = path.replace(PATH_CHARS_REGEXP, "\\$&");
21 return new RegExp(`(^|!)${regexpTypePartial}`, "g");
22};
23
24class RequestShortener {
25 constructor(directory) {
26 directory = normalizeBackSlashDirection(directory);
27 if (SEPARATOR_REGEXP.test(directory)) {
28 directory = directory.substr(0, directory.length - 1);
29 }
30
31 if (directory) {
32 this.currentDirectoryRegExp = createRegExpForPath(directory);
33 }
34
35 const dirname = path.dirname(directory);
36 const endsWithSeparator = SEPARATOR_REGEXP.test(dirname);
37 const parentDirectory = endsWithSeparator
38 ? dirname.substr(0, dirname.length - 1)
39 : dirname;
40 if (parentDirectory && parentDirectory !== directory) {
41 this.parentDirectoryRegExp = createRegExpForPath(parentDirectory);
42 }
43
44 if (__dirname.length >= 2) {
45 const buildins = normalizeBackSlashDirection(path.join(__dirname, ".."));
46 const buildinsAsModule =
47 this.currentDirectoryRegExp &&
48 this.currentDirectoryRegExp.test(buildins);
49 this.buildinsAsModule = buildinsAsModule;
50 this.buildinsRegExp = createRegExpForPath(buildins);
51 }
52
53 this.cache = new Map();
54 }
55
56 shorten(request) {
57 if (!request) return request;
58 const cacheEntry = this.cache.get(request);
59 if (cacheEntry !== undefined) {
60 return cacheEntry;
61 }
62 let result = normalizeBackSlashDirection(request);
63 if (this.buildinsAsModule && this.buildinsRegExp) {
64 result = result.replace(this.buildinsRegExp, "!(webpack)");
65 }
66 if (this.currentDirectoryRegExp) {
67 result = result.replace(this.currentDirectoryRegExp, "!.");
68 }
69 if (this.parentDirectoryRegExp) {
70 result = result.replace(this.parentDirectoryRegExp, "!..");
71 }
72 if (!this.buildinsAsModule && this.buildinsRegExp) {
73 result = result.replace(this.buildinsRegExp, "!(webpack)");
74 }
75 result = result.replace(INDEX_JS_REGEXP, "$1");
76 result = result.replace(FRONT_OR_BACK_BANG_REGEXP, "");
77 result = result.replace(MATCH_RESOURCE_REGEXP, " = ");
78 this.cache.set(request, result);
79 return result;
80 }
81}
82
83module.exports = RequestShortener;