vite-plugin-taro-plugin-framework-react 0.1.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/LICENSE +174 -0
- package/README.md +45 -0
- package/dist/api-loader.js +87 -0
- package/dist/api-loader.js.map +1 -0
- package/dist/index.js +763 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime.js +1002 -0
- package/dist/runtime.js.map +1 -0
- package/index.js +3 -0
- package/package.json +54 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,763 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var helper = require('@tarojs/helper');
|
|
6
|
+
var shared = require('@tarojs/shared');
|
|
7
|
+
var tslib = require('tslib');
|
|
8
|
+
var lodash = require('lodash');
|
|
9
|
+
var acorn = require('acorn');
|
|
10
|
+
var walk = require('acorn-walk');
|
|
11
|
+
var path = require('node:path');
|
|
12
|
+
|
|
13
|
+
function _interopNamespaceDefault(e) {
|
|
14
|
+
var n = Object.create(null);
|
|
15
|
+
if (e) {
|
|
16
|
+
Object.keys(e).forEach(function (k) {
|
|
17
|
+
if (k !== 'default') {
|
|
18
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
19
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function () { return e[k]; }
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
n.default = e;
|
|
27
|
+
return Object.freeze(n);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
var acorn__namespace = /*#__PURE__*/_interopNamespaceDefault(acorn);
|
|
31
|
+
var walk__namespace = /*#__PURE__*/_interopNamespaceDefault(walk);
|
|
32
|
+
|
|
33
|
+
function apiLoader (str) {
|
|
34
|
+
return `import {
|
|
35
|
+
useAddToFavorites,
|
|
36
|
+
useDidHide,
|
|
37
|
+
useDidShow,
|
|
38
|
+
useError,
|
|
39
|
+
useLaunch,
|
|
40
|
+
useLoad,
|
|
41
|
+
useOptionMenuClick,
|
|
42
|
+
useKeyboardHeight,
|
|
43
|
+
usePageNotFound,
|
|
44
|
+
usePageScroll,
|
|
45
|
+
usePullDownRefresh,
|
|
46
|
+
usePullIntercept,
|
|
47
|
+
useReachBottom,
|
|
48
|
+
useReady,
|
|
49
|
+
useResize,
|
|
50
|
+
useRouter,
|
|
51
|
+
useSaveExitState,
|
|
52
|
+
useShareAppMessage,
|
|
53
|
+
useShareTimeline,
|
|
54
|
+
useTabItemTap,
|
|
55
|
+
useTitleClick,
|
|
56
|
+
useScope,
|
|
57
|
+
useUnhandledRejection,
|
|
58
|
+
useUnload
|
|
59
|
+
} from '@tarojs/plugin-framework-react/dist/runtime'
|
|
60
|
+
${str}
|
|
61
|
+
|
|
62
|
+
taro.useAddToFavorites = useAddToFavorites
|
|
63
|
+
taro.useDidHide = useDidHide
|
|
64
|
+
taro.useDidShow = useDidShow
|
|
65
|
+
taro.useError = useError
|
|
66
|
+
taro.useLaunch = useLaunch
|
|
67
|
+
taro.useLoad = useLoad
|
|
68
|
+
taro.useOptionMenuClick = useOptionMenuClick
|
|
69
|
+
taro.useKeyboardHeight = useKeyboardHeight
|
|
70
|
+
taro.usePageNotFound = usePageNotFound
|
|
71
|
+
taro.usePageScroll = usePageScroll
|
|
72
|
+
taro.usePullDownRefresh = usePullDownRefresh
|
|
73
|
+
taro.usePullIntercept = usePullIntercept
|
|
74
|
+
taro.useReachBottom = useReachBottom
|
|
75
|
+
taro.useReady = useReady
|
|
76
|
+
taro.useResize = useResize
|
|
77
|
+
taro.useRouter = useRouter
|
|
78
|
+
taro.useSaveExitState = useSaveExitState
|
|
79
|
+
taro.useShareAppMessage = useShareAppMessage
|
|
80
|
+
taro.useShareTimeline = useShareTimeline
|
|
81
|
+
taro.useTabItemTap = useTabItemTap
|
|
82
|
+
taro.useTitleClick = useTitleClick
|
|
83
|
+
taro.useScope = useScope
|
|
84
|
+
taro.useUnhandledRejection = useUnhandledRejection
|
|
85
|
+
taro.useUnload = useUnload
|
|
86
|
+
|
|
87
|
+
export {
|
|
88
|
+
useAddToFavorites,
|
|
89
|
+
useDidHide,
|
|
90
|
+
useDidShow,
|
|
91
|
+
useError,
|
|
92
|
+
useLaunch,
|
|
93
|
+
useLoad,
|
|
94
|
+
useOptionMenuClick,
|
|
95
|
+
useKeyboardHeight,
|
|
96
|
+
usePageNotFound,
|
|
97
|
+
usePageScroll,
|
|
98
|
+
usePullDownRefresh,
|
|
99
|
+
usePullIntercept,
|
|
100
|
+
useReachBottom,
|
|
101
|
+
useReady,
|
|
102
|
+
useResize,
|
|
103
|
+
useRouter,
|
|
104
|
+
useSaveExitState,
|
|
105
|
+
useShareAppMessage,
|
|
106
|
+
useShareTimeline,
|
|
107
|
+
useTabItemTap,
|
|
108
|
+
useTitleClick,
|
|
109
|
+
useScope,
|
|
110
|
+
useUnhandledRejection,
|
|
111
|
+
useUnload
|
|
112
|
+
}
|
|
113
|
+
`;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function addConfig(source) {
|
|
117
|
+
const configsMap = {
|
|
118
|
+
enableShareAppMessage: ['onShareAppMessage', 'useShareAppMessage'],
|
|
119
|
+
enableShareTimeline: ['onShareTimeline', 'useShareTimeline']
|
|
120
|
+
};
|
|
121
|
+
const ast = acorn__namespace.parse(source, {
|
|
122
|
+
ecmaVersion: 'latest',
|
|
123
|
+
sourceType: 'module'
|
|
124
|
+
});
|
|
125
|
+
const additionConfig = {};
|
|
126
|
+
function check(name) {
|
|
127
|
+
Object.keys(configsMap).forEach(configName => {
|
|
128
|
+
const apis = configsMap[configName];
|
|
129
|
+
if (apis.includes(name)) {
|
|
130
|
+
additionConfig[configName] = true;
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
walk__namespace.simple(ast, {
|
|
135
|
+
FunctionExpression(node) {
|
|
136
|
+
if (!node.id || !node.id.name)
|
|
137
|
+
return;
|
|
138
|
+
check(node.id.name);
|
|
139
|
+
},
|
|
140
|
+
FunctionDeclaration(node) {
|
|
141
|
+
if (!node.id || !node.id.name)
|
|
142
|
+
return;
|
|
143
|
+
check(node.id.name);
|
|
144
|
+
},
|
|
145
|
+
CallExpression(node) {
|
|
146
|
+
const { callee } = node;
|
|
147
|
+
if (callee.type === 'Identifier') {
|
|
148
|
+
check(callee.name);
|
|
149
|
+
}
|
|
150
|
+
else if (callee.type === 'MemberExpression') {
|
|
151
|
+
if (callee.property.type === 'Identifier') {
|
|
152
|
+
check(callee.property.name);
|
|
153
|
+
}
|
|
154
|
+
else if (callee.property.type === 'Literal') {
|
|
155
|
+
check(callee.property.value);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
node.arguments.forEach((item) => {
|
|
159
|
+
if (item.type === 'Literal' && item.value) {
|
|
160
|
+
check(item.value);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
},
|
|
164
|
+
ClassDeclaration(node) {
|
|
165
|
+
// 类声明: class Foo {}
|
|
166
|
+
if (node.id && node.id.name) {
|
|
167
|
+
check(node.id.name);
|
|
168
|
+
}
|
|
169
|
+
// 类体方法: class Foo { bar() {} }
|
|
170
|
+
node.body.body.forEach((method) => {
|
|
171
|
+
if (method.type === 'MethodDefinition') {
|
|
172
|
+
if (method.key.type === 'Identifier') {
|
|
173
|
+
check(method.key.name);
|
|
174
|
+
}
|
|
175
|
+
else if (method.key.type === 'Literal') {
|
|
176
|
+
check(method.key.value);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
},
|
|
181
|
+
ClassExpression(node) {
|
|
182
|
+
// 类表达式: const A = class B {}
|
|
183
|
+
if (node.id && node.id.name) {
|
|
184
|
+
check(node.id.name);
|
|
185
|
+
}
|
|
186
|
+
node.body.body.forEach((method) => {
|
|
187
|
+
if (method.type === 'MethodDefinition') {
|
|
188
|
+
if (method.key.type === 'Identifier') {
|
|
189
|
+
check(method.key.name);
|
|
190
|
+
}
|
|
191
|
+
else if (method.key.type === 'Literal') {
|
|
192
|
+
check(method.key.value);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
},
|
|
197
|
+
});
|
|
198
|
+
return additionConfig;
|
|
199
|
+
}
|
|
200
|
+
function getLoaderMeta(framework) {
|
|
201
|
+
const loaderMeta = {
|
|
202
|
+
importFrameworkStatement: `
|
|
203
|
+
import * as React from 'react'
|
|
204
|
+
import ReactDOM from 'react-dom'
|
|
205
|
+
`,
|
|
206
|
+
mockAppStatement: `
|
|
207
|
+
class App extends React.Component {
|
|
208
|
+
render () {
|
|
209
|
+
return this.props.children
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
`,
|
|
213
|
+
frameworkArgs: 'React, ReactDOM, config',
|
|
214
|
+
creator: 'createReactApp',
|
|
215
|
+
creatorLocation: '@tarojs/plugin-framework-react/dist/runtime',
|
|
216
|
+
importFrameworkName: 'React',
|
|
217
|
+
extraImportForWeb: '',
|
|
218
|
+
execBeforeCreateWebApp: '',
|
|
219
|
+
modifyConfig(config, source) {
|
|
220
|
+
Object.assign(config, addConfig(source));
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
if (process.env.TARO_PLATFORM === 'web') {
|
|
224
|
+
if (framework === 'react' || framework === 'preact') {
|
|
225
|
+
const react = framework === 'preact' ? require('preact/compat') : require('react');
|
|
226
|
+
const majorVersion = Number((react.version || '18').split('.')[0]);
|
|
227
|
+
if (majorVersion >= 18) {
|
|
228
|
+
// Note: In react 18 or above, should using react-dom/client
|
|
229
|
+
loaderMeta.importFrameworkStatement = loaderMeta.importFrameworkStatement.replace('\'react-dom\'', '\'react-dom/client\'');
|
|
230
|
+
loaderMeta.extraImportForWeb += `import { findDOMNode, render, unstable_batchedUpdates } from 'react-dom'\n`;
|
|
231
|
+
loaderMeta.execBeforeCreateWebApp += `Object.assign(ReactDOM, { findDOMNode, render, unstable_batchedUpdates })\n`;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
return loaderMeta;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function h5iVitePlugin(ctx, framework) {
|
|
239
|
+
return [
|
|
240
|
+
injectLoaderMeta$2(ctx, framework),
|
|
241
|
+
setTaroApi(),
|
|
242
|
+
esbuildExclude(framework)
|
|
243
|
+
];
|
|
244
|
+
}
|
|
245
|
+
function injectLoaderMeta$2(ctx, framework) {
|
|
246
|
+
function customizer(object = '', sources = '') {
|
|
247
|
+
if ([object, sources].every(e => typeof e === 'string'))
|
|
248
|
+
return object + sources;
|
|
249
|
+
}
|
|
250
|
+
const { runnerUtils } = ctx;
|
|
251
|
+
const { getViteH5CompilerContext } = runnerUtils;
|
|
252
|
+
return {
|
|
253
|
+
name: 'taro-react:loader-meta',
|
|
254
|
+
buildStart() {
|
|
255
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
256
|
+
const viteCompilerContext = yield getViteH5CompilerContext(this);
|
|
257
|
+
if (viteCompilerContext) {
|
|
258
|
+
viteCompilerContext.loaderMeta = lodash.mergeWith(getLoaderMeta(framework), viteCompilerContext.loaderMeta, customizer);
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
function setTaroApi() {
|
|
265
|
+
// dev 环境通过 esbuild 来做; pro 环境通过 rollup load 钩子来做;因为生产环境不会走 esbuild
|
|
266
|
+
return {
|
|
267
|
+
name: 'taro-react:process-import-taro',
|
|
268
|
+
enforce: 'pre',
|
|
269
|
+
config: () => ({
|
|
270
|
+
optimizeDeps: {
|
|
271
|
+
esbuildOptions: {
|
|
272
|
+
plugins: [
|
|
273
|
+
{
|
|
274
|
+
name: 'taro:react-api',
|
|
275
|
+
setup(build) {
|
|
276
|
+
build.onLoad({ filter: helper.REG_TARO_H5_RUNTIME_API }, (args) => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
277
|
+
const input = yield helper.fs.readFile(args.path, 'utf8');
|
|
278
|
+
return {
|
|
279
|
+
contents: apiLoader(input + '\n' + 'const taro = Taro__default\n')
|
|
280
|
+
};
|
|
281
|
+
}));
|
|
282
|
+
},
|
|
283
|
+
}
|
|
284
|
+
]
|
|
285
|
+
}
|
|
286
|
+
},
|
|
287
|
+
}),
|
|
288
|
+
load(id) {
|
|
289
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
290
|
+
if (process.env.NODE_ENV === 'production' && helper.REG_TARO_H5_RUNTIME_API.test(id)) {
|
|
291
|
+
try {
|
|
292
|
+
const input = yield helper.fs.readFile(id, 'utf8');
|
|
293
|
+
return apiLoader(input + '\n' + 'const taro = Taro__default\n');
|
|
294
|
+
}
|
|
295
|
+
catch (_) {
|
|
296
|
+
return null;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
// todo 后面看看能否把 preact 改为虚拟模块
|
|
304
|
+
function esbuildExclude(framework) {
|
|
305
|
+
if (framework !== 'preact')
|
|
306
|
+
return null;
|
|
307
|
+
return {
|
|
308
|
+
name: 'taro-react:esvuild-exclude',
|
|
309
|
+
enforce: 'pre',
|
|
310
|
+
config: () => ({
|
|
311
|
+
optimizeDeps: {
|
|
312
|
+
exclude: ['react', 'preact']
|
|
313
|
+
}
|
|
314
|
+
})
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
function harmonyVitePlugin(ctx, framework) {
|
|
319
|
+
return [
|
|
320
|
+
injectLoaderMeta$1(ctx, framework),
|
|
321
|
+
aliasPlugin$1(ctx, framework),
|
|
322
|
+
];
|
|
323
|
+
}
|
|
324
|
+
function injectLoaderMeta$1(ctx, framework) {
|
|
325
|
+
return {
|
|
326
|
+
name: 'taro-react:loader-meta',
|
|
327
|
+
buildStart() {
|
|
328
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
329
|
+
const { runnerUtils } = ctx;
|
|
330
|
+
const { getViteHarmonyCompilerContext } = runnerUtils;
|
|
331
|
+
const viteCompilerContext = yield getViteHarmonyCompilerContext(this);
|
|
332
|
+
if (viteCompilerContext) {
|
|
333
|
+
viteCompilerContext.loaderMeta || (viteCompilerContext.loaderMeta = {});
|
|
334
|
+
Object.assign(viteCompilerContext.loaderMeta, getLoaderMeta(framework));
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
function aliasPlugin$1(ctx, framework) {
|
|
341
|
+
if (framework === 'react') {
|
|
342
|
+
return {
|
|
343
|
+
name: 'taro-react:alias',
|
|
344
|
+
config(config) {
|
|
345
|
+
var _a;
|
|
346
|
+
const alias = [
|
|
347
|
+
{ find: /react-dom$/, replacement: '@tarojs/react' },
|
|
348
|
+
{ find: /react-dom\/client$/, replacement: '@tarojs/react' },
|
|
349
|
+
];
|
|
350
|
+
const mainFields = ['unpkg', ...helper.defaultMainFields];
|
|
351
|
+
const resolveOptions = {
|
|
352
|
+
basedir: process.cwd(),
|
|
353
|
+
mainFields,
|
|
354
|
+
};
|
|
355
|
+
const isProd = config.mode === 'production';
|
|
356
|
+
// TODO:harmony 目前会导致部分包用 production 版本,部分用 development 版本,导致许多 api 报错
|
|
357
|
+
const isHarmony = ctx.runOpts.options.platform === 'harmony';
|
|
358
|
+
if (!isProd && ((_a = ctx.initialConfig.harmony) === null || _a === void 0 ? void 0 : _a.debugReact) !== true && !isHarmony) {
|
|
359
|
+
// 在React18中,使用了exports字段约定了模块暴露路径,其中并未暴露 ./cjs/ 。这将使上面的alias在编译时报错。相当的tricky。
|
|
360
|
+
// Why writeJson? prebundle will load package.json via readFile to check exports property.
|
|
361
|
+
const reactPkgPath = helper.resolveSync('react/package.json', resolveOptions);
|
|
362
|
+
if (reactPkgPath) {
|
|
363
|
+
const reactPkg = require('react/package.json');
|
|
364
|
+
const reactVersion = (reactPkg.version || '');
|
|
365
|
+
if ((/^[~^]?18/).test(reactVersion) && reactPkg.exports) {
|
|
366
|
+
reactPkg.exports = Object.assign(reactPkg.exports, {
|
|
367
|
+
'./cjs/': './cjs/'
|
|
368
|
+
});
|
|
369
|
+
helper.fs.writeJsonSync(reactPkgPath, reactPkg, { spaces: 2 });
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
return {
|
|
374
|
+
resolve: {
|
|
375
|
+
alias
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
return [];
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
function miniVitePlugin(ctx, framework) {
|
|
385
|
+
return [
|
|
386
|
+
injectLoaderMeta(ctx, framework),
|
|
387
|
+
aliasPlugin(ctx, framework),
|
|
388
|
+
];
|
|
389
|
+
}
|
|
390
|
+
function injectLoaderMeta(ctx, framework) {
|
|
391
|
+
return {
|
|
392
|
+
name: 'taro-react:loader-meta',
|
|
393
|
+
buildStart() {
|
|
394
|
+
const { runnerUtils } = ctx;
|
|
395
|
+
const { getViteMiniCompilerContext } = runnerUtils;
|
|
396
|
+
const viteCompilerContext = getViteMiniCompilerContext(this);
|
|
397
|
+
if (viteCompilerContext) {
|
|
398
|
+
viteCompilerContext.loaderMeta || (viteCompilerContext.loaderMeta = {});
|
|
399
|
+
Object.assign(viteCompilerContext.loaderMeta, getLoaderMeta(framework));
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
function aliasPlugin(ctx, framework) {
|
|
405
|
+
if (framework === 'react') {
|
|
406
|
+
return {
|
|
407
|
+
name: 'taro-react:alias',
|
|
408
|
+
config(config) {
|
|
409
|
+
var _a;
|
|
410
|
+
const alias = [
|
|
411
|
+
{ find: /react-dom$/, replacement: '@tarojs/react' },
|
|
412
|
+
{ find: /react-dom\/client$/, replacement: '@tarojs/react' },
|
|
413
|
+
];
|
|
414
|
+
const mainFields = ['unpkg', ...helper.defaultMainFields];
|
|
415
|
+
const resolveOptions = {
|
|
416
|
+
basedir: process.cwd(),
|
|
417
|
+
mainFields,
|
|
418
|
+
};
|
|
419
|
+
const isProd = config.mode === 'production';
|
|
420
|
+
// TODO:harmony 目前会导致部分包用 production 版本,部分用 development 版本,导致许多 api 报错
|
|
421
|
+
const isHarmony = ctx.runOpts.options.platform === 'harmony';
|
|
422
|
+
if (!isProd && ((_a = ctx.initialConfig.mini) === null || _a === void 0 ? void 0 : _a.debugReact) !== true && !isHarmony) {
|
|
423
|
+
// 不是生产环境,且没有设置 debugReact,则使用压缩版本的 react 依赖,减少体积
|
|
424
|
+
alias.push({ find: /react-reconciler$/, replacement: 'react-reconciler/cjs/react-reconciler.production.min.js' });
|
|
425
|
+
alias.push({ find: /^(?!.*mobx-react$).*react$/, replacement: 'react/cjs/react.production.min.js' });
|
|
426
|
+
alias.push({ find: /scheduler$/, replacement: 'scheduler/cjs/scheduler.production.min.js' });
|
|
427
|
+
alias.push({ find: /react\/jsx-runtime$/, replacement: 'react/cjs/react-jsx-runtime.production.min.js' });
|
|
428
|
+
// 在React18中,使用了exports字段约定了模块暴露路径,其中并未暴露 ./cjs/ 。这将使上面的alias在编译时报错。相当的tricky。
|
|
429
|
+
// Why writeJson? prebundle will load package.json via readFile to check exports property.
|
|
430
|
+
const reactPkgPath = helper.resolveSync('react/package.json', resolveOptions);
|
|
431
|
+
if (reactPkgPath) {
|
|
432
|
+
const reactPkg = require('react/package.json');
|
|
433
|
+
const reactVersion = (reactPkg.version || '');
|
|
434
|
+
if ((/^[~^]?18/).test(reactVersion) && reactPkg.exports) {
|
|
435
|
+
reactPkg.exports = Object.assign(reactPkg.exports, {
|
|
436
|
+
'./cjs/': './cjs/'
|
|
437
|
+
});
|
|
438
|
+
helper.fs.writeJsonSync(reactPkgPath, reactPkg, { spaces: 2 });
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
return {
|
|
443
|
+
resolve: {
|
|
444
|
+
alias
|
|
445
|
+
}
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
return [];
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
function modifyH5WebpackChain(ctx, framework, chain) {
|
|
454
|
+
var _a;
|
|
455
|
+
setLoader$2(framework, chain);
|
|
456
|
+
setPlugin(ctx, framework, chain);
|
|
457
|
+
const { isBuildNativeComp = false } = ((_a = ctx.runOpts) === null || _a === void 0 ? void 0 : _a.options) || {};
|
|
458
|
+
const webpackConfig = chain.toConfig();
|
|
459
|
+
const isProd = webpackConfig.mode === 'production';
|
|
460
|
+
const externals = {};
|
|
461
|
+
if (isBuildNativeComp && isProd) {
|
|
462
|
+
// Note: 该模式不支持 prebundle 优化,不必再处理
|
|
463
|
+
externals.react = {
|
|
464
|
+
commonjs: 'react',
|
|
465
|
+
commonjs2: 'react',
|
|
466
|
+
amd: 'react',
|
|
467
|
+
root: 'React'
|
|
468
|
+
};
|
|
469
|
+
externals['react-dom'] = {
|
|
470
|
+
commonjs: 'react-dom',
|
|
471
|
+
commonjs2: 'react-dom',
|
|
472
|
+
amd: 'react-dom',
|
|
473
|
+
root: 'ReactDOM'
|
|
474
|
+
};
|
|
475
|
+
if (framework === 'preact') {
|
|
476
|
+
externals.preact = 'preact';
|
|
477
|
+
}
|
|
478
|
+
chain.merge({
|
|
479
|
+
externalsType: 'umd'
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
chain.merge({
|
|
483
|
+
externals,
|
|
484
|
+
module: {
|
|
485
|
+
rule: {
|
|
486
|
+
'process-import-taro-h5': {
|
|
487
|
+
test: helper.REG_TARO_H5,
|
|
488
|
+
loader: require.resolve('./api-loader'),
|
|
489
|
+
},
|
|
490
|
+
},
|
|
491
|
+
},
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
function setLoader$2(framework, chain) {
|
|
495
|
+
function customizer(object = '', sources = '') {
|
|
496
|
+
if ([object, sources].every((e) => typeof e === 'string'))
|
|
497
|
+
return object + sources;
|
|
498
|
+
}
|
|
499
|
+
chain.plugin('mainPlugin').tap((args) => {
|
|
500
|
+
args[0].loaderMeta = lodash.mergeWith(getLoaderMeta(framework), args[0].loaderMeta, customizer);
|
|
501
|
+
return args;
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
function setPlugin(ctx, framework, chain) {
|
|
505
|
+
var _a, _b;
|
|
506
|
+
const config = ctx.initialConfig;
|
|
507
|
+
const webpackConfig = chain.toConfig();
|
|
508
|
+
const isProd = webpackConfig.mode === 'production';
|
|
509
|
+
if (!isProd && ((_b = (_a = config.h5) === null || _a === void 0 ? void 0 : _a.devServer) === null || _b === void 0 ? void 0 : _b.hot) !== false) {
|
|
510
|
+
// 默认开启 fast-refresh
|
|
511
|
+
if (framework === 'react') {
|
|
512
|
+
chain.plugin('fastRefreshPlugin').use(require('@pmmmwh/react-refresh-webpack-plugin'));
|
|
513
|
+
}
|
|
514
|
+
else if (framework === 'preact') {
|
|
515
|
+
chain.plugin('hotModuleReplacementPlugin').use(require('webpack').HotModuleReplacementPlugin);
|
|
516
|
+
chain.plugin('fastRefreshPlugin').use(require('@prefresh/webpack'));
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
const mainFields = ['unpkg', ...helper.defaultMainFields];
|
|
520
|
+
const resolveOptions = {
|
|
521
|
+
basedir: process.cwd(),
|
|
522
|
+
mainFields,
|
|
523
|
+
};
|
|
524
|
+
if (framework === 'react') {
|
|
525
|
+
const alias = chain.resolve.alias;
|
|
526
|
+
// Note: 本地 link 调试时,避免 react 重复打包
|
|
527
|
+
alias.set('react$', helper.resolveSync('react', resolveOptions));
|
|
528
|
+
alias.set('react-dom$', helper.resolveSync('react-dom', resolveOptions));
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
function modifyHarmonyWebpackChain(ctx, framework, chain) {
|
|
533
|
+
setAlias$2(ctx, framework, chain);
|
|
534
|
+
setLoader$1(framework, chain);
|
|
535
|
+
}
|
|
536
|
+
function setAlias$2(ctx, framework, chain) {
|
|
537
|
+
var _a;
|
|
538
|
+
const config = ctx.initialConfig;
|
|
539
|
+
const alias = chain.resolve.alias;
|
|
540
|
+
const mainFields = ['unpkg', ...helper.defaultMainFields];
|
|
541
|
+
const resolveOptions = {
|
|
542
|
+
basedir: process.cwd(),
|
|
543
|
+
mainFields,
|
|
544
|
+
};
|
|
545
|
+
if (framework === 'react') {
|
|
546
|
+
alias.set('react-dom$', '@tarojs/react');
|
|
547
|
+
alias.set('react-dom/client$', '@tarojs/react');
|
|
548
|
+
const webpackConfig = chain.toConfig();
|
|
549
|
+
const isProd = webpackConfig.mode === 'production';
|
|
550
|
+
if (!isProd && ((_a = config.harmony) === null || _a === void 0 ? void 0 : _a.debugReact) !== true) {
|
|
551
|
+
// 不是生产环境,且没有设置 debugReact,则使用压缩版本的 react 依赖,减少体积
|
|
552
|
+
// 兼容pnpm workspace
|
|
553
|
+
const reactModulePath = helper.resolveSync('react', resolveOptions);
|
|
554
|
+
const newFilePath = path.join(path.dirname(reactModulePath), 'cjs', 'react.production.min.js');
|
|
555
|
+
alias.set('react-reconciler$', 'react-reconciler/cjs/react-reconciler.production.min.js');
|
|
556
|
+
alias.set('react$', newFilePath);
|
|
557
|
+
alias.set('react/jsx-runtime$', 'react/cjs/react-jsx-runtime.production.min.js');
|
|
558
|
+
// 在React18中,使用了exports字段约定了模块暴露路径,其中并未暴露 ./cjs/ 。这将使上面的alias在编译时报错。相当的tricky。
|
|
559
|
+
// Why writeJson? prebundle will load package.json via readFile to check exports property.
|
|
560
|
+
const reactPkgPath = helper.resolveSync('react/package.json', resolveOptions);
|
|
561
|
+
if (reactPkgPath) {
|
|
562
|
+
const reactPkg = require('react/package.json');
|
|
563
|
+
const reactVersion = reactPkg.version || '';
|
|
564
|
+
if (/^[~^]?18/.test(reactVersion) && reactPkg.exports) {
|
|
565
|
+
reactPkg.exports = Object.assign(reactPkg.exports, {
|
|
566
|
+
'./cjs/': './cjs/',
|
|
567
|
+
});
|
|
568
|
+
helper.fs.writeJsonSync(reactPkgPath, reactPkg, { spaces: 2 });
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
function setLoader$1(framework, chain) {
|
|
575
|
+
chain.plugin('mainPlugin').tap((args) => {
|
|
576
|
+
var _a;
|
|
577
|
+
(_a = args[0]).loaderMeta || (_a.loaderMeta = {});
|
|
578
|
+
Object.assign(args[0].loaderMeta, getLoaderMeta(framework));
|
|
579
|
+
return args;
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
function modifyMiniWebpackChain(ctx, framework, chain) {
|
|
584
|
+
setAlias$1(ctx, framework, chain);
|
|
585
|
+
setLoader(framework, chain);
|
|
586
|
+
}
|
|
587
|
+
function setAlias$1(ctx, framework, chain) {
|
|
588
|
+
var _a;
|
|
589
|
+
const config = ctx.initialConfig;
|
|
590
|
+
const alias = chain.resolve.alias;
|
|
591
|
+
const mainFields = ['unpkg', ...helper.defaultMainFields];
|
|
592
|
+
const resolveOptions = {
|
|
593
|
+
basedir: process.cwd(),
|
|
594
|
+
mainFields,
|
|
595
|
+
};
|
|
596
|
+
if (framework === 'react') {
|
|
597
|
+
alias.set('react-dom$', '@tarojs/react');
|
|
598
|
+
alias.set('react-dom/client$', '@tarojs/react');
|
|
599
|
+
const webpackConfig = chain.toConfig();
|
|
600
|
+
const isProd = webpackConfig.mode === 'production';
|
|
601
|
+
if (!isProd && ((_a = config.mini) === null || _a === void 0 ? void 0 : _a.debugReact) !== true) {
|
|
602
|
+
// 不是生产环境,且没有设置 debugReact,则使用压缩版本的 react 依赖,减少体积
|
|
603
|
+
// 兼容pnpm workspace
|
|
604
|
+
const reactModulePath = helper.resolveSync('react', resolveOptions);
|
|
605
|
+
const newFilePath = path.join(path.dirname(reactModulePath), 'cjs', 'react.production.min.js');
|
|
606
|
+
alias.set('react-reconciler$', 'react-reconciler/cjs/react-reconciler.production.min.js');
|
|
607
|
+
alias.set(/^(?!.*mobx-react$).*react$/, newFilePath);
|
|
608
|
+
alias.set('react/jsx-runtime$', 'react/cjs/react-jsx-runtime.production.min.js');
|
|
609
|
+
// 在React18中,使用了exports字段约定了模块暴露路径,其中并未暴露 ./cjs/ 。这将使上面的alias在编译时报错。相当的tricky。
|
|
610
|
+
// Why writeJson? prebundle will load package.json via readFile to check exports property.
|
|
611
|
+
const reactPkgPath = helper.resolveSync('react/package.json', resolveOptions);
|
|
612
|
+
if (reactPkgPath) {
|
|
613
|
+
const reactPkg = require('react/package.json');
|
|
614
|
+
const reactVersion = reactPkg.version || '';
|
|
615
|
+
if (/^[~^]?18/.test(reactVersion) && reactPkg.exports) {
|
|
616
|
+
reactPkg.exports = Object.assign(reactPkg.exports, {
|
|
617
|
+
'./cjs/': './cjs/',
|
|
618
|
+
});
|
|
619
|
+
helper.fs.writeJsonSync(reactPkgPath, reactPkg, { spaces: 2 });
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
function setLoader(framework, chain) {
|
|
626
|
+
chain.plugin('miniPlugin').tap((args) => {
|
|
627
|
+
var _a;
|
|
628
|
+
(_a = args[0]).loaderMeta || (_a.loaderMeta = {});
|
|
629
|
+
Object.assign(args[0].loaderMeta, getLoaderMeta(framework));
|
|
630
|
+
return args;
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
function isReactLike(framework = 'react') {
|
|
635
|
+
return ['react', 'preact'].includes(framework);
|
|
636
|
+
}
|
|
637
|
+
var index = (ctx) => {
|
|
638
|
+
const { framework = 'react' } = ctx.initialConfig;
|
|
639
|
+
if (!isReactLike(framework))
|
|
640
|
+
return;
|
|
641
|
+
ctx.modifyWebpackChain(({ chain }) => {
|
|
642
|
+
// 通用
|
|
643
|
+
setAlias(framework, chain);
|
|
644
|
+
if (process.env.TARO_PLATFORM === 'web') {
|
|
645
|
+
// H5
|
|
646
|
+
modifyH5WebpackChain(ctx, framework, chain);
|
|
647
|
+
}
|
|
648
|
+
else if (process.env.TARO_PLATFORM === 'harmony' || process.env.TARO_ENV === 'harmony') {
|
|
649
|
+
// 鸿蒙
|
|
650
|
+
modifyHarmonyWebpackChain(ctx, framework, chain);
|
|
651
|
+
}
|
|
652
|
+
else {
|
|
653
|
+
// 小程序
|
|
654
|
+
modifyMiniWebpackChain(ctx, framework, chain);
|
|
655
|
+
}
|
|
656
|
+
});
|
|
657
|
+
ctx.modifyRunnerOpts(({ opts }) => {
|
|
658
|
+
if (!(opts === null || opts === void 0 ? void 0 : opts.compiler))
|
|
659
|
+
return;
|
|
660
|
+
if (shared.isString(opts.compiler)) {
|
|
661
|
+
opts.compiler = {
|
|
662
|
+
type: opts.compiler,
|
|
663
|
+
};
|
|
664
|
+
}
|
|
665
|
+
const { compiler } = opts;
|
|
666
|
+
if (compiler.type === 'webpack5') {
|
|
667
|
+
// 提供给 webpack5 依赖预编译收集器的第三方依赖
|
|
668
|
+
const deps = ['react', 'react-dom', 'react/jsx-runtime', '@tarojs/plugin-framework-react/dist/runtime'];
|
|
669
|
+
compiler.prebundle || (compiler.prebundle = {});
|
|
670
|
+
const prebundleOptions = compiler.prebundle;
|
|
671
|
+
prebundleOptions.include || (prebundleOptions.include = []);
|
|
672
|
+
prebundleOptions.include = prebundleOptions.include.concat(deps);
|
|
673
|
+
prebundleOptions.exclude || (prebundleOptions.exclude = []);
|
|
674
|
+
prebundleOptions.exclude.push(/mobx/); // 依赖会对 webpack 修改,默认排除
|
|
675
|
+
if (prebundleOptions.enable === false)
|
|
676
|
+
return;
|
|
677
|
+
const taroReactPlugin = {
|
|
678
|
+
name: 'taroReactPlugin',
|
|
679
|
+
setup(build) {
|
|
680
|
+
build.onLoad({ filter: helper.REG_TARO_H5 }, ({ path }) => {
|
|
681
|
+
const content = helper.fs.readFileSync(path).toString();
|
|
682
|
+
return {
|
|
683
|
+
contents: require('./api-loader')(content),
|
|
684
|
+
};
|
|
685
|
+
});
|
|
686
|
+
}
|
|
687
|
+
};
|
|
688
|
+
prebundleOptions.esbuild || (prebundleOptions.esbuild = {});
|
|
689
|
+
const esbuildConfig = prebundleOptions.esbuild;
|
|
690
|
+
esbuildConfig.plugins || (esbuildConfig.plugins = []);
|
|
691
|
+
esbuildConfig.plugins.push(taroReactPlugin);
|
|
692
|
+
}
|
|
693
|
+
else if (compiler.type === 'vite') {
|
|
694
|
+
compiler.vitePlugins || (compiler.vitePlugins = []);
|
|
695
|
+
compiler.vitePlugins.push(viteCommonPlugin(framework));
|
|
696
|
+
compiler.vitePlugins.push(VitePresetPlugin(framework));
|
|
697
|
+
if (process.env.TARO_PLATFORM === 'web') {
|
|
698
|
+
// H5
|
|
699
|
+
compiler.vitePlugins.push(h5iVitePlugin(ctx, framework));
|
|
700
|
+
}
|
|
701
|
+
else if (process.env.TARO_PLATFORM === 'harmony' || process.env.TARO_ENV === 'harmony') {
|
|
702
|
+
// 鸿蒙
|
|
703
|
+
compiler.vitePlugins.push(harmonyVitePlugin(ctx, framework));
|
|
704
|
+
}
|
|
705
|
+
else {
|
|
706
|
+
// 小程序
|
|
707
|
+
compiler.vitePlugins.push(miniVitePlugin(ctx, framework));
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
});
|
|
711
|
+
};
|
|
712
|
+
function setAlias(framework, chain) {
|
|
713
|
+
const alias = chain.resolve.alias;
|
|
714
|
+
if (framework === 'preact') {
|
|
715
|
+
alias.set('react', 'preact/compat');
|
|
716
|
+
alias.set('react-dom/test-utils', 'preact/test-utils');
|
|
717
|
+
alias.set('react-dom', 'preact/compat');
|
|
718
|
+
alias.set('react/jsx-runtime', 'preact/jsx-runtime');
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
function VitePresetPlugin(framework) {
|
|
722
|
+
return framework === 'preact'
|
|
723
|
+
? require('@preact/preset-vite').preact({
|
|
724
|
+
babel: {
|
|
725
|
+
plugins: [
|
|
726
|
+
['@babel/plugin-proposal-decorators', { legacy: true }],
|
|
727
|
+
['@babel/plugin-transform-class-properties', { loose: true }],
|
|
728
|
+
],
|
|
729
|
+
},
|
|
730
|
+
})
|
|
731
|
+
: require('@vitejs/plugin-react').default({
|
|
732
|
+
babel: {
|
|
733
|
+
plugins: [
|
|
734
|
+
['@babel/plugin-proposal-decorators', { legacy: true }],
|
|
735
|
+
['@babel/plugin-transform-class-properties', { loose: true }],
|
|
736
|
+
],
|
|
737
|
+
},
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
function viteCommonPlugin(framework) {
|
|
741
|
+
return {
|
|
742
|
+
name: 'taro-react:common',
|
|
743
|
+
config() {
|
|
744
|
+
const alias = framework === 'preact'
|
|
745
|
+
? [
|
|
746
|
+
{ find: 'react', replacement: 'preact/compat' },
|
|
747
|
+
{ find: 'react-dom/test-utils', replacement: 'preact/test-utils' },
|
|
748
|
+
{ find: 'react-dom', replacement: 'preact/compat' },
|
|
749
|
+
{ find: 'react/jsx-runtime', replacement: 'preact/jsx-runtime' },
|
|
750
|
+
]
|
|
751
|
+
: [];
|
|
752
|
+
return {
|
|
753
|
+
resolve: {
|
|
754
|
+
alias,
|
|
755
|
+
},
|
|
756
|
+
};
|
|
757
|
+
},
|
|
758
|
+
};
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
exports.default = index;
|
|
762
|
+
exports.isReactLike = isReactLike;
|
|
763
|
+
//# sourceMappingURL=index.js.map
|