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

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,11 +4,9 @@ import { SyncHook } from 'tapable';
4
4
  import type { Chunk, Compilation, Compiler } from 'webpack';
5
5
  import { ConcatSource } from 'webpack-sources';
6
6
  import type { Source } from 'webpack-sources';
7
- type StyleFilename = NonNullable<Compiler['options']['output']['cssFilename']>;
8
7
  export interface HmrCompilerPluginOptions {
9
8
  paths: IPaths;
10
9
  appConfig: AppConfig;
11
- styleFilename?: StyleFilename;
12
10
  debugNamespaces?: string;
13
11
  }
14
12
  type CompileRequested = SyncHook<[page: string]>;
@@ -29,7 +27,6 @@ export declare class HmrCompilerPlugin {
29
27
  private static readonly compilerHooksMap;
30
28
  private static readonly compilationHooksMap;
31
29
  private compiler?;
32
- private hasCompletedInitialBuild;
33
30
  private readonly pendingFiles;
34
31
  private readonly rebuildingFiles;
35
32
  private readonly options;
@@ -39,8 +36,6 @@ export declare class HmrCompilerPlugin {
39
36
  apply(compiler: Compiler): void;
40
37
  private requestCompile;
41
38
  private isPageChunk;
42
- /** PageShell 不包含真实页面的样式依赖,为缺失的页面样式补充空资产。 */
43
- private emitMissingPageStyleAssets;
44
39
  private reset;
45
40
  }
46
41
  export {};
@@ -21,7 +21,6 @@ const applyPatchBeforeStartup = (source, request) => {
21
21
  exports.applyPatchBeforeStartup = applyPatchBeforeStartup;
22
22
  class HmrCompilerPlugin {
23
23
  constructor(options) {
24
- this.hasCompletedInitialBuild = false;
25
24
  // 页面编译请求可能在任意时刻到达。先排队到下一轮 watchRun,避免与正在执行的编译相互覆盖。
26
25
  this.pendingFiles = new Set();
27
26
  // 当前编译批次的文件快照。与 pendingFiles 分离,确保编译期间新到达的请求留给下一批处理。
@@ -110,16 +109,6 @@ class HmrCompilerPlugin {
110
109
  return callback(null, true);
111
110
  callback();
112
111
  });
113
- const stage = compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_REPORT;
114
- compilation.hooks.processAssets.tap({ name: PLUGIN_NAME, stage }, () => {
115
- if (!this.hasCompletedInitialBuild && compilation.hash && compilation.errors.length === 0) {
116
- this.emitMissingPageStyleAssets(compilation);
117
- }
118
- });
119
- });
120
- compiler.hooks.afterEmit.tap(PLUGIN_NAME, compilation => {
121
- const isSuccessful = compilation.errors.length === 0 && Boolean(compilation.hash);
122
- this.hasCompletedInitialBuild = this.hasCompletedInitialBuild || isSuccessful;
123
112
  });
124
113
  // 当前批次完成后释放快照;编译期间新进入 pendingFiles 的请求不会被清理。
125
114
  compiler.hooks.done.tap(PLUGIN_NAME, () => this.rebuildingFiles.clear());
@@ -145,24 +134,8 @@ class HmrCompilerPlugin {
145
134
  return true;
146
135
  return Array.from(pages).some(page => { var _a; return ((_a = compilation.entrypoints.get(page)) === null || _a === void 0 ? void 0 : _a.getEntrypointChunk()) === chunk; });
147
136
  }
148
- /** PageShell 不包含真实页面的样式依赖,为缺失的页面样式补充空资产。 */
149
- emitMissingPageStyleAssets(compilation) {
150
- const { appConfig, styleFilename } = this.options;
151
- if (!styleFilename)
152
- return;
153
- (0, utils_1.getAllPages)(appConfig).forEach(page => {
154
- var _a;
155
- const chunk = (_a = compilation.entrypoints.get(page)) === null || _a === void 0 ? void 0 : _a.getEntrypointChunk();
156
- if (!chunk)
157
- return;
158
- const assetName = compilation.getPath(styleFilename, { chunk, contentHashType: 'css/mini-extract' });
159
- if (!compilation.getAsset(assetName))
160
- compilation.emitAsset(assetName, new webpack_sources_1.RawSource(''));
161
- });
162
- }
163
137
  reset() {
164
138
  (0, compile_state_1.clearCompiledPages)(this.options.paths.appPath);
165
- this.hasCompletedInitialBuild = false;
166
139
  this.rebuildingFiles.clear();
167
140
  this.pendingFiles.clear();
168
141
  }
@@ -1 +1 @@
1
- {"version":3,"file":"hmr-compiler-plugin.js","sourceRoot":"","sources":["../../src/compile/hmr-compiler-plugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hmr-compiler-plugin.js","sourceRoot":"","sources":["../../src/compile/hmr-compiler-plugin.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAuB;AACvB,2CAAkD;AAGlD,qCAAgC;AAEhC,qDAAuD;AAEvD,4CAA4C;AAC5C,mDAAoF;AACpF,oCAAoC;AACpC,gCAA2B;AAE3B,MAAM,WAAW,GAAG,SAAG,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAA;AAEnD,MAAM,WAAW,GAAG,mBAAmB,CAAA;AA+BhC,MAAM,uBAAuB,GAAG,CAAC,MAAc,EAAE,OAAe,EAAE,EAAE;IACvE,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,OAAO,KAAK,CAAC,CAAA;IACpD,OAAO,IAAI,8BAAY,CACnB,wCAAwC,YAAY,OAAO,EAC3D,MAAM,CACT,CAAA;AACL,CAAC,CAAA;AANY,QAAA,uBAAuB,2BAMnC;AAED,MAAa,iBAAiB;IAe1B,YAAY,OAAiC;QAR7C,mDAAmD;QAClC,iBAAY,GAAG,IAAI,GAAG,EAAU,CAAA;QAEjD,qDAAqD;QACpC,oBAAe,GAAG,IAAI,GAAG,EAAU,CAAA;QAKhD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IAC1B,CAAC;IAED,MAAM,CAAC,gBAAgB,CAAC,QAAkB;QACtC,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpD,MAAM,gBAAgB,GAAqB,IAAI,kBAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;YACjE,iBAAiB,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAC,gBAAgB,EAAC,CAAC,CAAA;QACxE,CAAC;QACD,OAAO,iBAAiB,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAE,CAAA;IAC5D,CAAC;IAED,MAAM,CAAC,mBAAmB,CAAC,WAAwB;QAC/C,IAAI,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YAC1D,MAAM,oBAAoB,GAAyB,IAAI,kBAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,CAAA;YAC5E,iBAAiB,CAAC,mBAAmB,CAAC,GAAG,CAAC,WAAW,EAAE,EAAC,oBAAoB,EAAC,CAAC,CAAA;QAClF,CAAC;QACD,OAAO,iBAAiB,CAAC,mBAAmB,CAAC,GAAG,CAAC,WAAW,CAAE,CAAA;IAClE,CAAC;IAED,KAAK,CAAC,QAAkB;QACpB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QAExB,iBAAiB,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,gBAAgB,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE;YAClF,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA;QAC7B,CAAC,CAAC,CAAA;QAEF,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,eAAe,CAAC,EAAE;;YACvD,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,KAAK,CAAC;gBAAE,OAAM;YAExC,mDAAmD;YACnD,qDAAqD;YACrD,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAA;YAC5B,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAA;YACjE,eAAe,CAAC,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,MAAA,eAAe,CAAC,aAAa,mCAAI,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAA;YACzG,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAA;QAC7B,CAAC,CAAC,CAAA;QAEF,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE;YACtD,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,IAAA,mBAAW,EAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAA;YAC1D,MAAM,WAAW,GAAG,CAAC,KAAY,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,KAAK,EAAE,KAAK,CAAC,CAAA;YACjF,MAAM,QAAQ,GAAG,iBAAiB,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAA;YACnE,MAAM,eAAe,GAAG,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,uBAAuB,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAA;YAE5G,MAAM,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAA;YAEpE,MAAM,WAAW,GAAG,qBAAqB,CAAA;YAEzC,QAAQ;YACR,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,KAAM,EAAC,EAAE,CAAC,cAAc,EAAE,YAA8B,EAAE,EAAE;gBACzJ,IAAI,CAAC,YAAY,CAAC,QAAQ;oBAAE,OAAM;gBAElC,IAAI,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,mBAAmB,CAAC;oBAAE,OAAM;gBAElF,MAAM,eAAe,GAAG,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAA;gBAErH,IAAI,eAAe,GAAG,CAAC;oBAAE,OAAM;gBAE/B,MAAM,aAAa,GAAG,EAAC,QAAQ,EAAE,YAAY,CAAC,QAAQ,EAAE,eAAe,EAAE,IAAI,CAAC,OAAO,CAAC,eAAe,EAAC,CAAA;gBACtG,iDAAiD;gBACjD,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC,EAAE,EAAC,MAAM,EAAE,mBAAmB,EAAE,OAAO,EAAE,aAAa,EAAC,CAAC,CAAA;YAC1G,CAAC,CACJ,CAAA;YAED,yEAAyE;YACzE,2CAA2C;YAC3C,eAAe,CAAC,WAAW,CAAC,GAAG,CAAC,EAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,KAAM,EAAC,EAAE,CAAC,MAAM,EAAE,EAAC,KAAK,EAAC,EAAE,EAAE;gBACrF,MAAM,gBAAgB,GAAG,WAAW,CAAC,KAAK,CAAC,CAAA;gBAC3C,QAAQ,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,gBAAgB,EAAE,KAAK,EAAC,CAAC,CAAA;gBACjG,OAAO,gBAAgB,CAAC,CAAC,CAAC,IAAI,2BAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;YAC1D,CAAC,CAAC,CAAA;YAEF,eAAe,CAAC,aAAa,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,EAAC,KAAK,EAAC,EAAE,EAAE;gBACxE,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;oBAAE,OAAO,MAAM,CAAA;gBAEtC,MAAM,gBAAgB,GAAG,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,uBAAuB;qBACvE,wBAAwB,CAAC,KAAK,EAAE,WAAW,CAAC,aAAa,CAAC,CAAA;gBAC/D,MAAM,SAAS,GAAG,WAAW,CAAC,OAAO,CAAC,gBAAgB,EAAE;oBACpD,KAAK;oBACL,eAAe,EAAE,YAAY;oBAC7B,IAAI,EAAE,WAAW,CAAC,IAAI;iBACzB,CAAC,CAAA;gBACF,MAAM,WAAW,GAAG,2BAAe,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;gBACxD,MAAM,YAAY,GAAG,cAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,cAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,WAAW,CAAC,CAAA;gBACpF,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,YAAY,EAAE,CAAA;gBAEjF,kDAAkD;gBAClD,yDAAyD;gBACzD,OAAO,IAAA,+BAAuB,EAAC,MAAM,EAAE,OAAO,CAAC,CAAA;YACnD,CAAC,CAAC,CAAA;YAEF,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,QAAQ,CAC7E,WAAW,EACX,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE;;gBAC3B,MAAM,CAAC,YAAY,CAAC,GAAG,MAAA,MAAA,MAAM,CAAC,QAAQ,0CAAE,KAAK,CAAC,GAAG,CAAC,mCAAI,EAAE,CAAA;gBACxD,kEAAkE;gBAClE,IAAI,YAAY,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,YAAY,CAAC;oBAAE,OAAO,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;gBACvF,QAAQ,EAAE,CAAA;YACd,CAAC,CACJ,CAAA;QAEL,CAAC,CAAC,CAAA;QAEF,6CAA6C;QAC7C,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC,CAAA;QAExE,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAA;IAClE,CAAC;IAEO,cAAc,CAAC,IAAY;;QAC/B,IAAI,CAAC;YACD,IAAI,IAAA,8BAAc,EAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC;gBAAE,OAAM;YAC5D,oDAAoD;YACpD,WAAW,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAA;YACrC,IAAA,gCAAgB,EAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;YAClD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAA,4BAAmB,EAAC,cAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;YAC7F,MAAA,MAAA,IAAI,CAAC,QAAQ,0CAAE,QAAQ,0CAAE,UAAU,EAAE,CAAA;QACzC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAA;QACvD,CAAC;IACL,CAAC;IAEO,WAAW,CAAC,WAAwB,EAAE,KAAkB,EAAE,KAAY;QAC1E,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAA;QACpD,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,WAAC,OAAA,CAAA,MAAA,WAAW,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,0CAAE,kBAAkB,EAAE,MAAK,KAAK,CAAA,EAAA,CAAC,CAAA;IAC5G,CAAC;IAEO,KAAK;QACT,IAAA,kCAAkB,EAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAC9C,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAA;QAC5B,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAA;IAC7B,CAAC;;AAlJL,8CAmJC;AAlJ2B,kCAAgB,GAAG,IAAI,OAAO,EAA8B,AAA5C,CAA4C;AAE5D,qCAAmB,GAAG,IAAI,OAAO,EAAoC,AAAlD,CAAkD"}
@@ -0,0 +1,28 @@
1
+ import type { Compiler } from 'webpack';
2
+ export declare const PLUGIN_NAME = "HmrOutputPlugin";
3
+ export interface AtomicOutputPluginOptions {
4
+ /** 这些资产仍由 Webpack 生成,但等其他资产输出完成后才按配置顺序发布。 */
5
+ deferredAssets?: readonly string[];
6
+ }
7
+ export declare class HmrOutputPlugin {
8
+ private readonly deferredAssets;
9
+ private readonly deferredOutputs;
10
+ constructor(options?: AtomicOutputPluginOptions);
11
+ apply(compiler: Compiler): void;
12
+ /**
13
+ * 代理原始 OutputFileSystem。
14
+ * 仅重写 writeFile,其余方法调用原始文件系统实现。
15
+ */
16
+ private createOutputFileSystem;
17
+ /**
18
+ * 创建自定义 writeFile 实现。
19
+ */
20
+ private createWriteFile;
21
+ private collectDeferredOutputs;
22
+ private getAssetName;
23
+ private flushDeferredOutputs;
24
+ /**
25
+ * 通过同目录临时文件和 rename 原子替换目标文件。
26
+ */
27
+ private writeFileAtomically;
28
+ }
@@ -0,0 +1,145 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.HmrOutputPlugin = exports.PLUGIN_NAME = void 0;
16
+ const node_crypto_1 = require("node:crypto");
17
+ const promises_1 = require("node:fs/promises");
18
+ const node_path_1 = __importDefault(require("node:path"));
19
+ exports.PLUGIN_NAME = 'HmrOutputPlugin';
20
+ class HmrOutputPlugin {
21
+ constructor(options = {}) {
22
+ var _a;
23
+ this.deferredOutputs = new WeakMap();
24
+ this.deferredAssets = (_a = options.deferredAssets) !== null && _a !== void 0 ? _a : [];
25
+ }
26
+ apply(compiler) {
27
+ const outputFileSystem = compiler.outputFileSystem;
28
+ if (!outputFileSystem)
29
+ throw new Error(`[${exports.PLUGIN_NAME}] Webpack outputFileSystem 尚未初始化`);
30
+ compiler.outputFileSystem = this.createOutputFileSystem(compiler, outputFileSystem);
31
+ // 尽可能在其他 emit tap 之后读取资产,随后 Webpack 才开始物理输出。
32
+ compiler.hooks.emit.tap({ name: exports.PLUGIN_NAME, stage: Number.MAX_SAFE_INTEGER }, compilation => {
33
+ if (compilation.errors.length > 0)
34
+ return;
35
+ this.collectDeferredOutputs(compiler, compilation);
36
+ });
37
+ // 等待普通资产写入完成后,再按配置顺序发布延迟资产。
38
+ compiler.hooks.afterEmit.tapPromise(exports.PLUGIN_NAME, (compilation) => __awaiter(this, void 0, void 0, function* () {
39
+ try {
40
+ if (compilation.errors.length > 0)
41
+ return;
42
+ yield this.flushDeferredOutputs(compilation);
43
+ }
44
+ finally {
45
+ this.deferredOutputs.delete(compilation);
46
+ }
47
+ }));
48
+ }
49
+ /**
50
+ * 代理原始 OutputFileSystem。
51
+ * 仅重写 writeFile,其余方法调用原始文件系统实现。
52
+ */
53
+ createOutputFileSystem(compiler, original) {
54
+ return new Proxy(original, {
55
+ get: (target, property) => {
56
+ if (property === 'writeFile')
57
+ return this.createWriteFile(compiler, original);
58
+ const value = Reflect.get(target, property, target);
59
+ return typeof value === 'function' ? value.bind(target) : value;
60
+ }
61
+ });
62
+ }
63
+ /**
64
+ * 创建自定义 writeFile 实现。
65
+ */
66
+ createWriteFile(compiler, original) {
67
+ const originalWriteFile = original.writeFile.bind(original);
68
+ return (file, data, optionsOrCallback, optionalCallback) => {
69
+ const callback = (() => {
70
+ if (typeof optionsOrCallback === 'function')
71
+ return optionsOrCallback;
72
+ return optionalCallback;
73
+ })();
74
+ const triggerOriginalWriteFile = () => {
75
+ if (typeof optionsOrCallback === 'function')
76
+ return originalWriteFile(file, data, optionsOrCallback);
77
+ if (optionalCallback)
78
+ originalWriteFile(file, data, optionsOrCallback, optionalCallback);
79
+ };
80
+ if (typeof file !== 'string' || !callback)
81
+ return triggerOriginalWriteFile();
82
+ const assetName = this.getAssetName(compiler, file);
83
+ if (assetName && this.deferredAssets.includes(assetName))
84
+ return callback(null);
85
+ this.writeFileAtomically(file, data).then(() => callback(null)).catch(error => callback(error));
86
+ };
87
+ }
88
+ collectDeferredOutputs(compiler, compilation) {
89
+ if (this.deferredAssets.length === 0)
90
+ return;
91
+ const { path: outputPath } = compiler.options.output;
92
+ if (!outputPath)
93
+ throw new Error(`[${exports.PLUGIN_NAME}] 无法收集延迟资产:output.path 未配置`);
94
+ const outputs = new Map();
95
+ this.deferredAssets.forEach(assetName => {
96
+ const asset = compilation.getAsset(assetName);
97
+ if (!asset)
98
+ return;
99
+ const data = asset.source.source();
100
+ outputs.set(assetName, { data, file: node_path_1.default.join(outputPath, assetName) });
101
+ });
102
+ this.deferredOutputs.set(compilation, outputs);
103
+ }
104
+ getAssetName(compiler, file) {
105
+ const { path: outputPath } = compiler.options.output;
106
+ if (!outputPath)
107
+ return;
108
+ const assetName = node_path_1.default.relative(outputPath, file).replaceAll('\\', '/');
109
+ if (assetName.startsWith('../') || node_path_1.default.isAbsolute(assetName))
110
+ return;
111
+ return assetName;
112
+ }
113
+ flushDeferredOutputs(compilation) {
114
+ return __awaiter(this, void 0, void 0, function* () {
115
+ const outputs = this.deferredOutputs.get(compilation);
116
+ if (!outputs)
117
+ return;
118
+ return Promise.all(this.deferredAssets.map(assetName => {
119
+ const output = outputs.get(assetName);
120
+ if (!output)
121
+ return;
122
+ return this.writeFileAtomically(output.file, output.data);
123
+ }));
124
+ });
125
+ }
126
+ /**
127
+ * 通过同目录临时文件和 rename 原子替换目标文件。
128
+ */
129
+ writeFileAtomically(targetPath, data) {
130
+ return __awaiter(this, void 0, void 0, function* () {
131
+ const directory = node_path_1.default.dirname(targetPath);
132
+ const temporaryPath = node_path_1.default.join(directory, `.${node_path_1.default.basename(targetPath)}.${(0, node_crypto_1.randomUUID)()}.tmp`);
133
+ yield (0, promises_1.mkdir)(directory, { recursive: true });
134
+ try {
135
+ yield (0, promises_1.writeFile)(temporaryPath, data);
136
+ yield (0, promises_1.rename)(temporaryPath, targetPath);
137
+ }
138
+ finally {
139
+ yield (0, promises_1.rm)(temporaryPath, { force: true });
140
+ }
141
+ });
142
+ }
143
+ }
144
+ exports.HmrOutputPlugin = HmrOutputPlugin;
145
+ //# sourceMappingURL=hmr-output-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hmr-output-plugin.js","sourceRoot":"","sources":["../../src/compile/hmr-output-plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { Compilation, Compiler } from 'webpack';
2
+ export interface HmrStylePluginOptions {
3
+ /** Webpack/Taro 生成的全局样式资产。 */
4
+ sourceAsset: string;
5
+ /** 固定入口资产;后续编译持续引用 patchAsset。 */
6
+ entryAsset: string;
7
+ /** 每轮热编译输出的独立样式资产。 */
8
+ patchAsset: string;
9
+ /** 是否将入口固定为对 patchAsset 的导入。 */
10
+ preserveEntry?: boolean;
11
+ /** 自定义源样式到 patch 样式的内容转换。 */
12
+ transform?: (source: string, compilation: Compilation) => string;
13
+ }
14
+ /**
15
+ * 将构建器生成的全局样式复制到独立 HMR 资产,并可固定入口文件。
16
+ * 应在构建器完成最终资产变换后运行。
17
+ */
18
+ export declare class HmrStylePlugin {
19
+ private readonly options;
20
+ private initialBuildDone;
21
+ constructor(options: HmrStylePluginOptions);
22
+ apply(compiler: Compiler): void;
23
+ private processAssets;
24
+ private updateAsset;
25
+ }
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HmrStylePlugin = void 0;
4
+ const webpack_sources_1 = require("webpack-sources");
5
+ const PLUGIN_NAME = 'HmrStylePlugin';
6
+ /**
7
+ * 将构建器生成的全局样式复制到独立 HMR 资产,并可固定入口文件。
8
+ * 应在构建器完成最终资产变换后运行。
9
+ */
10
+ class HmrStylePlugin {
11
+ constructor(options) {
12
+ this.initialBuildDone = false;
13
+ this.options = options;
14
+ }
15
+ apply(compiler) {
16
+ compiler.hooks.compilation.tap(PLUGIN_NAME, compilation => {
17
+ const stage = compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_REPORT;
18
+ compilation.hooks.processAssets.tap({ name: PLUGIN_NAME, stage }, () => this.processAssets(compilation));
19
+ });
20
+ compiler.hooks.afterEmit.tap(PLUGIN_NAME, compilation => {
21
+ if (compilation.errors.length === 0 && compilation.hash)
22
+ this.initialBuildDone = true;
23
+ });
24
+ compiler.hooks.watchClose.tap(PLUGIN_NAME, () => {
25
+ this.initialBuildDone = false;
26
+ });
27
+ }
28
+ processAssets(compilation) {
29
+ var _a;
30
+ if (!compilation.hash || compilation.errors.length > 0)
31
+ return;
32
+ const { sourceAsset, entryAsset, patchAsset, preserveEntry = true, transform } = this.options;
33
+ const source = (_a = compilation.getAsset(sourceAsset)) === null || _a === void 0 ? void 0 : _a.source.source().toString();
34
+ if (source !== undefined) {
35
+ const patchSource = transform ? transform(source, compilation) : source;
36
+ this.updateAsset(compilation, patchAsset, new webpack_sources_1.RawSource(patchSource), {
37
+ hotModuleReplacement: this.initialBuildDone
38
+ });
39
+ }
40
+ if (preserveEntry) {
41
+ const entry = new webpack_sources_1.RawSource(`@import ${JSON.stringify(`./${patchAsset}`)};\n`);
42
+ this.updateAsset(compilation, entryAsset, entry);
43
+ }
44
+ }
45
+ updateAsset(compilation, name, source, info = {}) {
46
+ if (compilation.getAsset(name))
47
+ compilation.updateAsset(name, source, info);
48
+ else
49
+ compilation.emitAsset(name, source, info);
50
+ }
51
+ }
52
+ exports.HmrStylePlugin = HmrStylePlugin;
53
+ //# sourceMappingURL=hmr-style-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hmr-style-plugin.js","sourceRoot":"","sources":["../../src/compile/hmr-style-plugin.ts"],"names":[],"mappings":";;;AACA,qDAAyC;AAezC,MAAM,WAAW,GAAG,gBAAgB,CAAA;AAEpC;;;GAGG;AACH,MAAa,cAAc;IAKvB,YAAY,OAA8B;QAFlC,qBAAgB,GAAG,KAAK,CAAA;QAG5B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IAC1B,CAAC;IAED,KAAK,CAAC,QAAkB;QACpB,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE;YACtD,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,2BAA2B,CAAA;YACtE,WAAW,CAAC,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,EAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAC,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAA;QAC1G,CAAC,CAAC,CAAA;QAEF,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE;YACpD,IAAI,WAAW,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,WAAW,CAAC,IAAI;gBAAE,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAA;QACzF,CAAC,CAAC,CAAA;QAEF,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,EAAE;YAC5C,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAA;QACjC,CAAC,CAAC,CAAA;IACN,CAAC;IAEO,aAAa,CAAC,WAAwB;;QAC1C,IAAI,CAAC,WAAW,CAAC,IAAI,IAAI,WAAW,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;YAAE,OAAM;QAE9D,MAAM,EAAC,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,GAAG,IAAI,EAAE,SAAS,EAAC,GAAG,IAAI,CAAC,OAAO,CAAA;QAC3F,MAAM,MAAM,GAAG,MAAA,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC,0CAAE,MAAM,CAAC,MAAM,GAAG,QAAQ,EAAE,CAAA;QAE5E,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACvB,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;YACvE,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,UAAU,EAAE,IAAI,2BAAS,CAAC,WAAW,CAAC,EAAE;gBAClE,oBAAoB,EAAE,IAAI,CAAC,gBAAgB;aAC9C,CAAC,CAAA;QACN,CAAC;QAED,IAAI,aAAa,EAAE,CAAC;YAChB,MAAM,KAAK,GAAG,IAAI,2BAAS,CAAC,WAAW,IAAI,CAAC,SAAS,CAAC,KAAK,UAAU,EAAE,CAAC,KAAK,CAAC,CAAA;YAC9E,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,UAAU,EAAE,KAAK,CAAC,CAAA;QACpD,CAAC;IACL,CAAC;IAEO,WAAW,CAAC,WAAwB,EAAE,IAAY,EAAE,MAAiB,EAAE,IAAI,GAAG,EAAE;QACpF,IAAI,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,WAAW,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAA;;YACtE,WAAW,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAA;IAClD,CAAC;CACJ;AA/CD,wCA+CC"}
@@ -1,4 +1,5 @@
1
1
  export declare const HMR_OUTPUT_PATH = "hmr";
2
2
  export declare const HMR_PATCH_ASSET = "hmr/patch.js";
3
+ export declare const HMR_PATCH_STYLE_ASSET = "hmr/patch.wxss";
3
4
  export declare const DEFAULT_HMR_PATCH_HISTORY_LIMIT = 20;
4
5
  export declare const DEFAULT_DEBUG_NAMESPACES = "taro-hmr-compile:*";
package/dist/constants.js CHANGED
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DEFAULT_DEBUG_NAMESPACES = exports.DEFAULT_HMR_PATCH_HISTORY_LIMIT = exports.HMR_PATCH_ASSET = exports.HMR_OUTPUT_PATH = void 0;
3
+ exports.DEFAULT_DEBUG_NAMESPACES = exports.DEFAULT_HMR_PATCH_HISTORY_LIMIT = exports.HMR_PATCH_STYLE_ASSET = exports.HMR_PATCH_ASSET = exports.HMR_OUTPUT_PATH = void 0;
4
4
  exports.HMR_OUTPUT_PATH = 'hmr';
5
5
  exports.HMR_PATCH_ASSET = `${exports.HMR_OUTPUT_PATH}/patch.js`;
6
+ exports.HMR_PATCH_STYLE_ASSET = `${exports.HMR_OUTPUT_PATH}/patch.wxss`;
6
7
  exports.DEFAULT_HMR_PATCH_HISTORY_LIMIT = 20;
7
8
  exports.DEFAULT_DEBUG_NAMESPACES = 'taro-hmr-compile:*';
8
9
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,eAAe,GAAG,KAAK,CAAA;AAEvB,QAAA,eAAe,GAAG,GAAG,uBAAe,WAAW,CAAA;AAE/C,QAAA,+BAA+B,GAAG,EAAE,CAAA;AAEpC,QAAA,wBAAwB,GAAG,oBAAoB,CAAA"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,eAAe,GAAG,KAAK,CAAA;AAEvB,QAAA,eAAe,GAAG,GAAG,uBAAe,WAAW,CAAA;AAE/C,QAAA,qBAAqB,GAAG,GAAG,uBAAe,aAAa,CAAA;AAEvD,QAAA,+BAA+B,GAAG,EAAE,CAAA;AAEpC,QAAA,wBAAwB,GAAG,oBAAoB,CAAA"}
package/dist/index.js CHANGED
@@ -15,12 +15,14 @@ const hmr_compiler_plugin_1 = require("./compile/hmr-compiler-plugin");
15
15
  const hmr_patch_plugin_1 = require("./patch/hmr-patch-plugin");
16
16
  const hmr_server_plugin_1 = require("./server/hmr-server-plugin");
17
17
  const compiler_1 = require("@taro-hmr-compile/core/compiler");
18
+ const hmr_output_plugin_1 = require("./compile/hmr-output-plugin");
18
19
  const log_1 = require("./log");
20
+ const CUSTOM_WRAPPER = 'custom-wrapper';
19
21
  exports.default = (ctx, pluginOpts) => {
20
22
  var _a, _b, _c;
21
23
  if (!((_a = ctx.runOpts.options) === null || _a === void 0 ? void 0 : _a.isWatch))
22
24
  return;
23
- const { appPath, sourcePath, outputPath } = ctx.paths;
25
+ const { appPath, sourcePath } = ctx.paths;
24
26
  const { framework } = ctx.initialConfig;
25
27
  const appConfig = (0, utils_1.getAppConfig)(ctx);
26
28
  const host = (_b = pluginOpts.host) !== null && _b !== void 0 ? _b : '127.0.0.1';
@@ -32,14 +34,17 @@ exports.default = (ctx, pluginOpts) => {
32
34
  })();
33
35
  if (debugNamespaces)
34
36
  (0, log_1.enableLog)(debugNamespaces);
35
- ctx.onBuildStart(() => (0, compiler_1.emptyDirFile)(outputPath));
37
+ ctx.modifyComponentConfig(({ componentConfig }) => {
38
+ if (componentConfig.thirdPartyComponents.has(CUSTOM_WRAPPER))
39
+ return;
40
+ componentConfig.thirdPartyComponents.set(CUSTOM_WRAPPER, new Set());
41
+ });
36
42
  ctx.modifyRunnerOpts(({ opts }) => {
37
43
  var _a;
38
44
  (_a = opts.output) !== null && _a !== void 0 ? _a : (opts.output = {});
39
45
  opts.output.clean = false;
40
46
  });
41
47
  ctx.modifyWebpackChain((_a) => __awaiter(void 0, [_a], void 0, function* ({ chain, webpack }) {
42
- var _b;
43
48
  const port = yield (0, compiler_1.findAvailablePort)(preferredPort, host);
44
49
  const compileUrl = `http://${host}:${port}/compile`;
45
50
  if (port !== preferredPort)
@@ -58,9 +63,15 @@ exports.default = (ctx, pluginOpts) => {
58
63
  .set('hotUpdateChunkFilename', `${constants_1.HMR_OUTPUT_PATH}/[id].[fullhash].hot-update.js`)
59
64
  .set('hotUpdateMainFilename', `${constants_1.HMR_OUTPUT_PATH}/[runtime].[fullhash].hot-update.json`);
60
65
  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 }]);
66
+ chain.plugin('hmr-compiler-plugin').use(hmr_compiler_plugin_1.HmrCompilerPlugin, [{
67
+ paths: ctx.paths,
68
+ appConfig,
69
+ debugNamespaces
70
+ }]);
63
71
  chain.plugin('hmr-plugin').use(webpack.HotModuleReplacementPlugin);
72
+ chain.plugin('hmr-output-plugin').use(hmr_output_plugin_1.HmrOutputPlugin, [{
73
+ deferredAssets: [constants_1.HMR_PATCH_STYLE_ASSET, constants_1.HMR_PATCH_ASSET, 'app.wxss'],
74
+ }]);
64
75
  chain.plugin('hmr-patch-plugin').use(hmr_patch_plugin_1.HmrPatchPlugin, [{ patchHistoryLimit }]);
65
76
  chain.plugin('hmr-server-plugin').use(hmr_server_plugin_1.HmrServerPlugin, [{ host, port }]);
66
77
  }));
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -5,13 +5,19 @@ export declare class HmrPatchPlugin {
5
5
  private previousHash;
6
6
  private initialBuildDone;
7
7
  private readonly patchProcessor;
8
+ private readonly preservedAssets;
8
9
  private readonly emittedAssetSources;
9
10
  constructor(options: HmrPatchPluginOptions);
10
11
  apply(compiler: Compiler): void;
11
12
  private processAssets;
13
+ /** 将 Webpack 汇总后的 App 样式放入固定 patch 文件,App 入口只保留稳定引用。 */
14
+ private processStyleAssets;
15
+ private emitAsset;
12
16
  /** 热更新转换完成后,保留固定 patch 与发生变化的模板、平台样式资产。 */
13
17
  private removeSupersededAssets;
14
18
  private emitPatchAsset;
15
19
  private reset;
20
+ /** 补丁已从 hot-update assets 生成后,在 Webpack 写盘前从本次 compilation 移除它们。 */
21
+ private removeHotUpdateAssets;
16
22
  }
