@mpxjs/webpack-plugin 2.7.8 → 2.7.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.
@@ -0,0 +1,51 @@
1
+ const ModuleDependency = require('webpack/lib/dependencies/ModuleDependency')
2
+ const makeSerializable = require('webpack/lib/util/makeSerializable')
3
+
4
+ class CommonJsAsyncDependency extends ModuleDependency {
5
+ constructor (request, range) {
6
+ super(request)
7
+ this.range = range
8
+ }
9
+
10
+ get type () {
11
+ return 'mpx cjs async'
12
+ }
13
+
14
+ get category () {
15
+ return 'commonjs'
16
+ }
17
+ }
18
+
19
+ CommonJsAsyncDependency.Template = class CommonJsAsyncDependencyTemplate extends (
20
+ ModuleDependency.Template
21
+ ) {
22
+ apply (
23
+ dep,
24
+ source,
25
+ {
26
+ runtimeTemplate,
27
+ moduleGraph,
28
+ chunkGraph,
29
+ runtimeRequirements
30
+ }
31
+ ) {
32
+ const requireExpr = runtimeTemplate.moduleExports({
33
+ module: moduleGraph.getModule(dep),
34
+ chunkGraph,
35
+ request: dep.request,
36
+ weak: dep.weak,
37
+ runtimeRequirements
38
+ })
39
+
40
+ const content = `Promise.resolve(${requireExpr})`
41
+
42
+ source.replace(dep.range[0], dep.range[1] - 1, content)
43
+ }
44
+ }
45
+
46
+ makeSerializable(
47
+ CommonJsAsyncDependency,
48
+ '@mpxjs/webpack-plugin/lib/dependencies/CommonJsAsyncDependency'
49
+ )
50
+
51
+ module.exports = CommonJsAsyncDependency
@@ -3,15 +3,19 @@ const makeSerializable = require('webpack/lib/util/makeSerializable')
3
3
  const path = require('path')
4
4
  const addQuery = require('../utils/add-query')
5
5
  const toPosix = require('../utils/to-posix')
6
+ const async = require('async')
7
+ const parseRequest = require('../utils/parse-request')
8
+ const { MPX_CURRENT_CHUNK } = require('../utils/const')
6
9
 
