@taro-hmr-compile/plugin-webpack 0.0.1-alpha.3

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.
Files changed (46) hide show
  1. package/dist/compile/compile-state.d.ts +3 -0
  2. package/dist/compile/compile-state.js +21 -0
  3. package/dist/compile/compile-state.js.map +1 -0
  4. package/dist/compile/hmr-compile-loader.d.ts +11 -0
  5. package/dist/compile/hmr-compile-loader.js +52 -0
  6. package/dist/compile/hmr-compile-loader.js.map +1 -0
  7. package/dist/compile/hmr-compiler-plugin.d.ts +38 -0
  8. package/dist/compile/hmr-compiler-plugin.js +158 -0
  9. package/dist/compile/hmr-compiler-plugin.js.map +1 -0
  10. package/dist/compile/inject-app-hmr-runtime.d.ts +1 -0
  11. package/dist/compile/inject-app-hmr-runtime.js +46 -0
  12. package/dist/compile/inject-app-hmr-runtime.js.map +1 -0
  13. package/dist/constants.d.ts +3 -0
  14. package/dist/constants.js +7 -0
  15. package/dist/constants.js.map +1 -0
  16. package/dist/index.d.ts +8 -0
  17. package/dist/index.js +49 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/patch/hmr-patch-manager.d.ts +30 -0
  20. package/dist/patch/hmr-patch-manager.js +75 -0
  21. package/dist/patch/hmr-patch-manager.js.map +1 -0
  22. package/dist/patch/hmr-patch-plugin.d.ts +16 -0
  23. package/dist/patch/hmr-patch-plugin.js +239 -0
  24. package/dist/patch/hmr-patch-plugin.js.map +1 -0
  25. package/dist/patch/hmr-patch-runtime-plugin.d.ts +4 -0
  26. package/dist/patch/hmr-patch-runtime-plugin.js +142 -0
  27. package/dist/patch/hmr-patch-runtime-plugin.js.map +1 -0
  28. package/dist/server/hmr-server-plugin.d.ts +13 -0
  29. package/dist/server/hmr-server-plugin.js +29 -0
  30. package/dist/server/hmr-server-plugin.js.map +1 -0
  31. package/dist/utils.d.ts +4 -0
  32. package/dist/utils.js +25 -0
  33. package/dist/utils.js.map +1 -0
  34. package/package.json +51 -0
  35. package/src/compile/compile-state.ts +15 -0
  36. package/src/compile/hmr-compile-loader.ts +72 -0
  37. package/src/compile/hmr-compiler-plugin.ts +191 -0
  38. package/src/compile/inject-app-hmr-runtime.ts +44 -0
  39. package/src/constants.ts +5 -0
  40. package/src/index.ts +67 -0
  41. package/src/patch/hmr-patch-manager.ts +102 -0
  42. package/src/patch/hmr-patch-plugin.ts +237 -0
  43. package/src/patch/hmr-patch-runtime-plugin.ts +150 -0
  44. package/src/server/hmr-server-plugin.ts +34 -0
  45. package/src/utils.ts +25 -0
  46. package/tsconfig.json +21 -0
