UNPKG

@ali-i18n-fe/dada-component

Version:
325 lines (270 loc) 8.74 kB
const { getPackageConfig } = require("./utils"); const { getDefaultPublicPath } = require("./utils/def"); const path = require("path"); const fs = require("fs"); const { log } = require("@ali-i18n-fe/lsc-utils"); const get = require("lodash/get"); const glob = require("glob"); module.exports = { currentPath: process.cwd(), readmePath: path.resolve(process.cwd(), "README.md"), readmeDocs: "", demoDocs: "", previewDocs: [], usageDocs: [], propsDocs: [], load() { this.outputPath = path.resolve(this.currentPath, "dist"); this.routeMap = require(path.resolve(this.outputPath, "routeMap.json")); this.isLibraryComponent = Object.keys(this.routeMap).length > 1; try { this.writeReadmePreview(); } catch (e) { log.error(e); } try { this.writeReadmeDocs(); } catch (e) { log.error(e); } try { this.writeReadmeTypes(); } catch (e) { log.error(e); } try { this.writeDemo(); } catch (e) { log.error(e); } try { this.writeReadmeAll(); } catch (e) { log.error(e); } }, writeReadmeTypes() { if (!fs.existsSync(this.readmePath)) { throw new Error("当前目录不存在README.md"); } let typesDocs; try { const routeValues = Object.values(this.routeMap); typesDocs = require(path.resolve(this.currentPath, "dist/typeFile.json")); typesDocs = routeValues.map(displayName => typesDocs[displayName] || {}); } catch (e) { throw new Error("读取typeFile异常"); } if (!typesDocs) { return; } this.propsDocs = typesDocs.map(typesDoc => { const props = Object.values(typesDoc.props || {}); if (!props.length) { return; } let propsTable = "property | propType | default | description\n"; propsTable += ":------: | :------: | :-----: | -----------\n"; const getType = function(path) { return `${get(this, path, "")}` .replace(/\n/g, "") .replace(/[| ]+?undefined/g, "") .replace(/[|]/g, "/"); }; props.forEach(propData => { propData.getType = getType; const name = propData.getType("name"); const type = propData.getType("type.name"); const defaultValue = propData.getType("defaultValue.value"); const description = propData.getType("description"); propsTable += `${name} | ${type} | ${defaultValue} | ${description} \n`; }); return propsTable; }); if (this.isLibraryComponent) { return; } const readmeContent = fs.readFileSync(this.readmePath, "utf8"); const replaceContent = this.replaceContent( readmeContent, "DOCS_PROPS", this.propsDocs[0] ); fs.writeFileSync(this.readmePath, replaceContent, "utf8"); console.log("README 自动构建成功!", this.readmePath); }, writeReadmeDocs() { if (!fs.existsSync(this.readmePath)) { throw new Error("当前目录不存在README.md"); } const docsContent = this.getDocsContent(); if (!docsContent.length) { throw new Error("未发现匹配Docs内容,请检查格式是否正确"); } this.usageDocs = docsContent.map( (content, index) => `\`\`\`tsx\n${this.getImports( Object.values(this.routeMap)[index] )}${content}\n\`\`\` ` ); if (this.isLibraryComponent) { return; } const readmeContent = fs.readFileSync(this.readmePath, "utf8"); const writeContent = this.usageDocs[0]; const replaceContent = readmeContent.replace( /\[!DOCS_USAGE.+?]/, writeContent ); fs.writeFileSync(this.readmePath, replaceContent, "utf8"); }, writeReadmePreview() { if (!fs.existsSync(this.readmePath)) { throw new Error("当前目录不存在README.md"); } const previewUrl = this.getPreviewUrls(); this.previewDocs = previewUrl.map(url => `![](${url})`); if (this.isLibraryComponent) { return; } const docsContent = this.previewDocs[0]; const readmeContent = fs.readFileSync(this.readmePath, "utf8"); const replaceContent = this.replaceContent( readmeContent, "DOCS_PREVIEW", docsContent ); fs.writeFileSync(this.readmePath, replaceContent, "utf8"); }, replaceContent(content, key, value) { return content.replace(new RegExp(`(.+)?\\[!${key}.+?](.+)?`), () => value); }, getPreviewUrls() { const files = Object.keys(this.routeMap).map(route => route.replace(/docs\/(.+\/?)?index\.js$/, "$1preview.png") ); if (!files.length) { throw new Error("当前目录不存在Preview"); } return files.map(file => `${getDefaultPublicPath()}docs/${file}`); }, getDocsContent() { const docsPaths = Object.keys(this.routeMap).map(route => route.replace(/docs\/(.+\/?)?index\.js$/, "$1docs.tsx") ); return docsPaths.map(docsPath => { const docsContent = fs.readFileSync( path.resolve(this.currentPath, "src", docsPath), "utf8" ); const [, demoContent] = /\/\*\*.+?DOCS_START.+?\*\*\/([\S\s]+?)\/\*\*.+?DOCS_END.+?\*\*\//.exec( docsContent ) || []; if (!demoContent) { return null; } return demoContent.trim(); }); }, getImports(componentName) { const packageInfo = getPackageConfig(); let imports = ""; imports += `import Components from '${packageInfo.name}';\n`; imports += `import React from 'react';\n`; imports += `import ReactDOM from 'react-dom';\n`; imports += `\n`; imports += `import '${packageInfo.name}/dist/index.css';\n`; imports += `\n`; if (this.isLibraryComponent) { imports += `const Component = Components['${componentName}'];\n`; } else { imports += `const Component = Components;\n`; } imports += `\n`; return imports; }, writeDemo() { if (!fs.existsSync(this.readmePath)) { throw new Error("当前目录不存在README.md"); } let demo; if (fs.existsSync(path.resolve(this.outputPath, "stories/index.html"))) { demo = `# Demo\n\n[Click to view demo](${getDefaultPublicPath()}stories/index.html)\n`; } else { demo = `[DOCS_DEMO]: [!DOCS_DEMO-自动生成,请勿修改]\n`; } const readmeContent = fs.readFileSync(this.readmePath, "utf8"); this.replaceContent(readmeContent, "DOCS_PROPS", this.propsDocs[0]); const replaceContent = this.replaceContent( readmeContent, "DOCS_DEMO", demo ); if (replaceContent !== readmeContent) { fs.writeFileSync(this.readmePath, replaceContent, "utf8"); } this.demoDocs = demo; }, writeReadmeAll() { if (!fs.existsSync(this.readmePath)) { throw new Error("当前目录不存在README.md"); } const demo = this.demoDocs; const componentNames = Object.values(this.routeMap); const readmeAllItems = componentNames.map((key, index) => { const preview = `# Preview\n\n${this.previewDocs[index] || ""}\n`; const usage = `# Usage\n\n${this.usageDocs[index] || ""}\n`; const props = `# Props\n\n${this.propsDocs[index] || ""}\n`; return [preview, usage, props]; }); let replaceContent; const readmeContent = fs.readFileSync(this.readmePath, "utf8"); if (!this.isLibraryComponent) { const writeReadmeItems = readmeAllItems[0]; if (demo) { writeReadmeItems.splice(1, 0, demo); } // single component replaceContent = this.replaceContent( readmeContent, "DOCS_ALL", writeReadmeItems.join("\n") ); } else { // lib components const typeFile = require(path.resolve( this.currentPath, "dist/typeFile.json" )); let writeContent = Object.values(this.routeMap) .map(componentKey => { const desc = (typeFile[componentKey] ? typeFile[componentKey].description : "") || ""; return `- **${componentKey}** ${desc}\n`; }) .join(""); writeContent += "\n"; if (demo) { writeContent += demo; writeContent += "\n"; } writeContent += readmeAllItems .map((item, index) => { const componentContent = item.map(con => "##" + con).join("\n"); return `## ${componentNames[index]}\n\n${componentContent}\n`; }) .join(""); replaceContent = this.replaceContent( readmeContent, "DOCS_ALL", writeContent ); } if (readmeContent !== replaceContent) { fs.writeFileSync(this.readmePath, replaceContent, "utf8"); } } };