vite-plugin-taro 0.3.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +44 -0
- package/README.md +22 -497
- package/client.d.ts +9 -0
- package/dist/node/plugins/client/client-taro.d.ts +4 -0
- package/dist/node/plugins/client/client-taro.js +19 -0
- package/dist/node/plugins/client/constant.d.ts +4 -0
- package/dist/node/plugins/client/constant.js +4 -0
- package/dist/node/plugins/conditional/conditional-directives.d.ts +4 -0
- package/dist/node/plugins/{conditional-directives.js → conditional/conditional-directives.js} +27 -11
- package/dist/node/plugins/css/plugins.d.ts +4 -0
- package/dist/node/plugins/css/plugins.js +84 -0
- package/dist/node/plugins/h5/constant.d.ts +2 -0
- package/dist/node/plugins/h5/constant.js +3 -0
- package/dist/node/plugins/h5/plugins.d.ts +4 -0
- package/dist/node/plugins/h5/plugins.js +161 -0
- package/dist/node/plugins/h5/resolver/module-resolver.d.ts +14 -0
- package/dist/node/plugins/h5/resolver/module-resolver.js +19 -0
- package/dist/node/plugins/h5/transform-app.d.ts +10 -0
- package/dist/node/plugins/h5/transform-app.js +48 -0
- package/dist/node/plugins/wx/dev/dev-host.d.ts +15 -0
- package/dist/node/plugins/wx/dev/dev-host.js +352 -0
- package/dist/node/plugins/wx/dev/hmr-files.d.ts +28 -0
- package/dist/node/plugins/wx/dev/hmr-files.js +34 -0
- package/dist/node/plugins/wx/dev/patch-publisher.d.ts +22 -0
- package/dist/node/plugins/wx/dev/patch-publisher.js +40 -0
- package/dist/node/plugins/wx/dev/plugin.d.ts +7 -0
- package/dist/node/plugins/wx/dev/plugin.js +73 -0
- package/dist/node/plugins/wx/dev/react-refresh.d.ts +20 -0
- package/dist/node/plugins/wx/dev/react-refresh.js +198 -0
- package/dist/node/plugins/wx/module.d.ts +45 -0
- package/dist/node/plugins/wx/module.js +66 -0
- package/dist/node/plugins/wx/native/compile-native-component-interface.d.ts +21 -0
- package/dist/node/plugins/wx/native/compile-native-component-interface.js +29 -0
- package/dist/node/plugins/wx/native/create-native-component-output.d.ts +15 -0
- package/dist/node/plugins/wx/native/create-native-component-output.js +39 -0
- package/dist/node/plugins/wx/native/native-component-assets.d.ts +26 -0
- package/dist/node/plugins/wx/native/native-component-assets.js +76 -0
- package/dist/node/plugins/wx/native/native-component-interface.d.ts +12 -0
- package/dist/node/plugins/wx/native/native-component-interface.js +201 -0
- package/dist/node/plugins/wx/output/files.d.ts +12 -0
- package/dist/node/plugins/wx/output/files.js +12 -0
- package/dist/node/plugins/wx/output/json.d.ts +14 -0
- package/dist/node/plugins/wx/output/json.js +52 -0
- package/dist/node/plugins/wx/output/relative-root.d.ts +2 -0
- package/dist/node/plugins/wx/output/relative-root.js +6 -0
- package/dist/node/plugins/wx/output/templates.d.ts +7 -0
- package/dist/node/plugins/wx/output/templates.js +100 -0
- package/dist/node/plugins/wx/placement/placer.d.ts +78 -0
- package/dist/node/plugins/wx/placement/placer.js +145 -0
- package/dist/node/plugins/wx/placement/plan.d.ts +46 -0
- package/dist/node/plugins/wx/placement/plan.js +210 -0
- package/dist/node/plugins/wx/plugins.d.ts +4 -0
- package/dist/node/plugins/wx/plugins.js +137 -0
- package/dist/node/plugins/wx/render/capsule-wrapper.d.ts +3 -0
- package/dist/node/plugins/wx/render/capsule-wrapper.js +64 -0
- package/dist/node/plugins/wx/render/capsule.d.ts +4 -0
- package/dist/node/plugins/wx/render/capsule.js +13 -0
- package/dist/node/plugins/wx/render/native.d.ts +9 -0
- package/dist/node/plugins/wx/render/native.js +45 -0
- package/dist/node/plugins/wx/render/transport.d.ts +17 -0
- package/dist/node/plugins/wx/render/transport.js +94 -0
- package/dist/node/plugins/wx/resolve/resolver.d.ts +7 -0
- package/dist/node/plugins/wx/resolve/resolver.js +86 -0
- package/dist/node/plugins/wx/resolve/specialize-bootstrap.d.ts +9 -0
- package/dist/node/plugins/wx/resolve/specialize-bootstrap.js +9 -0
- package/dist/node/plugins/wx/resolve/specialize-page-capsule.d.ts +9 -0
- package/dist/node/plugins/wx/resolve/specialize-page-capsule.js +11 -0
- package/dist/node/utils/constant.d.ts +1 -0
- package/dist/node/utils/constant.js +1 -0
- package/dist/node/utils/memoize.d.ts +122 -0
- package/dist/node/utils/memoize.js +86 -0
- package/dist/node/utils/modules.d.ts +20 -24
- package/dist/node/utils/modules.js +21 -34
- package/dist/node/utils/once.d.ts +10 -0
- package/dist/node/utils/once.js +20 -0
- package/dist/node/utils/packages.d.ts +1 -0
- package/dist/node/utils/packages.js +1 -1
- package/dist/node/utils/project-config.d.ts +3 -0
- package/dist/node/utils/project-config.js +8 -0
- package/dist/node/utils/serialized-task-queue.d.ts +9 -0
- package/dist/node/utils/serialized-task-queue.js +17 -0
- package/dist/node/utils/transform.d.ts +11 -0
- package/dist/node/utils/transform.js +58 -0
- package/dist/node/vite-plugin.d.ts +1 -1
- package/dist/node/vite-plugin.js +11 -27
- package/dist/options.d.ts +3 -4
- package/dist/runtime/{taro → client/taro}/api.d.ts +0 -1
- package/dist/runtime/client/taro/api.js +9 -0
- package/dist/runtime/client/taro/component.d.ts +1 -0
- package/dist/runtime/client/taro/component.js +1 -0
- package/dist/runtime/client/taro/define-native-component.d.ts +7 -0
- package/dist/runtime/client/taro/define-native-component.js +4 -0
- package/dist/runtime/h5/app.d.ts +2 -0
- package/dist/runtime/h5/app.js +15 -0
- package/dist/runtime/h5/taro-runtime.d.ts +1 -1
- package/dist/runtime/h5/taro-runtime.js +1 -4
- package/dist/runtime/wx/amphibious/bootstrap.d.ts +4 -0
- package/dist/runtime/wx/amphibious/bootstrap.js +16 -0
- package/dist/runtime/wx/amphibious/transport.d.ts +2 -0
- package/dist/runtime/wx/amphibious/transport.js +4 -0
- package/dist/runtime/wx/capsule/app.d.ts +2 -0
- package/dist/runtime/wx/capsule/app.js +7 -0
- package/dist/runtime/wx/capsule/component.d.ts +3 -0
- package/dist/runtime/wx/capsule/component.js +4 -0
- package/dist/runtime/wx/capsule/page.d.ts +3 -0
- package/dist/runtime/wx/capsule/page.js +68 -0
- package/dist/runtime/wx/capsule/taro-runtime.d.ts +6 -0
- package/dist/runtime/wx/capsule/taro-runtime.js +6 -0
- package/dist/runtime/wx/dev/dev-runtime.d.ts +1 -0
- package/dist/runtime/wx/dev/dev-runtime.js +246 -0
- package/dist/runtime/wx/native/app.d.ts +1 -0
- package/dist/runtime/wx/native/app.js +3 -0
- package/dist/runtime/wx/native/component.d.ts +1 -0
- package/dist/runtime/wx/native/component.js +3 -0
- package/dist/runtime/wx/native/page.d.ts +1 -0
- package/dist/runtime/wx/native/page.js +4 -0
- package/dist/runtime/wx/systemjs/system-core.d.ts +4 -0
- package/dist/runtime/wx/systemjs/system-core.js +331 -0
- package/package.json +21 -14
- package/src/node/plugins/client/client-taro.ts +23 -0
- package/src/node/plugins/client/constant.ts +5 -0
- package/src/node/plugins/{conditional-directives.ts → conditional/conditional-directives.ts} +33 -13
- package/src/node/plugins/css/plugins.ts +96 -0
- package/src/node/plugins/h5/constant.ts +4 -0
- package/src/node/plugins/h5/plugins.ts +197 -0
- package/src/node/plugins/h5/resolver/module-resolver.ts +32 -0
- package/src/node/plugins/h5/transform-app.ts +90 -0
- package/src/node/plugins/wx/dev/dev-host.ts +448 -0
- package/src/node/plugins/wx/dev/hmr-files.ts +55 -0
- package/src/node/plugins/wx/dev/patch-publisher.ts +49 -0
- package/src/node/plugins/wx/dev/plugin.ts +82 -0
- package/src/node/plugins/wx/dev/react-refresh.ts +227 -0
- package/src/node/plugins/wx/module.ts +97 -0
- package/src/node/plugins/wx/native/compile-native-component-interface.ts +47 -0
- package/src/node/plugins/wx/native/create-native-component-output.ts +57 -0
- package/src/node/plugins/wx/native/native-component-assets.ts +114 -0
- package/src/node/plugins/wx/native/native-component-interface.ts +265 -0
- package/src/node/plugins/wx/output/files.ts +27 -0
- package/src/node/plugins/wx/output/json.ts +79 -0
- package/src/node/plugins/wx/output/relative-root.ts +7 -0
- package/src/node/plugins/wx/output/templates.ts +141 -0
- package/src/node/plugins/wx/placement/placer.ts +172 -0
- package/src/node/plugins/wx/placement/plan.ts +306 -0
- package/src/node/plugins/wx/plugins.ts +165 -0
- package/src/node/plugins/wx/render/capsule-wrapper.ts +86 -0
- package/src/node/plugins/wx/render/capsule.ts +21 -0
- package/src/node/plugins/wx/render/native.ts +84 -0
- package/src/node/plugins/wx/render/transport.ts +157 -0
- package/src/node/plugins/wx/resolve/resolver.ts +125 -0
- package/src/node/plugins/wx/resolve/specialize-bootstrap.ts +27 -0
- package/src/node/plugins/wx/resolve/specialize-page-capsule.ts +29 -0
- package/src/node/utils/constant.ts +1 -0
- package/src/node/utils/memoize.ts +149 -0
- package/src/node/utils/modules.ts +36 -38
- package/src/node/utils/once.ts +21 -0
- package/src/node/utils/packages.ts +1 -1
- package/src/node/utils/project-config.ts +10 -0
- package/src/node/utils/serialized-task-queue.ts +20 -0
- package/src/node/utils/transform.ts +82 -0
- package/src/node/vite-plugin.ts +12 -32
- package/src/options.ts +3 -4
- package/src/runtime/client/taro/api.ts +11 -0
- package/src/runtime/client/taro/component.ts +1 -0
- package/src/runtime/client/taro/define-native-component.ts +15 -0
- package/src/runtime/h5/app.ts +25 -0
- package/src/runtime/h5/taro-runtime.ts +1 -4
- package/src/runtime/wx/amphibious/bootstrap.ts +22 -0
- package/src/runtime/wx/amphibious/transport.ts +10 -0
- package/src/runtime/wx/capsule/app.ts +9 -0
- package/src/runtime/wx/capsule/component.ts +6 -0
- package/src/runtime/wx/capsule/page.ts +96 -0
- package/src/runtime/wx/capsule/taro-runtime.ts +14 -0
- package/src/runtime/wx/dev/dev-runtime.ts +317 -0
- package/src/runtime/wx/native/app.ts +4 -0
- package/src/runtime/wx/native/component.ts +4 -0
- package/src/runtime/wx/native/page.ts +6 -0
- package/src/runtime/wx/systemjs/LICENSE +10 -0
- package/src/runtime/wx/systemjs/system-core.js +370 -0
- package/src/runtime/wx/systemjs/system.d.ts +55 -0
- package/src/runtime/wx/wechat.d.ts +52 -0
- package/README.zh.md +0 -521
- package/dist/node/build-context.d.ts +0 -25
- package/dist/node/build-context.js +0 -47
- package/dist/node/css/css-pipeline.d.ts +0 -35
- package/dist/node/css/css-pipeline.js +0 -154
- package/dist/node/plugins/conditional-directives.d.ts +0 -3
- package/dist/node/plugins/taro-runtime.d.ts +0 -5
- package/dist/node/plugins/taro-runtime.js +0 -18
- package/dist/node/targets/h5/plugin.d.ts +0 -6
- package/dist/node/targets/h5/plugin.js +0 -117
- package/dist/node/targets/h5/virtual-modules.d.ts +0 -5
- package/dist/node/targets/h5/virtual-modules.js +0 -60
- package/dist/node/targets/wx/companion-assets.d.ts +0 -19
- package/dist/node/targets/wx/companion-assets.js +0 -129
- package/dist/node/targets/wx/dev-server/development-session.d.ts +0 -32
- package/dist/node/targets/wx/dev-server/development-session.js +0 -215
- package/dist/node/targets/wx/dev-server/full-build-scheduler.d.ts +0 -14
- package/dist/node/targets/wx/dev-server/full-build-scheduler.js +0 -60
- package/dist/node/targets/wx/dev-server/js-utils.d.ts +0 -5
- package/dist/node/targets/wx/dev-server/js-utils.js +0 -28
- package/dist/node/targets/wx/dev-server/output.d.ts +0 -19
- package/dist/node/targets/wx/dev-server/output.js +0 -44
- package/dist/node/targets/wx/dev-server/rolldown-runtime-source.d.ts +0 -8
- package/dist/node/targets/wx/dev-server/rolldown-runtime-source.js +0 -95
- package/dist/node/targets/wx/dev-server/update-server-state.d.ts +0 -65
- package/dist/node/targets/wx/dev-server/update-server-state.js +0 -116
- package/dist/node/targets/wx/dev-server/update-transport.d.ts +0 -28
- package/dist/node/targets/wx/dev-server/update-transport.js +0 -212
- package/dist/node/targets/wx/dev-server/vite-bundled-dev-adapter.d.ts +0 -44
- package/dist/node/targets/wx/dev-server/vite-bundled-dev-adapter.js +0 -145
- package/dist/node/targets/wx/development-files.d.ts +0 -8
- package/dist/node/targets/wx/development-files.js +0 -8
- package/dist/node/targets/wx/plugin.d.ts +0 -6
- package/dist/node/targets/wx/plugin.js +0 -144
- package/dist/node/targets/wx/react-refresh.d.ts +0 -4
- package/dist/node/targets/wx/react-refresh.js +0 -38
- package/dist/node/targets/wx/virtual-modules.d.ts +0 -16
- package/dist/node/targets/wx/virtual-modules.js +0 -120
- package/dist/node/utils/async.d.ts +0 -8
- package/dist/node/utils/async.js +0 -16
- package/dist/node/utils/filesystem.d.ts +0 -13
- package/dist/node/utils/filesystem.js +0 -43
- package/dist/runtime/taro/api.js +0 -11
- package/dist/runtime/taro/components.d.ts +0 -2
- package/dist/runtime/taro/components.js +0 -2
- package/dist/runtime/wx/page-update.d.ts +0 -6
- package/dist/runtime/wx/page-update.js +0 -157
- package/dist/runtime/wx/taro-runtime.d.ts +0 -5
- package/dist/runtime/wx/taro-runtime.js +0 -6
- package/dist/runtime/wx/update-client-state.d.ts +0 -68
- package/dist/runtime/wx/update-client-state.js +0 -84
- package/dist/runtime/wx/update-client.d.ts +0 -1
- package/dist/runtime/wx/update-client.js +0 -171
- package/src/node/build-context.ts +0 -62
- package/src/node/css/css-pipeline.ts +0 -171
- package/src/node/plugins/taro-runtime.ts +0 -22
- package/src/node/targets/h5/plugin.ts +0 -135
- package/src/node/targets/h5/virtual-modules.ts +0 -71
- package/src/node/targets/wx/companion-assets.ts +0 -174
- package/src/node/targets/wx/dev-server/development-session.ts +0 -271
- package/src/node/targets/wx/dev-server/full-build-scheduler.ts +0 -62
- package/src/node/targets/wx/dev-server/js-utils.ts +0 -33
- package/src/node/targets/wx/dev-server/output.ts +0 -56
- package/src/node/targets/wx/dev-server/rolldown-runtime-source.ts +0 -95
- package/src/node/targets/wx/dev-server/update-server-state.ts +0 -183
- package/src/node/targets/wx/dev-server/update-transport.ts +0 -261
- package/src/node/targets/wx/dev-server/vite-bundled-dev-adapter.ts +0 -203
- package/src/node/targets/wx/development-files.ts +0 -11
- package/src/node/targets/wx/plugin.ts +0 -164
- package/src/node/targets/wx/react-refresh.ts +0 -51
- package/src/node/targets/wx/virtual-modules.ts +0 -152
- package/src/node/utils/async.ts +0 -19
- package/src/node/utils/filesystem.ts +0 -45
- package/src/runtime/taro/api.ts +0 -13
- package/src/runtime/taro/components.ts +0 -2
- package/src/runtime/wx/page-update.ts +0 -230
- package/src/runtime/wx/react-refresh.d.ts +0 -20
- package/src/runtime/wx/taro-runtime.ts +0 -7
- package/src/runtime/wx/update-client-state.ts +0 -138
- package/src/runtime/wx/update-client.ts +0 -223
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import path from 'node:path'
|
|
2
|
+
import type { ExistingRawSourceMap } from 'rolldown'
|
|
3
|
+
import { RolldownMagicString } from 'rolldown'
|
|
4
|
+
import { parseAst } from 'rolldown/parseAst'
|
|
5
|
+
import type { ESTree } from 'rolldown/utils'
|
|
6
|
+
import { normalizeModuleId } from '../../../utils/modules.ts'
|
|
7
|
+
import { clientTaroNativeId } from '../../client/constant.ts'
|
|
8
|
+
|
|
9
|
+
export type NativeComponentDefinition = {
|
|
10
|
+
folder: string
|
|
11
|
+
entry: string
|
|
12
|
+
fields: readonly string[]
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
type NativeComponentMacroImport = {
|
|
16
|
+
declaration: ESTree.ImportDeclaration
|
|
17
|
+
names: readonly string[]
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Replaces native component interface calls with source-folder names and returns their static metadata. */
|
|
21
|
+
export function transformNativeComponentInterfaces(code: string, id: string, sourcemap: boolean) {
|
|
22
|
+
const moduleId = normalizeModuleId(id)
|
|
23
|
+
const program = parseAst(
|
|
24
|
+
code,
|
|
25
|
+
{
|
|
26
|
+
astType: 'ts',
|
|
27
|
+
lang: 'tsx',
|
|
28
|
+
preserveParens: false,
|
|
29
|
+
sourceType: 'module'
|
|
30
|
+
},
|
|
31
|
+
moduleId
|
|
32
|
+
)
|
|
33
|
+
const declaredInterfaces = collectInterfaceDeclarations(program)
|
|
34
|
+
const macroImports = collectMacroImports(program)
|
|
35
|
+
const importedMacroNames: ReadonlySet<string> = new Set(macroImports.flatMap((item) => item.names))
|
|
36
|
+
const calls = collectTopLevelMacroCalls(program, importedMacroNames)
|
|
37
|
+
const replacements = calls.map((call) => {
|
|
38
|
+
const definition = parseDefinition(call, moduleId, declaredInterfaces, (message) =>
|
|
39
|
+
createTransformError(message, moduleId, code, call.start)
|
|
40
|
+
)
|
|
41
|
+
return { call, definition }
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
// This transform-local mutable buffer applies non-overlapping AST edits without regenerating untouched source.
|
|
45
|
+
const transformed = new RolldownMagicString(code, { filename: moduleId })
|
|
46
|
+
replacements.forEach(({ call, definition }) => {
|
|
47
|
+
transformed.overwrite(call.start, call.end, JSON.stringify(path.posix.basename(definition.folder)))
|
|
48
|
+
})
|
|
49
|
+
macroImports.forEach(({ declaration }) => {
|
|
50
|
+
transformed.remove(declaration.start, declaration.end)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
code: transformed.toString(),
|
|
55
|
+
map: sourcemap ? createSourceMap(transformed, moduleId) : null,
|
|
56
|
+
definitions: replacements.map(({ definition }) => definition)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Normalizes Rolldown's native source-map object to the public plugin source-map shape. */
|
|
61
|
+
function createSourceMap(transformed: RolldownMagicString, moduleId: string): ExistingRawSourceMap {
|
|
62
|
+
const sourceMap = transformed.generateMap({
|
|
63
|
+
hires: 'boundary',
|
|
64
|
+
includeContent: true,
|
|
65
|
+
source: moduleId
|
|
66
|
+
})
|
|
67
|
+
return {
|
|
68
|
+
file: sourceMap.file,
|
|
69
|
+
mappings: sourceMap.mappings,
|
|
70
|
+
names: sourceMap.names,
|
|
71
|
+
sources: sourceMap.sources,
|
|
72
|
+
sourcesContent: sourceMap.sourcesContent,
|
|
73
|
+
version: sourceMap.version
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Finds named imports of the compile-time macro and records their local aliases. */
|
|
78
|
+
function collectMacroImports(program: ESTree.Program): NativeComponentMacroImport[] {
|
|
79
|
+
return program.body.flatMap((statement) => {
|
|
80
|
+
if (statement.type !== 'ImportDeclaration' || statement.source.value !== clientTaroNativeId) {
|
|
81
|
+
return []
|
|
82
|
+
}
|
|
83
|
+
const names = statement.specifiers.flatMap((specifier) => {
|
|
84
|
+
if (specifier.type !== 'ImportSpecifier' || getStaticName(specifier.imported) !== 'defineNativeComponent') {
|
|
85
|
+
return []
|
|
86
|
+
}
|
|
87
|
+
return [specifier.local.name]
|
|
88
|
+
})
|
|
89
|
+
return names.length === 0 ? [] : [{ declaration: statement, names }]
|
|
90
|
+
})
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Collects direct module-level macro calls, excluding calls inside nested scopes. */
|
|
94
|
+
function collectTopLevelMacroCalls(
|
|
95
|
+
program: ESTree.Program,
|
|
96
|
+
importedMacroNames: ReadonlySet<string>
|
|
97
|
+
): ESTree.CallExpression[] {
|
|
98
|
+
return program.body.flatMap((statement) => {
|
|
99
|
+
if (statement.type === 'ExpressionStatement') {
|
|
100
|
+
return isImportedMacroCall(statement.expression, importedMacroNames) ? [statement.expression] : []
|
|
101
|
+
}
|
|
102
|
+
if (statement.type === 'ExportDefaultDeclaration') {
|
|
103
|
+
return isImportedMacroCall(statement.declaration, importedMacroNames) ? [statement.declaration] : []
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const declaration = statement.type === 'ExportNamedDeclaration' ? statement.declaration : statement
|
|
107
|
+
if (declaration?.type !== 'VariableDeclaration') {
|
|
108
|
+
return []
|
|
109
|
+
}
|
|
110
|
+
return declaration.declarations.flatMap(({ init }) => {
|
|
111
|
+
return isImportedMacroCall(init, importedMacroNames) ? [init] : []
|
|
112
|
+
})
|
|
113
|
+
})
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** Matches a direct call to one of the macro's module-level import bindings. */
|
|
117
|
+
function isImportedMacroCall(
|
|
118
|
+
node: ESTree.Expression | ESTree.Declaration | null | undefined,
|
|
119
|
+
importedMacroNames: ReadonlySet<string>
|
|
120
|
+
): node is ESTree.CallExpression {
|
|
121
|
+
return (
|
|
122
|
+
node?.type === 'CallExpression' && node.callee.type === 'Identifier' && importedMacroNames.has(node.callee.name)
|
|
123
|
+
)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** Parses one native entry loader and its optional TypeScript interface. */
|
|
127
|
+
function parseDefinition(
|
|
128
|
+
call: ESTree.CallExpression,
|
|
129
|
+
moduleId: string,
|
|
130
|
+
declaredInterfaces: ReadonlyMap<string, readonly ESTree.TSSignature[]>,
|
|
131
|
+
buildError: (message: string) => Error
|
|
132
|
+
): NativeComponentDefinition {
|
|
133
|
+
if (call.arguments.length !== 1) {
|
|
134
|
+
throw buildError('defineNativeComponent() requires exactly one entry loader')
|
|
135
|
+
}
|
|
136
|
+
const entryReference = readStaticEntryImport(call.arguments[0])
|
|
137
|
+
if (!entryReference) {
|
|
138
|
+
throw buildError('Native component entry must use () => import(...) with a static relative .js path')
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const entryPath = normalizeModuleId(path.resolve(path.dirname(moduleId), entryReference))
|
|
142
|
+
return {
|
|
143
|
+
folder: path.posix.dirname(entryPath),
|
|
144
|
+
entry: path.posix.basename(entryPath, '.js'),
|
|
145
|
+
fields: readInterfaceFields(call.typeArguments, declaredInterfaces, buildError)
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/** Collects non-generic local object aliases and interfaces as native template field declarations. */
|
|
150
|
+
function collectInterfaceDeclarations(program: ESTree.Program): ReadonlyMap<string, readonly ESTree.TSSignature[]> {
|
|
151
|
+
// This module-local map supports nearby declarations without constructing a TypeScript type-checker program.
|
|
152
|
+
const declarations = new Map<string, readonly ESTree.TSSignature[]>()
|
|
153
|
+
for (const statement of program.body) {
|
|
154
|
+
const declaration = statement.type === 'ExportNamedDeclaration' ? statement.declaration : statement
|
|
155
|
+
if (
|
|
156
|
+
declaration?.type === 'TSTypeAliasDeclaration' &&
|
|
157
|
+
!declaration.typeParameters &&
|
|
158
|
+
declaration.typeAnnotation.type === 'TSTypeLiteral'
|
|
159
|
+
) {
|
|
160
|
+
declarations.set(declaration.id.name, declaration.typeAnnotation.members)
|
|
161
|
+
continue
|
|
162
|
+
}
|
|
163
|
+
if (
|
|
164
|
+
declaration?.type === 'TSInterfaceDeclaration' &&
|
|
165
|
+
!declaration.typeParameters &&
|
|
166
|
+
declaration.extends.length === 0
|
|
167
|
+
) {
|
|
168
|
+
declarations.set(declaration.id.name, declaration.body.body)
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return declarations
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** Resolves an inline type or a non-generic object declaration from the current module. */
|
|
175
|
+
function resolveInterfaceMembers(
|
|
176
|
+
typeNode: ESTree.TSType,
|
|
177
|
+
declarations: ReadonlyMap<string, readonly ESTree.TSSignature[]>
|
|
178
|
+
): readonly ESTree.TSSignature[] | undefined {
|
|
179
|
+
if (typeNode.type === 'TSTypeLiteral') {
|
|
180
|
+
return typeNode.members
|
|
181
|
+
}
|
|
182
|
+
if (typeNode.type === 'TSTypeReference' && typeNode.typeName.type === 'Identifier' && !typeNode.typeArguments) {
|
|
183
|
+
return declarations.get(typeNode.typeName.name)
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/** Reads native template field names without resolving or validating their TypeScript value types. */
|
|
188
|
+
function readInterfaceFields(
|
|
189
|
+
typeArguments: ESTree.TSTypeParameterInstantiation | null | undefined,
|
|
190
|
+
declaredInterfaces: ReadonlyMap<string, readonly ESTree.TSSignature[]>,
|
|
191
|
+
buildError: (message: string) => Error
|
|
192
|
+
): string[] {
|
|
193
|
+
if (!typeArguments) {
|
|
194
|
+
return []
|
|
195
|
+
}
|
|
196
|
+
if (typeArguments.params.length !== 1) {
|
|
197
|
+
throw buildError('Native component interface must be one TypeScript object type')
|
|
198
|
+
}
|
|
199
|
+
const firstType = typeArguments.params[0]
|
|
200
|
+
const members = firstType ? resolveInterfaceMembers(firstType, declaredInterfaces) : undefined
|
|
201
|
+
if (!members) {
|
|
202
|
+
throw buildError('Native component interface must be inline or declared in the same module')
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// This local set preserves declaration order while rejecting ambiguous duplicate template fields.
|
|
206
|
+
const names = new Set<string>()
|
|
207
|
+
for (const member of members) {
|
|
208
|
+
if (member.type !== 'TSPropertySignature' && member.type !== 'TSMethodSignature') {
|
|
209
|
+
throw buildError('Native component interface must contain only static fields')
|
|
210
|
+
}
|
|
211
|
+
if (member.computed) {
|
|
212
|
+
throw buildError('Native component interface contains a computed field')
|
|
213
|
+
}
|
|
214
|
+
const name = getStaticName(member.key)
|
|
215
|
+
if (!name) {
|
|
216
|
+
throw buildError('Native component interface contains a computed field')
|
|
217
|
+
}
|
|
218
|
+
if (names.has(name)) {
|
|
219
|
+
throw buildError(`Duplicate native component interface field: ${name}`)
|
|
220
|
+
}
|
|
221
|
+
names.add(name)
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return [...names].filter((name) => name !== 'children')
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/** Reads an identifier or string-literal key. */
|
|
228
|
+
function getStaticName(node: ESTree.Node): string | undefined {
|
|
229
|
+
if (node.type === 'Identifier') {
|
|
230
|
+
return node.name
|
|
231
|
+
}
|
|
232
|
+
if (node.type === 'Literal' && typeof node.value === 'string') {
|
|
233
|
+
return node.value
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/** Reads a zero-argument entry loader containing one statically resolvable native `.js` import. */
|
|
238
|
+
function readStaticEntryImport(node: ESTree.Argument | null | undefined): string | undefined {
|
|
239
|
+
if (node?.type !== 'ArrowFunctionExpression' || node.params.length !== 0 || node.body.type !== 'ImportExpression') {
|
|
240
|
+
return undefined
|
|
241
|
+
}
|
|
242
|
+
const importExpression = node.body
|
|
243
|
+
if (
|
|
244
|
+
importExpression.source.type !== 'Literal' ||
|
|
245
|
+
typeof importExpression.source.value !== 'string' ||
|
|
246
|
+
importExpression.options !== null ||
|
|
247
|
+
!isLocalJavaScriptEntry(importExpression.source.value)
|
|
248
|
+
) {
|
|
249
|
+
return undefined
|
|
250
|
+
}
|
|
251
|
+
return importExpression.source.value
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/** Limits component entries to JavaScript files reachable from their interface module. */
|
|
255
|
+
function isLocalJavaScriptEntry(entry: string): boolean {
|
|
256
|
+
return (entry.startsWith('./') || entry.startsWith('../')) && path.posix.extname(entry) === '.js'
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/** Adds a stable source location to semantic errors reported after parsing. */
|
|
260
|
+
function createTransformError(message: string, moduleId: string, code: string, offset: number): Error {
|
|
261
|
+
const prefix = code.slice(0, offset)
|
|
262
|
+
const line = prefix.split('\n').length
|
|
263
|
+
const column = offset - prefix.lastIndexOf('\n')
|
|
264
|
+
return new Error(`${message}\n${moduleId}:${line}:${column}`)
|
|
265
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Rolldown } from 'vite'
|
|
2
|
+
import type { VitePluginTaroOptions } from '../../../../options.ts'
|
|
3
|
+
import { createNativeComponentOutput } from '../native/create-native-component-output.ts'
|
|
4
|
+
import type { GeneratedSubpackage } from '../placement/placer.ts'
|
|
5
|
+
import { createJsonAssets } from './json.ts'
|
|
6
|
+
import { createTemplateAssets } from './templates.ts'
|
|
7
|
+
|
|
8
|
+
/** Creates every native companion file derived from the final Rolldown bundle. */
|
|
9
|
+
export async function createOutputFiles({
|
|
10
|
+
bundle,
|
|
11
|
+
options,
|
|
12
|
+
subpackages,
|
|
13
|
+
getModuleInfo
|
|
14
|
+
}: {
|
|
15
|
+
bundle: Rolldown.OutputBundle
|
|
16
|
+
options: VitePluginTaroOptions
|
|
17
|
+
subpackages: readonly GeneratedSubpackage[]
|
|
18
|
+
getModuleInfo: (moduleId: string) => { meta: Rolldown.CustomPluginOptions } | null
|
|
19
|
+
}): Promise<Rolldown.EmittedFile[]> {
|
|
20
|
+
const nativeOutput = await createNativeComponentOutput({ bundle, getModuleInfo })
|
|
21
|
+
|
|
22
|
+
return [
|
|
23
|
+
...createJsonAssets({ options, subpackages, nativeComponents: nativeOutput.registrations }),
|
|
24
|
+
...createTemplateAssets(bundle, options, nativeOutput.registrations),
|
|
25
|
+
...nativeOutput.files
|
|
26
|
+
]
|
|
27
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { Rolldown } from 'vite'
|
|
2
|
+
import type { JsonObject, VitePluginTaroOptions, VitePluginTaroPageOption } from '../../../../options.ts'
|
|
3
|
+
import { createAppConfig } from '../../../utils/project-config.ts'
|
|
4
|
+
import type { GeneratedSubpackage } from '../placement/placer.ts'
|
|
5
|
+
import { isGeneratedSubpackageFile } from '../placement/plan.ts'
|
|
6
|
+
import { toRootRelativePath } from './relative-root.ts'
|
|
7
|
+
|
|
8
|
+
/** Creates every configured native JSON asset. */
|
|
9
|
+
export function createJsonAssets({
|
|
10
|
+
options,
|
|
11
|
+
subpackages,
|
|
12
|
+
nativeComponents
|
|
13
|
+
}: {
|
|
14
|
+
options: VitePluginTaroOptions
|
|
15
|
+
subpackages: readonly GeneratedSubpackage[]
|
|
16
|
+
nativeComponents: readonly { name: string; componentPath: string }[]
|
|
17
|
+
}): Rolldown.EmittedAsset[] {
|
|
18
|
+
return [
|
|
19
|
+
createJsonAsset('app.json', {
|
|
20
|
+
...createAppConfig(options),
|
|
21
|
+
...(subpackages.length > 0 ? { subPackages: subpackages } : {})
|
|
22
|
+
}),
|
|
23
|
+
|
|
24
|
+
...options.pages.map((page) => createJsonAsset(`${page.path}.json`, createPageJson(page, nativeComponents))),
|
|
25
|
+
|
|
26
|
+
createJsonAsset('project.config.json', options.projectConfigJson),
|
|
27
|
+
|
|
28
|
+
...(options.projectPrivateConfigJson
|
|
29
|
+
? [createJsonAsset('project.private.config.json', options.projectPrivateConfigJson)]
|
|
30
|
+
: []),
|
|
31
|
+
|
|
32
|
+
createJsonAsset('sitemap.json', options.sitemapJson)
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Creates Page JSON with generated Taro and native component registrations. */
|
|
37
|
+
function createPageJson(
|
|
38
|
+
page: VitePluginTaroPageOption,
|
|
39
|
+
nativeComponents: readonly { name: string; componentPath: string }[]
|
|
40
|
+
): JsonObject {
|
|
41
|
+
const usingComponents = isJsonObject(page.config.usingComponents) ? page.config.usingComponents : {}
|
|
42
|
+
|
|
43
|
+
// Cross-package components require a placeholder while WeChat downloads their generated subpackage. Paths are
|
|
44
|
+
// root-absolute, so remove the leading slash before testing the output-relative subpackage prefix.
|
|
45
|
+
// https://developers.weixin.qq.com/miniprogram/dev/framework/subpackages/async.html
|
|
46
|
+
// https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/placeholder.html
|
|
47
|
+
const placeholderEntries = nativeComponents.flatMap(({ name, componentPath }) =>
|
|
48
|
+
isGeneratedSubpackageFile(componentPath.slice(1)) ? ([[name, 'view']] as const) : []
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
...page.config,
|
|
53
|
+
...(placeholderEntries.length > 0 ? { componentPlaceholder: Object.fromEntries(placeholderEntries) } : {}),
|
|
54
|
+
usingComponents: {
|
|
55
|
+
...usingComponents,
|
|
56
|
+
...Object.fromEntries(nativeComponents.map(({ name, componentPath }) => [name, componentPath])),
|
|
57
|
+
comp: toRootRelativePath(page.path, 'comp')
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Tests whether a configured JSON value can be merged as an object. */
|
|
63
|
+
function isJsonObject(value: unknown): value is JsonObject {
|
|
64
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Serializes one native JSON object with stable formatting. */
|
|
68
|
+
export function renderJson(value: JsonObject): string {
|
|
69
|
+
return `${JSON.stringify(value, null, 4)}\n`
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Creates one native JSON asset. */
|
|
73
|
+
function createJsonAsset(fileName: string, value: JsonObject): Rolldown.EmittedAsset {
|
|
74
|
+
return {
|
|
75
|
+
type: 'asset',
|
|
76
|
+
fileName,
|
|
77
|
+
source: renderJson(value)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import path from 'node:path'
|
|
2
|
+
|
|
3
|
+
/** Creates a Page-relative path to a file emitted at the wx output root. */
|
|
4
|
+
export function toRootRelativePath(pagePath: string, rootFileName: string): string {
|
|
5
|
+
const relativePath = path.posix.relative(path.posix.dirname(pagePath), rootFileName)
|
|
6
|
+
return relativePath.startsWith('.') ? relativePath : `./${relativePath}`
|
|
7
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { recursiveMerge } from '@tarojs/helper'
|
|
2
|
+
import { Weapp as WxPlatform } from '@tarojs/plugin-platform-weapp'
|
|
3
|
+
import type { Rolldown } from 'vite'
|
|
4
|
+
import type { JsonObject, VitePluginTaroOptions } from '../../../../options.ts'
|
|
5
|
+
import { normalizeModuleId } from '../../../utils/modules.ts'
|
|
6
|
+
import { packageRequire } from '../../../utils/packages.ts'
|
|
7
|
+
import { renderJson } from './json.ts'
|
|
8
|
+
import { toRootRelativePath } from './relative-root.ts'
|
|
9
|
+
|
|
10
|
+
type TemplateComponentConfig = {
|
|
11
|
+
includes: Set<string>
|
|
12
|
+
exclude: Set<string>
|
|
13
|
+
thirdPartyComponents: Map<string, Set<string>>
|
|
14
|
+
includeAll: boolean
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const taroComponentsModulePath = packageRequire.resolve('@tarojs/plugin-platform-weapp/dist/components-react')
|
|
18
|
+
|
|
19
|
+
/** Creates Taro's shared WeChat templates and native WXML/WXSS companions for every Page. */
|
|
20
|
+
export function createTemplateAssets(
|
|
21
|
+
bundle: Rolldown.OutputBundle,
|
|
22
|
+
options: VitePluginTaroOptions,
|
|
23
|
+
nativeComponents: readonly {
|
|
24
|
+
name: string
|
|
25
|
+
fields: readonly string[]
|
|
26
|
+
}[]
|
|
27
|
+
): Rolldown.EmittedAsset[] {
|
|
28
|
+
const templateBuilder = createTemplateBuilder()
|
|
29
|
+
|
|
30
|
+
return [
|
|
31
|
+
createAsset(
|
|
32
|
+
'base.wxml',
|
|
33
|
+
templateBuilder.buildTemplate(collectTemplateComponentConfig(bundle, nativeComponents))
|
|
34
|
+
),
|
|
35
|
+
createAsset('utils.wxs', templateBuilder.buildXScript()),
|
|
36
|
+
createAsset('comp.wxml', templateBuilder.buildBaseComponentTemplate('.wxml')),
|
|
37
|
+
createAsset('comp.json', renderJson(createComponentJson())),
|
|
38
|
+
...options.pages.flatMap((page) => [
|
|
39
|
+
createAsset(
|
|
40
|
+
`${page.path}.wxml`,
|
|
41
|
+
templateBuilder.buildPageTemplate(toRootRelativePath(page.path, 'base.wxml'), {
|
|
42
|
+
content: page.config,
|
|
43
|
+
path: page.path
|
|
44
|
+
})
|
|
45
|
+
),
|
|
46
|
+
createAsset(`${page.path}.wxss`, '')
|
|
47
|
+
])
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Creates the Taro WeChat template builder without invoking its Webpack integration. */
|
|
52
|
+
function createTemplateBuilder() {
|
|
53
|
+
const platform = new WxPlatform(
|
|
54
|
+
{
|
|
55
|
+
helper: {
|
|
56
|
+
recursiveMerge
|
|
57
|
+
},
|
|
58
|
+
modifyWebpackChain() {},
|
|
59
|
+
registerPlatform() {}
|
|
60
|
+
},
|
|
61
|
+
{},
|
|
62
|
+
{}
|
|
63
|
+
)
|
|
64
|
+
platform.modifyTemplate({})
|
|
65
|
+
return platform.template
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Creates template metadata from reachable Taro hosts and native component JSX fields. */
|
|
69
|
+
function collectTemplateComponentConfig(
|
|
70
|
+
bundle: Rolldown.OutputBundle,
|
|
71
|
+
nativeComponents: readonly {
|
|
72
|
+
name: string
|
|
73
|
+
fields: readonly string[]
|
|
74
|
+
}[]
|
|
75
|
+
): TemplateComponentConfig {
|
|
76
|
+
// This local config accumulates names in output order before the template builder consumes it.
|
|
77
|
+
const config: TemplateComponentConfig = {
|
|
78
|
+
includes: new Set([
|
|
79
|
+
'view',
|
|
80
|
+
'catch-view',
|
|
81
|
+
'static-view',
|
|
82
|
+
'pure-view',
|
|
83
|
+
'click-view',
|
|
84
|
+
'scroll-view',
|
|
85
|
+
'image',
|
|
86
|
+
'static-image',
|
|
87
|
+
'text',
|
|
88
|
+
'static-text'
|
|
89
|
+
]),
|
|
90
|
+
exclude: new Set(),
|
|
91
|
+
thirdPartyComponents: new Map(),
|
|
92
|
+
includeAll: false
|
|
93
|
+
}
|
|
94
|
+
const components = findBundleModule(bundle, taroComponentsModulePath)
|
|
95
|
+
for (const name of components?.renderedExports ?? []) {
|
|
96
|
+
config.includes.add(toDashed(name))
|
|
97
|
+
}
|
|
98
|
+
for (const component of nativeComponents) {
|
|
99
|
+
config.thirdPartyComponents.set(component.name, new Set(component.fields))
|
|
100
|
+
}
|
|
101
|
+
return config
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** Finds one module in the final chunk metadata. */
|
|
105
|
+
function findBundleModule(bundle: Rolldown.OutputBundle, resolvedId: string): Rolldown.RenderedModule | undefined {
|
|
106
|
+
const normalizedResolvedId = normalizeModuleId(resolvedId)
|
|
107
|
+
for (const output of Object.values(bundle)) {
|
|
108
|
+
if (output.type !== 'chunk') {
|
|
109
|
+
continue
|
|
110
|
+
}
|
|
111
|
+
const found = Object.entries(output.modules).find(([id]) => normalizeModuleId(id) === normalizedResolvedId)
|
|
112
|
+
if (found) {
|
|
113
|
+
return found[1]
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** Converts a React component export to Taro's dashed host-component name. */
|
|
119
|
+
function toDashed(value: string): string {
|
|
120
|
+
return value.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase()
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** Creates the recursive component configuration expected by Taro's templates. */
|
|
124
|
+
function createComponentJson(): JsonObject {
|
|
125
|
+
return {
|
|
126
|
+
component: true,
|
|
127
|
+
styleIsolation: 'apply-shared',
|
|
128
|
+
usingComponents: {
|
|
129
|
+
comp: './comp'
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** Creates one emitted template or style asset. */
|
|
135
|
+
function createAsset(fileName: string, source: string): Rolldown.EmittedAsset {
|
|
136
|
+
return {
|
|
137
|
+
type: 'asset',
|
|
138
|
+
fileName,
|
|
139
|
+
source
|
|
140
|
+
}
|
|
141
|
+
}
|