-
Notifications
You must be signed in to change notification settings - Fork 4
/
index.js
122 lines (103 loc) · 3.48 KB
/
index.js
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
'use strict';
var path = require('path');
var ModuleFilenameHelpers = require('webpack/lib/ModuleFilenameHelpers');
var PACKAGE_NAME = require('./package.json').name;
function OmitTildeWebpackPlugin(options) {
this.options = (typeof options === 'object') ? options : {};
}
module.exports = OmitTildeWebpackPlugin;
OmitTildeWebpackPlugin.prototype.apply = function apply(compiler) {
var options = this.options,
warnings = [],
recursionMap = {};
// hook the compiler so we can push warnings in the warn() method
compiler.plugin('after-compile', afterCompile);
// add additional directory resolver
compiler.resolvers.normal.plugin('directory', directoryResolver);
function warn() {
var text = [PACKAGE_NAME]
.concat(Array.prototype.slice.call(arguments))
.join(' ');
if (warnings.indexOf(text) < 0) {
warnings.push(text);
}
}
function afterCompile(compilation, done) {
recursionMap = {};
compilation.warnings.push.apply(compilation.warnings, warnings);
done();
}
function directoryResolver(candidate, done) {
/* jshint validthis:true */
var doResolve = this.doResolve.bind(this);
// void recursing, request must lead with single ./ to be relevant
var requestFile = candidate.request.split('!').pop(),
normalisedFile = path.normalize(requestFile),
isRelevant = /^\.[\\\/]/.test(requestFile) && /^[^\.~\\\/]/.test(normalisedFile),
recursionKey = [candidate.path, normalisedFile].join('|'),
isRecursing = recursionMap[recursionKey];
// abort early
if (!isRelevant || isRecursing) {
done();
}
// proceed unless filtered
else {
var isIncluded = [
ModuleFilenameHelpers.matchObject(options.path || {}, candidate.path),
ModuleFilenameHelpers.matchObject(options.request || {}, candidate.request)
];
// verbose messaging
if (options.verbose) {
var text = [
PACKAGE_NAME + ':',
(isIncluded[0] ? '\u2713' : '\u2715') + ' path "' + candidate.path + '"',
(isIncluded[1] ? '\u2713' : '\u2715') + ' request "' + candidate.request + '"'
].join('\n ');
console.log(text);
}
// repeat the request, but this time we control the callbacks
if (isIncluded.every(Boolean)) {
recursionStart(recursionKey);
doResolve(['directory'], candidate, onDirectoryResolve);
}
// not relevant
else {
done();
}
}
function onDirectoryResolve(error, result) {
recursionEnd(recursionKey);
var amended;
// relaunch the request as a module, removing any relative path prefix
if (!result) {
amended = {
path : candidate.path,
request: normalisedFile,
query : candidate.query,
module : true
};
doResolve(['module'], amended, options.deprecate ? resolved : done);
}
// use the original request
else {
done(error, result);
}
function resolved(error, result) {
if (!error && result) {
warn([
'files should use ~ to refer to modules:',
' in directory: "' + candidate.path + '"',
' change "' + amended.request + '" -> "~' + amended.request + '"'
].join('\n'));
}
done(error, result);
}
}
}
function recursionStart(key) {
recursionMap[key] = true;
}
function recursionEnd(key) {
recursionMap[key] = false;
}
};