@@ -0,0 +1,239 @@
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
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.HmrPatchPlugin = void 0;
40
+ const generator_1 = __importDefault(require("@babel/generator"));
41
+ const parser_1 = require("@babel/parser");
42
+ const template_1 = __importDefault(require("@babel/template"));
43
+ const traverse_1 = __importDefault(require("@babel/traverse"));
44
+ const t = __importStar(require("@babel/types"));
45
+ const webpack_sources_1 = require("webpack-sources");
46
+ const constants_1 = require("../constants");
47
+ const hmr_compiler_plugin_1 = require("../compile/hmr-compiler-plugin");
48
+ const hmr_patch_manager_1 = require("../patch/hmr-patch-manager");
49
+ const hmr_patch_runtime_plugin_1 = require("./hmr-patch-runtime-plugin");
50
+ const PLUGIN_NAME = 'HmrPatchPlugin';
51
+ const HOT_UPDATE_MANIFEST_SUFFIX = '.hot-update.json';
52
+ const HOT_UPDATE_SCRIPT_SUFFIX = '.hot-update.js';
53
+ const HOT_UPDATE_HASH_PATTERN = /\.([0-9a-f]+)\.hot-update\.json$/i;
54
+ const STYLE_ASSET_PATTERN = /\.(?:css|wxss|acss|ttss|qss|jxss)(?:\.map)?$/i;
55
+ const TEMPLATE_RUNTIME_ASSET_PATTERN = /(?:^|\/)(?:base\.wxml|utils\.wxs)$/i;
56
+ const collectModuleFactories = (source, moduleFactories) => {
57
+ const ast = (0, parser_1.parse)(`(${source})`, { sourceType: 'script' });
58
+ const statement = ast.program.body[0];
59
+ if (!t.isExpressionStatement(statement) || !t.isObjectExpression(statement.expression)) {
60
+ throw new Error('[taro-hmr-compile] Page Chunk 模块段不是对象表达式');
61
+ }
62
+ statement.expression.properties.forEach(property => {
63
+ if (!t.isObjectProperty(property) || !t.isExpression(property.value)) {
64
+ throw new Error('[taro-hmr-compile] Page Chunk 模块对象包含无法识别的属性');
65
+ }
66
+ const { key } = property;
67
+ let moduleId;
68
+ if (t.isStringLiteral(key) || t.isNumericLiteral(key))
69
+ moduleId = String(key.value);
70
+ else if (t.isIdentifier(key) && !property.computed)
71
+ moduleId = key.name;
72
+ else
73
+ throw new Error('[taro-hmr-compile] Page Chunk 模块对象包含无法识别的模块 ID');
74
+ moduleFactories.set(moduleId, property.value);
75
+ });
76
+ };
77
+ /** 将本轮 Webpack hot-update 产物转换为内部 update 表示。 */
78
+ const createUpdatePatch = (toHash, assets) => {
79
+ const manifestAsset = assets.manifests[0];
80
+ const hashMatch = manifestAsset.name.match(HOT_UPDATE_HASH_PATTERN);
81
+ if (!hashMatch)
82
+ throw new Error(`[taro-hmr-compile] 无法从 ${manifestAsset.name} 提取 HMR 基线 hash`);
83
+ const moduleFactories = new Map();
84
+ assets.scripts.forEach(asset => {
85
+ const ast = (0, parser_1.parse)(asset.source.source().toString(), { sourceType: 'script' });
86
+ (0, traverse_1.default)(ast, {
87
+ CallExpression(nodePath) {
88
+ const { callee } = nodePath.node;
89
+ if (!t.isMemberExpression(callee) || !t.isIdentifier(callee.object, { name: 'wx' }))
90
+ return;
91
+ if (!t.isStringLiteral(callee.property) || !callee.property.value.startsWith('webpackHotUpdate'))
92
+ return;
93
+ const modules = nodePath.node.arguments[1];
94
+ if (!t.isObjectExpression(modules))
95
+ return;
96
+ modules.properties.forEach(property => {
97
+ if (!t.isObjectProperty(property) || !t.isExpression(property.value)) {
98
+ throw new Error('[taro-hmr-compile] HMR 模块对象包含无法识别的属性');
99
+ }
100
+ const { key } = property;
101
+ let moduleId;
102
+ if (t.isStringLiteral(key) || t.isNumericLiteral(key))
103
+ moduleId = String(key.value);
104
+ else if (t.isIdentifier(key) && !property.computed)
105
+ moduleId = key.name;
106
+ else
107
+ throw new Error('[taro-hmr-compile] HMR 模块对象包含无法识别的模块 ID');
108
+ moduleFactories.set(moduleId, property.value);
109
+ });
110
+ },
111
+ });
112
+ });
113
+ const removedModules = new Set();
114
+ assets.manifests.forEach(asset => {
115
+ var _a;
116
+ const manifest = JSON.parse(asset.source.source().toString());
117
+ (_a = manifest.m) === null || _a === void 0 ? void 0 : _a.forEach(moduleId => removedModules.add(String(moduleId)));
118
+ });
119
+ return {
120
+ type: 'update',
121
+ fromHash: hashMatch[1],
122
+ toHash,
123
+ moduleFactories,
124
+ removedModules: Array.from(removedModules),
125
+ };
126
+ };
127
+ /** 将内部 Patch 表示序列化为固定 patch.js。 */
128
+ const createPatchAssetSource = (patches) => {
129
+ const buildBootstrapPatchNode = template_1.default.expression(`({
130
+ type: 'bootstrap',
131
+ modules: %%MODULES%%
132
+ })`);
133
+ const buildUpdatePatchNode = template_1.default.expression(`({
134
+ type: 'update',
135
+ fromHash: %%FROM_HASH%%,
136
+ toHash: %%TO_HASH%%,
137
+ modules: %%MODULES%%,
138
+ removedModules: %%REMOVED_MODULES%%
139
+ })`);
140
+ const patchNodes = patches.map(patch => {
141
+ const modules = t.objectExpression(Array.from(patch.moduleFactories, ([moduleId, factory]) => t.objectProperty(t.stringLiteral(moduleId), factory)));
142
+ if (patch.type === 'bootstrap')
143
+ return buildBootstrapPatchNode({ MODULES: modules });
144
+ return buildUpdatePatchNode({
145
+ FROM_HASH: t.stringLiteral(patch.fromHash),
146
+ TO_HASH: t.stringLiteral(patch.toHash),
147
+ MODULES: modules,
148
+ REMOVED_MODULES: t.arrayExpression(patch.removedModules.map(moduleId => t.stringLiteral(moduleId))),
149
+ });
150
+ });
151
+ const statements = template_1.default.statements('module.exports = %%PATCHES%%;')({ PATCHES: t.arrayExpression(patchNodes) });
152
+ return (0, generator_1.default)(t.program(statements)).code;
153
+ };
154
+ const isPassthroughAsset = (assetName) => {
155
+ return STYLE_ASSET_PATTERN.test(assetName) || TEMPLATE_RUNTIME_ASSET_PATTERN.test(assetName);
156
+ };
157
+ class HmrPatchPlugin {
158
+ constructor(options) {
159
+ var _a;
160
+ this.hasCompletedInitialBuild = false;
161
+ this.emittedAssetSources = new Map();
162
+ this.patchManager = new hmr_patch_manager_1.HmrPatchManager((_a = options.patchHistoryLimit) !== null && _a !== void 0 ? _a : constants_1.DEFAULT_HMR_PATCH_HISTORY_LIMIT);
163
+ }
164
+ apply(compiler) {
165
+ new hmr_patch_runtime_plugin_1.HmrPatchRuntimePlugin().apply(compiler);
166
+ compiler.hooks.compilation.tap(PLUGIN_NAME, compilation => {
167
+ const initialPageFactories = new Map();
168
+ hmr_compiler_plugin_1.HmrCompilerPlugin.getCompilationHooks(compilation).pageChunkModules.tap(PLUGIN_NAME, source => {
169
+ collectModuleFactories(source, initialPageFactories);
170
+ });
171
+ // 等 Webpack 生成完整的 hot-update assets 后,再统一转换成固定的 patch.js。
172
+ const stage = compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_REPORT;
173
+ compilation.hooks.processAssets.tap({ name: PLUGIN_NAME, stage }, () => {
174
+ this.processAssets(compilation, initialPageFactories);
175
+ });
176
+ });
177
+ compiler.hooks.afterEmit.tap(PLUGIN_NAME, compilation => {
178
+ const isSuccessful = compilation.errors.length === 0 && Boolean(compilation.hash);
179
+ this.hasCompletedInitialBuild = this.hasCompletedInitialBuild || isSuccessful;
180
+ });
181
+ compiler.hooks.watchClose.tap(PLUGIN_NAME, () => this.reset());
182
+ }
183
+ processAssets(compilation, initialPageFactories) {
184
+ if (!compilation.hash || compilation.errors.length > 0)
185
+ return;
186
+ const originalAssets = compilation.getAssets();
187
+ if (!this.hasCompletedInitialBuild) {
188
+ this.patchManager.clear();
189
+ this.emittedAssetSources.clear();
190
+ originalAssets.forEach(asset => {
191
+ if (isPassthroughAsset(asset.name)) {
192
+ this.emittedAssetSources.set(asset.name, asset.source.source().toString());
193
+ }
194
+ });
195
+ this.patchManager.setBootstrap(initialPageFactories);
196
+ this.emitPatchAsset(compilation, false);
197
+ return;
198
+ }
199
+ const hotUpdateAssets = {
200
+ manifests: originalAssets.filter(asset => asset.name.endsWith(HOT_UPDATE_MANIFEST_SUFFIX)),
201
+ scripts: originalAssets.filter(asset => asset.name.endsWith(HOT_UPDATE_SCRIPT_SUFFIX)),
202
+ };
203
+ if (hotUpdateAssets.manifests.length) {
204
+ this.patchManager.appendUpdate(createUpdatePatch(compilation.hash, hotUpdateAssets));
205
+ this.emitPatchAsset(compilation, true);
206
+ }
207
+ // 增量 compilation 仍可能包含普通 chunk 资产,不能让它们覆盖初始 PageShell。
208
+ this.removeSupersededAssets(compilation, originalAssets);
209
+ }
210
+ /** 热更新转换完成后,保留固定 patch 与发生变化的模板、平台样式资产。 */
211
+ removeSupersededAssets(compilation, assets) {
212
+ assets.forEach(asset => {
213
+ if (asset.name === constants_1.HMR_PATCH_ASSET)
214
+ return;
215
+ if (!isPassthroughAsset(asset.name))
216
+ return compilation.deleteAsset(asset.name);
217
+ const source = asset.source.source().toString();
218
+ const previousSource = this.emittedAssetSources.get(asset.name);
219
+ this.emittedAssetSources.set(asset.name, source);
220
+ if (previousSource === source)
221
+ compilation.deleteAsset(asset.name);
222
+ });
223
+ }
224
+ emitPatchAsset(compilation, isHotUpdate) {
225
+ const source = new webpack_sources_1.RawSource(createPatchAssetSource(this.patchManager.getPatches()));
226
+ const assetInfo = { hotModuleReplacement: isHotUpdate };
227
+ if (compilation.getAsset(constants_1.HMR_PATCH_ASSET))
228
+ compilation.updateAsset(constants_1.HMR_PATCH_ASSET, source, assetInfo);
229
+ else
230
+ compilation.emitAsset(constants_1.HMR_PATCH_ASSET, source, assetInfo);
231
+ }
232
+ reset() {
233
+ this.hasCompletedInitialBuild = false;
234
+ this.emittedAssetSources.clear();
235
+ this.patchManager.clear();
236
+ }
237
+ }
238
+ exports.HmrPatchPlugin = HmrPatchPlugin;
239
+ //# sourceMappingURL=hmr-patch-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hmr-patch-plugin.js","sourceRoot":"","sources":["../../src/patch/hmr-patch-plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import webpack from 'webpack';
2
+ export declare class HmrPatchRuntimePlugin {
3
+ apply(compiler: webpack.Compiler): void;
4
+ }
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.HmrPatchRuntimePlugin = void 0;
7
+ const parser_1 = require("@babel/parser");
8
+ const generator_1 = __importDefault(require("@babel/generator"));
9
+ const webpack_1 = __importDefault(require("webpack"));
10
+ const PLUGIN_NAME = 'HmrPatchRuntimePlugin';
11
+ const hotRuntimeCode = `
12
+ var applyQueue = Promise.resolve();
13
+ var applySequence = 0;
14
+
15
+ ${webpack_1.default.RuntimeGlobals.require}.miniHmr = {
16
+ applyPatch: function(patch) {
17
+ if (!patch) return Promise.resolve();
18
+
19
+ var applyId = ++applySequence;
20
+ var enqueueHash = ${webpack_1.default.RuntimeGlobals.getFullHash}();
21
+ // 微信要求 Page() 在页面脚本求值期间同步注册。bootstrap 只补齐缺失工厂,
22
+ // 不会覆盖现有模块;必须在 Page Chunk startup 继续执行前同步完成。
23
+ if (patch.type === 'bootstrap') {
24
+ var installedModules = [];
25
+ Object.keys(patch.modules).forEach(function(moduleId) {
26
+ if (!Object.prototype.hasOwnProperty.call(${webpack_1.default.RuntimeGlobals.moduleFactories}, moduleId)) {
27
+ ${webpack_1.default.RuntimeGlobals.moduleFactories}[moduleId] = patch.modules[moduleId];
28
+ installedModules.push(moduleId);
29
+ }
30
+ });
31
+ console.log('[taro-hmr-compile] bootstrap patch installed', {
32
+ applyId: applyId,
33
+ installedModules: installedModules
34
+ });
35
+ return Promise.resolve(installedModules);
36
+ }
37
+
38
+ console.log('[taro-hmr-compile] patch enqueued', {
39
+ applyId: applyId,
40
+ type: patch.type,
41
+ runtimeHash: enqueueHash,
42
+ fromHash: patch.fromHash,
43
+ toHash: patch.toHash
44
+ });
45
+
46
+ var task = applyQueue.then(function() {
47
+ var runtimeHash = ${webpack_1.default.RuntimeGlobals.getFullHash}();
48
+ console.log('[taro-hmr-compile] patch dequeued', {
49
+ applyId: applyId,
50
+ runtimeHash: runtimeHash,
51
+ fromHash: patch.fromHash,
52
+ toHash: patch.toHash,
53
+ isStaleBaseline: runtimeHash !== patch.fromHash
54
+ });
55
+
56
+ if (runtimeHash === patch.toHash) {
57
+ console.log('[taro-hmr-compile] patch skipped at target hash', {
58
+ applyId: applyId,
59
+ runtimeHash: runtimeHash
60
+ });
61
+ return;
62
+ }
63
+
64
+ currentUpdateApplyHandlers = [];
65
+
66
+ ${webpack_1.default.RuntimeGlobals.require}.miniHmr.preparePatch(
67
+ patch,
68
+ currentUpdateApplyHandlers
69
+ );
70
+
71
+ return setStatus('ready')
72
+ .then(function() {
73
+ return hotApply();
74
+ })
75
+ .then(function(updatedModules) {
76
+ ${webpack_1.default.RuntimeGlobals.getFullHash} = function() {
77
+ return patch.toHash;
78
+ };
79
+
80
+ console.log('[taro-hmr-compile] patch applied', {
81
+ applyId: applyId,
82
+ fromHash: patch.fromHash,
83
+ toHash: patch.toHash,
84
+ updatedModules: updatedModules
85
+ });
86
+
87
+ return updatedModules;
88
+ });
89
+ });
90
+
91
+ // 单次失败不能阻塞后续 patch
92
+ applyQueue = task.catch(function() {});
93
+
94
+ return task;
95
+ }
96
+ };
97
+ `;
98
+ const chunkLoadingRuntimeCode = `
99
+ ${webpack_1.default.RuntimeGlobals.require}.miniHmr.preparePatch = function(patch, applyHandlers) {
100
+ currentUpdateChunks = {};
101
+ currentUpdate = Object.assign({}, patch.modules);
102
+ currentUpdateRemovedChunks = [];
103
+ currentUpdateRuntime = [];
104
+
105
+ if (patch.removedModules) {
106
+ patch.removedModules.forEach(function(moduleId) {
107
+ currentUpdate[moduleId] = false;
108
+ });
109
+ }
110
+
111
+ applyHandlers.push(applyHandler);
112
+ };
113
+ `;
114
+ const injectRuntime = (source, injectedCode) => {
115
+ const runtime = (0, parser_1.parse)(source, { sourceType: 'script' });
116
+ const injected = (0, parser_1.parse)(injectedCode, { sourceType: 'script' });
117
+ runtime.program.body.push(...injected.program.body);
118
+ return (0, generator_1.default)(runtime).code;
119
+ };
120
+ class HmrPatchRuntimePlugin {
121
+ apply(compiler) {
122
+ compiler.hooks.thisCompilation.tap(PLUGIN_NAME, compilation => {
123
+ compilation.hooks.runtimeModule.tap(PLUGIN_NAME, runtimeModule => {
124
+ const injectedCode = {
125
+ HotModuleReplacementRuntimeModule: hotRuntimeCode,
126
+ JsonpChunkLoadingRuntimeModule: chunkLoadingRuntimeCode,
127
+ }[runtimeModule.constructor.name];
128
+ if (!injectedCode)
129
+ return;
130
+ const generate = runtimeModule.generate.bind(runtimeModule);
131
+ runtimeModule.generate = () => {
132
+ const source = generate();
133
+ if (!source)
134
+ return source;
135
+ return injectRuntime(source, injectedCode);
136
+ };
137
+ });
138
+ });
139
+ }
140
+ }
141
+ exports.HmrPatchRuntimePlugin = HmrPatchRuntimePlugin;
142
+ //# sourceMappingURL=hmr-patch-runtime-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hmr-patch-runtime-plugin.js","sourceRoot":"","sources":["../../src/patch/hmr-patch-runtime-plugin.ts"],"names":[],"mappings":";;;;;;AAAA,0CAAmC;AACnC,iEAAuC;AACvC,sDAA6B;AAE7B,MAAM,WAAW,GAAG,uBAAuB,CAAA;AAE3C,MAAM,cAAc,GAAG;;;;EAIrB,iBAAO,CAAC,cAAc,CAAC,OAAO;;;;;wBAKR,iBAAO,CAAC,cAAc,CAAC,WAAW;;;;;;oDAMN,iBAAO,CAAC,cAAc,CAAC,eAAe;YAC9E,iBAAO,CAAC,cAAc,CAAC,eAAe;;;;;;;;;;;;;;;;;;;;0BAoBxB,iBAAO,CAAC,cAAc,CAAC,WAAW;;;;;;;;;;;;;;;;;;;QAmBpD,iBAAO,CAAC,cAAc,CAAC,OAAO;;;;;;;;;;YAU1B,iBAAO,CAAC,cAAc,CAAC,WAAW;;;;;;;;;;;;;;;;;;;;;CAqB7C,CAAC;AAEF,MAAM,uBAAuB,GAAG;EAC9B,iBAAO,CAAC,cAAc,CAAC,OAAO;;;;;;;;;;;;;;CAc/B,CAAA;AAED,MAAM,aAAa,GAAG,CAAC,MAAc,EAAE,YAAoB,EAAE,EAAE;IAC3D,MAAM,OAAO,GAAG,IAAA,cAAK,EAAC,MAAM,EAAE,EAAC,UAAU,EAAE,QAAQ,EAAC,CAAC,CAAA;IACrD,MAAM,QAAQ,GAAG,IAAA,cAAK,EAAC,YAAY,EAAE,EAAC,UAAU,EAAE,QAAQ,EAAC,CAAC,CAAA;IAE5D,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IAEnD,OAAO,IAAA,mBAAQ,EAAC,OAAO,CAAC,CAAC,IAAI,CAAA;AACjC,CAAC,CAAA;AAED,MAAa,qBAAqB;IAC9B,KAAK,CAAC,QAA0B;QAC5B,QAAQ,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,CAC9B,WAAW,EACX,WAAW,CAAC,EAAE;YACV,WAAW,CAAC,KAAK,CAAC,aAAa,CAAC,GAAG,CAC/B,WAAW,EACX,aAAa,CAAC,EAAE;gBACZ,MAAM,YAAY,GAAG;oBACjB,iCAAiC,EAAE,cAAc;oBACjD,8BAA8B,EAAE,uBAAuB;iBAC1D,CAAC,aAAa,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;gBAEjC,IAAI,CAAC,YAAY;oBAAE,OAAM;gBAEzB,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;gBAE3D,aAAa,CAAC,QAAQ,GAAG,GAAG,EAAE;oBAC1B,MAAM,MAAM,GAAG,QAAQ,EAAE,CAAA;oBAEzB,IAAI,CAAC,MAAM;wBAAE,OAAO,MAAM,CAAA;oBAE1B,OAAO,aAAa,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;gBAC9C,CAAC,CAAA;YACL,CAAC,CACJ,CAAA;QACL,CAAC,CACJ,CAAA;IACL,CAAC;CACJ;AA7BD,sDA6BC"}
@@ -0,0 +1,13 @@
1
+ import { HmrCompileServer } from '@taro-hmr-compile/core/compiler';
2
+ import type { Compiler } from 'webpack';
3
+ export interface HmrServerPluginOptions {
4
+ host?: string;
5
+ port?: number;
6
+ }
7
+ export declare class HmrServerPlugin extends HmrCompileServer {
8
+ private readonly options;
9
+ private compiler?;
10
+ constructor(options: HmrServerPluginOptions);
11
+ apply(compiler: Compiler): void;
12
+ compile(page: string): void;
13
+ }
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HmrServerPlugin = void 0;
4
+ const compiler_1 = require("@taro-hmr-compile/core/compiler");
5
+ const hmr_compiler_plugin_1 = require("../compile/hmr-compiler-plugin");
6
+ const PLUGIN_NAME = 'HmrServerPlugin';
7
+ class HmrServerPlugin extends compiler_1.HmrCompileServer {
8
+ constructor(options) {
9
+ super();
10
+ this.options = options;
11
+ }
12
+ apply(compiler) {
13
+ this.compiler = compiler;
14
+ compiler.hooks.afterEmit.tap(PLUGIN_NAME, compilation => {
15
+ var _a;
16
+ const isSuccessful = compilation.errors.length === 0 && Boolean(compilation.hash);
17
+ if (isSuccessful && !this.isServerRunning)
18
+ this.start((_a = this.options.port) !== null && _a !== void 0 ? _a : 8080, this.options.host);
19
+ });
20
+ compiler.hooks.watchClose.tap(PLUGIN_NAME, () => this.stop());
21
+ }
22
+ compile(page) {
23
+ if (!this.compiler)
24
+ throw new Error('[taro-hmr-compile] Compiler 尚未初始化');
25
+ hmr_compiler_plugin_1.HmrCompilerPlugin.getCompilerHooks(this.compiler).compileRequested.call(page);
26
+ }
27
+ }
28
+ exports.HmrServerPlugin = HmrServerPlugin;
29
+ //# sourceMappingURL=hmr-server-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hmr-server-plugin.js","sourceRoot":"","sources":["../../src/server/hmr-server-plugin.ts"],"names":[],"mappings":";;;AAAA,8DAAgE;AAEhE,wEAAgE;AAEhE,MAAM,WAAW,GAAG,iBAAiB,CAAA;AAOrC,MAAa,eAAgB,SAAQ,2BAAgB;IAGjD,YAA6B,OAA+B;QACxD,KAAK,EAAE,CAAA;QADkB,YAAO,GAAP,OAAO,CAAwB;IAE5D,CAAC;IAED,KAAK,CAAC,QAAkB;QACpB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QAExB,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE;;YACpD,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;YACjF,IAAI,YAAY,IAAI,CAAC,IAAI,CAAC,eAAe;gBAAE,IAAI,CAAC,KAAK,CAAC,MAAA,IAAI,CAAC,OAAO,CAAC,IAAI,mCAAI,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QACvG,CAAC,CAAC,CAAA;QAEF,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;IACjE,CAAC;IAEQ,OAAO,CAAC,IAAY;QACzB,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAA;QACxE,uCAAiB,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACjF,CAAC;CACJ;AAtBD,0CAsBC"}
@@ -0,0 +1,4 @@
1
+ import type { IPluginContext } from '@tarojs/service';
2
+ import type { AppConfig } from '@tarojs/taro';
3
+ export declare const getAppConfig: (ctx: IPluginContext) => AppConfig;
4
+ export declare const getAllPages: (appConfig: AppConfig) => string[];
package/dist/utils.js ADDED
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getAllPages = exports.getAppConfig = void 0;
7
+ const helper_1 = require("@tarojs/helper");
8
+ const path_1 = __importDefault(require("path"));
9
+ const getAppConfig = (ctx) => {
10
+ const sourceRoot = ctx.initialConfig.sourceRoot || 'src';
11
+ const appConfigPath = (0, helper_1.resolveMainFilePath)(path_1.default.resolve(ctx.paths.appPath, sourceRoot, 'app.config'));
12
+ return (0, helper_1.readConfig)(appConfigPath, ctx.initialConfig);
13
+ };
14
+ exports.getAppConfig = getAppConfig;
15
+ const getAllPages = (appConfig) => {
16
+ var _a, _b, _c;
17
+ const subPackages = [
18
+ ...((_a = appConfig.subPackages) !== null && _a !== void 0 ? _a : []),
19
+ ...((_b = appConfig.subpackages) !== null && _b !== void 0 ? _b : []),
20
+ ];
21
+ const subPackagePages = subPackages.flatMap(({ root, pages }) => pages.map(page => `${root.replace(/\/+$/, '')}/${page.replace(/^\/+/, '')}`));
22
+ return [...((_c = appConfig.pages) !== null && _c !== void 0 ? _c : []), ...subPackagePages];
23
+ };
24
+ exports.getAllPages = getAllPages;
25
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;;;;;AAAA,2CAA8D;AAG9D,gDAAuB;AAEhB,MAAM,YAAY,GAAG,CAAC,GAAmB,EAAa,EAAE;IAC3D,MAAM,UAAU,GAAG,GAAG,CAAC,aAAa,CAAC,UAAU,IAAI,KAAK,CAAA;IAExD,MAAM,aAAa,GAAG,IAAA,4BAAmB,EAAC,cAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC,CAAA;IAEpG,OAAO,IAAA,mBAAU,EAAC,aAAa,EAAE,GAAG,CAAC,aAAa,CAAC,CAAA;AACvD,CAAC,CAAA;AANY,QAAA,YAAY,gBAMxB;AAEM,MAAM,WAAW,GAAG,CAAC,SAAoB,EAAY,EAAE;;IAC1D,MAAM,WAAW,GAAG;QAChB,GAAG,CAAC,MAAA,SAAS,CAAC,WAAW,mCAAI,EAAE,CAAC;QAChC,GAAG,CAAC,MAAA,SAAS,CAAC,WAAW,mCAAI,EAAE,CAAC;KACnC,CAAA;IAED,MAAM,eAAe,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,EAAC,IAAI,EAAE,KAAK,EAAC,EAAE,EAAE,CAC1D,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC,CAC/E,CAAA;IAED,OAAO,CAAC,GAAG,CAAC,MAAA,SAAS,CAAC,KAAK,mCAAI,EAAE,CAAC,EAAE,GAAG,eAAe,CAAC,CAAA;AAC3D,CAAC,CAAA;AAXY,QAAA,WAAW,eAWvB"}
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@taro-hmr-compile/plugin-webpack",
3
+ "version": "0.0.1-alpha.3",
4
+ "description": "",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "keywords": [],
8
+ "author": "yu.pan",
9
+ "license": "MIT",
10
+ "publishConfig": {
11
+ "access": "public"
12
+ },
13
+ "devEngines": {
14
+ "packageManager": {
15
+ "name": "pnpm",
16
+ "version": "11.24.0",
17
+ "onFail": "download"
18
+ }
19
+ },
20
+ "type": "commonjs",
21
+ "peerDependencies": {
22
+ "@tarojs/helper": "^3.0.0",
23
+ "@tarojs/service": "^3.0.0",
24
+ "@tarojs/taro": "^3.0.0",
25
+ "webpack": "^5.0.0"
26
+ },
27
+ "devDependencies": {
28
+ "@tarojs/helper": "4.0.8",
29
+ "@tarojs/service": "^4.0.8",
30
+ "@tarojs/taro": "^4.0.8",
31
+ "@types/node": "^22.20.1",
32
+ "typescript": "^5.8.2",
33
+ "webpack": "^5.110.3"
34
+ },
35
+ "dependencies": {
36
+ "@babel/core": "^7.29.7",
37
+ "@babel/generator": "^8.0.5",
38
+ "@babel/parser": "^8.0.5",
39
+ "@babel/template": "^8.0.0",
40
+ "@babel/traverse": "^8.0.5",
41
+ "@babel/types": "^8.0.5",
42
+ "@taro-hmr-compile/core": "0.0.1-alpha.3",
43
+ "@taro-hmr-compile/react-refresh": "0.0.1-alpha.3",
44
+ "tapable": "^2.3.3",
45
+ "webpack-sources": "^3.5.1"
46
+ },
47
+ "scripts": {
48
+ "build": "tsc",
49
+ "test": "pnpm run build && node --test test/*.test.cjs"
50
+ }
51
+ }
@@ -0,0 +1,15 @@
1
+ const compiledPagesByApp = new Map<string, Set<string>>()
2
+
3
+ export const markPageCompiled = (appPath: string, page: string) => {
4
+ const compiledPages = compiledPagesByApp.get(appPath) ?? new Set<string>()
5
+ compiledPages.add(page)
6
+ compiledPagesByApp.set(appPath, compiledPages)
7
+ }
8
+
9
+ export const isPageCompiled = (appPath: string, page: string) => {
10
+ return compiledPagesByApp.get(appPath)?.has(page) ?? false
11
+ }
12
+
13
+ export const clearCompiledPages = (appPath: string) => {
14
+ compiledPagesByApp.delete(appPath)
15
+ }
@@ -0,0 +1,72 @@
1
+ import type {LoaderDefinitionFunction} from 'webpack'
2
+ import path from "path";
3
+ import {getAllPages} from '../utils'
4
+ import {isPageCompiled} from './compile-state'
5
+ import type {AppConfig} from "@tarojs/taro";
6
+ import {injectAppHmrRuntime} from './inject-app-hmr-runtime'
7
+
8
+
9
+ interface CreateShellOpt {
10
+ page: string
11
+ framework: 'react'
12
+ compileUrl: string
13
+ }
14
+
15
+ const createReactShell = (opt: CreateShellOpt) => {
16
+ const {page, compileUrl} = opt
17
+ return `
18
+ import Taro from '@tarojs/taro'
19
+ import { Text, View } from '@tarojs/components'
20
+ import { useEffect } from 'react'
21
+ const PageShell = () => {
22
+ useEffect(() => {
23
+ const data = { page: '${page}' }
24
+ const url = '${compileUrl}'
25
+ Taro.request({ url, method: 'POST', data }).catch(error => console.error('[taro-hmr-compile] 页面编译请求失败', error))
26
+ }, [])
27
+
28
+ return (
29
+ <View style={{ position: 'fixed', top: 0, right: 0, bottom: 0, left: 0, zIndex: 9999, display: 'flex', flexDirection: 'column', alignItems: 'flex-start', justifyContent: 'center', boxSizing: 'border-box', padding: '32px', color: '#fff', background: 'rgba(0, 0, 0, 0.88)' }}>
30
+ <Text style={{ display: 'block', color: '#ff5555', fontFamily: 'monospace', fontSize: '20px', fontWeight: 'bold' }}>HMR PageShell</Text>
31
+ <Text style={{ display: 'block', marginTop: '12px', color: '#fff', fontFamily: 'monospace', lineHeight: 1.6 }}>Waiting for page patch...</Text>
32
+ <Text style={{ display: 'block', marginTop: '6px', color: '#b3b3b3', fontFamily: 'monospace', lineHeight: 1.6, wordBreak: 'break-all' }}>${page}</Text>
33
+ </View>
34
+ )
35
+ }
36
+ export default PageShell
37
+ `
38
+ }
39
+
40
+ const createShell = (opt: CreateShellOpt) => {
41
+ if (opt.framework === 'react') return createReactShell(opt)
42
+ throw new Error(`unsupported framework: ${opt.framework}`)
43
+ }
44
+
45
+
46
+ interface LoaderOptions {
47
+ appPath: string
48
+ sourcePath: string
49
+ appConfig: AppConfig
50
+ framework: 'react'
51
+ compileUrl: string
52
+ }
53
+
54
+ const hmrCompileLoader: LoaderDefinitionFunction<LoaderOptions> = function (source) {
55
+ const {appPath, framework, appConfig, sourcePath, compileUrl} = this.getOptions()
56
+
57
+ const {dir: resourceDir, name: resourceName} = path.parse(path.relative(sourcePath, this.resourcePath))
58
+
59
+ const resourcePath = path.join(resourceDir, resourceName)
60
+
61
+ const isPageEntry = getAllPages(appConfig).includes(resourcePath)
62
+
63
+ const isAppEntry = resourcePath === 'app'
64
+
65
+ if (isAppEntry) return injectAppHmrRuntime(source)
66
+
67
+ if (!isPageEntry || isPageCompiled(appPath, resourcePath)) return source
68
+
69
+ return createShell({page: resourcePath, framework, compileUrl})
70
+ }
71
+
72
+ export default hmrCompileLoader