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

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 (58) 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-compiler-loader.d.ts +9 -0
  5. package/dist/compile/hmr-compiler-loader.js +199 -0
  6. package/dist/compile/hmr-compiler-loader.js.map +1 -0
  7. package/dist/compile/hmr-compiler-plugin.d.ts +46 -0
  8. package/dist/compile/hmr-compiler-plugin.js +173 -0
  9. package/dist/compile/hmr-compiler-plugin.js.map +1 -0
  10. package/dist/compile/lazy-compiler-loader.d.ts +18 -0
  11. package/dist/compile/lazy-compiler-loader.js +38 -0
  12. package/dist/compile/lazy-compiler-loader.js.map +1 -0
  13. package/dist/constants.d.ts +4 -0
  14. package/dist/constants.js +8 -0
  15. package/dist/constants.js.map +1 -0
  16. package/dist/index.d.ts +9 -0
  17. package/dist/index.js +68 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/log.d.ts +3 -0
  20. package/dist/log.js +11 -0
  21. package/dist/log.js.map +1 -0
  22. package/dist/patch/hmr-patch-plugin.d.ts +17 -0
  23. package/dist/patch/hmr-patch-plugin.js +93 -0
  24. package/dist/patch/hmr-patch-plugin.js.map +1 -0
  25. package/dist/patch/hmr-patch-processor.d.ts +30 -0
  26. package/dist/patch/hmr-patch-processor.js +122 -0
  27. package/dist/patch/hmr-patch-processor.js.map +1 -0
  28. package/dist/patch/hmr-patch-runtime-plugin.d.ts +4 -0
  29. package/dist/patch/hmr-patch-runtime-plugin.js +113 -0
  30. package/dist/patch/hmr-patch-runtime-plugin.js.map +1 -0
  31. package/dist/patch/types.d.ts +16 -0
  32. package/dist/patch/types.js +3 -0
  33. package/dist/patch/types.js.map +1 -0
  34. package/dist/patch/utils.d.ts +28 -0
  35. package/dist/patch/utils.js +179 -0
  36. package/dist/patch/utils.js.map +1 -0
  37. package/dist/server/hmr-server-plugin.d.ts +13 -0
  38. package/dist/server/hmr-server-plugin.js +42 -0
  39. package/dist/server/hmr-server-plugin.js.map +1 -0
  40. package/dist/utils.d.ts +4 -0
  41. package/dist/utils.js +25 -0
  42. package/dist/utils.js.map +1 -0
  43. package/package.json +58 -0
  44. package/src/compile/compile-state.ts +15 -0
  45. package/src/compile/hmr-compiler-loader.ts +177 -0
  46. package/src/compile/hmr-compiler-plugin.ts +233 -0
  47. package/src/compile/lazy-compiler-loader.ts +57 -0
  48. package/src/constants.ts +7 -0
  49. package/src/index.ts +81 -0
  50. package/src/log.ts +5 -0
  51. package/src/patch/hmr-patch-plugin.ts +111 -0
  52. package/src/patch/hmr-patch-processor.ts +169 -0
  53. package/src/patch/hmr-patch-runtime-plugin.ts +119 -0
  54. package/src/patch/types.ts +20 -0
  55. package/src/patch/utils.ts +179 -0
  56. package/src/server/hmr-server-plugin.ts +40 -0
  57. package/src/utils.ts +25 -0
  58. package/tsconfig.json +21 -0
