@mpxjs/webpack-plugin 2.8.48 → 2.8.50
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/lib/dependencies/CommonJsExtractDependency.js +51 -0
- package/lib/extractor.js +1 -0
- package/lib/helpers.js +9 -1
- package/lib/index.js +44 -2
- package/lib/json-compiler/helper.js +4 -3
- package/lib/json-compiler/index.js +1 -1
- package/lib/native-loader.js +17 -5
- package/lib/platform/json/wx/index.js +44 -2
- package/lib/platform/run-rules.js +2 -1
- package/lib/platform/template/normalize-component-rules.js +2 -0
- package/lib/platform/template/wx/component-config/fix-html-tag.js +17 -0
- package/lib/platform/template/wx/component-config/index.js +2 -0
- package/lib/runtime/components/web/filterTag.js +9 -30
- package/lib/runtime/components/web/getInnerListeners.js +2 -14
- package/lib/runtime/components/web/mpx-movable-view.vue +28 -9
- package/lib/runtime/components/web/mpx-picker-view.vue +1 -1
- package/lib/runtime/components/web/mpx-scroll-view.vue +3 -4
- package/lib/runtime/components/web/mpx-video.vue +5 -0
- package/lib/runtime/components/wx/default-page.mpx +27 -0
- package/lib/template-compiler/bind-this.js +248 -48
- package/lib/template-compiler/compiler.js +5 -29
- package/lib/template-compiler/index.js +2 -0
- package/lib/utils/dom-tag-config.js +101 -0
- package/lib/utils/make-map.js +12 -0
- package/lib/utils/string.js +7 -1
- package/lib/web/processJSON.js +35 -0
- package/package.json +2 -3
- package/lib/json-compiler/default-page.mpx +0 -3
- package/lib/template-compiler/preprocessor.js +0 -29
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const ModuleDependency = require('webpack/lib/dependencies/ModuleDependency')
|
|
2
|
+
const makeSerializable = require('webpack/lib/util/makeSerializable')
|
|
3
|
+
|
|
4
|
+
class CommonJsExtractDependency extends ModuleDependency {
|
|
5
|
+
constructor (request, range) {
|
|
6
|
+
super(request)
|
|
7
|
+
this.range = range
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
get type () {
|
|
11
|
+
return 'mpx cjs extract'
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
get category () {
|
|
15
|
+
return 'commonjs'
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
CommonJsExtractDependency.Template = class CommonJsExtractDependencyTemplate extends (
|
|
20
|
+
ModuleDependency.Template
|
|
21
|
+
) {
|
|
22
|
+
apply (
|
|
23
|
+
dep,
|
|
24
|
+
source,
|
|
25
|
+
{
|
|
26
|
+
runtimeTemplate,
|
|
27
|
+
moduleGraph,
|
|
28
|
+
chunkGraph,
|
|
29
|
+
runtimeRequirements
|
|
30
|
+
}
|
|
31
|
+
) {
|
|
32
|
+
let content = ''
|
|
33
|
+
if (!dep.weak) {
|
|
34
|
+
content = runtimeTemplate.moduleExports({
|
|
35
|
+
module: moduleGraph.getModule(dep),
|
|
36
|
+
chunkGraph,
|
|
37
|
+
request: dep.request,
|
|
38
|
+
weak: dep.weak,
|
|
39
|
+
runtimeRequirements
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
source.replace(dep.range[0], dep.range[1] - 1, content)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
makeSerializable(
|
|
47
|
+
CommonJsExtractDependency,
|
|
48
|
+
'@mpxjs/webpack-plugin/lib/dependencies/CommonJsExtractDependency'
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
module.exports = CommonJsExtractDependency
|
package/lib/extractor.js
CHANGED
package/lib/helpers.js
CHANGED
|
@@ -20,7 +20,15 @@ module.exports = function createHelpers (loaderContext) {
|
|
|
20
20
|
const { mode, env } = loaderContext.getMpx() || {}
|
|
21
21
|
|
|
22
22
|
function getRequire (type, part, extraOptions, index) {
|
|
23
|
-
|
|
23
|
+
let extract = false
|
|
24
|
+
switch (type) {
|
|
25
|
+
// eslint-disable-next-line no-fallthrough
|
|
26
|
+
case 'json':
|
|
27
|
+
case 'styles':
|
|
28
|
+
case 'template':
|
|
29
|
+
extract = true
|
|
30
|
+
}
|
|
31
|
+
return (extract ? 'require.extract(' : 'require(') + getRequestString(type, part, extraOptions, index) + ')'
|
|
24
32
|
}
|
|
25
33
|
|
|
26
34
|
function getImport (type, part, extraOptions, index) {
|
package/lib/index.js
CHANGED
|
@@ -8,6 +8,7 @@ const ReplaceDependency = require('./dependencies/ReplaceDependency')
|
|
|
8
8
|
const NullFactory = require('webpack/lib/NullFactory')
|
|
9
9
|
const CommonJsVariableDependency = require('./dependencies/CommonJsVariableDependency')
|
|
10
10
|
const CommonJsAsyncDependency = require('./dependencies/CommonJsAsyncDependency')
|
|
11
|
+
const CommonJsExtractDependency = require('./dependencies/CommonJsExtractDependency')
|
|
11
12
|
const harmonySpecifierTag = require('webpack/lib/dependencies/HarmonyImportDependencyParserPlugin').harmonySpecifierTag
|
|
12
13
|
const NormalModule = require('webpack/lib/NormalModule')
|
|
13
14
|
const EntryPlugin = require('webpack/lib/EntryPlugin')
|
|
@@ -124,6 +125,7 @@ class MpxWebpackPlugin {
|
|
|
124
125
|
options.resolveMode = options.resolveMode || 'webpack'
|
|
125
126
|
options.writeMode = options.writeMode || 'changed'
|
|
126
127
|
options.autoScopeRules = options.autoScopeRules || {}
|
|
128
|
+
options.renderOptimizeRules = options.renderOptimizeRules || {}
|
|
127
129
|
options.autoVirtualHostRules = options.autoVirtualHostRules || {}
|
|
128
130
|
options.forceDisableProxyCtor = options.forceDisableProxyCtor || false
|
|
129
131
|
options.transMpxRules = options.transMpxRules || {
|
|
@@ -405,13 +407,13 @@ class MpxWebpackPlugin {
|
|
|
405
407
|
name: 'MpxPartialCompilePlugin',
|
|
406
408
|
stage: -100
|
|
407
409
|
}, (obj, resolverContext, callback) => {
|
|
408
|
-
if (obj.path.startsWith(require.resolve('./
|
|
410
|
+
if (obj.path.startsWith(require.resolve('./runtime/components/wx/default-page.mpx'))) {
|
|
409
411
|
return callback(null, obj)
|
|
410
412
|
}
|
|
411
413
|
if (isResolvingPage(obj) && !matchCondition(obj.path, this.options.partialCompile)) {
|
|
412
414
|
const infix = obj.query ? '&' : '?'
|
|
413
415
|
obj.query += `${infix}resourcePath=${obj.path}`
|
|
414
|
-
obj.path = require.resolve('./
|
|
416
|
+
obj.path = require.resolve('./runtime/components/wx/default-page.mpx')
|
|
415
417
|
}
|
|
416
418
|
callback(null, obj)
|
|
417
419
|
})
|
|
@@ -554,6 +556,9 @@ class MpxWebpackPlugin {
|
|
|
554
556
|
compilation.dependencyFactories.set(CommonJsAsyncDependency, normalModuleFactory)
|
|
555
557
|
compilation.dependencyTemplates.set(CommonJsAsyncDependency, new CommonJsAsyncDependency.Template())
|
|
556
558
|
|
|
559
|
+
compilation.dependencyFactories.set(CommonJsExtractDependency, normalModuleFactory)
|
|
560
|
+
compilation.dependencyTemplates.set(CommonJsExtractDependency, new CommonJsExtractDependency.Template())
|
|
561
|
+
|
|
557
562
|
compilation.dependencyFactories.set(RecordVueContentDependency, new NullFactory())
|
|
558
563
|
compilation.dependencyTemplates.set(RecordVueContentDependency, new RecordVueContentDependency.Template())
|
|
559
564
|
})
|
|
@@ -628,6 +633,7 @@ class MpxWebpackPlugin {
|
|
|
628
633
|
appTitle: 'Mpx homepage',
|
|
629
634
|
attributes: this.options.attributes,
|
|
630
635
|
externals: this.options.externals,
|
|
636
|
+
renderOptimizeRules: this.options.renderOptimizeRules,
|
|
631
637
|
useRelativePath: this.options.useRelativePath,
|
|
632
638
|
removedChunks: [],
|
|
633
639
|
forceProxyEventRules: this.options.forceProxyEventRules,
|
|
@@ -923,6 +929,17 @@ class MpxWebpackPlugin {
|
|
|
923
929
|
})
|
|
924
930
|
|
|
925
931
|
compilation.hooks.finishModules.tap('MpxWebpackPlugin', (modules) => {
|
|
932
|
+
// 移除extractor抽取后的空模块
|
|
933
|
+
for (const module of modules) {
|
|
934
|
+
if (module.buildInfo.isEmpty) {
|
|
935
|
+
for (const connection of moduleGraph.getIncomingConnections(module)) {
|
|
936
|
+
if (connection.dependency.type === 'mpx cjs extract') {
|
|
937
|
+
connection.weak = true
|
|
938
|
+
connection.dependency.weak = true
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
}
|
|
926
943
|
// 自动跟进分包配置修改splitChunksPlugin配置
|
|
927
944
|
if (splitChunksPlugin) {
|
|
928
945
|
let needInit = false
|
|
@@ -1096,6 +1113,31 @@ class MpxWebpackPlugin {
|
|
|
1096
1113
|
stage: -1000
|
|
1097
1114
|
}, (expr, calleeMembers, callExpr) => requireAsyncHandler(callExpr, calleeMembers, expr.arguments))
|
|
1098
1115
|
|
|
1116
|
+
const requireExtractHandler = (expr, members, args) => {
|
|
1117
|
+
if (members[0] === 'extract') {
|
|
1118
|
+
const request = expr.arguments[0].value
|
|
1119
|
+
const range = expr.range
|
|
1120
|
+
const dep = new CommonJsExtractDependency(request, range)
|
|
1121
|
+
parser.state.current.addDependency(dep)
|
|
1122
|
+
if (args) parser.walkExpressions(args)
|
|
1123
|
+
return true
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
parser.hooks.callMemberChain
|
|
1128
|
+
.for('require')
|
|
1129
|
+
.tap({
|
|
1130
|
+
name: 'MpxWebpackPlugin',
|
|
1131
|
+
stage: -2000
|
|
1132
|
+
}, (expr, members) => requireExtractHandler(expr, members))
|
|
1133
|
+
|
|
1134
|
+
parser.hooks.callMemberChainOfCallMemberChain
|
|
1135
|
+
.for('require')
|
|
1136
|
+
.tap({
|
|
1137
|
+
name: 'MpxWebpackPlugin',
|
|
1138
|
+
stage: -2000
|
|
1139
|
+
}, (expr, calleeMembers, callExpr) => requireExtractHandler(callExpr, calleeMembers, expr.arguments))
|
|
1140
|
+
|
|
1099
1141
|
// hack babel polyfill global
|
|
1100
1142
|
parser.hooks.statementIf.tap('MpxWebpackPlugin', (expr) => {
|
|
1101
1143
|
if (/core-js.+microtask/.test(parser.state.module.resource)) {
|
|
@@ -22,6 +22,7 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning, custom
|
|
|
22
22
|
|
|
23
23
|
const isUrlRequest = r => isUrlRequestRaw(r, root, externals)
|
|
24
24
|
const urlToRequest = r => loaderUtils.urlToRequest(r)
|
|
25
|
+
const isScript = ext => /\.(ts|js)$/.test(ext)
|
|
25
26
|
|
|
26
27
|
const dynamicEntryMap = new Map()
|
|
27
28
|
|
|
@@ -73,7 +74,7 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning, custom
|
|
|
73
74
|
const resourceName = path.join(parsed.dir, parsed.name)
|
|
74
75
|
|
|
75
76
|
if (!outputPath) {
|
|
76
|
-
if (ext
|
|
77
|
+
if (isScript(ext) && resourceName.includes('node_modules') && mode !== 'web') {
|
|
77
78
|
let root = info.descriptionFileRoot
|
|
78
79
|
let name = 'nativeComponent'
|
|
79
80
|
if (info.descriptionFileData) {
|
|
@@ -91,7 +92,7 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning, custom
|
|
|
91
92
|
outputPath = getOutputPath(resourcePath, 'component')
|
|
92
93
|
}
|
|
93
94
|
}
|
|
94
|
-
if (ext
|
|
95
|
+
if (isScript(ext) && mode !== 'web') {
|
|
95
96
|
resource = `!!${nativeLoaderPath}!${resource}`
|
|
96
97
|
}
|
|
97
98
|
|
|
@@ -131,7 +132,7 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning, custom
|
|
|
131
132
|
outputPath = /^(.*?)(\.[^.]*)?$/.exec(relative)[1]
|
|
132
133
|
}
|
|
133
134
|
}
|
|
134
|
-
if (ext
|
|
135
|
+
if (isScript(ext) && mode !== 'web') {
|
|
135
136
|
resource = `!!${nativeLoaderPath}!${resource}`
|
|
136
137
|
}
|
|
137
138
|
const entry = getDynamicEntry(resource, 'page', outputPath, tarRoot, publicPath + tarRoot)
|
|
@@ -250,7 +250,7 @@ module.exports = function (content) {
|
|
|
250
250
|
const localPages = []
|
|
251
251
|
const subPackagesCfg = {}
|
|
252
252
|
const pageKeySet = new Set()
|
|
253
|
-
const defaultPagePath = require.resolve('
|
|
253
|
+
const defaultPagePath = require.resolve('../runtime/components/wx/default-page.mpx')
|
|
254
254
|
const processPages = (pages, context, tarRoot = '', callback) => {
|
|
255
255
|
if (pages) {
|
|
256
256
|
const pagesCache = []
|
package/lib/native-loader.js
CHANGED
|
@@ -8,7 +8,7 @@ const async = require('async')
|
|
|
8
8
|
const { matchCondition } = require('./utils/match-condition')
|
|
9
9
|
const { JSON_JS_EXT } = require('./utils/const')
|
|
10
10
|
const getRulesRunner = require('./platform')
|
|
11
|
-
|
|
11
|
+
// todo native-loader考虑与mpx-loader或加强复用,原生组件约等于4个区块都为src的.mpx文件
|
|
12
12
|
module.exports = function (content) {
|
|
13
13
|
this.cacheable()
|
|
14
14
|
|
|
@@ -44,6 +44,8 @@ module.exports = function (content) {
|
|
|
44
44
|
scss: '.scss'
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
const TS_EXT = '.ts'
|
|
48
|
+
|
|
47
49
|
let useJSONJS = false
|
|
48
50
|
let cssLang = ''
|
|
49
51
|
const hasScoped = (queryObj.scoped || autoScope) && mode === 'ali'
|
|
@@ -54,7 +56,7 @@ module.exports = function (content) {
|
|
|
54
56
|
this.resolve(parsed.dir, resourceName + extName, callback)
|
|
55
57
|
}
|
|
56
58
|
|
|
57
|
-
function
|
|
59
|
+
function checkCSSLangFile (callback) {
|
|
58
60
|
const langs = mpx.nativeConfig.cssLangs || ['less', 'stylus', 'scss', 'sass']
|
|
59
61
|
const results = []
|
|
60
62
|
async.eachOf(langs, function (lang, i, callback) {
|
|
@@ -89,6 +91,15 @@ module.exports = function (content) {
|
|
|
89
91
|
})
|
|
90
92
|
}
|
|
91
93
|
|
|
94
|
+
function checkTSFile (callback) {
|
|
95
|
+
checkFileExists(TS_EXT, (err, result) => {
|
|
96
|
+
if (!err && result) {
|
|
97
|
+
typeResourceMap.script = result
|
|
98
|
+
}
|
|
99
|
+
callback()
|
|
100
|
+
})
|
|
101
|
+
}
|
|
102
|
+
|
|
92
103
|
const emitWarning = (msg) => {
|
|
93
104
|
this.emitWarning(
|
|
94
105
|
new Error('[native-loader][' + this.resource + ']: ' + msg)
|
|
@@ -105,15 +116,16 @@ module.exports = function (content) {
|
|
|
105
116
|
async.waterfall([
|
|
106
117
|
(callback) => {
|
|
107
118
|
async.parallel([
|
|
108
|
-
|
|
109
|
-
checkJSONJSFile
|
|
119
|
+
checkCSSLangFile,
|
|
120
|
+
checkJSONJSFile,
|
|
121
|
+
checkTSFile
|
|
110
122
|
], (err) => {
|
|
111
123
|
callback(err)
|
|
112
124
|
})
|
|
113
125
|
},
|
|
114
126
|
(callback) => {
|
|
115
127
|
async.forEachOf(typeExtMap, (ext, key, callback) => {
|
|
116
|
-
//
|
|
128
|
+
// 对应资源存在预处理类型文件时跳过对应的标准文件检测
|
|
117
129
|
if (typeResourceMap[key]) {
|
|
118
130
|
return callback()
|
|
119
131
|
}
|
|
@@ -3,6 +3,7 @@ const normalizeTest = require('../normalize-test')
|
|
|
3
3
|
const changeKey = require('../change-key')
|
|
4
4
|
const normalize = require('../../../utils/normalize')
|
|
5
5
|
const { capitalToHyphen } = require('../../../utils/string')
|
|
6
|
+
const { isOriginTag } = require('../../../utils/dom-tag-config')
|
|
6
7
|
|
|
7
8
|
const mpxViewPath = normalize.lib('runtime/components/ali/mpx-view.mpx')
|
|
8
9
|
const mpxTextPath = normalize.lib('runtime/components/ali/mpx-text.mpx')
|
|
@@ -70,6 +71,19 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
70
71
|
return input
|
|
71
72
|
}
|
|
72
73
|
|
|
74
|
+
// 校验输出支付宝 componentGenerics 配置的正确性
|
|
75
|
+
function aliComponentGenericsValidate (input) {
|
|
76
|
+
const componentGenerics = input.componentGenerics
|
|
77
|
+
if (componentGenerics && typeof componentGenerics === 'object') {
|
|
78
|
+
Object.keys(componentGenerics).forEach(key => {
|
|
79
|
+
if (!componentGenerics[key].default) {
|
|
80
|
+
error(`Ali environment componentGenerics need to specify a default custom component! please check the configuration of component ${key}`)
|
|
81
|
+
}
|
|
82
|
+
})
|
|
83
|
+
}
|
|
84
|
+
return input
|
|
85
|
+
}
|
|
86
|
+
|
|
73
87
|
function fillGlobalComponents (input, { globalComponents }) {
|
|
74
88
|
if (globalComponents) {
|
|
75
89
|
Object.assign(globalComponents, input.usingComponents)
|
|
@@ -112,10 +126,30 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
112
126
|
}
|
|
113
127
|
}
|
|
114
128
|
|
|
129
|
+
/**
|
|
130
|
+
* 将小程序代码中使用的与原生 HTML tag 同名组件进行转化,以解决与原生tag命名冲突问题。
|
|
131
|
+
* @param {string} type usingComponents
|
|
132
|
+
* @returns input
|
|
133
|
+
*/
|
|
134
|
+
function webHTMLTagProcesser (type) {
|
|
135
|
+
return function (input) {
|
|
136
|
+
const usingComponents = input[type]
|
|
137
|
+
if (usingComponents) {
|
|
138
|
+
Object.keys(usingComponents).forEach(tag => {
|
|
139
|
+
if (isOriginTag(tag)) {
|
|
140
|
+
usingComponents[`mpx-com-${tag}`] = usingComponents[tag]
|
|
141
|
+
delete usingComponents[tag]
|
|
142
|
+
}
|
|
143
|
+
})
|
|
144
|
+
}
|
|
145
|
+
return input
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
115
149
|
const componentRules = [
|
|
116
150
|
{
|
|
117
151
|
test: 'componentGenerics',
|
|
118
|
-
ali:
|
|
152
|
+
ali: aliComponentGenericsValidate
|
|
119
153
|
},
|
|
120
154
|
{
|
|
121
155
|
test: 'componentPlaceholder',
|
|
@@ -124,6 +158,10 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
124
158
|
tt: deletePath(),
|
|
125
159
|
jd: deletePath()
|
|
126
160
|
},
|
|
161
|
+
{
|
|
162
|
+
test: 'usingComponents',
|
|
163
|
+
web: webHTMLTagProcesser('usingComponents')
|
|
164
|
+
},
|
|
127
165
|
{
|
|
128
166
|
test: 'usingComponents',
|
|
129
167
|
ali: componentNameCapitalToHyphen('usingComponents'),
|
|
@@ -224,7 +262,7 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
224
262
|
}
|
|
225
263
|
|
|
226
264
|
const spec = {
|
|
227
|
-
supportedModes: ['ali', 'swan', 'qq', 'tt', 'jd', 'qa', 'dd'],
|
|
265
|
+
supportedModes: ['ali', 'swan', 'qq', 'tt', 'jd', 'qa', 'dd', 'web'],
|
|
228
266
|
normalizeTest,
|
|
229
267
|
page: [
|
|
230
268
|
...windowRules,
|
|
@@ -325,6 +363,10 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
325
363
|
tt: deletePath(),
|
|
326
364
|
jd: deletePath(true)
|
|
327
365
|
},
|
|
366
|
+
{
|
|
367
|
+
test: 'usingComponents',
|
|
368
|
+
web: webHTMLTagProcesser('usingComponents')
|
|
369
|
+
},
|
|
328
370
|
{
|
|
329
371
|
test: 'usingComponents',
|
|
330
372
|
ali: componentNameCapitalToHyphen('usingComponents'),
|
|
@@ -11,6 +11,8 @@ module.exports = function normalizeComponentRules (cfgs, spec) {
|
|
|
11
11
|
if (cfg.test) {
|
|
12
12
|
result.test = cfg.test
|
|
13
13
|
}
|
|
14
|
+
// 透传 waterfall 信息
|
|
15
|
+
if (cfg.waterfall) result.waterfall = cfg.waterfall
|
|
14
16
|
const supportedModes = cfg.supportedModes || spec.supportedModes
|
|
15
17
|
// 合并component-config中组件的event 与index中公共的event规则
|
|
16
18
|
const eventRules = (cfg.event || []).concat(spec.event.rules)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const { isOriginTag } = require('../../../../utils/dom-tag-config')
|
|
2
|
+
|
|
3
|
+
module.exports = function () {
|
|
4
|
+
return {
|
|
5
|
+
waterfall: true,
|
|
6
|
+
test: (input) => isOriginTag(input),
|
|
7
|
+
// 处理原生tag
|
|
8
|
+
web (tag, data = {}) {
|
|
9
|
+
// @see packages/webpack-plugin/lib/platform/json/wx/index.js webHTMLTagProcesser
|
|
10
|
+
const newTag = `mpx-com-${tag}`
|
|
11
|
+
const usingComponents = data.usingComponents || []
|
|
12
|
+
// 存在同名组件,则返回新tag
|
|
13
|
+
if (usingComponents.includes(newTag)) return newTag
|
|
14
|
+
return tag
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -39,6 +39,7 @@ const view = require('./view')
|
|
|
39
39
|
const webView = require('./web-view')
|
|
40
40
|
const wxs = require('./wxs')
|
|
41
41
|
const component = require('./component')
|
|
42
|
+
const fixHTMLTag = require('./fix-html-tag')
|
|
42
43
|
|
|
43
44
|
module.exports = function getComponentConfigs ({ warn, error }) {
|
|
44
45
|
/**
|
|
@@ -79,6 +80,7 @@ module.exports = function getComponentConfigs ({ warn, error }) {
|
|
|
79
80
|
|
|
80
81
|
// 转换规则只需以微信为基准配置微信和支付宝的差异部分,比如微信和支付宝都支持但是写法不一致,或者微信支持而支付宝不支持的部分(抛出错误或警告)
|
|
81
82
|
return [
|
|
83
|
+
fixHTMLTag(),
|
|
82
84
|
...Nonsupport({ print }),
|
|
83
85
|
ad({ print }),
|
|
84
86
|
view({ print }),
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
const {
|
|
2
|
+
isRichTextTag,
|
|
3
|
+
isUnaryTag,
|
|
4
|
+
isSpace,
|
|
5
|
+
isContWidth,
|
|
6
|
+
isContHeight,
|
|
7
|
+
isContConRow
|
|
8
|
+
} = require('../../../utils/dom-tag-config')
|
|
9
|
+
|
|
1
10
|
// eslint-disable-next-line
|
|
2
11
|
const attribute = /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/ // useless escape
|
|
3
12
|
const ncname = '[a-zA-Z_][\\w\\-\\.]*'
|
|
@@ -11,36 +20,6 @@ const comment = /^<!\--/
|
|
|
11
20
|
const invalidAttributeRE = /[\s"'<>\/=]/
|
|
12
21
|
let currentParent
|
|
13
22
|
|
|
14
|
-
function makeMap (str, expectsLowerCase) {
|
|
15
|
-
const map = Object.create(null)
|
|
16
|
-
const list = str.split(',')
|
|
17
|
-
for (let i = 0; i < list.length; i++) {
|
|
18
|
-
map[list[i]] = true
|
|
19
|
-
}
|
|
20
|
-
return expectsLowerCase
|
|
21
|
-
? val => map[val.toLowerCase()]
|
|
22
|
-
: val => map[val]
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const isRichTextTag = makeMap(
|
|
26
|
-
'a,abbr,address,article,aside,b,bdi,bdo,big,blockquote,br,caption,' +
|
|
27
|
-
'center,cite,code,col,colgroup,dd,del,div,dl,dt,em,fieldset,' +
|
|
28
|
-
'font,footer,h1,h2,h3,h4,h5,h6,header,hr,i,img,ins,label,legend,' +
|
|
29
|
-
'li,mark,nav,ol,p,pre,q,rt,ruby,s,section,small,span,strong,sub,sup,' +
|
|
30
|
-
'table,tbody,td,tfoot,th,thead,tr,tt,u,ul'
|
|
31
|
-
)
|
|
32
|
-
const isUnaryTag = makeMap(
|
|
33
|
-
'area,base,br,col,embed,frame,hr,img,input,isindex,keygen,' +
|
|
34
|
-
'link,meta,param,source,track,wbr'
|
|
35
|
-
)
|
|
36
|
-
const isSpace = makeMap('ensp,emsp,nbsp')
|
|
37
|
-
|
|
38
|
-
const isContWidth = makeMap('col,colgroup,img,table,td,th,tr')
|
|
39
|
-
|
|
40
|
-
const isContHeight = makeMap('img,td,th,tr')
|
|
41
|
-
|
|
42
|
-
const isContConRow = makeMap('td,th,tr')
|
|
43
|
-
|
|
44
23
|
function makeAttrsMap (attrs) {
|
|
45
24
|
const map = {}
|
|
46
25
|
for (let i = 0, l = attrs.length; i < l; i++) {
|
|
@@ -144,20 +144,8 @@ export function inheritEvent (type, oe, detail = {}) {
|
|
|
144
144
|
}
|
|
145
145
|
|
|
146
146
|
export function getCustomEvent (type, detail = {}, target = null) {
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
const targetEl = target.$el || {}
|
|
150
|
-
const info = {
|
|
151
|
-
id: targetEl.id || '',
|
|
152
|
-
dataset: targetEl.dataset || {},
|
|
153
|
-
offsetTop: targetEl.offsetTop || 0,
|
|
154
|
-
offsetLeft: targetEl.offsetLeft || 0
|
|
155
|
-
}
|
|
156
|
-
Object.assign(targetInfo, {
|
|
157
|
-
target: info,
|
|
158
|
-
currentTarget: info
|
|
159
|
-
})
|
|
160
|
-
}
|
|
147
|
+
const targetEl = (target && target.$el) || null
|
|
148
|
+
const targetInfo = targetEl ? { target: targetEl, currentTarget: targetEl } : {}
|
|
161
149
|
return {
|
|
162
150
|
type,
|
|
163
151
|
detail,
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
</div>
|
|
2
|
+
<div class="mpx-movable-scroll-content" ref="scrollContent">
|
|
3
|
+
<div class="mpx-movable-scroll-item">
|
|
4
|
+
<slot></slot>
|
|
6
5
|
</div>
|
|
6
|
+
</div>
|
|
7
7
|
</template>
|
|
8
8
|
|
|
9
9
|
<script type="text/ecmascript-6">
|
|
10
|
-
import {getCustomEvent} from './getInnerListeners'
|
|
10
|
+
import {getCustomEvent, extendEvent} from './getInnerListeners'
|
|
11
11
|
import BScroll from '@better-scroll/core'
|
|
12
12
|
import Movable from '@better-scroll/movable'
|
|
13
13
|
import Zoom from '@better-scroll/zoom'
|
|
@@ -121,6 +121,13 @@
|
|
|
121
121
|
newVal = 0.5
|
|
122
122
|
}
|
|
123
123
|
this.bs.zoomTo(newVal, 'center', 'center')
|
|
124
|
+
},
|
|
125
|
+
disabled (newVal) {
|
|
126
|
+
if (newVal) {
|
|
127
|
+
this.bs && this.bs.disable()
|
|
128
|
+
} else {
|
|
129
|
+
this.bs && this.bs.enable()
|
|
130
|
+
}
|
|
124
131
|
}
|
|
125
132
|
},
|
|
126
133
|
mounted () {
|
|
@@ -204,6 +211,14 @@
|
|
|
204
211
|
this.bs.movingDirectionY = -1
|
|
205
212
|
}
|
|
206
213
|
})
|
|
214
|
+
actionsHandlerHooks.on('start', (e) => {
|
|
215
|
+
extendEvent(e, { detail: Object.assign({}, e.detail) })
|
|
216
|
+
this.$emit('touchstart', e)
|
|
217
|
+
})
|
|
218
|
+
actionsHandlerHooks.on('end', (e) => {
|
|
219
|
+
extendEvent(e, { detail: Object.assign({}, e.detail) })
|
|
220
|
+
this.$emit('touchend', e)
|
|
221
|
+
})
|
|
207
222
|
actionsHandlerHooks.on('move', ({ deltaX, deltaY, e }) => {
|
|
208
223
|
if (this.isZooming) {
|
|
209
224
|
return
|
|
@@ -215,7 +230,9 @@
|
|
|
215
230
|
this.touchEvent = 'vtouchmove'
|
|
216
231
|
}
|
|
217
232
|
}
|
|
218
|
-
|
|
233
|
+
extendEvent(e, { detail: Object.assign({}, e.detail), currentTarget: e.target })
|
|
234
|
+
this.$emit(this.touchEvent, e)
|
|
235
|
+
this.$emit('touchmove', e)
|
|
219
236
|
this.isFirstTouch = false
|
|
220
237
|
})
|
|
221
238
|
if (this.inertia) { // movable-view是否带有惯性
|
|
@@ -302,7 +319,9 @@
|
|
|
302
319
|
}
|
|
303
320
|
</script>
|
|
304
321
|
<style lang="stylus" rel="stylesheet/stylus" scoped>
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
322
|
+
.mpx-movable-scroll-content
|
|
323
|
+
position: absolute
|
|
324
|
+
.mpx-movable-scroll-item
|
|
325
|
+
width: 100%
|
|
326
|
+
height: 100%
|
|
308
327
|
</style>
|
|
@@ -264,10 +264,9 @@
|
|
|
264
264
|
},
|
|
265
265
|
initLayerComputed () {
|
|
266
266
|
const wrapper = this.$refs.wrapper
|
|
267
|
-
const
|
|
268
|
-
|
|
269
|
-
this.$refs.innerWrapper.style.
|
|
270
|
-
this.$refs.innerWrapper.style.height = `${wrapperHeight}px`
|
|
267
|
+
const computedStyle = getComputedStyle(wrapper)
|
|
268
|
+
this.$refs.innerWrapper.style.width = `${computedStyle.clientWidth - parseInt(computedStyle.paddingLeft) - parseInt(computedStyle.paddingRight)}px`
|
|
269
|
+
this.$refs.innerWrapper.style.height = `${computedStyle.clientHeight - parseInt(computedStyle.paddingTop) - parseInt(computedStyle.paddingBottom)}px`
|
|
271
270
|
const innerWrapper = this.$refs.innerWrapper
|
|
272
271
|
const childrenArr = Array.from(innerWrapper.children)
|
|
273
272
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view>局部构建兜底页面</view>
|
|
3
|
+
<view>当前路由:{{currentRoute}}</view>
|
|
4
|
+
</template>
|
|
5
|
+
|
|
6
|
+
<script>
|
|
7
|
+
import { onLoad } from '@mpxjs/core'
|
|
8
|
+
import { createPage } from '@mpxjs/core'
|
|
9
|
+
|
|
10
|
+
createPage({
|
|
11
|
+
data() {
|
|
12
|
+
return {
|
|
13
|
+
currentRoute: '',
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
onLoad() {
|
|
17
|
+
this.getPagePath()
|
|
18
|
+
},
|
|
19
|
+
methods: {
|
|
20
|
+
getPagePath() {
|
|
21
|
+
const pages = getCurrentPages() || []
|
|
22
|
+
const currPage = pages[pages.length - 1]
|
|
23
|
+
this.currentRoute = currPage && currPage.route || ''
|
|
24
|
+
},
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
</script>
|
|
@@ -19,9 +19,159 @@ dangerousKeys.split(',').forEach((key) => {
|
|
|
19
19
|
dangerousKeyMap[key] = true
|
|
20
20
|
})
|
|
21
21
|
|
|
22
|
+
// 判断 Identifier 是否需要处理
|
|
23
|
+
function checkBindThis (path) {
|
|
24
|
+
return !(t.isDeclaration(path.parent) && path.parentKey === 'id') &&
|
|
25
|
+
!(t.isFunction(path.parent) && path.listKey === 'params') &&
|
|
26
|
+
!(t.isMethod(path.parent) && path.parentKey === 'key' && !path.parent.computed) &&
|
|
27
|
+
!(t.isProperty(path.parent) && path.parentKey === 'key' && !path.parent.computed) &&
|
|
28
|
+
!(t.isMemberExpression(path.parent) && path.parentKey === 'property' && !path.parent.computed) &&
|
|
29
|
+
!t.isArrayPattern(path.parent) &&
|
|
30
|
+
!t.isObjectPattern(path.parent) &&
|
|
31
|
+
!hash[path.node.name]
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// 计算访问路径
|
|
35
|
+
function calPropName (path) {
|
|
36
|
+
let current = path.parentPath
|
|
37
|
+
let last = path
|
|
38
|
+
let keyPath = '' + path.node.name
|
|
39
|
+
|
|
40
|
+
while (current.isMemberExpression() && last.parentKey !== 'property') {
|
|
41
|
+
if (current.node.computed) {
|
|
42
|
+
if (t.isLiteral(current.node.property)) {
|
|
43
|
+
if (t.isStringLiteral(current.node.property)) {
|
|
44
|
+
if (dangerousKeyMap[current.node.property.value]) {
|
|
45
|
+
break
|
|
46
|
+
}
|
|
47
|
+
keyPath += `.${current.node.property.value}`
|
|
48
|
+
} else {
|
|
49
|
+
keyPath += `[${current.node.property.value}]`
|
|
50
|
+
}
|
|
51
|
+
} else {
|
|
52
|
+
break
|
|
53
|
+
}
|
|
54
|
+
} else {
|
|
55
|
+
if (dangerousKeyMap[current.node.property.name]) {
|
|
56
|
+
break
|
|
57
|
+
}
|
|
58
|
+
keyPath += `.${current.node.property.name}`
|
|
59
|
+
}
|
|
60
|
+
last = current
|
|
61
|
+
current = current.parentPath
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
last,
|
|
66
|
+
keyPath
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function checkDelAndGetPath (path) {
|
|
71
|
+
let current = path
|
|
72
|
+
let delPath = path
|
|
73
|
+
let canDel = true
|
|
74
|
+
let ignore = false
|
|
75
|
+
let replace = false
|
|
76
|
+
|
|
77
|
+
// 确定删除路径
|
|
78
|
+
while (!t.isBlockStatement(current)) {
|
|
79
|
+
// case: !!a
|
|
80
|
+
if (t.isUnaryExpression(current.parent) && current.key === 'argument') {
|
|
81
|
+
delPath = current.parentPath
|
|
82
|
+
} else if (t.isCallExpression(current.parent)) {
|
|
83
|
+
// case: String(a) || this._p(a)
|
|
84
|
+
const args = current.node.arguments || current.parent.arguments || []
|
|
85
|
+
if (args.length === 1) {
|
|
86
|
+
delPath = current.parentPath
|
|
87
|
+
} else {
|
|
88
|
+
// case: this._i(a, function() {})
|
|
89
|
+
canDel = false
|
|
90
|
+
break
|
|
91
|
+
}
|
|
92
|
+
} else if (t.isMemberExpression(current.parent)) { // case: String(a,'123').b.c
|
|
93
|
+
if (current.parent.computed && !t.isLiteral(current.parent.property)) { // case: a[b] or a.b[c.d]
|
|
94
|
+
canDel = false
|
|
95
|
+
break
|
|
96
|
+
} else {
|
|
97
|
+
delPath = current.parentPath
|
|
98
|
+
}
|
|
99
|
+
} else {
|
|
100
|
+
break
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
current = current.parentPath
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// 确定是否可删除
|
|
107
|
+
while (!t.isBlockStatement(current) && canDel) {
|
|
108
|
+
const { key, container } = current
|
|
109
|
+
if (
|
|
110
|
+
t.isLogicalExpression(container) || // a && b
|
|
111
|
+
(t.isIfStatement(container) && key === 'test') // if (a) {}
|
|
112
|
+
) {
|
|
113
|
+
canDel = false
|
|
114
|
+
break
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (t.isConditionalExpression(container)) {
|
|
118
|
+
if (key === 'test') canDel = false
|
|
119
|
+
else ignore = true
|
|
120
|
+
break
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (
|
|
124
|
+
t.isBinaryExpression(container) || // 运算 a + b
|
|
125
|
+
(key === 'value' && t.isObjectProperty(container) && canDel) // ({ name: a })
|
|
126
|
+
) {
|
|
127
|
+
canDel = true
|
|
128
|
+
replace = true
|
|
129
|
+
// 不能break,case: if (a + b) {}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
current = current.parentPath
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
delPath,
|
|
137
|
+
canDel,
|
|
138
|
+
ignore,
|
|
139
|
+
replace
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// 判断前缀是否存在(只判断前缀,全等的情况,会返回false)
|
|
144
|
+
function checkPrefix (keys, key) {
|
|
145
|
+
for (let i = 0; i < keys.length; i++) {
|
|
146
|
+
const str = keys[i]
|
|
147
|
+
if (key === str) continue
|
|
148
|
+
// 确保判断当前标识是完整的单词
|
|
149
|
+
if (key.startsWith(str) && (key[str.length] === '.' || key[str.length] === '[')) return true
|
|
150
|
+
}
|
|
151
|
+
return false
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function dealRemove (path, replace) {
|
|
155
|
+
while (path.key === 'expression' && t.isExpressionStatement(path.parentPath)) {
|
|
156
|
+
path = path.parentPath
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
try {
|
|
160
|
+
if (replace) {
|
|
161
|
+
path.replaceWith(t.stringLiteral(''))
|
|
162
|
+
} else {
|
|
163
|
+
t.validate(path, path.key, null)
|
|
164
|
+
path.remove()
|
|
165
|
+
}
|
|
166
|
+
} catch (e) {
|
|
167
|
+
console.error(e)
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
22
171
|
module.exports = {
|
|
23
172
|
transform (code, {
|
|
24
173
|
needCollect = false,
|
|
174
|
+
renderReduce = false,
|
|
25
175
|
ignoreMap = {}
|
|
26
176
|
} = {}) {
|
|
27
177
|
const ast = babylon.parse(code, {
|
|
@@ -30,10 +180,71 @@ module.exports = {
|
|
|
30
180
|
]
|
|
31
181
|
})
|
|
32
182
|
|
|
183
|
+
let currentBlock = null
|
|
184
|
+
const bindingsMap = new Map()
|
|
185
|
+
|
|
33
186
|
const propKeys = []
|
|
34
187
|
let isProps = false
|
|
35
188
|
|
|
189
|
+
const collectVisitor = {
|
|
190
|
+
BlockStatement: {
|
|
191
|
+
enter (path) { // 收集作用域下所有变量(keyPath)
|
|
192
|
+
bindingsMap.set(path, {
|
|
193
|
+
parent: currentBlock,
|
|
194
|
+
bindings: {}
|
|
195
|
+
})
|
|
196
|
+
currentBlock = path
|
|
197
|
+
},
|
|
198
|
+
exit (path) {
|
|
199
|
+
currentBlock = bindingsMap.get(path).parent
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
Identifier (path) {
|
|
203
|
+
if (
|
|
204
|
+
checkBindThis(path) &&
|
|
205
|
+
!path.scope.hasBinding(path.node.name) &&
|
|
206
|
+
!ignoreMap[path.node.name]
|
|
207
|
+
) {
|
|
208
|
+
const { last, keyPath } = calPropName(path)
|
|
209
|
+
path.needBind = true
|
|
210
|
+
if (needCollect) {
|
|
211
|
+
last.collectPath = t.stringLiteral(keyPath)
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (!renderReduce) return
|
|
215
|
+
|
|
216
|
+
const { delPath, canDel, ignore, replace } = checkDelAndGetPath(path)
|
|
217
|
+
if (ignore) return
|
|
218
|
+
|
|
219
|
+
delPath.delInfo = {
|
|
220
|
+
keyPath,
|
|
221
|
+
canDel,
|
|
222
|
+
replace
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const { bindings } = bindingsMap.get(currentBlock)
|
|
226
|
+
const target = bindings[keyPath] || []
|
|
227
|
+
target.push({
|
|
228
|
+
path: delPath,
|
|
229
|
+
canDel
|
|
230
|
+
})
|
|
231
|
+
bindings[keyPath] = target
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
36
236
|
const bindThisVisitor = {
|
|
237
|
+
BlockStatement: {
|
|
238
|
+
enter (path) {
|
|
239
|
+
const scope = bindingsMap.get(path)
|
|
240
|
+
const parentScope = bindingsMap.get(scope.parent)
|
|
241
|
+
scope.pBindings = parentScope ? Object.assign({}, parentScope.bindings, parentScope.pBindings) : {}
|
|
242
|
+
currentBlock = path
|
|
243
|
+
},
|
|
244
|
+
exit (path) {
|
|
245
|
+
currentBlock = bindingsMap.get(path).parent
|
|
246
|
+
}
|
|
247
|
+
},
|
|
37
248
|
// 标记收集props数据
|
|
38
249
|
CallExpression: {
|
|
39
250
|
enter (path) {
|
|
@@ -50,76 +261,65 @@ module.exports = {
|
|
|
50
261
|
exit (path) {
|
|
51
262
|
if (path.isProps) {
|
|
52
263
|
// 移除无意义的__props调用
|
|
53
|
-
path.
|
|
264
|
+
const args = path.node.arguments[0]
|
|
265
|
+
path.replaceWith(args)
|
|
54
266
|
isProps = false
|
|
55
267
|
delete path.isProps
|
|
56
268
|
}
|
|
57
269
|
}
|
|
58
270
|
},
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
!(t.isMemberExpression(path.parent) && path.parentKey === 'property' && !path.parent.computed) &&
|
|
66
|
-
!t.isArrayPattern(path.parent) &&
|
|
67
|
-
!t.isObjectPattern(path.parent) &&
|
|
68
|
-
!hash[path.node.name]
|
|
69
|
-
) {
|
|
70
|
-
let current
|
|
71
|
-
let last
|
|
72
|
-
if (!path.scope.hasBinding(path.node.name) && !ignoreMap[path.node.name]) {
|
|
73
|
-
// bind this
|
|
74
|
-
path.replaceWith(t.memberExpression(t.thisExpression(), path.node))
|
|
271
|
+
// enter 先于特定标识执行
|
|
272
|
+
enter (path) {
|
|
273
|
+
// 删除重复变量
|
|
274
|
+
if (path.delInfo) {
|
|
275
|
+
const { keyPath, canDel, replace } = path.delInfo
|
|
276
|
+
delete path.delInfo
|
|
75
277
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
278
|
+
if (canDel) {
|
|
279
|
+
const data = bindingsMap.get(currentBlock)
|
|
280
|
+
const { bindings, pBindings } = data
|
|
281
|
+
const allBindings = Object.assign({}, pBindings, bindings)
|
|
79
282
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
keyPath += `.${current.node.property.value}`
|
|
93
|
-
} else {
|
|
94
|
-
keyPath += `[${current.node.property.value}]`
|
|
95
|
-
}
|
|
96
|
-
} else {
|
|
97
|
-
break
|
|
98
|
-
}
|
|
99
|
-
} else {
|
|
100
|
-
if (dangerousKeyMap[current.node.property.name]) {
|
|
101
|
-
break
|
|
102
|
-
}
|
|
103
|
-
keyPath += `.${current.node.property.name}`
|
|
283
|
+
// 优先判断前缀,再判断全等
|
|
284
|
+
if (checkPrefix(Object.keys(allBindings), keyPath) || pBindings[keyPath]) {
|
|
285
|
+
dealRemove(path, replace)
|
|
286
|
+
return
|
|
287
|
+
} else {
|
|
288
|
+
const currentBlockVars = bindings[keyPath]
|
|
289
|
+
if (currentBlockVars.length > 1) {
|
|
290
|
+
const index = currentBlockVars.findIndex(item => !item.canDel)
|
|
291
|
+
if (index !== -1 || currentBlockVars[0].path !== path) { // 当前block中存在不可删除的变量 || 不是第一个可删除变量,即可删除该变量
|
|
292
|
+
dealRemove(path, replace)
|
|
293
|
+
return
|
|
104
294
|
}
|
|
105
|
-
last = current
|
|
106
|
-
current = current.parentPath
|
|
107
295
|
}
|
|
108
|
-
last.collectPath = t.stringLiteral(keyPath)
|
|
109
296
|
}
|
|
110
297
|
}
|
|
111
298
|
}
|
|
299
|
+
|
|
300
|
+
// bind this 将 a 转换成 this.a
|
|
301
|
+
if (path.needBind) {
|
|
302
|
+
const name = path.node.name
|
|
303
|
+
if (name) { // 确保path没有被删除 且 没有被替换成字符串
|
|
304
|
+
if (isProps) {
|
|
305
|
+
propKeys.push(name)
|
|
306
|
+
}
|
|
307
|
+
path.replaceWith(t.memberExpression(t.thisExpression(), path.node))
|
|
308
|
+
}
|
|
309
|
+
delete path.needBind
|
|
310
|
+
}
|
|
112
311
|
},
|
|
113
312
|
MemberExpression: {
|
|
114
313
|
exit (path) {
|
|
115
314
|
if (path.collectPath) {
|
|
116
|
-
path.replaceWith(t.callExpression(t.memberExpression(t.thisExpression(), t.identifier('_c')), [path.collectPath, path.node]))
|
|
315
|
+
path.node && path.replaceWith(t.callExpression(t.memberExpression(t.thisExpression(), t.identifier('_c')), [path.collectPath, path.node]))
|
|
117
316
|
delete path.collectPath
|
|
118
317
|
}
|
|
119
318
|
}
|
|
120
319
|
}
|
|
121
320
|
}
|
|
122
321
|
|
|
322
|
+
traverse(ast, collectVisitor)
|
|
123
323
|
traverse(ast, bindThisVisitor)
|
|
124
324
|
|
|
125
325
|
return {
|
|
@@ -10,40 +10,13 @@ const getRulesRunner = require('../platform/index')
|
|
|
10
10
|
const addQuery = require('../utils/add-query')
|
|
11
11
|
const transDynamicClassExpr = require('./trans-dynamic-class-expr')
|
|
12
12
|
const dash2hump = require('../utils/hump-dash').dash2hump
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
* Make a map and return a function for checking if a key
|
|
16
|
-
* is in that map.
|
|
17
|
-
*/
|
|
18
|
-
function makeMap (str, expectsLowerCase) {
|
|
19
|
-
const map = Object.create(null)
|
|
20
|
-
const list = str.split(',')
|
|
21
|
-
for (let i = 0; i < list.length; i++) {
|
|
22
|
-
map[list[i]] = true
|
|
23
|
-
}
|
|
24
|
-
return expectsLowerCase
|
|
25
|
-
? function (val) {
|
|
26
|
-
return map[val.toLowerCase()]
|
|
27
|
-
}
|
|
28
|
-
: function (val) {
|
|
29
|
-
return map[val]
|
|
30
|
-
}
|
|
31
|
-
}
|
|
13
|
+
const makeMap = require('../utils/make-map')
|
|
14
|
+
const { isNonPhrasingTag } = require('../utils/dom-tag-config')
|
|
32
15
|
|
|
33
16
|
const no = function () {
|
|
34
17
|
return false
|
|
35
18
|
}
|
|
36
19
|
|
|
37
|
-
// HTML5 tags https://html.spec.whatwg.org/multipage/indices.html#elements-3
|
|
38
|
-
// Phrasing Content https://html.spec.whatwg.org/multipage/dom.html#phrasing-content
|
|
39
|
-
const isNonPhrasingTag = makeMap(
|
|
40
|
-
'address,article,aside,base,blockquote,body,caption,col,colgroup,dd,' +
|
|
41
|
-
'details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,' +
|
|
42
|
-
'h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,' +
|
|
43
|
-
'optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,' +
|
|
44
|
-
'title,tr,track'
|
|
45
|
-
)
|
|
46
|
-
|
|
47
20
|
/*!
|
|
48
21
|
* HTML Parser By John Resig (ejohn.org)
|
|
49
22
|
* Modified by Juriy "kangax" Zaytsev
|
|
@@ -653,6 +626,9 @@ function parse (template, options) {
|
|
|
653
626
|
srcMode,
|
|
654
627
|
type: 'template',
|
|
655
628
|
testKey: 'tag',
|
|
629
|
+
data: {
|
|
630
|
+
usingComponents: options.usingComponents
|
|
631
|
+
},
|
|
656
632
|
warn: _warn,
|
|
657
633
|
error: _error
|
|
658
634
|
})
|
|
@@ -20,6 +20,7 @@ module.exports = function (raw) {
|
|
|
20
20
|
const packageName = queryObj.packageRoot || mpx.currentPackageRoot || 'main'
|
|
21
21
|
const componentsMap = mpx.componentsMap[packageName]
|
|
22
22
|
const wxsContentMap = mpx.wxsContentMap
|
|
23
|
+
const renderOptimizeRules = mpx.renderOptimizeRules
|
|
23
24
|
const usingComponents = queryObj.usingComponents || []
|
|
24
25
|
const componentPlaceholder = queryObj.componentPlaceholder || []
|
|
25
26
|
const hasComment = queryObj.hasComment
|
|
@@ -97,6 +98,7 @@ global.currentInject = {
|
|
|
97
98
|
try {
|
|
98
99
|
bindResult = bindThis(rawCode, {
|
|
99
100
|
needCollect: true,
|
|
101
|
+
renderReduce: matchCondition(resourcePath, renderOptimizeRules),
|
|
100
102
|
ignoreMap: meta.wxsModuleMap
|
|
101
103
|
})
|
|
102
104
|
} catch (e) {
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// These tag configs are shared between compiler-dom and runtime-dom, so they
|
|
2
|
+
// must be extracted in shared to avoid creating a dependency between the two.
|
|
3
|
+
const makeMap = require('./make-map')
|
|
4
|
+
|
|
5
|
+
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element
|
|
6
|
+
const HTML_TAGS =
|
|
7
|
+
'html,body,base,head,link,meta,style,title,address,article,aside,footer,' +
|
|
8
|
+
'header,hgroup,h1,h2,h3,h4,h5,h6,nav,section,div,dd,dl,dt,figcaption,' +
|
|
9
|
+
'figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,' +
|
|
10
|
+
'data,dfn,em,i,kbd,mark,q,rp,rt,ruby,s,samp,small,span,strong,sub,sup,' +
|
|
11
|
+
'time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,' +
|
|
12
|
+
'canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,' +
|
|
13
|
+
'th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,' +
|
|
14
|
+
'option,output,progress,select,textarea,details,dialog,menu,' +
|
|
15
|
+
'summary,template,blockquote,iframe,tfoot'
|
|
16
|
+
|
|
17
|
+
// https://developer.mozilla.org/en-US/docs/Web/SVG/Element
|
|
18
|
+
const SVG_TAGS =
|
|
19
|
+
'svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,' +
|
|
20
|
+
'defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,' +
|
|
21
|
+
'feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,' +
|
|
22
|
+
'feDistantLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,' +
|
|
23
|
+
'feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,' +
|
|
24
|
+
'fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,' +
|
|
25
|
+
'foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,' +
|
|
26
|
+
'mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,' +
|
|
27
|
+
'polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,' +
|
|
28
|
+
'text,textPath,title,tspan,unknown,use,view'
|
|
29
|
+
|
|
30
|
+
const VOID_TAGS =
|
|
31
|
+
'area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr'
|
|
32
|
+
|
|
33
|
+
// HTML5 tags https://html.spec.whatwg.org/multipage/indices.html#elements-3
|
|
34
|
+
// Phrasing Content https://html.spec.whatwg.org/multipage/dom.html#phrasing-content
|
|
35
|
+
const isNonPhrasingTag = makeMap(
|
|
36
|
+
'address,article,aside,base,blockquote,body,caption,col,colgroup,dd,' +
|
|
37
|
+
'details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,' +
|
|
38
|
+
'h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,' +
|
|
39
|
+
'optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,' +
|
|
40
|
+
'title,tr,track'
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
const isRichTextTag = makeMap(
|
|
44
|
+
'a,abbr,address,article,aside,b,bdi,bdo,big,blockquote,br,caption,' +
|
|
45
|
+
'center,cite,code,col,colgroup,dd,del,div,dl,dt,em,fieldset,' +
|
|
46
|
+
'font,footer,h1,h2,h3,h4,h5,h6,header,hr,i,img,ins,label,legend,' +
|
|
47
|
+
'li,mark,nav,ol,p,pre,q,rt,ruby,s,section,small,span,strong,sub,sup,' +
|
|
48
|
+
'table,tbody,td,tfoot,th,thead,tr,tt,u,ul'
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
const isUnaryTag = makeMap(
|
|
52
|
+
'area,base,br,col,embed,frame,hr,img,input,isindex,keygen,' +
|
|
53
|
+
'link,meta,param,source,track,wbr'
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
// https://developers.weixin.qq.com/miniprogram/dev/component/
|
|
57
|
+
// 以后可能在框架中原生支持这些标签,所以需要进行判断
|
|
58
|
+
const isNativeMiniTag = makeMap(
|
|
59
|
+
'cover-image,cover-view,match-media,movable-area,movable-view,' +
|
|
60
|
+
'page-container,root-portal,scroll-view,swiper,swiper-item,view,' +
|
|
61
|
+
'icon,progress,rich-text,text,button,checkbox,checkbox-group,editor,' +
|
|
62
|
+
'form,input,keyboard-accessory,label,picker,picker-view,' +
|
|
63
|
+
'picker-view-column,radio,radio-group,slider,switch,textarea,' +
|
|
64
|
+
'grid-view,list-view,share-element,snapshot,span,sticky-header,' +
|
|
65
|
+
'sticky-section,functional-page-navigator,navigator,audio,camera,' +
|
|
66
|
+
'channel-live,channel-video,image,live-player,live-pusher,video,' +
|
|
67
|
+
'voip-room,map,canvas,web-view,ad,ad-custom,official-account,' +
|
|
68
|
+
'open-data,native-component,aria-component,page-meta'
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
const isSpace = makeMap('ensp,emsp,nbsp')
|
|
72
|
+
|
|
73
|
+
const isContWidth = makeMap('col,colgroup,img,table,td,th,tr')
|
|
74
|
+
|
|
75
|
+
const isContHeight = makeMap('img,td,th,tr')
|
|
76
|
+
|
|
77
|
+
const isContConRow = makeMap('td,th,tr')
|
|
78
|
+
|
|
79
|
+
const isHTMLTag = makeMap(HTML_TAGS)
|
|
80
|
+
|
|
81
|
+
const isSVGTag = makeMap(SVG_TAGS)
|
|
82
|
+
|
|
83
|
+
const isVoidTag = makeMap(VOID_TAGS)
|
|
84
|
+
|
|
85
|
+
// 是否为原始tag,包括 html tag 和小程序原生 tag
|
|
86
|
+
const isOriginTag = (tag) => isHTMLTag(tag) || isSVGTag(tag) || isVoidTag(tag) || isNativeMiniTag(tag)
|
|
87
|
+
|
|
88
|
+
module.exports = {
|
|
89
|
+
isOriginTag,
|
|
90
|
+
isHTMLTag,
|
|
91
|
+
isSVGTag,
|
|
92
|
+
isVoidTag,
|
|
93
|
+
isNonPhrasingTag,
|
|
94
|
+
isRichTextTag,
|
|
95
|
+
isUnaryTag,
|
|
96
|
+
isSpace,
|
|
97
|
+
isContWidth,
|
|
98
|
+
isContHeight,
|
|
99
|
+
isNativeMiniTag,
|
|
100
|
+
isContConRow
|
|
101
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Make a map and return a function for checking if a key
|
|
3
|
+
* is in that map.
|
|
4
|
+
*/
|
|
5
|
+
module.exports = function makeMap (str, expectsLowerCase) {
|
|
6
|
+
const map = Object.create(null)
|
|
7
|
+
const list = str.split(',')
|
|
8
|
+
for (let i = 0; i < list.length; i++) {
|
|
9
|
+
map[list[i]] = true
|
|
10
|
+
}
|
|
11
|
+
return expectsLowerCase ? val => !!map[val.toLowerCase()] : val => !!map[val]
|
|
12
|
+
}
|
package/lib/utils/string.js
CHANGED
|
@@ -23,8 +23,14 @@ function capitalToHyphen (v) {
|
|
|
23
23
|
return ret
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
// 删除空行
|
|
27
|
+
function trimBlankRow (str) {
|
|
28
|
+
return str.replace(/^\s*[\r\n]/gm, '')
|
|
29
|
+
}
|
|
30
|
+
|
|
26
31
|
module.exports = {
|
|
27
32
|
isCapital,
|
|
28
33
|
isMustache,
|
|
29
|
-
capitalToHyphen
|
|
34
|
+
capitalToHyphen,
|
|
35
|
+
trimBlankRow
|
|
30
36
|
}
|
package/lib/web/processJSON.js
CHANGED
|
@@ -9,8 +9,10 @@ const parseComponent = require('../parser')
|
|
|
9
9
|
const getJSONContent = require('../utils/get-json-content')
|
|
10
10
|
const resolve = require('../utils/resolve')
|
|
11
11
|
const createJSONHelper = require('../json-compiler/helper')
|
|
12
|
+
const getRulesRunner = require('../platform/index')
|
|
12
13
|
const { RESOLVE_IGNORED_ERR } = require('../utils/const')
|
|
13
14
|
const RecordResourceMapDependency = require('../dependencies/RecordResourceMapDependency')
|
|
15
|
+
const RecordGlobalComponentsDependency = require('../dependencies/RecordGlobalComponentsDependency')
|
|
14
16
|
|
|
15
17
|
module.exports = function (json, {
|
|
16
18
|
loaderContext,
|
|
@@ -26,6 +28,7 @@ module.exports = function (json, {
|
|
|
26
28
|
const mpx = loaderContext.getMpx()
|
|
27
29
|
const {
|
|
28
30
|
mode,
|
|
31
|
+
srcMode,
|
|
29
32
|
env,
|
|
30
33
|
projectRoot
|
|
31
34
|
} = mpx
|
|
@@ -75,12 +78,44 @@ module.exports = function (json, {
|
|
|
75
78
|
})
|
|
76
79
|
}
|
|
77
80
|
|
|
81
|
+
const { resourcePath } = parseRequest(loaderContext.resource)
|
|
82
|
+
const isApp = !(pagesMap[resourcePath] || componentsMap[resourcePath])
|
|
83
|
+
|
|
78
84
|
if (!json) {
|
|
79
85
|
return callback()
|
|
80
86
|
}
|
|
81
87
|
// 由于json需要提前读取在template处理中使用,src的场景已经在loader中处理了,此处无需考虑json.src的场景
|
|
82
88
|
try {
|
|
83
89
|
jsonObj = JSON5.parse(json.content)
|
|
90
|
+
// 处理runner
|
|
91
|
+
const rulesRunnerOptions = {
|
|
92
|
+
mode,
|
|
93
|
+
srcMode,
|
|
94
|
+
type: 'json',
|
|
95
|
+
waterfall: true,
|
|
96
|
+
warn: emitWarning,
|
|
97
|
+
error: emitError,
|
|
98
|
+
data: {
|
|
99
|
+
// polyfill global usingComponents & record globalComponents
|
|
100
|
+
globalComponents: mpx.usingComponents
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (!isApp) {
|
|
105
|
+
rulesRunnerOptions.mainKey = pagesMap[resourcePath] ? 'page' : 'component'
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const rulesRunner = getRulesRunner(rulesRunnerOptions)
|
|
109
|
+
|
|
110
|
+
if (rulesRunner) {
|
|
111
|
+
rulesRunner(jsonObj)
|
|
112
|
+
}
|
|
113
|
+
if (isApp) {
|
|
114
|
+
// 收集全局组件
|
|
115
|
+
Object.assign(mpx.usingComponents, jsonObj.usingComponents)
|
|
116
|
+
// 在 rulesRunner 运行后保存全局注册组件
|
|
117
|
+
loaderContext._module.addPresentationalDependency(new RecordGlobalComponentsDependency(mpx.usingComponents, loaderContext.context))
|
|
118
|
+
}
|
|
84
119
|
} catch (e) {
|
|
85
120
|
return callback(e)
|
|
86
121
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mpxjs/webpack-plugin",
|
|
3
|
-
"version": "2.8.
|
|
3
|
+
"version": "2.8.50",
|
|
4
4
|
"description": "mpx compile core",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mpx"
|
|
@@ -29,7 +29,6 @@
|
|
|
29
29
|
"@better-scroll/zoom": "^2.5.1",
|
|
30
30
|
"acorn-walk": "^7.2.0",
|
|
31
31
|
"async": "^2.6.0",
|
|
32
|
-
"consolidate": "^0.15.1",
|
|
33
32
|
"css": "^2.2.1",
|
|
34
33
|
"css-selector-tokenizer": "^0.7.0",
|
|
35
34
|
"cssnano": "^5.0.16",
|
|
@@ -82,5 +81,5 @@
|
|
|
82
81
|
"engines": {
|
|
83
82
|
"node": ">=14.14.0"
|
|
84
83
|
},
|
|
85
|
-
"gitHead": "
|
|
84
|
+
"gitHead": "32f30631cc5f37503fb7791cb3b0d6c901ee2b27"
|
|
86
85
|
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
// loader for pre-processing templates with e.g. pug
|
|
2
|
-
|
|
3
|
-
const cons = require('consolidate')
|
|
4
|
-
const loaderUtils = require('loader-utils')
|
|
5
|
-
|
|
6
|
-
module.exports = function (content) {
|
|
7
|
-
this.cacheable && this.cacheable()
|
|
8
|
-
const callback = this.async()
|
|
9
|
-
const opt = loaderUtils.getOptions(this) || {}
|
|
10
|
-
|
|
11
|
-
if (!cons[opt.engine]) {
|
|
12
|
-
return callback(new Error(
|
|
13
|
-
'Template engine \'' + opt.engine + '\' ' +
|
|
14
|
-
'isn\'t available in Consolidate.js'
|
|
15
|
-
))
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const templateOption = opt.templateOption
|
|
19
|
-
|
|
20
|
-
// for relative includes
|
|
21
|
-
templateOption.filename = this.resourcePath
|
|
22
|
-
|
|
23
|
-
cons[opt.engine].render(content, templateOption, function (err, html) {
|
|
24
|
-
if (err) {
|
|
25
|
-
return callback(err)
|
|
26
|
-
}
|
|
27
|
-
callback(null, html)
|
|
28
|
-
})
|
|
29
|
-
}
|