glass-easel-miniprogram-webpack-plugin 0.1.1 → 0.2.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/helpers.js CHANGED
@@ -1,7 +1,8 @@
1
1
  /* eslint-disable */
2
2
 
3
- exports.escapeJsString = (str) => str.replace(/["'\\\r\n`]/g, (c) => {
4
- if (c === '\r') return '\\r'
5
- if (c === '\n') return '\\n'
6
- return `\\${c}`
7
- })
3
+ exports.escapeJsString = (str) =>
4
+ str.replace(/["'\\\r\n`]/g, (c) => {
5
+ if (c === '\r') return '\\r'
6
+ if (c === '\n') return '\\n'
7
+ return `\\${c}`
8
+ })
package/index.js CHANGED
@@ -1,8 +1,6 @@
1
- /* eslint-disable */
2
-
3
1
  const fs = require('fs').promises
4
2
  const path = require('path')
5
- const { NormalModule } = require('webpack')
3
+ const webpack = require('webpack')
6
4
  const { RawSource } = require('webpack-sources')
7
5
  const VirtualModulesPlugin = require('webpack-virtual-modules')
8
6
  const chokidar = require('chokidar')
@@ -10,6 +8,7 @@ const { TmplGroup } = require('glass-easel-template-compiler')
10
8
 
11
9
  const { escapeJsString } = require('./helpers')
12
10
 
11
+ const GlassEaselMiniprogramWxmlLoader = path.join(__dirname, 'wxml_loader.js')
13
12
  const GlassEaselMiniprogramWxssLoader = path.join(__dirname, 'wxss_loader.js')
14
13
 
15
14
  const PLUGIN_NAME = 'GlassEaselMiniprogramWebpackPlugin'
