@taro-hmr-compile/plugin-webpack 0.0.1 → 0.0.2
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.
|
@@ -4,9 +4,9 @@ interface CreateShellOpt {
|
|
|
4
4
|
page: string;
|
|
5
5
|
framework: 'react';
|
|
6
6
|
compileUrl: string;
|
|
7
|
-
memo: boolean;
|
|
8
7
|
}
|
|
9
8
|
export declare const createReactShell: (opt: CreateShellOpt) => string;
|
|
9
|
+
export declare const wrapReactPage: (source: string, pageName: string) => string;
|
|
10
10
|
interface LoaderOptions {
|
|
11
11
|
appPath: string;
|
|
12
12
|
sourcePath: string;
|
|
@@ -1,19 +1,56 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
37
|
};
|
|
5
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.createReactShell = void 0;
|
|
39
|
+
exports.wrapReactPage = exports.createReactShell = void 0;
|
|
7
40
|
const path_1 = __importDefault(require("path"));
|
|
8
41
|
const utils_1 = require("../utils");
|
|
9
42
|
const compile_state_1 = require("./compile-state");
|
|
43
|
+
const generator_1 = __importDefault(require("@babel/generator"));
|
|
44
|
+
const parser_1 = require("@babel/parser");
|
|
45
|
+
const template_1 = __importDefault(require("@babel/template"));
|
|
46
|
+
const traverse_1 = __importDefault(require("@babel/traverse"));
|
|
47
|
+
const t = __importStar(require("@babel/types"));
|
|
10
48
|
const createReactShell = (opt) => {
|
|
11
|
-
const { page, compileUrl
|
|
49
|
+
const { page, compileUrl } = opt;
|
|
12
50
|
return `
|
|
13
51
|
import { PageShell } from ${JSON.stringify(require.resolve('@taro-hmr-compile/core/runtime'))}
|
|
14
|
-
${memo ? "import React from 'react'" : ''}
|
|
15
52
|
const Page = () => <PageShell page={${JSON.stringify(page)}} compileUrl={${JSON.stringify(compileUrl)}}/>
|
|
16
|
-
export default
|
|
53
|
+
export default Page
|
|
17
54
|
`;
|
|
18
55
|
};
|
|
19
56
|
exports.createReactShell = createReactShell;
|
|
@@ -22,16 +59,73 @@ const createShell = (opt) => {
|
|
|
22
59
|
return (0, exports.createReactShell)(opt);
|
|
23
60
|
throw new Error(`unsupported framework: ${opt.framework}`);
|
|
24
61
|
};
|
|
25
|
-
const
|
|
26
|
-
|
|
62
|
+
const wrapReactPage = (source, pageName) => {
|
|
63
|
+
const ast = (0, parser_1.parse)(source, { sourceType: 'module', plugins: ['typescript', 'jsx'] });
|
|
64
|
+
const runtimeRequest = require.resolve('@taro-hmr-compile/core/runtime');
|
|
65
|
+
(0, traverse_1.default)(ast, {
|
|
66
|
+
Program(programPath) {
|
|
67
|
+
const hasWithHmrPage = () => programPath.node.body.some(node => {
|
|
68
|
+
if (!t.isImportDeclaration(node) || node.source.value !== runtimeRequest)
|
|
69
|
+
return false;
|
|
70
|
+
return node.specifiers.some(specifier => {
|
|
71
|
+
return t.isImportSpecifier(specifier) && t.isIdentifier(specifier.imported, { name: 'withHmrPage' });
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
if (hasWithHmrPage())
|
|
75
|
+
return;
|
|
76
|
+
const withHmrPage = programPath.scope.generateUidIdentifier('withHmrPage');
|
|
77
|
+
programPath.traverse({
|
|
78
|
+
ExportDefaultDeclaration(exportPath) {
|
|
79
|
+
if (hasWithHmrPage())
|
|
80
|
+
return;
|
|
81
|
+
const declaration = exportPath.node.declaration;
|
|
82
|
+
// 跳过只有类型声明、没有函数实现 的 TypeScript 节点
|
|
83
|
+
if (t.isTSDeclareFunction(declaration))
|
|
84
|
+
return;
|
|
85
|
+
const component = (() => {
|
|
86
|
+
// 具名函数或类保留原声明,通过名称引用,避免破坏模块内的其他引用。
|
|
87
|
+
if ((t.isFunctionDeclaration(declaration) || t.isClassDeclaration(declaration)) && declaration.id)
|
|
88
|
+
return t.identifier(declaration.id.name);
|
|
89
|
+
// 标识符、箭头函数、observer(...) 等表达式可以直接作为包装参数。
|
|
90
|
+
if (t.isExpression(declaration))
|
|
91
|
+
return declaration;
|
|
92
|
+
// 匿名函数或类声明需要先转成表达式,才能作为包装参数。
|
|
93
|
+
return t.toExpression(declaration);
|
|
94
|
+
})();
|
|
95
|
+
const defaultExport = template_1.default.statement(`export default %%WRAPPER%%(%%COMPONENT%%, %%PAGE_NAME%%);`)({
|
|
96
|
+
WRAPPER: withHmrPage,
|
|
97
|
+
COMPONENT: component,
|
|
98
|
+
PAGE_NAME: t.stringLiteral(pageName),
|
|
99
|
+
});
|
|
100
|
+
const hasNamedDeclaration = (t.isFunctionDeclaration(declaration) || t.isClassDeclaration(declaration)) && Boolean(declaration.id);
|
|
101
|
+
// 先插入 runtime 导入,让替换后重新入队的默认导出也能识别为已处理。
|
|
102
|
+
programPath.unshiftContainer('body', template_1.default.statement(`import { withHmrPage as %%WRAPPER%% } from %%RUNTIME%%;`)({
|
|
103
|
+
WRAPPER: withHmrPage,
|
|
104
|
+
RUNTIME: t.stringLiteral(runtimeRequest),
|
|
105
|
+
}));
|
|
106
|
+
// 具名函数或类保留声明,再追加包装后的默认导出。
|
|
107
|
+
if (hasNamedDeclaration)
|
|
108
|
+
exportPath.replaceWithMultiple([declaration, defaultExport]);
|
|
109
|
+
// 表达式或匿名声明直接替换为包装后的默认导出。
|
|
110
|
+
if (!hasNamedDeclaration)
|
|
111
|
+
exportPath.replaceWith(defaultExport);
|
|
112
|
+
exportPath.skip();
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
return (0, generator_1.default)(ast).code;
|
|
27
118
|
};
|
|
119
|
+
exports.wrapReactPage = wrapReactPage;
|
|
28
120
|
const lazyCompilerLoader = function (source) {
|
|
29
121
|
const { appPath, framework, appConfig, sourcePath, compileUrl, lazyCompileExclude = [] } = this.getOptions();
|
|
30
122
|
const { dir: resourceDir, name: resourceName } = path_1.default.parse(path_1.default.relative(sourcePath, this.resourcePath));
|
|
31
123
|
const resourcePath = path_1.default.join(resourceDir, resourceName).replace(/\\/g, '/');
|
|
32
124
|
const isPageEntry = (0, utils_1.getAllPages)(appConfig).includes(resourcePath);
|
|
33
|
-
if (!isPageEntry
|
|
125
|
+
if (!isPageEntry)
|
|
34
126
|
return source;
|
|
127
|
+
if ((0, compile_state_1.isPageCompiled)(appPath, resourcePath))
|
|
128
|
+
return (0, exports.wrapReactPage)(source, resourcePath);
|
|
35
129
|
const isExcluded = lazyCompileExclude.some(excludePath => {
|
|
36
130
|
if (!excludePath)
|
|
37
131
|
return false;
|
|
@@ -39,8 +133,8 @@ const lazyCompilerLoader = function (source) {
|
|
|
39
133
|
return normalizedPath.endsWith('/') ? resourcePath.startsWith(normalizedPath) : resourcePath === normalizedPath;
|
|
40
134
|
});
|
|
41
135
|
if (isExcluded)
|
|
42
|
-
return source;
|
|
43
|
-
return createShell({ page: resourcePath, framework, compileUrl
|
|
136
|
+
return (0, exports.wrapReactPage)(source, resourcePath);
|
|
137
|
+
return createShell({ page: resourcePath, framework, compileUrl });
|
|
44
138
|
};
|
|
45
139
|
exports.default = lazyCompilerLoader;
|
|
46
140
|
//# sourceMappingURL=lazy-compiler-loader.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lazy-compiler-loader.js","sourceRoot":"","sources":["../../src/compile/lazy-compiler-loader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"lazy-compiler-loader.js","sourceRoot":"","sources":["../../src/compile/lazy-compiler-loader.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taro-hmr-compile/plugin-webpack",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"@babel/template": "^7.29.7",
|
|
46
46
|
"@babel/traverse": "^7.29.8",
|
|
47
47
|
"@babel/types": "^7.29.8",
|
|
48
|
-
"@taro-hmr-compile/core": "0.0.
|
|
48
|
+
"@taro-hmr-compile/core": "0.0.2",
|
|
49
49
|
"debug": "^4.4.3",
|
|
50
50
|
"lodash": "^4.18.1",
|
|
51
51
|
"tapable": "^2.3.3",
|
|
@@ -3,22 +3,25 @@ import path from "path";
|
|
|
3
3
|
import {getAllPages} from '../utils'
|
|
4
4
|
import {isPageCompiled} from './compile-state'
|
|
5
5
|
import type {AppConfig} from "@tarojs/taro";
|
|
6
|
+
import generator from '@babel/generator'
|
|
7
|
+
import {parse} from '@babel/parser'
|
|
8
|
+
import template from '@babel/template'
|
|
9
|
+
import traverse from '@babel/traverse'
|
|
10
|
+
import * as t from '@babel/types'
|
|
6
11
|
|
|
7
12
|
|
|
8
13
|
interface CreateShellOpt {
|
|
9
14
|
page: string
|
|
10
15
|
framework: 'react'
|
|
11
16
|
compileUrl: string
|
|
12
|
-
memo: boolean
|
|
13
17
|
}
|
|
14
18
|
|
|
15
19
|
export const createReactShell = (opt: CreateShellOpt) => {
|
|
16
|
-
const {page, compileUrl
|
|
20
|
+
const {page, compileUrl} = opt
|
|
17
21
|
return `
|
|
18
22
|
import { PageShell } from ${JSON.stringify(require.resolve('@taro-hmr-compile/core/runtime'))}
|
|
19
|
-
${memo ? "import React from 'react'" : ''}
|
|
20
23
|
const Page = () => <PageShell page={${JSON.stringify(page)}} compileUrl={${JSON.stringify(compileUrl)}}/>
|
|
21
|
-
export default
|
|
24
|
+
export default Page
|
|
22
25
|
`
|
|
23
26
|
}
|
|
24
27
|
|
|
@@ -27,8 +30,69 @@ const createShell = (opt: CreateShellOpt) => {
|
|
|
27
30
|
throw new Error(`unsupported framework: ${opt.framework}`)
|
|
28
31
|
}
|
|
29
32
|
|
|
30
|
-
const
|
|
31
|
-
|
|
33
|
+
export const wrapReactPage = (source: string, pageName: string): string => {
|
|
34
|
+
const ast = parse(source, {sourceType: 'module', plugins: ['typescript', 'jsx']})
|
|
35
|
+
const runtimeRequest = require.resolve('@taro-hmr-compile/core/runtime')
|
|
36
|
+
|
|
37
|
+
traverse(ast, {
|
|
38
|
+
Program(programPath) {
|
|
39
|
+
const hasWithHmrPage = () => programPath.node.body.some(node => {
|
|
40
|
+
if (!t.isImportDeclaration(node) || node.source.value !== runtimeRequest) return false
|
|
41
|
+
|
|
42
|
+
return node.specifiers.some(specifier => {
|
|
43
|
+
return t.isImportSpecifier(specifier) && t.isIdentifier(specifier.imported, {name: 'withHmrPage'})
|
|
44
|
+
})
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
if (hasWithHmrPage()) return
|
|
48
|
+
|
|
49
|
+
const withHmrPage = programPath.scope.generateUidIdentifier('withHmrPage')
|
|
50
|
+
|
|
51
|
+
programPath.traverse({
|
|
52
|
+
ExportDefaultDeclaration(exportPath) {
|
|
53
|
+
if (hasWithHmrPage()) return
|
|
54
|
+
const declaration = exportPath.node.declaration
|
|
55
|
+
|
|
56
|
+
// 跳过只有类型声明、没有函数实现 的 TypeScript 节点
|
|
57
|
+
if (t.isTSDeclareFunction(declaration)) return
|
|
58
|
+
|
|
59
|
+
const component = (() => {
|
|
60
|
+
// 具名函数或类保留原声明,通过名称引用,避免破坏模块内的其他引用。
|
|
61
|
+
if ((t.isFunctionDeclaration(declaration) || t.isClassDeclaration(declaration)) && declaration.id) return t.identifier(declaration.id.name)
|
|
62
|
+
|
|
63
|
+
// 标识符、箭头函数、observer(...) 等表达式可以直接作为包装参数。
|
|
64
|
+
if (t.isExpression(declaration)) return declaration
|
|
65
|
+
|
|
66
|
+
// 匿名函数或类声明需要先转成表达式,才能作为包装参数。
|
|
67
|
+
return t.toExpression(declaration)
|
|
68
|
+
})()
|
|
69
|
+
const defaultExport = template.statement(`export default %%WRAPPER%%(%%COMPONENT%%, %%PAGE_NAME%%);`)({
|
|
70
|
+
WRAPPER: withHmrPage,
|
|
71
|
+
COMPONENT: component,
|
|
72
|
+
PAGE_NAME: t.stringLiteral(pageName),
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
const hasNamedDeclaration = (t.isFunctionDeclaration(declaration) || t.isClassDeclaration(declaration)) && Boolean(declaration.id)
|
|
76
|
+
|
|
77
|
+
// 先插入 runtime 导入,让替换后重新入队的默认导出也能识别为已处理。
|
|
78
|
+
programPath.unshiftContainer('body', template.statement(`import { withHmrPage as %%WRAPPER%% } from %%RUNTIME%%;`)({
|
|
79
|
+
WRAPPER: withHmrPage,
|
|
80
|
+
RUNTIME: t.stringLiteral(runtimeRequest),
|
|
81
|
+
}))
|
|
82
|
+
|
|
83
|
+
// 具名函数或类保留声明,再追加包装后的默认导出。
|
|
84
|
+
if (hasNamedDeclaration) exportPath.replaceWithMultiple([declaration, defaultExport])
|
|
85
|
+
|
|
86
|
+
// 表达式或匿名声明直接替换为包装后的默认导出。
|
|
87
|
+
if (!hasNamedDeclaration) exportPath.replaceWith(defaultExport)
|
|
88
|
+
|
|
89
|
+
exportPath.skip()
|
|
90
|
+
},
|
|
91
|
+
})
|
|
92
|
+
},
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
return generator(ast).code
|
|
32
96
|
}
|
|
33
97
|
|
|
34
98
|
|
|
@@ -50,7 +114,9 @@ const lazyCompilerLoader: LoaderDefinitionFunction<LoaderOptions> = function (so
|
|
|
50
114
|
|
|
51
115
|
const isPageEntry = getAllPages(appConfig).includes(resourcePath)
|
|
52
116
|
|
|
53
|
-
if (!isPageEntry
|
|
117
|
+
if (!isPageEntry) return source
|
|
118
|
+
|
|
119
|
+
if (isPageCompiled(appPath, resourcePath)) return wrapReactPage(source, resourcePath)
|
|
54
120
|
|
|
55
121
|
const isExcluded = lazyCompileExclude.some(excludePath => {
|
|
56
122
|
if (!excludePath) return false
|
|
@@ -58,9 +124,9 @@ const lazyCompilerLoader: LoaderDefinitionFunction<LoaderOptions> = function (so
|
|
|
58
124
|
return normalizedPath.endsWith('/') ? resourcePath.startsWith(normalizedPath) : resourcePath === normalizedPath
|
|
59
125
|
})
|
|
60
126
|
|
|
61
|
-
if (isExcluded) return source
|
|
127
|
+
if (isExcluded) return wrapReactPage(source, resourcePath)
|
|
62
128
|
|
|
63
|
-
return createShell({page: resourcePath, framework, compileUrl
|
|
129
|
+
return createShell({page: resourcePath, framework, compileUrl})
|
|
64
130
|
}
|
|
65
131
|
|
|
66
132
|
export default lazyCompilerLoader
|