glass-easel-miniprogram-webpack-plugin 0.2.1 → 0.3.0
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/.eslintignore +6 -0
- package/README.md +14 -0
- package/{helpers.js → helpers.ts} +1 -1
- package/index.js +506 -389
- package/index.ts +565 -0
- package/package.json +7 -6
- package/tsconfig.json +9 -0
- package/wxml_loader.js +8 -2
package/index.js
CHANGED
|
@@ -1,409 +1,526 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
20
|
+
if (mod && mod.__esModule) return mod;
|
|
21
|
+
var result = {};
|
|
22
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
23
|
+
__setModuleDefault(result, mod);
|
|
24
|
+
return result;
|
|
25
|
+
};
|
|
26
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
27
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
28
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
29
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
30
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
31
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
32
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.GlassEaselMiniprogramWebpackPlugin = exports.GlassEaselMiniprogramWxssLoader = exports.GlassEaselMiniprogramWxmlLoader = void 0;
|
|
37
|
+
const node_fs_1 = require("node:fs");
|
|
38
|
+
const path = __importStar(require("node:path"));
|
|
39
|
+
const webpack_1 = require("webpack");
|
|
40
|
+
const glass_easel_template_compiler_1 = require("glass-easel-template-compiler");
|
|
41
|
+
const helpers_1 = require("./helpers");
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
43
|
+
const chokidar = require('chokidar');
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
45
|
+
const { RawSource } = require('webpack-sources');
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
47
|
+
const VirtualModulesPlugin = require('webpack-virtual-modules');
|
|
48
|
+
exports.GlassEaselMiniprogramWxmlLoader = path.join(__dirname, 'wxml_loader.js');
|
|
49
|
+
exports.GlassEaselMiniprogramWxssLoader = path.join(__dirname, 'wxss_loader.js');
|
|
50
|
+
const PLUGIN_NAME = 'GlassEaselMiniprogramWebpackPlugin';
|
|
51
|
+
const CACHE_ETAG = 1;
|
|
52
|
+
const readCache = (compiler, key) => new Promise((resolve) => {
|
|
53
|
+
const cacheKey = `${PLUGIN_NAME}|${key}`;
|
|
54
|
+
compiler.cache.get(cacheKey, CACHE_ETAG, (err, cache) => {
|
|
55
|
+
if (!err && cache !== undefined) {
|
|
56
|
+
resolve(cache);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
resolve(undefined);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
const writeCache = (compiler, key, value) => new Promise((resolve) => {
|
|
64
|
+
const cacheKey = `${PLUGIN_NAME}|${key}`;
|
|
65
|
+
compiler.cache.store(cacheKey, CACHE_ETAG, value, (_err) => {
|
|
66
|
+
resolve();
|
|
67
|
+
});
|
|
68
|
+
});
|
|
16
69
|
class StyleSheetManager {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
add(compPath, srcPath) {
|
|
24
|
-
let scopeNameNum = this.scopeNameInc
|
|
25
|
-
this.scopeNameInc += 1
|
|
26
|
-
let scopeName = ''
|
|
27
|
-
do {
|
|
28
|
-
const n = scopeNameNum % 52
|
|
29
|
-
let c
|
|
30
|
-
if (n >= 26) {
|
|
31
|
-
c = String.fromCharCode(n - 26 + 97)
|
|
32
|
-
} else {
|
|
33
|
-
c = String.fromCharCode(n + 65)
|
|
34
|
-
}
|
|
35
|
-
scopeName += c
|
|
36
|
-
scopeNameNum = Math.floor(scopeNameNum / 52)
|
|
37
|
-
} while (scopeNameNum > 0)
|
|
38
|
-
this.map[compPath] = {
|
|
39
|
-
srcPath,
|
|
40
|
-
scopeName,
|
|
70
|
+
constructor(disableClassPrefix) {
|
|
71
|
+
this.map = Object.create(null);
|
|
72
|
+
this.enableStyleScope = Object.create(null);
|
|
73
|
+
this.scopeNameInc = 0;
|
|
74
|
+
this.disableClassPrefix = disableClassPrefix;
|
|
41
75
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
76
|
+
add(compPath, srcPath) {
|
|
77
|
+
let scopeNameNum = this.scopeNameInc;
|
|
78
|
+
this.scopeNameInc += 1;
|
|
79
|
+
let scopeName = '';
|
|
80
|
+
do {
|
|
81
|
+
const n = scopeNameNum % 52;
|
|
82
|
+
let c;
|
|
83
|
+
if (n >= 26) {
|
|
84
|
+
c = String.fromCharCode(n - 26 + 97);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
c = String.fromCharCode(n + 65);
|
|
88
|
+
}
|
|
89
|
+
scopeName += c;
|
|
90
|
+
scopeNameNum = Math.floor(scopeNameNum / 52);
|
|
91
|
+
} while (scopeNameNum > 0);
|
|
92
|
+
this.map[compPath] = {
|
|
93
|
+
srcPath,
|
|
94
|
+
scopeName,
|
|
95
|
+
};
|
|
54
96
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const s = `backend.registerStyleSheetContent('${escapeJsString(
|
|
61
|
-
compPath,
|
|
62
|
-
)}', require('${escapeJsString(srcPath)}'));`
|
|
63
|
-
return s
|
|
64
|
-
})
|
|
65
|
-
return `
|
|
66
|
-
function (backend) { ${arr.join('')} }
|
|
67
|
-
`
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
class GlassEaselMiniprogramWebpackPlugin {
|
|
72
|
-
constructor(options) {
|
|
73
|
-
this.path = options.path || './src'
|
|
74
|
-
this.resourceFilePattern = options.resourceFilePattern || /\.(jpg|jpeg|png|gif|html)$/
|
|
75
|
-
this.defaultEntry = 'pages/index/index'
|
|
76
|
-
this.virtualModules = new VirtualModulesPlugin()
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
apply(compiler) {
|
|
80
|
-
// search paths
|
|
81
|
-
const codeRoot = path.resolve(this.path)
|
|
82
|
-
const params = {
|
|
83
|
-
globalStaticConfig: {},
|
|
84
|
-
compInfoMap: Object.create(null),
|
|
85
|
-
resPathMap: Object.create(null),
|
|
86
|
-
appEntry: null,
|
|
87
|
-
tmplGroup: new TmplGroup(),
|
|
88
|
-
styleSheetManager: new StyleSheetManager(),
|
|
97
|
+
setStyleIsolation(compPath, styleIsolation, isComponent) {
|
|
98
|
+
const enabled = styleIsolation
|
|
99
|
+
? styleIsolation !== 'shared' && styleIsolation !== 'page-shared'
|
|
100
|
+
: isComponent;
|
|
101
|
+
this.enableStyleScope[compPath] = enabled;
|
|
89
102
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const json = await fs.readFile(path.join(codeRoot, `${relPath}.json`), { encoding: 'utf8' })
|
|
97
|
-
const parsed = JSON.parse(json)
|
|
98
|
-
if (parsed && (parsed.component === true || typeof parsed.usingComponents === 'object')) {
|
|
99
|
-
staticConfig = parsed
|
|
103
|
+
getScopeName(compPath) {
|
|
104
|
+
var _a;
|
|
105
|
+
if (this.disableClassPrefix)
|
|
106
|
+
return undefined;
|
|
107
|
+
if (this.enableStyleScope[compPath]) {
|
|
108
|
+
return (_a = this.map[compPath]) === null || _a === void 0 ? void 0 : _a.scopeName;
|
|
100
109
|
}
|
|
101
|
-
|
|
102
|
-
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
toCodeString() {
|
|
113
|
+
const arr = Object.entries(this.map).map(([compPath, { srcPath }]) => {
|
|
114
|
+
const s = `backend.registerStyleSheetContent('${(0, helpers_1.escapeJsString)(compPath)}', require('${(0, helpers_1.escapeJsString)(srcPath)}'));`;
|
|
115
|
+
return s;
|
|
116
|
+
});
|
|
117
|
+
return `
|
|
118
|
+
function (backend) {
|
|
119
|
+
backend.registerStyleSheetContent('app', require('./app.wxss'))
|
|
120
|
+
${arr.join('')}
|
|
103
121
|
}
|
|
104
|
-
|
|
122
|
+
`;
|
|
105
123
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
124
|
+
}
|
|
125
|
+
class GlassEaselMiniprogramWebpackPlugin {
|
|
126
|
+
constructor(options) {
|
|
127
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
128
|
+
this.virtualModules = new VirtualModulesPlugin();
|
|
129
|
+
this.path = options.path || './src';
|
|
130
|
+
this.resourceFilePattern = options.resourceFilePattern || /\.(jpg|jpeg|png|gif)$/;
|
|
131
|
+
this.defaultEntry = options.defaultEntry || 'pages/index/index';
|
|
132
|
+
this.customBootstrap = options.customBootstrap || false;
|
|
133
|
+
this.disableClassPrefix = options.disableClassPrefix || false;
|
|
112
134
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
}
|
|
139
|
-
} catch (e) {
|
|
140
|
-
params.globalStaticConfig = {}
|
|
141
|
-
}
|
|
142
|
-
return
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// for app.ts or app.js, load it first
|
|
146
|
-
if (relPath === 'app.ts' || relPath === 'app.js') {
|
|
147
|
-
params.appEntry = relPath
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// find component by json files
|
|
151
|
-
const extName = path.extname(relPath)
|
|
152
|
-
if (extName === '.json') {
|
|
153
|
-
const staticConfig = await isCompPath(relPath.slice(0, -extName.length))
|
|
154
|
-
if (staticConfig) {
|
|
155
|
-
const compPath = relPath.slice(0, -5)
|
|
135
|
+
apply(compiler) {
|
|
136
|
+
const codeRoot = path.resolve(this.path);
|
|
137
|
+
const compInfoMap = Object.create(null);
|
|
138
|
+
const resPathMap = Object.create(null);
|
|
139
|
+
const wxmlContentMap = Object.create(null);
|
|
140
|
+
let globalStaticConfig = {};
|
|
141
|
+
let appEntry = null;
|
|
142
|
+
const depsTmplGroup = new glass_easel_template_compiler_1.TmplGroup();
|
|
143
|
+
const styleSheetManager = new StyleSheetManager(this.disableClassPrefix);
|
|
144
|
+
// cleanup wasm modules
|
|
145
|
+
compiler.hooks.shutdown.tap(PLUGIN_NAME, () => {
|
|
146
|
+
depsTmplGroup.free();
|
|
147
|
+
});
|
|
148
|
+
// determine a file is located in the code root or not, returning relative path if true
|
|
149
|
+
const normalizePath = (absPath) => {
|
|
150
|
+
const p = path.relative(codeRoot, absPath);
|
|
151
|
+
if (p.split(path.sep, 1)[0] === '..')
|
|
152
|
+
return null;
|
|
153
|
+
return p.split(path.sep).join('/');
|
|
154
|
+
};
|
|
155
|
+
// determine a path is a component path or not, returning the json content if true
|
|
156
|
+
const isCompPath = (relPath) => __awaiter(this, void 0, void 0, function* () {
|
|
157
|
+
if (!relPath)
|
|
158
|
+
return null;
|
|
159
|
+
let staticConfig = null;
|
|
156
160
|
try {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
staticConfig,
|
|
161
|
+
const json = yield node_fs_1.promises.readFile(path.join(codeRoot, `${relPath}.json`), { encoding: 'utf8' });
|
|
162
|
+
const parsed = JSON.parse(json);
|
|
163
|
+
if (parsed && (parsed.component === true || typeof parsed.usingComponents === 'object')) {
|
|
164
|
+
staticConfig = parsed;
|
|
162
165
|
}
|
|
163
|
-
params.styleSheetManager.setStyleIsolation(
|
|
164
|
-
compPath,
|
|
165
|
-
staticConfig.styleIsolation,
|
|
166
|
-
!!staticConfig.component,
|
|
167
|
-
)
|
|
168
|
-
return
|
|
169
|
-
}
|
|
170
|
-
} catch (e) {
|
|
171
|
-
/* empty */
|
|
172
166
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
if (jsFileStat.isFile()) {
|
|
176
|
-
params.compInfoMap[compPath] = {
|
|
177
|
-
main: `${compPath}.js`,
|
|
178
|
-
staticConfig,
|
|
179
|
-
}
|
|
180
|
-
return
|
|
181
|
-
}
|
|
182
|
-
} catch (e) {
|
|
183
|
-
/* empty */
|
|
167
|
+
catch (e) {
|
|
168
|
+
/* empty */
|
|
184
169
|
}
|
|
185
|
-
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
if (x.loader === GlassEaselMiniprogramWxssLoader) {
|
|
296
|
-
x.options = {
|
|
297
|
-
classPrefix: params.styleSheetManager.getScopeName(compPath),
|
|
298
|
-
relPath,
|
|
170
|
+
return staticConfig;
|
|
171
|
+
});
|
|
172
|
+
// search for component files
|
|
173
|
+
let codeRootWatching = false;
|
|
174
|
+
const searchCodeRoot = (enableWatch) => __awaiter(this, void 0, void 0, function* () {
|
|
175
|
+
if (codeRootWatching)
|
|
176
|
+
return;
|
|
177
|
+
codeRootWatching = true;
|
|
178
|
+
const handleFile = (relPath) => __awaiter(this, void 0, void 0, function* () {
|
|
179
|
+
// for app.json, spread the global field
|
|
180
|
+
if (relPath === 'app.json') {
|
|
181
|
+
try {
|
|
182
|
+
const json = yield node_fs_1.promises.readFile(path.join(codeRoot, relPath), { encoding: 'utf8' });
|
|
183
|
+
const staticConfig = JSON.parse(json);
|
|
184
|
+
if (staticConfig.usingComponents) {
|
|
185
|
+
globalStaticConfig = {
|
|
186
|
+
usingComponents: staticConfig.usingComponents,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
catch (e) {
|
|
191
|
+
globalStaticConfig = {};
|
|
192
|
+
}
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
// for app.ts or app.js, load it first
|
|
196
|
+
if (relPath === 'app.ts' || relPath === 'app.js') {
|
|
197
|
+
appEntry = relPath;
|
|
198
|
+
}
|
|
199
|
+
// find component by json files
|
|
200
|
+
const extName = path.extname(relPath);
|
|
201
|
+
if (extName === '.json') {
|
|
202
|
+
const staticConfig = yield isCompPath(relPath.slice(0, -extName.length));
|
|
203
|
+
if (staticConfig) {
|
|
204
|
+
const compPath = relPath.slice(0, -extName.length);
|
|
205
|
+
const absPath = path.join(codeRoot, `${compPath}.wxss`);
|
|
206
|
+
let hasWxss = false;
|
|
207
|
+
try {
|
|
208
|
+
hasWxss = (yield node_fs_1.promises.stat(absPath)).isFile();
|
|
209
|
+
}
|
|
210
|
+
catch (e) {
|
|
211
|
+
/* empty */
|
|
212
|
+
}
|
|
213
|
+
try {
|
|
214
|
+
const tsFileStat = yield node_fs_1.promises.stat(path.join(codeRoot, `${compPath}.ts`));
|
|
215
|
+
if (tsFileStat.isFile()) {
|
|
216
|
+
compInfoMap[compPath] = {
|
|
217
|
+
main: `${compPath}.ts`,
|
|
218
|
+
taskConfig: staticConfig.taskConfig,
|
|
219
|
+
hasWxss,
|
|
220
|
+
};
|
|
221
|
+
styleSheetManager.add(compPath, absPath);
|
|
222
|
+
styleSheetManager.setStyleIsolation(compPath, staticConfig.styleIsolation, !!staticConfig.component);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
catch (e) {
|
|
227
|
+
/* empty */
|
|
228
|
+
}
|
|
229
|
+
try {
|
|
230
|
+
const jsFileStat = yield node_fs_1.promises.stat(path.join(codeRoot, `${compPath}.js`));
|
|
231
|
+
if (jsFileStat.isFile()) {
|
|
232
|
+
compInfoMap[compPath] = {
|
|
233
|
+
main: `${compPath}.js`,
|
|
234
|
+
taskConfig: staticConfig.taskConfig,
|
|
235
|
+
hasWxss,
|
|
236
|
+
};
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
catch (e) {
|
|
241
|
+
/* empty */
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
// find wxss file for components
|
|
246
|
+
if (extName === '.wxss') {
|
|
247
|
+
const compPath = relPath.slice(0, -5);
|
|
248
|
+
if (compInfoMap[compPath]) {
|
|
249
|
+
compInfoMap[compPath].hasWxss = true;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
// find resource files
|
|
253
|
+
if (this.resourceFilePattern.test(relPath)) {
|
|
254
|
+
resPathMap[relPath] = true;
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
const removeEntry = (relPath) => {
|
|
258
|
+
delete resPathMap[relPath];
|
|
259
|
+
const extName = path.extname(relPath);
|
|
260
|
+
const compPath = relPath.slice(0, -extName.length);
|
|
261
|
+
if (compInfoMap[compPath]) {
|
|
262
|
+
if (extName === '.json') {
|
|
263
|
+
delete compInfoMap[compPath];
|
|
264
|
+
}
|
|
265
|
+
else if (extName === '.wxss') {
|
|
266
|
+
compInfoMap[compPath].hasWxss = false;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
// await readdirp(codeRoot, handleFile)
|
|
271
|
+
yield new Promise((resolve, reject) => {
|
|
272
|
+
const promises = [];
|
|
273
|
+
/* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call */
|
|
274
|
+
const watcher = chokidar.watch(codeRoot, { ignoreInitial: false });
|
|
275
|
+
watcher
|
|
276
|
+
.on('add', (p) => {
|
|
277
|
+
const normalized = normalizePath(p);
|
|
278
|
+
if (normalized) {
|
|
279
|
+
promises.push(handleFile(normalized));
|
|
299
280
|
}
|
|
300
|
-
}
|
|
301
281
|
})
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
}
|
|
282
|
+
.on('unlink', (p) => {
|
|
283
|
+
const normalized = normalizePath(p);
|
|
284
|
+
if (normalized)
|
|
285
|
+
removeEntry(normalized);
|
|
307
286
|
})
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
287
|
+
.on('ready', () => {
|
|
288
|
+
Promise.all(promises)
|
|
289
|
+
.then(() => {
|
|
290
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
291
|
+
if (!enableWatch)
|
|
292
|
+
return watcher.close();
|
|
293
|
+
return null;
|
|
294
|
+
})
|
|
295
|
+
.then(resolve)
|
|
296
|
+
.catch(reject);
|
|
297
|
+
});
|
|
298
|
+
/* eslint-enable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call */
|
|
299
|
+
});
|
|
300
|
+
});
|
|
301
|
+
// init component list before run
|
|
302
|
+
compiler.hooks.beforeRun.tapPromise(PLUGIN_NAME, () => __awaiter(this, void 0, void 0, function* () {
|
|
303
|
+
yield searchCodeRoot(false);
|
|
304
|
+
}));
|
|
305
|
+
compiler.hooks.watchRun.tapPromise(PLUGIN_NAME, () => __awaiter(this, void 0, void 0, function* () {
|
|
306
|
+
yield searchCodeRoot(true);
|
|
307
|
+
}));
|
|
308
|
+
// rewrite component entry paths
|
|
309
|
+
compiler.resolverFactory.hooks.resolver.for('normal').tap(PLUGIN_NAME, (resolver) => {
|
|
310
|
+
resolver.hooks.result.tap(PLUGIN_NAME, (data) => {
|
|
311
|
+
var _a;
|
|
312
|
+
if (data.path === false)
|
|
313
|
+
return data;
|
|
314
|
+
const absPath = data.path;
|
|
315
|
+
const extName = path.extname(absPath);
|
|
316
|
+
if (extName === '.js' || extName === '.ts') {
|
|
317
|
+
const relPath = normalizePath(absPath);
|
|
318
|
+
if (relPath && compInfoMap[relPath.slice(0, -3)]) {
|
|
319
|
+
const redirected = `${absPath.slice(0, -3)}.glass-easel-component`;
|
|
320
|
+
if (((_a = data.context) === null || _a === void 0 ? void 0 : _a.issuer) !== redirected) {
|
|
321
|
+
data.path = redirected;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
return data;
|
|
326
|
+
});
|
|
327
|
+
});
|
|
328
|
+
// collect virtual files
|
|
329
|
+
const virtualModules = this.virtualModules;
|
|
330
|
+
virtualModules.apply(compiler);
|
|
331
|
+
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
|
|
332
|
+
// add loaders
|
|
333
|
+
webpack_1.NormalModule.getCompilationHooks(compilation).beforeLoaders.tap(PLUGIN_NAME, (loaders, mod) => {
|
|
334
|
+
const absPath = mod.resource;
|
|
335
|
+
const extName = path.extname(absPath);
|
|
336
|
+
if (extName === '.wxml' || extName === '.wxss') {
|
|
337
|
+
const relPath = path.relative(codeRoot, absPath).split(path.sep).join('/');
|
|
338
|
+
const compPath = relPath.slice(0, -extName.length);
|
|
339
|
+
if (extName === '.wxss') {
|
|
340
|
+
loaders.forEach((x) => {
|
|
341
|
+
if (x.loader === exports.GlassEaselMiniprogramWxssLoader) {
|
|
342
|
+
x.options = {
|
|
343
|
+
classPrefix: styleSheetManager.getScopeName(compPath),
|
|
344
|
+
relPath,
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
else if (extName === '.wxml') {
|
|
350
|
+
loaders.forEach((x) => {
|
|
351
|
+
if (x.loader === exports.GlassEaselMiniprogramWxmlLoader) {
|
|
352
|
+
x.options = {
|
|
353
|
+
addTemplate(content) {
|
|
354
|
+
wxmlContentMap[compPath] = content;
|
|
355
|
+
depsTmplGroup.addTmpl(compPath, content);
|
|
356
|
+
const deps = depsTmplGroup
|
|
357
|
+
.getDirectDependencies(compPath)
|
|
358
|
+
.concat(depsTmplGroup.getScriptDependencies(compPath));
|
|
359
|
+
return {
|
|
360
|
+
compPath,
|
|
361
|
+
deps,
|
|
362
|
+
codeRoot,
|
|
363
|
+
};
|
|
364
|
+
},
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
});
|
|
371
|
+
// do some rebuild after all module compilation done
|
|
372
|
+
compilation.hooks.finishModules.tapPromise(PLUGIN_NAME, (modules) => __awaiter(this, void 0, void 0, function* () {
|
|
373
|
+
const tasks = [];
|
|
374
|
+
let indexModule;
|
|
375
|
+
const tmplGroup = new glass_easel_template_compiler_1.TmplGroup();
|
|
376
|
+
// collect compilation results
|
|
377
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
378
|
+
for (const m of modules) {
|
|
379
|
+
if (m.type !== 'javascript/auto')
|
|
380
|
+
continue;
|
|
381
|
+
const module = m;
|
|
382
|
+
if (module.resource === `${codeRoot}/index.js`) {
|
|
383
|
+
indexModule = module;
|
|
384
|
+
continue;
|
|
385
|
+
}
|
|
386
|
+
const absPath = module.resource;
|
|
387
|
+
const extName = path.extname(absPath);
|
|
388
|
+
if (extName === '.wxml') {
|
|
389
|
+
if (module.loaders.some((x) => x.loader === exports.GlassEaselMiniprogramWxmlLoader)) {
|
|
390
|
+
// check wxml results, read cache if needed
|
|
391
|
+
const relPath = path.relative(codeRoot, absPath).split(path.sep).join('/');
|
|
392
|
+
const compPath = relPath.slice(0, -extName.length);
|
|
393
|
+
// eslint-disable-next-line no-loop-func
|
|
394
|
+
tasks.push((() => __awaiter(this, void 0, void 0, function* () {
|
|
395
|
+
let content = wxmlContentMap[compPath];
|
|
396
|
+
if (content) {
|
|
397
|
+
// TODO use compiled content as better cache
|
|
398
|
+
yield writeCache(compiler, relPath, content);
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
401
|
+
const s = yield readCache(compiler, relPath);
|
|
402
|
+
if (s === undefined) {
|
|
403
|
+
throw new Error(`Cannot find WXML compilation result for ${relPath} (webpack cache broken?)`);
|
|
404
|
+
}
|
|
405
|
+
content = s;
|
|
406
|
+
}
|
|
407
|
+
if (typeof content === 'string') {
|
|
408
|
+
tmplGroup.addTmpl(compPath, content);
|
|
409
|
+
}
|
|
410
|
+
}))());
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
// write index module
|
|
415
|
+
yield Promise.all(tasks);
|
|
416
|
+
yield new Promise((resolve) => {
|
|
417
|
+
updateVirtualIndexFile(tmplGroup);
|
|
418
|
+
tmplGroup.free();
|
|
419
|
+
compilation.rebuildModule(indexModule, () => resolve());
|
|
420
|
+
});
|
|
421
|
+
}));
|
|
422
|
+
// add virtual component js file
|
|
423
|
+
const updateComponentJsFile = (compPath) => {
|
|
424
|
+
const compInfo = compInfoMap[compPath];
|
|
425
|
+
const scopeName = styleSheetManager.getScopeName(compPath);
|
|
426
|
+
const scopeNameStr = scopeName === undefined ? undefined : `'${scopeName}'`;
|
|
427
|
+
const jsonSrcPath = path.join(codeRoot, `${compPath}.json`);
|
|
428
|
+
const wxmlSrcPath = path.join(codeRoot, `${compPath}.wxml`);
|
|
429
|
+
const wxssSrcPath = path.join(codeRoot, `${compPath}.wxss`);
|
|
430
|
+
const addStyleSheet = compInfo.hasWxss
|
|
431
|
+
? `
|
|
432
|
+
require('${(0, helpers_1.escapeJsString)(wxssSrcPath)}')
|
|
433
|
+
codeSpace.addStyleSheet(
|
|
434
|
+
'${(0, helpers_1.escapeJsString)(compPath)}',
|
|
435
|
+
'${(0, helpers_1.escapeJsString)(compPath)}',
|
|
436
|
+
${scopeNameStr}
|
|
437
|
+
)
|
|
327
438
|
`
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
index
|
|
439
|
+
: '';
|
|
440
|
+
virtualModules.writeModule(path.join(codeRoot, `${compPath}.glass-easel-component`), `
|
|
441
|
+
var index = require('${(0, helpers_1.escapeJsString)(codeRoot)}/index.js')
|
|
442
|
+
var codeSpace = index.codeSpace
|
|
443
|
+
var staticConfig = require('${(0, helpers_1.escapeJsString)(jsonSrcPath)}')
|
|
444
|
+
staticConfig.usingComponents = Object.assign(
|
|
445
|
+
{},
|
|
446
|
+
index.globalUsingComponents,
|
|
447
|
+
staticConfig.usingComponents
|
|
448
|
+
)
|
|
449
|
+
codeSpace.addComponentStaticConfig('${(0, helpers_1.escapeJsString)(compPath)}', staticConfig)
|
|
450
|
+
codeSpace.addCompiledTemplate('${(0, helpers_1.escapeJsString)(compPath)}', {
|
|
331
451
|
groupList: index.genObjectGroups,
|
|
332
|
-
content: index.genObjectGroups[require(
|
|
333
|
-
'${escapeJsString(codeRoot)}/${escapeJsString(compPath)}.wxml'
|
|
334
|
-
)]
|
|
452
|
+
content: index.genObjectGroups[require('${(0, helpers_1.escapeJsString)(wxmlSrcPath)}')]
|
|
335
453
|
})
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
'
|
|
339
|
-
${scopeNameStr}
|
|
340
|
-
)
|
|
341
|
-
index.codeSpace.globalComponentEnv(index.globalObject, '${escapeJsString(
|
|
342
|
-
compPath,
|
|
343
|
-
)}', () => {
|
|
344
|
-
require('./${escapeJsString(path.basename(compInfo.main))}')
|
|
454
|
+
${addStyleSheet}
|
|
455
|
+
codeSpace.globalComponentEnv(index.globalObject, '${(0, helpers_1.escapeJsString)(compPath)}', () => {
|
|
456
|
+
require('./${(0, helpers_1.escapeJsString)(path.basename(compInfo.main))}')
|
|
345
457
|
})
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
458
|
+
`);
|
|
459
|
+
};
|
|
460
|
+
Object.keys(compInfoMap).forEach((compPath) => updateComponentJsFile(compPath));
|
|
461
|
+
// add virtual index file
|
|
462
|
+
const updateVirtualIndexFile = (tmplGroup) => {
|
|
463
|
+
const entryHeader = `
|
|
464
|
+
var adapter = require('glass-easel-miniprogram-adapter')
|
|
465
|
+
var glassEasel = adapter.glassEasel
|
|
466
|
+
var env = new adapter.MiniProgramEnv()
|
|
467
|
+
exports.env = env
|
|
468
|
+
var codeSpace = env.createCodeSpace('', true)
|
|
469
|
+
codeSpace.addStyleSheet('app', 'app')
|
|
470
|
+
exports.codeSpace = codeSpace
|
|
471
|
+
exports.genObjectGroups = ${tmplGroup ? tmplGroup.getTmplGenObjectGroups() : '{}'}
|
|
472
|
+
exports.globalUsingComponents = ${JSON.stringify(globalStaticConfig.usingComponents)}
|
|
473
|
+
exports.globalObject = (function () {
|
|
474
|
+
if (typeof this !== 'undefined') { return this }
|
|
475
|
+
if (typeof globalThis !== 'undefined') { return globalThis }
|
|
476
|
+
if (typeof self !== 'undefined') { return self }
|
|
477
|
+
if (typeof window !== 'undefined') { return window }
|
|
478
|
+
if (typeof global !== 'undefined') { return global }
|
|
479
|
+
throw new Error('The global object cannot be recognized')
|
|
480
|
+
})()
|
|
481
|
+
`;
|
|
482
|
+
const entryFooter = `
|
|
483
|
+
var initWithBackend = function (backend) {
|
|
484
|
+
var ab = env.associateBackend(backend)
|
|
485
|
+
;(${styleSheetManager.toCodeString()})(ab)
|
|
486
|
+
return ab
|
|
487
|
+
}
|
|
488
|
+
exports.initWithBackend = initWithBackend
|
|
489
|
+
var registerGlobalEventListener = function (backend) {
|
|
490
|
+
backend.onEvent((target, type, detail, options) => {
|
|
491
|
+
glassEasel.triggerEvent(target, type, detail, options)
|
|
492
|
+
})
|
|
493
|
+
}
|
|
494
|
+
exports.registerGlobalEventListener = registerGlobalEventListener
|
|
495
|
+
`;
|
|
496
|
+
const bootstrap = this.customBootstrap
|
|
497
|
+
? ''
|
|
498
|
+
: `
|
|
499
|
+
var backend = new glassEasel.CurrentWindowBackendContext()
|
|
500
|
+
registerGlobalEventListener(backend)
|
|
501
|
+
var ab = initWithBackend(backend)
|
|
502
|
+
var root = ab.createRoot('glass-easel-root', codeSpace, '${(0, helpers_1.escapeJsString)(this.defaultEntry)}')
|
|
503
|
+
var placeholder = document.createElement('span')
|
|
504
|
+
document.body.appendChild(placeholder)
|
|
505
|
+
root.attach(document.body, placeholder)
|
|
506
|
+
`;
|
|
507
|
+
const entries = Object.values(compInfoMap).map((compInfo) => compInfo.main);
|
|
508
|
+
if (appEntry)
|
|
509
|
+
entries.unshift(appEntry);
|
|
510
|
+
virtualModules.writeModule(path.join(codeRoot, 'index.js'), entryHeader +
|
|
511
|
+
entries.map((p) => `require('./${(0, helpers_1.escapeJsString)(p)}')\n`).join('') +
|
|
512
|
+
entryFooter +
|
|
513
|
+
bootstrap);
|
|
514
|
+
};
|
|
515
|
+
updateVirtualIndexFile();
|
|
516
|
+
// copy res files
|
|
517
|
+
compilation.hooks.additionalAssets.tapPromise(PLUGIN_NAME, () => __awaiter(this, void 0, void 0, function* () {
|
|
518
|
+
yield Promise.all(Object.keys(resPathMap).map((p) => __awaiter(this, void 0, void 0, function* () {
|
|
519
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
|
|
520
|
+
compilation.assets[p] = new RawSource(yield node_fs_1.promises.readFile(path.join(codeRoot, p)));
|
|
521
|
+
})));
|
|
522
|
+
}));
|
|
523
|
+
});
|
|
524
|
+
}
|
|
405
525
|
}
|
|
406
|
-
|
|
407
|
-
exports.GlassEaselMiniprogramWebpackPlugin = GlassEaselMiniprogramWebpackPlugin
|
|
408
|
-
exports.GlassEaselMiniprogramWxmlLoader = GlassEaselMiniprogramWxmlLoader
|
|
409
|
-
exports.GlassEaselMiniprogramWxssLoader = GlassEaselMiniprogramWxssLoader
|
|
526
|
+
exports.GlassEaselMiniprogramWebpackPlugin = GlassEaselMiniprogramWebpackPlugin;
|