diff --git a/packages/taro-cli/templates/default/config/index.js b/packages/taro-cli/templates/default/config/index.js
index 97e8de997a2c..52569c612114 100644
--- a/packages/taro-cli/templates/default/config/index.js
+++ b/packages/taro-cli/templates/default/config/index.js
@@ -27,7 +27,12 @@ export default defineConfig{{#if typescript }}<'{{ to_lower_case compiler }}'>{{
}
},
framework: '{{ to_lower_case framework }}',
- compiler: '{{ to_lower_case compiler }}',{{#if (eq compiler "Webpack5") }}
+ compiler: {
+ type: '{{ to_lower_case compiler }}',
+ {{#if (eq compiler "Vite") }}
+ vitePlugins: [],
+ {{/if}}
+ },{{#if (eq compiler "Webpack5") }}
cache: {
enable: false // Webpack 持久化缓存配置,建议开启。默认配置请参考:https://docs.taro.zone/docs/config-detail#cache
},{{/if}}
diff --git a/packages/taro-components/types/RichText.d.ts b/packages/taro-components/types/RichText.d.ts
index f09f5a69e1c3..d86d6fb0b2a1 100644
--- a/packages/taro-components/types/RichText.d.ts
+++ b/packages/taro-components/types/RichText.d.ts
@@ -15,19 +15,19 @@ interface RichTextProps extends StandardProps {
*/
space?: keyof RichTextProps.TSpace
/** 富文本是否可以长按选中,可用于复制,粘贴,长按搜索等场景
- * @default false(基础库 3.150.1 以前版本)true(基础库 3.150.1 及以后版本)
+ * @default false (基础库 3.150.1 以前版本)true(基础库 3.150.1 及以后版本)
* @supported swan, h5, harmony_hybrid
*/
- selectable?: string
+ selectable?: boolean
/** 阻止长按图片时弹起默认菜单(将该属性设置为image-menu-prevent或image-menu-prevent="true"),只在初始化时有效,不能动态变更;若不想阻止弹起默认菜单,则不需要设置此属性
* @default false
* @supported swan
*/
- imageMenuPrevent?: string
+ imageMenuPrevent?: boolean
/** 富文本中的图片是否可点击预览。在不设置的情况下,若 rich-text 未监听点击事件,则默认开启。未显示设置 preview 时会进行点击默认预览判断,建议显示设置 preview
* @supported swan
*/
- preview?: string
+ preview?: boolean
/** 触摸。
* @supported alipay
*/
diff --git a/packages/taro-h5/src/api/base/weapp/life-cycle.ts b/packages/taro-h5/src/api/base/weapp/life-cycle.ts
index 2b496fe57ef9..fb49881442c5 100644
--- a/packages/taro-h5/src/api/base/weapp/life-cycle.ts
+++ b/packages/taro-h5/src/api/base/weapp/life-cycle.ts
@@ -1,14 +1,16 @@
import Taro from '@tarojs/api'
+import { temporarilyNotSupport } from '../../../utils'
+
const launchOptions: Taro.getLaunchOptionsSync.LaunchOptions = {
path: '',
query: {},
scene: 0,
shareTicket: '',
- referrerInfo: {}
+ referrerInfo: {},
}
-function initLaunchOptions (options = {}) {
+function initLaunchOptions(options = {}) {
Object.assign(launchOptions, options)
}
@@ -17,3 +19,7 @@ Taro.eventCenter.once('__taroRouterLaunch', initLaunchOptions)
// 生命周期
export const getLaunchOptionsSync: typeof Taro.getLaunchOptionsSync = () => launchOptions
export const getEnterOptionsSync: typeof Taro.getEnterOptionsSync = () => launchOptions
+
+export const onApiCategoryChange = /* @__PURE__ */ temporarilyNotSupport('onApiCategoryChange')
+export const offApiCategoryChange = /* @__PURE__ */ temporarilyNotSupport('offApiCategoryChange')
+export const getApiCategory = /* @__PURE__ */ temporarilyNotSupport('getApiCategory')
diff --git a/packages/taro-platform-h5/src/program.ts b/packages/taro-platform-h5/src/program.ts
index a635cf8a683d..8684642d9749 100644
--- a/packages/taro-platform-h5/src/program.ts
+++ b/packages/taro-platform-h5/src/program.ts
@@ -139,7 +139,9 @@ export default class H5 extends TaroPlatformWeb {
break
default:
if (this.useHtmlComponents) {
- args[0].loaderMeta.extraImportForWeb += `import '${require.resolve('@tarojs/components-react/dist/index.css')}'\nimport { PullDownRefresh } from '@tarojs/components'\n`
+ args[0].loaderMeta.extraImportForWeb += `import '${require.resolve(
+ '@tarojs/components-react/dist/index.css'
+ )}'\nimport { PullDownRefresh } from '@tarojs/components'\n`
args[0].loaderMeta.execBeforeCreateWebApp += `config.PullDownRefresh = PullDownRefresh\n`
}
}
@@ -180,7 +182,7 @@ export default class H5 extends TaroPlatformWeb {
function injectLoaderMeta() {
return {
name: 'taro:vite-h5-loader-meta',
- async buildStart () {
+ async buildStart() {
const viteCompilerContext = await getViteH5CompilerContext(this)
if (viteCompilerContext) {
viteCompilerContext.loaderMeta ||= {
@@ -222,7 +224,10 @@ export default class H5 extends TaroPlatformWeb {
const viteCompilerContext = await getViteH5CompilerContext(this)
if (viteCompilerContext) {
const exts = Array.from(new Set(viteCompilerContext.frameworkExts.concat(SCRIPT_EXT)))
- if (id.startsWith(viteCompilerContext.sourceDir) && exts.some((ext) => id.includes(ext))) {
+ if (
+ path.normalize(id).startsWith(viteCompilerContext.sourceDir) &&
+ exts.some((ext) => id.includes(ext))
+ ) {
// @TODO 后续考虑使用 SWC 插件的方式实现
const result = await transformAsync(code, {
filename: id,
@@ -231,7 +236,7 @@ export default class H5 extends TaroPlatformWeb {
require('babel-plugin-transform-taroapi'),
{
packageName: '@tarojs/taro',
- definition: require(that.libraryDefinition)
+ definition: require(that.libraryDefinition),
},
],
],
diff --git a/packages/taro-vite-runner/src/h5/mpa.ts b/packages/taro-vite-runner/src/h5/mpa.ts
index a11ad9440455..fff30c5d9b9f 100644
--- a/packages/taro-vite-runner/src/h5/mpa.ts
+++ b/packages/taro-vite-runner/src/h5/mpa.ts
@@ -21,34 +21,28 @@ export default function (viteCompilerContext: ViteH5CompilerContext): PluginOpti
designWidth: taroConfig.designWidth,
deviceRatio: taroConfig.deviceRatio,
option: taroConfig.postcss,
- esnextModules: taroConfig.esnextModules || []
+ esnextModules: taroConfig.esnextModules || [],
})
const [, pxtransformOption] = __postcssOption.find(([name]) => name === 'postcss-pxtransform') || []
- function createRewire (
- reg: string,
- baseUrl: string,
- proxyUrlKeys: string[],
- ) {
+ function createRewire(reg: string, baseUrl: string, proxyUrlKeys: string[]) {
return {
from: new RegExp(`/${reg}.html`),
to({ parsedUrl }) {
const pathname: string = parsedUrl.pathname
const excludeBaseUrl = pathname.replace(baseUrl, '/')
- const template = path.resolve(baseUrl, 'index.html')
+ const template = path.posix.join(baseUrl, 'index.html')
if (excludeBaseUrl === '/') {
return template
}
- const isApiUrl = proxyUrlKeys.some((item) =>
- pathname.startsWith(path.resolve(baseUrl, item)),
- )
+ const isApiUrl = proxyUrlKeys.some((item) => pathname.startsWith(path.posix.join(baseUrl, item)))
return isApiUrl ? excludeBaseUrl : template
},
}
}
- function getIsHtmlEntry (pathName: string) {
+ function getIsHtmlEntry(pathName: string) {
return pages.some(({ name }) => {
const pageName = removeHeadSlash(path.join(basename, name))
const htmlPath = path.join(appPath, taroConfig.sourceRoot || 'src', `${pageName}.html`)
@@ -60,7 +54,7 @@ export default function (viteCompilerContext: ViteH5CompilerContext): PluginOpti
const input = {}
pages.forEach((page) => {
const { name } = page
- const pageName = removeHeadSlash(path.join(basename, name))
+ const pageName = removeHeadSlash(path.posix.join(basename, name))
const htmlPath = path.join(appPath, taroConfig.sourceRoot || 'src', `${pageName}.html`)
input[pageName] = htmlPath
})
@@ -70,19 +64,19 @@ export default function (viteCompilerContext: ViteH5CompilerContext): PluginOpti
return {
name: 'taro:vite-h5-mpa',
enforce: 'pre',
- buildStart () {
+ buildStart() {
const getRoutesConfig = (pageName: string) => {
- const page = pages.find(({ name }) => name === pageName) || pages[0] as VitePageMeta
+ const page = pages.find(({ name }) => name === pageName) || (pages[0] as VitePageMeta)
const routesConfig = [
'config.routes = []',
`config.route = ${genRouterResource(page)}`,
- `config.pageName = "${pageName}"`
+ `config.pageName = "${page.name}"`,
].join('\n')
return routesConfig
}
viteCompilerContext.routerMeta = {
routerCreator: 'createMultiRouter',
- getRoutesConfig
+ getRoutesConfig,
}
},
config: () => ({
@@ -90,41 +84,43 @@ export default function (viteCompilerContext: ViteH5CompilerContext): PluginOpti
rollupOptions: {
input: getInput(),
output: {
- entryFileNames: (chunkInfo) => `js/${chunkInfo.name}.[hash].js`
- }
- }
- }
+ entryFileNames: (chunkInfo) => `js/${chunkInfo.name}.[hash].js`,
+ },
+ },
+ },
}),
- configureServer (server) {
+ configureServer(server) {
const rewrites: { from: RegExp, to: any }[] = []
const proxy = server.config.server.proxy || {}
const proxyKeys = Object.keys(proxy)
const baseUrl = server.config.base ?? '/'
pages.forEach(({ name }) => {
- const pageName = removeHeadSlash(path.join(basename, name))
+ const pageName = removeHeadSlash(path.posix.join(basename, name))
rewrites.push(createRewire(pageName, baseUrl, proxyKeys))
})
- server.middlewares.use(history({
- disableDotRule: undefined,
- htmlAcceptHeaders: ['text/html', 'application/xhtml+xml'],
- rewrites: rewrites
- }))
+ server.middlewares.use(
+ history({
+ disableDotRule: undefined,
+ htmlAcceptHeaders: ['text/html', 'application/xhtml+xml'],
+ rewrites: rewrites,
+ })
+ )
},
- async resolveId (source, importer, options) {
+ async resolveId(source, importer, options) {
// 处理 html 文件
const isEntry = getIsHtmlEntry(source)
if (isEntry) return source
// 处理 config.ts 入口文件
const resolved = await this.resolve(source, importer, { ...options, skipSelf: true })
- if (resolved?.id && pages.some(({ configPath }) => resolved.id.startsWith(configPath))) {
+ if (resolved?.id && pages.some(({ configPath }) => resolved.id.startsWith(configPath.replace(/\\/g, '/')))) {
// mpa 模式,入口文件为每个page下的config
const queryParams = getQueryParams(source)
const pageName = queryParams?.[PAGENAME_QUERY]
const pureId = path.parse(resolved.id).dir
const params = {
[ENTRY_QUERY]: 'true',
- [PAGENAME_QUERY]: pageName as string
+ [PAGENAME_QUERY]: pageName as string,
}
const queryString = generateQueryString(params)
return appendVirtualModulePrefix(pureId + `?${queryString}`)
@@ -132,7 +128,7 @@ export default function (viteCompilerContext: ViteH5CompilerContext): PluginOpti
return null
},
- load (id) {
+ load(id) {
// 处理 html 文件
const isEntryHtml = getIsHtmlEntry(id)
if (isEntryHtml) return htmlTemplate
@@ -145,9 +141,11 @@ export default function (viteCompilerContext: ViteH5CompilerContext): PluginOpti
let srciptSource = configPath.replace(sourceDir, '')
let page
if (isProd) {
- page = pages.filter(({ name }) => filePath?.startsWith(`/${removeHeadSlash(path.join(basename, name))}`))?.[0]
+ page = pages.find(({ name }) => filePath?.startsWith(`/${removeHeadSlash(path.posix.join(basename, name))}`))
} else {
- page = pages.filter(({ name }) => originalUrl?.startsWith(`/${removeHeadSlash(path.join(basename, name))}`))?.[0]
+ page = pages.find(({ name }) =>
+ originalUrl?.startsWith(`/${removeHeadSlash(path.posix.join(basename, name))}`)
+ )
}
if (page) {
const params = { [PAGENAME_QUERY]: page.name }
@@ -157,7 +155,7 @@ export default function (viteCompilerContext: ViteH5CompilerContext): PluginOpti
const htmlScript = getHtmlScript(srciptSource, pxtransformOption)
return html.replace(/\n`
}
- htmlScript += ` `
+ htmlScript += ` `
return htmlScript
}
diff --git a/packages/taro-webpack5-runner/src/webpack/MiniBaseConfig.ts b/packages/taro-webpack5-runner/src/webpack/MiniBaseConfig.ts
index 6b3f925fe179..1e05328bfbe9 100644
--- a/packages/taro-webpack5-runner/src/webpack/MiniBaseConfig.ts
+++ b/packages/taro-webpack5-runner/src/webpack/MiniBaseConfig.ts
@@ -57,7 +57,7 @@ export class MiniBaseConfig extends BaseConfig {
// 小程序使用 regenerator-runtime@0.11
'regenerator-runtime': require.resolve('regenerator-runtime'),
// 开发组件库时 link 到本地调试,runtime 包需要指向本地 node_modules 顶层的 runtime,保证闭包值 Current 一致,shared 也一样
- '@tarojs/runtime': resolveSync('@tarojs/runtime', resolveOptions),
+ '@tarojs/runtime': resolveSync('@tarojs/runtime', { basedir: appPath, mainFields: ['main', ...mainFields] }),
'@tarojs/shared': resolveSync('@tarojs/shared', resolveOptions),
},
// [Webpack 4] config.node: { fs: false, path: false }
diff --git a/packages/taro/types/api/base/weapp/life-cycle.d.ts b/packages/taro/types/api/base/weapp/life-cycle.d.ts
index f2986b923d35..52782b465911 100644
--- a/packages/taro/types/api/base/weapp/life-cycle.d.ts
+++ b/packages/taro/types/api/base/weapp/life-cycle.d.ts
@@ -1,6 +1,21 @@
import Taro from '../../../index'
declare module '../../../index' {
+ namespace onApiCategoryChange {
+ type Listener = (res: { apiCategory: keyof onApiCategoryChange.ApiCategory }) => void
+
+ /** API 类别合法值 */
+ interface ApiCategory {
+ /** 默认类别 */
+ default
+ /** 原生功能化,视频号直播商品、商品橱窗等场景打开的小程序 */
+ nativeFunctionalized
+ /** 仅浏览,朋友圈快照页等场景打开的小程序 */
+ browseOnly
+ /** 内嵌,通过打开半屏小程序能力打开的小程序 */
+ embedded
+ }
+ }
namespace getLaunchOptionsSync {
/** 启动参数 */
interface LaunchOptions {
@@ -132,6 +147,20 @@ declare module '../../../index' {
}
interface TaroStatic {
+ /**
+ * 监听 API 类别变化事件
+ * @param listener API 类别变化事件的监听函数
+ * @supported weapp
+ * @see https://developers.weixin.qq.com/miniprogram/dev/api/base/app/life-cycle/wx.onApiCategoryChange.html
+ */
+ onApiCategoryChange(listener: onApiCategoryChange.Listener): void
+ /**
+ * 移除 API 类别变化事件的监听函数
+ * @param listener onApiCategoryChange 传入的监听函数。不传此参数则移除所有监听函数。
+ * @supported weapp
+ * @see https://developers.weixin.qq.com/miniprogram/dev/api/base/app/life-cycle/wx.offApiCategoryChange.html
+ */
+ offApiCategoryChange(listener?: onApiCategoryChange.Listener): void
/**
* 获取小程序启动时的参数。与 [`App.onLaunch`](https://developers.weixin.qq.com/miniprogram/dev/reference/api/App.html#onlaunchobject-object) 的回调参数一致。
*
@@ -151,5 +180,11 @@ declare module '../../../index' {
* @see https://developers.weixin.qq.com/miniprogram/dev/api/base/app/life-cycle/wx.getEnterOptionsSync.html
*/
getEnterOptionsSync(): getEnterOptionsSync.EnterOptions
+ /**
+ * 获取当前 API 类别
+ * @supported weapp
+ * @see https://developers.weixin.qq.com/miniprogram/dev/api/base/app/life-cycle/wx.getApiCategory.html
+ */
+ getApiCategory(): keyof onApiCategoryChange.ApiCategory
}
}
diff --git a/packages/taro/types/api/open-api/subscribe-message.d.ts b/packages/taro/types/api/open-api/subscribe-message.d.ts
index a168306a7f76..2ecbbddf7aa1 100644
--- a/packages/taro/types/api/open-api/subscribe-message.d.ts
+++ b/packages/taro/types/api/open-api/subscribe-message.d.ts
@@ -7,11 +7,11 @@ declare module '../../index' {
* 需要订阅的消息模板的id的集合(注意:iOS客户端7.0.6版本、Android客户端7.0.7版本之后的一次性订阅/长期订阅才支持多个模板消息,iOS客户端7.0.5版本、Android客户端7.0.6版本之前的一次订阅只支持一个模板消息)消息模板id在[微信公众平台(mp.weixin.qq.com)-功能-订阅消息]中配置
* @supported weapp, tt
*/
- tmplIds: string[]
+ tmplIds?: string[]
/** 需要订阅的消息模板 id 集合(注意:1、一次性模板 id 和长期性模板 id 不可同时使用,2、一次最多传入三个模板 id
* @supported alipay
*/
- entityIds: string[]
+ entityIds?: string[]
/** 模板小程序 appId,仅在服务商代调用场景下需要传入
* @supported alipay
*/
diff --git a/packages/taro/types/api/ui/interaction.d.ts b/packages/taro/types/api/ui/interaction.d.ts
index d5682a10554f..f189e547bad7 100644
--- a/packages/taro/types/api/ui/interaction.d.ts
+++ b/packages/taro/types/api/ui/interaction.d.ts
@@ -50,9 +50,15 @@ declare module '../../index' {
success?: (result: SuccessCallbackResult) => void
/** 提示的标题 */
title?: string
+ /** 是否显示输入框 */
+ editable?: boolean
+ /** 显示输入框时的提示文本 */
+ placeholderText?: string
}
interface SuccessCallbackResult extends TaroGeneral.CallbackResult {
+ /** editable 为 true 时,用户输入的文本 */
+ content?: string
/** 为 true 时,表示用户点击了取消(用于 Android 系统区分点击蒙层关闭还是点击取消按钮关闭) */
cancel: boolean
/** 为 true 时,表示用户点击了确定按钮 */
@@ -256,7 +262,7 @@ declare module '../../index' {
* ```
* @see https://developers.weixin.qq.com/miniprogram/dev/api/ui/interaction/wx.hideLoading.html
*/
- hideLoading(option?: hideLoading.Option): void /** 隐藏 loading 提示框
+ hideLoading(option?: hideLoading.Option): void /** 隐藏 loading 提示框
/** 开启小程序页面返回询问对话框
* @supported weapp
diff --git a/packages/taro/types/compile/config/mini.d.ts b/packages/taro/types/compile/config/mini.d.ts
index d3cad4e908b6..b1d909700a1c 100644
--- a/packages/taro/types/compile/config/mini.d.ts
+++ b/packages/taro/types/compile/config/mini.d.ts
@@ -4,6 +4,7 @@ import type { IOption, IPostcssOption, IUrlLoaderOption } from './util'
import type { OutputOptions as RollupOutputOptions } from 'rollup'
import type { Compiler, CompilerTypes, CompilerWebpackTypes } from '../compiler'
import type { OutputExt } from './project'
+import type { Shortcuts } from '@tarojs/shared'
interface Runtime {
enableInnerHTML?: boolean
@@ -15,6 +16,24 @@ interface Runtime {
enableMutationObserver?: boolean
}
+interface PrerenderPageConfig {
+ /** 页面路径 */
+ path: string
+ /** 页面的路由参数,对应 `getCurrentInstance().router.params` */
+ params: Record
+}
+
+/** DOM 树数据,Taro 通过遍历它动态渲染数据 */
+interface MiniData {
+ [Shortcuts.Childnodes]?: MiniData[]
+ [Shortcuts.NodeName]: string
+ [Shortcuts.Class]?: string
+ [Shortcuts.Style]?: string
+ [Shortcuts.Text]?: string
+ sid: string
+ uid?: string
+}
+
export interface IMiniAppConfig {
/** 用于控制是否生成 js、css 对应的 sourceMap (默认值:watch 模式下为 true,否则为 false) */
enableSourceMap?: boolean
@@ -44,15 +63,28 @@ export interface IMiniAppConfig
webpackChain?: (chain: Chain, webpack: typeof Webpack, PARSE_AST_TYPE: any) => void
/** webpack 编译模式下,可用于修改、拓展 Webpack 的 output 选项,配置项参考[官方文档](https://webpack.js.org/configuration/output/)
- * vite 编译模式下,用于修改、扩展 rollup 的 output,目前仅适配 chunkFileNames 和 assetFileNames 两个配置,修改其他配置请使用 vite 插件进行修改。配置想参考[官方文档](https://rollupjs.org/configuration-options/)
- */
+ * vite 编译模式下,用于修改、扩展 rollup 的 output,目前仅适配 chunkFileNames 和 assetFileNames 两个配置,修改其他配置请使用 vite 插件进行修改。配置想参考[官方文档](https://rollupjs.org/configuration-options/)
+ */
output?: T extends 'vite'
- ? Pick & OutputExt
+ ? Pick & OutputExt
: Webpack.Configuration['output'] & OutputExt
/** 配置 postcss 相关插件 */
postcss?: IPostcssOption<'mini'>
+ /**预渲染
+ * https://docs.taro.zone/docs/prerender
+ */
+ prerender?: {
+ match?: string | string[]
+ include?: Array
+ exclude?: string[]
+ mock?: Record
+ console?: boolean
+ transformData?: (data: MiniData, config: PrerenderPageConfig) => MiniData
+ transformXML?: (data: MiniData, config: PrerenderPageConfig, xml: string) => MiniData
+ }
+
/** [css-loader](https://github.com/webpack-contrib/css-loader) 的附加配置 */
cssLoaderOption?: IOption