-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
107 lines (90 loc) · 3.15 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
const espree = require('espree');
const path = require('path');
const defaultOptions = {
addExtension: 'js',
customResolver: null,
ecmaVersion: 6,
aliases: {}
};
const isLocalPath = (filename) =>
filename.startsWith('./') ||
filename.startsWith('../') ||
filename.startsWith('/');
const hasExtension = (filename, extension) => filename.endsWith('.' + extension);
// This is copypasted from karma middleware
const filePathToUrlPath = (filePath, basePath, urlRoot, proxyPath) => {
if (filePath.startsWith(basePath)) {
return proxyPath + urlRoot.substr(1) + 'base' + filePath.substr(basePath.length)
}
return proxyPath + urlRoot.substr(1) + 'absolute' + filePath
};
const createModuleResolverPreprocessor = (karmaConfig, args = {}, config = {}, logger, helper) => {
const log = logger.create('preprocessor:module-resolver');
const options = helper.merge({}, defaultOptions, args, config);
// Process longer aliases first to avoid collision with shorter ones
const sortedAliases = Object.keys(options.aliases).sort().reverse();
// Normalize path to absolute
for (const alias of sortedAliases) {
options.aliases[alias] = path.resolve(karmaConfig.basePath, options.aliases[alias]);
}
const resolvePath = (modulePath) => {
if (options.customResolver) {
return options.customResolver(modulePath);
}
let result = modulePath;
if (options.addExtension && !hasExtension(modulePath, options.addExtension)) {
result += '.' + options.addExtension;
}
if (!isLocalPath(result)) {
for (const alias of sortedAliases) {
if (result.startsWith(alias)) {
const pathUnderAlias = path.relative(alias, result);
const absolutePath = path.resolve(options.aliases[alias], pathUnderAlias);
result = filePathToUrlPath(
absolutePath,
karmaConfig.basePath,
karmaConfig.urlRoot,
karmaConfig.upstreamProxy ? karmaConfig.upstreamProxy.path : '/'
)
}
}
}
return result;
};
return (content, file, done) => {
log.debug('Processing "%s".', file.originalPath);
let ast = null;
try {
ast = espree.parse(content, {
ecmaVersion: options.ecmaVersion,
sourceType: 'module'
});
} catch (e) {
log.error('%s\n at %s', e.message, file.originalPath);
done(e, null);
return;
}
let patchedContent = content;
for (const node of ast.body.reverse()) {
// Imports can only be at top level as per specification
if (node.type === 'ImportDeclaration' && node.source.type === 'Literal') {
const resolved = resolvePath(node.source.value)
.replace(/\\/g, '\\\\'); // Great job, Windows
if (resolved !== node.source.value) {
const replacement = node.source.raw.replace(node.source.value, resolved);
log.debug('Replacing import from "%s" with "%s"', node.source.value, resolved);
patchedContent =
patchedContent.slice(0, node.source.start) +
replacement +
patchedContent.slice(node.source.end);
}
}
}
done(patchedContent);
}
};
createModuleResolverPreprocessor.$inject = ['config', 'args', 'config.moduleResolverPreprocessor', 'logger', 'helper'];
// PUBLISH DI MODULE
module.exports = {
'preprocessor:module-resolver': ['factory', createModuleResolverPreprocessor]
};