7
10
  class DynamicEntryDependency extends NullDependency {
8
- constructor (resource, entryType, outputPath = '', packageRoot = '', relativePath = '', range) {
11
+ constructor (request, entryType, outputPath = '', packageRoot = '', relativePath = '', context = '', range) {
9
12
  super()
10
- this.resource = resource
13
+ this.request = request
11
14
  this.entryType = entryType
12
15
  this.outputPath = outputPath
13
16
  this.packageRoot = packageRoot
14
17
  this.relativePath = relativePath
18
+ this.context = context
15
19
  this.range = range
16
20
  }
17
21
 
@@ -20,57 +24,78 @@ class DynamicEntryDependency extends NullDependency {
20
24
  }
21
25
 
22
26
  get key () {
23
- const { resource, entryType, outputPath, packageRoot, relativePath, range } = this
24
- return toPosix([resource, entryType, outputPath, packageRoot, relativePath, ...range].join('|'))
27
+ const { request, entryType, outputPath, packageRoot, relativePath, context, range } = this
28
+ return toPosix([request, entryType, outputPath, packageRoot, relativePath, context, ...range].join('|'))
25
29
  }
26
30
 
27
31
  addEntry (compilation, callback) {
28
32
  const mpx = compilation.__mpx__
29
- const publicPath = compilation.outputOptions.publicPath || ''
30
- let { resource, entryType, outputPath, relativePath, originEntryNode } = this
31
-
32
- const { packageRoot, outputPath: filename, alreadyOutputted } = mpx.getPackageInfo({
33
- resource,
34
- outputPath,
35
- resourceType: entryType,
36
- warn (e) {
37
- compilation.warnings.push(e)
33
+ let { request, entryType, outputPath, relativePath, context, originEntryNode, publicPath, resolver } = this
34
+
35
+ async.waterfall([
36
+ (callback) => {
37
+ if (context && resolver) {
38
+ resolver.resolve({}, context, request, {}, (err, resource) => {
39
+ callback(err, resource)
40
+ })
41
+ } else {
42
+ callback(null, request)
43
+ }
38
44
  },
39
- error (e) {
40
- compilation.errors.push(e)
45
+ (resource, callback) => {
46
+ if (!outputPath) {
47
+ const { resourcePath } = parseRequest(resource)
48
+ outputPath = mpx.getOutputPath(resourcePath, entryType)
49
+ }
50
+
51
+ const { packageRoot, outputPath: filename, alreadyOutputted } = mpx.getPackageInfo({
52
+ resource,
53
+ outputPath,
54
+ resourceType: entryType,
55
+ warn (e) {
56
+ compilation.warnings.push(e)
57
+ },
58
+ error (e) {
59
+ compilation.errors.push(e)
60
+ }
61
+ })
62
+
63
+ let resultPath = publicPath + filename
64
+ if (relativePath && relativePath !== MPX_CURRENT_CHUNK) {
65
+ resultPath = toPosix(path.relative(relativePath, resultPath))
66
+ }
67
+
68
+ // export类型的resultPath需要添加.js后缀
69
+ if (entryType === 'export') resultPath += '.js'
70
+
71
+ if (alreadyOutputted) return callback(null, { resultPath })
72
+
73
+ // 对于常规js模块不应添加packageRoot避免冗余
74
+ if (packageRoot && entryType !== 'export') {
75
+ resource = addQuery(resource, { packageRoot }, true)
76
+ }
77
+
78
+ mpx.addEntry(resource, filename, (err, entryModule) => {
79
+ if (err) return callback(err)
80
+ if (entryType === 'export') {
81
+ mpx.exportModules.add(entryModule)
82
+ }
83
+ originEntryNode.addChild(mpx.getEntryNode(entryModule, entryType))
84
+ return callback(null, {
85
+ resultPath,
86
+ entryModule
87
+ })
88
+ })
41
89
  }
42
- })
43
-
44
- let resultPath = publicPath + filename
45
- if (relativePath) {
46
- resultPath = toPosix(path.relative(relativePath, resultPath))
47
- }
48
-
49
- // export类型的resultPath需要添加.js后缀
50
- if (entryType === 'export') resultPath += '.js'
51
-
52
- if (alreadyOutputted) return callback(null, { resultPath })
53
-
54
- if (packageRoot) {
55
- resource = addQuery(resource, { packageRoot })
56
- }
57
- mpx.addEntry(resource, filename, (err, entryModule) => {
58
- if (err) return callback(err)
59
- if (entryType === 'export') {
60
- mpx.exportModules.add(entryModule)
61
- }
62
- originEntryNode.addChild(mpx.getEntryNode(entryModule, entryType))
63
- return callback(null, {
64
- resultPath,
65
- entryModule
66
- })
67
- })
90
+ ], callback)
68
91
  }
69
92
 
70
93
  mpxAction (module, compilation, callback) {
71
94
  const mpx = compilation.__mpx__
72
- const { packageRoot } = this
95
+ const { packageRoot, context } = this
73
96
  this.originEntryNode = mpx.getEntryNode(module)
97
+ this.publicPath = compilation.outputOptions.publicPath || ''
98
+ if (context) this.resolver = compilation.resolverFactory.get('normal', module.resolveOptions)
74
99
  // 分包构建在需要在主包构建完成后在finishMake中处理,返回的资源路径先用key来占位,在合成extractedAssets时再进行最终替换
75
100
  if (packageRoot && mpx.currentPackageRoot !== packageRoot) {
76
101
  mpx.subpackagesEntriesMap[packageRoot] = mpx.subpackagesEntriesMap[packageRoot] || []
@@ -87,41 +112,52 @@ class DynamicEntryDependency extends NullDependency {
87
112
 
88
113
  // hash会影响最终的codeGenerateResult是否走缓存,由于该dep中resultPath是动态变更的,需要将其更新到hash中,避免错误使用缓存
89
114
  updateHash (hash, context) {
90
- const { resultPath } = this
115
+ const { resultPath, relativePath } = this
91
116
  if (resultPath) hash.update(resultPath)
117
+ // relativePath为MPX_CURRENT_CHUNK时,插入随机数hash使当前module的codeGeneration cache失效,以执行dep.apply动态获取当前module所属的chunk路径
118
+ if (relativePath === MPX_CURRENT_CHUNK) hash.update('' + Math.random())
92
119
  super.updateHash(hash, context)
93
120
  }
94
121
 
95
122
  serialize (context) {
96
123
  const { write } = context
97
- write(this.resource)
124
+ write(this.request)
98
125
  write(this.entryType)
99
126
  write(this.outputPath)
100
127
  write(this.packageRoot)
101
128
  write(this.relativePath)
129
+ write(this.context)
102
130
  write(this.range)
103
131
  super.serialize(context)
104
132
  }
105
133
 
106
134
  deserialize (context) {
107
135
  const { read } = context
108
- this.resource = read()
136
+ this.request = read()
109
137
  this.entryType = read()
110
138
  this.outputPath = read()
111
139
  this.packageRoot = read()
112
140
  this.relativePath = read()
141
+ this.context = read()
113
142
  this.range = read()
114
143
  super.deserialize(context)
115
144
  }
116
145
  }
117
146
 
118
147
  DynamicEntryDependency.Template = class DynamicEntryDependencyTemplate {
119
- apply (dep, source) {
120
- const { resultPath, range, key, outputPath } = dep
148
+ apply (dep, source, {
149
+ module,
150
+ chunkGraph
151
+ }) {
152
+ let { resultPath, range, key, outputPath, relativePath, publicPath } = dep
121
153
  if (outputPath === 'custom-tab-bar/index') {
122
154
  // replace with true for custom-tab-bar
123
155
  source.replace(range[0], range[1] - 1, 'true')
124
156
  } else if (resultPath) {
157
+ if (relativePath === MPX_CURRENT_CHUNK) {
158
+ relativePath = publicPath + path.dirname(chunkGraph.getModuleChunks(module)[0].name)
159
+ resultPath = toPosix(path.relative(relativePath, resultPath))
160
+ }
125
161
  source.replace(range[0], range[1] - 1, JSON.stringify(resultPath))
126
162
  } else {
127
163
  const replaceRange = `mpx_replace_path_${key}`
package/lib/extractor.js CHANGED
@@ -36,6 +36,11 @@ module.exports.pitch = async function (remainingRequest) {
36
36
  }
37
37
  })
38
38
 
39
+ if (issuerResource) {
40
+ // 清空issuerResource/index query避免importModule对于不同的issuer无法复用模块缓存
41
+ remainingRequest = addQuery(remainingRequest, {}, false, ['issuerResource', 'index'])
42
+ }
43
+
39
44
  let request = remainingRequest
40
45
  // static的情况下需要用record-loader记录相关静态资源的输出路径,不能直接在这里记录,需要确保在子依赖开始构建前完成记录,因为子依赖构建时可能就需要访问当前资源的输出路径
41
46
  if (isStatic) {
package/lib/index.js CHANGED
@@ -7,6 +7,7 @@ const InjectDependency = require('./dependencies/InjectDependency')
7
7
  const ReplaceDependency = require('./dependencies/ReplaceDependency')
8
8
  const NullFactory = require('webpack/lib/NullFactory')
9
9
  const CommonJsVariableDependency = require('./dependencies/CommonJsVariableDependency')
10
+ const CommonJsAsyncDependency = require('./dependencies/CommonJsAsyncDependency')
10
11
  const NormalModule = require('webpack/lib/NormalModule')
11
12
  const EntryPlugin = require('webpack/lib/EntryPlugin')
12
13
  const JavascriptModulesPlugin = require('webpack/lib/javascript/JavascriptModulesPlugin')
@@ -33,7 +34,7 @@ const RemoveEntryDependency = require('./dependencies/RemoveEntryDependency')
33
34
  const SplitChunksPlugin = require('webpack/lib/optimize/SplitChunksPlugin')
34
35
  const fixRelative = require('./utils/fix-relative')
35
36
  const parseRequest = require('./utils/parse-request')
36
- const matchCondition = require('./utils/match-condition')
37
+ const { matchCondition } = require('./utils/match-condition')
37
38
  const { preProcessDefs } = require('./utils/index')
38
39
  const config = require('./config')
39
40
  const hash = require('hash-sum')
@@ -49,7 +50,7 @@ const extractorPath = normalize.lib('extractor')
49
50
  const async = require('async')
50
51
  const stringifyLoadersAndResource = require('./utils/stringify-loaders-resource')
51
52
  const emitFile = require('./utils/emit-file')
52
- const { MPX_PROCESSED_FLAG, MPX_DISABLE_EXTRACTOR_CACHE } = require('./utils/const')
53
+ const { MPX_PROCESSED_FLAG, MPX_DISABLE_EXTRACTOR_CACHE, MPX_CURRENT_CHUNK } = require('./utils/const')
53
54
  const isEmptyObject = require('./utils/is-empty-object')
54
55
 
55
56
  const isProductionLikeMode = options => {
@@ -406,7 +407,7 @@ class MpxWebpackPlugin {
406
407
  async.each(deps, (dep, callback) => {
407
408
  dep.addEntry(compilation, (err, { resultPath }) => {
408
409
  if (err) return callback(err)
409
- mpx.replacePathMap[dep.key] = resultPath
410
+ dep.resultPath = mpx.replacePathMap[dep.key] = resultPath
410
411
  callback()
411
412
  })
412
413
  }, callback)
@@ -471,6 +472,9 @@ class MpxWebpackPlugin {
471
472
 
472
473
  compilation.dependencyFactories.set(CommonJsVariableDependency, normalModuleFactory)
473
474
  compilation.dependencyTemplates.set(CommonJsVariableDependency, new CommonJsVariableDependency.Template())
475
+
476
+ compilation.dependencyFactories.set(CommonJsAsyncDependency, normalModuleFactory)
477
+ compilation.dependencyTemplates.set(CommonJsAsyncDependency, new CommonJsAsyncDependency.Template())
474
478
  })
475
479
 
476
480
  compiler.hooks.thisCompilation.tap('MpxWebpackPlugin', (compilation, { normalModuleFactory }) => {
@@ -512,6 +516,7 @@ class MpxWebpackPlugin {
512
516
  usingComponents: {},
513
517
  // todo es6 map读写性能高于object,之后会逐步替换
514
518
  vueContentCache: new Map(),
519
+ wxsAssetsCache: new Map(),
515
520
  currentPackageRoot: '',
516
521
  wxsContentMap: {},
517
522
  forceUsePageCtor: this.options.forceUsePageCtor,
@@ -911,6 +916,43 @@ class MpxWebpackPlugin {
911
916
  return true
912
917
  })
913
918
 
919
+ const requireAsyncHandler = (expr, members) => {
920
+ if (members[0] === 'async') {
921
+ let request = expr.arguments[0].value
922
+ const range = expr.arguments[0].range
923
+ const context = parser.state.module.context
924
+ const { queryObj } = parseRequest(request)
925
+ if (queryObj.root) {
926
+ // 删除root query
927
+ request = addQuery(request, {}, false, ['root'])
928
+ // 目前仅wx支持require.async,其余平台使用CommonJsAsyncDependency进行模拟抹平
929
+ if (mpx.mode === 'wx') {
930
+ const dep = new DynamicEntryDependency(request, 'export', '', queryObj.root, MPX_CURRENT_CHUNK, context, range)
931
+ parser.state.current.addPresentationalDependency(dep)
932
+ } else {
933
+ const range = expr.range
934
+ const dep = new CommonJsAsyncDependency(request, range)
935
+ parser.state.current.addDependency(dep)
936
+ }
937
+ return true
938
+ }
939
+ }
940
+ }
941
+
942
+ parser.hooks.callMemberChain
943
+ .for('require')
944
+ .tap({
945
+ name: 'MpxWebpackPlugin',
946
+ stage: -1000
947
+ }, (expr, members) => requireAsyncHandler(expr, members))
948
+
949
+ parser.hooks.callMemberChainOfCallMemberChain
950
+ .for('require')
951
+ .tap({
952
+ name: 'MpxWebpackPlugin',
953
+ stage: -1000
954
+ }, (expr, calleeMembers, callExpr) => requireAsyncHandler(callExpr, calleeMembers))
955
+
914
956
  const transHandler = (expr) => {
915
957
  const module = parser.state.module
916
958
  const current = parser.state.current
@@ -3,6 +3,7 @@ const normalize = require('../utils/normalize')
3
3
  const nativeLoaderPath = normalize.lib('native-loader')
4
4
  const isUrlRequestRaw = require('../utils/is-url-request')
5
5
  const parseRequest = require('../utils/parse-request')
6
+ const addQuery = require('../utils/add-query')
6
7
  const loaderUtils = require('loader-utils')
7
8
  const resolve = require('../utils/resolve')
8
9
 
@@ -23,10 +24,10 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning, custom
23
24
 
24
25
  let dynamicEntryCount = 0
25
26
 
26
- const getDynamicEntry = (resource, type, outputPath = '', packageRoot = '', relativePath = '') => {
27
- if (typeof customGetDynamicEntry === 'function') return customGetDynamicEntry(resource, type, outputPath, packageRoot, relativePath)
27
+ const getDynamicEntry = (request, type, outputPath = '', packageRoot = '', relativePath = '', context = '') => {
28
+ if (typeof customGetDynamicEntry === 'function') return customGetDynamicEntry(request, type, outputPath, packageRoot, relativePath, context)
28
29
  const key = `mpx_dynamic_entry_${dynamicEntryCount++}`
29
- const value = `__mpx_dynamic_entry__( ${JSON.stringify(resource)},${JSON.stringify(type)},${JSON.stringify(outputPath)},${JSON.stringify(packageRoot)},${JSON.stringify(relativePath)})`
30
+ const value = `__mpx_dynamic_entry__( ${JSON.stringify(request)},${JSON.stringify(type)},${JSON.stringify(outputPath)},${JSON.stringify(packageRoot)},${JSON.stringify(relativePath)},${JSON.stringify(context)})`
30
31
  dynamicEntryMap.set(key, value)
31
32
  return key
32
33
  }
@@ -47,8 +48,13 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning, custom
47
48
  resolve(context, component, loaderContext, (err, resource, info) => {
48
49
  if (err) return callback(err)
49
50
  const { resourcePath, queryObj } = parseRequest(resource)
50
- // 目前只有微信支持分包异步化
51
- if (queryObj.root && mode === 'wx') tarRoot = queryObj.root
51
+
52
+ if (queryObj.root) {
53
+ // 删除root query
54
+ resource = addQuery(resource, {}, false, ['root'])
55
+ // 目前只有微信支持分包异步化
56
+ if (mode === 'wx') tarRoot = queryObj.root
57
+ }
52
58
  const parsed = path.parse(resourcePath)
53
59
  const ext = parsed.ext
54
60
  const resourceName = path.join(parsed.dir, parsed.name)
package/lib/loader.js CHANGED
@@ -3,7 +3,7 @@ const parseComponent = require('./parser')
3
3
  const createHelpers = require('./helpers')
4
4
  const loaderUtils = require('loader-utils')
5
5
  const parseRequest = require('./utils/parse-request')
6
- const matchCondition = require('./utils/match-condition')
6
+ const { matchCondition } = require('./utils/match-condition')
7
7
  const fixUsingComponent = require('./utils/fix-using-component')
8
8
  const addQuery = require('./utils/add-query')
9
9
  const async = require('async')
@@ -254,7 +254,7 @@ module.exports = function (content) {
254
254
  output += `global.currentCtorType = ${JSON.stringify(ctor.replace(/^./, (match) => {
255
255
  return match.toLowerCase()
256
256
  }))}\n`
257
- output += `global.currentResourceType = '${ctorType}'\n`
257
+ output += `global.currentResourceType = ${JSON.stringify(ctorType)}\n`
258
258
 
259
259
  // template
260
260
  output += '/* template */\n'
@@ -5,7 +5,7 @@ const config = require('./config')
5
5
  const createHelpers = require('./helpers')
6
6
  const getJSONContent = require('./utils/get-json-content')
7
7
  const async = require('async')
8
- const matchCondition = require('./utils/match-condition')
8
+ const { matchCondition } = require('./utils/match-condition')
9
9
  const fixUsingComponent = require('./utils/fix-using-component')
10
10
  const { JSON_JS_EXT } = require('./utils/const')
11
11
 
@@ -175,7 +175,9 @@ module.exports = function (content) {
175
175
 
176
176
  // 注入构造函数
177
177
  let ctor = 'App'
178
+ let ctorType = 'app'
178
179
  if (pagesMap[resourcePath]) {
180
+ ctorType = 'page'
179
181
  if (mpx.forceUsePageCtor || mode === 'ali' || mode === 'swan') {
180
182
  ctor = 'Page'
181
183
  } else {
@@ -183,11 +185,13 @@ module.exports = function (content) {
183
185
  }
184
186
  } else if (componentsMap[resourcePath]) {
185
187
  ctor = 'Component'
188
+ ctorType = 'component'
186
189
  }
187
190
  output += `global.currentCtor = ${ctor}\n`
188
191
  output += `global.currentCtorType = ${JSON.stringify(ctor.replace(/^./, (match) => {
189
192
  return match.toLowerCase()
190
193
  }))}\n`
194
+ output += `global.currentResourceType = ${JSON.stringify(ctorType)}\n`
191
195
 
192
196
  if (srcMode) {
193
197
  output += `global.currentSrcMode = ${JSON.stringify(srcMode)}\n`
@@ -2,7 +2,7 @@ const path = require('path')
2
2
  const stringifyQuery = require('../utils/stringify-query')
3
3
  const parseQuery = require('loader-utils').parseQuery
4
4
  const addInfix = require('../utils/add-infix')
5
- const matchCondition = require('../utils/match-condition')
5
+ const { matchCondition } = require('../utils/match-condition')
6
6
  const { JSON_JS_EXT } = require('../utils/const')
7
7
 
8
8
  module.exports = class AddEnvPlugin {
@@ -1,7 +1,7 @@
1
1
  const path = require('path')
2
2
  const stringifyQuery = require('../utils/stringify-query')
3
3
  const parseQuery = require('loader-utils').parseQuery
4
- const matchCondition = require('../utils/match-condition')
4
+ const { matchCondition } = require('../utils/match-condition')
5
5
  const addInfix = require('../utils/add-infix')
6
6
  const { JSON_JS_EXT } = require('../utils/const')
7
7
 
@@ -1,5 +1,5 @@
1
1
  <script>
2
- import getInnerListeners from './getInnerListeners'
2
+ import getInnerListeners, { extendEvent } from './getInnerListeners'
3
3
 
4
4
  export default {
5
5
  name: 'mpx-image',
@@ -23,6 +23,13 @@
23
23
  beforeCreate () {
24
24
  this.image = new Image()
25
25
  this.image.onload = (e) => {
26
+ extendEvent(e, {
27
+ detail: {
28
+ width: this.image.width,
29
+ height: this.image.height
30
+ }
31
+ })
32
+
26
33
  this.$emit('load', e)
27
34
  }
28
35
  this.image.onerror = (e) => {
@@ -7,7 +7,7 @@ const vw = require('./plugins/vw')
7
7
  const pluginCondStrip = require('./plugins/conditional-strip')
8
8
  const scopeId = require('./plugins/scope-id')
9
9
  const transSpecial = require('./plugins/trans-special')
10
- const matchCondition = require('../utils/match-condition')
10
+ const { matchCondition } = require('../utils/match-condition')
11
11
  const parseRequest = require('../utils/parse-request')
12
12
 
13
13
  module.exports = function (css, map) {
@@ -3,6 +3,7 @@ const he = require('he')
3
3
  const config = require('../config')
4
4
  const { MPX_ROOT_VIEW, MPX_APP_MODULE_ID } = require('../utils/const')
5
5
  const normalize = require('../utils/normalize')
6
+ const { normalizeCondition } = require('../utils/match-condition')
6
7
  const isValidIdentifierStr = require('../utils/is-valid-identifier-str')
7
8
  const isEmptyObject = require('../utils/is-empty-object')
8
9
  const getRulesRunner = require('../platform/index')
@@ -10,7 +11,6 @@ const addQuery = require('../utils/add-query')
10
11
  const transDynamicClassExpr = require('./trans-dynamic-class-expr')
11
12
  const dash2hump = require('../utils/hump-dash').dash2hump
12
13
  const { inBrowser } = require('../utils/env')
13
-
14
14
  /**
15
15
  * Make a map and return a function for checking if a key
16
16
  * is in that map.
@@ -737,8 +737,10 @@ function parse (template, options) {
737
737
 
738
738
  currentParent.children.push(element)
739
739
  element.parent = currentParent
740
-
741
740
  processElement(element, root, options, meta)
741
+ if (isComponentNode(element, options) && mode === 'ali' && !options.hasVirtualHost) {
742
+ processAliAddComponentRootView(element, options, stack, currentParent)
743
+ }
742
744
  tagNames.add(element.tag)
743
745
 
744
746
  if (!unary) {
@@ -1800,36 +1802,70 @@ function processBuiltInComponents (el, meta) {
1800
1802
  }
1801
1803
  }
1802
1804
 
1803
- function processAliStyleClassHack (el, options, root) {
1804
- let processor
1805
- // 处理组件标签
1806
- if (isComponentNode(el, options)) processor = ({ value, typeName }) => [typeName, value]
1807
- // 处理组件根节点
1808
- if (options.isComponent && el === root && isRealNode(el)) {
1809
- processor = ({ name, value, typeName }) => {
1810
- let sep = name === 'style' ? ';' : ' '
1811
- value = value ? `{{${typeName}||''}}${sep}${value}` : `{{${typeName}||''}}`
1812
- return [name, value]
1805
+ function processAliAddComponentRootView (el, options, stack, currentParent) {
1806
+ const processAttrsConditions = [
1807
+ { condition: /^(on|catch)Tap$/, action: 'clone' },
1808
+ { condition: /^(on|catch)TouchStart$/, action: 'clone' },
1809
+ { condition: /^(on|catch)TouchMove$/, action: 'clone' },
1810
+ { condition: /^(on|catch)TouchEnd$/, action: 'clone' },
1811
+ { condition: /^(on|catch)TouchCancel$/, action: 'clone' },
1812
+ { condition: /^(on|catch)LongTap$/, action: 'clone' },
1813
+ { condition: /^data-/, action: 'clone' },
1814
+ { condition: 'style', action: 'move' },
1815
+ { condition: 'class', action: 'append', value: `${MPX_ROOT_VIEW} host-${options.moduleId}` }
1816
+ ]
1817
+ let newElAttrs = []
1818
+ let allAttrs = cloneAttrsList(el.attrsList)
1819
+
1820
+ function processClone (attr) {
1821
+ newElAttrs.push(attr)
1822
+ }
1823
+
1824
+ function processMove (attr) {
1825
+ let movedAttr = getAndRemoveAttr(el, attr.name)
1826
+ if (movedAttr.has) {
1827
+ newElAttrs.push({
1828
+ name: attr,
1829
+ value: movedAttr.val
1830
+ })
1813
1831
  }
1814
1832
  }
1815
- // 非上述两种不处理
1816
- if (!processor) return
1817
- // 处理style、class
1818
- ['style', 'class'].forEach((type) => {
1819
- let exp = getAndRemoveAttr(el, type).val
1820
- let typeName = 'mpx' + type.replace(/^./, (matched) => matched.toUpperCase())
1821
- let [newName, newValue] = processor({
1822
- name: type,
1823
- value: exp,
1824
- typeName
1825
- })
1826
- if (newValue !== undefined) {
1827
- addAttrs(el, [{
1828
- name: newName,
1829
- value: newValue
1830
- }])
1833
+
1834
+ function processAppend (attr, item) {
1835
+ const getNeedAppendAttrValue = el.attrsMap[attr.name]
1836
+ if (getNeedAppendAttrValue) {
1837
+ item.value = getNeedAppendAttrValue + ' ' + item.value
1831
1838
  }
1839
+ newElAttrs.push({
1840
+ name: attr.name,
1841
+ value: item.value
1842
+ })
1843
+ }
1844
+
1845
+ processAttrsConditions.forEach(item => {
1846
+ const matcher = normalizeCondition(item.condition)
1847
+ allAttrs.forEach((attr) => {
1848
+ if (matcher(attr.name)) {
1849
+ if (item.action === 'clone') {
1850
+ processClone(attr)
1851
+ } else if (item.action === 'move') {
1852
+ processMove(attr)
1853
+ } else if (item.action === 'append') {
1854
+ processAppend(attr, item)
1855
+ }
1856
+ }
1857
+ })
1832
1858
  })
1859
+
1860
+ // create new el
1861
+ let componentWrapView = createASTElement('view', newElAttrs)
1862
+ currentParent.children.pop()
1863
+ currentParent.children.push(componentWrapView)
1864
+ componentWrapView.parent = currentParent
1865
+ componentWrapView.children.push(el)
1866
+ el.parent = componentWrapView
1867
+
1868
+ el = componentWrapView
1833
1869
  }
1834
1870
 
1835
1871
  // 有virtualHost情况wx组件注入virtualHost。无virtualHost阿里组件注入root-view。其他跳过。
@@ -1841,17 +1877,17 @@ function getVirtualHostRoot (options, meta) {
1841
1877
  !meta.options && (meta.options = {})
1842
1878
  meta.options.virtualHost = true
1843
1879
  }
1844
- if (mode === 'ali' && !options.hasVirtualHost) {
1845
- // ali组件根节点实体化
1846
- let rootView = createASTElement('view', [
1847
- {
1848
- name: 'class',
1849
- value: `${MPX_ROOT_VIEW} host-${options.moduleId}`
1850
- }
1851
- ])
1852
- processElement(rootView, rootView, options, meta)
1853
- return rootView
1854
- }
1880
+ // if (mode === 'ali' && !options.hasVirtualHost) {
1881
+ // // ali组件根节点实体化
1882
+ // let rootView = createASTElement('view', [
1883
+ // {
1884
+ // name: 'class',
1885
+ // value: `${MPX_ROOT_VIEW} host-${options.moduleId}`
1886
+ // }
1887
+ // ])
1888
+ // processElement(rootView, rootView, options, meta)
1889
+ // return rootView
1890
+ // }
1855
1891
  }
1856
1892
  return getTempNode()
1857
1893
  }
@@ -2060,11 +2096,6 @@ function processElement (el, root, options, meta) {
2060
2096
  processShow(el, options, root)
2061
2097
  }
2062
2098
 
2063
- // 当mode为ali不管是不是跨平台都需要进行此处理,以保障ali当中的refs相关增强能力正常运行
2064
- if (mode === 'ali') {
2065
- processAliStyleClassHack(el, options, root)
2066
- }
2067
-
2068
2099
  if (!pass) {
2069
2100
  processBindEvent(el, options)
2070
2101
  processComponentIs(el, options)
@@ -1,7 +1,7 @@
1
1
  const compiler = require('./compiler')
2
2
  const bindThis = require('./bind-this').transform
3
3
  const parseRequest = require('../utils/parse-request')
4
- const matchCondition = require('../utils/match-condition')
4
+ const { matchCondition } = require('../utils/match-condition')
5
5
  const loaderUtils = require('loader-utils')
6
6
 
7
7
  module.exports = function (raw) {
@@ -5,5 +5,6 @@ module.exports = {
5
5
  RESOLVE_IGNORED_ERR: new Error('Resolve ignored!'),
6
6
  JSON_JS_EXT: '.json.js',
7
7
  MPX_ROOT_VIEW: 'mpx-root-view', // 根节点类名
8
- MPX_APP_MODULE_ID: 'mpx-app-scope' // app文件moduleId
8
+ MPX_APP_MODULE_ID: 'mpx-app-scope', // app文件moduleId
9
+ MPX_CURRENT_CHUNK: 'mpx_current_chunk'
9
10
  }
@@ -7,8 +7,6 @@ module.exports = function evalJSONJS (source, filename, loaderContext) {
7
7
  const defValues = defKeys.map((key) => {
8
8
  return defs[key]
9
9
  })
10
- // 记录依赖
11
- loaderContext.addDependency(filename)
12
10
  const dirname = path.dirname(filename)
13
11
  // eslint-disable-next-line no-new-func
14
12
  const func = new Function('module', 'exports', 'require', '__filename', '__dirname', ...defKeys, source)
@@ -5,6 +5,8 @@ const async = require('async')
5
5
  const { JSON_JS_EXT } = require('./const')
6
6
 
7
7
  module.exports = function getJSONContent (json, loaderContext, callback) {
8
+ // error process
9
+ if (!loaderContext._compiler) return callback(null, '{}')
8
10
  const fs = loaderContext._compiler.inputFileSystem
9
11
  async.waterfall([
10
12
  (callback) => {
@@ -45,4 +45,7 @@ const matchCondition = (resourcePath, condition = {}) => {
45
45
  return matched
46
46
  }
47
47
 
48
- module.exports = matchCondition
48
+ module.exports = {
49
+ matchCondition,
50
+ normalizeCondition
51
+ }
@@ -2,8 +2,7 @@ const templateCompiler = require('../template-compiler/compiler')
2
2
  const genComponentTag = require('../utils/gen-component-tag')
3
3
  const addQuery = require('../utils/add-query')
4
4
  const parseRequest = require('../utils/parse-request')
5
-
6
- // const matchCondition = require('../utils/match-condition')
5
+ // const { matchCondition } = require('../utils/match-condition')
7
6
 
8
7
  function calculateRootEleChild (arr) {
9
8
  if (!arr) {
package/lib/wxs/loader.js CHANGED
@@ -1,5 +1,6 @@
1
1
  const NodeTargetPlugin = require('webpack/lib/node/NodeTargetPlugin')
2
2
  const EntryPlugin = require('webpack/lib/EntryPlugin')
3
+ const LazySet = require('webpack/lib/util/LazySet')
3
4
  const LimitChunkCountPlugin = require('webpack/lib/optimize/LimitChunkCountPlugin')
4
5
  const path = require('path')
5
6
  const WxsPlugin = require('./WxsPlugin')
@@ -7,9 +8,12 @@ const RecordResourceMapDependency = require('../dependencies/RecordResourceMapDe
7
8
  const parseRequest = require('../utils/parse-request')
8
9
  const toPosix = require('../utils/to-posix')
9
10
  const fixRelative = require('../utils/fix-relative')
11
+ const addQuery = require('../utils/add-query')
10
12
  const config = require('../config')
11
13
 
12
- module.exports = function () {
14
+ module.exports = content => content
15
+
16
+ module.exports.pitch = function (remainingRequest) {
13
17
  const nativeCallback = this.async()
14
18
  const moduleGraph = this._compilation.moduleGraph
15
19
  const mpx = this.getMpx()
@@ -46,63 +50,91 @@ module.exports = function () {
46
50
  nativeCallback(null, `module.exports = ${JSON.stringify(relativePath)};`)
47
51
  }
48
52
 
49
- const outputOptions = {
50
- filename,
51
- // 避免输出的wxs中包含es语法
52
- environment: {
53
- // The environment supports arrow functions ('() => { ... }').
54
- arrowFunction: false,
55
- // The environment supports BigInt as literal (123n).
56
- bigIntLiteral: false,
57
- // The environment supports const and let for variable declarations.
58
- const: false,
59
- // The environment supports destructuring ('{ a, b } = obj').
60
- destructuring: false,
61
- // The environment supports an async import() function to import EcmaScript modules.
62
- dynamicImport: false,
63
- // The environment supports 'for of' iteration ('for (const x of array) { ... }').
64
- forOf: false,
65
- // The environment supports ECMAScript Module syntax to import ECMAScript modules (import ... from '...').
66
- module: false
67
- }
68
- }
69
- // wxs文件必须经过pre-loader
70
- const request = '!!' + this.remainingRequest
71
- const plugins = [
72
- new WxsPlugin({ mode }),
73
- new NodeTargetPlugin(),
74
- new EntryPlugin(this.context, request, { name: getName(filename) }),
75
- new LimitChunkCountPlugin({ maxChunks: 1 })
76
- ]
53
+ // 清空issuerResource query避免文件内容输出报错并进行子编译缓存优化
54
+ const request = '!!' + addQuery(remainingRequest, {}, false, ['issuerResource'])
77
55
 
78
- const childCompiler = this._compilation.createChildCompiler(resourcePath, outputOptions, plugins)
56
+ // request中已经包含全量构成filename的信息,故可以直接使用request作为key来进行缓存
57
+ if (!mpx.wxsAssetsCache.has(request)) {
58
+ mpx.wxsAssetsCache.set(request, new Promise((resolve, reject) => {
59
+ const outputOptions = {
60
+ filename,
61
+ // 避免输出的wxs中包含es语法
62
+ environment: {
63
+ // The environment supports arrow functions ('() => { ... }').
64
+ arrowFunction: false,
65
+ // The environment supports BigInt as literal (123n).
66
+ bigIntLiteral: false,
67
+ // The environment supports const and let for variable declarations.
68
+ const: false,
69
+ // The environment supports destructuring ('{ a, b } = obj').
70
+ destructuring: false,
71
+ // The environment supports an async import() function to import EcmaScript modules.
72
+ dynamicImport: false,
73
+ // The environment supports 'for of' iteration ('for (const x of array) { ... }').
74
+ forOf: false,
75
+ // The environment supports ECMAScript Module syntax to import ECMAScript modules (import ... from '...').
76
+ module: false
77
+ }
78
+ }
79
79
 
80
- childCompiler.hooks.afterCompile.tap('MpxWebpackPlugin', (compilation) => {
81
- // 持久化缓存,使用module.buildInfo.assets来输出文件
82
- compilation.getAssets().forEach(({ name, source, info }) => {
83
- this.emitFile(name, source.source(), undefined, info)
84
- })
85
- compilation.clearAssets()
86
- })
80
+ const plugins = [
81
+ new WxsPlugin({ mode }),
82
+ new NodeTargetPlugin(),
83
+ new EntryPlugin(this.context, request, { name: getName(filename) }),
84
+ new LimitChunkCountPlugin({ maxChunks: 1 })
85
+ ]
86
+
87
+ const childCompiler = this._compilation.createChildCompiler(resourcePath, outputOptions, plugins)
88
+
89
+ let assets = []
87
90
 
88
- childCompiler.runAsChild((err, entries, compilation) => {
89
- if (err) return callback(err)
90
- if (compilation.errors.length > 0) {
91
- return callback(compilation.errors[0])
92
- }
91
+ childCompiler.hooks.afterCompile.tap('MpxWebpackPlugin', (compilation) => {
92
+ // 持久化缓存,使用module.buildInfo.assets来输出文件
93
+ assets = compilation.getAssets()
94
+ compilation.clearAssets()
95
+ })
93
96
 
94
- compilation.fileDependencies.forEach((dep) => {
97
+ childCompiler.runAsChild((err, entries, compilation) => {
98
+ if (err) return reject(err)
99
+ const fileDependencies = new LazySet()
100
+ const contextDependencies = new LazySet()
101
+ const missingDependencies = new LazySet()
102
+ const buildDependencies = new LazySet()
103
+ compilation.modules.forEach((module) => {
104
+ module.addCacheDependencies(
105
+ fileDependencies,
106
+ contextDependencies,
107
+ missingDependencies,
108
+ buildDependencies
109
+ )
110
+ })
111
+ resolve({
112
+ assets,
113
+ fileDependencies,
114
+ contextDependencies,
115
+ missingDependencies,
116
+ buildDependencies
117
+ })
118
+ })
119
+ }))
120
+ }
121
+
122
+ mpx.wxsAssetsCache.get(request).then(({ assets, fileDependencies, contextDependencies, missingDependencies, buildDependencies }) => {
123
+ assets.forEach(({ name, source, info }) => {
124
+ this.emitFile(name, source.source(), undefined, info)
125
+ })
126
+ fileDependencies.forEach((dep) => {
95
127
  this.addDependency(dep)
96
- }, this)
97
- compilation.contextDependencies.forEach((dep) => {
128
+ })
129
+ contextDependencies.forEach((dep) => {
98
130
  this.addContextDependency(dep)
99
- }, this)
100
- compilation.missingDependencies.forEach((dep) => {
131
+ })
132
+ missingDependencies.forEach((dep) => {
101
133
  this.addMissingDependency(dep)
102
134
  })
103
- compilation.buildDependencies.forEach((dep) => {
135
+ buildDependencies.forEach((dep) => {
104
136
  this.addBuildDependency(dep)
105
137
  })
106
138
  callback()
107
- })
139
+ }).catch(callback)
108
140
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mpxjs/webpack-plugin",
3
- "version": "2.7.8",
3
+ "version": "2.7.11",
4
4
  "description": "mpx compile core",
5
5
  "keywords": [
6
6
  "mpx"
@@ -80,5 +80,5 @@
80
80
  "engines": {
81
81
  "node": ">=14.14.0"
82
82
  },
83
- "gitHead": "7c4e607bae13678cadc080d3303e9b432074d03e"
83
+ "gitHead": "484feb97fc5741ce3984fd235833fe0ab83593b9"
84
84
  }