@mpxjs/webpack-plugin 2.6.110 → 2.7.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/lib/dependencies/AppEntryDependency.js +56 -0
  2. package/lib/dependencies/CommonJsVariableDependency.js +69 -0
  3. package/lib/dependencies/DynamicEntryDependency.js +131 -0
  4. package/lib/dependencies/FlagPluginDependency.js +23 -0
  5. package/lib/dependencies/InjectDependency.js +43 -0
  6. package/lib/dependencies/RecordGlobalComponentsDependency.js +50 -0
  7. package/lib/dependencies/RecordResourceMapDependency.js +52 -0
  8. package/lib/dependencies/RemoveEntryDependency.js +40 -0
  9. package/lib/{dependency → dependencies}/ReplaceDependency.js +19 -2
  10. package/lib/dependencies/ResolveDependency.js +84 -0
  11. package/lib/extractor.js +73 -178
  12. package/lib/file-loader.js +7 -19
  13. package/lib/helpers.js +42 -330
  14. package/lib/index.js +497 -376
  15. package/lib/json-compiler/helper.js +148 -0
  16. package/lib/json-compiler/index.js +195 -439
  17. package/lib/json-compiler/plugin.js +150 -0
  18. package/lib/json-compiler/{theme-loader.js → theme.js} +5 -3
  19. package/lib/loader.js +107 -226
  20. package/lib/native-loader.js +65 -132
  21. package/lib/parser.js +1 -2
  22. package/lib/record-loader.js +11 -0
  23. package/lib/{path-loader.js → resolve-loader.js} +0 -0
  24. package/lib/resolver/AddEnvPlugin.js +3 -2
  25. package/lib/resolver/AddModePlugin.js +3 -2
  26. package/lib/runtime/base.styl +5 -0
  27. package/lib/runtime/i18n.wxs +3 -3
  28. package/lib/runtime/optionProcessor.js +3 -3
  29. package/lib/selector.js +9 -11
  30. package/lib/style-compiler/index.js +12 -19
  31. package/lib/template-compiler/compiler.js +21 -162
  32. package/lib/template-compiler/index.js +47 -136
  33. package/lib/url-loader.js +11 -29
  34. package/lib/utils/add-query.js +1 -1
  35. package/lib/utils/const.js +9 -0
  36. package/lib/utils/emit-file.js +10 -0
  37. package/lib/utils/eval-json-js.js +31 -0
  38. package/lib/utils/get-entry-name.js +13 -0
  39. package/lib/utils/get-json-content.js +41 -0
  40. package/lib/utils/is-url-request.js +10 -1
  41. package/lib/utils/normalize.js +0 -13
  42. package/lib/utils/parse-request.js +3 -3
  43. package/lib/utils/resolve.js +13 -0
  44. package/lib/utils/set.js +47 -0
  45. package/lib/utils/stringify-loaders-resource.js +25 -0
  46. package/lib/utils/stringify-query.js +4 -0
  47. package/lib/web/processJSON.js +113 -142
  48. package/lib/web/processScript.js +32 -26
  49. package/lib/web/processTemplate.js +57 -39
  50. package/lib/wxml/{wxml-loader.js → loader.js} +24 -60
  51. package/lib/wxs/WxsModuleIdsPlugin.js +32 -0
  52. package/lib/wxs/WxsParserPlugin.js +2 -2
  53. package/lib/wxs/WxsPlugin.js +4 -8
  54. package/lib/wxs/WxsTemplatePlugin.js +46 -92
  55. package/lib/wxs/{wxs-i18n-loader.js → i18n-loader.js} +1 -3
  56. package/lib/wxs/{wxs-loader.js → loader.js} +41 -50
  57. package/lib/wxs/{wxs-pre-loader.js → pre-loader.js} +3 -4
  58. package/lib/wxss/loader.js +31 -43
  59. package/lib/wxss/localsLoader.js +1 -5
  60. package/package.json +5 -9
  61. package/lib/built-in-loader.js +0 -49
  62. package/lib/content-loader.js +0 -13
  63. package/lib/dependency/ChildCompileDependency.js +0 -24
  64. package/lib/dependency/InjectDependency.js +0 -26
  65. package/lib/dependency/RemovedModuleDependency.js +0 -23
  66. package/lib/dependency/ResolveDependency.js +0 -49
  67. package/lib/plugin-loader.js +0 -287
  68. package/lib/staticConfig.js +0 -4
  69. package/lib/utils/get-main-compilation.js +0 -6
  70. package/lib/utils/read-json-for-src.js +0 -34
  71. package/lib/utils/try-require.js +0 -16
  72. package/lib/wxss/getImportPrefix.js +0 -30