package/dist/index.js ADDED
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const constants_1 = require("./constants");
13
+ const utils_1 = require("./utils");
14
+ const hmr_compiler_plugin_1 = require("./compile/hmr-compiler-plugin");
15
+ const hmr_patch_plugin_1 = require("./patch/hmr-patch-plugin");
16
+ const hmr_server_plugin_1 = require("./server/hmr-server-plugin");
17
+ const compiler_1 = require("@taro-hmr-compile/core/compiler");
18
+ const log_1 = require("./log");
19
+ exports.default = (ctx, pluginOpts) => {
20
+ var _a, _b, _c;
21
+ if (!((_a = ctx.runOpts.options) === null || _a === void 0 ? void 0 : _a.isWatch))
22
+ return;
23
+ const { appPath, sourcePath, outputPath } = ctx.paths;
24
+ const { framework } = ctx.initialConfig;
25
+ const appConfig = (0, utils_1.getAppConfig)(ctx);
26
+ const host = (_b = pluginOpts.host) !== null && _b !== void 0 ? _b : '127.0.0.1';
27
+ const preferredPort = (_c = pluginOpts.port) !== null && _c !== void 0 ? _c : 8080;
28
+ const debugNamespaces = (() => {
29
+ if (typeof pluginOpts.debug === 'string')
30
+ return pluginOpts.debug;
31
+ return pluginOpts.debug ? constants_1.DEFAULT_DEBUG_NAMESPACES : undefined;
32
+ })();
33
+ if (debugNamespaces)
34
+ (0, log_1.enableLog)(debugNamespaces);
35
+ ctx.onBuildStart(() => (0, compiler_1.emptyDirFile)(outputPath));
36
+ ctx.modifyRunnerOpts(({ opts }) => {
37
+ var _a;
38
+ (_a = opts.output) !== null && _a !== void 0 ? _a : (opts.output = {});
39
+ opts.output.clean = false;
40
+ });
41
+ ctx.modifyWebpackChain((_a) => __awaiter(void 0, [_a], void 0, function* ({ chain, webpack }) {
42
+ var _b;
43
+ const port = yield (0, compiler_1.findAvailablePort)(preferredPort, host);
44
+ const compileUrl = `http://${host}:${port}/compile`;
45
+ if (port !== preferredPort)
46
+ console.warn(`[taro-hmr-compile] 端口 ${preferredPort} 已被占用,自动使用端口 ${port}`);
47
+ chain.optimization.usedExports(false);
48
+ chain.module
49
+ .rule('lazy-compiler')
50
+ .test(/\.[jt]sx?$/)
51
+ .include.add(ctx.paths.sourcePath)
52
+ .end()
53
+ .use('lazy-compiler-loader')
54
+ .loader(require.resolve('./compile/lazy-compiler-loader'))
55
+ .options({ appPath, sourcePath, appConfig, framework, compileUrl })
56
+ .end();
57
+ chain.output
58
+ .set('hotUpdateChunkFilename', `${constants_1.HMR_OUTPUT_PATH}/[id].[fullhash].hot-update.js`)
59
+ .set('hotUpdateMainFilename', `${constants_1.HMR_OUTPUT_PATH}/[runtime].[fullhash].hot-update.json`);
60
+ const { patchHistoryLimit } = pluginOpts;
61
+ const [{ filename: styleFilename }] = ((_b = chain.plugin('miniCssExtractPlugin')) === null || _b === void 0 ? void 0 : _b.get('args')) || [];
62
+ chain.plugin('hmr-compiler-plugin').use(hmr_compiler_plugin_1.HmrCompilerPlugin, [{ paths: ctx.paths, appConfig, styleFilename, debugNamespaces }]);
63
+ chain.plugin('hmr-plugin').use(webpack.HotModuleReplacementPlugin);
64
+ chain.plugin('hmr-patch-plugin').use(hmr_patch_plugin_1.HmrPatchPlugin, [{ patchHistoryLimit }]);
65
+ chain.plugin('hmr-server-plugin').use(hmr_server_plugin_1.HmrServerPlugin, [{ host, port }]);
66
+ }));
67
+ };
68
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;AAEA,2CAAqE;AACrE,mCAAoC;AACpC,uEAA+D;AAC/D,+DAAuD;AACvD,kEAA0D;AAC1D,8DAA+E;AAC/E,+BAA+B;AAU/B,kBAAe,CAAC,GAAmB,EAAE,UAAyC,EAAE,EAAE;;IAC9E,IAAI,CAAC,CAAA,MAAA,GAAG,CAAC,OAAO,CAAC,OAAO,0CAAE,OAAO,CAAA;QAAE,OAAM;IAEzC,MAAM,EAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAC,GAAG,GAAG,CAAC,KAAK,CAAA;IAEnD,MAAM,EAAC,SAAS,EAAC,GAAG,GAAG,CAAC,aAAa,CAAA;IAErC,MAAM,SAAS,GAAc,IAAA,oBAAY,EAAC,GAAG,CAAC,CAAA;IAE9C,MAAM,IAAI,GAAG,MAAA,UAAU,CAAC,IAAI,mCAAI,WAAW,CAAA;IAE3C,MAAM,aAAa,GAAG,MAAA,UAAU,CAAC,IAAI,mCAAI,IAAI,CAAA;IAE7C,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE;QAC1B,IAAI,OAAO,UAAU,CAAC,KAAK,KAAK,QAAQ;YAAE,OAAO,UAAU,CAAC,KAAK,CAAA;QACjE,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,oCAAwB,CAAC,CAAC,CAAC,SAAS,CAAA;IAClE,CAAC,CAAC,EAAE,CAAA;IAEJ,IAAI,eAAe;QAAE,IAAA,eAAS,EAAC,eAAe,CAAC,CAAA;IAE/C,GAAG,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,IAAA,uBAAY,EAAC,UAAU,CAAC,CAAC,CAAA;IAEhD,GAAG,CAAC,gBAAgB,CAAC,CAAC,EAAC,IAAI,EAAC,EAAE,EAAE;;QAC5B,MAAA,IAAI,CAAC,MAAM,oCAAX,IAAI,CAAC,MAAM,GAAK,EAAE,EAAA;QAClB,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,KAAK,CAAA;IAC7B,CAAC,CAAC,CAAA;IAEF,GAAG,CAAC,kBAAkB,CAAC,KAAyB,EAAE,4CAApB,EAAC,KAAK,EAAE,OAAO,EAAC;;QAC1C,MAAM,IAAI,GAAG,MAAM,IAAA,4BAAiB,EAAC,aAAa,EAAE,IAAI,CAAC,CAAA;QAEzD,MAAM,UAAU,GAAG,UAAU,IAAI,IAAI,IAAI,UAAU,CAAA;QAEnD,IAAI,IAAI,KAAK,aAAa;YAAE,OAAO,CAAC,IAAI,CAAC,yBAAyB,aAAa,gBAAgB,IAAI,EAAE,CAAC,CAAA;QAEtG,KAAK,CAAC,YAAY,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;QAErC,KAAK,CAAC,MAAM;aACP,IAAI,CAAC,eAAe,CAAC;aACrB,IAAI,CAAC,YAAY,CAAC;aAClB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC;aACjC,GAAG,EAAE;aACL,GAAG,CAAC,sBAAsB,CAAC;aAC3B,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAC;aACzD,OAAO,CAAC,EAAC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAC,CAAC;aAChE,GAAG,EAAE,CAAA;QAEV,KAAK,CAAC,MAAM;aACP,GAAG,CAAC,wBAAwB,EAAE,GAAG,2BAAe,gCAAgC,CAAC;aACjF,GAAG,CAAC,uBAAuB,EAAE,GAAG,2BAAe,uCAAuC,CAAC,CAAA;QAE5F,MAAM,EAAC,iBAAiB,EAAC,GAAG,UAAU,CAAA;QAEtC,MAAM,CAAC,EAAC,QAAQ,EAAE,aAAa,EAAC,CAAC,GAAG,CAAA,MAAA,KAAK,CAAC,MAAM,CAAC,sBAAsB,CAAC,0CAAE,GAAG,CAAC,MAAM,CAAC,KAAI,EAAE,CAAA;QAE3F,KAAK,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,GAAG,CAAC,uCAAiB,EAAE,CAAC,EAAC,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,eAAe,EAAC,CAAC,CAAC,CAAA;QAE3H,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAA;QAElE,KAAK,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,iCAAc,EAAE,CAAC,EAAC,iBAAiB,EAAC,CAAC,CAAC,CAAA;QAE3E,KAAK,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,GAAG,CAAC,mCAAe,EAAE,CAAC,EAAC,IAAI,EAAE,IAAI,EAAC,CAAC,CAAC,CAAA;IAC1E,CAAC,CAAA,CAAC,CAAA;AACN,CAAC,CAAA"}
package/dist/log.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import createDebug from 'debug';
2
+ export declare const log: createDebug.Debugger;
3
+ export declare const enableLog: (namespaces: string) => void;
package/dist/log.js ADDED
@@ -0,0 +1,11 @@
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.enableLog = exports.log = void 0;
7
+ const debug_1 = __importDefault(require("debug"));
8
+ exports.log = (0, debug_1.default)('taro-hmr-compile:webpack');
9
+ const enableLog = (namespaces) => debug_1.default.enable(namespaces);
10
+ exports.enableLog = enableLog;
11
+ //# sourceMappingURL=log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.js","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":";;;;;;AAAA,kDAA+B;AAElB,QAAA,GAAG,GAAG,IAAA,eAAW,EAAC,0BAA0B,CAAC,CAAA;AAEnD,MAAM,SAAS,GAAG,CAAC,UAAkB,EAAE,EAAE,CAAC,eAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;AAAlE,QAAA,SAAS,aAAyD"}
@@ -0,0 +1,17 @@
1
+ import type { Compiler } from 'webpack';
2
+ import { HmrPatchProcessorOptions } from "./hmr-patch-processor";
3
+ type HmrPatchPluginOptions = Partial<HmrPatchProcessorOptions>;
4
+ export declare class HmrPatchPlugin {
5
+ private previousHash;
6
+ private initialBuildDone;
7
+ private readonly patchProcessor;
8
+ private readonly emittedAssetSources;
9
+ constructor(options: HmrPatchPluginOptions);
10
+ apply(compiler: Compiler): void;
11
+ private processAssets;
12
+ /** 热更新转换完成后,保留固定 patch 与发生变化的模板、平台样式资产。 */
13
+ private removeSupersededAssets;
14
+ private emitPatchAsset;
15
+ private reset;
16
+ }
17
+ export {};
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HmrPatchPlugin = void 0;
4
+ const webpack_sources_1 = require("webpack-sources");
5
+ const constants_1 = require("../constants");
6
+ const hmr_compiler_plugin_1 = require("../compile/hmr-compiler-plugin");
7
+ const hmr_patch_runtime_plugin_1 = require("./hmr-patch-runtime-plugin");
8
+ const hmr_patch_processor_1 = require("./hmr-patch-processor");
9
+ const PLUGIN_NAME = 'HmrPatchPlugin';
10
+ const HOT_UPDATE_MANIFEST_SUFFIX = '.hot-update.json';
11
+ const HOT_UPDATE_SCRIPT_SUFFIX = '.hot-update.js';
12
+ const STYLE_ASSET_PATTERN = /\.(?:css|wxss|acss|ttss|qss|jxss)(?:\.map)?$/i;
13
+ const TEMPLATE_RUNTIME_ASSET_PATTERN = /(?:^|\/)(?:base\.wxml|utils\.wxs)$/i;
14
+ const isPassthroughAsset = (assetName) => {
15
+ return STYLE_ASSET_PATTERN.test(assetName) || TEMPLATE_RUNTIME_ASSET_PATTERN.test(assetName);
16
+ };
17
+ class HmrPatchPlugin {
18
+ constructor(options) {
19
+ this.previousHash = '';
20
+ this.initialBuildDone = false;
21
+ this.emittedAssetSources = new Map();
22
+ this.patchProcessor = new hmr_patch_processor_1.HmrPatchProcessor(options);
23
+ }
24
+ apply(compiler) {
25
+ new hmr_patch_runtime_plugin_1.HmrPatchRuntimePlugin().apply(compiler);
26
+ compiler.hooks.compilation.tap(PLUGIN_NAME, compilation => {
27
+ hmr_compiler_plugin_1.HmrCompilerPlugin.getCompilationHooks(compilation).chunkModulesRendered.tap(PLUGIN_NAME, options => {
28
+ this.patchProcessor.processChunkModules(Object.assign({ compilation }, options));
29
+ });
30
+ // 等 Webpack 生成完整的 hot-update assets 后,再统一转换成固定的 patch.js。
31
+ const stage = compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_REPORT;
32
+ compilation.hooks.processAssets.tap({ name: PLUGIN_NAME, stage }, () => this.processAssets(compilation));
33
+ });
34
+ compiler.hooks.afterEmit.tap(PLUGIN_NAME, compilation => {
35
+ const isSuccessful = compilation.errors.length === 0 && Boolean(compilation.hash);
36
+ this.initialBuildDone = this.initialBuildDone || isSuccessful;
37
+ });
38
+ compiler.hooks.watchClose.tap(PLUGIN_NAME, () => this.reset());
39
+ }
40
+ processAssets(compilation) {
41
+ const { previousHash: fromHash, initialBuildDone } = this;
42
+ const { hash: toHash, errors: compilationErrors } = compilation;
43
+ if (!toHash || compilationErrors.length > 0)
44
+ return;
45
+ // 首次编译完成过滤文件输出
46
+ if (!initialBuildDone) {
47
+ this.patchProcessor.commitBootstrapFactories(compilation);
48
+ compilation.getAssets().forEach(asset => {
49
+ if (!isPassthroughAsset(asset.name))
50
+ return;
51
+ this.emittedAssetSources.set(asset.name, asset.source.source().toString());
52
+ });
53
+ this.previousHash = toHash;
54
+ return this.emitPatchAsset(compilation, false);
55
+ }
56
+ const manifests = compilation.getAssets().filter(asset => asset.name.endsWith(HOT_UPDATE_MANIFEST_SUFFIX));
57
+ const scripts = compilation.getAssets().filter(asset => asset.name.endsWith(HOT_UPDATE_SCRIPT_SUFFIX));
58
+ this.patchProcessor.processUpdate({ toHash, fromHash, manifests, scripts });
59
+ this.emitPatchAsset(compilation, true);
60
+ this.removeSupersededAssets(compilation);
61
+ this.previousHash = toHash;
62
+ }
63
+ /** 热更新转换完成后,保留固定 patch 与发生变化的模板、平台样式资产。 */
64
+ removeSupersededAssets(compilation) {
65
+ compilation.getAssets().forEach(asset => {
66
+ if (asset.name === constants_1.HMR_PATCH_ASSET)
67
+ return;
68
+ if (!isPassthroughAsset(asset.name))
69
+ return compilation.deleteAsset(asset.name);
70
+ const source = asset.source.source().toString();
71
+ const previousSource = this.emittedAssetSources.get(asset.name);
72
+ this.emittedAssetSources.set(asset.name, source);
73
+ if (previousSource === source)
74
+ compilation.deleteAsset(asset.name);
75
+ });
76
+ }
77
+ emitPatchAsset(compilation, isHotUpdate) {
78
+ const source = new webpack_sources_1.RawSource(this.patchProcessor.generate());
79
+ const assetInfo = { hotModuleReplacement: isHotUpdate };
80
+ if (compilation.getAsset(constants_1.HMR_PATCH_ASSET))
81
+ compilation.updateAsset(constants_1.HMR_PATCH_ASSET, source, assetInfo);
82
+ else
83
+ compilation.emitAsset(constants_1.HMR_PATCH_ASSET, source, assetInfo);
84
+ }
85
+ reset() {
86
+ this.previousHash = '';
87
+ this.initialBuildDone = false;
88
+ this.emittedAssetSources.clear();
89
+ this.patchProcessor.reset();
90
+ }
91
+ }
92
+ exports.HmrPatchPlugin = HmrPatchPlugin;
93
+ //# 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,30 @@
1
+ import { type Chunk, type Compilation } from "webpack";
2
+ import { ParseHotUpdateAssetsOptions } from "./utils";
3
+ interface ProcessChunkModulesOptions {
4
+ source: string;
5
+ compilation: Compilation;
6
+ isBootstrapChunk: boolean;
7
+ chunk: Chunk;
8
+ }
9
+ export interface HmrPatchProcessorOptions {
10
+ patchHistoryLimit?: number;
11
+ }
12
+ interface ProcessUpdateOptions extends ParseHotUpdateAssetsOptions {
13
+ fromHash: string;
14
+ toHash: string;
15
+ }
16
+ export declare class HmrPatchProcessor {
17
+ private readonly bootstrapFactories;
18
+ private readonly bootstrapFactoriesByCompilation;
19
+ private readonly moduleHashesByFullHash;
20
+ private recentUpdatePatches;
21
+ private readonly opts;
22
+ constructor(opts: Partial<HmrPatchProcessorOptions>);
23
+ private getChangedModuleIdsByFullHash;
24
+ processUpdate(opt: ProcessUpdateOptions): void;
25
+ processChunkModules(opt: ProcessChunkModulesOptions): void;
26
+ commitBootstrapFactories(compilation: Compilation): void;
27
+ generate(): string;
28
+ reset(): void;
29
+ }
30
+ export {};
@@ -0,0 +1,122 @@
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.HmrPatchProcessor = void 0;
7
+ const utils_1 = require("./utils");
8
+ const isNil_1 = __importDefault(require("lodash/isNil"));
9
+ const constants_1 = require("../constants");
10
+ const areModuleHashesEqual = (left, right) => {
11
+ if (!left || !right || left.size !== right.size)
12
+ return false;
13
+ return Array.from(left).every(hash => right.has(hash));
14
+ };
15
+ class HmrPatchProcessor {
16
+ constructor(opts) {
17
+ this.bootstrapFactories = new Map();
18
+ this.bootstrapFactoriesByCompilation = new WeakMap();
19
+ this.moduleHashesByFullHash = new Map();
20
+ this.recentUpdatePatches = [];
21
+ this.opts = opts;
22
+ }
23
+ getChangedModuleIdsByFullHash(fromHash, toHash) {
24
+ const fromModuleHashes = this.moduleHashesByFullHash.get(fromHash);
25
+ const toModuleHashes = this.moduleHashesByFullHash.get(toHash);
26
+ // 任一编译缺少 Hash 基线时不做过滤,避免误丢有效的 hot-update 模块。
27
+ if (!fromModuleHashes || !toModuleHashes)
28
+ return;
29
+ // 同时检查前后两次编译的模块,确保新增、修改和删除都能被识别。
30
+ const moduleIds = new Set(fromModuleHashes.keys());
31
+ toModuleHashes.forEach((_, moduleId) => moduleIds.add(moduleId));
32
+ const changedModuleIds = new Set();
33
+ moduleIds.forEach(moduleId => {
34
+ const fromModuleHash = fromModuleHashes.get(moduleId);
35
+ const toModuleHash = toModuleHashes.get(moduleId);
36
+ if (!areModuleHashesEqual(fromModuleHash, toModuleHash))
37
+ changedModuleIds.add(moduleId);
38
+ });
39
+ return changedModuleIds;
40
+ }
41
+ processUpdate(opt) {
42
+ var _a;
43
+ const { fromHash, toHash } = opt;
44
+ const tempPatchInfo = (0, utils_1.parseHotUpdateAssets)(opt);
45
+ const changedModuleIds = this.getChangedModuleIdsByFullHash(fromHash, toHash);
46
+ const moduleFactories = (() => {
47
+ if (!changedModuleIds)
48
+ return Array.from(tempPatchInfo.moduleFactories.values());
49
+ return Array.from(tempPatchInfo.moduleFactories.values()).filter(item => changedModuleIds.has(item.moduleId));
50
+ })();
51
+ const removedModules = (() => {
52
+ if (!changedModuleIds)
53
+ return Array.from(tempPatchInfo.removedModules.values());
54
+ return Array.from(tempPatchInfo.removedModules.values()).filter(item => changedModuleIds.has(item));
55
+ })();
56
+ const { runtimeModules } = tempPatchInfo;
57
+ this.recentUpdatePatches.push({ type: 'update', moduleFactories, runtimeModules, fromHash, toHash, removedModules });
58
+ const patchHistoryLimit = Math.max(1, (_a = this.opts.patchHistoryLimit) !== null && _a !== void 0 ? _a : constants_1.DEFAULT_HMR_PATCH_HISTORY_LIMIT);
59
+ if (this.recentUpdatePatches.length <= patchHistoryLimit)
60
+ return;
61
+ const [oldestUpdatePatch, secondOldestUpdatePatch, ...rest] = this.recentUpdatePatches;
62
+ const mergedUpdatePatch = (0, utils_1.mergeUpdatePatches)(oldestUpdatePatch, secondOldestUpdatePatch);
63
+ this.recentUpdatePatches = [mergedUpdatePatch, ...rest];
64
+ this.moduleHashesByFullHash.delete(oldestUpdatePatch.toHash);
65
+ }
66
+ processChunkModules(opt) {
67
+ const { chunk, compilation, isBootstrapChunk, source } = opt;
68
+ const { hash: fullHash } = compilation;
69
+ const modules = (0, utils_1.parseChunkAsset)(source);
70
+ modules.forEach(moduleFactory => {
71
+ var _a;
72
+ const { moduleId, factory } = moduleFactory;
73
+ if (isBootstrapChunk) {
74
+ const compilationFactories = (_a = this.bootstrapFactoriesByCompilation.get(compilation)) !== null && _a !== void 0 ? _a : new Map();
75
+ compilationFactories.set(moduleId, { moduleId, factory });
76
+ this.bootstrapFactoriesByCompilation.set(compilation, compilationFactories);
77
+ }
78
+ });
79
+ if (!fullHash)
80
+ return;
81
+ const moduleHashes = (() => {
82
+ const hasCurFullHashModuleHashMap = this.moduleHashesByFullHash.has(fullHash);
83
+ if (!hasCurFullHashModuleHashMap)
84
+ this.moduleHashesByFullHash.set(fullHash, new Map());
85
+ return this.moduleHashesByFullHash.get(fullHash);
86
+ })();
87
+ const { chunkGraph, codeGenerationResults } = compilation;
88
+ Array.from(chunkGraph.getChunkModulesIterable(chunk)).forEach(module => {
89
+ var _a;
90
+ const moduleId = chunkGraph.getModuleId(module);
91
+ if ((0, isNil_1.default)(moduleId))
92
+ return;
93
+ const normalizedModuleId = String(moduleId);
94
+ // 获取模块在当前 chunk.runtime 下的 Hash,优先从 codeGenerationResults 获取,如果没有对应的代码生成结果,则回退到 chunkGraph 获取
95
+ const moduleHash = (codeGenerationResults === null || codeGenerationResults === void 0 ? void 0 : codeGenerationResults.has(module, chunk.runtime))
96
+ ? codeGenerationResults.getHash(module, chunk.runtime)
97
+ : chunkGraph.getModuleHash(module, chunk.runtime);
98
+ const hashes = (_a = moduleHashes.get(normalizedModuleId)) !== null && _a !== void 0 ? _a : new Set();
99
+ hashes.add(moduleHash);
100
+ moduleHashes.set(normalizedModuleId, hashes);
101
+ });
102
+ }
103
+ commitBootstrapFactories(compilation) {
104
+ var _a;
105
+ this.bootstrapFactories.clear();
106
+ (_a = this.bootstrapFactoriesByCompilation.get(compilation)) === null || _a === void 0 ? void 0 : _a.forEach(moduleFactory => {
107
+ this.bootstrapFactories.set(moduleFactory.moduleId, moduleFactory);
108
+ });
109
+ this.bootstrapFactoriesByCompilation.delete(compilation);
110
+ }
111
+ generate() {
112
+ const { bootstrapFactories, recentUpdatePatches } = this;
113
+ return (0, utils_1.generatePatchAssetSource)({ bootstrapFactories, recentUpdatePatches });
114
+ }
115
+ reset() {
116
+ this.bootstrapFactories.clear();
117
+ this.moduleHashesByFullHash.clear();
118
+ this.recentUpdatePatches = [];
119
+ }
120
+ }
121
+ exports.HmrPatchProcessor = HmrPatchProcessor;
122
+ //# sourceMappingURL=hmr-patch-processor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hmr-patch-processor.js","sourceRoot":"","sources":["../../src/patch/hmr-patch-processor.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,113 @@
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
+
14
+ ${webpack_1.default.RuntimeGlobals.require}.miniHmr = {
15
+ shouldApplyBootstrapPatch: function(patch) {
16
+ if (!patch) return false;
17
+
18
+ return Object.keys(patch.modules).some(function(moduleId) {
19
+ return !Object.prototype.hasOwnProperty.call(${webpack_1.default.RuntimeGlobals.moduleFactories}, moduleId);
20
+ });
21
+ },
22
+ applyBootstrapPatch: function(patch) {
23
+ if (!patch) return [];
24
+
25
+ // 微信要求 Page() 在页面脚本求值期间同步注册。bootstrap 只补齐缺失工厂,
26
+ // 不会覆盖现有模块;必须在 Page Chunk startup 继续执行前同步完成。
27
+ var installedModules = [];
28
+ Object.keys(patch.modules).forEach(function(moduleId) {
29
+ if (!Object.prototype.hasOwnProperty.call(${webpack_1.default.RuntimeGlobals.moduleFactories}, moduleId)) {
30
+ ${webpack_1.default.RuntimeGlobals.moduleFactories}[moduleId] = patch.modules[moduleId];
31
+ installedModules.push(moduleId);
32
+ }
33
+ });
34
+ return installedModules;
35
+ },
36
+ applyUpdatePatch: function(patch) {
37
+ if (!patch) return Promise.resolve();
38
+
39
+ globalThis.log('apply update patch %O', patch);
40
+
41
+ var task = applyQueue.then(function() {
42
+ var runtimeHash = ${webpack_1.default.RuntimeGlobals.getFullHash}();
43
+
44
+ if (runtimeHash === patch.toHash) return;
45
+
46
+ currentUpdateApplyHandlers = [];
47
+
48
+ ${webpack_1.default.RuntimeGlobals.require}.miniHmr.preparePatch(patch, currentUpdateApplyHandlers);
49
+
50
+ return setStatus('ready')
51
+ .then(function() { return hotApply(); })
52
+ .then(function(updatedModules) {
53
+ ${webpack_1.default.RuntimeGlobals.getFullHash} = function() { return patch.toHash; };
54
+ return updatedModules;
55
+ });
56
+ });
57
+
58
+ // 单次失败不能阻塞后续 patch
59
+ applyQueue = task.catch(function() {});
60
+
61
+ return task;
62
+ }
63
+ };
64
+ `;
65
+ const chunkLoadingRuntimeCode = `
66
+ ${webpack_1.default.RuntimeGlobals.require}.miniHmr.preparePatch = function(patch, applyHandlers) {
67
+ currentUpdateChunks = {};
68
+ currentUpdate = Object.assign({}, patch.modules);
69
+ currentUpdateRemovedChunks = [];
70
+ currentUpdateRuntime = patch.runtimeModules ? patch.runtimeModules.slice() : [];
71
+
72
+ if (patch.removedModules) {
73
+ patch.removedModules.forEach(function(moduleId) {
74
+ currentUpdate[moduleId] = false;
75
+ });
76
+ }
77
+
78
+ applyHandlers.push(applyHandler);
79
+ };
80
+ `;
81
+ const injectRuntime = (source, injectedCode) => {
82
+ const runtime = (0, parser_1.parse)(source, { sourceType: 'script' });
83
+ const injected = (0, parser_1.parse)(injectedCode, { sourceType: 'script' });
84
+ runtime.program.body.push(...injected.program.body);
85
+ return (0, generator_1.default)(runtime).code;
86
+ };
87
+ class HmrPatchRuntimePlugin {
88
+ apply(compiler) {
89
+ compiler.hooks.thisCompilation.tap(PLUGIN_NAME, compilation => {
90
+ compilation.hooks.additionalTreeRuntimeRequirements.tap(PLUGIN_NAME, (_chunk, runtimeRequirements) => {
91
+ runtimeRequirements.add(webpack_1.default.RuntimeGlobals.require);
92
+ runtimeRequirements.add(webpack_1.default.RuntimeGlobals.getFullHash);
93
+ });
94
+ compilation.hooks.runtimeModule.tap(PLUGIN_NAME, runtimeModule => {
95
+ const injectedCode = {
96
+ HotModuleReplacementRuntimeModule: hotRuntimeCode,
97
+ JsonpChunkLoadingRuntimeModule: chunkLoadingRuntimeCode,
98
+ }[runtimeModule.constructor.name];
99
+ if (!injectedCode)
100
+ return;
101
+ const generate = runtimeModule.generate.bind(runtimeModule);
102
+ runtimeModule.generate = () => {
103
+ const source = generate();
104
+ if (!source)
105
+ return source;
106
+ return injectRuntime(source, injectedCode);
107
+ };
108
+ });
109
+ });
110
+ }
111
+ }
112
+ exports.HmrPatchRuntimePlugin = HmrPatchRuntimePlugin;
113
+ //# 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;;;EAGrB,iBAAO,CAAC,cAAc,CAAC,OAAO;;;;;qDAKqB,iBAAO,CAAC,cAAc,CAAC,eAAe;;;;;;;;;;kDAUzC,iBAAO,CAAC,cAAc,CAAC,eAAe;UAC9E,iBAAO,CAAC,cAAc,CAAC,eAAe;;;;;;;;;;;;0BAYtB,iBAAO,CAAC,cAAc,CAAC,WAAW;;;;;;QAMpD,iBAAO,CAAC,cAAc,CAAC,OAAO;;;;;YAK1B,iBAAO,CAAC,cAAc,CAAC,WAAW;;;;;;;;;;;CAW7C,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,iCAAiC,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,MAAM,EAAE,mBAAmB,EAAE,EAAE;gBACjG,mBAAmB,CAAC,GAAG,CAAC,iBAAO,CAAC,cAAc,CAAC,OAAO,CAAC,CAAA;gBACvD,mBAAmB,CAAC,GAAG,CAAC,iBAAO,CAAC,cAAc,CAAC,WAAW,CAAC,CAAA;YAC/D,CAAC,CAAC,CAAA;YAEF,WAAW,CAAC,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,WAAW,EAAE,aAAa,CAAC,EAAE;gBAC7D,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,CAAC,CAAA;QACN,CAAC,CACJ,CAAA;IACL,CAAC;CACJ;AA/BD,sDA+BC"}
@@ -0,0 +1,16 @@
1
+ import type { Expression } from "@babel/types";
2
+ export interface ModuleFactory {
3
+ factory: Expression;
4
+ moduleId: string;
5
+ }
6
+ export interface HotUpdateManifest {
7
+ m?: Array<string | number>;
8
+ }
9
+ export interface UpdatePatchSource {
10
+ type: 'update';
11
+ fromHash: string;
12
+ toHash: string;
13
+ moduleFactories: ModuleFactory[];
14
+ runtimeModules: Expression[];
15
+ removedModules: string[];
16
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/patch/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,28 @@
1
+ import * as t from "@babel/types";
2
+ import { Asset } from "webpack";
3
+ import { ModuleFactory } from "./types";
4
+ import { UpdatePatchSource } from "./types";
5
+ export interface ParseHotUpdateAssetsOptions {
6
+ manifests: Readonly<Asset>[];
7
+ scripts: Readonly<Asset>[];
8
+ }
9
+ /**
10
+ * 解析热更新产物
11
+ * @param opt
12
+ */
13
+ export declare const parseHotUpdateAssets: (opt: ParseHotUpdateAssetsOptions) => {
14
+ moduleFactories: Map<string, ModuleFactory>;
15
+ runtimeModules: t.Expression[];
16
+ removedModules: Set<string>;
17
+ };
18
+ /**
19
+ * 解析 chunk 产物
20
+ * @param source
21
+ */
22
+ export declare const parseChunkAsset: (source: string) => Map<string, ModuleFactory>;
23
+ export declare const mergeUpdatePatches: (basePatch: UpdatePatchSource, nextPatch: UpdatePatchSource) => UpdatePatchSource;
24
+ export interface generatePatchAssetSourceOpts {
25
+ bootstrapFactories: Map<string, ModuleFactory>;
26
+ recentUpdatePatches: UpdatePatchSource[];
27
+ }
28
+ export declare const generatePatchAssetSource: (opt: generatePatchAssetSourceOpts) => string;