@@ -58,7 +57,9 @@ class StyleSheetManager {
58
57
 
59
58
  toCodeString() {
60
59
  const arr = Object.entries(this.map).map(([compPath, { srcPath }]) => {
61
- const s = `backend.registerStyleSheetContent('${escapeJsString(compPath)}', require('${escapeJsString(srcPath)}'));`
60
+ const s = `backend.registerStyleSheetContent('${escapeJsString(
61
+ compPath,
62
+ )}', require('${escapeJsString(srcPath)}'));`
62
63
  return s
63
64
  })
64
65
  return `
@@ -97,7 +98,9 @@ class GlassEaselMiniprogramWebpackPlugin {
97
98
  if (parsed && (parsed.component === true || typeof parsed.usingComponents === 'object')) {
98
99
  staticConfig = parsed
99
100
  }
100
- } catch (e) { /* empty */ }
101
+ } catch (e) {
102
+ /* empty */
103
+ }
101
104
  return staticConfig
102
105
  }
103
106
 
@@ -109,10 +112,19 @@ class GlassEaselMiniprogramWebpackPlugin {
109
112
  }
110
113
 
111
114
  // search for component files
112
- let codeRootWatching = false
115
+ let codeRootPromises = null
113
116
  const searchCodeRoot = async (enableWatch) => {
114
- if (codeRootWatching) return
115
- codeRootWatching = true
117
+ if (codeRootPromises) {
118
+ // wait a short while for changes
119
+ await new Promise((resolve) => {
120
+ setTimeout(resolve, 250)
121
+ })
122
+ const promises = codeRootPromises
123
+ codeRootPromises = []
124
+ await Promise.all(promises)
125
+ return
126
+ }
127
+ codeRootPromises = []
116
128
  const handleFile = async (relPath) => {
117
129
  // for app.json, spread the global field
118
130
  if (relPath === 'app.json') {
@@ -155,7 +167,9 @@ class GlassEaselMiniprogramWebpackPlugin {
155
167
  )
156
168
  return
157
169
  }
158
- } catch (e) { /* empty */ }
170
+ } catch (e) {
171
+ /* empty */
172
+ }
159
173
  try {
160
174
  const jsFileStat = await fs.stat(path.join(codeRoot, `${compPath}.js`))
161
175
  if (jsFileStat.isFile()) {
@@ -165,7 +179,9 @@ class GlassEaselMiniprogramWebpackPlugin {
165
179
  }
166
180
  return
167
181
  }
168
- } catch (e) { /* empty */ }
182
+ } catch (e) {
183
+ /* empty */
184
+ }
169
185
  }
170
186
  }
171
187
 
@@ -183,6 +199,14 @@ class GlassEaselMiniprogramWebpackPlugin {
183
199
  // TODO support wxss file remove
184
200
  }
185
201
 
202
+ // add wxs
203
+ if (extName === '.wxs') {
204
+ const src = await fs.readFile(path.join(codeRoot, relPath), { encoding: 'utf8' })
205
+ const scriptPath = relPath.slice(0, -extName.length)
206
+ params.tmplGroup.addScript(scriptPath, src)
207
+ // TODO support wxs file remove
208
+ }
209
+
186
210
  // find resource files
187
211
  if (this.resourceFilePattern.test(relPath)) {
188
212
  params.resPathMap[relPath] = true
@@ -196,14 +220,13 @@ class GlassEaselMiniprogramWebpackPlugin {
196
220
 
197
221
  // await readdirp(codeRoot, handleFile)
198
222
  await new Promise((resolve, reject) => {
199
- const promises = []
200
223
  const watcher = chokidar.watch(codeRoot, { ignoreInitial: false })
201
224
  watcher
202
225
  .on('add', (p) => {
203
- promises.push(handleFile(normalizePath(p)))
226
+ codeRootPromises.push(handleFile(normalizePath(p)))
204
227
  })
205
228
  .on('change', (p) => {
206
- promises.push(handleFile(normalizePath(p)))
229
+ codeRootPromises.push(handleFile(normalizePath(p)))
207
230
  })
208
231
  .on('unlink', (p) => {
209
232
  removeEntry(normalizePath(p))
@@ -212,6 +235,8 @@ class GlassEaselMiniprogramWebpackPlugin {
212
235
  throw new Error(err)
213
236
  })
214
237
  .on('ready', () => {
238
+ const promises = codeRootPromises
239
+ codeRootPromises = []
215
240
  Promise.all(promises)
216
241
  .then(() => {
217
242
  if (!enableWatch) return watcher.close()
@@ -232,32 +257,36 @@ class GlassEaselMiniprogramWebpackPlugin {
232
257
  })
233
258
 
234
259
  // rewrite component entry paths
235
- compiler.resolverFactory.hooks.resolver
236
- .for('normal')
237
- .tap(PLUGIN_NAME, (resolver) => {
238
- resolver.hooks.result.tap(PLUGIN_NAME, (data) => {
239
- const absPath = data.path
240
- const extName = path.extname(absPath)
241
- if (extName === '.js' || extName === '.ts') {
242
- const relPath = normalizePath(absPath)
243
- if (relPath && params.compInfoMap[relPath.slice(0, -3)]) {
244
- const redirected = `${absPath.slice(0, -3)}.component`
245
- if (data.context.issuer !== redirected) {
246
- data.path = redirected
247
- }
260
+ compiler.resolverFactory.hooks.resolver.for('normal').tap(PLUGIN_NAME, (resolver) => {
261
+ resolver.hooks.result.tap(PLUGIN_NAME, (data) => {
262
+ const absPath = data.path
263
+ const extName = path.extname(absPath)
264
+ if (extName === '.js' || extName === '.ts') {
265
+ const relPath = normalizePath(absPath)
266
+ if (relPath && params.compInfoMap[relPath.slice(0, -3)]) {
267
+ const redirected = `${absPath.slice(0, -3)}.component`
268
+ if (data.context.issuer !== redirected) {
269
+ data.path = redirected
248
270
  }
249
271
  }
250
- return data
251
- })
272
+ }
273
+ return data
252
274
  })
275
+ })
253
276
 
254
277
  // add loaders
255
278
  compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
256
- NormalModule.getCompilationHooks(compilation).beforeLoaders
257
- .tap(PLUGIN_NAME, (loaders, mod) => {
279
+ webpack.NormalModule.getCompilationHooks(compilation).beforeLoaders.tap(
280
+ PLUGIN_NAME,
281
+ (loaders, mod) => {
258
282
  const absPath = mod.resource
259
283
  const extName = path.extname(absPath)
260
- if (extName === '.ts' || extName === '.js' || extName === '.wxml' || extName === '.wxss') {
284
+ if (
285
+ extName === '.ts' ||
286
+ extName === '.js' ||
287
+ extName === '.wxml' ||
288
+ extName === '.wxss'
289
+ ) {
261
290
  const relPath = path.relative(codeRoot, absPath).split(path.sep).join('/')
262
291
  const compPath = relPath.slice(0, -extName.length)
263
292
  if (params.compInfoMap[compPath] || compPath === 'app') {
@@ -270,10 +299,17 @@ class GlassEaselMiniprogramWebpackPlugin {
270
299
  }
271
300
  }
272
301
  })
302
+ } else if (extName === '.wxml' && compPath !== 'app') {
303
+ loaders.forEach((x) => {
304
+ if (x.loader === GlassEaselMiniprogramWxmlLoader) {
305
+ x.options = { compPath }
306
+ }
307
+ })
273
308
  }
274
309
  }
275
310
  }
276
- })
311
+ },
312
+ )
277
313
  })
278
314
 
279
315
  // collect virtual files
@@ -293,14 +329,18 @@ class GlassEaselMiniprogramWebpackPlugin {
293
329
  index.codeSpace.addComponentStaticConfig('${escapeJsString(compPath)}', ${json})
294
330
  index.codeSpace.addCompiledTemplate('${escapeJsString(compPath)}', {
295
331
  groupList: index.genObjectGroups,
296
- content: index.genObjectGroups['${escapeJsString(compPath)}']
332
+ content: index.genObjectGroups[require(
333
+ '${escapeJsString(codeRoot)}/${escapeJsString(compPath)}.wxml'
334
+ )]
297
335
  })
298
336
  index.codeSpace.addStyleSheet(
299
337
  '${escapeJsString(compPath)}',
300
338
  '${escapeJsString(compPath)}',
301
- ${scopeNameStr},
339
+ ${scopeNameStr}
302
340
  )
303
- index.codeSpace.globalComponentEnv(index.globalObject, '${escapeJsString(compPath)}', () => {
341
+ index.codeSpace.globalComponentEnv(index.globalObject, '${escapeJsString(
342
+ compPath,
343
+ )}', () => {
304
344
  require('./${escapeJsString(path.basename(compInfo.main))}')
305
345
  })
306
346
  `,
@@ -336,7 +376,9 @@ class GlassEaselMiniprogramWebpackPlugin {
336
376
  })()
337
377
  `
338
378
  const entryFooter = `
339
- var root = ab.createRoot('glass-easel-root', codeSpace, '${escapeJsString(this.defaultEntry)}')
379
+ var root = ab.createRoot('glass-easel-root', codeSpace, '${escapeJsString(
380
+ this.defaultEntry,
381
+ )}')
340
382
  var placeholder = document.createElement('span')