17
23
  export {};
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.HmrPatchPlugin = void 0;
4
7
  const webpack_sources_1 = require("webpack-sources");
8
+ const node_path_1 = __importDefault(require("node:path"));
5
9
  const constants_1 = require("../constants");
6
10
  const hmr_compiler_plugin_1 = require("../compile/hmr-compiler-plugin");
7
11
  const hmr_patch_runtime_plugin_1 = require("./hmr-patch-runtime-plugin");
@@ -11,6 +15,7 @@ const HOT_UPDATE_MANIFEST_SUFFIX = '.hot-update.json';
11
15
  const HOT_UPDATE_SCRIPT_SUFFIX = '.hot-update.js';
12
16
  const STYLE_ASSET_PATTERN = /\.(?:css|wxss|acss|ttss|qss|jxss)(?:\.map)?$/i;
13
17
  const TEMPLATE_RUNTIME_ASSET_PATTERN = /(?:^|\/)(?:base\.wxml|utils\.wxs)$/i;
18
+ const STYLE_ENTRY_ASSET = 'app.wxss';
14
19
  const isPassthroughAsset = (assetName) => {
15
20
  return STYLE_ASSET_PATTERN.test(assetName) || TEMPLATE_RUNTIME_ASSET_PATTERN.test(assetName);
16
21
  };
