diff --git a/devui-cli/shared/utils.js b/devui-cli/shared/utils.js index 16acce59e28bb548e26ca60c07e382ff8783ab30..11fb60c7065a929734587fda721d59df57f0960a 100644 --- a/devui-cli/shared/utils.js +++ b/devui-cli/shared/utils.js @@ -3,6 +3,8 @@ const { INDEX_FILE_NAME, DEVUI_DIR } = require('./constant') const { resolve } = require('path') const logger = require('./logger') const fs = require('fs-extra') +const traverse = require("@babel/traverse").default +const babelParser = require("@babel/parser") exports.bigCamelCase = (str) => { return upperFirst(camelCase(str)) @@ -29,10 +31,38 @@ exports.parseExportByFileInfo = (fileInfo, ignoreParseError) => { const exportModule = {} const indexContent = fs.readFileSync(fileInfo.path, { encoding: 'utf-8' }) - const defaultRe = /export default/ - const partRe = /export {/ + const ast = babelParser.parse(indexContent, { + sourceType: 'module', + plugins: [ + 'typescript' + ] + }) + + const exportName = [] + let exportDefault = null + + traverse(ast, { + ExportNamedDeclaration({node}) { + if (node.specifiers.length) { + node.specifiers.forEach(specifier => { + exportName.push(specifier.local.name) + }) + } else if (node.declaration) { + if (node.declaration.declarations) { + node.declaration.declarations.forEach(dec => { + exportName.push(dec.id.name) + }) + } else if (node.declaration.id) { + exportName.push(node.declaration.id.name) + } + } + }, + ExportDefaultDeclaration() { + exportDefault = fileInfo.name + 'Install' + } + }) - if (!defaultRe.test(indexContent)) { + if (!exportDefault) { logger.error(`${fileInfo.path} must have "export default".`) if (ignoreParseError) { @@ -42,9 +72,9 @@ exports.parseExportByFileInfo = (fileInfo, ignoreParseError) => { } } - if (!partRe.test(indexContent)) { - logger.error(`${fileInfo.path} must have "export {}".`) - + if (!exportName.length) { + logger.error(`${fileInfo.path} must have "export xxx".`) + if (ignoreParseError) { return exportModule } else { @@ -52,69 +82,43 @@ exports.parseExportByFileInfo = (fileInfo, ignoreParseError) => { } } - const parts = [] - let searchContent = indexContent - - while (searchContent.search(partRe) !== -1) { - const reStartIndex = indexContent.search(partRe) - const partContent = this.extractStr(indexContent, '{', '}', reStartIndex) - - partContent - .replace(/(\s|\r|\n|\t)/g, '') - .split(',') - .forEach((p) => parts.push(p)) - - searchContent = indexContent.slice(reStartIndex + partContent.length) - } - - exportModule.default = fileInfo.name + 'Install' - exportModule.parts = parts + exportModule.default = exportDefault + exportModule.parts = exportName exportModule.fileInfo = fileInfo return exportModule } exports.parseComponentInfo = (name) => { - const componentInfo = {} + const componentInfo = { + name: this.bigCamelCase(name) + } + let hasExportDefault = false const indexContent = fs.readFileSync(resolve(DEVUI_DIR, name, INDEX_FILE_NAME), { encoding: 'utf-8' }) - const defaultRe = /export default/ - - if (!defaultRe.test(indexContent)) { - logger.warning(`${this.bigCamelCase(name)} must have "export default" and component info.`) - } else { - const reStartIndex = indexContent.indexOf('export default {') - const extraRe = /((^['"])|(['"]$))/g + const ast = babelParser.parse(indexContent, { + sourceType: 'module', + plugins: [ + 'typescript' + ] + }) + traverse(ast, { + ExportDefaultDeclaration({node}) { + hasExportDefault = true + if (node.declaration && node.declaration.properties) { + const properties = node.declaration.properties + properties.forEach(pro => { + if (pro.type === 'ObjectProperty') { + componentInfo[pro.key.name] = pro.value.value + } + }) + } + } + }) - componentInfo.title = this.extractStr(indexContent, 'title:', ',', reStartIndex).trim().replace(extraRe, '') - componentInfo.category = this.extractStr(indexContent, 'category:', ',', reStartIndex).trim().replace(extraRe, '') - componentInfo.status = this.transformNullishStr( - this.extractStr(indexContent, 'status:', ',', reStartIndex).trim().replace(extraRe, '') - ) + if (!hasExportDefault) { + logger.warning(`${componentInfo.name} must have "export default" and component info.`) } - componentInfo.name = this.bigCamelCase(name) - return componentInfo } - -exports.transformNullishStr = (str) => { - console.log(str) - switch (str) { - case 'null': - return null - case 'undefined': - return undefined - default: - return str - } -} - -exports.extractStr = (content = '', startKeywords = '', endKeywords = '', startIndex = 0) => { - const keywordsStartIndex = content.indexOf(startKeywords, startIndex) + startKeywords.length - const keywordsEndIndex = content.indexOf(endKeywords, keywordsStartIndex) - - if ([keywordsStartIndex - startIndex, keywordsEndIndex].some((index) => index < 0)) return '' - - return content.slice(keywordsStartIndex, keywordsEndIndex) -} diff --git a/package.json b/package.json index fe1f86db4c8886e3d1fbb68878cd48170bdb7c21..10e28d82bd681eff325c7f93192fb1da761b7c99 100644 --- a/package.json +++ b/package.json @@ -47,8 +47,10 @@ "vue-router": "^4.0.3" }, "devDependencies": { + "@babel/parser": "^7.15.5", "@babel/preset-env": "^7.14.5", "@babel/preset-typescript": "^7.14.5", + "@babel/traverse": "^7.15.4", "@commitlint/cli": "^11.0.0", "@commitlint/config-conventional": "^11.0.0", "@ls-lint/ls-lint": "^1.10.0", diff --git a/yarn.lock b/yarn.lock index 241d93cf78647a649265659382bc8fee534aec4f..a1204615da29dd52c0a2eb0750d1fb11732d9415 100644 --- a/yarn.lock +++ b/yarn.lock @@ -160,6 +160,15 @@ jsesc "^2.5.1" source-map "^0.5.0" +"@babel/generator@^7.15.4": + version "7.15.4" + resolved "http://nexus3.ey.com.cn/repository/npm-group/@babel/generator/-/generator-7.15.4.tgz#85acb159a267ca6324f9793986991ee2022a05b0" + integrity sha1-hayxWaJnymMk+Xk5hpke4gIqBbA= + dependencies: + "@babel/types" "^7.15.4" + jsesc "^2.5.1" + source-map "^0.5.0" + "@babel/helper-annotate-as-pure@^7.14.5": version "7.14.5" resolved "https://registry.nlark.com/@babel/helper-annotate-as-pure/download/@babel/helper-annotate-as-pure-7.14.5.tgz#7bf478ec3b71726d56a8ca5775b046fc29879e61" @@ -235,6 +244,15 @@ "@babel/template" "^7.14.5" "@babel/types" "^7.14.5" +"@babel/helper-function-name@^7.15.4": + version "7.15.4" + resolved "http://nexus3.ey.com.cn/repository/npm-group/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz#845744dafc4381a4a5fb6afa6c3d36f98a787ebc" + integrity sha1-hFdE2vxDgaSl+2r6bD02+Yp4frw= + dependencies: + "@babel/helper-get-function-arity" "^7.15.4" + "@babel/template" "^7.15.4" + "@babel/types" "^7.15.4" + "@babel/helper-get-function-arity@^7.14.5": version "7.14.5" resolved "https://registry.nlark.com/@babel/helper-get-function-arity/download/@babel/helper-get-function-arity-7.14.5.tgz#25fbfa579b0937eee1f3b805ece4ce398c431815" @@ -242,6 +260,13 @@ dependencies: "@babel/types" "^7.14.5" +"@babel/helper-get-function-arity@^7.15.4": + version "7.15.4" + resolved "http://nexus3.ey.com.cn/repository/npm-group/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz#098818934a137fce78b536a3e015864be1e2879b" + integrity sha1-CYgYk0oTf854tTaj4BWGS+Hih5s= + dependencies: + "@babel/types" "^7.15.4" + "@babel/helper-hoist-variables@^7.14.5": version "7.14.5" resolved "https://registry.nlark.com/@babel/helper-hoist-variables/download/@babel/helper-hoist-variables-7.14.5.tgz#e0dd27c33a78e577d7c8884916a3e7ef1f7c7f8d" @@ -249,6 +274,13 @@ dependencies: "@babel/types" "^7.14.5" +"@babel/helper-hoist-variables@^7.15.4": + version "7.15.4" + resolved "http://nexus3.ey.com.cn/repository/npm-group/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz#09993a3259c0e918f99d104261dfdfc033f178df" + integrity sha1-CZk6MlnA6Rj5nRBCYd/fwDPxeN8= + dependencies: + "@babel/types" "^7.15.4" + "@babel/helper-member-expression-to-functions@^7.15.0": version "7.15.0" resolved "https://registry.nlark.com/@babel/helper-member-expression-to-functions/download/@babel/helper-member-expression-to-functions-7.15.0.tgz#0ddaf5299c8179f27f37327936553e9bba60990b" @@ -329,6 +361,13 @@ dependencies: "@babel/types" "^7.14.5" +"@babel/helper-split-export-declaration@^7.15.4": + version "7.15.4" + resolved "http://nexus3.ey.com.cn/repository/npm-group/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz#aecab92dcdbef6a10aa3b62ab204b085f776e257" + integrity sha1-rsq5Lc2+9qEKo7YqsgSwhfd24lc= + dependencies: + "@babel/types" "^7.15.4" + "@babel/helper-validator-identifier@^7.10.4", "@babel/helper-validator-identifier@^7.14.5", "@babel/helper-validator-identifier@^7.14.9": version "7.14.9" resolved "https://registry.nlark.com/@babel/helper-validator-identifier/download/@babel/helper-validator-identifier-7.14.9.tgz#6654d171b2024f6d8ee151bf2509699919131d48" @@ -377,6 +416,11 @@ resolved "https://registry.nlark.com/@babel/parser/download/@babel/parser-7.15.0.tgz#b6d6e29058ca369127b0eeca2a1c4b5794f1b6b9" integrity sha1-ttbikFjKNpEnsO7KKhxLV5Txtrk= +"@babel/parser@^7.15.4", "@babel/parser@^7.15.5": + version "7.15.5" + resolved "http://nexus3.ey.com.cn/repository/npm-group/@babel/parser/-/parser-7.15.5.tgz#d33a58ca69facc05b26adfe4abebfed56c1c2dac" + integrity sha1-0zpYymn6zAWyat/kq+v+1WwcLaw= + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.14.5": version "7.14.5" resolved "https://registry.nlark.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/download/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.14.5.tgz#4b467302e1548ed3b1be43beae2cc9cf45e0bb7e" @@ -1012,6 +1056,15 @@ "@babel/parser" "^7.14.5" "@babel/types" "^7.14.5" +"@babel/template@^7.15.4": + version "7.15.4" + resolved "http://nexus3.ey.com.cn/repository/npm-group/@babel/template/-/template-7.15.4.tgz#51898d35dcf3faa670c4ee6afcfd517ee139f194" + integrity sha1-UYmNNdzz+qZwxO5q/P1RfuE58ZQ= + dependencies: + "@babel/code-frame" "^7.14.5" + "@babel/parser" "^7.15.4" + "@babel/types" "^7.15.4" + "@babel/traverse@7.12.1": version "7.12.1" resolved "https://registry.nlark.com/@babel/traverse/download/@babel/traverse-7.12.1.tgz#941395e0c5cc86d5d3e75caa095d3924526f0c1e" @@ -1042,6 +1095,21 @@ debug "^4.1.0" globals "^11.1.0" +"@babel/traverse@^7.15.4": + version "7.15.4" + resolved "http://nexus3.ey.com.cn/repository/npm-group/@babel/traverse/-/traverse-7.15.4.tgz#ff8510367a144bfbff552d9e18e28f3e2889c22d" + integrity sha1-/4UQNnoUS/v/VS2eGOKPPiiJwi0= + dependencies: + "@babel/code-frame" "^7.14.5" + "@babel/generator" "^7.15.4" + "@babel/helper-function-name" "^7.15.4" + "@babel/helper-hoist-variables" "^7.15.4" + "@babel/helper-split-export-declaration" "^7.15.4" + "@babel/parser" "^7.15.4" + "@babel/types" "^7.15.4" + debug "^4.1.0" + globals "^11.1.0" + "@babel/types@7.12.1": version "7.12.1" resolved "https://registry.nlark.com/@babel/types/download/@babel/types-7.12.1.tgz#e109d9ab99a8de735be287ee3d6a9947a190c4ae" @@ -1059,6 +1127,14 @@ "@babel/helper-validator-identifier" "^7.14.9" to-fast-properties "^2.0.0" +"@babel/types@^7.15.4": + version "7.15.4" + resolved "http://nexus3.ey.com.cn/repository/npm-group/@babel/types/-/types-7.15.4.tgz#74eeb86dbd6748d2741396557b9860e57fce0a0d" + integrity sha1-dO64bb1nSNJ0E5ZVe5hg5X/OCg0= + dependencies: + "@babel/helper-validator-identifier" "^7.14.9" + to-fast-properties "^2.0.0" + "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.npm.taobao.org/@bcoe/v8-coverage/download/@bcoe/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -2551,6 +2627,11 @@ babel-walk@3.0.0-canary-5: dependencies: "@babel/types" "^7.9.6" +babylon@^6.18.0: + version "6.18.0" + resolved "http://nexus3.ey.com.cn/repository/npm-group/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + integrity sha1-ry87iPpvXB5MY00aD46sT1WzleM= + bail@^1.0.0: version "1.0.5" resolved "https://registry.nlark.com/bail/download/bail-1.0.5.tgz?cache=0&sync_timestamp=1621401842495&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fbail%2Fdownload%2Fbail-1.0.5.tgz#b6fa133404a392cbc1f8c4bf63f5953351e7a776"