diff --git a/packages/shared/src/constants.ts b/packages/shared/src/constants.ts index 252c2d1effb0..690009f095c9 100644 --- a/packages/shared/src/constants.ts +++ b/packages/shared/src/constants.ts @@ -31,3 +31,117 @@ export const PLATFORM_CONFIG_MAP = { type: PLATFORM_TYPE.QUICK }, } + +export const TT_SPECIFIC_COMPONENTS = new Set([ + 'page-container', + 'slot', + 'custom-wrapper', + 'clue-order-form', + 'aweme-group', + 'pay-button', + 'address-area', + 'consume-card', + 'aweme-data', + 'rate-button', + 'store-area', + 'inline-payment-panel', + 'aweme-user-card', + 'aweme-live-book', + 'draw-ad', + 'lynx-view', + 'flow-ad', + 'ai-agent-chat', + 'component' +]) + +export const DEFAULT_COMPONENTS = new Set([ + 'view', + 'scroll-view', + 'swiper', + 'cover-view', + 'cover-image', + 'icon', + 'text', + 'rich-text', + 'progress', + 'button', + 'checkbox', + 'form', + 'input', + 'label', + 'picker', + 'picker-view', + 'picker-view-column', + 'radio', + 'radio-group', + 'checkbox-group', + 'slider', + 'switch', + 'textarea', + 'navigator', + 'audio', + 'image', + 'video', + 'camera', + 'live-player', + 'live-pusher', + 'map', + 'canvas', + 'open-data', + 'web-view', + 'swiper-item', + 'movable-area', + 'movable-view', + 'functional-page-navigator', + 'ad', + 'block', + 'import', + 'official-account', + 'editor' +]) + +export const UNITLESS_PROPERTIES_SET = new Set([ + 'animation-iteration-count', + 'border-image-outset', + 'border-image-slice', + 'border-image-width', + 'box-flex', + 'box-flex-group', + 'box-ordinal-group', + 'column-count', + 'columns', + 'flex', + 'flex-grow', + 'flex-positive', + 'flex-shrink', + 'flex-negative', + 'flex-order', + 'grid-area', + 'grid-row', + 'grid-row-end', + 'grid-row-span', + 'grid-row-start', + 'grid-column', + 'grid-column-end', + 'grid-column-span', + 'grid-column-start', + 'font-weight', + 'line-clamp', + 'line-height', + 'opacity', + 'order', + 'orphans', + 'tab-size', + 'widows', + 'z-index', + 'zoom', + // SVG-related properties + 'fill-opacity', + 'flood-opacity', + 'stop-opacity', + 'stroke-dasharray', + 'stroke-dashoffset', + 'stroke-miterlimit', + 'stroke-opacity', + 'stroke-width', +]) diff --git a/packages/shared/src/utils.ts b/packages/shared/src/utils.ts index 66805e6623aa..ca8748d4062b 100644 --- a/packages/shared/src/utils.ts +++ b/packages/shared/src/utils.ts @@ -249,3 +249,25 @@ export function indent (str: string, size: number): string { }) .join('\n') } + +export enum TTRenderType { + V1 = 1, + V2 = 2, +} + +declare const tt: any +let ttUseV2TTDom: boolean | undefined + +export function isEnableTTDom() { + // 目前仅对于 react 支持 ttdom + if (process.env.TARO_ENV !== 'tt' || process.env.FRAMEWORK !== 'react' || typeof tt === 'undefined') { + return false + } + if (ttUseV2TTDom !== undefined) return ttUseV2TTDom + + const ttMode = tt.getRenderMode ? tt.getRenderMode() : TTRenderType.V1 + + ttMode === TTRenderType.V2 && tt.__$enableTTDom$__ ? (ttUseV2TTDom = true) : (ttUseV2TTDom = false) + + return ttUseV2TTDom +} diff --git a/packages/taro-react/src/props.ts b/packages/taro-react/src/props.ts index 808c5b6ff382..2c048580bdec 100644 --- a/packages/taro-react/src/props.ts +++ b/packages/taro-react/src/props.ts @@ -1,5 +1,5 @@ -import { convertNumber2PX, FormElement } from '@tarojs/runtime' -import { capitalize, internalComponents, isFunction, isNumber, isObject, isString, PLATFORM_TYPE, toCamelCase } from '@tarojs/shared' +import { convertNumber2PX, eventHandlerTTDom, FormElement, setInnerHTML } from '@tarojs/runtime' +import { capitalize, internalComponents, isEnableTTDom, isFunction, isNumber, isObject, isString, PLATFORM_TYPE, toCamelCase, UNITLESS_PROPERTIES_SET } from '@tarojs/shared' import type { Style, TaroElement } from '@tarojs/runtime' @@ -8,6 +8,7 @@ import type { Style, TaroElement } from '@tarojs/runtime' export type Props = Record const IS_NON_DIMENSIONAL = /aspect|acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i +const IS_DATASET_OR_ARIA = /^(data|aria)-/ function isEventName (s: string) { return s[0] === 'o' && s[1] === 'n' @@ -125,6 +126,17 @@ function setEvent (dom: TaroElement, name: string, value: unknown, oldValue?: un eventName = 'tap' } + if (process.env.TARO_ENV === 'tt' && isEnableTTDom()) { + if (isFunction(oldValue)) { + (dom as any).removeEventListener(`bind${eventName}`, dom[`__${eventName}__`]) + } + if (isFunction(value)) { + dom[`__${eventName}__`] = eventHandlerTTDom.bind(null, dom, value) + dom.addEventListener(`bind${eventName}`, dom[`__${eventName}__`], isCapture) + } + return + } + if (isFunction(value)) { if (oldValue) { dom.removeEventListener(eventName, oldValue as any, process.env.TARO_PLATFORM !== PLATFORM_TYPE.HARMONY ? false : undefined) @@ -228,42 +240,50 @@ function setProperty (dom: TaroElement, name: string, value: unknown, oldValue?: ) { // skip } else if (name === 'style') { - if (/harmony.*cpp/.test(process.env.TARO_ENV || '')) { - return dom.setAttribute('_style4cpp', value) - } - const style = dom.style - if (isString(value)) { - style.cssText = value + if (process.env.TARO_ENV === 'tt' && isEnableTTDom()) { + if (isString(value)) { + dom.setAttribute('style', value) + } else if (isObject(value)) { + dom.setAttribute('style', styleObjectToCss(value as StyleValue)) + } } else { - if (isString(oldValue)) { - style.cssText = '' - oldValue = null + if (/harmony.*cpp/.test(process.env.TARO_ENV || '')) { + return dom.setAttribute('_style4cpp', value) } + const style = dom.style + if (isString(value)) { + style.cssText = value + } else { + if (isString(oldValue)) { + style.cssText = '' + oldValue = null + } - if (isObject(oldValue)) { - for (const i in oldValue) { - if (!(value && i in (value as StyleValue))) { - // Harmony特殊处理 - if (process.env.TARO_PLATFORM === PLATFORM_TYPE.HARMONY && i === 'position' && oldValue[i] === 'fixed') { - // @ts-ignore - dom.setLayer(0) + if (isObject(oldValue)) { + for (const i in oldValue) { + if (!(value && i in (value as StyleValue))) { + // Harmony特殊处理 + if (process.env.TARO_PLATFORM === PLATFORM_TYPE.HARMONY && i === 'position' && oldValue[i] === 'fixed') { + // @ts-ignore + dom.setLayer(0) + } + setStyle(style, i, '') } - setStyle(style, i, '') } } - } - if (isObject(value)) { - for (const i in value) { - if (!oldValue || !isEqual(value[i], (oldValue as StyleValue)[i])) { - // Harmony特殊处理 - if (process.env.TARO_PLATFORM === PLATFORM_TYPE.HARMONY && i === 'position') { - if (value[i] === 'fixed' || (value[i] !== 'fixed' && oldValue?.[i])) { - // @ts-ignore - dom.setLayer(value[i] === 'fixed' ? 1 : 0) + if (isObject(value)) { + for (const i in value) { + if (!oldValue || !isEqual(value[i], (oldValue as StyleValue)[i])) { + // Harmony特殊处理 + if (process.env.TARO_PLATFORM === PLATFORM_TYPE.HARMONY && i === 'position') { + if (value[i] === 'fixed' || (value[i] !== 'fixed' && oldValue?.[i])) { + // @ts-ignore + dom.setLayer(value[i] === 'fixed' ? 1 : 0) + } } + setStyle(style, i, value[i]) } - setStyle(style, i, value[i]) } } } @@ -275,10 +295,17 @@ function setProperty (dom: TaroElement, name: string, value: unknown, oldValue?: const oldHtml = (oldValue as DangerouslySetInnerHTML)?.__html ?? '' if (newHtml || oldHtml) { if (oldHtml !== newHtml) { - dom.innerHTML = newHtml + if (process.env.TARO_ENV === 'tt' && isEnableTTDom()) { + setInnerHTML(dom, newHtml) + } else { + dom.innerHTML = newHtml + } } } } else if (!isFunction(value)) { + if (process.env.TARO_ENV === 'tt' && isEnableTTDom() && !IS_DATASET_OR_ARIA.test(name)) { + name = toCamelCase(name) + } if (value == null) { dom.removeAttribute(name) } else { @@ -297,3 +324,13 @@ function setPseudo(dom: TaroElement, name: '::after' | '::before', value: StyleV dom.set_pseudo_before(value) } } + +function styleObjectToCss(style: StyleValue) { + return Object.entries(style) + .map(([key, value]) => { + const kebabCaseKey = key.replace(/([A-Z])/g, '-$1').toLowerCase() + const cssValue = typeof value === 'number' && !UNITLESS_PROPERTIES_SET.has(kebabCaseKey) ? `${value}px` : value === null ? '' : value + return `${kebabCaseKey}: ${cssValue};` + }) + .join(' ') +} diff --git a/packages/taro-runtime/src/bom/document.ts b/packages/taro-runtime/src/bom/document.ts index d94f52001ce5..d458d929bb67 100644 --- a/packages/taro-runtime/src/bom/document.ts +++ b/packages/taro-runtime/src/bom/document.ts @@ -1,3 +1,5 @@ +import { DEFAULT_COMPONENTS, isEnableTTDom, TT_SPECIFIC_COMPONENTS } from '@tarojs/shared' + import { APP, BODY, @@ -43,5 +45,154 @@ function createDocument (): TaroDocument { return doc } +declare const tt: any + +export function createTTDomDocument(): TaroDocument { + const document = tt?.appDocument + if (!document) { + throw new Error('tt.appDocument is not found') + } + const html = document.createElement(HTML) + const head = document.createElement(HEAD) + const body = document.createElement(BODY) + const app = document.createElement(APP) + app.id = APP + const container = document.createElement(CONTAINER) + + const emptyFunction = () => {} + + document.childNodes.push(html) + html.childNodes.push(head, body) + body.childNodes.push(container) + container.childNodes.push(app) + + document.documentElement = html + document.head = head + document.body = body + document.appElement = app + + let builtInComponents = tt?.getBuiltInComponents?.() + if (Array.isArray(builtInComponents)) { + builtInComponents = new Set(builtInComponents) + } else if (!(builtInComponents instanceof Set)) { + builtInComponents = new Set([...DEFAULT_COMPONENTS, ...TT_SPECIFIC_COMPONENTS]) + } + + document.getElementById = function getElementById(id: string) { + if (id === 'app') { + return app + } else { + return Object.getPrototypeOf(this).getElementById.call(this, id) + } + } + + document.getLastPage = function getLastPage() { + let last + for (const v of this._pageDocumentMap.values()) last = v + return last + } + + document.createElement = function (type: string, ...args) { + if (type === 'root') { + return this.getLastPage() + } else { + const el = builtInComponents.has(type) + ? Object.getPrototypeOf(this).createElement.call(this, type, ...args) + : Object.getPrototypeOf(this).createNativeComponent.call(this, type, { + __tt__inner__options__: { + name: type, + }, + }) + // 给元素加上 scopeId + el.setAttribute('class', '') + + // 保存原始的 setAttribute 和 removeAttribute + const originalSetAttribute = el.setAttribute.bind(el) + const originalRemoveAttribute = el.removeAttribute.bind(el) + + // 拦截 setAttribute 来处理 catchMove + el.setAttribute = function (name: string, value: any) { + const result = originalSetAttribute(name, value) + + // 处理 catchMove 属性 + if (name === 'catchMove' && value) { + el.addEventListener('catchtouchmove', emptyFunction) + } + + return result + } + + // 拦截 removeAttribute 来处理 catchMove + el.removeAttribute = function (name: string) { + const oldValue = el.getAttribute(name) + + // 处理 catchMove 属性 + if (name === 'catchMove' && oldValue) { + el.removeEventListener('catchtouchmove', emptyFunction) + } + + return originalRemoveAttribute(name) + } + + if (process.env.FRAMEWORK === 'preact') { + const ttEventListener = el.addEventListener.bind(el) + const ttRemoveEventListener = el.removeEventListener.bind(el) + + el.addEventListener = function (type: string, listener) { + if (type === 'click') { + type = 'tap' + } + + const bindEventName = type.startsWith('bind') || type.startsWith('catch') ? type : `bind${type}` + // 创建包装函数 + const wrapper = (event) => { + const type = event.type + // 对齐 modifyMpEvent 处理逻辑 + if (type === 'tap') { + event.type = 'click' + } else if (type === 'focus') { + event.type = 'focusin' + } else if (type === 'blur') { + event.type = 'focusout' + } + Object.assign(event, { + mpEvent: event, + bubbles: true, + cancelable: true, + }) + listener.call(el, event) + } + + // 保存包装函数的引用,用于后续移除 + if (!el.__eventWrappers) { + el.__eventWrappers = new WeakMap() + } + el.__eventWrappers.set(listener, wrapper) + + ttEventListener(bindEventName, wrapper) + } + + el.removeEventListener = function (type: string, listener) { + if (type === 'click') { + type = 'tap' + } + + const bindEventName = type.startsWith('bind') || type.startsWith('catch') ? type : `bind${type}` + // 获取之前保存的包装函数 + const wrapper = el.__eventWrappers?.get(listener) + if (wrapper) { + ttRemoveEventListener(bindEventName, wrapper) + delete el.__eventWrappers[listener] + } + } + } + + return el + } + } + return document +} + // Note: 小程序端 vite 打包成 commonjs,const document = xxx 会报错,所以把 document 改为 taroDocumentProvider -export const taroDocumentProvider: TaroDocument = process.env.TARO_PLATFORM === 'web' ? env.document : (env.document = createDocument()) +export const taroDocumentProvider: TaroDocument = process.env.TARO_PLATFORM === 'web' ? env.document : (env.document = + isEnableTTDom() ? createTTDomDocument() : createDocument()) diff --git a/packages/taro-runtime/src/dom-external/inner-html/html.ts b/packages/taro-runtime/src/dom-external/inner-html/html.ts index fa3377f3403e..eb50c23374c7 100644 --- a/packages/taro-runtime/src/dom-external/inner-html/html.ts +++ b/packages/taro-runtime/src/dom-external/inner-html/html.ts @@ -1,3 +1,5 @@ +import { isEnableTTDom } from '@tarojs/shared' + import { options } from '../../options' import { parser } from './parser' @@ -17,11 +19,21 @@ options.html = { renderHTMLTag: false } +declare const tt: any + export function setInnerHTML (element: TaroNode, html: string) { while (element.firstChild) { element.removeChild(element.firstChild) } - const children = parser(html, element.ownerDocument) + let { ownerDocument } = element + + if (process.env.TARO_ENV === 'tt' && isEnableTTDom()) { + if ('appDocument' in tt) { + ownerDocument = tt.appDocument + } + } + + const children = parser(html, ownerDocument) for (let i = 0; i < children.length; i++) { element.appendChild(children[i]) diff --git a/packages/taro-runtime/src/dom/event.ts b/packages/taro-runtime/src/dom/event.ts index 389b128cf586..08eece7c7de2 100644 --- a/packages/taro-runtime/src/dom/event.ts +++ b/packages/taro-runtime/src/dom/event.ts @@ -202,3 +202,12 @@ export function eventHandler (event: MpEvent) { } } } + +export function eventHandlerTTDom(ele: any, listener: (event: MpEvent, element: any) => void, event: MpEvent) { + Object.assign(event, { + mpEvent: event, + bubbles: true, + cancelable: true, + }) + listener(event, ele) +} diff --git a/packages/taro-runtime/src/dsl/common.ts b/packages/taro-runtime/src/dsl/common.ts index 9a05b3aa4195..34c67c698db1 100644 --- a/packages/taro-runtime/src/dsl/common.ts +++ b/packages/taro-runtime/src/dsl/common.ts @@ -2,7 +2,8 @@ import { EMPTY_OBJ, ensure, EventChannel, getComponentsAlias, hooks, internalComponents, - isArray, isFunction, isString, isUndefined, Shortcuts + isArray, isEnableTTDom, + isFunction, isString, isUndefined, Shortcuts } from '@tarojs/shared' import { raf } from '../bom/raf' @@ -149,14 +150,22 @@ export function createPageConfig (component: any, pageName?: string, data?: Reco const mount = () => { Current.app!.mount!(component, $taroPath, () => { - pageElement = env.document.getElementById($taroPath) + if (process.env.TARO_ENV === 'tt' && isEnableTTDom()) { + pageElement = (env.document as any).getPageDocumentById(this.__webviewId__) + } else { + pageElement = env.document.getElementById($taroPath) + } ensure(pageElement !== null, '没有找到页面实例。') safeExecute($taroPath, ON_LOAD, this.$taroParams) loadResolver() if (process.env.TARO_PLATFORM !== 'web') { pageElement.ctx = this - pageElement.performUpdate(true, cb) + if (process.env.TARO_ENV === 'tt' && isEnableTTDom()) { + (pageElement as any).sync() + } else { + pageElement.performUpdate(true, cb) + } } else { isFunction(cb) && cb() } @@ -323,7 +332,9 @@ export function createComponentConfig (component: React.ComponentClass, componen safeExecute(path, ON_LOAD) if (process.env.TARO_PLATFORM !== 'web') { componentElement.ctx = this - componentElement.performUpdate(true) + if (process.env.TARO_ENV !== 'tt' || !isEnableTTDom()) { + componentElement.performUpdate(true) + } } }) }, @@ -360,6 +371,10 @@ export function createRecursiveComponentConfig (componentName?: string) { const lifeCycles = isCustomWrapper ? { [ATTACHED] () { + if (process.env.TARO_ENV === 'tt' && isEnableTTDom()) { + return + } + const componentId = this.data.i?.sid || this.props.i?.sid if (isString(componentId)) { customWrapperCache.set(componentId, this) @@ -370,6 +385,10 @@ export function createRecursiveComponentConfig (componentName?: string) { } }, [DETACHED] () { + if (process.env.TARO_ENV === 'tt' && isEnableTTDom()) { + return + } + const componentId = this.data.i?.sid || this.props.i?.sid if (isString(componentId)) { customWrapperCache.delete(componentId) diff --git a/packages/taro-runtime/src/index.ts b/packages/taro-runtime/src/index.ts index fae771ea8612..d8e53d6d8ead 100644 --- a/packages/taro-runtime/src/index.ts +++ b/packages/taro-runtime/src/index.ts @@ -17,13 +17,14 @@ export { URLSearchParams } from './bom/URLSearchParams' export { taroHistoryProvider as history, taroLocationProvider as location, taroWindowProvider as window } from './bom/window' // dom export { TaroElement } from './dom/element' -export { createEvent, eventHandler, TaroEvent } from './dom/event' +export { createEvent, eventHandler, eventHandlerTTDom, TaroEvent } from './dom/event' export { FormElement } from './dom/form' export { TaroNode } from './dom/node' export { TaroRootElement } from './dom/root' export { Style } from './dom/style' export { SVGElement } from './dom/svg' export { TaroText } from './dom/text' +export { setInnerHTML } from './dom-external/inner-html/html' export { MutationObserver } from './dom-external/mutation-observer' // others export { env } diff --git a/packages/taro-runtime/src/interface/hydrate.ts b/packages/taro-runtime/src/interface/hydrate.ts index 472885720f7e..7bb08c94f268 100644 --- a/packages/taro-runtime/src/interface/hydrate.ts +++ b/packages/taro-runtime/src/interface/hydrate.ts @@ -12,6 +12,7 @@ export interface MpInstance { data: any exitState?: any selectComponent: (selector: string) => any + __webviewId__?: number } export interface MiniElementData { diff --git a/packages/taro-webpack5-runner/src/plugins/MiniPlugin.ts b/packages/taro-webpack5-runner/src/plugins/MiniPlugin.ts index 2a457502000d..ef02bfc7337d 100644 --- a/packages/taro-webpack5-runner/src/plugins/MiniPlugin.ts +++ b/packages/taro-webpack5-runner/src/plugins/MiniPlugin.ts @@ -196,7 +196,8 @@ export default class TaroMiniPlugin { isBuildPlugin, addChunkPages, pages: this.pages, - framework: framework + framework: framework, + appConfig: this.appConfig }).apply(compiler) }) ) @@ -216,7 +217,8 @@ export default class TaroMiniPlugin { isBuildPlugin, addChunkPages, pages: this.pages, - framework: framework + framework: framework, + appConfig: this.appConfig }) this.loadChunksPlugin.apply(compiler) } @@ -1025,7 +1027,8 @@ export default class TaroMiniPlugin { pages: childPages, framework: this.options.framework, isIndependentPackages: true, - needAddCommon: [`${name}/comp`, `${name}/custom-wrapper`] + needAddCommon: [`${name}/comp`, `${name}/custom-wrapper`], + appConfig: this.appConfig }).apply(childCompiler) // 添加 comp 和 custom-wrapper 组件 new TaroSingleEntryPlugin(compiler.context, path.resolve(__dirname, '..', 'template/comp'), `${name}/comp`, META_TYPE.STATIC).apply(childCompiler) diff --git a/packages/taro-webpack5-runner/src/plugins/TaroLoadChunksPlugin.ts b/packages/taro-webpack5-runner/src/plugins/TaroLoadChunksPlugin.ts index ee9696ec308f..a353e7fe3408 100644 --- a/packages/taro-webpack5-runner/src/plugins/TaroLoadChunksPlugin.ts +++ b/packages/taro-webpack5-runner/src/plugins/TaroLoadChunksPlugin.ts @@ -3,6 +3,7 @@ import { taroJsComponents } from '@tarojs/helper' import { toDashed } from '@tarojs/shared' +import { AppConfig } from '@tarojs/taro' import { sources } from 'webpack' import { componentConfig } from '../utils/component' @@ -23,6 +24,7 @@ interface IOptions { pages: Set needAddCommon?: string[] isIndependentPackages?: boolean + appConfig?: AppConfig } export default class TaroLoadChunksPlugin { @@ -34,6 +36,7 @@ export default class TaroLoadChunksPlugin { isCompDepsFound: boolean needAddCommon: string[] isIndependentPackages: boolean + appConfig: AppConfig | undefined constructor (options: IOptions) { this.commonChunks = options.commonChunks @@ -43,6 +46,7 @@ export default class TaroLoadChunksPlugin { this.pages = options.pages this.needAddCommon = options.needAddCommon || [] this.isIndependentPackages = options.isIndependentPackages || false + this.appConfig = options.appConfig } apply (compiler: Compiler) { @@ -129,7 +133,7 @@ export default class TaroLoadChunksPlugin { } if (miniType === META_TYPE.ENTRY) { - return addRequireToSource(getChunkIdOrName(chunk), modules, commonChunks) + return addRequireToSource(getChunkIdOrName(chunk), modules, commonChunks, this.appConfig) } if (this.isIndependentPackages && diff --git a/packages/taro-webpack5-runner/src/utils/webpack.ts b/packages/taro-webpack5-runner/src/utils/webpack.ts index 4268a110169a..1f8f6b132ae7 100644 --- a/packages/taro-webpack5-runner/src/utils/webpack.ts +++ b/packages/taro-webpack5-runner/src/utils/webpack.ts @@ -2,6 +2,7 @@ import path from 'node:path' import { promoteRelativePath } from '@tarojs/helper' import { isBoolean } from '@tarojs/shared' +import { AppConfig } from '@tarojs/taro' import { sources } from 'webpack' import type { Chunk, ChunkGraph, Compilation, Stats } from 'webpack' @@ -11,8 +12,14 @@ const { ConcatSource } = sources /** * 在文本头部加入一些 require 语句 */ -export function addRequireToSource (id: string, modules: sources.Source, commonChunks: (Chunk | { name: string })[]) { +export function addRequireToSource (id: string, modules: sources.Source, commonChunks: (Chunk | { name: string })[], appConfig?: AppConfig) { const source = new ConcatSource() + if (process.env.TARO_ENV === 'tt' && appConfig) { + source.add(` +if (typeof tt !== 'undefined') { + tt.__$enableTTDom$__ = ${appConfig.enableTTDom}; +}\n`) + } commonChunks.forEach(chunkItem => { source.add(`require(${JSON.stringify(promoteRelativePath(path.relative(id, chunkItem.name!)))});\n`) }) diff --git a/packages/taro/types/taro.config.d.ts b/packages/taro/types/taro.config.d.ts index 2e948de78331..b880c86aa9f2 100644 --- a/packages/taro/types/taro.config.d.ts +++ b/packages/taro/types/taro.config.d.ts @@ -683,6 +683,11 @@ declare module './index' { * @supported alipay */ behavior?: Behavior + /** + * 用于开启抖音小程序的 tt-dom 渲染模式 + * @supported tt + */ + enableTTDom?: boolean } interface Config extends PageConfig, AppConfig {