Skip to content

Commit 65fc75c

Browse files
committed
feat: keyboard avoiding use translate
1 parent 7b75599 commit 65fc75c

File tree

8 files changed

+294
-24
lines changed

8 files changed

+294
-24
lines changed
Lines changed: 240 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,245 @@
1+
import * as webpack from 'webpack'
2+
3+
declare module 'webpack' {
4+
interface Compilation {
5+
__mpx__: MpxContext
6+
}
7+
8+
interface Compiler {
9+
__mpx__?: boolean
10+
}
11+
}
112

213
declare global {
314
interface MpxWebpackPluginOptions {
4-
style: {
5-
cssCondition?: {
6-
before?: boolean;
7-
after?: boolean;
8-
beforeExclude?: (string | RegExp)[];
9-
afterExclude?: (string | RegExp)[];
10-
legacy?: boolean;
11-
afterLegacy?: boolean;
12-
beforeLegacy?: boolean;
13-
}
14-
}
15+
style: {
16+
cssCondition?: {
17+
before?: boolean
18+
after?: boolean
19+
beforeExclude?: (string | RegExp)[]
20+
afterExclude?: (string | RegExp)[]
21+
legacy?: boolean
22+
afterLegacy?: boolean
23+
beforeLegacy?: boolean
24+
}
1525
}
26+
}
27+
28+
type MpxLoaderContext<T> = webpack.LoaderContext<T> & {
29+
getMpx(): MpxContext
30+
}
31+
32+
interface MpxContext {
33+
/**
34+
* 用于使用 webpack-virtual-modules 功能,目前仅在输出 web 时支持使用
35+
*/
36+
__vfs: any | null
37+
38+
/**
39+
* app 信息,便于获取 appName
40+
*/
41+
appInfo: {
42+
resourcePath?: string
43+
name?: string
44+
[key: string]: any
45+
}
46+
47+
/**
48+
* pageConfig 信息
49+
*/
50+
pageConfigsMap: Record<string, any>
51+
52+
/**
53+
* pages 全局记录,无需区分主包/分包
54+
*/
55+
pagesMap: Record<string, string>
56+
57+
/**
58+
* 组件资源记录,按所属包进行记录(如 componentsMap.main)
59+
*/
60+
componentsMap: Record<string, Record<string, string>>
61+
62+
/**
63+
* 静态资源(图片、字体、独立样式)等,按所属包进行记录
64+
*/
65+
staticResourcesMap: Record<string, Record<string, string>>
66+
67+
/**
68+
* 用于记录命中 subpackageModulesRules 的 JS 模块分包归属,用于 JS 多分包冗余输出
69+
*/
70+
subpackageModulesMap: Record<string, Record<string, string>>
71+
72+
/**
73+
* 记录其他资源,如 pluginMain、pluginExport,无需区分主包/分包
74+
*/
75+
otherResourcesMap: Record<string, any>
76+
77+
/**
78+
* 记录独立分包
79+
*/
80+
independentSubpackagesMap: Record<string, any>
81+
82+
subpackagesEntriesMap: Record<string, any>
83+
postSubpackageEntriesMap: Record<string, any>
84+
replacePathMap: Record<string, string>
85+
86+
/**
87+
* 导出模块集合
88+
*/
89+
exportModules: Set<any>
90+
91+
/**
92+
* 记录动态添加入口的分包信息
93+
*/
94+
dynamicEntryInfo: Record<string, any>
95+
96+
/**
97+
* 记录 entryModule 与 entryNode 的对应关系,用于体积分析
98+
*/
99+
entryNodeModulesMap: Map<any, any>
100+
101+
/**
102+
* 记录与 asset 相关联的 modules,用于体积分析
103+
*/
104+
assetsModulesMap: Map<string, Set<any>>
105+
106+
/**
107+
* 记录与 asset 相关联的 AST,用于体积分析和 esCheck,避免重复 parse
108+
*/
109+
assetsASTsMap: Map<string, any>
110+
111+
/**
112+
* 记录 RequireExternalDependency 相关资源路径
113+
*/
114+
externalRequestsMap: Map<string, any>
115+
116+
globalComponents: Record<string, any>
117+
globalComponentsInfo: Record<string, any>
118+
119+
/**
120+
* todo: es6 Map 读写性能高于 object,之后会逐步替换
121+
*/
122+
wxsAssetsCache: Map<string, any>
123+
addEntryPromiseMap: Map<string, Promise<any>>
124+
currentPackageRoot: string
125+
wxsContentMap: Record<string, string>
126+
127+
/**
128+
* 是否强制使用页面构造函数
129+
*/
130+
forceUsePageCtor: boolean
131+
132+
resolveMode: string
133+
mode: string
134+
srcMode: string
135+
env: string
136+
externalClasses: string[]
137+
projectRoot: string
138+
autoScopeRules: any
139+
autoVirtualHostRules: any
140+
customTextRules: any
141+
transRpxRules: any
142+
postcssInlineConfig: any
143+
decodeHTMLText: boolean
144+
145+
/**
146+
* native 文件专用配置
147+
*/
148+
i18n: any | null
149+
checkUsingComponentsRules: any
150+
forceDisableBuiltInLoader: boolean
151+
152+
/**
153+
* 默认的应用标题
154+
*/
155+
appTitle: string
156+
157+
attributes: any[]
158+
externals: any[]
159+
useRelativePath: boolean
160+
removedChunks: any[]
161+
forceProxyEventRules: any
162+
163+
/**
164+
* 若配置 disableRequireAsync=true,则全平台构建不支持异步分包
165+
*/
166+
supportRequireAsync: boolean
167+
partialCompileRules: any
168+
asyncSubpackageRules: any[]
169+
transSubpackageRules: any
170+
optimizeRenderRules: any[]
171+
172+
addEntryModuleIssuer: (module: string, issuer: string) => void
173+
174+
/**
175+
* 资源路径的哈希函数(用于生成输出唯一名)
176+
*/
177+
pathHash: (resourcePath: string) => string
178+
179+
// 缓存与工具
180+
loaderContentCache: Map<string, any>
181+
extractedFilesCache: Map<string, string>
182+
183+
// 函数接口
184+
185+
/**
186+
* 收集动态入口信息(分包、文件名、是否为页面、是否包含异步等)
187+
*/
188+
collectDynamicEntryInfo: (info: { resource: string; packageName: string; filename: string; entryType: string; hasAsync: boolean }) => void
189+
190+
/**
191+
* 添加入口(包装了 webpack 的 addEntry)
192+
*/
193+
addEntry: (request: string, name: string, callback: (err?: Error, result?: any) => void) => any
194+
195+
getModuleId: (filePath: string, isApp?: boolean) => string
196+
getEntryNode: (module: any, type?: string) => any
197+
198+
/**
199+
* 根据资源路径和类型返回输出路径(支持自定义输出、冲突处理等)
200+
*/
201+
getOutputPath: (resourcePath: string, type: string, opts?: { ext?: string; conflictPath?: string }) => string
202+
203+
/**
204+
* 获取提取后的文件名(支持静态、插件、普通资源)
205+
*/
206+
getExtractedFile: (resource: string, opts?: { error?: (err: Error) => void }) => string
207+
208+
recordResourceMap: (params: {
209+
resourcePath: string
210+
resourceType: string
211+
outputPath?: string
212+
packageRoot?: string
213+
recordOnly?: boolean
214+
warn?: (e: Error) => void
215+
error?: (e: Error) => void
216+
}) => { outputPath?: string; alreadyOutputted?: boolean }
217+
218+
getPackageInfo: (params: {
219+
resource: string
220+
resourceType: string
221+
outputPath?: string
222+
issuerResource?: string
223+
warn?: (e: Error) => void
224+
error?: (e: Error) => void
225+
}) => { packageName: string; packageRoot: string; outputPath?: string; alreadyOutputted?: boolean }
226+
227+
// 运行时信息与注入相关
228+
runtimeInfo: Record<string, any>
229+
dynamicSlotDependencies: Record<string, any>
230+
dynamicTemplateRuleRunner: any
231+
232+
/**
233+
* 依据 package 注入到 mpx-custom-element-*.json 里面的组件路径
234+
*/
235+
getPackageInjectedComponentsMap: (packageName?: string) => Record<string, string>
236+
237+
getPackageInjectedTemplateConfig: (packageName?: string) => any
238+
injectDynamicSlotDependencies: (usingComponents: string, resourcePath: string) => string
239+
changeHashNameForAstNode: (templateAst: string, componentsMap: any) => string
240+
collectDynamicSlotDependencies: (packageName?: string) => void
241+
242+
// 其它任意扩展字段
243+
[key: string]: any
244+
}
16245
}

