vite-plugin-taro 0.5.3 → 0.5.4
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/dist/node/plugins/client/client-taro.js +12 -8
- package/dist/node/plugins/h5/create-stencil-client-adapter.d.ts +24 -0
- package/dist/node/plugins/h5/create-stencil-client-adapter.js +80 -0
- package/dist/node/plugins/h5/plugins.js +11 -50
- package/package.json +12 -12
- package/src/node/plugins/client/client-taro.ts +13 -8
- package/src/node/plugins/h5/create-stencil-client-adapter.ts +109 -0
- package/src/node/plugins/h5/plugins.ts +11 -72
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { normalizeModuleId } from '../../utils/modules.js';
|
|
2
|
-
import {
|
|
2
|
+
import { resolvePackageFile } from '../../utils/packages.js';
|
|
3
3
|
import { clientTaroNativeId } from './constant.js';
|
|
4
4
|
import { injectTaroFrameworkApis } from './inject-taro-framework-apis.js';
|
|
5
5
|
/*
|
|
@@ -26,13 +26,19 @@ const clientTaroModules = new Map([
|
|
|
26
26
|
]);
|
|
27
27
|
/** Creates the shared Taro facade backed by the selected target's API implementation. */
|
|
28
28
|
export function createClientTaroPlugin(target) {
|
|
29
|
-
const
|
|
29
|
+
const platformTaroId = resolvePlatformTaroId(target);
|
|
30
30
|
return {
|
|
31
31
|
name: 'vpt:client-taro',
|
|
32
32
|
enforce: 'pre',
|
|
33
|
-
resolveId(id, importer) {
|
|
33
|
+
async resolveId(id, importer) {
|
|
34
34
|
if (id === '@tarojs/taro') {
|
|
35
|
-
|
|
35
|
+
if (!isClientTaroFacade(importer)) {
|
|
36
|
+
return clientTaroApiPath;
|
|
37
|
+
}
|
|
38
|
+
// Delegate the platform backend to Vite instead of returning an absolute dependency path. H5 marks this
|
|
39
|
+
// backend as an optimization root, so delegation lets Vite substitute its prebundled facade. Removing it
|
|
40
|
+
// bypasses CommonJS interop and exposes backend details such as base64-js directly to the browser.
|
|
41
|
+
return this.resolve(platformTaroId, importer, { skipSelf: true });
|
|
36
42
|
}
|
|
37
43
|
return clientTaroModules.get(id);
|
|
38
44
|
},
|
|
@@ -44,10 +50,8 @@ export function createClientTaroPlugin(target) {
|
|
|
44
50
|
}
|
|
45
51
|
};
|
|
46
52
|
}
|
|
47
|
-
function
|
|
48
|
-
return target === 'h5'
|
|
49
|
-
? packageRequire.resolve('@tarojs/plugin-platform-h5/dist/runtime/apis')
|
|
50
|
-
: packageRequire.resolve('@tarojs/taro');
|
|
53
|
+
function resolvePlatformTaroId(target) {
|
|
54
|
+
return target === 'h5' ? '@tarojs/plugin-platform-h5/dist/runtime/apis' : '@tarojs/taro';
|
|
51
55
|
}
|
|
52
56
|
function isClientTaroFacade(importer) {
|
|
53
57
|
return importer !== undefined && normalizeModuleId(importer) === normalizedClientTaroApiPath;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Plugin } from 'vite';
|
|
2
|
+
/**
|
|
3
|
+
* Creates the compiler-owned adaptation of Stencil's client style insertion.
|
|
4
|
+
*
|
|
5
|
+
* Taro components inject their styles through this internal client. Its default insertion point places those styles
|
|
6
|
+
* after application CSS, allowing component defaults to override application rules. The adapter is registered in both
|
|
7
|
+
* Vite's application pipeline and the independent dependency-optimization build: removing either registration leaves
|
|
8
|
+
* production or development with an unadapted client. This explicit dual registration removes the former optimization
|
|
9
|
+
* exclusion while keeping one transformation implementation.
|
|
10
|
+
*/
|
|
11
|
+
export declare function createStencilClientAdapter(): Plugin;
|
|
12
|
+
/** Applies the shared Stencil adaptation in either the application or dependency-optimization pipeline. */
|
|
13
|
+
export declare function adaptStencilClient(code: string, id: string): Promise<{
|
|
14
|
+
code: string;
|
|
15
|
+
map: {
|
|
16
|
+
version: number;
|
|
17
|
+
sources: string[];
|
|
18
|
+
names: string[];
|
|
19
|
+
sourceRoot?: string | undefined;
|
|
20
|
+
sourcesContent?: string[] | undefined;
|
|
21
|
+
mappings: string;
|
|
22
|
+
file: string;
|
|
23
|
+
} | null | undefined;
|
|
24
|
+
} | undefined>;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { transformAsync, types } from '@babel/core';
|
|
2
|
+
import { normalizeModuleId } from '../../utils/modules.js';
|
|
3
|
+
import { packageRequire } from '../../utils/packages.js';
|
|
4
|
+
const stencilClientPath = packageRequire.resolve('@stencil/core/internal/client', {
|
|
5
|
+
paths: [packageRequire.resolve('@tarojs/components/package.json')]
|
|
6
|
+
});
|
|
7
|
+
const normalizedStencilClientPath = normalizeModuleId(stencilClientPath);
|
|
8
|
+
/**
|
|
9
|
+
* Creates the compiler-owned adaptation of Stencil's client style insertion.
|
|
10
|
+
*
|
|
11
|
+
* Taro components inject their styles through this internal client. Its default insertion point places those styles
|
|
12
|
+
* after application CSS, allowing component defaults to override application rules. The adapter is registered in both
|
|
13
|
+
* Vite's application pipeline and the independent dependency-optimization build: removing either registration leaves
|
|
14
|
+
* production or development with an unadapted client. This explicit dual registration removes the former optimization
|
|
15
|
+
* exclusion while keeping one transformation implementation.
|
|
16
|
+
*/
|
|
17
|
+
export function createStencilClientAdapter() {
|
|
18
|
+
return {
|
|
19
|
+
name: 'vpt:h5-stencil-client',
|
|
20
|
+
transform: adaptStencilClient
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/** Applies the shared Stencil adaptation in either the application or dependency-optimization pipeline. */
|
|
24
|
+
export async function adaptStencilClient(code, id) {
|
|
25
|
+
if (normalizeModuleId(id) !== normalizedStencilClientPath) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const transformed = await transformAsync(code, {
|
|
29
|
+
babelrc: false,
|
|
30
|
+
configFile: false,
|
|
31
|
+
filename: stencilClientPath,
|
|
32
|
+
plugins: [rewriteStencilStyleInsertion],
|
|
33
|
+
sourceFileName: stencilClientPath,
|
|
34
|
+
sourceMaps: true
|
|
35
|
+
});
|
|
36
|
+
if (transformed?.code === undefined || transformed.code === null) {
|
|
37
|
+
throw new Error(`Failed to adapt Stencil client: ${stencilClientPath}`);
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
code: transformed.code,
|
|
41
|
+
map: transformed.map
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/** Keeps Stencil-injected Taro component styles before application stylesheets. */
|
|
45
|
+
function rewriteStencilStyleInsertion() {
|
|
46
|
+
return {
|
|
47
|
+
name: 'vpt:rewrite-stencil-style-insertion',
|
|
48
|
+
visitor: {
|
|
49
|
+
CallExpression(callPath) {
|
|
50
|
+
if (!isStencilStyleInsertBeforeCall(callPath)) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
callPath
|
|
54
|
+
.get('arguments.1')
|
|
55
|
+
.replaceWith(types.conditionalExpression(types.callExpression(types.memberExpression(types.identifier('scopeId'), types.identifier('startsWith')), [types.stringLiteral('sc-taro-')]), createStyleQuery('style,link[rel="stylesheet"]'), createStyleQuery('link')));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/** Identifies Stencil's default component-style insertion call. */
|
|
61
|
+
function isStencilStyleInsertBeforeCall(callPath) {
|
|
62
|
+
const { callee, arguments: callArguments } = callPath.node;
|
|
63
|
+
return (types.isMemberExpression(callee) &&
|
|
64
|
+
types.isIdentifier(callee.object, { name: 'styleContainerNode' }) &&
|
|
65
|
+
types.isIdentifier(callee.property, { name: 'insertBefore' }) &&
|
|
66
|
+
types.isIdentifier(callArguments[0], { name: 'styleElm' }) &&
|
|
67
|
+
isStyleQuery(callArguments[1], 'link'));
|
|
68
|
+
}
|
|
69
|
+
/** Identifies one style-container querySelector call. */
|
|
70
|
+
function isStyleQuery(node, selector) {
|
|
71
|
+
return (types.isCallExpression(node) &&
|
|
72
|
+
types.isMemberExpression(node.callee) &&
|
|
73
|
+
types.isIdentifier(node.callee.object, { name: 'styleContainerNode' }) &&
|
|
74
|
+
types.isIdentifier(node.callee.property, { name: 'querySelector' }) &&
|
|
75
|
+
types.isStringLiteral(node.arguments[0], { value: selector }));
|
|
76
|
+
}
|
|
77
|
+
/** Creates one style-container querySelector call. */
|
|
78
|
+
function createStyleQuery(selector) {
|
|
79
|
+
return types.callExpression(types.memberExpression(types.identifier('styleContainerNode'), types.identifier('querySelector')), [types.stringLiteral(selector)]);
|
|
80
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { types } from '@babel/core';
|
|
2
1
|
import babel from '@rolldown/plugin-babel';
|
|
3
2
|
import { esTarget } from '../../utils/constant.js';
|
|
4
3
|
import { toViteFileImportPath } from '../../utils/modules.js';
|
|
5
4
|
import { packageRequire } from '../../utils/packages.js';
|
|
6
5
|
import { clientTaroApiId } from '../client/client-taro.js';
|
|
7
6
|
import { h5AppPath } from './constant.js';
|
|
7
|
+
import { createStencilClientAdapter } from './create-stencil-client-adapter.js';
|
|
8
8
|
import { createModuleResolver } from './resolver/module-resolver.js';
|
|
9
9
|
/** Creates the plugins that own the H5 target. */
|
|
10
10
|
export function createH5TargetPlugins(options) {
|
|
@@ -21,12 +21,6 @@ function createH5TargetPlugin(options) {
|
|
|
21
21
|
resolve: {
|
|
22
22
|
mainFields: ['main:h5', 'browser', 'module', 'jsnext:main', 'jsnext'],
|
|
23
23
|
alias: [
|
|
24
|
-
{
|
|
25
|
-
find: /^@stencil\/core\/internal\/client$/,
|
|
26
|
-
replacement: packageRequire.resolve('@stencil/core/internal/client', {
|
|
27
|
-
paths: [packageRequire.resolve('@tarojs/components/package.json')]
|
|
28
|
-
})
|
|
29
|
-
},
|
|
30
24
|
{
|
|
31
25
|
find: /^@tarojs\/components$/,
|
|
32
26
|
replacement: packageRequire.resolve('@tarojs/components/lib/react')
|
|
@@ -38,7 +32,15 @@ function createH5TargetPlugin(options) {
|
|
|
38
32
|
]
|
|
39
33
|
},
|
|
40
34
|
optimizeDeps: {
|
|
41
|
-
|
|
35
|
+
// The compiler-owned H5 app and Taro facade are injected after Vite's initial HTML scan. Prebundle
|
|
36
|
+
// the facade's platform backend as one boundary so its CommonJS implementation details receive
|
|
37
|
+
// interop without duplicating their package list. ReactDOM needs the same treatment for the H5 app.
|
|
38
|
+
include: ['@tarojs/plugin-platform-h5/dist/runtime/apis', 'react-dom/client'],
|
|
39
|
+
// Dependency optimization is its own Rolldown build and does not run application transform plugins.
|
|
40
|
+
// Register the same adapter there so optimized Taro components cannot embed Stencil's original client.
|
|
41
|
+
rolldownOptions: {
|
|
42
|
+
plugins: [createStencilClientAdapter()]
|
|
43
|
+
}
|
|
42
44
|
},
|
|
43
45
|
build: {
|
|
44
46
|
target: esTarget
|
|
@@ -89,11 +91,7 @@ function createH5IndexHtmlTags() {
|
|
|
89
91
|
/** Creates H5-only Babel transforms for Stencil CSS ordering and Taro API imports. */
|
|
90
92
|
function createH5SupportPlugins() {
|
|
91
93
|
return [
|
|
92
|
-
|
|
93
|
-
include: /[\\/]@stencil[\\/]core[\\/]internal[\\/]client[\\/]index\.js(?:\?.*)?$/,
|
|
94
|
-
exclude: [],
|
|
95
|
-
plugins: [rewriteStencilStyleInsertion]
|
|
96
|
-
}),
|
|
94
|
+
createStencilClientAdapter(),
|
|
97
95
|
babel({
|
|
98
96
|
plugins: [
|
|
99
97
|
[
|
|
@@ -107,43 +105,6 @@ function createH5SupportPlugins() {
|
|
|
107
105
|
})
|
|
108
106
|
];
|
|
109
107
|
}
|
|
110
|
-
/** Keeps Stencil-injected Taro component styles before application stylesheets. */
|
|
111
|
-
function rewriteStencilStyleInsertion() {
|
|
112
|
-
return {
|
|
113
|
-
name: 'vpt:rewrite-stencil-style-insertion',
|
|
114
|
-
visitor: {
|
|
115
|
-
CallExpression(callPath) {
|
|
116
|
-
if (!isStencilStyleInsertBeforeCall(callPath)) {
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
callPath
|
|
120
|
-
.get('arguments.1')
|
|
121
|
-
.replaceWith(types.conditionalExpression(types.callExpression(types.memberExpression(types.identifier('scopeId'), types.identifier('startsWith')), [types.stringLiteral('sc-taro-')]), createStyleQuery('style,link[rel="stylesheet"]'), createStyleQuery('link')));
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
/** Identifies Stencil's default component-style insertion call. */
|
|
127
|
-
function isStencilStyleInsertBeforeCall(callPath) {
|
|
128
|
-
const { callee, arguments: callArguments } = callPath.node;
|
|
129
|
-
return (types.isMemberExpression(callee) &&
|
|
130
|
-
types.isIdentifier(callee.object, { name: 'styleContainerNode' }) &&
|
|
131
|
-
types.isIdentifier(callee.property, { name: 'insertBefore' }) &&
|
|
132
|
-
types.isIdentifier(callArguments[0], { name: 'styleElm' }) &&
|
|
133
|
-
isStyleQuery(callArguments[1], 'link'));
|
|
134
|
-
}
|
|
135
|
-
/** Identifies one style-container querySelector call. */
|
|
136
|
-
function isStyleQuery(node, selector) {
|
|
137
|
-
return (types.isCallExpression(node) &&
|
|
138
|
-
types.isMemberExpression(node.callee) &&
|
|
139
|
-
types.isIdentifier(node.callee.object, { name: 'styleContainerNode' }) &&
|
|
140
|
-
types.isIdentifier(node.callee.property, { name: 'querySelector' }) &&
|
|
141
|
-
types.isStringLiteral(node.arguments[0], { value: selector }));
|
|
142
|
-
}
|
|
143
|
-
/** Creates one style-container querySelector call. */
|
|
144
|
-
function createStyleQuery(selector) {
|
|
145
|
-
return types.callExpression(types.memberExpression(types.identifier('styleContainerNode'), types.identifier('querySelector')), [types.stringLiteral(selector)]);
|
|
146
|
-
}
|
|
147
108
|
/** Creates H5 Taro compile-time constants. */
|
|
148
109
|
function createH5Defines() {
|
|
149
110
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-plugin-taro",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"author": "sep2",
|
|
5
5
|
"description": "Vite 8 plugin for building one React/Taro codebase for WeChat Mini Program and H5 targets.",
|
|
6
6
|
"type": "module",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"bugs": {
|
|
13
13
|
"url": "https://github.com/sep2/vite-plugin-taro/issues"
|
|
14
14
|
},
|
|
15
|
-
"homepage": "https://
|
|
15
|
+
"homepage": "https://vpt.js.org",
|
|
16
16
|
"main": "./dist/vite.js",
|
|
17
17
|
"module": "./dist/vite.js",
|
|
18
18
|
"types": "./dist/vite.d.ts",
|
|
@@ -58,24 +58,24 @@
|
|
|
58
58
|
"@babel/plugin-transform-modules-systemjs": "^7.29.8",
|
|
59
59
|
"@rolldown/plugin-babel": "^0.2.3",
|
|
60
60
|
"@tailwindcss-mangle/engine": "0.2.0",
|
|
61
|
-
"@tarojs/components": "
|
|
62
|
-
"@tarojs/helper": "
|
|
63
|
-
"@tarojs/plugin-platform-h5": "
|
|
64
|
-
"@tarojs/plugin-platform-weapp": "
|
|
65
|
-
"@tarojs/router": "
|
|
66
|
-
"@tarojs/runtime": "
|
|
67
|
-
"@tarojs/taro": "
|
|
61
|
+
"@tarojs/components": "4.2.0",
|
|
62
|
+
"@tarojs/helper": "4.2.0",
|
|
63
|
+
"@tarojs/plugin-platform-h5": "4.2.0",
|
|
64
|
+
"@tarojs/plugin-platform-weapp": "4.2.0",
|
|
65
|
+
"@tarojs/router": "4.2.0",
|
|
66
|
+
"@tarojs/runtime": "4.2.0",
|
|
67
|
+
"@tarojs/taro": "4.2.0",
|
|
68
68
|
"@vitejs/plugin-react": "^6.0.5",
|
|
69
69
|
"@weapp-tailwindcss/postcss": "3.2.8",
|
|
70
|
-
"babel-plugin-transform-taroapi": "
|
|
70
|
+
"babel-plugin-transform-taroapi": "4.2.0",
|
|
71
71
|
"picocolors": "^1.1.1",
|
|
72
72
|
"react-reconciler": "0.33.0",
|
|
73
73
|
"react-refresh": "^0.18.0",
|
|
74
74
|
"rolldown": "1.2.3",
|
|
75
75
|
"tailwindcss": "^4.3.3",
|
|
76
76
|
"weapp-tailwindcss": "^5.2.11",
|
|
77
|
-
"@tarojs/plugin-framework-react": "npm:vite-plugin-taro-plugin-framework-react@0.5.
|
|
78
|
-
"@tarojs/react": "npm:vite-plugin-taro-react@0.5.
|
|
77
|
+
"@tarojs/plugin-framework-react": "npm:vite-plugin-taro-plugin-framework-react@0.5.4",
|
|
78
|
+
"@tarojs/react": "npm:vite-plugin-taro-react@0.5.4"
|
|
79
79
|
},
|
|
80
80
|
"peerDependencies": {
|
|
81
81
|
"react": "^19.0.0",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Plugin } from 'vite'
|
|
2
2
|
import type { VitePluginTaroTarget } from '../../../options.ts'
|
|
3
3
|
import { normalizeModuleId } from '../../utils/modules.ts'
|
|
4
|
-
import {
|
|
4
|
+
import { resolvePackageFile } from '../../utils/packages.ts'
|
|
5
5
|
import { clientTaroNativeId } from './constant.ts'
|
|
6
6
|
import { injectTaroFrameworkApis } from './inject-taro-framework-apis.ts'
|
|
7
7
|
|
|
@@ -33,15 +33,22 @@ const clientTaroModules = new Map([
|
|
|
33
33
|
|
|
34
34
|
/** Creates the shared Taro facade backed by the selected target's API implementation. */
|
|
35
35
|
export function createClientTaroPlugin(target: VitePluginTaroTarget): Plugin {
|
|
36
|
-
const
|
|
36
|
+
const platformTaroId = resolvePlatformTaroId(target)
|
|
37
37
|
|
|
38
38
|
return {
|
|
39
39
|
name: 'vpt:client-taro',
|
|
40
40
|
enforce: 'pre',
|
|
41
41
|
|
|
42
|
-
resolveId(id, importer) {
|
|
42
|
+
async resolveId(id, importer) {
|
|
43
43
|
if (id === '@tarojs/taro') {
|
|
44
|
-
|
|
44
|
+
if (!isClientTaroFacade(importer)) {
|
|
45
|
+
return clientTaroApiPath
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Delegate the platform backend to Vite instead of returning an absolute dependency path. H5 marks this
|
|
49
|
+
// backend as an optimization root, so delegation lets Vite substitute its prebundled facade. Removing it
|
|
50
|
+
// bypasses CommonJS interop and exposes backend details such as base64-js directly to the browser.
|
|
51
|
+
return this.resolve(platformTaroId, importer, { skipSelf: true })
|
|
45
52
|
}
|
|
46
53
|
return clientTaroModules.get(id)
|
|
47
54
|
},
|
|
@@ -55,10 +62,8 @@ export function createClientTaroPlugin(target: VitePluginTaroTarget): Plugin {
|
|
|
55
62
|
}
|
|
56
63
|
}
|
|
57
64
|
|
|
58
|
-
function
|
|
59
|
-
return target === 'h5'
|
|
60
|
-
? packageRequire.resolve('@tarojs/plugin-platform-h5/dist/runtime/apis')
|
|
61
|
-
: packageRequire.resolve('@tarojs/taro')
|
|
65
|
+
function resolvePlatformTaroId(target: VitePluginTaroTarget): string {
|
|
66
|
+
return target === 'h5' ? '@tarojs/plugin-platform-h5/dist/runtime/apis' : '@tarojs/taro'
|
|
62
67
|
}
|
|
63
68
|
|
|
64
69
|
function isClientTaroFacade(importer: string | undefined): boolean {
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import type { types as BabelTypes } from '@babel/core'
|
|
2
|
+
import { type NodePath, type PluginObj, transformAsync, types } from '@babel/core'
|
|
3
|
+
import type { Plugin } from 'vite'
|
|
4
|
+
import { normalizeModuleId } from '../../utils/modules.ts'
|
|
5
|
+
import { packageRequire } from '../../utils/packages.ts'
|
|
6
|
+
|
|
7
|
+
const stencilClientPath = packageRequire.resolve('@stencil/core/internal/client', {
|
|
8
|
+
paths: [packageRequire.resolve('@tarojs/components/package.json')]
|
|
9
|
+
})
|
|
10
|
+
const normalizedStencilClientPath = normalizeModuleId(stencilClientPath)
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Creates the compiler-owned adaptation of Stencil's client style insertion.
|
|
14
|
+
*
|
|
15
|
+
* Taro components inject their styles through this internal client. Its default insertion point places those styles
|
|
16
|
+
* after application CSS, allowing component defaults to override application rules. The adapter is registered in both
|
|
17
|
+
* Vite's application pipeline and the independent dependency-optimization build: removing either registration leaves
|
|
18
|
+
* production or development with an unadapted client. This explicit dual registration removes the former optimization
|
|
19
|
+
* exclusion while keeping one transformation implementation.
|
|
20
|
+
*/
|
|
21
|
+
export function createStencilClientAdapter(): Plugin {
|
|
22
|
+
return {
|
|
23
|
+
name: 'vpt:h5-stencil-client',
|
|
24
|
+
transform: adaptStencilClient
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Applies the shared Stencil adaptation in either the application or dependency-optimization pipeline. */
|
|
29
|
+
export async function adaptStencilClient(code: string, id: string) {
|
|
30
|
+
if (normalizeModuleId(id) !== normalizedStencilClientPath) {
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const transformed = await transformAsync(code, {
|
|
35
|
+
babelrc: false,
|
|
36
|
+
configFile: false,
|
|
37
|
+
filename: stencilClientPath,
|
|
38
|
+
plugins: [rewriteStencilStyleInsertion],
|
|
39
|
+
sourceFileName: stencilClientPath,
|
|
40
|
+
sourceMaps: true
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
if (transformed?.code === undefined || transformed.code === null) {
|
|
44
|
+
throw new Error(`Failed to adapt Stencil client: ${stencilClientPath}`)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
code: transformed.code,
|
|
49
|
+
map: transformed.map
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Keeps Stencil-injected Taro component styles before application stylesheets. */
|
|
54
|
+
function rewriteStencilStyleInsertion(): PluginObj {
|
|
55
|
+
return {
|
|
56
|
+
name: 'vpt:rewrite-stencil-style-insertion',
|
|
57
|
+
visitor: {
|
|
58
|
+
CallExpression(callPath) {
|
|
59
|
+
if (!isStencilStyleInsertBeforeCall(callPath)) {
|
|
60
|
+
return
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
callPath
|
|
64
|
+
.get('arguments.1')
|
|
65
|
+
.replaceWith(
|
|
66
|
+
types.conditionalExpression(
|
|
67
|
+
types.callExpression(
|
|
68
|
+
types.memberExpression(types.identifier('scopeId'), types.identifier('startsWith')),
|
|
69
|
+
[types.stringLiteral('sc-taro-')]
|
|
70
|
+
),
|
|
71
|
+
createStyleQuery('style,link[rel="stylesheet"]'),
|
|
72
|
+
createStyleQuery('link')
|
|
73
|
+
)
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Identifies Stencil's default component-style insertion call. */
|
|
81
|
+
function isStencilStyleInsertBeforeCall(callPath: NodePath<BabelTypes.CallExpression>): boolean {
|
|
82
|
+
const { callee, arguments: callArguments } = callPath.node
|
|
83
|
+
return (
|
|
84
|
+
types.isMemberExpression(callee) &&
|
|
85
|
+
types.isIdentifier(callee.object, { name: 'styleContainerNode' }) &&
|
|
86
|
+
types.isIdentifier(callee.property, { name: 'insertBefore' }) &&
|
|
87
|
+
types.isIdentifier(callArguments[0], { name: 'styleElm' }) &&
|
|
88
|
+
isStyleQuery(callArguments[1], 'link')
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Identifies one style-container querySelector call. */
|
|
93
|
+
function isStyleQuery(node: BabelTypes.Node | null | undefined, selector: string): boolean {
|
|
94
|
+
return (
|
|
95
|
+
types.isCallExpression(node) &&
|
|
96
|
+
types.isMemberExpression(node.callee) &&
|
|
97
|
+
types.isIdentifier(node.callee.object, { name: 'styleContainerNode' }) &&
|
|
98
|
+
types.isIdentifier(node.callee.property, { name: 'querySelector' }) &&
|
|
99
|
+
types.isStringLiteral(node.arguments[0], { value: selector })
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** Creates one style-container querySelector call. */
|
|
104
|
+
function createStyleQuery(selector: string): ReturnType<typeof types.callExpression> {
|
|
105
|
+
return types.callExpression(
|
|
106
|
+
types.memberExpression(types.identifier('styleContainerNode'), types.identifier('querySelector')),
|
|
107
|
+
[types.stringLiteral(selector)]
|
|
108
|
+
)
|
|
109
|
+
}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import type { types as BabelTypes } from '@babel/core'
|
|
2
|
-
import { type NodePath, type PluginObj, types } from '@babel/core'
|
|
3
1
|
import babel from '@rolldown/plugin-babel'
|
|
4
2
|
import type { HtmlTagDescriptor, Plugin, PluginOption } from 'vite'
|
|
5
3
|
import type { VitePluginTaroOptions } from '../../../options.ts'
|
|
@@ -8,6 +6,7 @@ import { toViteFileImportPath } from '../../utils/modules.ts'
|
|
|
8
6
|
import { packageRequire } from '../../utils/packages.ts'
|
|
9
7
|
import { clientTaroApiId } from '../client/client-taro.ts'
|
|
10
8
|
import { h5AppPath } from './constant.ts'
|
|
9
|
+
import { createStencilClientAdapter } from './create-stencil-client-adapter.ts'
|
|
11
10
|
import { createModuleResolver } from './resolver/module-resolver.ts'
|
|
12
11
|
|
|
13
12
|
/** Creates the plugins that own the H5 target. */
|
|
@@ -28,12 +27,6 @@ function createH5TargetPlugin(options: VitePluginTaroOptions): Plugin {
|
|
|
28
27
|
resolve: {
|
|
29
28
|
mainFields: ['main:h5', 'browser', 'module', 'jsnext:main', 'jsnext'],
|
|
30
29
|
alias: [
|
|
31
|
-
{
|
|
32
|
-
find: /^@stencil\/core\/internal\/client$/,
|
|
33
|
-
replacement: packageRequire.resolve('@stencil/core/internal/client', {
|
|
34
|
-
paths: [packageRequire.resolve('@tarojs/components/package.json')]
|
|
35
|
-
})
|
|
36
|
-
},
|
|
37
30
|
{
|
|
38
31
|
find: /^@tarojs\/components$/,
|
|
39
32
|
replacement: packageRequire.resolve('@tarojs/components/lib/react')
|
|
@@ -45,7 +38,15 @@ function createH5TargetPlugin(options: VitePluginTaroOptions): Plugin {
|
|
|
45
38
|
]
|
|
46
39
|
},
|
|
47
40
|
optimizeDeps: {
|
|
48
|
-
|
|
41
|
+
// The compiler-owned H5 app and Taro facade are injected after Vite's initial HTML scan. Prebundle
|
|
42
|
+
// the facade's platform backend as one boundary so its CommonJS implementation details receive
|
|
43
|
+
// interop without duplicating their package list. ReactDOM needs the same treatment for the H5 app.
|
|
44
|
+
include: ['@tarojs/plugin-platform-h5/dist/runtime/apis', 'react-dom/client'],
|
|
45
|
+
// Dependency optimization is its own Rolldown build and does not run application transform plugins.
|
|
46
|
+
// Register the same adapter there so optimized Taro components cannot embed Stencil's original client.
|
|
47
|
+
rolldownOptions: {
|
|
48
|
+
plugins: [createStencilClientAdapter()]
|
|
49
|
+
}
|
|
49
50
|
},
|
|
50
51
|
build: {
|
|
51
52
|
target: esTarget
|
|
@@ -101,11 +102,7 @@ function createH5IndexHtmlTags(): HtmlTagDescriptor[] {
|
|
|
101
102
|
/** Creates H5-only Babel transforms for Stencil CSS ordering and Taro API imports. */
|
|
102
103
|
function createH5SupportPlugins(): PluginOption[] {
|
|
103
104
|
return [
|
|
104
|
-
|
|
105
|
-
include: /[\\/]@stencil[\\/]core[\\/]internal[\\/]client[\\/]index\.js(?:\?.*)?$/,
|
|
106
|
-
exclude: [],
|
|
107
|
-
plugins: [rewriteStencilStyleInsertion]
|
|
108
|
-
}),
|
|
105
|
+
createStencilClientAdapter(),
|
|
109
106
|
babel({
|
|
110
107
|
plugins: [
|
|
111
108
|
[
|
|
@@ -122,64 +119,6 @@ function createH5SupportPlugins(): PluginOption[] {
|
|
|
122
119
|
]
|
|
123
120
|
}
|
|
124
121
|
|
|
125
|
-
/** Keeps Stencil-injected Taro component styles before application stylesheets. */
|
|
126
|
-
function rewriteStencilStyleInsertion(): PluginObj {
|
|
127
|
-
return {
|
|
128
|
-
name: 'vpt:rewrite-stencil-style-insertion',
|
|
129
|
-
visitor: {
|
|
130
|
-
CallExpression(callPath) {
|
|
131
|
-
if (!isStencilStyleInsertBeforeCall(callPath)) {
|
|
132
|
-
return
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
callPath
|
|
136
|
-
.get('arguments.1')
|
|
137
|
-
.replaceWith(
|
|
138
|
-
types.conditionalExpression(
|
|
139
|
-
types.callExpression(
|
|
140
|
-
types.memberExpression(types.identifier('scopeId'), types.identifier('startsWith')),
|
|
141
|
-
[types.stringLiteral('sc-taro-')]
|
|
142
|
-
),
|
|
143
|
-
createStyleQuery('style,link[rel="stylesheet"]'),
|
|
144
|
-
createStyleQuery('link')
|
|
145
|
-
)
|
|
146
|
-
)
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/** Identifies Stencil's default component-style insertion call. */
|
|
153
|
-
function isStencilStyleInsertBeforeCall(callPath: NodePath<BabelTypes.CallExpression>): boolean {
|
|
154
|
-
const { callee, arguments: callArguments } = callPath.node
|
|
155
|
-
return (
|
|
156
|
-
types.isMemberExpression(callee) &&
|
|
157
|
-
types.isIdentifier(callee.object, { name: 'styleContainerNode' }) &&
|
|
158
|
-
types.isIdentifier(callee.property, { name: 'insertBefore' }) &&
|
|
159
|
-
types.isIdentifier(callArguments[0], { name: 'styleElm' }) &&
|
|
160
|
-
isStyleQuery(callArguments[1], 'link')
|
|
161
|
-
)
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/** Identifies one style-container querySelector call. */
|
|
165
|
-
function isStyleQuery(node: BabelTypes.Node | null | undefined, selector: string): boolean {
|
|
166
|
-
return (
|
|
167
|
-
types.isCallExpression(node) &&
|
|
168
|
-
types.isMemberExpression(node.callee) &&
|
|
169
|
-
types.isIdentifier(node.callee.object, { name: 'styleContainerNode' }) &&
|
|
170
|
-
types.isIdentifier(node.callee.property, { name: 'querySelector' }) &&
|
|
171
|
-
types.isStringLiteral(node.arguments[0], { value: selector })
|
|
172
|
-
)
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/** Creates one style-container querySelector call. */
|
|
176
|
-
function createStyleQuery(selector: string): ReturnType<typeof types.callExpression> {
|
|
177
|
-
return types.callExpression(
|
|
178
|
-
types.memberExpression(types.identifier('styleContainerNode'), types.identifier('querySelector')),
|
|
179
|
-
[types.stringLiteral(selector)]
|
|
180
|
-
)
|
|
181
|
-
}
|
|
182
|
-
|
|
183
122
|
/** Creates H5 Taro compile-time constants. */
|
|
184
123
|
function createH5Defines(): Record<string, string> {
|
|
185
124
|
return {
|