@mpxjs/webpack-plugin 2.7.0-alpha.0 → 2.7.0-alpha.2
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/README.md +1 -1
- package/lib/config.js +14 -0
- package/lib/dependencies/AddEntryDependency.js +24 -0
- package/lib/dependencies/AppEntryDependency.js +2 -0
- package/lib/dependencies/CommonJsAsyncDependency.js +51 -0
- package/lib/dependencies/CommonJsVariableDependency.js +13 -6
- package/lib/dependencies/DynamicEntryDependency.js +85 -41
- package/lib/dependencies/FlagPluginDependency.js +1 -0
- package/lib/dependencies/RecordIndependentDependency.js +44 -0
- package/lib/dependencies/RecordResourceMapDependency.js +62 -0
- package/lib/dependencies/RemoveEntryDependency.js +40 -0
- package/lib/dependencies/ResolveDependency.js +11 -6
- package/lib/extractor.js +17 -7
- package/lib/file-loader.js +2 -2
- package/lib/helpers.js +6 -12
- package/lib/independent-loader.js +52 -0
- package/lib/index.js +595 -304
- package/lib/json-compiler/helper.js +36 -32
- package/lib/json-compiler/index.js +119 -66
- package/lib/json-compiler/plugin.js +23 -7
- package/lib/loader.js +135 -90
- package/lib/native-loader.js +37 -69
- package/lib/parser.js +1 -2
- package/lib/partial-compile/index.js +35 -0
- package/lib/platform/json/wx/index.js +8 -3
- package/lib/platform/template/normalize-component-rules.js +2 -3
- package/lib/platform/template/wx/component-config/button.js +17 -5
- package/lib/platform/template/wx/component-config/image.js +4 -0
- package/lib/platform/template/wx/component-config/input.js +4 -0
- package/lib/platform/template/wx/component-config/navigator.js +1 -1
- package/lib/platform/template/wx/component-config/rich-text.js +4 -0
- package/lib/platform/template/wx/component-config/scroll-view.js +4 -0
- package/lib/platform/template/wx/component-config/switch.js +4 -0
- package/lib/platform/template/wx/component-config/text.js +4 -0
- package/lib/platform/template/wx/component-config/textarea.js +5 -0
- package/lib/platform/template/wx/component-config/view.js +4 -0
- package/lib/platform/template/wx/index.js +149 -3
- package/lib/record-loader.js +2 -2
- package/lib/resolve-loader.js +4 -1
- package/lib/resolver/AddEnvPlugin.js +4 -3
- package/lib/resolver/AddModePlugin.js +4 -3
- package/lib/resolver/FixDescriptionInfoPlugin.js +28 -0
- package/lib/resolver/PackageEntryPlugin.js +23 -36
- package/lib/runtime/base.styl +5 -0
- package/lib/runtime/components/tenon/getInnerListeners.js +317 -0
- package/lib/runtime/components/tenon/tenon-button.vue +305 -0
- package/lib/runtime/components/tenon/tenon-image.vue +61 -0
- package/lib/runtime/components/tenon/tenon-input.vue +99 -0
- package/lib/runtime/components/tenon/tenon-rich-text.vue +21 -0
- package/lib/runtime/components/tenon/tenon-scroll-view.vue +124 -0
- package/lib/runtime/components/tenon/tenon-switch.vue +91 -0
- package/lib/runtime/components/tenon/tenon-text-area.vue +64 -0
- package/lib/runtime/components/tenon/tenon-text.vue +64 -0
- package/lib/runtime/components/tenon/tenon-view.vue +93 -0
- package/lib/runtime/components/tenon/util.js +44 -0
- package/lib/runtime/components/web/getInnerListeners.js +51 -45
- package/lib/runtime/components/web/mpx-image.vue +20 -5
- package/lib/runtime/components/web/mpx-keep-alive.vue +4 -1
- package/lib/runtime/components/web/mpx-movable-view.vue +6 -2
- package/lib/runtime/components/web/mpx-swiper.vue +37 -8
- package/lib/runtime/components/web/mpx-tab-bar-container.vue +2 -2
- package/lib/runtime/components/web/mpx-textarea.vue +1 -1
- package/lib/runtime/i18n.wxs +28 -8
- package/lib/runtime/optionProcessor.js +50 -20
- package/lib/runtime/optionProcessor.tenon.js +386 -0
- package/lib/runtime/stringify.wxs +6 -4
- package/lib/selector.js +23 -5
- package/lib/style-compiler/index.js +12 -13
- package/lib/style-compiler/load-postcss-config.js +3 -1
- package/lib/style-compiler/plugins/conditional-strip.js +68 -65
- package/lib/style-compiler/plugins/hm.js +20 -0
- package/lib/style-compiler/plugins/rpx.js +43 -37
- package/lib/style-compiler/plugins/scope-id.js +79 -72
- package/lib/style-compiler/plugins/trans-special.js +25 -18
- package/lib/style-compiler/plugins/trim.js +13 -7
- package/lib/style-compiler/plugins/vw.js +19 -12
- package/lib/template-compiler/bind-this.js +4 -4
- package/lib/template-compiler/compiler.js +172 -62
- package/lib/template-compiler/index.js +8 -9
- package/lib/template-compiler/trans-dynamic-class-expr.js +32 -22
- package/lib/tenon/index.js +105 -0
- package/lib/tenon/processJSON.js +356 -0
- package/lib/tenon/processScript.js +261 -0
- package/lib/tenon/processStyles.js +21 -0
- package/lib/tenon/processTemplate.js +133 -0
- package/lib/utils/const.js +6 -1
- package/lib/utils/eval-json-js.js +31 -0
- package/lib/utils/get-entry-name.js +3 -3
- package/lib/utils/get-json-content.js +42 -0
- package/lib/utils/get-relative-path.js +25 -0
- package/lib/utils/match-condition.js +4 -1
- package/lib/utils/normalize.js +4 -2
- package/lib/utils/resolve.js +13 -0
- package/lib/web/processJSON.js +113 -144
- package/lib/web/processScript.js +45 -38
- package/lib/web/processTemplate.js +56 -41
- package/lib/wxml/loader.js +1 -6
- package/lib/wxs/WxsModuleIdsPlugin.js +11 -14
- package/lib/wxs/i18n-loader.js +5 -4
- package/lib/wxs/loader.js +87 -56
- package/lib/wxs/pre-loader.js +30 -10
- package/lib/wxss/loader.js +3 -3
- package/lib/wxss/processCss.js +135 -131
- package/package.json +23 -17
- package/lib/built-in-loader.js +0 -49
- package/lib/dependencies/RecordStaticResourceDependency.js +0 -47
- package/lib/utils/get-main-compilation.js +0 -6
- package/lib/utils/read-json-for-src.js +0 -34
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')
|
|
@@ -11,27 +11,38 @@ const processJSON = require('./web/processJSON')
|
|
|
11
11
|
const processScript = require('./web/processScript')
|
|
12
12
|
const processStyles = require('./web/processStyles')
|
|
13
13
|
const processTemplate = require('./web/processTemplate')
|
|
14
|
-
const
|
|
14
|
+
const processForTenon = require('./tenon/index')
|
|
15
|
+
const getJSONContent = require('./utils/get-json-content')
|
|
15
16
|
const normalize = require('./utils/normalize')
|
|
16
17
|
const getEntryName = require('./utils/get-entry-name')
|
|
17
18
|
const AppEntryDependency = require('./dependencies/AppEntryDependency')
|
|
19
|
+
const RecordResourceMapDependency = require('./dependencies/RecordResourceMapDependency')
|
|
20
|
+
const CommonJsVariableDependency = require('./dependencies/CommonJsVariableDependency')
|
|
21
|
+
const { MPX_APP_MODULE_ID } = require('./utils/const')
|
|
22
|
+
const path = require('path')
|
|
18
23
|
|
|
19
24
|
module.exports = function (content) {
|
|
20
25
|
this.cacheable()
|
|
21
26
|
|
|
27
|
+
// 兼容处理处理ts-loader中watch-run/updateFile逻辑,直接跳过当前loader及后续的vue-loader返回内容
|
|
28
|
+
if (path.extname(this.resourcePath) === '.ts') {
|
|
29
|
+
this.loaderIndex -= 2
|
|
30
|
+
return content
|
|
31
|
+
}
|
|
32
|
+
|
|
22
33
|
const mpx = this.getMpx()
|
|
23
34
|
if (!mpx) {
|
|
24
35
|
return content
|
|
25
36
|
}
|
|
26
37
|
const { resourcePath, queryObj } = parseRequest(this.resource)
|
|
27
|
-
|
|
38
|
+
|
|
39
|
+
const packageRoot = queryObj.packageRoot || mpx.currentPackageRoot
|
|
40
|
+
const packageName = packageRoot || 'main'
|
|
41
|
+
const independent = queryObj.independent
|
|
28
42
|
const pagesMap = mpx.pagesMap
|
|
29
43
|
const componentsMap = mpx.componentsMap[packageName]
|
|
30
|
-
const resolveMode = mpx.resolveMode
|
|
31
|
-
const projectRoot = mpx.projectRoot
|
|
32
44
|
const mode = mpx.mode
|
|
33
45
|
const env = mpx.env
|
|
34
|
-
const defs = mpx.defs
|
|
35
46
|
const i18n = mpx.i18n
|
|
36
47
|
const globalSrcMode = mpx.srcMode
|
|
37
48
|
const localSrcMode = queryObj.mode
|
|
@@ -39,16 +50,6 @@ module.exports = function (content) {
|
|
|
39
50
|
const vueContentCache = mpx.vueContentCache
|
|
40
51
|
const autoScope = matchCondition(resourcePath, mpx.autoScopeRules)
|
|
41
52
|
|
|
42
|
-
// 支持资源query传入page或component支持页面/组件单独编译
|
|
43
|
-
if ((queryObj.component && !componentsMap[resourcePath]) || (queryObj.page && !pagesMap[resourcePath])) {
|
|
44
|
-
const entryName = getEntryName(this)
|
|
45
|
-
if (queryObj.component) {
|
|
46
|
-
componentsMap[resourcePath] = entryName || 'noEntryComponent'
|
|
47
|
-
} else {
|
|
48
|
-
pagesMap[resourcePath] = entryName || 'noEntryPage'
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
53
|
let ctorType = 'app'
|
|
53
54
|
if (pagesMap[resourcePath]) {
|
|
54
55
|
// page
|
|
@@ -58,42 +59,40 @@ module.exports = function (content) {
|
|
|
58
59
|
ctorType = 'component'
|
|
59
60
|
}
|
|
60
61
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
this
|
|
62
|
+
// 支持资源query传入isPage或isComponent支持页面/组件单独编译
|
|
63
|
+
if (ctorType === 'app' && (queryObj.isComponent || queryObj.isPage)) {
|
|
64
|
+
const entryName = getEntryName(this) || (queryObj.isComponent ? 'noEntryComponent' : 'noEntryPage')
|
|
65
|
+
ctorType = queryObj.isComponent ? 'component' : 'page'
|
|
66
|
+
this._module.addPresentationalDependency(new RecordResourceMapDependency(resourcePath, ctorType, entryName, packageRoot))
|
|
64
67
|
}
|
|
65
68
|
|
|
66
69
|
const loaderContext = this
|
|
67
70
|
const stringifyRequest = r => loaderUtils.stringifyRequest(loaderContext, r)
|
|
68
71
|
const isProduction = this.minimize || process.env.NODE_ENV === 'production'
|
|
69
|
-
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
const moduleId = 'm' + mpx.pathHash(filePath)
|
|
72
|
+
const filePath = this.resourcePath
|
|
73
|
+
const moduleId = ctorType === 'app' ? MPX_APP_MODULE_ID : 'm' + mpx.pathHash(filePath)
|
|
73
74
|
|
|
74
75
|
const parts = parseComponent(content, {
|
|
75
76
|
filePath,
|
|
76
77
|
needMap: this.sourceMap,
|
|
77
78
|
mode,
|
|
78
|
-
defs,
|
|
79
79
|
env
|
|
80
80
|
})
|
|
81
81
|
|
|
82
|
+
const {
|
|
83
|
+
getRequire
|
|
84
|
+
} = createHelpers(loaderContext)
|
|
85
|
+
|
|
82
86
|
let output = ''
|
|
83
87
|
const callback = this.async()
|
|
84
88
|
|
|
85
89
|
async.waterfall([
|
|
86
90
|
(callback) => {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if (err) return callback(err)
|
|
91
|
-
json.content = result
|
|
92
|
-
callback()
|
|
93
|
-
})
|
|
94
|
-
} else {
|
|
91
|
+
getJSONContent(parts.json || {}, loaderContext, (err, content) => {
|
|
92
|
+
if (err) return callback(err)
|
|
93
|
+
if (parts.json) parts.json.content = content
|
|
95
94
|
callback()
|
|
96
|
-
}
|
|
95
|
+
})
|
|
97
96
|
},
|
|
98
97
|
(callback) => {
|
|
99
98
|
// web输出模式下没有任何inject,可以通过cache直接返回,由于读取src json可能会新增模块依赖,需要在之后返回缓存内容
|
|
@@ -124,12 +123,51 @@ module.exports = function (content) {
|
|
|
124
123
|
}
|
|
125
124
|
}
|
|
126
125
|
|
|
127
|
-
|
|
128
|
-
if (mode === 'web') {
|
|
126
|
+
if (mode === 'tenon') {
|
|
129
127
|
if (ctorType === 'app' && !queryObj.app) {
|
|
130
128
|
const request = addQuery(this.resource, { app: true })
|
|
131
129
|
output += `
|
|
132
130
|
import App from ${stringifyRequest(request)}
|
|
131
|
+
import * as Tenon from '@hummer/tenon-vue'
|
|
132
|
+
|
|
133
|
+
Tenon.render(App)\n`
|
|
134
|
+
// 直接结束loader进入parse
|
|
135
|
+
this.loaderIndex = -1
|
|
136
|
+
return callback(null, output)
|
|
137
|
+
}
|
|
138
|
+
if (ctorType === 'page' && queryObj.tenon) {
|
|
139
|
+
console.log(resourcePath)
|
|
140
|
+
const request = addQuery(resourcePath, { page: true })
|
|
141
|
+
output += `
|
|
142
|
+
import page from ${stringifyRequest(request)}
|
|
143
|
+
import * as Tenon from '@hummer/tenon-vue'
|
|
144
|
+
|
|
145
|
+
Tenon.render(page)\n`
|
|
146
|
+
this.loaderIndex = -1
|
|
147
|
+
return callback(null, output)
|
|
148
|
+
}
|
|
149
|
+
return processForTenon({
|
|
150
|
+
mpx,
|
|
151
|
+
loaderContext,
|
|
152
|
+
isProduction,
|
|
153
|
+
queryObj,
|
|
154
|
+
filePath,
|
|
155
|
+
parts,
|
|
156
|
+
ctorType,
|
|
157
|
+
autoScope,
|
|
158
|
+
componentsMap,
|
|
159
|
+
vueContentCache,
|
|
160
|
+
moduleId,
|
|
161
|
+
callback
|
|
162
|
+
})
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// 处理mode为web时输出vue格式文件
|
|
166
|
+
if (mode === 'web') {
|
|
167
|
+
if (ctorType === 'app' && !queryObj.isApp) {
|
|
168
|
+
const request = addQuery(this.resource, { isApp: true })
|
|
169
|
+
output += `
|
|
170
|
+
import App from ${stringifyRequest(request)}
|
|
133
171
|
import Vue from 'vue'
|
|
134
172
|
new Vue({
|
|
135
173
|
el: '#app',
|
|
@@ -148,20 +186,15 @@ module.exports = function (content) {
|
|
|
148
186
|
async.parallel([
|
|
149
187
|
(callback) => {
|
|
150
188
|
processTemplate(parts.template, {
|
|
189
|
+
loaderContext,
|
|
151
190
|
hasScoped,
|
|
152
191
|
hasComment,
|
|
153
192
|
isNative,
|
|
154
|
-
mode,
|
|
155
193
|
srcMode,
|
|
156
|
-
defs,
|
|
157
|
-
loaderContext,
|
|
158
194
|
moduleId,
|
|
159
195
|
ctorType,
|
|
160
196
|
usingComponents,
|
|
161
|
-
componentGenerics
|
|
162
|
-
decodeHTMLText: mpx.decodeHTMLText,
|
|
163
|
-
externalClasses: mpx.externalClasses,
|
|
164
|
-
checkUsingComponents: mpx.checkUsingComponents
|
|
197
|
+
componentGenerics
|
|
165
198
|
}, callback)
|
|
166
199
|
},
|
|
167
200
|
(callback) => {
|
|
@@ -173,16 +206,9 @@ module.exports = function (content) {
|
|
|
173
206
|
},
|
|
174
207
|
(callback) => {
|
|
175
208
|
processJSON(parts.json, {
|
|
176
|
-
mode,
|
|
177
|
-
env,
|
|
178
|
-
defs,
|
|
179
|
-
resolveMode,
|
|
180
209
|
loaderContext,
|
|
181
210
|
pagesMap,
|
|
182
|
-
|
|
183
|
-
pathHash: mpx.pathHash,
|
|
184
|
-
componentsMap,
|
|
185
|
-
projectRoot
|
|
211
|
+
componentsMap
|
|
186
212
|
}, callback)
|
|
187
213
|
}
|
|
188
214
|
], (err, res) => {
|
|
@@ -198,23 +224,20 @@ module.exports = function (content) {
|
|
|
198
224
|
}
|
|
199
225
|
|
|
200
226
|
processScript(parts.script, {
|
|
227
|
+
loaderContext,
|
|
201
228
|
ctorType,
|
|
202
229
|
srcMode,
|
|
203
|
-
loaderContext,
|
|
204
230
|
isProduction,
|
|
205
|
-
i18n,
|
|
206
231
|
componentGenerics,
|
|
207
|
-
projectRoot,
|
|
208
232
|
jsonConfig: jsonRes.jsonObj,
|
|
209
|
-
|
|
233
|
+
outputPath: queryObj.outputPath || '',
|
|
210
234
|
tabBarMap: jsonRes.tabBarMap,
|
|
211
235
|
tabBarStr: jsonRes.tabBarStr,
|
|
212
236
|
builtInComponentsMap: templateRes.builtInComponentsMap,
|
|
213
237
|
genericsInfo: templateRes.genericsInfo,
|
|
214
238
|
wxsModuleMap: templateRes.wxsModuleMap,
|
|
215
239
|
localComponentsMap: jsonRes.localComponentsMap,
|
|
216
|
-
localPagesMap: jsonRes.localPagesMap
|
|
217
|
-
forceDisableBuiltInLoader: mpx.forceDisableBuiltInLoader
|
|
240
|
+
localPagesMap: jsonRes.localPagesMap
|
|
218
241
|
}, callback)
|
|
219
242
|
}
|
|
220
243
|
], (err, scriptRes) => {
|
|
@@ -225,29 +248,48 @@ module.exports = function (content) {
|
|
|
225
248
|
})
|
|
226
249
|
}
|
|
227
250
|
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
|
|
251
|
+
const moduleGraph = this._compilation.moduleGraph
|
|
252
|
+
|
|
253
|
+
const issuer = moduleGraph.getIssuer(this._module)
|
|
254
|
+
|
|
255
|
+
if (issuer) {
|
|
256
|
+
return callback(new Error(`Current ${ctorType} [${this.resourcePath}] is issued by [${issuer.resource}], which is not allowed!`))
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (ctorType === 'app') {
|
|
260
|
+
const appName = getEntryName(this)
|
|
261
|
+
this._module.addPresentationalDependency(new AppEntryDependency(resourcePath, appName))
|
|
262
|
+
}
|
|
231
263
|
|
|
232
264
|
// 注入模块id及资源路径
|
|
233
265
|
output += `global.currentModuleId = ${JSON.stringify(moduleId)}\n`
|
|
234
266
|
if (!isProduction) {
|
|
235
267
|
output += `global.currentResource = ${JSON.stringify(filePath)}\n`
|
|
236
268
|
}
|
|
237
|
-
if (ctorType === 'app' && i18n) {
|
|
238
|
-
output += `global.i18n = ${JSON.stringify({ locale: i18n.locale, version: 0 })}\n`
|
|
239
269
|
|
|
270
|
+
// 为app注入i18n
|
|
271
|
+
if (i18n && ctorType === 'app') {
|
|
240
272
|
const i18nWxsPath = normalize.lib('runtime/i18n.wxs')
|
|
241
273
|
const i18nWxsLoaderPath = normalize.lib('wxs/i18n-loader.js')
|
|
242
274
|
const i18nWxsRequest = i18nWxsLoaderPath + '!' + i18nWxsPath
|
|
275
|
+
this._module.addDependency(new CommonJsVariableDependency(i18nWxsRequest))
|
|
276
|
+
// 避免该模块被concatenate导致注入的i18n没有最先执行
|
|
277
|
+
this._module.buildInfo.moduleConcatenationBailout = 'i18n'
|
|
278
|
+
}
|
|
243
279
|
|
|
244
|
-
|
|
280
|
+
// 为独立分包注入init module
|
|
281
|
+
if (independent && typeof independent === 'string') {
|
|
282
|
+
const independentLoader = normalize.lib('independent-loader.js')
|
|
283
|
+
const independentInitRequest = `!!${independentLoader}!${independent}`
|
|
284
|
+
this._module.addDependency(new CommonJsVariableDependency(independentInitRequest))
|
|
285
|
+
// 避免该模块被concatenate导致注入的independent init没有最先执行
|
|
286
|
+
this._module.buildInfo.moduleConcatenationBailout = 'independent init'
|
|
245
287
|
}
|
|
288
|
+
|
|
246
289
|
// 注入构造函数
|
|
247
290
|
let ctor = 'App'
|
|
248
291
|
if (ctorType === 'page') {
|
|
249
|
-
|
|
250
|
-
if (mpx.forceUsePageCtor || mode === 'ali' || mode === 'swan') {
|
|
292
|
+
if (mpx.forceUsePageCtor || mode === 'ali') {
|
|
251
293
|
ctor = 'Page'
|
|
252
294
|
} else {
|
|
253
295
|
ctor = 'Component'
|
|
@@ -259,6 +301,7 @@ module.exports = function (content) {
|
|
|
259
301
|
output += `global.currentCtorType = ${JSON.stringify(ctor.replace(/^./, (match) => {
|
|
260
302
|
return match.toLowerCase()
|
|
261
303
|
}))}\n`
|
|
304
|
+
output += `global.currentResourceType = ${JSON.stringify(ctorType)}\n`
|
|
262
305
|
|
|
263
306
|
// template
|
|
264
307
|
output += '/* template */\n'
|
|
@@ -266,6 +309,10 @@ module.exports = function (content) {
|
|
|
266
309
|
|
|
267
310
|
if (template) {
|
|
268
311
|
const extraOptions = {
|
|
312
|
+
...template.src ? {
|
|
313
|
+
...queryObj,
|
|
314
|
+
resourcePath
|
|
315
|
+
} : null,
|
|
269
316
|
hasScoped,
|
|
270
317
|
hasComment,
|
|
271
318
|
isNative,
|
|
@@ -286,52 +333,50 @@ module.exports = function (content) {
|
|
|
286
333
|
parts.styles.forEach((style, i) => {
|
|
287
334
|
const scoped = style.scoped || autoScope
|
|
288
335
|
const extraOptions = {
|
|
336
|
+
// style src会被特殊处理为全局复用样式,不添加resourcePath,添加isStatic及issuerFile
|
|
337
|
+
...style.src ? {
|
|
338
|
+
...queryObj,
|
|
339
|
+
isStatic: true,
|
|
340
|
+
issuerResource: addQuery(this.resource, { type: 'styles' }, true)
|
|
341
|
+
} : null,
|
|
289
342
|
moduleId,
|
|
290
343
|
scoped
|
|
291
344
|
}
|
|
292
345
|
// require style
|
|
293
|
-
if (style.src) {
|
|
294
|
-
// style src会被特殊处理为全局复用样式,不添加resourcePath,添加isStatic及issuerResource
|
|
295
|
-
extraOptions.isStatic = true
|
|
296
|
-
extraOptions.issuerFile = mpx.getExtractedFile(this.resource)
|
|
297
|
-
}
|
|
298
346
|
output += getRequire('styles', style, extraOptions, i) + '\n'
|
|
299
347
|
})
|
|
300
|
-
}
|
|
301
|
-
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
if (parts.styles.filter(style => !style.src).length === 0 && ctorType === 'app' && mode === 'ali') {
|
|
351
|
+
output += getRequire('styles', {}, {}, parts.styles.length) + '\n'
|
|
302
352
|
}
|
|
303
353
|
|
|
304
354
|
// json
|
|
305
355
|
output += '/* json */\n'
|
|
306
356
|
// 给予json默认值, 确保生成json request以自动补全json
|
|
307
357
|
const json = parts.json || {}
|
|
308
|
-
output += getRequire('json', json, json.src && {
|
|
358
|
+
output += getRequire('json', json, json.src && {
|
|
359
|
+
...queryObj,
|
|
360
|
+
resourcePath
|
|
361
|
+
}) + '\n'
|
|
309
362
|
|
|
310
363
|
// script
|
|
311
364
|
output += '/* script */\n'
|
|
312
365
|
let scriptSrcMode = srcMode
|
|
313
|
-
|
|
366
|
+
// 给予script默认值, 确保生成js request以自动补全js
|
|
367
|
+
const script = parts.script || {}
|
|
314
368
|
if (script) {
|
|
315
369
|
scriptSrcMode = script.mode || scriptSrcMode
|
|
316
370
|
if (scriptSrcMode) output += `global.currentSrcMode = ${JSON.stringify(scriptSrcMode)}\n`
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
'createApp({})\n'
|
|
325
|
-
break
|
|
326
|
-
case 'page':
|
|
327
|
-
output += 'import {createPage} from "@mpxjs/core"\n' +
|
|
328
|
-
'createPage({})\n'
|
|
329
|
-
break
|
|
330
|
-
case 'component':
|
|
331
|
-
output += 'import {createComponent} from "@mpxjs/core"\n' +
|
|
332
|
-
'createComponent({})\n'
|
|
371
|
+
// 传递ctorType以补全js内容
|
|
372
|
+
const extraOptions = {
|
|
373
|
+
...script.src ? {
|
|
374
|
+
...queryObj,
|
|
375
|
+
resourcePath
|
|
376
|
+
} : null,
|
|
377
|
+
ctorType
|
|
333
378
|
}
|
|
334
|
-
output += '\n'
|
|
379
|
+
output += getRequire('script', script, extraOptions) + '\n'
|
|
335
380
|
}
|
|
336
381
|
callback(null, output)
|
|
337
382
|
}
|
package/lib/native-loader.js
CHANGED
|
@@ -3,10 +3,11 @@ const JSON5 = require('json5')
|
|
|
3
3
|
const parseRequest = require('./utils/parse-request')
|
|
4
4
|
const config = require('./config')
|
|
5
5
|
const createHelpers = require('./helpers')
|
|
6
|
-
const
|
|
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
|
+
const { JSON_JS_EXT } = require('./utils/const')
|
|
10
11
|
|
|
11
12
|
module.exports = function (content) {
|
|
12
13
|
this.cacheable()
|
|
@@ -23,7 +24,6 @@ module.exports = function (content) {
|
|
|
23
24
|
const moduleId = 'm' + mpx.pathHash(filePath)
|
|
24
25
|
const { resourcePath, queryObj } = parseRequest(this.resource)
|
|
25
26
|
const mode = mpx.mode
|
|
26
|
-
const defs = mpx.defs
|
|
27
27
|
const globalSrcMode = mpx.srcMode
|
|
28
28
|
const localSrcMode = queryObj.mode
|
|
29
29
|
const packageName = queryObj.packageRoot || mpx.currentPackageRoot || 'main'
|
|
@@ -33,12 +33,10 @@ module.exports = function (content) {
|
|
|
33
33
|
const resourceName = path.join(parsed.dir, parsed.name)
|
|
34
34
|
const isApp = !(pagesMap[resourcePath] || componentsMap[resourcePath])
|
|
35
35
|
const srcMode = localSrcMode || globalSrcMode
|
|
36
|
-
const fs = this._compiler.inputFileSystem
|
|
37
36
|
const typeExtMap = config[srcMode].typeExtMap
|
|
38
37
|
const typeResourceMap = {}
|
|
39
38
|
const autoScope = matchCondition(resourcePath, mpx.autoScopeRules)
|
|
40
39
|
|
|
41
|
-
const EXT_MPX_JSON = '.json.js'
|
|
42
40
|
const CSS_LANG_EXT_MAP = {
|
|
43
41
|
less: '.less',
|
|
44
42
|
stylus: '.styl',
|
|
@@ -46,40 +44,18 @@ module.exports = function (content) {
|
|
|
46
44
|
scss: '.scss'
|
|
47
45
|
}
|
|
48
46
|
|
|
49
|
-
let
|
|
47
|
+
let useJSONJS = false
|
|
50
48
|
let cssLang = ''
|
|
51
49
|
const hasScoped = (queryObj.scoped || autoScope) && mode === 'ali'
|
|
52
50
|
const hasComment = false
|
|
53
51
|
const isNative = true
|
|
54
52
|
|
|
55
|
-
const tryEvalMPXJSON = (callback) => {
|
|
56
|
-
const { rawResourcePath } = parseRequest(typeResourceMap['json'])
|
|
57
|
-
const _src = rawResourcePath
|
|
58
|
-
this.addDependency(_src)
|
|
59
|
-
fs.readFile(_src, (err, raw) => {
|
|
60
|
-
if (err) {
|
|
61
|
-
callback(err)
|
|
62
|
-
} else {
|
|
63
|
-
try {
|
|
64
|
-
const source = raw.toString('utf-8')
|
|
65
|
-
const text = mpxJSON.compileMPXJSONText({ source, defs, filePath: _src })
|
|
66
|
-
callback(null, text)
|
|
67
|
-
} catch (e) {
|
|
68
|
-
callback(e)
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
})
|
|
72
|
-
}
|
|
73
|
-
|
|
74
53
|
const checkFileExists = (extName, callback) => {
|
|
75
|
-
this.resolve(parsed.dir, resourceName + extName,
|
|
76
|
-
err = null
|
|
77
|
-
callback(err, result)
|
|
78
|
-
})
|
|
54
|
+
this.resolve(parsed.dir, resourceName + extName, callback)
|
|
79
55
|
}
|
|
80
56
|
|
|
81
57
|
function checkCSSLangFiles (callback) {
|
|
82
|
-
const langs = mpx.
|
|
58
|
+
const langs = mpx.nativeConfig.cssLangs || ['less', 'stylus', 'scss', 'sass']
|
|
83
59
|
const results = []
|
|
84
60
|
async.eachOf(langs, function (lang, i, callback) {
|
|
85
61
|
if (!CSS_LANG_EXT_MAP[lang]) {
|
|
@@ -89,7 +65,7 @@ module.exports = function (content) {
|
|
|
89
65
|
if (!err && result) {
|
|
90
66
|
results[i] = result
|
|
91
67
|
}
|
|
92
|
-
callback(
|
|
68
|
+
callback()
|
|
93
69
|
})
|
|
94
70
|
}, function (err) {
|
|
95
71
|
for (let i = 0; i < langs.length; i++) {
|
|
@@ -103,14 +79,13 @@ module.exports = function (content) {
|
|
|
103
79
|
})
|
|
104
80
|
}
|
|
105
81
|
|
|
106
|
-
function
|
|
107
|
-
|
|
108
|
-
checkFileExists(EXT_MPX_JSON, (err, result) => {
|
|
82
|
+
function checkJSONJSFile (callback) {
|
|
83
|
+
checkFileExists(JSON_JS_EXT, (err, result) => {
|
|
109
84
|
if (!err && result) {
|
|
110
85
|
typeResourceMap.json = result
|
|
111
|
-
|
|
86
|
+
useJSONJS = true
|
|
112
87
|
}
|
|
113
|
-
callback(
|
|
88
|
+
callback()
|
|
114
89
|
})
|
|
115
90
|
}
|
|
116
91
|
|
|
@@ -119,55 +94,42 @@ module.exports = function (content) {
|
|
|
119
94
|
(callback) => {
|
|
120
95
|
async.parallel([
|
|
121
96
|
checkCSSLangFiles,
|
|
122
|
-
|
|
97
|
+
checkJSONJSFile
|
|
123
98
|
], (err) => {
|
|
124
99
|
callback(err)
|
|
125
100
|
})
|
|
126
101
|
},
|
|
127
102
|
(callback) => {
|
|
128
103
|
async.forEachOf(typeExtMap, (ext, key, callback) => {
|
|
129
|
-
// 检测到
|
|
130
|
-
if (
|
|
104
|
+
// 检测到jsonjs或cssLang时跳过对应类型文件检测
|
|
105
|
+
if (typeResourceMap[key]) {
|
|
131
106
|
return callback()
|
|
132
107
|
}
|
|
133
108
|
checkFileExists(ext, (err, result) => {
|
|
134
109
|
if (!err && result) {
|
|
135
110
|
typeResourceMap[key] = result
|
|
136
111
|
}
|
|
137
|
-
callback(
|
|
112
|
+
callback()
|
|
138
113
|
})
|
|
139
114
|
}, callback)
|
|
140
115
|
},
|
|
141
116
|
(callback) => {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
146
|
-
if (typeResourceMap['json']) {
|
|
147
|
-
// eslint-disable-next-line handle-callback-err
|
|
148
|
-
const { rawResourcePath } = parseRequest(typeResourceMap['json'])
|
|
149
|
-
fs.readFile(rawResourcePath, (err, raw) => {
|
|
150
|
-
if (err) {
|
|
151
|
-
callback(err)
|
|
152
|
-
} else {
|
|
153
|
-
callback(null, raw.toString('utf-8'))
|
|
154
|
-
}
|
|
155
|
-
})
|
|
156
|
-
} else {
|
|
157
|
-
callback(null, '{}')
|
|
158
|
-
}
|
|
159
|
-
}
|
|
117
|
+
getJSONContent({
|
|
118
|
+
src: typeResourceMap.json,
|
|
119
|
+
useJSONJS
|
|
120
|
+
}, this, callback)
|
|
160
121
|
}, (content, callback) => {
|
|
161
|
-
let
|
|
122
|
+
let json
|
|
162
123
|
try {
|
|
163
|
-
|
|
164
|
-
if (ret.usingComponents) {
|
|
165
|
-
fixUsingComponent(ret.usingComponents, mode)
|
|
166
|
-
usingComponents = usingComponents.concat(Object.keys(ret.usingComponents))
|
|
167
|
-
}
|
|
124
|
+
json = JSON5.parse(content)
|
|
168
125
|
} catch (e) {
|
|
126
|
+
return callback(e)
|
|
127
|
+
}
|
|
128
|
+
let usingComponents = Object.keys(mpx.usingComponents)
|
|
129
|
+
if (json.usingComponents) {
|
|
130
|
+
fixUsingComponent(json.usingComponents, mode)
|
|
131
|
+
usingComponents = usingComponents.concat(Object.keys(json.usingComponents))
|
|
169
132
|
}
|
|
170
|
-
|
|
171
133
|
const {
|
|
172
134
|
getRequire
|
|
173
135
|
} = createHelpers(loaderContext)
|
|
@@ -175,11 +137,10 @@ module.exports = function (content) {
|
|
|
175
137
|
const getRequireByType = (type) => {
|
|
176
138
|
const src = typeResourceMap[type]
|
|
177
139
|
const part = { src }
|
|
178
|
-
const extraOptions =
|
|
140
|
+
const extraOptions = {
|
|
141
|
+
...queryObj,
|
|
179
142
|
resourcePath
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
if (type !== 'script') this.addDependency(src)
|
|
143
|
+
}
|
|
183
144
|
|
|
184
145
|
switch (type) {
|
|
185
146
|
case 'template':
|
|
@@ -199,6 +160,9 @@ module.exports = function (content) {
|
|
|
199
160
|
scoped: hasScoped
|
|
200
161
|
})
|
|
201
162
|
break
|
|
163
|
+
case 'json':
|
|
164
|
+
if (useJSONJS) part.useJSONJS = true
|
|
165
|
+
break
|
|
202
166
|
}
|
|
203
167
|
return getRequire(type, part, extraOptions)
|
|
204
168
|
}
|
|
@@ -211,7 +175,9 @@ module.exports = function (content) {
|
|
|
211
175
|
|
|
212
176
|
// 注入构造函数
|
|
213
177
|
let ctor = 'App'
|
|
178
|
+
let ctorType = 'app'
|
|
214
179
|
if (pagesMap[resourcePath]) {
|
|
180
|
+
ctorType = 'page'
|
|
215
181
|
if (mpx.forceUsePageCtor || mode === 'ali' || mode === 'swan') {
|
|
216
182
|
ctor = 'Page'
|
|
217
183
|
} else {
|
|
@@ -219,11 +185,13 @@ module.exports = function (content) {
|
|
|
219
185
|
}
|
|
220
186
|
} else if (componentsMap[resourcePath]) {
|
|
221
187
|
ctor = 'Component'
|
|
188
|
+
ctorType = 'component'
|
|
222
189
|
}
|
|
223
190
|
output += `global.currentCtor = ${ctor}\n`
|
|
224
191
|
output += `global.currentCtorType = ${JSON.stringify(ctor.replace(/^./, (match) => {
|
|
225
192
|
return match.toLowerCase()
|
|
226
193
|
}))}\n`
|
|
194
|
+
output += `global.currentResourceType = ${JSON.stringify(ctorType)}\n`
|
|
227
195
|
|
|
228
196
|
if (srcMode) {
|
|
229
197
|
output += `global.currentSrcMode = ${JSON.stringify(srcMode)}\n`
|
package/lib/parser.js
CHANGED
|
@@ -6,7 +6,7 @@ const SourceMapGenerator = require('source-map').SourceMapGenerator
|
|
|
6
6
|
const splitRE = /\r?\n/g
|
|
7
7
|
const emptyRE = /^(?:\/\/)?\s*$/
|
|
8
8
|
|
|
9
|
-
module.exports = (content, { filePath, needMap, mode,
|
|
9
|
+
module.exports = (content, { filePath, needMap, mode, env }) => {
|
|
10
10
|
// 缓存需要mode隔离,不同mode经过区块条件编译parseComponent得到的内容并不一致
|
|
11
11
|
const cacheKey = hash(filePath + content + mode + env)
|
|
12
12
|
|
|
@@ -14,7 +14,6 @@ module.exports = (content, { filePath, needMap, mode, defs, env }) => {
|
|
|
14
14
|
if (output) return JSON.parse(output)
|
|
15
15
|
output = compiler.parseComponent(content, {
|
|
16
16
|
mode,
|
|
17
|
-
defs,
|
|
18
17
|
filePath,
|
|
19
18
|
pad: 'line',
|
|
20
19
|
env
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const { matchCondition } = require('../utils/match-condition')
|
|
2
|
+
const { parseQuery } = require('loader-utils')
|
|
3
|
+
|
|
4
|
+
class MpxPartialCompilePlugin {
|
|
5
|
+
constructor (condition) {
|
|
6
|
+
this.condition = condition
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
isResolvingPage (obj) {
|
|
10
|
+
// valid query should start with '?'
|
|
11
|
+
const query = obj.query || '?'
|
|
12
|
+
return parseQuery(query).isPage
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
apply (compiler) {
|
|
16
|
+
compiler.resolverFactory.hooks.resolver.intercept({
|
|
17
|
+
factory: (type, hook) => {
|
|
18
|
+
hook.tap('MpxPartialCompilePlugin', (resolver) => {
|
|
19
|
+
resolver.hooks.result.tapAsync({
|
|
20
|
+
name: 'MpxPartialCompilePlugin',
|
|
21
|
+
stage: -100
|
|
22
|
+
}, (obj, resolverContext, callback) => {
|
|
23
|
+
if (this.isResolvingPage(obj) && !matchCondition(obj.path, this.condition)) {
|
|
24
|
+
obj.path = false
|
|
25
|
+
}
|
|
26
|
+
callback(null, obj)
|
|
27
|
+
})
|
|
28
|
+
})
|
|
29
|
+
return hook
|
|
30
|
+
}
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
module.exports = MpxPartialCompilePlugin
|