@taro-hmr-compile/plugin-webpack 0.0.1-alpha.5 → 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.
- package/dist/compile/hmr-compiler-loader.d.ts +9 -0
- package/dist/compile/hmr-compiler-loader.js +154 -0
- package/dist/compile/hmr-compiler-loader.js.map +1 -0
- package/dist/compile/hmr-compiler-plugin.d.ts +2 -1
- package/dist/compile/hmr-compiler-plugin.js +19 -1
- package/dist/compile/hmr-compiler-plugin.js.map +1 -1
- package/dist/compile/lazy-compiler-loader.d.ts +17 -0
- package/dist/compile/lazy-compiler-loader.js +34 -0
- package/dist/compile/lazy-compiler-loader.js.map +1 -0
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +2 -1
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +32 -14
- package/dist/index.js.map +1 -1
- package/dist/log.d.ts +3 -0
- package/dist/log.js +11 -0
- package/dist/log.js.map +1 -0
- package/dist/patch/hmr-patch-plugin.js +1 -1
- package/dist/patch/hmr-patch-plugin.js.map +1 -1
- package/dist/patch/hmr-patch-runtime-plugin.js +29 -58
- package/dist/patch/hmr-patch-runtime-plugin.js.map +1 -1
- package/dist/server/hmr-server-plugin.js +19 -6
- package/dist/server/hmr-server-plugin.js.map +1 -1
- package/package.json +8 -6
- package/src/compile/hmr-compiler-loader.ts +123 -0
- package/src/compile/hmr-compiler-plugin.ts +35 -1
- package/src/compile/lazy-compiler-loader.ts +51 -0
- package/src/constants.ts +2 -0
- package/src/index.ts +24 -12
- package/src/log.ts +5 -0
- package/src/patch/hmr-patch-plugin.ts +2 -2
- package/src/patch/hmr-patch-runtime-plugin.ts +44 -75
- package/src/server/hmr-server-plugin.ts +9 -3
- package/dist/compile/hmr-compile-loader.d.ts +0 -11
- package/dist/compile/hmr-compile-loader.js +0 -52
- package/dist/compile/hmr-compile-loader.js.map +0 -1
- package/dist/compile/inject-app-hmr-runtime.d.ts +0 -1
- package/dist/compile/inject-app-hmr-runtime.js +0 -79
- package/dist/compile/inject-app-hmr-runtime.js.map +0 -1
- package/src/compile/hmr-compile-loader.ts +0 -72
- 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
|
-
|
|
13
|
-
if (!patch) return
|
|
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
|
-
|
|
20
|
-
|
|
21
|
-
Object.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
45
|
-
|
|
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.
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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
|
-
|
|
104
|
+
if (!injectedCode) return
|
|
135
105
|
|
|
136
|
-
|
|
106
|
+
const generate = runtimeModule.generate.bind(runtimeModule)
|
|
137
107
|
|
|
138
|
-
|
|
139
|
-
|
|
108
|
+
runtimeModule.generate = () => {
|
|
109
|
+
const source = generate()
|
|
140
110
|
|
|
141
|
-
|
|
111
|
+
if (!source) return source
|
|
142
112
|
|
|
143
|
-
|
|
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.
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
}
|