packages/webpack-plugin/lib/index.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ const isProductionLikeMode = options => {
8787
return options.mode === 'production' || !options.mode
8888
}
8989

90+
/**
91+
* @param {import('webpack').NormalModule} module
92+
* @returns
93+
*/
9094
const isStaticModule = module => {
9195
if (!module.resource) return false
9296
const { queryObj } = parseRequest(module.resource)
@@ -323,6 +327,9 @@ class MpxWebpackPlugin {
323327
}
324328
}
325329

330+
/**
331+
* @param {import('webpack').Compiler} compiler
332+
*/
326333
apply (compiler) {
327334
// 注入 fs 代理
328335
startFSStripForCss(this.options.defs)

packages/webpack-plugin/lib/loader.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ const processWeb = require('./web')
1919
const processReact = require('./react')
2020
const genMpxCustomElement = require('./runtime-render/gen-mpx-custom-element')
2121

22+
/**
23+
* @this {MpxLoaderContext<any>}
24+
* @param {string} content
25+
*/
2226
module.exports = function (content) {
2327
this.cacheable()
2428

packages/webpack-plugin/lib/platform/template/wx/component-config/button.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ module.exports = function ({ print }) {
197197
qa: qaPropLog
198198
},
199199
{
200-
test: /^(lang|from-type|hover-class|send-message-title|send-message-path|send-message-img|app-parameter|show-message-card|phone-number-no-quota-toast|bindgetuserinfo|bindcontact|createliveactivity|bindgetphonenumber|bindgetrealtimephonenumber|binderror|bindopensetting|bindlaunchapp|bindchooseavatar|bindagreeprivacyauthorization)$/,
200+
test: /^(lang|from-type|send-message-title|send-message-path|send-message-img|app-parameter|show-message-card|phone-number-no-quota-toast|bindgetuserinfo|bindcontact|createliveactivity|bindgetphonenumber|bindgetrealtimephonenumber|binderror|bindopensetting|bindlaunchapp|bindchooseavatar|bindagreeprivacyauthorization)$/,
201201
ios: iosPropLog,
202202
android: androidPropLog,
203203
harmony: harmonyPropLog

packages/webpack-plugin/lib/runtime/components/react/mpx-keyboard-avoiding-view.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }: Keyboa
2525
const isShow = useRef<boolean>(false)
2626

2727
const animatedStyle = useAnimatedStyle(() => ({
28-
// translate/position top可能会导致底部渲染区域缺失
29-
marginTop: -offset.value,
28+
// translate/position top+ overflow hidden 在 android 上时因为键盘顶起让页面高度变小,同时元素位置上移
29+
// 此时最底部的区域是超出了页面高度的,hidden生效就被隐藏掉,因此需要 android 配置聚焦时禁用高度缩小
30+
// margin-top 因为在 react-native 上和 flex 1 同时存在时,负值只会让容器高度整体变高,不会让元素上移
31+
transform: [{ translateY: -offset.value }],
3032
flexBasis: basic.value as DimensionValue
3133
}))
3234

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// 用于 react 生成
2+
{
3+
"include": [
4+
"./"
5+
],
6+
"exclude": [],
7+
"compilerOptions": {
8+
"target": "esnext",
9+
"module": "esnext",
10+
"outDir": "./dist",
11+
"rootDir": "./",
12+
"noImplicitThis": true,
13+
"noImplicitAny": true,
14+
"skipLibCheck": true,
15+
"strictNullChecks": true,
16+
"moduleResolution": "node",
17+
"declaration": true,
18+
"allowSyntheticDefaultImports": true,
19+
"jsx": "preserve",
20+
"lib": [
21+
"esnext",
22+
"dom",
23+
"dom.iterable"
24+
],
25+
}
26+
}

packages/webpack-plugin/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080
"scripts": {
8181
"test": "jest --passWithNoTests",
8282
"copy-icons": "cp -r ./lib/runtime/components/react/mpx-icon/icons ./lib/runtime/components/react/dist/mpx-icon/icons",
83-
"build": "rimraf ./lib/runtime/components/react/dist && tsc && npm run copy-icons"
83+
"build": "rimraf ./lib/runtime/components/react/dist && tsc -p ./lib/runtime/components/react/tsconfig.json && npm run copy-icons"
8484
},
8585
"devDependencies": {
8686
"@d11/react-native-fast-image": "^8.6.12",
@@ -99,7 +99,8 @@
9999
"react-native-video": "^6.9.0",
100100
"react-native-vision-camera": "^4.7.2",
101101
"react-native-webview": "^13.12.2",
102-
"rimraf": "^6.0.1"
102+
"rimraf": "^6.0.1",
103+
"webpack": "^5.75.0"
103104
},
104105
"engines": {
105106
"node": ">=14.14.0"
Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
1+
// 用于lib下文件的语法检查,ts 类型提示
12
{
23
"include": [
4+
"./lib",
5+
],
6+
"exclude": [
37
"./lib/runtime/components/react"
48
],
59
"compilerOptions": {
10+
"module": "nodenext",
611
"target": "esnext",
7-
"module": "esnext",
8-
"outDir": "./lib/runtime/components/react/dist",
912
"noImplicitThis": true,
1013
"noImplicitAny": true,
1114
"skipLibCheck": true,
15+
"allowJs": true,
16+
"checkJs": false,
1217
"strictNullChecks": true,
13-
"moduleResolution": "node",
14-
"declaration": true,
15-
"declarationMap": true,
18+
"moduleResolution": "nodenext",
1619
"allowSyntheticDefaultImports": true,
17-
"jsx": "preserve",
20+
"noEmit": true,
1821
"lib": [
1922
"esnext",
20-
"dom",
21-
"dom.iterable"
2223
]
2324
}
2425
}

0 commit comments

Comments
 (0)