@@ -18,6 +23,7 @@ class HmrPatchPlugin {
18
23
  constructor(options) {
19
24
  this.previousHash = '';
20
25
  this.initialBuildDone = false;
26
+ this.preservedAssets = new Set([constants_1.HMR_PATCH_ASSET, STYLE_ENTRY_ASSET, constants_1.HMR_PATCH_STYLE_ASSET]);
21
27
  this.emittedAssetSources = new Map();
22
28
  this.patchProcessor = new hmr_patch_processor_1.HmrPatchProcessor(options);
23
29
  }
@@ -29,7 +35,13 @@ class HmrPatchPlugin {
29
35
  });
30
36
  // 等 Webpack 生成完整的 hot-update assets 后,再统一转换成固定的 patch.js。
31
37
  const stage = compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_REPORT;
32
- compilation.hooks.processAssets.tap({ name: PLUGIN_NAME, stage }, () => this.processAssets(compilation));
38
+ compilation.hooks.processAssets.tap({ name: PLUGIN_NAME, stage }, () => {
39
+ if (compilation.errors.length > 0 || !compilation.hash)
40
+ return;
41
+ this.processStyleAssets(compilation);
42
+ this.processAssets(compilation);
43
+ });
44
+ this.removeHotUpdateAssets(compilation);
33
45
  });
