webpack-react-docgen-typescript
Version:
A webpack loader with cache react-docgen-typescript
104 lines (103 loc) • 5.29 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_extra_1 = __importDefault(require("fs-extra"));
const os_1 = __importDefault(require("os"));
const path_1 = __importDefault(require("path"));
const find_cache_dir_1 = __importDefault(require("find-cache-dir"));
const loader_utils_1 = require("loader-utils");
const react_docgen_typescript_1 = require("react-docgen-typescript");
const crypto_1 = require("crypto");
const defaults_1 = require("./defaults");
module.exports.default = function (source) {
return __awaiter(this, void 0, void 0, function* () {
const options = loader_utils_1.getOptions(this) || {};
const { forceRegenerate, fileNameResolver, transformProps = tables => tables[0], propFilter, componentNameResolver = defaults_1.computeComponentName, shouldExtractLiteralValuesFromEnum, savePropValueAsString, } = options;
const parserOptions = { propFilter, componentNameResolver, shouldExtractLiteralValuesFromEnum, savePropValueAsString };
const parser = react_docgen_typescript_1.withDefaultConfig(parserOptions);
const cacheFolder = find_cache_dir_1.default({ name: 'webpack-react-docgen-typescript' }) || os_1.default.tmpdir();
//create cache folder if it doesnt exist
if (!fs_extra_1.default.existsSync(cacheFolder)) {
fs_extra_1.default.mkdirSync(cacheFolder, { recursive: true });
}
const cachedFileName = fileNameResolver ? fileNameResolver(Object.assign(Object.assign({}, this), { cacheFolder })) :
path_1.default.join(cacheFolder, crypto_1.createHash('md5').update(this.resourcePath).digest('hex'));
if (!cachedFileName) {
return source;
}
const parseTypes = () => __awaiter(this, void 0, void 0, function* () {
let parsed;
try {
parsed = parser.parse(this.resourcePath);
}
catch (e) {
console.warn(`\nTS: issue parsing ${this.resourcePath}`);
}
const result = parsed && Array.isArray(parsed) && parsed.length > 0 ? parsed : {};
fs_extra_1.default.writeFileSync(cachedFileName, JSON.stringify(result));
return result;
});
let docgenInfo = null;
if (forceRegenerate) {
//force remove the cached file
if (fs_extra_1.default.existsSync(cachedFileName)) {
fs_extra_1.default.unlink(cachedFileName);
}
}
//check if the options have changed
const optionsHash = crypto_1.createHash('md5').update(JSON.stringify(parserOptions)).digest('hex').substr(0, 6);
const optionsFileName = path_1.default.join(cacheFolder, '--options--.cache');
if (fs_extra_1.default.existsSync(optionsFileName)) {
const lastOptions = fs_extra_1.default.readFileSync(optionsFileName, 'utf8');
if (lastOptions !== optionsHash) {
//empty the cache folder files
fs_extra_1.default.emptyDirSync(cacheFolder);
//last options are different from current options
fs_extra_1.default.writeFileSync(optionsFileName, optionsHash);
}
}
else {
fs_extra_1.default.writeFileSync(optionsFileName, optionsHash);
}
if (fs_extra_1.default.existsSync(cachedFileName)) {
const cacheStats = fs_extra_1.default.statSync(cachedFileName);
const fileStats = fs_extra_1.default.statSync(this.resourcePath);
if (cacheStats.mtime.getTime() >= fileStats.mtime.getTime()) {
const fileData = fs_extra_1.default.readFileSync(cachedFileName);
docgenInfo = JSON.parse(fileData);
}
else {
docgenInfo = yield parseTypes();
}
}
else {
//does not exist in cache, re-generate
docgenInfo = yield parseTypes();
}
if (Array.isArray(docgenInfo) && docgenInfo.length > 0) {
docgenInfo = transformProps(docgenInfo);
if (docgenInfo) {
const doc = Array.isArray(docgenInfo) && docgenInfo.length > 0 ? docgenInfo[0] : docgenInfo;
return source + `
try {
//@ts-ignore
${doc.displayName}.__docgenInfo = ${JSON.stringify(doc)};
} catch (e) {
}
`;
}
}
return source;
});
};