@@ -0,0 +1,31 @@
1
+ const path = require('path')
2
+
3
+ module.exports = function evalJSONJS (source, filename, loaderContext) {
4
+ const fs = loaderContext._compiler.inputFileSystem
5
+ const defs = loaderContext.getMpx().defs
6
+ const defKeys = Object.keys(defs)
7
+ const defValues = defKeys.map((key) => {
8
+ return defs[key]
9
+ })
10
+ // 记录依赖
11
+ loaderContext.addDependency(filename)
12
+ const dirname = path.dirname(filename)
13
+ // eslint-disable-next-line no-new-func
14
+ const func = new Function('module', 'exports', 'require', '__filename', '__dirname', ...defKeys, source)
15
+ const module = {
16
+ exports: {}
17
+ }
18
+ // 此处采用readFileSync+evalJSONJS而不直接使用require获取依赖内容有两个原因:
19
+ // 1. 支持依赖中正常访问defs变量
20
+ // 2. 避免对应的依赖文件被作为buildDependencies
21
+ func(module, module.exports, function (request) {
22
+ if (request.startsWith('.')) {
23
+ request = path.join(dirname, request)
24
+ }
25
+ const filename = require.resolve(request)
26
+ const source = fs.readFileSync(filename).toString('utf-8')
27
+ return evalJSONJS(source, filename, loaderContext)
28
+ }, filename, dirname, ...defValues)
29
+
30
+ return module.exports
31
+ }
@@ -0,0 +1,13 @@
1
+ module.exports = function (loaderContext) {
2
+ const compilation = loaderContext._compilation
3
+ const moduleGraph = compilation.moduleGraph
4
+ let entryName = ''
5
+ for (const [name, { dependencies }] of compilation.entries) {
6
+ const entryModule = moduleGraph.getModule(dependencies[0])
7
+ if (entryModule.resource === loaderContext.resource) {
8
+ entryName = name
9
+ break
10
+ }
11
+ }
12
+ return entryName
13
+ }
@@ -0,0 +1,41 @@
1
+ const parseRequest = require('./parse-request')
2
+ const evalJSONJS = require('./eval-json-js')
3
+ const resolve = require('./resolve')
4
+ const async = require('async')
5
+ const { JSON_JS_EXT } = require('./const')
6
+
7
+ module.exports = function getJSONContent (json, loaderContext, callback) {
8
+ const fs = loaderContext._compiler.inputFileSystem
9
+ async.waterfall([
10
+ (callback) => {
11
+ if (json.src) {
12
+ resolve(loaderContext.context, json.src, loaderContext, (err, result) => {
13
+ if (err) return callback(err)
14
+ const { rawResourcePath: resourcePath } = parseRequest(result)
15
+ fs.readFile(resourcePath, (err, content) => {
16
+ if (err) return callback(err)
17
+ callback(null, {
18
+ content: content.toString('utf-8'),
19
+ useJSONJS: json.useJSONJS || resourcePath.endsWith(JSON_JS_EXT),
20
+ filename: resourcePath
21
+
22
+ })
23
+ })
24
+ })
25
+ } else {
26
+ callback(null, {
27
+ content: json.content,
28
+ useJSONJS: json.useJSONJS,
29
+ filename: loaderContext.resourcePath
30
+ })
31
+ }
32
+ },
33
+ ({ content, useJSONJS, filename }, callback) => {
34
+ if (!content) return callback(null, '{}')
35
+ if (useJSONJS) {
36
+ content = JSON.stringify(evalJSONJS(content, filename, loaderContext))
37
+ }
38
+ callback(null, content)
39
+ }
40
+ ], callback)
41
+ }
@@ -1,7 +1,7 @@
1
1
  const isUrlRequestRaw = require('loader-utils').isUrlRequest
