vite-plugin-taro 0.2.2 → 0.3.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.md +83 -106
- package/README.zh.md +83 -104
- package/dist/node/build-context.d.ts +25 -0
- package/dist/node/build-context.js +48 -0
- package/dist/node/css/css-pipeline.d.ts +21 -0
- package/dist/node/css/css-pipeline.js +129 -0
- package/dist/node/plugins/conditional-directives.d.ts +3 -0
- package/dist/node/plugins/conditional-directives.js +62 -0
- package/dist/node/plugins/taro-runtime.d.ts +5 -0
- package/dist/node/plugins/taro-runtime.js +18 -0
- package/dist/node/targets/h5/plugin.d.ts +6 -0
- package/dist/node/targets/h5/plugin.js +117 -0
- package/dist/node/targets/h5/virtual-modules.d.ts +5 -0
- package/dist/node/targets/h5/virtual-modules.js +60 -0
- package/dist/node/targets/wx/companion-assets.d.ts +18 -0
- package/dist/node/targets/wx/companion-assets.js +121 -0
- package/dist/node/targets/wx/dev-server/development-session.d.ts +31 -0
- package/dist/node/targets/wx/dev-server/development-session.js +202 -0
- package/dist/node/targets/wx/dev-server/full-build-scheduler.d.ts +14 -0
- package/dist/node/targets/wx/dev-server/full-build-scheduler.js +60 -0
- package/dist/node/targets/wx/dev-server/js-utils.d.ts +5 -0
- package/dist/node/targets/wx/dev-server/js-utils.js +28 -0
- package/dist/node/targets/wx/dev-server/output.d.ts +19 -0
- package/dist/node/targets/wx/dev-server/output.js +44 -0
- package/dist/node/targets/wx/dev-server/rolldown-runtime-source.d.ts +8 -0
- package/dist/node/targets/wx/dev-server/rolldown-runtime-source.js +95 -0
- package/dist/node/targets/wx/dev-server/update-server-state.d.ts +65 -0
- package/dist/node/targets/wx/dev-server/update-server-state.js +116 -0
- package/dist/node/targets/wx/dev-server/update-transport.d.ts +28 -0
- package/dist/node/targets/wx/dev-server/update-transport.js +212 -0
- package/dist/node/targets/wx/dev-server/vite-bundled-dev-adapter.d.ts +44 -0
- package/dist/node/targets/wx/dev-server/vite-bundled-dev-adapter.js +145 -0
- package/dist/node/targets/wx/development-files.d.ts +8 -0
- package/dist/node/targets/wx/development-files.js +8 -0
- package/dist/node/targets/wx/plugin.d.ts +6 -0
- package/dist/node/targets/wx/plugin.js +143 -0
- package/dist/node/targets/wx/react-refresh.d.ts +4 -0
- package/dist/node/targets/wx/react-refresh.js +38 -0
- package/dist/node/targets/wx/virtual-modules.d.ts +16 -0
- package/dist/node/targets/wx/virtual-modules.js +120 -0
- package/dist/node/utils/async.d.ts +8 -0
- package/dist/node/utils/async.js +16 -0
- package/dist/node/utils/filesystem.d.ts +13 -0
- package/dist/node/utils/filesystem.js +43 -0
- package/dist/{vite/utils.d.ts → node/utils/modules.d.ts} +2 -2
- package/dist/{vite/utils.js → node/utils/modules.js} +10 -3
- package/dist/node/utils/packages.d.ts +2 -0
- package/dist/node/utils/packages.js +8 -0
- package/dist/node/vite-plugin.d.ts +4 -0
- package/dist/node/vite-plugin.js +33 -0
- package/dist/options.d.ts +21 -0
- package/dist/{shim/h5.d.ts → runtime/h5/taro-runtime.d.ts} +3 -1
- package/dist/runtime/h5/taro-runtime.js +9 -0
- package/dist/runtime/taro/api.d.ts +5 -0
- package/dist/{virtual → runtime/taro}/api.js +3 -0
- package/dist/runtime/taro/components.d.ts +2 -0
- package/dist/runtime/taro/components.js +2 -0
- package/dist/runtime/wx/page-update.d.ts +6 -0
- package/dist/runtime/wx/page-update.js +157 -0
- package/dist/{shim/wx.d.ts → runtime/wx/taro-runtime.d.ts} +1 -0
- package/dist/{shim/wx.js → runtime/wx/taro-runtime.js} +1 -0
- package/dist/runtime/wx/update-client-state.d.ts +68 -0
- package/dist/runtime/wx/update-client-state.js +84 -0
- package/dist/runtime/wx/update-client.d.ts +1 -0
- package/dist/runtime/wx/update-client.js +170 -0
- package/dist/vite.d.ts +2 -2
- package/dist/vite.js +1 -1
- package/package.json +15 -11
- package/src/node/build-context.ts +63 -0
- package/src/node/css/css-pipeline.ts +147 -0
- package/src/node/plugins/conditional-directives.ts +76 -0
- package/src/node/plugins/taro-runtime.ts +22 -0
- package/src/node/targets/h5/plugin.ts +135 -0
- package/src/node/targets/h5/virtual-modules.ts +71 -0
- package/src/node/targets/wx/companion-assets.ts +160 -0
- package/src/node/targets/wx/dev-server/development-session.ts +253 -0
- package/src/node/targets/wx/dev-server/full-build-scheduler.ts +62 -0
- package/src/node/targets/wx/dev-server/js-utils.ts +33 -0
- package/src/node/targets/wx/dev-server/output.ts +56 -0
- package/src/node/targets/wx/dev-server/rolldown-runtime-source.ts +95 -0
- package/src/node/targets/wx/dev-server/update-server-state.ts +183 -0
- package/src/node/targets/wx/dev-server/update-transport.ts +261 -0
- package/src/node/targets/wx/dev-server/vite-bundled-dev-adapter.ts +203 -0
- package/src/node/targets/wx/development-files.ts +11 -0
- package/src/node/targets/wx/plugin.ts +163 -0
- package/src/node/targets/wx/react-refresh.ts +51 -0
- package/src/node/targets/wx/virtual-modules.ts +152 -0
- package/src/node/utils/async.ts +19 -0
- package/src/node/utils/filesystem.ts +45 -0
- package/src/{vite/utils.ts → node/utils/modules.ts} +11 -3
- package/src/node/utils/packages.ts +10 -0
- package/src/node/vite-plugin.ts +41 -0
- package/src/options.ts +25 -0
- package/src/runtime/h5/taro-css.d.ts +3 -0
- package/src/runtime/h5/taro-runtime.ts +10 -0
- package/src/{virtual → runtime/taro}/api.ts +3 -0
- package/src/runtime/taro/components.ts +2 -0
- package/src/runtime/wx/page-update.ts +230 -0
- package/src/runtime/wx/react-refresh.d.ts +20 -0
- package/src/{shim/wx.ts → runtime/wx/taro-runtime.ts} +1 -0
- package/src/runtime/wx/update-client-state.ts +138 -0
- package/src/runtime/wx/update-client.ts +222 -0
- package/src/vite.ts +2 -2
- package/dist/shim/h5.js +0 -5
- package/dist/virtual/api.d.ts +0 -3
- package/dist/virtual/components.d.ts +0 -1
- package/dist/virtual/components.js +0 -1
- package/dist/vite/constants.d.ts +0 -4
- package/dist/vite/constants.js +0 -8
- package/dist/vite/plugins.d.ts +0 -8
- package/dist/vite/plugins.js +0 -186
- package/dist/vite/tailwindcss.d.ts +0 -3
- package/dist/vite/tailwindcss.js +0 -35
- package/dist/vite/targets/h5.d.ts +0 -31
- package/dist/vite/targets/h5.js +0 -201
- package/dist/vite/targets/wx.d.ts +0 -74
- package/dist/vite/targets/wx.js +0 -362
- package/dist/vite/types.d.ts +0 -38
- package/dist/vite/virtual-modules.d.ts +0 -3
- package/dist/vite/virtual-modules.js +0 -13
- package/dist/vite/vite-plugin-taro.d.ts +0 -7
- package/dist/vite/vite-plugin-taro.js +0 -80
- package/src/shim/h5.ts +0 -6
- package/src/virtual/components.ts +0 -1
- package/src/vite/constants.ts +0 -12
- package/src/vite/plugins.ts +0 -218
- package/src/vite/tailwindcss.ts +0 -41
- package/src/vite/targets/h5.ts +0 -229
- package/src/vite/targets/wx.ts +0 -436
- package/src/vite/types.ts +0 -48
- package/src/vite/virtual-modules.ts +0 -14
- package/src/vite/vite-plugin-taro.ts +0 -106
- /package/dist/{vite/types.js → options.js} +0 -0
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Plugin } from 'vite';
|
|
2
|
+
/** Public IDs used by Taro's API transform and generated target modules. */
|
|
3
|
+
export declare const virtualTaroApiId = "virtual:taro/api";
|
|
4
|
+
/** Resolves target-neutral Taro shims once instead of duplicating this concern in every target plugin. */
|
|
5
|
+
export declare function createTaroRuntimePlugin(): Plugin;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { resolvePackageFile } from '../utils/packages.js';
|
|
2
|
+
/** Public IDs used by Taro's API transform and generated target modules. */
|
|
3
|
+
export const virtualTaroApiId = 'virtual:taro/api';
|
|
4
|
+
const virtualTaroComponentsId = 'virtual:taro/components';
|
|
5
|
+
const runtimeModules = new Map([
|
|
6
|
+
[virtualTaroApiId, resolvePackageFile('dist/runtime/taro/api.js')],
|
|
7
|
+
[virtualTaroComponentsId, resolvePackageFile('dist/runtime/taro/components.js')]
|
|
8
|
+
]);
|
|
9
|
+
/** Resolves target-neutral Taro shims once instead of duplicating this concern in every target plugin. */
|
|
10
|
+
export function createTaroRuntimePlugin() {
|
|
11
|
+
return {
|
|
12
|
+
name: 'vite-plugin-taro:runtime',
|
|
13
|
+
enforce: 'pre',
|
|
14
|
+
resolveId(id) {
|
|
15
|
+
return runtimeModules.get(id);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { PluginOption, UserConfig } from 'vite';
|
|
2
|
+
import type { BuildContext } from '../../build-context.ts';
|
|
3
|
+
/** Creates the plugins that own the complete H5 target lifecycle. */
|
|
4
|
+
export declare function createH5TargetPlugins(context: BuildContext): PluginOption[];
|
|
5
|
+
/** Supplies the complete H5 target configuration from the same target owner as its plugins. */
|
|
6
|
+
export declare function createH5ViteConfig(context: BuildContext): UserConfig;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import babel from '@rolldown/plugin-babel';
|
|
2
|
+
import { virtualTaroApiId } from '../../plugins/taro-runtime.js';
|
|
3
|
+
import { stripVirtualPrefix } from '../../utils/modules.js';
|
|
4
|
+
import { packageRequire } from '../../utils/packages.js';
|
|
5
|
+
import { createH5IndexHtmlTags, isH5VirtualModuleId, loadH5VirtualModule } from './virtual-modules.js';
|
|
6
|
+
/** Creates the plugins that own the complete H5 target lifecycle. */
|
|
7
|
+
export function createH5TargetPlugins(context) {
|
|
8
|
+
return [...createH5SupportPlugins(), createH5TargetPlugin(context)];
|
|
9
|
+
}
|
|
10
|
+
function createH5TargetPlugin(context) {
|
|
11
|
+
return {
|
|
12
|
+
name: 'vite-plugin-taro:h5',
|
|
13
|
+
resolveId: {
|
|
14
|
+
order: 'pre',
|
|
15
|
+
handler(id) {
|
|
16
|
+
return isH5VirtualModuleId(id) ? `\0${id}` : undefined;
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
load: {
|
|
20
|
+
order: 'post',
|
|
21
|
+
handler(id) {
|
|
22
|
+
return loadH5VirtualModule(stripVirtualPrefix(id), context);
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
transformIndexHtml: {
|
|
26
|
+
order: 'pre',
|
|
27
|
+
handler() {
|
|
28
|
+
return createH5IndexHtmlTags(context);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/** Creates H5-only Babel transforms for Stencil CSS ordering and Taro API imports. */
|
|
34
|
+
function createH5SupportPlugins() {
|
|
35
|
+
return [
|
|
36
|
+
babel({
|
|
37
|
+
include: /[\\/]@stencil[\\/]core[\\/]internal[\\/]client[\\/]index\.js(?:\?.*)?$/,
|
|
38
|
+
exclude: [],
|
|
39
|
+
plugins: [rewriteStencilStyleInsertion]
|
|
40
|
+
}),
|
|
41
|
+
babel({
|
|
42
|
+
plugins: [
|
|
43
|
+
[
|
|
44
|
+
packageRequire.resolve('babel-plugin-transform-taroapi'),
|
|
45
|
+
{
|
|
46
|
+
packageName: virtualTaroApiId,
|
|
47
|
+
definition: packageRequire(packageRequire.resolve('@tarojs/plugin-platform-h5/dist/definition.json'))
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
]
|
|
51
|
+
})
|
|
52
|
+
];
|
|
53
|
+
}
|
|
54
|
+
/** Keeps Stencil-injected Taro component styles before application stylesheets. */
|
|
55
|
+
function rewriteStencilStyleInsertion() {
|
|
56
|
+
return {
|
|
57
|
+
name: 'rewrite-stencil-style-insertion',
|
|
58
|
+
visitor: {
|
|
59
|
+
CallExpression(path) {
|
|
60
|
+
if (!isStencilStyleInsertBeforeCall(path))
|
|
61
|
+
return;
|
|
62
|
+
path.get('arguments.1').replaceWithSourceString(`scopeId.startsWith('sc-taro-') ? styleContainerNode.querySelector('style,link[rel="stylesheet"]') : styleContainerNode.querySelector('link')`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function isStencilStyleInsertBeforeCall(path) {
|
|
68
|
+
return (path.get('callee').matchesPattern('styleContainerNode.insertBefore') &&
|
|
69
|
+
path.get('arguments.0').toString() === 'styleElm' &&
|
|
70
|
+
path.get('arguments.1').toString() === "styleContainerNode.querySelector('link')");
|
|
71
|
+
}
|
|
72
|
+
/** Supplies the complete H5 target configuration from the same target owner as its plugins. */
|
|
73
|
+
export function createH5ViteConfig(context) {
|
|
74
|
+
return {
|
|
75
|
+
define: createH5TaroDefines(),
|
|
76
|
+
resolve: {
|
|
77
|
+
mainFields: ['main:h5', 'browser', 'module', 'jsnext:main', 'jsnext'],
|
|
78
|
+
alias: [
|
|
79
|
+
{
|
|
80
|
+
find: /^@stencil\/core\/internal\/client$/,
|
|
81
|
+
replacement: packageRequire.resolve('@stencil/core/internal/client', {
|
|
82
|
+
paths: [packageRequire.resolve('@tarojs/components/package.json')]
|
|
83
|
+
})
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
find: /^@tarojs\/components$/,
|
|
87
|
+
replacement: packageRequire.resolve('@tarojs/components/lib/react')
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
find: /^@tarojs\/components\/dist\/components$/,
|
|
91
|
+
replacement: packageRequire.resolve('@tarojs/components/dist/components')
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
find: /^@tarojs\/taro$/,
|
|
95
|
+
replacement: packageRequire.resolve('@tarojs/plugin-platform-h5/dist/runtime/apis')
|
|
96
|
+
}
|
|
97
|
+
]
|
|
98
|
+
},
|
|
99
|
+
optimizeDeps: {
|
|
100
|
+
exclude: ['@stencil/core/internal/client']
|
|
101
|
+
},
|
|
102
|
+
build: {
|
|
103
|
+
target: 'es2018',
|
|
104
|
+
minify: !context.development
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function createH5TaroDefines() {
|
|
109
|
+
return {
|
|
110
|
+
'process.env.FRAMEWORK': JSON.stringify('react'),
|
|
111
|
+
'process.env.SUPPORT_TARO_POLYFILL': JSON.stringify('disabled'),
|
|
112
|
+
'process.env.TARO_ENV': JSON.stringify('h5'),
|
|
113
|
+
'process.env.TARO_PLATFORM': JSON.stringify('web'),
|
|
114
|
+
'process.env.SUPPORT_DINGTALK_NAVIGATE': JSON.stringify('disabled'),
|
|
115
|
+
DEPRECATED_ADAPTER_COMPONENT: 'false'
|
|
116
|
+
};
|
|
117
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { HtmlTagDescriptor } from 'vite';
|
|
2
|
+
import type { BuildContext } from '../../build-context.ts';
|
|
3
|
+
export declare function isH5VirtualModuleId(id: string): boolean;
|
|
4
|
+
export declare function loadH5VirtualModule(id: string, context: BuildContext): string | undefined;
|
|
5
|
+
export declare function createH5IndexHtmlTags(context: BuildContext): HtmlTagDescriptor[] | undefined;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { createPageComponentImportPath, toViteFileImportPath } from '../../utils/modules.js';
|
|
2
|
+
import { resolvePackageFile } from '../../utils/packages.js';
|
|
3
|
+
const h5TaroRuntimeImportPath = toViteFileImportPath(resolvePackageFile('dist/runtime/h5/taro-runtime.js'));
|
|
4
|
+
const virtualH5EntryId = 'virtual:vite-plugin-taro/h5';
|
|
5
|
+
export function isH5VirtualModuleId(id) {
|
|
6
|
+
return id === virtualH5EntryId;
|
|
7
|
+
}
|
|
8
|
+
export function loadH5VirtualModule(id, context) {
|
|
9
|
+
if (id === virtualH5EntryId)
|
|
10
|
+
return createH5EntrySource(context);
|
|
11
|
+
}
|
|
12
|
+
export function createH5IndexHtmlTags(context) {
|
|
13
|
+
if (context.project.target !== 'h5')
|
|
14
|
+
return;
|
|
15
|
+
return [
|
|
16
|
+
{
|
|
17
|
+
tag: 'script',
|
|
18
|
+
attrs: { type: 'module' },
|
|
19
|
+
children: `import '${virtualH5EntryId}'`,
|
|
20
|
+
injectTo: 'body'
|
|
21
|
+
}
|
|
22
|
+
];
|
|
23
|
+
}
|
|
24
|
+
function createH5EntrySource(context) {
|
|
25
|
+
const appConfig = JSON.stringify(createH5AppConfig(context.project.appConfig));
|
|
26
|
+
const routes = createH5RoutesSource(context.project.pages);
|
|
27
|
+
return `import {
|
|
28
|
+
createHashHistory,
|
|
29
|
+
createReactApp,
|
|
30
|
+
createRouter,
|
|
31
|
+
handleAppMount,
|
|
32
|
+
window
|
|
33
|
+
} from ${JSON.stringify(h5TaroRuntimeImportPath)}
|
|
34
|
+
import React from 'react'
|
|
35
|
+
import ReactDOM from 'react-dom/client'
|
|
36
|
+
import AppComponent from ${JSON.stringify(toViteFileImportPath(context.project.appComponentFile))}
|
|
37
|
+
|
|
38
|
+
const config = window.__taroAppConfig = ${appConfig}
|
|
39
|
+
config.routes = ${routes}
|
|
40
|
+
const app = createReactApp(AppComponent, React, ReactDOM, config)
|
|
41
|
+
const history = createHashHistory({ window })
|
|
42
|
+
handleAppMount(config, history)
|
|
43
|
+
createRouter(history, app, config, React)
|
|
44
|
+
`;
|
|
45
|
+
}
|
|
46
|
+
function createH5AppConfig(sharedAppConfig) {
|
|
47
|
+
return { router: {}, ...sharedAppConfig };
|
|
48
|
+
}
|
|
49
|
+
function createH5RoutesSource(pages) {
|
|
50
|
+
const routes = pages.map((page) => [
|
|
51
|
+
'Object.assign({',
|
|
52
|
+
` path: ${JSON.stringify(page.path)},`,
|
|
53
|
+
' load: async function(context, params) {',
|
|
54
|
+
` const page = await import(${JSON.stringify(createPageComponentImportPath(page.path))})`,
|
|
55
|
+
' return [page, context, params]',
|
|
56
|
+
' }',
|
|
57
|
+
`}, ${JSON.stringify(page.config)})`
|
|
58
|
+
].join('\n'));
|
|
59
|
+
return `[\n${routes.join(',\n')}\n]`;
|
|
60
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { BuildContext } from '../../build-context.ts';
|
|
2
|
+
type WxAssetSource = string | Uint8Array;
|
|
3
|
+
export type WxBundle = Record<string, {
|
|
4
|
+
type: 'asset' | 'chunk';
|
|
5
|
+
source?: WxAssetSource;
|
|
6
|
+
modules?: Record<string, {
|
|
7
|
+
renderedExports?: string[];
|
|
8
|
+
}>;
|
|
9
|
+
}>;
|
|
10
|
+
type WxAssetEmitter = {
|
|
11
|
+
emitFile(asset: {
|
|
12
|
+
type: 'asset';
|
|
13
|
+
fileName: string;
|
|
14
|
+
source: WxAssetSource;
|
|
15
|
+
}): string;
|
|
16
|
+
};
|
|
17
|
+
export declare function emitWxCompanionAssets(emitter: WxAssetEmitter, bundle: WxBundle, context: BuildContext): void;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { recursiveMerge } from '@tarojs/helper';
|
|
3
|
+
import { Weapp as WxPlatform } from '@tarojs/plugin-platform-weapp';
|
|
4
|
+
import { normalizeModuleId } from '../../utils/modules.js';
|
|
5
|
+
import { packageRequire } from '../../utils/packages.js';
|
|
6
|
+
const taroWxComponentsPath = packageRequire.resolve('@tarojs/plugin-platform-weapp/dist/components-react');
|
|
7
|
+
const templateBuilder = createWxTemplateBuilder();
|
|
8
|
+
export function emitWxCompanionAssets(emitter, bundle, context) {
|
|
9
|
+
for (const asset of createWxCompanionAssets(bundle, context)) {
|
|
10
|
+
emitter.emitFile({ type: 'asset', fileName: asset.fileName, source: asset.source });
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function createWxCompanionAssets(bundle, context) {
|
|
14
|
+
const json = (value) => (context.development ? JSON.stringify(value, null, 2) : JSON.stringify(value));
|
|
15
|
+
return [
|
|
16
|
+
{ fileName: 'app.json', source: json(context.project.appConfig) },
|
|
17
|
+
{ fileName: 'app.wxss', source: collectWxBundleStyles(bundle) },
|
|
18
|
+
{
|
|
19
|
+
fileName: 'base.wxml',
|
|
20
|
+
source: templateBuilder.buildTemplate(collectWxTemplateComponentConfig(bundle))
|
|
21
|
+
},
|
|
22
|
+
{ fileName: 'utils.wxs', source: templateBuilder.buildXScript() },
|
|
23
|
+
{ fileName: 'comp.wxml', source: templateBuilder.buildBaseComponentTemplate('.wxml') },
|
|
24
|
+
{ fileName: 'comp.json', source: json(createWxComponentConfig()) },
|
|
25
|
+
{ fileName: 'project.config.json', source: json(createWxProjectConfig(context)) },
|
|
26
|
+
{ fileName: 'project.private.config.json', source: json(context.project.projectPrivateConfigJson) },
|
|
27
|
+
{ fileName: 'sitemap.json', source: json(context.project.sitemapJson) },
|
|
28
|
+
...context.project.pages.flatMap((page) => [
|
|
29
|
+
{
|
|
30
|
+
fileName: `${page.path}.wxml`,
|
|
31
|
+
source: templateBuilder.buildPageTemplate(relativeWxRootAsset(page.path, 'base.wxml'), {
|
|
32
|
+
content: page.config,
|
|
33
|
+
path: page.path
|
|
34
|
+
})
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
fileName: `${page.path}.json`,
|
|
38
|
+
source: json({
|
|
39
|
+
...page.config,
|
|
40
|
+
usingComponents: { comp: relativeWxRootAsset(page.path, 'comp') }
|
|
41
|
+
})
|
|
42
|
+
},
|
|
43
|
+
{ fileName: `${page.path}.wxss`, source: '' }
|
|
44
|
+
])
|
|
45
|
+
];
|
|
46
|
+
}
|
|
47
|
+
function createWxProjectConfig(context) {
|
|
48
|
+
const projectConfig = context.project.projectConfigJson;
|
|
49
|
+
const setting = isJsonObject(projectConfig.setting) ? projectConfig.setting : {};
|
|
50
|
+
return {
|
|
51
|
+
...projectConfig,
|
|
52
|
+
setting: { ...setting, compileHotReLoad: true }
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function isJsonObject(value) {
|
|
56
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
57
|
+
}
|
|
58
|
+
function createWxTemplateBuilder() {
|
|
59
|
+
const platform = new WxPlatform({ helper: { recursiveMerge }, modifyWebpackChain() { }, registerPlatform() { } }, {}, {});
|
|
60
|
+
platform.modifyTemplate({});
|
|
61
|
+
return platform.template;
|
|
62
|
+
}
|
|
63
|
+
function relativeWxRootAsset(pagePath, rootAsset) {
|
|
64
|
+
const relativePath = path.posix.relative(path.posix.dirname(pagePath), rootAsset);
|
|
65
|
+
return relativePath.startsWith('.') ? relativePath : `./${relativePath}`;
|
|
66
|
+
}
|
|
67
|
+
function collectWxTemplateComponentConfig(bundle) {
|
|
68
|
+
const config = {
|
|
69
|
+
includes: new Set([
|
|
70
|
+
'view',
|
|
71
|
+
'catch-view',
|
|
72
|
+
'static-view',
|
|
73
|
+
'pure-view',
|
|
74
|
+
'click-view',
|
|
75
|
+
'scroll-view',
|
|
76
|
+
'image',
|
|
77
|
+
'static-image',
|
|
78
|
+
'text',
|
|
79
|
+
'static-text'
|
|
80
|
+
]),
|
|
81
|
+
exclude: new Set(),
|
|
82
|
+
thirdPartyComponents: new Map(),
|
|
83
|
+
includeAll: false
|
|
84
|
+
};
|
|
85
|
+
const components = findBundleModule(bundle, taroWxComponentsPath);
|
|
86
|
+
for (const name of components?.renderedExports ?? [])
|
|
87
|
+
config.includes.add(toDashed(name));
|
|
88
|
+
return config;
|
|
89
|
+
}
|
|
90
|
+
function findBundleModule(bundle, resolvedId) {
|
|
91
|
+
const normalizedResolvedId = normalizeModuleId(resolvedId);
|
|
92
|
+
for (const item of Object.values(bundle)) {
|
|
93
|
+
if (item.type !== 'chunk')
|
|
94
|
+
continue;
|
|
95
|
+
const found = Object.entries(item.modules ?? {}).find(([id]) => normalizeModuleId(id) === normalizedResolvedId);
|
|
96
|
+
if (found)
|
|
97
|
+
return found[1];
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
function toDashed(value) {
|
|
101
|
+
return value.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
|
|
102
|
+
}
|
|
103
|
+
function createWxComponentConfig() {
|
|
104
|
+
return {
|
|
105
|
+
component: true,
|
|
106
|
+
styleIsolation: 'apply-shared',
|
|
107
|
+
usingComponents: { comp: './comp' }
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
function collectWxBundleStyles(bundle) {
|
|
111
|
+
const styles = [];
|
|
112
|
+
for (const [fileName, item] of Object.entries(bundle)) {
|
|
113
|
+
if (item.type !== 'asset' || !fileName.endsWith('.css'))
|
|
114
|
+
continue;
|
|
115
|
+
const source = typeof item.source === 'string' ? item.source : new TextDecoder().decode(item.source);
|
|
116
|
+
if (source)
|
|
117
|
+
styles.push(source);
|
|
118
|
+
delete bundle[fileName];
|
|
119
|
+
}
|
|
120
|
+
return styles.join('\n');
|
|
121
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ViteDevServer } from 'vite';
|
|
2
|
+
import type { BuildContext } from '../../../build-context.ts';
|
|
3
|
+
type WxDevServerContext = Pick<BuildContext, 'vite' | 'css'>;
|
|
4
|
+
/** Owns one WX bundled-development graph and all writes to its fixed output directory. */
|
|
5
|
+
export declare class WxDevelopmentSession {
|
|
6
|
+
private readonly context;
|
|
7
|
+
private readonly server;
|
|
8
|
+
private readonly adapter;
|
|
9
|
+
private readonly updateTransport;
|
|
10
|
+
private readonly outDir;
|
|
11
|
+
private readonly initialBundle;
|
|
12
|
+
private readonly outputQueue;
|
|
13
|
+
private readonly fullBuildScheduler;
|
|
14
|
+
private originalPrintUrls;
|
|
15
|
+
private snapshot;
|
|
16
|
+
constructor(context: WxDevServerContext, server: ViteDevServer);
|
|
17
|
+
private get config();
|
|
18
|
+
install(): void;
|
|
19
|
+
close(): Promise<void>;
|
|
20
|
+
private readonly printUrls;
|
|
21
|
+
private readonly handleHttpListening;
|
|
22
|
+
private readonly handleWatchedFile;
|
|
23
|
+
private handleBundleOutput;
|
|
24
|
+
private handlePatch;
|
|
25
|
+
private handleError;
|
|
26
|
+
private requestFullBuild;
|
|
27
|
+
private waitForInitialBundle;
|
|
28
|
+
private reportOutputError;
|
|
29
|
+
private reportRebuildError;
|
|
30
|
+
}
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Top-level owner of one WX development lifecycle.
|
|
3
|
+
*
|
|
4
|
+
* It serializes every output write, connects DevEngine patches to the update transport, and coalesces conservative full
|
|
5
|
+
* rebuilds. No other module writes plugin-generated WX development files directly.
|
|
6
|
+
*/
|
|
7
|
+
import fs from 'node:fs/promises';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import colors from 'picocolors';
|
|
10
|
+
import { SerializedTaskQueue } from '../../../utils/async.js';
|
|
11
|
+
import { copyDirectoryIfExists, copyFileOrRemove, writeFileAtomically, writeFilesAtomically } from '../../../utils/filesystem.js';
|
|
12
|
+
import { wxDevelopmentDirectory, wxUpdateControlFile, wxUpdateFile } from '../development-files.js';
|
|
13
|
+
import { FullBuildScheduler } from './full-build-scheduler.js';
|
|
14
|
+
import { transformWxCompatibleJavaScript, transformWxOutputChunks } from './js-utils.js';
|
|
15
|
+
import { isWxFullBuildOutput, normalizeWxBundleStyles, setWxAppStyles } from './output.js';
|
|
16
|
+
import { WxUpdateTransport } from './update-transport.js';
|
|
17
|
+
import { ViteBundledDevAdapter } from './vite-bundled-dev-adapter.js';
|
|
18
|
+
const maxRetainedDeltaCount = 1_000;
|
|
19
|
+
const maxRetainedDeltaBytes = 16 * 1024 * 1024;
|
|
20
|
+
const fullBuildDebounceDelay = 100;
|
|
21
|
+
/** Owns one WX bundled-development graph and all writes to its fixed output directory. */
|
|
22
|
+
export class WxDevelopmentSession {
|
|
23
|
+
context;
|
|
24
|
+
server;
|
|
25
|
+
adapter;
|
|
26
|
+
updateTransport;
|
|
27
|
+
outDir;
|
|
28
|
+
initialBundle = Promise.withResolvers();
|
|
29
|
+
outputQueue;
|
|
30
|
+
fullBuildScheduler;
|
|
31
|
+
originalPrintUrls;
|
|
32
|
+
snapshot = { lifecycle: 'open', outputPhase: 'starting', latestAppStyles: '' };
|
|
33
|
+
constructor(context, server) {
|
|
34
|
+
this.context = context;
|
|
35
|
+
this.server = server;
|
|
36
|
+
const config = context.vite;
|
|
37
|
+
this.outDir = path.resolve(config.root, config.build.outDir);
|
|
38
|
+
this.outputQueue = new SerializedTaskQueue((error) => this.reportOutputError(error));
|
|
39
|
+
this.updateTransport = new WxUpdateTransport(server, () => this.requestFullBuild(), (buildId, source) => this.outputQueue.enqueue(async () => {
|
|
40
|
+
// A full build queued before this write invalidates the old batch instead of letting it overwrite
|
|
41
|
+
// the new build's empty update.js.
|
|
42
|
+
if (!this.updateTransport.isCurrentBuild(buildId))
|
|
43
|
+
return;
|
|
44
|
+
await writeFileAtomically(path.join(this.outDir, wxUpdateFile), source);
|
|
45
|
+
}));
|
|
46
|
+
this.adapter = new ViteBundledDevAdapter(config, server, {
|
|
47
|
+
onOutput: (output) => this.handleBundleOutput(output),
|
|
48
|
+
onPatch: (files, output) => this.handlePatch(files, output),
|
|
49
|
+
onError: (message) => this.handleError(message),
|
|
50
|
+
waitForInitialBundle: () => this.waitForInitialBundle()
|
|
51
|
+
});
|
|
52
|
+
this.fullBuildScheduler = new FullBuildScheduler(fullBuildDebounceDelay, () => this.adapter.rebuild(), (error) => this.reportRebuildError(error));
|
|
53
|
+
}
|
|
54
|
+
get config() {
|
|
55
|
+
return this.context.vite;
|
|
56
|
+
}
|
|
57
|
+
install() {
|
|
58
|
+
this.updateTransport.install();
|
|
59
|
+
this.server.httpServer?.once('listening', this.handleHttpListening);
|
|
60
|
+
this.adapter.install();
|
|
61
|
+
this.originalPrintUrls = this.server.printUrls.bind(this.server);
|
|
62
|
+
this.server.printUrls = this.printUrls;
|
|
63
|
+
if (this.config.publicDir)
|
|
64
|
+
this.server.watcher.add(this.config.publicDir);
|
|
65
|
+
this.server.watcher.on('change', this.handleWatchedFile);
|
|
66
|
+
this.server.watcher.on('add', this.handleWatchedFile);
|
|
67
|
+
this.server.watcher.on('unlink', this.handleWatchedFile);
|
|
68
|
+
}
|
|
69
|
+
async close() {
|
|
70
|
+
if (this.snapshot.lifecycle === 'closed')
|
|
71
|
+
return;
|
|
72
|
+
this.snapshot = { ...this.snapshot, lifecycle: 'closed' };
|
|
73
|
+
this.server.watcher.off('change', this.handleWatchedFile);
|
|
74
|
+
this.server.watcher.off('add', this.handleWatchedFile);
|
|
75
|
+
this.server.watcher.off('unlink', this.handleWatchedFile);
|
|
76
|
+
this.server.httpServer?.off('listening', this.handleHttpListening);
|
|
77
|
+
if (this.server.printUrls === this.printUrls && this.originalPrintUrls) {
|
|
78
|
+
this.server.printUrls = this.originalPrintUrls;
|
|
79
|
+
}
|
|
80
|
+
this.updateTransport.close();
|
|
81
|
+
await this.fullBuildScheduler.close();
|
|
82
|
+
await this.outputQueue.waitForIdle();
|
|
83
|
+
}
|
|
84
|
+
printUrls = () => {
|
|
85
|
+
this.originalPrintUrls?.();
|
|
86
|
+
const projectDirectory = relativeToViteConfig(this.outDir, this.config.configFile, this.config.root);
|
|
87
|
+
this.server.config.logger.info(` ${colors.green('➜')} ${colors.bold('WeChat DevTools')}: ${colors.cyan(projectDirectory)}`);
|
|
88
|
+
};
|
|
89
|
+
handleHttpListening = () => {
|
|
90
|
+
this.outputQueue.enqueue(() => writeFileAtomically(path.join(this.outDir, wxUpdateControlFile), this.updateTransport.createControlSource()));
|
|
91
|
+
};
|
|
92
|
+
handleWatchedFile = (file) => {
|
|
93
|
+
if (isFileInside(file, this.config.publicDir)) {
|
|
94
|
+
const destination = path.join(this.outDir, path.relative(this.config.publicDir, file));
|
|
95
|
+
this.outputQueue.enqueue(() => copyFileOrRemove(file, destination));
|
|
96
|
+
this.requestFullBuild();
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
handleBundleOutput(output) {
|
|
100
|
+
const appStyles = normalizeWxBundleStyles(output);
|
|
101
|
+
if (appStyles !== undefined)
|
|
102
|
+
this.snapshot = { ...this.snapshot, latestAppStyles: appStyles };
|
|
103
|
+
if (isWxFullBuildOutput(output) && this.snapshot.latestAppStyles) {
|
|
104
|
+
setWxAppStyles(output, this.snapshot.latestAppStyles);
|
|
105
|
+
}
|
|
106
|
+
if (!isWxFullBuildOutput(output)) {
|
|
107
|
+
this.outputQueue.enqueue(async () => {
|
|
108
|
+
await transformWxOutputChunks(output);
|
|
109
|
+
await writeDevelopmentOutput(this.outDir, output);
|
|
110
|
+
});
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const buildId = this.updateTransport.createBuildId();
|
|
114
|
+
setDevelopmentAsset(output, wxUpdateControlFile, this.updateTransport.createControlSource(buildId));
|
|
115
|
+
setDevelopmentAsset(output, wxUpdateFile, 'void 0;\n');
|
|
116
|
+
this.outputQueue.enqueue(async () => {
|
|
117
|
+
await transformWxOutputChunks(output);
|
|
118
|
+
if (this.snapshot.outputPhase === 'starting') {
|
|
119
|
+
// The directory is plugin-owned; clearing it once removes stale files from previous protocol designs.
|
|
120
|
+
await fs.rm(path.join(this.outDir, wxDevelopmentDirectory), { recursive: true, force: true });
|
|
121
|
+
}
|
|
122
|
+
// Invalidate old HTTP reports before writing the new build epoch into the fixed DevTools directory.
|
|
123
|
+
this.updateTransport.commitFullBuild(buildId);
|
|
124
|
+
await writeDevelopmentOutput(this.outDir, output);
|
|
125
|
+
await copyDirectoryIfExists(this.config.publicDir, this.outDir);
|
|
126
|
+
const moduleCount = this.adapter.registerBundleModules(output);
|
|
127
|
+
this.snapshot = { ...this.snapshot, outputPhase: 'ready' };
|
|
128
|
+
this.initialBundle.resolve();
|
|
129
|
+
this.server.config.logger.info(`[vite-plugin-taro] WX bundle ready (${moduleCount} modules, ${output.length} files)`);
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
handlePatch(files, output) {
|
|
133
|
+
if (!isSafeJavaScriptPatch(files, output)) {
|
|
134
|
+
this.requestFullBuild();
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
this.adapter.registerPatchModules(output.code);
|
|
138
|
+
this.outputQueue.enqueue(async () => {
|
|
139
|
+
const transformed = await this.context.css.transformWxClassNames(output.code, output.filename);
|
|
140
|
+
const compatibleCode = await transformWxCompatibleJavaScript(transformed.code, output.filename);
|
|
141
|
+
if (this.updateTransport.retainedDeltaCount >= maxRetainedDeltaCount ||
|
|
142
|
+
this.updateTransport.retainedDeltaBytes + Buffer.byteLength(compatibleCode) >= maxRetainedDeltaBytes) {
|
|
143
|
+
this.requestFullBuild();
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
this.updateTransport.addDelta(compatibleCode);
|
|
147
|
+
});
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
handleError(message) {
|
|
151
|
+
this.server.config.logger.error('[vite-plugin-taro] WX update failed', { error: new Error(message) });
|
|
152
|
+
}
|
|
153
|
+
requestFullBuild() {
|
|
154
|
+
this.fullBuildScheduler.request();
|
|
155
|
+
}
|
|
156
|
+
async waitForInitialBundle() {
|
|
157
|
+
await this.initialBundle.promise;
|
|
158
|
+
await this.outputQueue.waitForIdle();
|
|
159
|
+
}
|
|
160
|
+
reportOutputError(error) {
|
|
161
|
+
const normalizedError = error instanceof Error ? error : new Error(String(error));
|
|
162
|
+
this.server.config.logger.error(`[vite-plugin-taro] WX development output failed: ${normalizedError.stack ?? normalizedError.message}`);
|
|
163
|
+
}
|
|
164
|
+
reportRebuildError(error) {
|
|
165
|
+
const normalizedError = error instanceof Error ? error : new Error(String(error));
|
|
166
|
+
this.server.config.logger.error('[vite-plugin-taro] WX rebuild failed', { error: normalizedError });
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
function writeDevelopmentOutput(outDir, output) {
|
|
170
|
+
return writeFilesAtomically(output.map((item) => ({
|
|
171
|
+
file: path.join(outDir, item.fileName),
|
|
172
|
+
source: item.type === 'chunk' ? item.code : item.source
|
|
173
|
+
})));
|
|
174
|
+
}
|
|
175
|
+
function setDevelopmentAsset(output, fileName, source) {
|
|
176
|
+
const index = output.findIndex((item) => item.type === 'asset' && item.fileName === fileName);
|
|
177
|
+
const asset = { type: 'asset', fileName, source };
|
|
178
|
+
if (index >= 0)
|
|
179
|
+
output[index] = asset;
|
|
180
|
+
else
|
|
181
|
+
output.push(asset);
|
|
182
|
+
}
|
|
183
|
+
function relativeToViteConfig(outDir, configFile, root) {
|
|
184
|
+
const configDirectory = configFile ? path.dirname(configFile) : root;
|
|
185
|
+
const relativePath = path.relative(configDirectory, outDir).replaceAll('\\', '/');
|
|
186
|
+
if (!relativePath)
|
|
187
|
+
return '.';
|
|
188
|
+
return relativePath.startsWith('.') ? relativePath : `./${relativePath}`;
|
|
189
|
+
}
|
|
190
|
+
function isFileInside(file, directory) {
|
|
191
|
+
if (!directory)
|
|
192
|
+
return false;
|
|
193
|
+
const relative = path.relative(directory, file);
|
|
194
|
+
return relative !== '' && !relative.startsWith('..') && !path.isAbsolute(relative);
|
|
195
|
+
}
|
|
196
|
+
function isSafeJavaScriptPatch(files, output) {
|
|
197
|
+
if (output.type !== 'Patch' || output.hmrBoundaries.length === 0)
|
|
198
|
+
return false;
|
|
199
|
+
if (output.code.includes('__vite__updateStyle') || output.code.includes('.updateStyle('))
|
|
200
|
+
return false;
|
|
201
|
+
return files.every((file) => /\.[cm]?[jt]sx?$/.test(file));
|
|
202
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Full-build scheduling owned by one WX development session. */
|
|
2
|
+
/** Coalesces trailing-edge requests while guaranteeing one full build at a time. */
|
|
3
|
+
export declare class FullBuildScheduler {
|
|
4
|
+
private readonly delay;
|
|
5
|
+
private readonly runBuild;
|
|
6
|
+
private readonly reportError;
|
|
7
|
+
private phase;
|
|
8
|
+
private timer;
|
|
9
|
+
private work;
|
|
10
|
+
constructor(delay: number, runBuild: () => Promise<void>, reportError: (error: unknown) => void);
|
|
11
|
+
request(): void;
|
|
12
|
+
close(): Promise<void>;
|
|
13
|
+
private start;
|
|
14
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/** Full-build scheduling owned by one WX development session. */
|
|
2
|
+
/** Coalesces trailing-edge requests while guaranteeing one full build at a time. */
|
|
3
|
+
export class FullBuildScheduler {
|
|
4
|
+
delay;
|
|
5
|
+
runBuild;
|
|
6
|
+
reportError;
|
|
7
|
+
phase = 'idle';
|
|
8
|
+
timer;
|
|
9
|
+
work;
|
|
10
|
+
constructor(delay, runBuild, reportError) {
|
|
11
|
+
this.delay = delay;
|
|
12
|
+
this.runBuild = runBuild;
|
|
13
|
+
this.reportError = reportError;
|
|
14
|
+
}
|
|
15
|
+
request() {
|
|
16
|
+
switch (this.phase) {
|
|
17
|
+
case 'closed':
|
|
18
|
+
return;
|
|
19
|
+
case 'building':
|
|
20
|
+
this.phase = 'building-with-pending-request';
|
|
21
|
+
return;
|
|
22
|
+
case 'building-with-pending-request':
|
|
23
|
+
return;
|
|
24
|
+
case 'idle':
|
|
25
|
+
case 'scheduled':
|
|
26
|
+
if (this.timer)
|
|
27
|
+
clearTimeout(this.timer);
|
|
28
|
+
this.phase = 'scheduled';
|
|
29
|
+
this.timer = setTimeout(() => this.start(), this.delay);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async close() {
|
|
33
|
+
if (this.phase === 'closed') {
|
|
34
|
+
await this.work;
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
this.phase = 'closed';
|
|
38
|
+
if (this.timer)
|
|
39
|
+
clearTimeout(this.timer);
|
|
40
|
+
this.timer = undefined;
|
|
41
|
+
await this.work;
|
|
42
|
+
}
|
|
43
|
+
start() {
|
|
44
|
+
if (this.phase !== 'scheduled')
|
|
45
|
+
return;
|
|
46
|
+
this.timer = undefined;
|
|
47
|
+
this.phase = 'building';
|
|
48
|
+
this.work = this.runBuild()
|
|
49
|
+
.catch(this.reportError)
|
|
50
|
+
.finally(() => {
|
|
51
|
+
this.work = undefined;
|
|
52
|
+
if (this.phase === 'closed')
|
|
53
|
+
return;
|
|
54
|
+
const repeat = this.phase === 'building-with-pending-request';
|
|
55
|
+
this.phase = 'idle';
|
|
56
|
+
if (repeat)
|
|
57
|
+
this.request();
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { WxOutputFile } from './output.ts';
|
|
2
|
+
/** Lowers generated JavaScript syntax that WeChat's upload parser does not accept. */
|
|
3
|
+
export declare function transformWxCompatibleJavaScript(code: string, filename: string): Promise<string>;
|
|
4
|
+
/** Applies the compatibility transform to every JavaScript chunk in a DevEngine output batch. */
|
|
5
|
+
export declare function transformWxOutputChunks(output: WxOutputFile[]): Promise<void>;
|