341
383
  document.body.appendChild(placeholder)
342
384
  root.attach(document.body, placeholder)
@@ -344,19 +386,24 @@ class GlassEaselMiniprogramWebpackPlugin {
344
386
  const entries = Object.values(params.compInfoMap).map((compInfo) => compInfo.main)
345
387
  if (params.appEntry) entries.unshift(params.appEntry)
346
388
  virtualModules.writeModule(
347
- `${codeRoot}/index.js`,
348
- entryHeader + entries.map((p) => `require('./${escapeJsString(p)}')\n`).join('') + entryFooter,
389
+ path.join(codeRoot, 'index.js'),
390
+ entryHeader +
391
+ entries.map((p) => `require('./${escapeJsString(p)}')\n`).join('') +
392
+ entryFooter,
349
393
  )
350
394
 
351
395
  // copy res files
352
396
  compilation.hooks.additionalAssets.tapPromise(PLUGIN_NAME, async () => {
353
- await Promise.all(Object.keys(params.resPathMap).map(async (p) => {
354
- compilation.assets[p] = new RawSource(await fs.readFile(path.join(codeRoot, p)))
355
- }))
397
+ await Promise.all(
398
+ Object.keys(params.resPathMap).map(async (p) => {
399
+ compilation.assets[p] = new RawSource(await fs.readFile(path.join(codeRoot, p)))
400
+ }),
401
+ )
356
402
  })
357
403
  })
