diff --git a/packages/fes-preset-built-in/src/plugins/misc/route/index.js b/packages/fes-preset-built-in/src/plugins/misc/route/index.js index 272d662e..9ff40cba 100644 --- a/packages/fes-preset-built-in/src/plugins/misc/route/index.js +++ b/packages/fes-preset-built-in/src/plugins/misc/route/index.js @@ -2,7 +2,7 @@ import { readdirSync, statSync, readFileSync } from 'fs'; import { join, extname, posix, basename } from 'path'; -import { lodash } from '@fesjs/utils'; +import { lodash, parser, generator } from '@fesjs/utils'; import { parse } from '@vue/compiler-sfc'; import { Logger } from '@fesjs/compiler'; import { runtimePath } from '../../../utils/constants'; @@ -21,7 +21,7 @@ const logger = new Logger('fes:router'); const isProcessFile = function (path) { const ext = extname(path); - return statSync(path).isFile() && ['.vue', '.jsx'].includes(ext); + return statSync(path).isFile() && ['.vue', '.jsx', '.tsx'].includes(ext); }; const isProcessDirectory = function (path, item) { @@ -88,16 +88,12 @@ const genRoutes = function (parentRoutes, path, parentRoutePath, config) { // 文件或者目录的绝对路径 const component = join(path, item); if (isProcessFile(component)) { - const { descriptor } = parse(readFileSync(component, 'utf-8')); - const routeMetaBlock = descriptor.customBlocks.find( - b => b.type === 'config' - ); const ext = extname(item); const fileName = basename(item, ext); // 路由的path const routePath = getRoutePath(parentRoutePath, fileName); if (cacheGenRoutes[routePath]) { - logger.warn(`[WARNING]: The file path: ${routePath}(.jsx/.vue) conflict in router,will only use ${routePath}.jsx,please remove one of.`); + logger.warn(`[WARNING]: The file path: ${routePath}(.jsx/.tsx/.vue) conflict in router,will only use ${routePath}.tsx or ${routePath}.jsx,please remove one of.`); return; } cacheGenRoutes[routePath] = true; @@ -105,7 +101,28 @@ const genRoutes = function (parentRoutes, path, parentRoutePath, config) { // 路由名称 const routeName = getRouteName(parentRoutePath, fileName); const componentPath = getComponentPath(parentRoutePath, fileName, config); - const routeMeta = routeMetaBlock?.content ? JSON.parse(routeMetaBlock.content) : {}; + + const content = readFileSync(component, 'utf-8'); + let routeMeta = {}; + if (ext === '.vue') { + const { descriptor } = parse(content); + const routeMetaBlock = descriptor.customBlocks.find( + b => b.type === 'config' + ); + routeMeta = routeMetaBlock?.content ? JSON.parse(routeMetaBlock.content) : {}; + } + if (ext === '.jsx' || ext === '.tsx') { + const ast = parser.parse(content, { + sourceType: 'module', + plugins: ['jsx', 'typescript'] + }); + const defineRouteExpression = ast.program.body.filter(expression => expression.type === 'ExpressionStatement' && expression.expression.type === 'CallExpression' && expression.expression.callee.name === 'defineRoute')[0]; + if (defineRouteExpression) { + const argument = generator(defineRouteExpression.expression.arguments[0]); + routeMeta = JSON.parse(argument.code.replace(/'/g, '"').replace(/(\S+):/g, (global, m1) => `"${m1}":`)); + } + } + const routeConfig = { path: routePath, component: componentPath, @@ -302,7 +319,7 @@ export default function (api) { api.addCoreExports(() => [ { - specifiers: ['getRoutes', 'getRouter', 'getHistory', 'destroyRouter'], + specifiers: ['getRoutes', 'getRouter', 'getHistory', 'destroyRouter', 'defineRoute'], source: absCoreFilePath } ]); diff --git a/packages/fes-preset-built-in/src/plugins/misc/route/template/routes.tpl b/packages/fes-preset-built-in/src/plugins/misc/route/template/routes.tpl index e6a6c6aa..1e3db781 100644 --- a/packages/fes-preset-built-in/src/plugins/misc/route/template/routes.tpl +++ b/packages/fes-preset-built-in/src/plugins/misc/route/template/routes.tpl @@ -60,3 +60,7 @@ export const destroyRouter = ()=>{ router = null; history = null; } + +export const defineRoute = (param)=>{ + return param +} diff --git a/packages/fes-template-h5/src/pages/test.jsx b/packages/fes-template-h5/src/pages/test.jsx deleted file mode 100644 index 84472aed..00000000 --- a/packages/fes-template-h5/src/pages/test.jsx +++ /dev/null @@ -1,7 +0,0 @@ -import { defineComponent } from 'vue'; - -export default defineComponent({ - setup() { - return () =>
hello jsx
; - } -}); diff --git a/packages/fes-template-h5/src/pages/test.tsx b/packages/fes-template-h5/src/pages/test.tsx new file mode 100644 index 00000000..2f95063a --- /dev/null +++ b/packages/fes-template-h5/src/pages/test.tsx @@ -0,0 +1,13 @@ +import { defineRoute } from '@fesjs/fes'; +import { defineComponent } from 'vue'; + +defineRoute({ + title: 'test', + name: 'test' +}); + +export default defineComponent({ + setup() { + return () =>
hello tsx
; + } +}); diff --git a/packages/fes-utils/package.json b/packages/fes-utils/package.json index e1020935..ac5bbe32 100644 --- a/packages/fes-utils/package.json +++ b/packages/fes-utils/package.json @@ -25,6 +25,7 @@ }, "dependencies": { "@babel/parser": "^7.15.0", + "@babel/generator": "^7.15.0", "@babel/traverse": "^7.15.0", "chalk": "^4.1.2", "chokidar": "^3.5.2", diff --git a/packages/fes-utils/src/index.js b/packages/fes-utils/src/index.js index 816691c2..c7967646 100644 --- a/packages/fes-utils/src/index.js +++ b/packages/fes-utils/src/index.js @@ -8,6 +8,7 @@ import glob from 'glob'; import createDebug from 'debug'; import * as parser from '@babel/parser'; import traverse from '@babel/traverse'; +import generator from '@babel/generator'; import rimraf from 'rimraf'; import mkdirp from 'mkdirp'; import pkgUp from 'pkg-up'; @@ -40,7 +41,8 @@ export { traverse, pkgUp, portfinder, - resolve + resolve, + generator }; export {