Skip to content

Instantly share code, notes, and snippets.

@IgnusG
Last active September 6, 2016 19:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save IgnusG/da04250adf9e90162692b4982c596c0c to your computer and use it in GitHub Desktop.
Save IgnusG/da04250adf9e90162692b4982c596c0c to your computer and use it in GitHub Desktop.
Modifies context of imports. Should be called before whatever compiles the imports
const fs = require('fs');
const requirePatterns = [
/(import.*from\W*)(?:(')(.*)(?!\/)'|(")(.*)(?!\/)")(.*)/g,
/(require\W*\()(?:(')(.*)(?!\/)'|(")(.*)(?!\/)")(.*)/g
];
const extension = '.ts';
function decodeOption(key, value) {
switch (key) {
case 'preserve-depth': return value === 'true';
default: return value;
}
}
function parseOptions(query) {
query = query.substring(1).split('&');
const options = {
paths: query[0].split(':').map(function(e) {
return e.replace(/\/$/, '')
})
};
for (var i = 0; i < query.length; i++) {
var obj = query[i].split('=');
options[obj[0]] = decodeOption(obj[0], obj[1]);
}
return options;
}
function isScopePresent(scope, path) {
return !!~path.indexOf(scope);
}
function escapeToRoot(path) {
return '../'.repeat(path.split('/').length);
}
function splitPathOnPattern(path, pathPattern) {
return new RegExp('(.*)(' + pathPattern + ')((?:(?!'+ pathPattern +').)*)').exec(path);
}
function isImportValid(path) {
try {
fs.statSync(path);
return true;
} catch (e) {
return false;
}
}
function generateRequirePattern() {
return new RegExp(requirePatterns.map(r => r.source).join('|'), 'g');
}
module.exports = function(content) {
this.cacheable();
const options = parseOptions(this.query);
const paths = options.paths;
const preserveDepth = options['preserve-depth'];
var context = this.context;
if (isScopePresent(paths[0], context)) {
var pathRequirePattern = generateRequirePattern();
var contextPathParts = splitPathOnPattern(context, paths[0]);
var relativeResourcePath = contextPathParts[2] + contextPathParts[3];
var newResourcePathPrefix = escapeToRoot(relativeResourcePath) + paths[1];
var absoluteResourceDirPath = contextPathParts[1] + paths[1];
var resourcePath = (preserveDepth ? contextPathParts[3] : '') + '/';
newResourcePathPrefix += resourcePath;
absoluteResourceDirPath += resourcePath;
var imports;
while ((imports = pathRequirePattern.exec(content)) != null) {
var quotes = imports[2] || imports[4];
var importResource = imports[3] || imports[5];
var absoluteImportPath = absoluteResourceDirPath + importResource + extension;
if (isImportValid(absoluteImportPath)) {
var newImportPath = imports[1] + quotes + newResourcePathPrefix + importResource + quotes + imports[6];
content = content.slice(0, imports.index) + newImportPath + content.slice(imports.index + imports[0].length);
}
}
}
return content;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment