UNPKG

react-imported-component

Version:
146 lines (145 loc) 9.55 kB
"use strict"; /* 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;