@taro-hmr-compile/plugin-webpack 0.0.1-alpha.4 → 0.0.1-alpha.6

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 (42) hide show
  1. package/dist/compile/hmr-compiler-loader.d.ts +9 -0
  2. package/dist/compile/hmr-compiler-loader.js +154 -0
  3. package/dist/compile/hmr-compiler-loader.js.map +1 -0
  4. package/dist/compile/hmr-compiler-plugin.d.ts +2 -1
  5. package/dist/compile/hmr-compiler-plugin.js +19 -1
  6. package/dist/compile/hmr-compiler-plugin.js.map +1 -1
  7. package/dist/compile/lazy-compiler-loader.d.ts +17 -0
  8. package/dist/compile/lazy-compiler-loader.js +34 -0
  9. package/dist/compile/lazy-compiler-loader.js.map +1 -0
  10. package/dist/constants.d.ts +1 -0
  11. package/dist/constants.js +2 -1
  12. package/dist/constants.js.map +1 -1
  13. package/dist/index.d.ts +1 -0
  14. package/dist/index.js +32 -14
  15. package/dist/index.js.map +1 -1
  16. package/dist/log.d.ts +3 -0
  17. package/dist/log.js +11 -0
  18. package/dist/log.js.map +1 -0
  19. package/dist/patch/hmr-patch-plugin.js +1 -1
  20. package/dist/patch/hmr-patch-plugin.js.map +1 -1
  21. package/dist/patch/hmr-patch-runtime-plugin.js +29 -58
  22. package/dist/patch/hmr-patch-runtime-plugin.js.map +1 -1
  23. package/dist/server/hmr-server-plugin.js +19 -6
  24. package/dist/server/hmr-server-plugin.js.map +1 -1
  25. package/package.json +8 -7
  26. package/src/compile/hmr-compiler-loader.ts +123 -0
  27. package/src/compile/hmr-compiler-plugin.ts +35 -1
  28. package/src/compile/lazy-compiler-loader.ts +51 -0
  29. package/src/constants.ts +2 -0
  30. package/src/index.ts +24 -12
  31. package/src/log.ts +5 -0
  32. package/src/patch/hmr-patch-plugin.ts +2 -2
  33. package/src/patch/hmr-patch-runtime-plugin.ts +44 -75
  34. package/src/server/hmr-server-plugin.ts +9 -3
  35. package/dist/compile/hmr-compile-loader.d.ts +0 -11
  36. package/dist/compile/hmr-compile-loader.js +0 -52
  37. package/dist/compile/hmr-compile-loader.js.map +0 -1
  38. package/dist/compile/inject-app-hmr-runtime.d.ts +0 -1
  39. package/dist/compile/inject-app-hmr-runtime.js +0 -79
  40. package/dist/compile/inject-app-hmr-runtime.js.map +0 -1
  41. package/src/compile/hmr-compile-loader.ts +0 -72
  42. package/src/compile/inject-app-hmr-runtime.ts +0 -44
@@ -6,80 +6,47 @@ const PLUGIN_NAME = 'HmrPatchRuntimePlugin'
6
6
 
