react-imported-component
Version:
I will import your component, and help to handle it
146 lines (145 loc) • 9.55 kB
JavaScript
/* tslint:disable no-console */
Object.defineProperty(exports, "__esModule", { value: true });
exports.scanTop = exports.remapImports = exports.cleanFileContent = exports.getDynamicImports = void 0;
var tslib_1 = require("tslib");
var fs_1 = require("fs");
var path_1 = require("path");
// @ts-ignore
var scan_directory_1 = (0, tslib_1.__importDefault)(require("scan-directory"));
var constants_1 = require("../configuration/constants");
var shared_1 = require("./shared");
var RESOLVE_EXTENSIONS = ['.js', '.jsx', '.ts', '.tsx', '.mjs'];
var trimImport = function (str) { return str.replace(/['"]/g, ''); };
var getImportMatch = (0, shared_1.getMatchString)("(['\"]?[\\w-/.@]+['\"]?)\\)", 1);
var getImports = function (str) {
return getImportMatch(str
// remove comments
.replace(/\/\*([^\*]*)\*\//gi, '')
.replace(/\/\/(.*)/gi, '')
// remove new lines
.replace(/\n/gi, '')
// remove spaces?
.replace(/[\s]+\)/i, ')'));
};
var getComment = (0, shared_1.getMatchString)(/\/\*.*\*\//, 0);
var getChunkName = (0, shared_1.getMatchString)('webpackChunkName: "([^"]*)"', 1);
var clientSideOnly = function (comment) { return comment.indexOf(constants_1.CLIENT_SIDE_ONLY) >= 0; };
var clearComment = function (str) { return str.replace('webpackPrefetch: true', '').replace('webpackPreload: true', ''); };
var getImportString = function (pattern, selected) {
return function (str) {
return (0, shared_1.getMatchString)(pattern, selected)(str).map(function (statement) {
return {
name: trimImport(getImports(statement + ')')[0] || ''),
comment: clearComment(getComment(statement)[0] || ''),
};
});
};
};
exports.getDynamicImports = getImportString("import[\\s]?\\((([^)])+['\"]?)\\)", 1);
var cleanFileContent = function (content) {
var mapping = [];
// wrap
var wrapped = content.replace(new RegExp("import[\\s]?\\((([^)])+['\"]?)\\)", 'g'), function (match) {
var placement = mapping.push(match) - 1;
return "imported_" + placement + "_replacement";
});
var cleaned = wrapped.replace(new RegExp('//.*', 'g'), '').replace(new RegExp('\\/\\*[\\s\\S]*?\\*\\/', 'gm'), '');
var unwrapped = cleaned.replace(new RegExp('imported_([\\d]*)_replacement', 'g'), function (_, b) {
return mapping[+b];
});
return unwrapped;
};
exports.cleanFileContent = cleanFileContent;
var mapImports = function (file, imports) {
return imports.map(function (dep) {
var name = dep.name;
if (name && name.charAt(0) === '.') {
return (0, tslib_1.__assign)((0, tslib_1.__assign)({}, dep), { file: file, name: (0, path_1.resolve)((0, path_1.dirname)(file), name), doNotTransform: false });
}
return (0, tslib_1.__assign)((0, tslib_1.__assign)({}, dep), { file: file, doNotTransform: true });
});
};
var rejectSystemFiles = function (test) { return function (file, stats) {
if (stats.isDirectory()) {
return !test(file);
}
return false;
}; };
var rejectNodeModulesAndDotFolders = function (file) { return !(file.match(/node_modules/) || file.match(/(\/\.\w+)/)); };
var remapImports = function (data, root, targetDir, getRelativeName, imports, testImport, chunkName) {
return data
.map(function (_a) {
var file = _a.file, content = _a.content;
return mapImports(file, (0, exports.getDynamicImports)((0, exports.cleanFileContent)(content)));
})
.forEach(function (importBlock) {
return importBlock.forEach(function (_a) {
var name = _a.name, comment = _a.comment, doNotTransform = _a.doNotTransform, file = _a.file;
var rootName = doNotTransform ? name : getRelativeName(root, name);
var fileName = doNotTransform ? name : getRelativeName(targetDir, name);
var sourceName = getRelativeName(root, file);
if (testImport(rootName, sourceName)) {
var isClientSideOnly = clientSideOnly(comment);
var givenChunkName = getChunkName(comment)[0] || '';
var def = "[() => import(" + comment + "'" + fileName + "'), '" + ((chunkName && chunkName(rootName, sourceName, { chunkName: givenChunkName })) || givenChunkName) + "', '" + rootName + "', " + isClientSideOnly + "] /* from " + sourceName + " */";
var slot = getRelativeName(root, name);
// keep the maximal definition
imports[slot] = !imports[slot] ? def : imports[slot].length > def.length ? imports[slot] : def;
}
});
});
};
exports.remapImports = remapImports;
function scanTop(root, start, target) {
function scan() {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function () {
var sourceDir, configurationFile, _a, _b, testFolder, _c, testFile, _d, testImport, chunkName, configuration, files, data, imports, targetDir;
var _this = this;
return (0, tslib_1.__generator)(this, function (_e) {
switch (_e.label) {
case 0:
sourceDir = (0, path_1.resolve)(root, start);
console.log('scanning', sourceDir, 'for imports...');
configurationFile = (0, path_1.resolve)(root, '.imported.js');
_a = (0, fs_1.existsSync)(configurationFile) ? require(configurationFile) : {}, _b = _a.testFolder, testFolder = _b === void 0 ? rejectNodeModulesAndDotFolders : _b, _c = _a.testFile, testFile = _c === void 0 ? function () { return true; } : _c, _d = _a.testImport, testImport = _d === void 0 ? function () { return true; } : _d, chunkName = _a.chunkName, configuration = _a.configuration;
return [4 /*yield*/, (0, scan_directory_1.default)(sourceDir, undefined, rejectSystemFiles(testFolder))];
case 1:
files = (_e.sent())
.filter(function (name) { return (0, shared_1.normalizePath)(name).indexOf(target) === -1; })
.filter(function (name) { return RESOLVE_EXTENSIONS.indexOf((0, path_1.extname)(name)) >= 0; })
.filter(function (name) { return testFile(name); })
.sort();
return [4 /*yield*/, Promise.all(files.map(function (file) { return (0, tslib_1.__awaiter)(_this, void 0, void 0, function () {
var content;
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, (0, shared_1.getFileContent)(file)];
case 1:
content = _a.sent();
return [2 /*return*/, {
file: file,
content: content,
}];
}
});
}); }))];
case 2:
data = _e.sent();
imports = {};
targetDir = (0, path_1.resolve)(root, (0, path_1.dirname)(target));
(0, exports.remapImports)(data, root, targetDir, shared_1.getRelative, imports, testImport, chunkName);
console.log(Object.keys(imports).length + " imports found, saving to " + target);
(0, shared_1.pWriteFile)(target, "\n /* eslint-disable */\n /* tslint:disable */\n \n // generated by react-imported-component, DO NOT EDIT \n import {assignImportedComponents} from 'react-imported-component/macro';\n " + (configuration &&
"import {setConfiguration} from 'react-imported-component/boot';\n// as configured in .imported.js\nsetConfiguration(" + JSON.stringify(configuration, null, 2) + ");\n ") + " \n \n // all your imports are defined here\n // all, even the ones you tried to hide in comments (that's the cost of making a very fast parser)\n // to remove any import from here\n // 1) use magic comment `import(/* client-side */ './myFile')` - and it will disappear\n // 2) use file filter to ignore specific locations (refer to the README - https://github.com/theKashey/react-imported-component/#server-side-auto-import)\n // 3) use .imported.js to control this table generation (refer to the README - https://github.com/theKashey/react-imported-component/#-imported-js)\n \n const applicationImports = assignImportedComponents([\n" + Object.keys(imports)
.map(function (key) { return " " + imports[key] + ","; })
.sort()
.join('\n') + "\n ]);\n \n export default applicationImports;\n \n // @ts-ignore\n if (module.hot) {\n // these imports would make this module a parent for the imported modules.\n // but this is just a helper - so ignore(and accept!) all updates\n \n // @ts-ignore\n module.hot.accept(() => null);\n } \n ");
return [2 /*return*/];
}
});
});
}
return scan();
}
exports.scanTop = scanTop;
;