Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(vite): fix h5 build error when use vite #16256

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion packages/taro-cli/templates/default/config/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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}}
Expand Down
8 changes: 4 additions & 4 deletions packages/taro-components/types/RichText.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
10 changes: 8 additions & 2 deletions packages/taro-h5/src/api/base/weapp/life-cycle.ts
Original file line number Diff line number Diff line change
@@ -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)
}

Expand All @@ -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')
13 changes: 9 additions & 4 deletions packages/taro-platform-h5/src/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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`
}
}
Expand Down Expand Up @@ -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 ||= {
Expand Down Expand Up @@ -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,
Expand All @@ -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),
},
],
],
Expand Down
66 changes: 32 additions & 34 deletions packages/taro-vite-runner/src/h5/mpa.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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`)
Expand All @@ -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
})
Expand All @@ -70,69 +64,71 @@ 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: () => ({
build: {
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}`)
}

return null
},
load (id) {
load(id) {
// 处理 html 文件
const isEntryHtml = getIsHtmlEntry(id)
if (isEntryHtml) return htmlTemplate
Expand All @@ -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 }
Expand All @@ -157,7 +155,7 @@ export default function (viteCompilerContext: ViteH5CompilerContext): PluginOpti
const htmlScript = getHtmlScript(srciptSource, pxtransformOption)

return html.replace(/<script><%= htmlWebpackPlugin.options.script %><\/script>/, htmlScript)
}
},
},
}
}
4 changes: 2 additions & 2 deletions packages/taro-vite-runner/src/utils/html.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export function getHtmlScript (entryScript: string, pxtransformOption): string {
export function getHtmlScript(entryScript: string, pxtransformOption): string {
let htmlScript = ''
const options = pxtransformOption?.config || {}
const max = options?.maxRootSize ?? 40
Expand All @@ -11,6 +11,6 @@ export function getHtmlScript (entryScript: string, pxtransformOption): string {
if ((options?.targetUnit ?? 'rem') === 'rem') {
htmlScript = `<script>!function(n){function f(){var e=n.document.documentElement,r=e.getBoundingClientRect(),width=r.width,height=r.height,arr=[width,height].filter(function(value){return Boolean(value)}),w=Math.min.apply(Math,arr),x=${rootValue}*w/${designWidth};e.style.fontSize=x>=${max}?"${max}px":x<=${min}?"${min}px":x+"px"}; n.addEventListener("resize",(function(){f()})),f()}(window);</script>\n`
}
htmlScript += ` <script type="module" src="${entryScript}"></script>`
htmlScript += ` <script type="module" src="${entryScript.replace(/\\/g, '/')}"></script>`
return htmlScript
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export class MiniBaseConfig extends BaseConfig {
// 小程序使用 [email protected]
'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 }
Expand Down
35 changes: 35 additions & 0 deletions packages/taro/types/api/base/weapp/life-cycle.d.ts
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -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) 的回调参数一致。
*
Expand All @@ -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
}
}
4 changes: 2 additions & 2 deletions packages/taro/types/api/open-api/subscribe-message.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
8 changes: 7 additions & 1 deletion packages/taro/types/api/ui/interaction.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 时,表示用户点击了确定按钮 */
Expand Down Expand Up @@ -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
Expand Down
Loading
Loading