7
7
  const hotRuntimeCode = `
8
8
  var applyQueue = Promise.resolve();
9
- var applySequence = 0;
10
9
 
11
10
  ${webpack.RuntimeGlobals.require}.miniHmr = {
12
- applyPatch: function(patch) {
13
- if (!patch) return Promise.resolve();
11
+ shouldApplyBootstrapPatch: function(patch) {
12
+ if (!patch) return false;
13
+
14
+ return Object.keys(patch.modules).some(function(moduleId) {
15
+ return !Object.prototype.hasOwnProperty.call(${webpack.RuntimeGlobals.moduleFactories}, moduleId);
16
+ });
17
+ },
18
+ applyBootstrapPatch: function(patch) {
19
+ if (!patch) return [];
14
20
 
15
- var applyId = ++applySequence;
16
- var enqueueHash = ${webpack.RuntimeGlobals.getFullHash}();
17
21
  // 微信要求 Page() 在页面脚本求值期间同步注册。bootstrap 只补齐缺失工厂,
18
22
  // 不会覆盖现有模块;必须在 Page Chunk startup 继续执行前同步完成。
19
- if (patch.type === 'bootstrap') {
20
- var installedModules = [];
21
- Object.keys(patch.modules).forEach(function(moduleId) {
22
- if (!Object.prototype.hasOwnProperty.call(${webpack.RuntimeGlobals.moduleFactories}, moduleId)) {
23
- ${webpack.RuntimeGlobals.moduleFactories}[moduleId] = patch.modules[moduleId];
24
- installedModules.push(moduleId);
25
- }
26
- });
27
- console.log('[taro-hmr-compile] bootstrap patch installed', {
28
- applyId: applyId,
29
- installedModules: installedModules
30
- });
31
- return Promise.resolve(installedModules);
32
- }
33
-
34
- console.log('[taro-hmr-compile] patch enqueued', {
35
- applyId: applyId,
36
- type: patch.type,
37
- runtimeHash: enqueueHash,
38
- fromHash: patch.fromHash,
39
- toHash: patch.toHash
23
+ var installedModules = [];
24
+ Object.keys(patch.modules).forEach(function(moduleId) {
25
+ if (!Object.prototype.hasOwnProperty.call(${webpack.RuntimeGlobals.moduleFactories}, moduleId)) {
26
+ ${webpack.RuntimeGlobals.moduleFactories}[moduleId] = patch.modules[moduleId];
27
+ installedModules.push(moduleId);
28
+ }
40
29
  });
30
+ return installedModules;
31
+ },
32
+ applyUpdatePatch: function(patch) {
33
+ if (!patch) return Promise.resolve();
34
+
35
+ globalThis.log('apply update patch %O', patch);
41
36
 
42
37
  var task = applyQueue.then(function() {
43
38
  var runtimeHash = ${webpack.RuntimeGlobals.getFullHash}();
44
- console.log('[taro-hmr-compile] patch dequeued', {
45
- applyId: applyId,
46
- runtimeHash: runtimeHash,
47
- fromHash: patch.fromHash,
48
- toHash: patch.toHash,
49
- isStaleBaseline: runtimeHash !== patch.fromHash
50
- });
51
-
52
- if (runtimeHash === patch.toHash) {
53
- console.log('[taro-hmr-compile] patch skipped at target hash', {
54
- applyId: applyId,
55
- runtimeHash: runtimeHash
56
- });
57
- return;
58
- }
39
+
40
+ if (runtimeHash === patch.toHash) return;
59
41
 
60
42
  currentUpdateApplyHandlers = [];
61
43
 
62
- ${webpack.RuntimeGlobals.require}.miniHmr.preparePatch(
63
- patch,
64
- currentUpdateApplyHandlers
65
- );
44
+ ${webpack.RuntimeGlobals.require}.miniHmr.preparePatch(patch, currentUpdateApplyHandlers);
66
45
 
67
46
  return setStatus('ready')
68
- .then(function() {
69
- return hotApply();
70
- })
47
+ .then(function() { return hotApply(); })
71
48
  .then(function(updatedModules) {
72
- ${webpack.RuntimeGlobals.getFullHash} = function() {
73
- return patch.toHash;
74
- };
75
-
76
- console.log('[taro-hmr-compile] patch applied', {
77
- applyId: applyId,
78
- fromHash: patch.fromHash,
79
- toHash: patch.toHash,
80
- updatedModules: updatedModules
81
- });
82
-
49
+ ${webpack.RuntimeGlobals.getFullHash} = function() { return patch.toHash; };
83
50
  return updatedModules;
84
51
  });
85
52
  });
@@ -123,27 +90,29 @@ export class HmrPatchRuntimePlugin {
123
90
  compiler.hooks.thisCompilation.tap(
124
91
  PLUGIN_NAME,
125
92
  compilation => {
126
- compilation.hooks.runtimeModule.tap(
127
- PLUGIN_NAME,
128
- runtimeModule => {
129
- const injectedCode = {
130
- HotModuleReplacementRuntimeModule: hotRuntimeCode,
131
- JsonpChunkLoadingRuntimeModule: chunkLoadingRuntimeCode,
132
- }[runtimeModule.constructor.name]
93
+ compilation.hooks.additionalTreeRuntimeRequirements.tap(PLUGIN_NAME, (_chunk, runtimeRequirements) => {
94
+ runtimeRequirements.add(webpack.RuntimeGlobals.require)
95
+ runtimeRequirements.add(webpack.RuntimeGlobals.getFullHash)
96
+ })
97
+
98
+ compilation.hooks.runtimeModule.tap(PLUGIN_NAME, runtimeModule => {
99
+ const injectedCode = {
100
+ HotModuleReplacementRuntimeModule: hotRuntimeCode,
101
+ JsonpChunkLoadingRuntimeModule: chunkLoadingRuntimeCode,
102
+ }[runtimeModule.constructor.name]
133
103
 
134
- if (!injectedCode) return
104
+ if (!injectedCode) return
135
105
 
136
- const generate = runtimeModule.generate.bind(runtimeModule)
106
+ const generate = runtimeModule.generate.bind(runtimeModule)
137
107
 
138
- runtimeModule.generate = () => {
139
- const source = generate()
108
+ runtimeModule.generate = () => {
109
+ const source = generate()
140
110
 
141
- if (!source) return source
111
+ if (!source) return source
142
112
 
143
- return injectRuntime(source, injectedCode)
144
- }
145
- },
146
- )
113
+ return injectRuntime(source, injectedCode)
114
+ }
115
+ })
147
116
  },
148
117
  )
149
118
  }
@@ -1,6 +1,9 @@
1
1
  import {HmrCompileServer} from '@taro-hmr-compile/core/compiler'
2
2
  import type {Compiler} from 'webpack'
3
3
  import {HmrCompilerPlugin} from '../compile/hmr-compiler-plugin'
4
+ import {log} from "../log";
5
+
6
+ const serverLog = log.extend('HmrServerPlugin')
4
7
 
5
8
  const PLUGIN_NAME = 'HmrServerPlugin'
6
9
 
@@ -19,15 +22,18 @@ export class HmrServerPlugin extends HmrCompileServer {
19
22
  apply(compiler: Compiler) {
20
23
  this.compiler = compiler
21
24
 
22
- compiler.hooks.afterEmit.tap(PLUGIN_NAME, compilation => {
23
- const isSuccessful = compilation.errors.length === 0 && Boolean(compilation.hash)
24
- if (isSuccessful && !this.isServerRunning) this.start(this.options.port ?? 8080, this.options.host)
25
+ compiler.hooks.beforeCompile.tapPromise(PLUGIN_NAME, async () => {
26
+ if (this.isServerRunning) return
27
+ const {port = 8080, host} = this.options
28
+ serverLog('start server %O', {port, host})
29
+ await this.start(port, host)
25
30
  })
26
31
 
27
32
  compiler.hooks.watchClose.tap(PLUGIN_NAME, () => this.stop())
28
33
  }
29
34
 
30
35
  override compile(page: string) {
36
+ serverLog('receive compile %s', page)
31
37
  if (!this.compiler) throw new Error('[taro-hmr-compile] Compiler 尚未初始化')
32
38
  HmrCompilerPlugin.getCompilerHooks(this.compiler).compileRequested.call(page)
33
39
  }
@@ -1,11 +0,0 @@
1
- import type { LoaderDefinitionFunction } from 'webpack';
2
- import type { AppConfig } from "@tarojs/taro";
3
- interface LoaderOptions {
4
- appPath: string;
5
- sourcePath: string;
6
- appConfig: AppConfig;
7
- framework: 'react';
8
- compileUrl: string;
9
- }
10
- declare const hmrCompileLoader: LoaderDefinitionFunction<LoaderOptions>;
11
- export default hmrCompileLoader;
@@ -1,52 +0,0 @@
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
- const path_1 = __importDefault(require("path"));
7
- const utils_1 = require("../utils");
8
- const compile_state_1 = require("./compile-state");
9
- const inject_app_hmr_runtime_1 = require("./inject-app-hmr-runtime");
10
- const createReactShell = (opt) => {
11
- const { page, compileUrl } = opt;
12
- return `
13
- import Taro from '@tarojs/taro'
14
- import { Text, View } from '@tarojs/components'
15
- import { useEffect } from 'react'
16
- const PageShell = () => {
17
- useEffect(() => {
18
- const data = { page: '${page}' }
19
- const url = '${compileUrl}'
20
- Taro.request({ url, method: 'POST', data }).catch(error => console.error('[taro-hmr-compile] 页面编译请求失败', error))
21
- }, [])
22
-
23
- return (
24
- <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)' }}>
25
- <Text style={{ display: 'block', color: '#ff5555', fontFamily: 'monospace', fontSize: '20px', fontWeight: 'bold' }}>HMR PageShell</Text>
26
- <Text style={{ display: 'block', marginTop: '12px', color: '#fff', fontFamily: 'monospace', lineHeight: 1.6 }}>Waiting for page patch...</Text>
27
- <Text style={{ display: 'block', marginTop: '6px', color: '#b3b3b3', fontFamily: 'monospace', lineHeight: 1.6, wordBreak: 'break-all' }}>${page}</Text>
28
- </View>
29
- )
30
- }
31
- export default PageShell
32
- `;
33
- };
34
- const createShell = (opt) => {
35
- if (opt.framework === 'react')
36
- return createReactShell(opt);
37
- throw new Error(`unsupported framework: ${opt.framework}`);
38
- };
39
- const hmrCompileLoader = function (source) {
40
- const { appPath, framework, appConfig, sourcePath, compileUrl } = this.getOptions();
41
- const { dir: resourceDir, name: resourceName } = path_1.default.parse(path_1.default.relative(sourcePath, this.resourcePath));
42
- const resourcePath = path_1.default.join(resourceDir, resourceName);
43
- const isPageEntry = (0, utils_1.getAllPages)(appConfig).includes(resourcePath);
44
- const isAppEntry = resourcePath === 'app';
45
- if (isAppEntry)
46
- return (0, inject_app_hmr_runtime_1.injectAppHmrRuntime)(source);
47
- if (!isPageEntry || (0, compile_state_1.isPageCompiled)(appPath, resourcePath))
48
- return source;
49
- return createShell({ page: resourcePath, framework, compileUrl });
50
- };
51
- exports.default = hmrCompileLoader;
52
- //# sourceMappingURL=hmr-compile-loader.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hmr-compile-loader.js","sourceRoot":"","sources":["../../src/compile/hmr-compile-loader.ts"],"names":[],"mappings":";;;;;AACA,gDAAwB;AACxB,oCAAoC;AACpC,mDAA8C;AAE9C,qEAA4D;AAS5D,MAAM,gBAAgB,GAAG,CAAC,GAAmB,EAAE,EAAE;IAC7C,MAAM,EAAC,IAAI,EAAE,UAAU,EAAC,GAAG,GAAG,CAAA;IAC9B,OAAO;;;;;;gCAMqB,IAAI;uBACb,UAAU;;;;;;;;qJAQoH,IAAI;;;;;KAKpJ,CAAA;AACL,CAAC,CAAA;AAED,MAAM,WAAW,GAAG,CAAC,GAAmB,EAAE,EAAE;IACxC,IAAI,GAAG,CAAC,SAAS,KAAK,OAAO;QAAE,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAA;IAC3D,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,CAAC,SAAS,EAAE,CAAC,CAAA;AAC9D,CAAC,CAAA;AAWD,MAAM,gBAAgB,GAA4C,UAAU,MAAM;IAC9E,MAAM,EAAC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAC,GAAG,IAAI,CAAC,UAAU,EAAE,CAAA;IAEjF,MAAM,EAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,YAAY,EAAC,GAAG,cAAI,CAAC,KAAK,CAAC,cAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAA;IAEvG,MAAM,YAAY,GAAG,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,CAAA;IAEzD,MAAM,WAAW,GAAG,IAAA,mBAAW,EAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAA;IAEjE,MAAM,UAAU,GAAG,YAAY,KAAK,KAAK,CAAA;IAEzC,IAAI,UAAU;QAAE,OAAO,IAAA,4CAAmB,EAAC,MAAM,CAAC,CAAA;IAElD,IAAI,CAAC,WAAW,IAAI,IAAA,8BAAc,EAAC,OAAO,EAAE,YAAY,CAAC;QAAE,OAAO,MAAM,CAAA;IAExE,OAAO,WAAW,CAAC,EAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAC,CAAC,CAAA;AACnE,CAAC,CAAA;AAED,kBAAe,gBAAgB,CAAA"}
@@ -1 +0,0 @@
1
- export declare const injectAppHmrRuntime: (source: string) => string;
@@ -1,79 +0,0 @@
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.injectAppHmrRuntime = void 0;
40
- const template_1 = __importDefault(require("@babel/template"));
41
- const traverse_1 = __importDefault(require("@babel/traverse"));
42
- const generator_1 = __importDefault(require("@babel/generator"));
43
- const parser = __importStar(require("@babel/parser"));
44
- const webpack_1 = __importDefault(require("webpack"));
45
- const injectAppHmrRuntime = (source) => {
46
- const ast = parser.parse(source, { sourceType: 'module', plugins: ['typescript', 'jsx'] });
47
- const buildHmrCode = template_1.default.statements(`
48
- import { mergePatches, injectHmrLifecycle } from '@taro-hmr-compile/core/runtime'
49
- injectHmrLifecycle()
50
- globalThis.miniHmrApplyPatch = (patches)=>{
51
- const bootstrapPatch = patches.find(patch => patch.type === 'bootstrap')
52
- return __webpack_require__.miniHmr.applyPatch(bootstrapPatch).then(() => {
53
- const updatePatch = mergePatches(${webpack_1.default.RuntimeGlobals.getFullHash}(), patches)
54
- return __webpack_require__.miniHmr.applyPatch(updatePatch)
55
- }).catch(error => {
56
- console.error('[taro-hmr-compile] patch apply failed', error)
57
- })
58
- };
59
- `, { placeholderPattern: false });
60
- (0, traverse_1.default)(ast, {
61
- Program(path) {
62
- const body = path.get('body');
63
- const hasInjected = body.some(item => {
64
- return item.isImportDeclaration() && item.node.source.value === '@taro-hmr-compile/core/runtime';
65
- });
66
- if (hasInjected)
67
- return;
68
- const nodes = buildHmrCode();
69
- const lastImport = [...body].reverse().find(item => item.isImportDeclaration());
70
- if (lastImport)
71
- lastImport.insertAfter(nodes);
72
- if (!lastImport)
73
- path.unshiftContainer('body', nodes);
74
- }
75
- });
76
- return (0, generator_1.default)(ast).code;
77
- };
78
- exports.injectAppHmrRuntime = injectAppHmrRuntime;
79
- //# sourceMappingURL=inject-app-hmr-runtime.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"inject-app-hmr-runtime.js","sourceRoot":"","sources":["../../src/compile/inject-app-hmr-runtime.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+DAAsC;AACtC,+DAAsC;AACtC,iEAAwC;AACxC,sDAAuC;AACvC,sDAA8B;AAEvB,MAAM,mBAAmB,GAAG,CAAC,MAAc,EAAE,EAAE;IAClD,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,EAAC,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,YAAY,EAAE,KAAK,CAAC,EAAC,CAAC,CAAA;IAExF,MAAM,YAAY,GAAG,kBAAQ,CAAC,UAAU,CAAC;;;;;;6CAMA,iBAAO,CAAC,cAAc,CAAC,WAAW;;;;;;KAM1E,EAAE,EAAC,kBAAkB,EAAE,KAAK,EAAC,CAAC,CAAA;IAE/B,IAAA,kBAAQ,EAAC,GAAG,EAAE;QACV,OAAO,CAAC,IAAI;YACR,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;YAE7B,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;gBACjC,OAAO,IAAI,CAAC,mBAAmB,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,gCAAgC,CAAA;YACpG,CAAC,CAAC,CAAA;YAEF,IAAI,WAAW;gBAAE,OAAM;YAEvB,MAAM,KAAK,GAAG,YAAY,EAAE,CAAA;YAE5B,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAA;YAE/E,IAAI,UAAU;gBAAE,UAAU,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;YAE7C,IAAI,CAAC,UAAU;gBAAE,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;QACzD,CAAC;KACJ,CAAC,CAAA;IACF,OAAO,IAAA,mBAAS,EAAC,GAAG,CAAC,CAAC,IAAI,CAAA;AAC9B,CAAC,CAAA;AArCY,QAAA,mBAAmB,uBAqC/B"}
@@ -1,72 +0,0 @@
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
@@ -1,44 +0,0 @@
1
- import template from '@babel/template'
2
- import traverse from '@babel/traverse'
3
- import generator from '@babel/generator'
4
- import * as parser from '@babel/parser'
5
- import webpack from "webpack";
6
-
7
- export const injectAppHmrRuntime = (source: string) => {
8
- const ast = parser.parse(source, {sourceType: 'module', plugins: ['typescript', 'jsx']})
9
-
10
- const buildHmrCode = template.statements(`
11
- import { mergePatches, injectHmrLifecycle } from '@taro-hmr-compile/core/runtime'
12
- injectHmrLifecycle()
13
- globalThis.miniHmrApplyPatch = (patches)=>{
14
- const bootstrapPatch = patches.find(patch => patch.type === 'bootstrap')
15
- return __webpack_require__.miniHmr.applyPatch(bootstrapPatch).then(() => {
16
- const updatePatch = mergePatches(${webpack.RuntimeGlobals.getFullHash}(), patches)
17
- return __webpack_require__.miniHmr.applyPatch(updatePatch)
18
- }).catch(error => {
19
- console.error('[taro-hmr-compile] patch apply failed', error)
20
- })
21
- };
22
- `, {placeholderPattern: false})
23
-
24
- traverse(ast, {
25
- Program(path) {
26
- const body = path.get('body')
27
-
28
- const hasInjected = body.some(item => {
29
- return item.isImportDeclaration() && item.node.source.value === '@taro-hmr-compile/core/runtime'
30
- })
31
-
32
- if (hasInjected) return
33
-
34
- const nodes = buildHmrCode()
35
-
36
- const lastImport = [...body].reverse().find(item => item.isImportDeclaration())
37
-
38
- if (lastImport) lastImport.insertAfter(nodes)
39
-
40
- if (!lastImport) path.unshiftContainer('body', nodes)
41
- }
42
- })
43
- return generator(ast).code
44
- }