提交 2dc6bd7d 编写于 作者: fxy060608's avatar fxy060608

feat(h5): support jsx/tsx

上级 83c79f2c
......@@ -3,11 +3,11 @@ import { Plugin } from 'vite'
import { createFilter, FilterPattern } from '@rollup/pluginutils'
import {
EXTNAME_VUE,
parseVueRequest,
matchEasycom,
addImportDeclaration,
genResolveEasycomCode,
EXTNAME_VUE_TEMPLATE,
} from '@dcloudio/uni-cli-shared'
interface UniEasycomPluginOptions {
......@@ -26,7 +26,7 @@ export function uniEasycomPlugin(options: UniEasycomPluginOptions): Plugin {
const { filename, query } = parseVueRequest(id)
if (
query.type !== 'template' &&
(query.vue || !EXTNAME_VUE.includes(path.extname(filename)))
(query.vue || !EXTNAME_VUE_TEMPLATE.includes(path.extname(filename)))
) {
return
}
......
......@@ -18,6 +18,7 @@
"url": "https://github.com/dcloudio/uni-app/issues"
},
"dependencies": {
"@babel/core": "^7.16.5",
"@babel/parser": "^7.16.4",
"@babel/types": "^7.16.0",
"@dcloudio/uni-i18n": "3.0.0-alpha-3030420211227001",
......
......@@ -2,6 +2,7 @@ export const PUBLIC_DIR = 'static'
export const EXTNAME_JS = ['.js', '.ts', '.jsx', '.tsx']
export const EXTNAME_TS = ['.ts', '.tsx']
export const EXTNAME_VUE = ['.vue', '.nvue']
export const EXTNAME_VUE_TEMPLATE = ['.vue', '.nvue', '.jsx', '.tsx']
export const EXTNAME_VUE_RE = /\.(vue|nvue)$/
export const EXTNAME_JS_RE = /\.[jt]sx?$/
export const EXTNAME_TS_RE = /\.tsx?$/
......
......@@ -70,7 +70,10 @@ export function initEasycoms(
const res = {
options,
filter: createFilter(
['components/*/*.vue', 'uni_modules/*/components/*/*.vue'],
[
'components/*/*.(vue|jsx|tsx)',
'uni_modules/*/components/*/*.(vue|jsx|tsx)',
],
[],
{
resolve: inputDir,
......@@ -110,7 +113,7 @@ function initEasycom({
dirs,
rootDir,
custom,
extensions = ['.vue'],
extensions = ['.vue', '.jsx', '.tsx'],
}: EasycomOption) {
clearEasycom()
const easycomsObj = Object.create(null)
......
......@@ -24,6 +24,9 @@ interface UniVitePluginUniOptions {
directiveTransforms?: CompilerOptions['directiveTransforms']
nodeTransforms?: CompilerOptions['nodeTransforms']
}
jsxOptions?: {
babelPlugins?: any[]
}
copyOptions?: CopyOptions | (() => CopyOptions)
}
export interface UniVitePlugin extends Plugin {
......
import * as BabelCore from '@babel/core'
import type { PluginObj } from '@babel/core'
import { isBuiltInComponent } from '@dcloudio/uni-shared'
export function transformUniH5Jsx({ types }: typeof BabelCore): PluginObj {
return {
name: 'babel-plugin-uni-h5-jsx',
visitor: {
JSXOpeningElement({ node: { name } }) {
if (types.isJSXIdentifier(name) && isBuiltInComponent(name.name)) {
name.name = 'v-uni-' + name.name
}
},
},
}
}
export * from './transforms'
export * from './utils'
export { transformUniH5Jsx } from './babel'
export { isExternalUrl } from './transforms/templateUtils'
......@@ -3,6 +3,7 @@ import {
transformMatchMedia,
transformPageHead,
transformTapToClick,
transformUniH5Jsx,
UniVitePlugin,
} from '@dcloudio/uni-cli-shared'
import { isH5NativeTag, isH5CustomElement } from '@dcloudio/uni-shared'
......@@ -25,5 +26,8 @@ export function createUni(): UniVitePlugin['uni'] {
assets: ['hybrid/html'],
},
compilerOptions,
jsxOptions: {
babelPlugins: [transformUniH5Jsx],
},
}
}
......@@ -5,7 +5,6 @@ import { camelize, capitalize } from '@vue/shared'
import { COMPONENT_PREFIX, isBuiltInComponent } from '@dcloudio/uni-shared'
import {
EXTNAME_VUE,
H5_COMPONENTS_STYLE_PATH,
BASE_COMPONENTS_STYLE_PATH,
COMPONENT_DEPS_CSS,
......@@ -15,6 +14,7 @@ import {
matchEasycom,
addImportDeclaration,
genResolveEasycomCode,
EXTNAME_VUE_TEMPLATE,
} from '@dcloudio/uni-cli-shared'
const H5_COMPONENTS_PATH = '@dcloudio/uni-h5'
......@@ -71,7 +71,7 @@ export function uniEasycomPlugin(options: UniEasycomPluginOptions): Plugin {
const { filename, query } = parseVueRequest(id)
if (
query.type !== 'template' &&
(query.vue || !EXTNAME_VUE.includes(path.extname(filename)))
(query.vue || !EXTNAME_VUE_TEMPLATE.includes(path.extname(filename)))
) {
return
}
......
......@@ -46,7 +46,7 @@ export interface VitePluginUniOptions {
inputDir?: string
outputDir?: string
vueOptions?: VueOptions
vueJsxOptions?: VueJSXPluginOptions | boolean
vueJsxOptions?: (VueJSXPluginOptions & { babelPlugins?: any[] }) | boolean
viteLegacyOptions?: ViteLegacyOptions | false
}
export interface VitePluginUniResolvedOptions extends VitePluginUniOptions {
......@@ -104,7 +104,11 @@ export default function uniPlugin(
if (options.vueJsxOptions) {
plugins.push(
vueJsxPlugin(
initPluginVueJsxOptions(options, uniPluginOptions.compilerOptions)
initPluginVueJsxOptions(
options,
uniPluginOptions.compilerOptions,
uniPluginOptions.jsxOptions
)
)
)
}
......
......@@ -24,12 +24,14 @@ export function initPluginUniOptions(UniVitePlugins: UniVitePlugin[]) {
const targets: UniViteCopyPluginTarget[] = []
const transformEvent: Record<string, string> = Object.create(null)
const compilerOptions: Required<UniVitePlugin>['uni']['compilerOptions'] = {}
const jsxOptions: Required<UniVitePlugin>['uni']['jsxOptions'] = {}
let compiler: TemplateCompiler | undefined
UniVitePlugins.forEach((plugin) => {
const {
compiler: pluginTemplateCompiler,
copyOptions: pluginCopyOptions,
compilerOptions: pluginCompilerOptions,
jsxOptions: pluginJsxOptions,
} = plugin.uni || {}
if (pluginTemplateCompiler) {
compiler = pluginTemplateCompiler
......@@ -37,6 +39,9 @@ export function initPluginUniOptions(UniVitePlugins: UniVitePlugin[]) {
if (pluginCompilerOptions) {
extend(compilerOptions, pluginCompilerOptions)
}
if (pluginJsxOptions) {
extend(jsxOptions, pluginJsxOptions)
}
if (pluginCopyOptions) {
let copyOptions = pluginCopyOptions as CopyOptions
if (isFunction(pluginCopyOptions)) {
......@@ -58,6 +63,7 @@ export function initPluginUniOptions(UniVitePlugins: UniVitePlugin[]) {
},
transformEvent,
compilerOptions,
jsxOptions,
}
}
......
......@@ -106,7 +106,8 @@ export function initPluginVueJsxOptions(
options: VitePluginUniResolvedOptions,
{
isCustomElement,
}: Required<Required<UniVitePlugin>['uni']>['compilerOptions']
}: Required<Required<UniVitePlugin>['uni']>['compilerOptions'],
jsxOptions: Required<Required<UniVitePlugin>['uni']>['jsxOptions']
) {
const vueJsxOptions = isPlainObject(options.vueJsxOptions)
? options.vueJsxOptions
......@@ -115,6 +116,13 @@ export function initPluginVueJsxOptions(
vueJsxOptions.optimize = true
}
vueJsxOptions.isCustomElement = isCustomElement as (tag: string) => boolean
if (!vueJsxOptions.babelPlugins) {
vueJsxOptions.babelPlugins = []
}
if (isArray(jsxOptions.babelPlugins)) {
vueJsxOptions.babelPlugins.push(...jsxOptions.babelPlugins)
}
return vueJsxOptions
}
......
......@@ -353,6 +353,7 @@ importers:
packages/uni-cli-shared:
specifiers:
'@babel/core': ^7.16.5
'@babel/parser': ^7.16.4
'@babel/types': ^7.16.0
'@dcloudio/uni-i18n': 3.0.0-alpha-3030420211227001
......@@ -395,7 +396,8 @@ importers:
tapable: ^2.2.0
xregexp: 3.1.0
dependencies:
'@babel/parser': 7.16.4
'@babel/core': 7.16.5
'@babel/parser': 7.16.6
'@babel/types': 7.16.0
'@dcloudio/uni-i18n': link:../uni-i18n
'@dcloudio/uni-shared': link:../uni-shared
......@@ -3242,7 +3244,7 @@ packages:
/@vue/compiler-core/3.2.26:
resolution: {integrity: sha512-N5XNBobZbaASdzY9Lga2D9Lul5vdCIOXvUMd6ThcN8zgqQhPKfCV+wfAJNNJKQkSHudnYRO2gEB+lp0iN3g2Tw==}
dependencies:
'@babel/parser': 7.16.4
'@babel/parser': 7.16.6
'@vue/shared': 3.2.26
estree-walker: 2.0.2
source-map: 0.6.1
......@@ -3256,7 +3258,7 @@ packages:
/@vue/compiler-sfc/3.2.26:
resolution: {integrity: sha512-ePpnfktV90UcLdsDQUh2JdiTuhV0Skv2iYXxfNMOK/F3Q+2BO0AulcVcfoksOpTJGmhhfosWfMyEaEf0UaWpIw==}
dependencies:
'@babel/parser': 7.16.4
'@babel/parser': 7.16.6
'@vue/compiler-core': 3.2.26
'@vue/compiler-dom': 3.2.26
'@vue/compiler-ssr': 3.2.26
......@@ -3279,7 +3281,7 @@ packages:
/@vue/reactivity-transform/3.2.26:
resolution: {integrity: sha512-XKMyuCmzNA7nvFlYhdKwD78rcnmPb7q46uoR00zkX6yZrUmcCQ5OikiwUEVbvNhL5hBJuvbSO95jB5zkUon+eQ==}
dependencies:
'@babel/parser': 7.16.4
'@babel/parser': 7.16.6
'@vue/compiler-core': 3.2.26
'@vue/shared': 3.2.26
estree-walker: 2.0.2
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册