34
46
  compiler.hooks.afterEmit.tap(PLUGIN_NAME, compilation => {
35
47
  const isSuccessful = compilation.errors.length === 0 && Boolean(compilation.hash);
@@ -60,10 +72,39 @@ class HmrPatchPlugin {
60
72
  this.removeSupersededAssets(compilation);
61
73
  this.previousHash = toHash;
62
74
  }
75
+ /** 将 Webpack 汇总后的 App 样式放入固定 patch 文件,App 入口只保留稳定引用。 */
76
+ processStyleAssets(compilation) {
77
+ const entryAsset = compilation.getAsset(STYLE_ENTRY_ASSET);
78
+ const source = entryAsset === null || entryAsset === void 0 ? void 0 : entryAsset.source.source().toString();
79
+ if (!source)
80
+ return;
81
+ const importPath = node_path_1.default.posix.relative(node_path_1.default.posix.dirname(STYLE_ENTRY_ASSET), constants_1.HMR_PATCH_STYLE_ASSET);
82
+ const patchImport = importPath.startsWith('.') ? importPath : `./${importPath}`;
83
+ const alreadyPatched = source.trim() === `@import "${patchImport}";` || source.trim() === `@import '${patchImport}';`;
84
+ if (!alreadyPatched) {
85
+ const patchDirectory = node_path_1.default.posix.dirname(constants_1.HMR_PATCH_STYLE_ASSET);
86
+ const sourceDirectory = node_path_1.default.posix.dirname(STYLE_ENTRY_ASSET);
87
+ const patchSource = source.replace(/(@import\s+)(["'])([^"']+)\2/g, (match, prefix, quote, request) => {
88
+ if (/^(?:[a-z]+:|\/|#)/i.test(request))
89
+ return match;
90
+ const resolved = node_path_1.default.posix.normalize(node_path_1.default.posix.join(sourceDirectory, request));
91
+ const relative = node_path_1.default.posix.relative(patchDirectory, resolved);
92
+ return `${prefix}${quote}${relative.startsWith('.') ? relative : `./${relative}`}${quote}`;
93
+ });
94
+ this.emitAsset(compilation, constants_1.HMR_PATCH_STYLE_ASSET, new webpack_sources_1.RawSource(patchSource));
95
+ }
96
+ this.emitAsset(compilation, STYLE_ENTRY_ASSET, new webpack_sources_1.RawSource(`@import ${JSON.stringify(patchImport)};\n`));
97
+ }
98
+ emitAsset(compilation, assetName, source) {
99
+ if (compilation.getAsset(assetName))
100
+ compilation.updateAsset(assetName, source);
101
+ else
102
+ compilation.emitAsset(assetName, source);
103
+ }
63
104
  /** 热更新转换完成后,保留固定 patch 与发生变化的模板、平台样式资产。 */
64
105
  removeSupersededAssets(compilation) {
65
106
  compilation.getAssets().forEach(asset => {
66
- if (asset.name === constants_1.HMR_PATCH_ASSET)
107
+ if (this.preservedAssets.has(asset.name))
67
108
  return;
68
109
  if (!isPassthroughAsset(asset.name))
69
110
  return compilation.deleteAsset(asset.name);
@@ -88,6 +129,14 @@ class HmrPatchPlugin {
88
129
  this.emittedAssetSources.clear();
89
130
  this.patchProcessor.reset();
90
131
  }
132
+ /** 补丁已从 hot-update assets 生成后,在 Webpack 写盘前从本次 compilation 移除它们。 */
133
+ removeHotUpdateAssets(compilation) {
134
+ compilation.getAssets().forEach(asset => {
135
+ if (asset.name.endsWith(HOT_UPDATE_MANIFEST_SUFFIX) || asset.name.endsWith(HOT_UPDATE_SCRIPT_SUFFIX)) {
136
+ compilation.deleteAsset(asset.name);
137
+ }
138
+ });
139
+ }
91
140
  }
92
141
  exports.HmrPatchPlugin = HmrPatchPlugin;
93
142
  //# sourceMappingURL=hmr-patch-plugin.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"hmr-patch-plugin.js","sourceRoot":"","sources":["../../src/patch/hmr-patch-plugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hmr-patch-plugin.js","sourceRoot":"","sources":["../../src/patch/hmr-patch-plugin.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.1-alpha.10",
3
+ "version": "0.0.1-alpha.11",
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.1-alpha.10",
48
+ "@taro-hmr-compile/core": "0.0.1-alpha.11",
49
49
  "debug": "^4.4.3",
50
50
  "lodash": "^4.18.1",
51
51
  "tapable": "^2.3.3",
@@ -20,12 +20,9 @@ interface TaroNormalModule {
20
20
  loaders: Array<{ loader: string; options?: unknown }>
21
21
  }
22
22
 
23
- type StyleFilename = NonNullable<Compiler['options']['output']['cssFilename']>
24
-
25
23
  export interface HmrCompilerPluginOptions {
26
24
  paths: IPaths
27
25
  appConfig: AppConfig
28
- styleFilename?: StyleFilename
29
26
  debugNamespaces?: string
30
27
  }
31
28
 
@@ -62,8 +59,6 @@ export class HmrCompilerPlugin {
62
59
 
63
60
  private compiler?: Compiler
64
61
 
65
- private hasCompletedInitialBuild = false
66
-
67
62
  // 页面编译请求可能在任意时刻到达。先排队到下一轮 watchRun,避免与正在执行的编译相互覆盖。
68
63
  private readonly pendingFiles = new Set<string>()
69
64
 
@@ -173,17 +168,6 @@ export class HmrCompilerPlugin {
173
168
  },
174
169
  )
175
170
 
176
- const stage = compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_REPORT
177
- compilation.hooks.processAssets.tap({name: PLUGIN_NAME, stage}, () => {
178
- if (!this.hasCompletedInitialBuild && compilation.hash && compilation.errors.length === 0) {
179
- this.emitMissingPageStyleAssets(compilation)
180
- }
181
- })
182
- })
183
-
184
- compiler.hooks.afterEmit.tap(PLUGIN_NAME, compilation => {
185
- const isSuccessful = compilation.errors.length === 0 && Boolean(compilation.hash)
186
- this.hasCompletedInitialBuild = this.hasCompletedInitialBuild || isSuccessful
187
171
  })
188
172
 
189
173
  // 当前批次完成后释放快照;编译期间新进入 pendingFiles 的请求不会被清理。
@@ -210,23 +194,8 @@ export class HmrCompilerPlugin {
210
194
  return Array.from(pages).some(page => compilation.entrypoints.get(page)?.getEntrypointChunk() === chunk)
211
195
  }
212
196
 
213
- /** PageShell 不包含真实页面的样式依赖,为缺失的页面样式补充空资产。 */
214
- private emitMissingPageStyleAssets(compilation: Compilation) {
215
- const {appConfig, styleFilename} = this.options
216
- if (!styleFilename) return
217
-
218
- getAllPages(appConfig).forEach(page => {
219
- const chunk = compilation.entrypoints.get(page)?.getEntrypointChunk()
220
- if (!chunk) return
221
-
222
- const assetName = compilation.getPath(styleFilename, {chunk, contentHashType: 'css/mini-extract'})
223
- if (!compilation.getAsset(assetName)) compilation.emitAsset(assetName, new RawSource(''))
224
- })
225
- }
226
-
227
197
  private reset() {
228
198
  clearCompiledPages(this.options.paths.appPath)
229
- this.hasCompletedInitialBuild = false
230
199
  this.rebuildingFiles.clear()
231
200
  this.pendingFiles.clear()
232
201
  }
@@ -0,0 +1,158 @@
1
+ import {randomUUID} from 'node:crypto'
2
+ import type {NoParamCallback, PathOrFileDescriptor, WriteFileOptions} from 'node:fs'
3
+ import {mkdir, rename, rm, writeFile} from 'node:fs/promises'
4
+ import path from 'node:path'
5
+ import type {Compilation, Compiler, OutputFileSystem} from 'webpack'
6
+
7
+ export const PLUGIN_NAME = 'HmrOutputPlugin'
8
+
9
+ type WriteFile = OutputFileSystem['writeFile']
10
+
11
+ type WriteFileData = string | NodeJS.ArrayBufferView
12
+
13
+ export interface AtomicOutputPluginOptions {
14
+ /** 这些资产仍由 Webpack 生成,但等其他资产输出完成后才按配置顺序发布。 */
15
+ deferredAssets?: readonly string[]
16
+ }
17
+
18
+ interface DeferredOutput {
19
+ data: WriteFileData
20
+ file: string
21
+ }
22
+
23
+ export class HmrOutputPlugin {
24
+ private readonly deferredAssets: readonly string[]
25
+
26
+ private readonly deferredOutputs = new WeakMap<Compilation, Map<string, DeferredOutput>>()
27
+
28
+ constructor(options: AtomicOutputPluginOptions = {}) {
29
+ this.deferredAssets = options.deferredAssets ?? []
30
+ }
31
+
32
+ apply(compiler: Compiler): void {
33
+ const outputFileSystem = compiler.outputFileSystem
34
+
35
+ if (!outputFileSystem) throw new Error(`[${PLUGIN_NAME}] Webpack outputFileSystem 尚未初始化`)
36
+
37
+ compiler.outputFileSystem = this.createOutputFileSystem(compiler, outputFileSystem)
38
+
39
+ // 尽可能在其他 emit tap 之后读取资产,随后 Webpack 才开始物理输出。
40
+ compiler.hooks.emit.tap({name: PLUGIN_NAME, stage: Number.MAX_SAFE_INTEGER}, compilation => {
41
+ if (compilation.errors.length > 0) return
42
+ this.collectDeferredOutputs(compiler, compilation)
43
+ })
44
+
45
+ // 等待普通资产写入完成后,再按配置顺序发布延迟资产。
46
+ compiler.hooks.afterEmit.tapPromise(PLUGIN_NAME, async compilation => {
47
+ try {
48
+ if (compilation.errors.length > 0) return
49
+ await this.flushDeferredOutputs(compilation)
50
+ } finally {
51
+ this.deferredOutputs.delete(compilation)
52
+ }
53
+ })
54
+ }
55
+
56
+ /**
57
+ * 代理原始 OutputFileSystem。
58
+ * 仅重写 writeFile,其余方法调用原始文件系统实现。
59
+ */
60
+ private createOutputFileSystem(compiler: Compiler, original: OutputFileSystem): OutputFileSystem {
61
+ return new Proxy(original, {
62
+ get: (target, property) => {
63
+ if (property === 'writeFile') return this.createWriteFile(compiler, original)
64
+ const value = Reflect.get(target, property, target)
65
+ return typeof value === 'function' ? value.bind(target) : value
66
+ }
67
+ })
68
+ }
69
+
70
+ /**
71
+ * 创建自定义 writeFile 实现。
72
+ */
73
+ private createWriteFile(compiler: Compiler, original: OutputFileSystem): WriteFile {
74
+ const originalWriteFile = original.writeFile.bind(original)
75
+
76
+ return (file: PathOrFileDescriptor, data: WriteFileData, optionsOrCallback: WriteFileOptions | NoParamCallback, optionalCallback?: NoParamCallback): void => {
77
+
78
+ const callback = (() => {
79
+ if (typeof optionsOrCallback === 'function') return optionsOrCallback
80
+ return optionalCallback
81
+ })()
82
+
83
+ const triggerOriginalWriteFile = () => {
84
+ if (typeof optionsOrCallback === 'function') return originalWriteFile(file, data, optionsOrCallback)
85
+ if (optionalCallback) originalWriteFile(file, data, optionsOrCallback, optionalCallback)
86
+ }
87
+
88
+ if (typeof file !== 'string' || !callback) return triggerOriginalWriteFile()
89
+
90
+ const assetName = this.getAssetName(compiler, file)
91
+
92
+ if (assetName && this.deferredAssets.includes(assetName)) return callback(null)
93
+
94
+ this.writeFileAtomically(file, data).then(() => callback(null)).catch(error => callback(error))
95
+ }
96
+ }
97
+
98
+ private collectDeferredOutputs(compiler: Compiler, compilation: Compilation): void {
99
+ if (this.deferredAssets.length === 0) return
100
+
101
+ const {path: outputPath} = compiler.options.output
102
+
103
+ if (!outputPath) throw new Error(`[${PLUGIN_NAME}] 无法收集延迟资产:output.path 未配置`)
104
+
105
+ const outputs = new Map<string, DeferredOutput>()
106
+
107
+ this.deferredAssets.forEach(assetName => {
108
+ const asset = compilation.getAsset(assetName)
109
+ if (!asset) return
110
+ const data = asset.source.source()
111
+ outputs.set(assetName, {data, file: path.join(outputPath, assetName)})
112
+ })
113
+
114
+ this.deferredOutputs.set(compilation, outputs)
115
+ }
116
+
117
+ private getAssetName(compiler: Compiler, file: string) {
118
+ const {path: outputPath} = compiler.options.output
119
+
120
+ if (!outputPath) return
121
+
122
+ const assetName = path.relative(outputPath, file).replaceAll('\\', '/')
123
+
124
+ if (assetName.startsWith('../') || path.isAbsolute(assetName)) return
125
+
126
+ return assetName
127
+ }
128
+
129
+ private async flushDeferredOutputs(compilation: Compilation) {
130
+ const outputs = this.deferredOutputs.get(compilation)
131
+
132
+ if (!outputs) return
133
+
134
+ return Promise.all(this.deferredAssets.map(assetName => {
135
+ const output = outputs.get(assetName)
136
+ if (!output) return
137
+ return this.writeFileAtomically(output.file, output.data)
138
+ }))
139
+ }
140
+
141
+ /**
142
+ * 通过同目录临时文件和 rename 原子替换目标文件。
143
+ */
144
+ private async writeFileAtomically(targetPath: string, data: WriteFileData): Promise<void> {
145
+ const directory = path.dirname(targetPath)
146
+
147
+ const temporaryPath = path.join(directory, `.${path.basename(targetPath)}.${randomUUID()}.tmp`)
148
+
149
+ await mkdir(directory, {recursive: true})
150
+
151
+ try {
152
+ await writeFile(temporaryPath, data)
153
+ await rename(temporaryPath, targetPath)
154
+ } finally {
155
+ await rm(temporaryPath, {force: true})
156
+ }
157
+ }
158
+ }
@@ -0,0 +1,70 @@
1
+ import type {Compilation, Compiler} from 'webpack'
2
+ import {RawSource} from 'webpack-sources'
3
+
4
+ export interface HmrStylePluginOptions {
5
+ /** Webpack/Taro 生成的全局样式资产。 */
6
+ sourceAsset: string
7
+ /** 固定入口资产;后续编译持续引用 patchAsset。 */
8
+ entryAsset: string
9
+ /** 每轮热编译输出的独立样式资产。 */
10
+ patchAsset: string
11
+ /** 是否将入口固定为对 patchAsset 的导入。 */
12
+ preserveEntry?: boolean
13
+ /** 自定义源样式到 patch 样式的内容转换。 */
14
+ transform?: (source: string, compilation: Compilation) => string
15
+ }
16
+
17
+ const PLUGIN_NAME = 'HmrStylePlugin'
18
+
19
+ /**
20
+ * 将构建器生成的全局样式复制到独立 HMR 资产,并可固定入口文件。
21
+ * 应在构建器完成最终资产变换后运行。
22
+ */
23
+ export class HmrStylePlugin {
24
+ private readonly options: HmrStylePluginOptions
25
+
26
+ private initialBuildDone = false
27
+
28
+ constructor(options: HmrStylePluginOptions) {
29
+ this.options = options
30
+ }
31
+
32
+ apply(compiler: Compiler) {
33
+ compiler.hooks.compilation.tap(PLUGIN_NAME, compilation => {
34
+ const stage = compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_REPORT
35
+ compilation.hooks.processAssets.tap({name: PLUGIN_NAME, stage}, () => this.processAssets(compilation))
36
+ })
37
+
38
+ compiler.hooks.afterEmit.tap(PLUGIN_NAME, compilation => {
39
+ if (compilation.errors.length === 0 && compilation.hash) this.initialBuildDone = true
40
+ })
41
+
42
+ compiler.hooks.watchClose.tap(PLUGIN_NAME, () => {
43
+ this.initialBuildDone = false
44
+ })
45
+ }
46
+
47
+ private processAssets(compilation: Compilation) {
48
+ if (!compilation.hash || compilation.errors.length > 0) return
49
+
50
+ const {sourceAsset, entryAsset, patchAsset, preserveEntry = true, transform} = this.options
51
+ const source = compilation.getAsset(sourceAsset)?.source.source().toString()
52
+
53
+ if (source !== undefined) {
54
+ const patchSource = transform ? transform(source, compilation) : source
55
+ this.updateAsset(compilation, patchAsset, new RawSource(patchSource), {
56
+ hotModuleReplacement: this.initialBuildDone
57
+ })
58
+ }
59
+
60
+ if (preserveEntry) {
61
+ const entry = new RawSource(`@import ${JSON.stringify(`./${patchAsset}`)};\n`)
62
+ this.updateAsset(compilation, entryAsset, entry)
63
+ }
64
+ }
65
+
66
+ private updateAsset(compilation: Compilation, name: string, source: RawSource, info = {}) {
67
+ if (compilation.getAsset(name)) compilation.updateAsset(name, source, info)
68
+ else compilation.emitAsset(name, source, info)
69
+ }
70
+ }
package/src/constants.ts CHANGED
@@ -2,6 +2,8 @@ export const HMR_OUTPUT_PATH = 'hmr'
2
2
 
3
3
  export const HMR_PATCH_ASSET = `${HMR_OUTPUT_PATH}/patch.js`
4
4
 
5
+ export const HMR_PATCH_STYLE_ASSET = `${HMR_OUTPUT_PATH}/patch.wxss`
6
+
5
7
  export const DEFAULT_HMR_PATCH_HISTORY_LIMIT = 20
6
8
 
7
9
  export const DEFAULT_DEBUG_NAMESPACES = 'taro-hmr-compile:*'
package/src/index.ts CHANGED
@@ -1,13 +1,15 @@
1
1
  import type {IPluginContext} from '@tarojs/service'
2
2
  import type {AppConfig} from '@tarojs/taro'
3
- import {HMR_OUTPUT_PATH, DEFAULT_DEBUG_NAMESPACES} from './constants'
3
+ import {HMR_OUTPUT_PATH, HMR_PATCH_ASSET, HMR_PATCH_STYLE_ASSET, DEFAULT_DEBUG_NAMESPACES} from './constants'
4
4
  import {getAppConfig} from './utils'
5
5
  import {HmrCompilerPlugin} from './compile/hmr-compiler-plugin'
6
6
  import {HmrPatchPlugin} from './patch/hmr-patch-plugin'
7
7
  import {HmrServerPlugin} from './server/hmr-server-plugin'
8
- import {emptyDirFile, findAvailablePort} from '@taro-hmr-compile/core/compiler'
8
+ import {findAvailablePort} from '@taro-hmr-compile/core/compiler'
9
+ import {HmrOutputPlugin} from './compile/hmr-output-plugin'
9
10
  import {enableLog} from './log'
10
11
 
12
+ const CUSTOM_WRAPPER = 'custom-wrapper'
11
13
 
12
14
  export interface WebpackHmrCompileOpt {
13
15
  host: string
@@ -19,7 +21,7 @@ export interface WebpackHmrCompileOpt {
19
21
  export default (ctx: IPluginContext, pluginOpts: Partial<WebpackHmrCompileOpt>) => {
20
22
  if (!ctx.runOpts.options?.isWatch) return
21
23
 
22
- const {appPath, sourcePath, outputPath} = ctx.paths
24
+ const {appPath, sourcePath} = ctx.paths
23
25
 
24
26
  const {framework} = ctx.initialConfig
25
27
 
@@ -36,7 +38,10 @@ export default (ctx: IPluginContext, pluginOpts: Partial<WebpackHmrCompileOpt>)
36
38
 
37
39
  if (debugNamespaces) enableLog(debugNamespaces)
38
40
 
39
- ctx.onBuildStart(() => emptyDirFile(outputPath))
41
+ ctx.modifyComponentConfig(({componentConfig}) => {
42
+ if (componentConfig.thirdPartyComponents.has(CUSTOM_WRAPPER)) return
43
+ componentConfig.thirdPartyComponents.set(CUSTOM_WRAPPER, new Set())
44
+ })
40
45
 
41
46
  ctx.modifyRunnerOpts(({opts}) => {
42
47
  opts.output ??= {}
@@ -68,12 +73,17 @@ export default (ctx: IPluginContext, pluginOpts: Partial<WebpackHmrCompileOpt>)
68
73
 
69
74
  const {patchHistoryLimit} = pluginOpts
70
75
 
71
- const [{filename: styleFilename}] = chain.plugin('miniCssExtractPlugin')?.get('args') || []
72
-
73
- chain.plugin('hmr-compiler-plugin').use(HmrCompilerPlugin, [{paths: ctx.paths, appConfig, styleFilename, debugNamespaces}])
74
-
76
+ chain.plugin('hmr-compiler-plugin').use(HmrCompilerPlugin, [{
77
+ paths: ctx.paths,
78
+ appConfig,
79
+ debugNamespaces
80
+ }])
75
81
  chain.plugin('hmr-plugin').use(webpack.HotModuleReplacementPlugin)
76
82
 
83
+ chain.plugin('hmr-output-plugin').use(HmrOutputPlugin, [{
84
+ deferredAssets: [HMR_PATCH_STYLE_ASSET, HMR_PATCH_ASSET, 'app.wxss'],
85
+ }])
86
+
77
87
  chain.plugin('hmr-patch-plugin').use(HmrPatchPlugin, [{patchHistoryLimit}])
78
88
 
79
89
  chain.plugin('hmr-server-plugin').use(HmrServerPlugin, [{host, port}])
@@ -1,6 +1,7 @@
1
1
  import type {Compilation, Compiler} from 'webpack'
2
2
  import {RawSource} from 'webpack-sources'
3
- import {HMR_PATCH_ASSET} from '../constants'
3
+ import path from 'node:path'
4
+ import {HMR_PATCH_ASSET, HMR_PATCH_STYLE_ASSET} from '../constants'
4
5
  import {HmrCompilerPlugin} from '../compile/hmr-compiler-plugin'
5
6
  import {HmrPatchRuntimePlugin} from './hmr-patch-runtime-plugin'
6
7
  import {HmrPatchProcessor, HmrPatchProcessorOptions} from "./hmr-patch-processor";
@@ -10,6 +11,7 @@ const HOT_UPDATE_MANIFEST_SUFFIX = '.hot-update.json'
10
11
  const HOT_UPDATE_SCRIPT_SUFFIX = '.hot-update.js'
11
12
  const STYLE_ASSET_PATTERN = /\.(?:css|wxss|acss|ttss|qss|jxss)(?:\.map)?$/i
12
13
  const TEMPLATE_RUNTIME_ASSET_PATTERN = /(?:^|\/)(?:base\.wxml|utils\.wxs)$/i
14
+ const STYLE_ENTRY_ASSET = 'app.wxss'
13
15
 
14
16
  type HmrPatchPluginOptions = Partial<HmrPatchProcessorOptions>
15
17
 
@@ -25,6 +27,8 @@ export class HmrPatchPlugin {
25
27
 
26
28
  private readonly patchProcessor: HmrPatchProcessor
27
29
 
30
+ private readonly preservedAssets = new Set([HMR_PATCH_ASSET, STYLE_ENTRY_ASSET, HMR_PATCH_STYLE_ASSET])
31
+
28
32
  private readonly emittedAssetSources = new Map<string, string>()
29
33
 
30
34
  constructor(options: HmrPatchPluginOptions) {
@@ -41,7 +45,12 @@ export class HmrPatchPlugin {
41
45
 
42
46
  // 等 Webpack 生成完整的 hot-update assets 后,再统一转换成固定的 patch.js。
43
47
  const stage = compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_REPORT
44
- compilation.hooks.processAssets.tap({name: PLUGIN_NAME, stage}, () => this.processAssets(compilation))
48
+ compilation.hooks.processAssets.tap({name: PLUGIN_NAME, stage}, () => {
49
+ if (compilation.errors.length > 0 || !compilation.hash) return
50
+ this.processStyleAssets(compilation)
51
+ this.processAssets(compilation)
52
+ })
53
+ this.removeHotUpdateAssets(compilation)
45
54
  })
46
55
 
47
56
  compiler.hooks.afterEmit.tap(PLUGIN_NAME, compilation => {
@@ -82,10 +91,40 @@ export class HmrPatchPlugin {
82
91
  this.previousHash = toHash
83
92
  }
84
93
 
94
+ /** 将 Webpack 汇总后的 App 样式放入固定 patch 文件,App 入口只保留稳定引用。 */
95
+ private processStyleAssets(compilation: Compilation) {
96
+ const entryAsset = compilation.getAsset(STYLE_ENTRY_ASSET)
97
+ const source = entryAsset?.source.source().toString()
98
+ if (!source) return
99
+
100
+ const importPath = path.posix.relative(path.posix.dirname(STYLE_ENTRY_ASSET), HMR_PATCH_STYLE_ASSET)
101
+ const patchImport = importPath.startsWith('.') ? importPath : `./${importPath}`
102
+ const alreadyPatched = source.trim() === `@import "${patchImport}";` || source.trim() === `@import '${patchImport}';`
103
+
104
+ if (!alreadyPatched) {
105
+ const patchDirectory = path.posix.dirname(HMR_PATCH_STYLE_ASSET)
106
+ const sourceDirectory = path.posix.dirname(STYLE_ENTRY_ASSET)
107
+ const patchSource = source.replace(/(@import\s+)(["'])([^"']+)\2/g, (match, prefix: string, quote: string, request: string) => {
108
+ if (/^(?:[a-z]+:|\/|#)/i.test(request)) return match
109
+ const resolved = path.posix.normalize(path.posix.join(sourceDirectory, request))
110
+ const relative = path.posix.relative(patchDirectory, resolved)
111
+ return `${prefix}${quote}${relative.startsWith('.') ? relative : `./${relative}`}${quote}`
112
+ })
113
+ this.emitAsset(compilation, HMR_PATCH_STYLE_ASSET, new RawSource(patchSource))
114
+ }
115
+
116
+ this.emitAsset(compilation, STYLE_ENTRY_ASSET, new RawSource(`@import ${JSON.stringify(patchImport)};\n`))
117
+ }
118
+
119
+ private emitAsset(compilation: Compilation, assetName: string, source: RawSource) {
120
+ if (compilation.getAsset(assetName)) compilation.updateAsset(assetName, source)
121
+ else compilation.emitAsset(assetName, source)
122
+ }
123
+
85
124
  /** 热更新转换完成后,保留固定 patch 与发生变化的模板、平台样式资产。 */
86
125
  private removeSupersededAssets(compilation: Compilation) {
87
126
  compilation.getAssets().forEach(asset => {
88
- if (asset.name === HMR_PATCH_ASSET) return
127
+ if (this.preservedAssets.has(asset.name)) return
89
128
  if (!isPassthroughAsset(asset.name)) return compilation.deleteAsset(asset.name)
90
129
 
91
130
  const source = asset.source.source().toString()
@@ -108,4 +147,13 @@ export class HmrPatchPlugin {
108
147
  this.emittedAssetSources.clear()
109
148
  this.patchProcessor.reset()
110
149
  }
150
+ /** 补丁已从 hot-update assets 生成后,在 Webpack 写盘前从本次 compilation 移除它们。 */
151
+ private removeHotUpdateAssets(compilation: Compilation) {
152
+ compilation.getAssets().forEach(asset => {
153
+ if (asset.name.endsWith(HOT_UPDATE_MANIFEST_SUFFIX) || asset.name.endsWith(HOT_UPDATE_SCRIPT_SUFFIX)) {
154
+ compilation.deleteAsset(asset.name)
155
+ }
156
+ })
157
+ }
158
+
111
159
  }
@@ -0,0 +1,15 @@
1
+ import type { IProjectConfig } from '@tarojs/taro/types/compile'
2
+ import type { IComponentConfig } from '@tarojs/taro/types/compile/hooks'
3
+
4
+ declare module '@tarojs/service' {
5
+ interface IPluginContext {
6
+ modifyComponentConfig: (
7
+ callback: (args: {
8
+ componentConfig: IComponentConfig
9
+ config: IProjectConfig
10
+ }) => void,
11
+ ) => void
12
+ }
13
+ }
14
+
15
+ export {}