diff --git a/package.json b/package.json index 2fbbc3afc4..2692de7cb6 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "trailingComma": "all" }, "dependencies": { + "@swc/core": "^1.2.224", "@types/hast": "^2.3.4", "@umijs/core": "^4.0.9", "estree-util-to-js": "^1.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c17dcbfda7..1db9c46224 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,7 @@ specifiers: '@commitlint/cli': ^17.0.3 '@commitlint/config-conventional': ^17.0.3 '@jest/types': ^27.0.0 + '@swc/core': ^1.2.224 '@types/hast': ^2.3.4 '@types/jest': ^27.0.0 '@types/node': ^18.6.3 @@ -30,6 +31,7 @@ specifiers: v8-compile-cache: 2.3.0 dependencies: + '@swc/core': 1.2.224 '@types/hast': 2.3.4 '@umijs/core': 4.0.9 estree-util-to-js: 1.1.0 @@ -42,7 +44,7 @@ dependencies: v8-compile-cache: 2.3.0 devDependencies: - '@commitlint/cli': 17.0.3 + '@commitlint/cli': 17.0.3_@swc+core@1.2.224 '@commitlint/config-conventional': 17.0.3 '@jest/types': 27.5.1 '@types/jest': 27.5.2 @@ -58,7 +60,7 @@ devDependencies: prettier-plugin-organize-imports: 3.0.0_prettier@2.7.1 prettier-plugin-packagejson: 2.2.18_prettier@2.7.1 stylelint: 14.9.1 - ts-node: 10.9.1_@types+node@18.6.3 + ts-node: 10.9.1_blivvyhjodith2di6bceuxvw54 packages: @@ -468,14 +470,14 @@ packages: exec-sh: 0.3.6 minimist: 1.2.6 - /@commitlint/cli/17.0.3: + /@commitlint/cli/17.0.3_@swc+core@1.2.224: resolution: {integrity: sha512-oAo2vi5d8QZnAbtU5+0cR2j+A7PO8zuccux65R/EycwvsZrDVyW518FFrnJK2UQxbRtHFFIG+NjQ6vOiJV0Q8A==} engines: {node: '>=v14'} hasBin: true dependencies: '@commitlint/format': 17.0.0 '@commitlint/lint': 17.0.3 - '@commitlint/load': 17.0.3 + '@commitlint/load': 17.0.3_@swc+core@1.2.224 '@commitlint/read': 17.0.0 '@commitlint/types': 17.0.0 execa: 5.1.1 @@ -542,7 +544,7 @@ packages: '@commitlint/types': 17.0.0 dev: true - /@commitlint/load/17.0.3: + /@commitlint/load/17.0.3_@swc+core@1.2.224: resolution: {integrity: sha512-3Dhvr7GcKbKa/ey4QJ5MZH3+J7QFlARohUow6hftQyNjzoXXROm+RwpBes4dDFrXG1xDw9QPXA7uzrOShCd4bw==} engines: {node: '>=v14'} dependencies: @@ -553,7 +555,7 @@ packages: '@types/node': 18.6.3 chalk: 4.1.2 cosmiconfig: 7.0.1 - cosmiconfig-typescript-loader: 2.0.2_e2tlcjkk7tlngjdlhzx5hjlnv4 + cosmiconfig-typescript-loader: 2.0.2_mudjenbihprizuiv7k7itu2awu lodash: 4.17.21 resolve-from: 5.0.0 typescript: 4.7.4 @@ -1547,6 +1549,152 @@ packages: deepmerge: 4.2.2 svgo: 2.8.0 + /@swc/core-android-arm-eabi/1.2.224: + resolution: {integrity: sha512-viVOYrhSqNxdDOCNu2UUfiAK0qjkmk/fB9mObdSb+48JlHv4kYBnSLjaIhj0NlXCsxgetH7QFbjrKXRJ+gpHqw==} + engines: {node: '>=10'} + cpu: [arm] + os: [android] + requiresBuild: true + dependencies: + '@swc/wasm': 1.2.122 + optional: true + + /@swc/core-android-arm64/1.2.224: + resolution: {integrity: sha512-HCfdnVyslhMX25BDOqE7rOcl3a6QHs34O3xLLY2J/wg2ICtbxehpbpBPrp+VBG3Ngv7VGD9OPhmFgGxElFtZLQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [android] + requiresBuild: true + dependencies: + '@swc/wasm': 1.2.130 + optional: true + + /@swc/core-darwin-arm64/1.2.224: + resolution: {integrity: sha512-jzv8Eop0GDe4owRDWr02n/xT7Bm6eTFWoM3nFXOM865gNYfASGGm3HHm4z20yndIxq5xuKHcOOH9QXQQhe/lQA==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + optional: true + + /@swc/core-darwin-x64/1.2.224: + resolution: {integrity: sha512-hpdJt/BJ45+hcgs461nJxgMJVNN/2uJL8TLvFxeOJiDpF4r1elRxYfDC1W8ctMWB3eB3Wepz3Ku2z8l9UgPnyQ==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + requiresBuild: true + optional: true + + /@swc/core-freebsd-x64/1.2.224: + resolution: {integrity: sha512-bVIXwwjYA1ZdMKTwrAosxG808nQqvHhzs/fOKUrl1VeZ9CTHA0FzpSXwaBf1shbUVKvQVPKydY0K5q9dkSUkpw==} + engines: {node: '>=10'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dependencies: + '@swc/wasm': 1.2.130 + optional: true + + /@swc/core-linux-arm-gnueabihf/1.2.224: + resolution: {integrity: sha512-MY3UQI3IOjME5TpuIhwI0lqKHsU3x7BwlU4n/mLNe2lH3DLaP0rrGHCMI2iJqfiYKU1Rg1r01HXmysuiriF1TA==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + requiresBuild: true + dependencies: + '@swc/wasm': 1.2.130 + optional: true + + /@swc/core-linux-arm64-gnu/1.2.224: + resolution: {integrity: sha512-tEpaGq4wp79tR+4s0h8xbzcxW6tZOfb2/Jf1vrmRYfRBqryBRTdtn14Rfy4qlK3s/SC3NfI2MKxZRgcGnMCeWw==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + optional: true + + /@swc/core-linux-arm64-musl/1.2.224: + resolution: {integrity: sha512-jnrYqXc7aRzBnEqEp3nAi9tjuUhBnN0pSKiHJytlBP1QkXnH7HD44Da9udmKUFYB5hHpwaXE0NIh7jK0nSMnhw==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + optional: true + + /@swc/core-linux-x64-gnu/1.2.224: + resolution: {integrity: sha512-UBkeDlG+PrIXDH1sR4EIXN5qK4a677IHb6RBghbvBDJS61X9/nTDxtCF7/zCqDxJRahhUrT6lDsYpuLCws2hiw==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + requiresBuild: true + optional: true + + /@swc/core-linux-x64-musl/1.2.224: + resolution: {integrity: sha512-CQMGDzxKvkzf6TOdaWnmhb6uk1XEhM/mM3BDfX+hx9j3Hg3bFw9qmPvrkoWI2G8J50MvpoR1iPBYyG2LNeQWeg==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + requiresBuild: true + optional: true + + /@swc/core-win32-arm64-msvc/1.2.224: + resolution: {integrity: sha512-03V4apubsOhLKQNmfWGlgvDCJkhlh0ZOHcGddxb7bD4PeP6U0lnABG3hlz2uicwcIGBPu/p7jtm5/hezeiXE6Q==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dependencies: + '@swc/wasm': 1.2.130 + optional: true + + /@swc/core-win32-ia32-msvc/1.2.224: + resolution: {integrity: sha512-gPOmIdhCwkb5BbDiPs/4t1LIElFLoQwiv45XwK5wADh1qzLD3A8EtpnpXfLsjL/fUMlLIGCgHQ6BQ0x04VrI1Q==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dependencies: + '@swc/wasm': 1.2.130 + optional: true + + /@swc/core-win32-x64-msvc/1.2.224: + resolution: {integrity: sha512-xALNoKi/UAQ2NflIkCBaZ4Nib75a4YwFp2pZ5Yen3vR8hxK2UJYlaNwyfsBwWfMOMsNxQ1Q1aaqoo0L+XON53Q==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + requiresBuild: true + optional: true + + /@swc/core/1.2.224: + resolution: {integrity: sha512-K0B0QKT0eSpPlL4amWJzllYJigQdE7+ha6VQVks6g/oiko1yMYP8lGcCKOKb+KuvW1ltPzlyFqi7h7ryEVG2vQ==} + engines: {node: '>=10'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@swc/core-android-arm-eabi': 1.2.224 + '@swc/core-android-arm64': 1.2.224 + '@swc/core-darwin-arm64': 1.2.224 + '@swc/core-darwin-x64': 1.2.224 + '@swc/core-freebsd-x64': 1.2.224 + '@swc/core-linux-arm-gnueabihf': 1.2.224 + '@swc/core-linux-arm64-gnu': 1.2.224 + '@swc/core-linux-arm64-musl': 1.2.224 + '@swc/core-linux-x64-gnu': 1.2.224 + '@swc/core-linux-x64-musl': 1.2.224 + '@swc/core-win32-arm64-msvc': 1.2.224 + '@swc/core-win32-ia32-msvc': 1.2.224 + '@swc/core-win32-x64-msvc': 1.2.224 + + /@swc/wasm/1.2.122: + resolution: {integrity: sha512-sM1VCWQxmNhFtdxME+8UXNyPNhxNu7zdb6ikWpz0YKAQQFRGT5ThZgJrubEpah335SUToNg8pkdDF7ibVCjxbQ==} + requiresBuild: true + optional: true + + /@swc/wasm/1.2.130: + resolution: {integrity: sha512-rNcJsBxS70+pv8YUWwf5fRlWX6JoY/HJc25HD/F8m6Kv7XhJdqPPMhyX6TKkUBPAG7TWlZYoxa+rHAjPy4Cj3Q==} + requiresBuild: true + optional: true + /@tootallnate/once/1.1.2: resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==} engines: {node: '>= 6'} @@ -3115,7 +3263,7 @@ packages: object-assign: 4.1.1 vary: 1.1.2 - /cosmiconfig-typescript-loader/2.0.2_e2tlcjkk7tlngjdlhzx5hjlnv4: + /cosmiconfig-typescript-loader/2.0.2_mudjenbihprizuiv7k7itu2awu: resolution: {integrity: sha512-KmE+bMjWMXJbkWCeY4FJX/npHuZPNr9XF9q9CIQ/bpFwi1qHfCmSiKarrCcRa0LO4fWjk93pVoeRtJAkTGcYNw==} engines: {node: '>=12', npm: '>=6'} peerDependencies: @@ -3124,7 +3272,7 @@ packages: dependencies: '@types/node': 18.6.3 cosmiconfig: 7.0.1 - ts-node: 10.9.1_e2tlcjkk7tlngjdlhzx5hjlnv4 + ts-node: 10.9.1_mudjenbihprizuiv7k7itu2awu typescript: 4.7.4 transitivePeerDependencies: - '@swc/core' @@ -5570,7 +5718,7 @@ packages: pretty-format: 27.5.1 slash: 3.0.0 strip-json-comments: 3.1.1 - ts-node: 10.9.1_@types+node@18.6.3 + ts-node: 10.9.1_blivvyhjodith2di6bceuxvw54 transitivePeerDependencies: - bufferutil - canvas @@ -9193,7 +9341,7 @@ packages: resolution: {integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==} dev: false - /ts-node/10.9.1_@types+node@18.6.3: + /ts-node/10.9.1_blivvyhjodith2di6bceuxvw54: resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true peerDependencies: @@ -9208,6 +9356,7 @@ packages: optional: true dependencies: '@cspotcode/source-map-support': 0.8.1 + '@swc/core': 1.2.224 '@tsconfig/node10': 1.0.9 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 @@ -9222,7 +9371,7 @@ packages: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 - /ts-node/10.9.1_e2tlcjkk7tlngjdlhzx5hjlnv4: + /ts-node/10.9.1_mudjenbihprizuiv7k7itu2awu: resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true peerDependencies: @@ -9237,6 +9386,7 @@ packages: optional: true dependencies: '@cspotcode/source-map-support': 0.8.1 + '@swc/core': 1.2.224 '@tsconfig/node10': 1.0.9 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 diff --git a/src/features/compile.ts b/src/features/compile.ts index fe57e5d15f..ad2987a22e 100644 --- a/src/features/compile.ts +++ b/src/features/compile.ts @@ -1,7 +1,12 @@ +import ReactTechStack from '@/techStacks/react'; import type { IApi } from '@/types'; export default (api: IApi) => { - api.chainWebpack((memo) => { + // register react tech stack by default + api.registerTechStack(() => new ReactTechStack()); + + // configure loader to compile markdown + api.chainWebpack(async (memo) => { const babelInUmi = memo.module.rule('src').use('babel-loader').entries(); memo.module diff --git a/src/techStacks/react.ts b/src/techStacks/react.ts new file mode 100644 index 0000000000..217edc650e --- /dev/null +++ b/src/techStacks/react.ts @@ -0,0 +1,69 @@ +import type { IDumiTechStack } from '@/types'; +import { + transformSync, + type ExportDefaultDeclaration, + type ExportDefaultExpression, + type ModuleDeclaration, +} from '@swc/core'; +import Visitor from '@swc/core/Visitor'; + +/** + * swc plugin for replace export to return + */ +class ReactDemoVisitor extends Visitor { + visitExportDefaultDeclaration( + n: ExportDefaultDeclaration, + ): ModuleDeclaration { + return { + type: 'ReturnStatement', + span: n.span, + argument: n.decl, + } as any; + } + + visitExportDefaultExpression(n: ExportDefaultExpression): ModuleDeclaration { + return { + type: 'ReturnStatement', + span: n.span, + argument: n.expression, + } as any; + } +} + +export default class ReactTechStack implements IDumiTechStack { + name = 'react'; + + isSupported(...[, lang]: Parameters) { + return ['jsx', 'tsx'].includes(lang); + } + + transformCode(...[raw, opts]: Parameters) { + if (opts.type === 'code-block') { + const isTSX = opts.fileAbsPath.endsWith('.tsx'); + const { code } = transformSync(raw, { + jsc: { + parser: { + syntax: isTSX ? 'typescript' : 'ecmascript', + [isTSX ? 'tsx' : 'jsx']: true, + }, + target: 'es2022', + }, + module: { + // all imports to require + type: 'commonjs', + // no __esModule flag + importInterop: 'none', + // no 'use strict' + strictMode: false, + }, + plugin: (m) => new ReactDemoVisitor().visitProgram(m), + }); + + return `(function () { +${code} +})()`; + } + + return raw; + } +}