2
2
  const tagRE = /\{\{((?:.|\n|\r)+?)\}\}(?!})/
3
3
 
4
- module.exports = function isUrlRequest (url, root) {
4
+ module.exports = function isUrlRequest (url, root, externals) {
5
5
  // 对于非字符串或空字符串url直接返回false
6
6
  if (!url || typeof url !== 'string') return false
7
7
  // 对于@开头且后续字符串为合法标识符的情况也返回false,识别为theme变量
@@ -9,5 +9,14 @@ module.exports = function isUrlRequest (url, root) {
9
9
  if (/^.+:\/\//.test(url)) return false
10
10
  // 对于url中存在Mustache插值的情况也返回false
11
11
  if (tagRE.test(url)) return false
12
+ // url存在于externals中也返回false
13
+ if (externals && externals.some((external) => {
14
+ if (typeof external === 'string') {
15
+ return external === url
16
+ } else if (external instanceof RegExp) {
17
+ return external.test(url)
18
+ }
19
+ return false
20
+ })) return false
12
21
  return isUrlRequestRaw(url, root)
13
22
  }
@@ -1,16 +1,3 @@
1
- const fs = require('fs')
2
1
  const path = require('path')
3
2
 
4
3
  exports.lib = file => path.resolve(__dirname, '../', file)
5
-
6
- exports.dep = dep => {
7
- if (
8
- fs.existsSync(path.resolve(__dirname, '../../node_modules', dep))
9
- ) {
10
- // npm 2 or npm linked
11
- return '@mpxjs/webpack-plugin/node_modules/' + dep
12
- } else {
13
- // npm 3
14
- return dep
15
- }
16
- }
@@ -4,7 +4,7 @@ const path = require('path')
4
4
 
5
5
  function genQueryObj (result) {
6
6
  // 避免外部修改queryObj影响缓存
7
- result.queryObj = parseQuery(result.resourceQuery)
7
+ result.queryObj = parseQuery(result.resourceQuery || '?')
8
8
  return result
9
9
  }
10
10
 
@@ -16,13 +16,13 @@ module.exports = function parseRequest (request) {
16
16
  let resource = elements.pop()
17
17
  let loaderString = elements.join('!')
18
18
  let resourcePath = resource
19
- let resourceQuery = '?'
19
+ let resourceQuery = ''
20
20
  const queryIndex = resource.indexOf('?')
21
21
  if (queryIndex >= 0) {
22
22
  resourcePath = resource.slice(0, queryIndex)
23
23
  resourceQuery = resource.slice(queryIndex)
24
24
  }
25
- const queryObj = parseQuery(resourceQuery)
25
+ const queryObj = parseQuery(resourceQuery || '?')
26
26
  const rawResourcePath = resourcePath
27
27
  if (queryObj.resourcePath) {
28
28
  resourcePath = queryObj.resourcePath
@@ -0,0 +1,13 @@
1
+ const parseRequest = require('./parse-request')
2
+ const { RESOLVE_IGNORED_ERR } = require('./const')
3
+
4
+ // todo 提供不记录dependency的resolve方法,非必要的情况下不记录dependency,提升缓存利用率
5
+ module.exports = (context, request, loaderContext, callback) => {
6
+ const { queryObj } = parseRequest(request)
7
+ context = queryObj.context || context
8
+ return loaderContext.resolve(context, request, (err, resource, info) => {
9
+ if (err) return callback(err)
10
+ if (resource === false) return callback(RESOLVE_IGNORED_ERR)
11
+ callback(null, resource, info)
12
+ })
13
+ }
@@ -0,0 +1,47 @@
1
+ module.exports = {
2
+ every (set, fn) {
3
+ for (const item of set) {
4
+ if (!fn(item)) return false
5
+ }
6
+ return true
7
+ },
8
+ has (set, fn) {
9
+ for (const item of set) {
10
+ if (fn(item)) return true
11
+ }
12
+ return false
13
+ },
14
+ map (set, fn) {
15
+ const result = new Set()
16
+ set.forEach((item) => {
17
+ result.add(fn(item))
18
+ })
19
+ return result
20
+ },
21
+ filter (set, fn) {
22
+ const result = new Set()
23
+ set.forEach((item) => {
24
+ if (fn(item)) {
25
+ result.add(item)
26
+ }
27
+ })
28
+ return result
29
+ },
30
+ concat (setA, setB) {
31
+ const result = new Set()
32
+ setA.forEach((item) => {
33
+ result.add(item)
34
+ })
35
+ setB.forEach((item) => {
36
+ result.add(item)
37
+ })
38
+ return result
39
+ },
40
+ mapToArr (set, fn) {
41
+ const result = []
42
+ set.forEach((item) => {
43
+ result.push(fn(item))
44
+ })
45
+ return result
46
+ }
47
+ }
@@ -0,0 +1,25 @@
1
+ const loaderToIdent = data => {
2
+ if (!data.options) {
3
+ return data.loader
4
+ }
5
+ if (typeof data.options === 'string') {
6
+ return data.loader + '?' + data.options
7
+ }
8
+ if (typeof data.options !== 'object') {
9
+ throw new Error('loader options must be string or object')
10
+ }
11
+ if (data.ident) {
12
+ return data.loader + '??' + data.ident
13
+ }
14
+ return data.loader + '?' + JSON.stringify(data.options)
15
+ }
16
+
17
+ const stringifyLoadersAndResource = (loaders, resource) => {
18
+ let str = ''
19
+ for (const loader of loaders) {
20
+ str += loaderToIdent(loader) + '!'
21
+ }
22
+ return str + resource
23
+ }
24
+
25
+ module.exports = stringifyLoadersAndResource
@@ -16,6 +16,10 @@ function stringifyQuery (obj, useJSON) {
16
16
  return
17
17
  }
18
18
 
19
+ if (val === true) {
20
+ return key
21
+ }
22
+
19
23
  if (Array.isArray(val)) {
20
24
  const key2 = `${key}[]`
21
25
  const result = []
@@ -6,28 +6,30 @@ const parseRequest = require('../utils/parse-request')
6
6
  const toPosix = require('../utils/to-posix')
7
7
  const addQuery = require('../utils/add-query')
8
8
  const parseComponent = require('../parser')
9
- const readJsonForSrc = require('../utils/read-json-for-src')
10
- const isUrlRequest = require('../utils/is-url-request')
9
+ const getJSONContent = require('../utils/get-json-content')
10
+ const resolve = require('../utils/resolve')
11
+ const createJSONHelper = require('../json-compiler/helper')
12
+ const { RESOLVE_IGNORED_ERR } = require('../utils/const')
13
+ const RecordResourceMapDependency = require('../dependencies/RecordResourceMapDependency')
11
14
 
12
- module.exports = function (json, options, rawCallback) {
13
- const mode = options.mode
14
- const env = options.env
15
- const defs = options.defs
16
- const loaderContext = options.loaderContext
17
- const resolveMode = options.resolveMode
18
- const pagesMap = options.pagesMap
19
- const componentsMap = options.componentsMap
20
- const pagesEntryMap = options.pagesEntryMap
21
- const projectRoot = options.projectRoot
22
- const pathHash = options.pathHash
15
+ module.exports = function (json, {
16
+ loaderContext,
17
+ pagesMap,
18
+ componentsMap
19
+ }, rawCallback) {
23
20
  const localPagesMap = {}
24
21
  const localComponentsMap = {}
25
- const buildInfo = loaderContext._module.buildInfo
26
-
27
22
  let output = '/* json */\n'
28
23
  let jsonObj = {}
29
24
  let tabBarMap
30
25
  let tabBarStr
26
+ const mpx = loaderContext.getMpx()
27
+ const {
28
+ mode,
29
+ env,
30
+ projectRoot
31
+ } = mpx
32
+
31
33
  const context = loaderContext.context
32
34
 
33
35
  const emitWarning = (msg) => {
@@ -37,13 +39,31 @@ module.exports = function (json, options, rawCallback) {
37
39
  }
38
40
 
39
41
  const emitError = (msg) => {
40
- this.emitError(
41
- new Error('[json compiler][' + this.resource + ']: ' + msg)
42
+ loaderContext.emitError(
43
+ new Error('[json compiler][' + loaderContext.resource + ']: ' + msg)
42
44
  )
43
45
  }
44
46
 
45
47
  const stringifyRequest = r => loaderUtils.stringifyRequest(loaderContext, r)
46
48
 
49
+ const {
50
+ isUrlRequest,
51
+ urlToRequest,
52
+ processPage,
53
+ processComponent
54
+ } = createJSONHelper({
55
+ loaderContext,
56
+ emitWarning,
57
+ emitError,
58
+ customGetDynamicEntry (resource, type, outputPath, packageRoot) {
59
+ return {
60
+ resource,
61
+ outputPath: toPosix(path.join(packageRoot, outputPath)),
62
+ packageRoot
63
+ }
64
+ }
65
+ })
66
+
47
67
  const callback = (err) => {
48
68
  return rawCallback(err, {
49
69
  output,
@@ -67,12 +87,6 @@ module.exports = function (json, options, rawCallback) {
67
87
 
68
88
  const fs = loaderContext._compiler.inputFileSystem
69
89
 
70
- const resolve = (context, request, callback) => {
71
- const { queryObj } = parseRequest(request)
72
- context = queryObj.context || context
73
- return loaderContext.resolve(context, request, callback)
74
- }
75
-
76
90
  const defaultTabbar = {
77
91
  borderStyle: 'black',
78
92
  position: 'bottom',
@@ -90,7 +104,7 @@ module.exports = function (json, options, rawCallback) {
90
104
  tabBarStr = JSON.stringify(tabBar)
91
105
  tabBarStr = tabBarStr.replace(/"(iconPath|selectedIconPath)":"([^"]+)"/g, function (matched, $1, $2) {
92
106
  if (isUrlRequest($2, projectRoot)) {
93
- return `"${$1}":require(${stringifyRequest(loaderUtils.urlToRequest($2, projectRoot))})`
107
+ return `"${$1}":require(${stringifyRequest(urlToRequest($2, projectRoot))})`
94
108
  }
95
109
  return matched
96
110
  })
@@ -100,45 +114,37 @@ module.exports = function (json, options, rawCallback) {
100
114
 
101
115
  const processPackages = (packages, context, callback) => {
102
116
  if (packages) {
103
- async.forEach(packages, (packagePath, callback) => {
104
- const parsed = parseRequest(packagePath)
105
- const queryObj = parsed.queryObj
106
- // readFile无法处理query
107
- packagePath = parsed.resourcePath
117
+ async.each(packages, (packagePath, callback) => {
118
+ const { queryObj } = parseRequest(packagePath)
108
119
  async.waterfall([
109
120
  (callback) => {
110
- resolve(context, packagePath, (err, result) => {
111
- callback(err, result)
121
+ resolve(context, packagePath, loaderContext, (err, result) => {
122
+ if (err) return callback(err)
123
+ const { rawResourcePath } = parseRequest(result)
124
+ callback(err, rawResourcePath)
112
125
  })
113
126
  },
114
127
  (result, callback) => {
115
- loaderContext.addDependency(result)
116
128
  fs.readFile(result, (err, content) => {
117
129
  if (err) return callback(err)
118
130
  callback(err, result, content.toString('utf-8'))
119
131
  })
120
132
  },
121
133
  (result, content, callback) => {
122
- const filePath = result
123
- const extName = path.extname(filePath)
134
+ const extName = path.extname(result)
124
135
  if (extName === '.mpx' || extName === '.vue') {
125
136
  const parts = parseComponent(content, {
126
- filePath,
137
+ filePath: result,
127
138
  needMap: loaderContext.sourceMap,
128
139
  mode,
129
- defs,
130
140
  env
131
141
  })
132
- const json = parts.json || {}
133
- if (json.content) {
134
- content = json.content
135
- } else if (json.src) {
136
- return readJsonForSrc(json.src, loaderContext, (content) => {
137
- callback(null, result, content)
138
- })
139
- }
142
+ getJSONContent(parts.json || {}, loaderContext, (err, content) => {
143
+ callback(err, result, content)
144
+ })
145
+ } else {
146
+ callback(null, result, content)
140
147
  }
141
- callback(null, result, content)
142
148
  },
143
149
  (result, content, callback) => {
144
150
  try {
@@ -159,12 +165,17 @@ module.exports = function (json, options, rawCallback) {
159
165
  pages: content.pages,
160
166
  ...queryObj
161
167
  }
168
+
169
+ if (content.plugins) {
170
+ subPackage.plugins = content.plugins
171
+ }
172
+
162
173
  processSelfQueue.push((callback) => {
163
174
  processSubPackage(subPackage, context, callback)
164
175
  })
165
176
  } else {
166
177
  processSelfQueue.push((callback) => {
167
- processPages(content.pages, '', '', context, callback)
178
+ processPages(content.pages, context, '', callback)
168
179
  })
169
180
  }
170
181
  }
@@ -179,77 +190,41 @@ module.exports = function (json, options, rawCallback) {
179
190
  callback()
180
191
  }
181
192
  }
182
- ], callback)
193
+ ], (err) => {
194
+ callback(err === RESOLVE_IGNORED_ERR ? null : err)
195
+ })
183
196
  }, callback)
184
197
  } else {
185
198
  callback()
186
199
  }
187
200
  }
188
201
 
189
- const getPageName = (resourcePath, ext) => {
190
- const baseName = path.basename(resourcePath, ext)
191
- return path.join('pages', baseName + pathHash(resourcePath), baseName)
192
- }
202
+ const pageKeySet = new Set()
193
203
 
194
- const processPages = (pages, srcRoot = '', tarRoot = '', context, callback) => {
204
+ const processPages = (pages, context, tarRoot = '', callback) => {
195
205
  if (pages) {
196
- context = path.join(context, srcRoot)
197
- async.forEach(pages, (page, callback) => {
198
- let aliasPath = ''
199
- if (typeof page !== 'string') {
200
- aliasPath = page.path
201
- page = page.src
202
- }
203
- if (!isUrlRequest(page, projectRoot)) return callback()
204
- if (resolveMode === 'native') {
205
- page = loaderUtils.urlToRequest(page, projectRoot)
206
- }
207
- resolve(context, page, (err, resource) => {
208
- if (err) return callback(err)
206
+ async.each(pages, (page, callback) => {
207
+ processPage(page, context, tarRoot, (err, { resource, outputPath } = {}, { isFirst, key } = {}) => {
208
+ if (err) return callback(err === RESOLVE_IGNORED_ERR ? null : err)
209
+ if (pageKeySet.has(key)) return callback()
210
+ pageKeySet.add(key)
209
211
  const { resourcePath, queryObj } = parseRequest(resource)
210
- const ext = path.extname(resourcePath)
211
- // 获取pageName
212
- let pageName
213
- if (aliasPath) {
214
- pageName = toPosix(path.join(tarRoot, aliasPath))
215
- // 判断 key 存在重复情况直接报错
216
- for (let key in pagesMap) {
217
- if (pagesMap[key] === pageName && key !== resourcePath) {
218
- emitError(`Current page [${resourcePath}] registers a conflict page path [${pageName}] with existed page [${key}], which is not allowed, please rename it!`)
219
- return callback()
220
- }
212
+ if (localPagesMap[outputPath]) {
213
+ const { resourcePath: oldResourcePath } = parseRequest(localPagesMap[outputPath].resource)
214
+ if (oldResourcePath !== resourcePath) {
215
+ const oldOutputPath = outputPath
216
+ outputPath = mpx.getOutputPath(resourcePath, 'page', { conflictPath: outputPath })
217
+ emitWarning(new Error(`Current page [${resourcePath}] is registered with a conflict outputPath [${oldOutputPath}] which is already existed in system, will be renamed with [${outputPath}], use ?resolve to get the real outputPath!`))
221
218
  }
222
- } else {
223
- const relative = path.relative(context, resourcePath)
224
- if (/^\./.test(relative)) {
225
- // 如果当前page不存在于context中,对其进行重命名
226
- pageName = toPosix(path.join(tarRoot, getPageName(resourcePath, ext)))
227
- emitWarning(`Current page [${resourcePath}] is not in current pages directory [${context}], the page path will be replaced with [${pageName}], use ?resolve to get the page path and navigate to it!`)
228
- } else {
229
- pageName = toPosix(path.join(tarRoot, /^(.*?)(\.[^.]*)?$/.exec(relative)[1]))
230
- // 如果当前page与已有page存在命名冲突,也进行重命名
231
- for (let key in pagesMap) {
232
- // 此处引入pagesEntryMap确保相同entry下路由路径重复注册才报错,不同entry下的路由路径重复则无影响
233
- if (pagesMap[key] === pageName && key !== resourcePath && pagesEntryMap[key] === loaderContext.resourcePath) {
234
- const pageNameRaw = pageName
235
- pageName = toPosix(path.join(tarRoot, getPageName(resourcePath, ext)))
236
- emitWarning(`Current page [${resourcePath}] is registered with a conflict page path [${pageNameRaw}] which is already existed in system, the page path will be replaced with [${pageName}], use ?resolve to get the page path and navigate to it!`)
237
- break
238
- }
239
- }
240
- }
241
- }
242
- if (pagesMap[resourcePath]) {
243
- emitWarning(`Current page [${resourcePath}] which is imported from [${loaderContext.resourcePath}] has been registered in pagesMap already, it will be ignored, please check it and remove the redundant page declaration!`)
244
- return callback()
245
219
  }
246
- buildInfo.pagesMap = buildInfo.pagesMap || {}
247
- buildInfo.pagesMap[resourcePath] = pagesMap[resourcePath] = pageName
248
- pagesEntryMap[resourcePath] = loaderContext.resourcePath
249
- localPagesMap[pageName] = {
250
- resource: addQuery(resource, { page: true }),
220
+
221
+ pagesMap[resourcePath] = outputPath
222
+ loaderContext._module.addPresentationalDependency(new RecordResourceMapDependency(resourcePath, 'page', outputPath))
223
+
224
+ localPagesMap[outputPath] = {
225
+ resource: addQuery(resource, { isPage: true }),
251
226
  async: tarRoot || queryObj.async,
252
- isFirst: queryObj.isFirst
227
+ isFirst
253
228
  }
254
229
  callback()
255
230
  })
@@ -261,10 +236,15 @@ module.exports = function (json, options, rawCallback) {
261
236
 
262
237
  const processSubPackage = (subPackage, context, callback) => {
263
238
  if (subPackage) {
239
+ if (typeof subPackage.root === 'string' && subPackage.root.startsWith('.')) {
240
+ emitError(`Current subpackage root [${subPackage.root}] is not allow starts with '.'`)
241
+ return callback()
242
+ }
264
243
  let tarRoot = subPackage.tarRoot || subPackage.root || ''
265
244
  let srcRoot = subPackage.srcRoot || subPackage.root || ''
266
245
  if (!tarRoot) return callback()
267
- processPages(subPackage.pages, srcRoot, tarRoot, context, callback)
246
+ context = path.join(context, srcRoot)
247
+ processPages(subPackage.pages, context, tarRoot, callback)
268
248
  } else {
269
249
  callback()
270
250
  }
@@ -272,7 +252,7 @@ module.exports = function (json, options, rawCallback) {
272
252
 
273
253
  const processSubPackages = (subPackages, context, callback) => {
274
254
  if (subPackages) {
275
- async.forEach(subPackages, (subPackage, callback) => {
255
+ async.each(subPackages, (subPackage, callback) => {
276
256
  processSubPackage(subPackage, context, callback)
277
257
  }, callback)
278
258
  } else {
@@ -282,48 +262,38 @@ module.exports = function (json, options, rawCallback) {
282
262
 
283
263
  const processComponents = (components, context, callback) => {
284
264
  if (components) {
285
- async.forEachOf(components, (component, name, callback) => {
286
- processComponent(component, name, context, callback)
265
+ async.eachOf(components, (component, name, callback) => {
266
+ processComponent(component, context, {}, (err, { resource, outputPath } = {}) => {
267
+ if (err === RESOLVE_IGNORED_ERR) {
268
+ return callback()
269
+ }
270
+ const { resourcePath, queryObj } = parseRequest(resource)
271
+ componentsMap[resourcePath] = outputPath
272
+ loaderContext._module.addPresentationalDependency(new RecordResourceMapDependency(resourcePath, 'component', outputPath))
273
+
274
+ localComponentsMap[name] = {
275
+ resource: addQuery(resource, {
276
+ isComponent: true,
277
+ outputPath
278
+ }),
279
+ async: queryObj.async
280
+ }
281
+ callback()
282
+ })
287
283
  }, callback)
288
284
  } else {
289
285
  callback()
290
286
  }
291
287
  }
292
288
 
293
- const processComponent = (component, name, context, callback) => {
294
- if (!isUrlRequest(component, projectRoot)) return callback()
295
-
296
- if (resolveMode === 'native') {
297
- component = loaderUtils.urlToRequest(component, projectRoot)
298
- }
299
-
300
- resolve(context, component, (err, resource) => {
301
- if (err) return callback(err)
302
- const { resourcePath, queryObj } = parseRequest(resource)
303
- const parsed = path.parse(resourcePath)
304
- const componentId = parsed.name + pathHash(resourcePath)
305
-
306
- buildInfo.packageName = 'main'
307
- buildInfo.componentsMap = buildInfo.componentsMap || {}
308
- buildInfo.componentsMap[resourcePath] = componentsMap[resourcePath] = componentId
309
-
310
- localComponentsMap[name] = {
311
- resource: addQuery(resource, { component: true, componentId }),
312
- async: queryObj.async
313
- }
314
- callback()
315
- })
316
- }
317
-
318
289
  const processGenerics = (generics, context, callback) => {
319
290
  if (generics) {
320
- async.forEachOf(generics, (generic, name, callback) => {
321
- if (generic.default) {
322
- processComponent(generic.default, `${name}default`, context, callback)
323
- } else {
324
- callback()
325
- }
326
- }, callback)
291
+ const genericsComponents = {}
292
+ Object.keys(generics).forEach((name) => {
293
+ const generic = generics[name]
294
+ if (generic.default) genericsComponents[`${name}default`] = generic.default
295
+ })
296
+ processComponents(genericsComponents, context, callback)
327
297
  } else {
328
298
  callback()
329
299
  }
@@ -331,6 +301,7 @@ module.exports = function (json, options, rawCallback) {
331
301
 
332
302
  async.parallel([
333
303
  (callback) => {
304
+ // 添加首页标识
334
305
  if (jsonObj.pages && jsonObj.pages[0]) {
335
306
  if (typeof jsonObj.pages[0] !== 'string') {
336
307
  jsonObj.pages[0].src = addQuery(jsonObj.pages[0].src, { isFirst: true })
@@ -338,7 +309,7 @@ module.exports = function (json, options, rawCallback) {
338
309
  jsonObj.pages[0] = addQuery(jsonObj.pages[0], { isFirst: true })
339
310
  }
340
311
  }
341
- processPages(jsonObj.pages, '', '', context, callback)
312
+ processPages(jsonObj.pages, context, '', callback)
342
313
  },
343
314
  (callback) => {
344
315
  processComponents(jsonObj.usingComponents, context, callback)