358
404
  }
359
405
  }
360
406
 
361
407
  exports.GlassEaselMiniprogramWebpackPlugin = GlassEaselMiniprogramWebpackPlugin
408
+ exports.GlassEaselMiniprogramWxmlLoader = GlassEaselMiniprogramWxmlLoader
362
409
  exports.GlassEaselMiniprogramWxssLoader = GlassEaselMiniprogramWxssLoader
package/package.json CHANGED
@@ -1,12 +1,14 @@
1
1
  {
2
2
  "name": "glass-easel-miniprogram-webpack-plugin",
3
3
  "description": "The webpack plugin of the glass-easel project for MiniProgram file structure",
4
- "version": "0.1.1",
4
+ "version": "0.2.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/wechat-miniprogram/glass-easel.git"
8
8
  },
9
- "keywords": ["glass-easel"],
9
+ "keywords": [
10
+ "glass-easel"
11
+ ],
10
12
  "author": "wechat-miniprogram",
11
13
  "license": "MIT",
12
14
  "bugs": {
@@ -28,6 +30,6 @@
28
30
  "glass-easel-template-compiler": "0.1",
29
31
  "source-map": "^0.7.4",
30
32
  "webpack-sources": "^3.2.1",
31
- "webpack-virtual-modules": "^0.4.3"
33
+ "webpack-virtual-modules": "^0.5.0"
32
34
  }
33
35
  }
package/wxml_loader.js ADDED
@@ -0,0 +1,9 @@
1
+ const { escapeJsString } = require('./helpers')
2
+
3
+ module.exports = function (src, prevMap, meta) {
4
+ const { compPath } = this.query
5
+ return `
6
+ // build time ${new Date().getTime()}
7
+ module.exports = '${escapeJsString(compPath)}'
8
+ `
9
+ }
package/wxss_loader.js CHANGED
@@ -14,17 +14,19 @@ module.exports = function (src, prevMap, meta) {
14
14
  if (prevMap) {
15
15
  const destConsumer = new SourceMapConsumer(ssSourceMap)
16
16
  const srcConsumer = new SourceMapConsumer(prevMap)
17
- Promise.all([destConsumer, srcConsumer]).then(([destConsumer, srcConsumer]) => {
18
- const gen = SourceMapGenerator.fromSourceMap(destConsumer)
19
- gen.applySourceMap(srcConsumer, this.resourcePath)
20
- destConsumer.destroy()
21
- srcConsumer.destroy()
22
- map = gen.toJSON()
23
- callback(null, ss, map, meta)
24
- return undefined
25
- }).catch((err) => {
26
- callback(err)
27
- })
17
+ Promise.all([destConsumer, srcConsumer])
18
+ .then(([destConsumer, srcConsumer]) => {
19
+ const gen = SourceMapGenerator.fromSourceMap(destConsumer)
20
+ gen.applySourceMap(srcConsumer, this.resourcePath)
21
+ destConsumer.destroy()
22
+ srcConsumer.destroy()
23
+ map = gen.toJSON()
24
+ callback(null, ss, map, meta)
25
+ return undefined
26
+ })
27
+ .catch((err) => {
28
+ callback(err)
29
+ })
28
30
  } else {
29
31
  map = ssSourceMap
30
32
  callback(null, ss, map, meta)