@mpxjs/webpack-plugin 2.7.1-beta.9 → 2.7.1

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.
@@ -22,6 +22,7 @@ class RecordResourceMapDependency extends NullDependency {
22
22
  resourceType,
23
23
  outputPath,
24
24
  packageRoot,
25
+ recordOnly: true,
25
26
  warn (e) {
26
27
  compilation.warnings.push(e)
27
28
  },
package/lib/index.js CHANGED
@@ -566,7 +566,7 @@ class MpxWebpackPlugin {
566
566
  const hash = mpx.pathHash(resourcePath)
567
567
  const customOutputPath = this.options.customOutputPath
568
568
  if (conflictPath) return conflictPath.replace(/(\.[^\\/]+)?$/, match => hash + match)
569
- if (typeof customOutputPath === 'function') return customOutputPath(type, name, hash, ext)
569
+ if (typeof customOutputPath === 'function') return customOutputPath(type, name, hash, ext).replace(/^\//, '')
570
570
  if (type === 'component' || type === 'page') return path.join(type + 's', name + hash, 'index' + ext)
571
571
  return path.join(type, name + hash + ext)
572
572
  },
@@ -597,25 +597,28 @@ class MpxWebpackPlugin {
597
597
  mpx.extractedFilesCache.set(resource, file)
598
598
  return file
599
599
  },
600
- recordResourceMap: ({ resourcePath, resourceType, outputPath, packageRoot = '', warn, error }) => {
600
+ recordResourceMap: ({ resourcePath, resourceType, outputPath, packageRoot = '', recordOnly, warn, error }) => {
601
601
  const packageName = packageRoot || 'main'
602
602
  const resourceMap = mpx[`${resourceType}sMap`] || mpx.otherResourcesMap
603
603
  const currentResourceMap = resourceMap.main ? resourceMap[packageName] = resourceMap[packageName] || {} : resourceMap
604
+ let alreadyOutputted = false
604
605
  if (outputPath) {
605
606
  if (!currentResourceMap[resourcePath] || currentResourceMap[resourcePath] === true) {
606
- // 输出路径冲突检测,如果存在输出路径冲突,对输出路径进行重命名
607
- // todo 用outputPathMap来检测输出路径冲突
608
- for (let key in currentResourceMap) {
609
- if (currentResourceMap[key] === outputPath && key !== resourcePath) {
610
- outputPath = mpx.getOutputPath(resourcePath, resourceType, { conflictPath: outputPath })
611
- warn && warn(new Error(`Current ${resourceType} [${resourcePath}] is registered with conflicted outputPath [${currentResourceMap[key]}] which is already existed in system, will be renamed with [${outputPath}], use ?resolve to get the real outputPath!`))
612
- break
607
+ if (!recordOnly) {
608
+ // 在非recordOnly的模式下,进行输出路径冲突检测,如果存在输出路径冲突,则对输出路径进行重命名
609
+ for (let key in currentResourceMap) {
610
+ // todo 用outputPathMap来检测输出路径冲突
611
+ if (currentResourceMap[key] === outputPath && key !== resourcePath) {
612
+ outputPath = mpx.getOutputPath(resourcePath, resourceType, { conflictPath: outputPath })
613
+ warn && warn(new Error(`Current ${resourceType} [${resourcePath}] is registered with conflicted outputPath [${currentResourceMap[key]}] which is already existed in system, will be renamed with [${outputPath}], use ?resolve to get the real outputPath!`))
614
+ break
615
+ }
613
616
  }
614
617
  }
615
618
  currentResourceMap[resourcePath] = outputPath
616
619
  } else {
617
620
  if (currentResourceMap[resourcePath] === outputPath) {
618
- return true
621
+ alreadyOutputted = true
619
622
  } else {
620
623
  error && error(new Error(`Current ${resourceType} [${resourcePath}] is already registered with outputPath [${currentResourceMap[resourcePath]}], you can not register it with another outputPath [${outputPath}]!`))
621
624
  }
@@ -623,7 +626,11 @@ class MpxWebpackPlugin {
623
626
  } else if (!currentResourceMap[resourcePath]) {
624
627
  currentResourceMap[resourcePath] = true
625
628
  }
626
- return false
629
+
630
+ return {
631
+ outputPath,
632
+ alreadyOutputted
633
+ }
627
634
  },
628
635
  // 组件和静态资源的输出规则如下:
629
636
  // 1. 主包引用的资源输出至主包
@@ -675,20 +682,18 @@ class MpxWebpackPlugin {
675
682
 
676
683
  if (outputPath) outputPath = toPosix(path.join(packageRoot, outputPath))
677
684
 
678
- const alreadyOutputted = mpx.recordResourceMap({
679
- resourcePath,
680
- resourceType,
681
- outputPath,
682
- packageRoot,
683
- warn,
684
- error
685
- })
686
-
687
685
  return {
688
686
  packageName,
689
687
  packageRoot,
690
- outputPath,
691
- alreadyOutputted
688
+ // 返回outputPath及alreadyOutputted
689
+ ...mpx.recordResourceMap({
690
+ resourcePath,
691
+ resourceType,
692
+ outputPath,
693
+ packageRoot,
694
+ warn,
695
+ error
696
+ })
692
697
  }
693
698
  }
694
699
  }
@@ -763,12 +768,13 @@ class MpxWebpackPlugin {
763
768
  }
764
769
  }
765
770
  } else if (independent) {
766
- // ContextModule和RawModule只在独立分包的情况下添加分包标记,其余默认不添加
771
+ // ContextModule/RawModuleExternalModule等只在独立分包的情况下添加分包标记,其余默认不添加
767
772
  const postfix = `|independent=${independent}|${currentPackageRoot}`
768
- if (module._identifier) {
769
- module._identifier += postfix
770
- } else if (module.identifierStr) {
771
- module.identifierStr += postfix
773
+ const rawIdentifier = module.identifier
774
+ if (rawIdentifier) {
775
+ module.identifier = () => {
776
+ return rawIdentifier.call(module) + postfix
777
+ }
772
778
  }
773
779
  }
774
780
  return rawAddModule.call(compilation, module, callback)
@@ -97,7 +97,7 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning, custom
97
97
  const ext = path.extname(resourcePath)
98
98
  let outputPath
99
99
  if (aliasPath) {
100
- outputPath = aliasPath
100
+ outputPath = aliasPath.replace(/^\//, '')
101
101
  } else {
102
102
  const relative = path.relative(context, resourcePath)
103
103
  if (/^\./.test(relative)) {
@@ -41,7 +41,9 @@
41
41
  },
42
42
  data () {
43
43
  return {
44
- currentIndex: this.current
44
+ currentIndex: this.current,
45
+ currentChildLength: 0,
46
+ lastChildLength: 0
45
47
  }
46
48
  },
47
49
  computed: {
@@ -81,6 +83,9 @@
81
83
  }
82
84
  }
83
85
  },
86
+ updated () {
87
+ this.currentChildLength = this.$children && this.$children.length
88
+ },
84
89
  watch: {
85
90
  current (val) {
86
91
  if (this.bs) {
@@ -89,6 +94,15 @@
89
94
  }
90
95
  this.changeSource = ''
91
96
  this.goto(val)
97
+ },
98
+ currentChildLength(val) {
99
+ if (val < this.lastChildLength && val < this.currentIndex) {
100
+ this.goto(0, 0)
101
+ }
102
+ if (this.lastChildLength || (!this.lastChildLength && !this.autoplay)) {
103
+ this.bs && this.bs.refresh()
104
+ }
105
+ this.lastChildLength = val
92
106
  }
93
107
  },
94
108
  activated () {
@@ -167,10 +181,11 @@
167
181
  refresh () {
168
182
  this.bs && this.bs.refresh()
169
183
  },
170
- goto (index) {
184
+ goto (index, time) {
171
185
  const x = this.vertical ? 0 : index
172
186
  const y = this.vertical ? index : 0
173
- this.bs && this.bs.goToPage(x, y)
187
+ const speed = time === 0 ? 0 : this.duration
188
+ this.bs && this.bs.goToPage(x, y, speed)
174
189
  }
175
190
  },
176
191
  render (createElement) {
@@ -120,6 +120,8 @@ function stringifyArray (value) {
120
120
  }
121
121
 
122
122
  var mpxDashReg = genRegExp('(.+)MpxDash$')
123
+ // 转义字符在wxs正则中存在平台兼容性问题,用[$]规避使用转义字符
124
+ var mpxDashReplaceReg = genRegExp('[$]', 'g')
123
125
 
124
126
  function stringifyObject (value) {
125
127
  var res = ''
@@ -129,7 +131,7 @@ function stringifyObject (value) {
129
131
  if (value[key]) {
130
132
  if (res) res += ' '
131
133
  if (mpxDashReg.test(key)) {
132
- key = hump2dash(mpxDashReg.exec(key)[1])
134
+ key = mpxDashReg.exec(key)[1].replace(mpxDashReplaceReg, '-')
133
135
  }
134
136
  res += key
135
137
  }
@@ -1,5 +1,3 @@
1
- const postcss = require('postcss')
2
-
3
1
  /**
4
2
  * 按平台条件编译CSS,用法如下:
5
3
  * @type {postcss.Plugin<any>}
@@ -44,7 +42,7 @@ const postcss = require('postcss')
44
42
  // @mpx-endif
45
43
  // */
46
44
  // `
47
- module.exports = postcss.plugin('conditional-strip', (options = {}) => {
45
+ module.exports = (options = {}) => {
48
46
  const { defs } = options
49
47
 
50
48
  const defKeys = Object.keys(defs)
@@ -91,71 +89,76 @@ module.exports = postcss.plugin('conditional-strip', (options = {}) => {
91
89
  return parseCondition(/@mpx-elif[^(]*?\(([\s\S]*)\)/, content)
92
90
  }
93
91
 
94
- return function (root, result) {
95
- const condsStacks = []
96
- const currentConds = []
97
- let curDepth = -1
92
+ return {
93
+ postcssPlugin: 'conditional-strip',
94
+ Once (root) {
95
+ const condsStacks = []
96
+ const currentConds = []
97
+ let curDepth = -1
98
98
 
99
- root.walk(node => {
100
- let isKeyword = false
101
- if (node.type === 'comment') {
102
- const { text } = node
103
- if (isIfStart(text)) {
104
- isKeyword = true
105
- const cond = parseIf(text)
106
- curDepth++
107
- const parentCond = currentConds[curDepth - 1]
108
- if (parentCond && parentCond.shouldRemove) {
109
- cond.shouldRemove = true
110
- }
111
- cond.children.push(node)
112
- condsStacks.push({
113
- if: cond
114
- })
115
- currentConds[curDepth] = cond
116
- } else if (isElseIf(text)) {
117
- isKeyword = true
118
- const cond = parseElseIf(text)
119
- const parentCond = currentConds[curDepth - 1]
120
- if (parentCond && parentCond.shouldRemove) {
121
- cond.shouldRemove = true
122
- }
123
- cond.children.push(node)
124
- condsStacks[curDepth].elif = cond
125
- currentConds[curDepth] = cond
126
- } else if (isElse(text)) {
127
- isKeyword = true
128
- const curConds = condsStacks[curDepth]
129
- const cond = {
130
- shouldRemove: !(curConds.if.shouldRemove && (!curConds.elif || curConds.elif.shouldRemove)),
131
- children: [node]
132
- }
133
- const parentCond = currentConds[curDepth - 1]
134
- if (parentCond && parentCond.shouldRemove) {
135
- cond.shouldRemove = true
136
- }
137
- condsStacks[curDepth].else = cond
138
- currentConds[curDepth] = cond
139
- } else if (isEndIf(text)) {
140
- isKeyword = true
141
- const curConds = condsStacks.pop()
142
- Object.keys(curConds).forEach(k => {
143
- curConds[k].children.forEach(node => {
144
- node.remove()
99
+ root.walk(node => {
100
+ let isKeyword = false
101
+ if (node.type === 'comment') {
102
+ const { text } = node
103
+ if (isIfStart(text)) {
104
+ isKeyword = true
105
+ const cond = parseIf(text)
106
+ curDepth++
107
+ const parentCond = currentConds[curDepth - 1]
108
+ if (parentCond && parentCond.shouldRemove) {
109
+ cond.shouldRemove = true
110
+ }
111
+ cond.children.push(node)
112
+ condsStacks.push({
113
+ if: cond
145
114
  })
146
- })
147
- currentConds.pop()
148
- curDepth--
149
- node.remove()
115
+ currentConds[curDepth] = cond
116
+ } else if (isElseIf(text)) {
117
+ isKeyword = true
118
+ const cond = parseElseIf(text)
119
+ const parentCond = currentConds[curDepth - 1]
120
+ if (parentCond && parentCond.shouldRemove) {
121
+ cond.shouldRemove = true
122
+ }
123
+ cond.children.push(node)
124
+ condsStacks[curDepth].elif = cond
125
+ currentConds[curDepth] = cond
126
+ } else if (isElse(text)) {
127
+ isKeyword = true
128
+ const curConds = condsStacks[curDepth]
129
+ const cond = {
130
+ shouldRemove: !(curConds.if.shouldRemove && (!curConds.elif || curConds.elif.shouldRemove)),
131
+ children: [node]
132
+ }
133
+ const parentCond = currentConds[curDepth - 1]
134
+ if (parentCond && parentCond.shouldRemove) {
135
+ cond.shouldRemove = true
136
+ }
137
+ condsStacks[curDepth].else = cond
138
+ currentConds[curDepth] = cond
139
+ } else if (isEndIf(text)) {
140
+ isKeyword = true
141
+ const curConds = condsStacks.pop()
142
+ Object.keys(curConds).forEach(k => {
143
+ curConds[k].children.forEach(node => {
144
+ node.remove()
145
+ })
146
+ })
147
+ currentConds.pop()
148
+ curDepth--
149
+ node.remove()
150
+ }
150
151
  }
151
- }
152
152
 
153
- if (!isKeyword) {
154
- const curCond = currentConds[curDepth]
155
- if (curCond && curCond.shouldRemove) {
156
- curCond.children.push(node)
153
+ if (!isKeyword) {
154
+ const curCond = currentConds[curDepth]
155
+ if (curCond && curCond.shouldRemove) {
156
+ curCond.children.push(node)
157
+ }
157
158
  }
158
- }
159
- })
159
+ })
160
+ }
160
161
  }
161
- })
162
+ }
163
+
164
+ module.exports.postcss = true
@@ -1,45 +1,51 @@
1
- const postcss = require('postcss')
2
1
  const pxRegExp = /\b(\d+(\.\d+)?)px\b/
3
2
  const pxRegExpG = /\b(\d+(\.\d+)?)px\b/g
3
+ // rpx
4
+ module.exports = (options = {}) => {
5
+ return {
6
+ postcssPlugin: 'rpx',
7
+ Once (root) {
8
+ const mode = options.mode || 'only'
9
+ const defaultIgnoreComment = mode === 'all' ? 'use px' : 'use rpx'
10
+ const baseWidth = 750
11
+ const designWidth = options.designWidth || 750
12
+ const ratio = +(baseWidth / designWidth).toFixed(2)
13
+ function isIgnoreComment (node) {
14
+ let result = node && node.type === 'comment' && node.text.trim() === (options.comment || defaultIgnoreComment)
15
+ if (result) {
16
+ node.remove()
17
+ }
18
+ return result
19
+ }
4
20
 
5
- module.exports = postcss.plugin('rpx', (options = {}) => root => {
6
- const mode = options.mode || 'only'
7
- const defaultIgnoreComment = mode === 'all' ? 'use px' : 'use rpx'
8
- const baseWidth = 750
9
- const designWidth = options.designWidth || 750
10
- const ratio = +(baseWidth / designWidth).toFixed(2)
11
- function isIgnoreComment (node) {
12
- let result = node && node.type === 'comment' && node.text.trim() === (options.comment || defaultIgnoreComment)
13
- if (result) {
14
- node.remove()
15
- }
16
- return result
17
- }
21
+ function transRpx (declaration) {
22
+ if (pxRegExp.test(declaration.value)) {
23
+ declaration.value = declaration.value.replace(pxRegExpG, function (match, $1) {
24
+ if ($1 === '0') return $1
25
+ return `${$1 * ratio}rpx`
26
+ })
27
+ }
28
+ }
18
29
 
19
- function transRpx (declaration) {
20
- if (pxRegExp.test(declaration.value)) {
21
- declaration.value = declaration.value.replace(pxRegExpG, function (match, $1) {
22
- if ($1 === '0') return $1
23
- return `${$1 * ratio}rpx`
30
+ root.walkRules(rule => {
31
+ let ignore = false
32
+ if (isIgnoreComment(rule.prev()) || isIgnoreComment(rule.last)) {
33
+ ignore = true
34
+ }
35
+ rule.walkDecls(declaration => {
36
+ if (ignore || isIgnoreComment(declaration.prev())) {
37
+ if (mode === 'only') {
38
+ transRpx(declaration)
39
+ }
40
+ } else {
41
+ if (mode === 'all') {
42
+ transRpx(declaration)
43
+ }
44
+ }
45
+ })
24
46
  })
25
47
  }
26
48
  }
49
+ }
27
50
 
28
- root.walkRules(rule => {
29
- let ignore = false
30
- if (isIgnoreComment(rule.prev()) || isIgnoreComment(rule.last)) {
31
- ignore = true
32
- }
33
- rule.walkDecls(declaration => {
34
- if (ignore || isIgnoreComment(declaration.prev())) {
35
- if (mode === 'only') {
36
- transRpx(declaration)
37
- }
38
- } else {
39
- if (mode === 'all') {
40
- transRpx(declaration)
41
- }
42
- }
43
- })
44
- })
45
- })
51
+ module.exports.postcss = true
@@ -1,81 +1,88 @@
1
- const postcss = require('postcss')
2
1
  const selectorParser = require('postcss-selector-parser')
2
+ // scope-id
3
3
 
4
- module.exports = postcss.plugin('scope-id', ({ id }) => root => {
5
- const keyframes = Object.create(null)
4
+ module.exports = ({ id }) => {
5
+ return {
6
+ postcssPlugin: 'scope-id',
7
+ Once: (root) => {
8
+ const keyframes = Object.create(null)
6
9
 
7
- root.each(function rewriteSelector (node) {
8
- if (!node.selector) {
9
- // handle media queries
10
- if (node.type === 'atrule') {
11
- if (node.name === 'media' || node.name === 'supports') {
12
- node.each(rewriteSelector)
13
- } else if (/-?keyframes$/.test(node.name)) {
14
- // register keyframes
15
- keyframes[node.params] = node.params = node.params + '-' + id
16
- }
17
- }
18
- return
19
- }
20
- node.selector = selectorParser(selectors => {
21
- selectors.each(selector => {
22
- let node = null
23
- selector.each(n => {
24
- // ">>>" combinator
25
- if (n.type === 'combinator' && n.value === '>>>') {
26
- n.value = ' '
27
- n.spaces.before = n.spaces.after = ''
28
- return false
29
- }
30
- // /deep/ alias for >>>, since >>> doesn't work in SASS
31
- if (n.type === 'tag' && n.value === '/deep/') {
32
- const prev = n.prev()
33
- if (prev && prev.type === 'combinator' && prev.value === ' ') {
34
- prev.remove()
10
+ root.each(function rewriteSelector (node) {
11
+ if (!node.selector) {
12
+ // handle media queries
13
+ if (node.type === 'atrule') {
14
+ if (node.name === 'media' || node.name === 'supports') {
15
+ node.each(rewriteSelector)
16
+ } else if (/-?keyframes$/.test(node.name)) {
17
+ // register keyframes
18
+ keyframes[node.params] = node.params = node.params + '-' + id
35
19
  }
36
- n.remove()
37
- return false
38
20
  }
39
- if (n.type !== 'pseudo' && n.type !== 'combinator') {
40
- node = n
41
- }
42
- })
43
- // 对于page selector不添加scope id
44
- if (node && node.type === 'tag' && node.value === 'page') return
45
- selector.insertAfter(node, selectorParser.className({
46
- value: id
47
- }))
21
+ return
22
+ }
23
+ node.selector = selectorParser(selectors => {
24
+ selectors.each(selector => {
25
+ let node = null
26
+ selector.each(n => {
27
+ // ">>>" combinator
28
+ if (n.type === 'combinator' && n.value === '>>>') {
29
+ n.value = ' '
30
+ n.spaces.before = n.spaces.after = ''
31
+ return false
32
+ }
33
+ // /deep/ alias for >>>, since >>> doesn't work in SASS
34
+ if (n.type === 'tag' && n.value === '/deep/') {
35
+ const prev = n.prev()
36
+ if (prev && prev.type === 'combinator' && prev.value === ' ') {
37
+ prev.remove()
38
+ }
39
+ n.remove()
40
+ return false
41
+ }
42
+ if (n.type !== 'pseudo' && n.type !== 'combinator') {
43
+ node = n
44
+ }
45
+ })
46
+ // 对于page selector不添加scope id
47
+ if (node && node.type === 'tag' && node.value === 'page') return
48
+ selector.insertAfter(node, selectorParser.className({
49
+ value: id
50
+ }))
51
+ })
52
+ }).process(node.selector).result
48
53
  })
49
- }).process(node.selector).result
50
- })
51
54
 
52
- // If keyframes are found in this <style>, find and rewrite animation names
53
- // in declarations.
54
- // Caveat: this only works for keyframes and animation rules in the same
55
- // <style> element.
56
- if (Object.keys(keyframes).length) {
57
- root.walkDecls(decl => {
58
- // individual animation-name declaration
59
- if (/-?animation-name$/.test(decl.prop)) {
60
- decl.value = decl.value.split(',')
61
- .map(v => keyframes[v.trim()] || v.trim())
62
- .join(',')
63
- }
64
- // shorthand
65
- if (/-?animation$/.test(decl.prop)) {
66
- decl.value = decl.value.split(',')
67
- .map(v => {
68
- const vals = v.trim().split(/\s+/)
69
- const i = vals.findIndex(val => keyframes[val])
70
- if (i !== -1) {
71
- vals.splice(i, 1, keyframes[vals[i]])
72
- return vals.join(' ')
73
- } else {
74
- return v
75
- }
76
- })
77
- .join(',')
55
+ // If keyframes are found in this <style>, find and rewrite animation names
56
+ // in declarations.
57
+ // Caveat: this only works for keyframes and animation rules in the same
58
+ // <style> element.
59
+ if (Object.keys(keyframes).length) {
60
+ root.walkDecls(decl => {
61
+ // individual animation-name declaration
62
+ if (/-?animation-name$/.test(decl.prop)) {
63
+ decl.value = decl.value.split(',')
64
+ .map(v => keyframes[v.trim()] || v.trim())
65
+ .join(',')
66
+ }
67
+ // shorthand
68
+ if (/-?animation$/.test(decl.prop)) {
69
+ decl.value = decl.value.split(',')
70
+ .map(v => {
71
+ const vals = v.trim().split(/\s+/)
72
+ const i = vals.findIndex(val => keyframes[val])
73
+ if (i !== -1) {
74
+ vals.splice(i, 1, keyframes[vals[i]])
75
+ return vals.join(' ')
76
+ } else {
77
+ return v
78
+ }
79
+ })
80
+ .join(',')
81
+ }
82
+ })
78
83
  }
79
- })
84
+ }
80
85
  }
81
- })
86
+ }
87
+
88
+ module.exports.postcss = true
@@ -1,21 +1,28 @@
1
- const postcss = require('postcss')
2
1
  const selectorParser = require('postcss-selector-parser')
2
+ // trans-special
3
3
 
4
- module.exports = postcss.plugin('trans-special', ({ id }) => root => {
5
- root.each(function rewriteSelector (node) {
6
- if (!node.selector) return
7
- node.selector = selectorParser(selectors => {
8
- selectors.each(selector => {
9
- selector.each(n => {
10
- if (/^:host$/.test(n.value)) {
11
- const compoundSelectors = n.nodes
12
- n.replaceWith(selectorParser.className({
13
- value: 'host-' + id
14
- }))
15
- selector.insertAfter(n, compoundSelectors)
16
- }
17
- })
4
+ module.exports = ({ id }) => {
5
+ return {
6
+ postcssPlugin: 'trans-special',
7
+ Once: (root) => {
8
+ root.each(function rewriteSelector (node) {
9
+ if (!node.selector) return
10
+ node.selector = selectorParser(selectors => {
11
+ selectors.each(selector => {
12
+ selector.each(n => {
13
+ if (/^:host$/.test(n.value)) {
14
+ const compoundSelectors = n.nodes
15
+ n.replaceWith(selectorParser.className({
16
+ value: 'host-' + id
17
+ }))
18
+ selector.insertAfter(n, compoundSelectors)
19
+ }
20
+ })
21
+ })
22
+ }).process(node.selector).result
18
23
  })
19
- }).process(node.selector).result
20
- })
21
- })
24
+ }
25
+ }
26
+ }
27
+
28
+ module.exports.postcss = true
@@ -1,9 +1,15 @@
1
- const postcss = require('postcss')
2
1
 
3
- module.exports = postcss.plugin('trim', opts => css => {
4
- css.walk(({ type, raws }) => {
5
- if (type === 'rule' || type === 'atrule') {
6
- raws.before = raws.after = '\n'
2
+ module.exports = (opts) => {
3
+ return {
4
+ postcssPlugin: 'trim',
5
+ Once: (root) => {
6
+ root.walk(({ type, raws }) => {
7
+ if (type === 'rule' || type === 'atrule') {
8
+ raws.before = raws.after = '\n'
9
+ }
10
+ })
7
11
  }
8
- })
9
- })
12
+ }
13
+ }
14
+
15
+ module.exports.postcss = true
@@ -1,23 +1,29 @@
1
- const postcss = require('postcss')
2
1
  const rpxRegExp = /\b(\d+(\.\d+)?)rpx\b/
3
2
  const rpxRegExpG = /\b(\d+(\.\d+)?)rpx\b/g
4
3
 
5
- module.exports = postcss.plugin('vw', (options = {}) => root => {
6
- const rpx2vwRatio = +(100 / 750).toFixed(8)
4
+ module.exports = (options = {}) => {
5
+ return {
6
+ postcssPlugin: 'vw',
7
+ Once: (root) => {
8
+ const rpx2vwRatio = +(100 / 750).toFixed(8)
7
9
 
8
- const transRpxFn = options.transRpxFn && typeof options.transRpxFn === 'function' ? options.transRpxFn : function (match, $1) {
9
- if ($1 === '0') return $1
10
- return `${$1 * rpx2vwRatio}vw`
11
- }
12
- function transVw (declaration) {
13
- if (rpxRegExp.test(declaration.value)) {
14
- declaration.value = declaration.value.replace(rpxRegExpG, transRpxFn)
10
+ const transRpxFn = options.transRpxFn && typeof options.transRpxFn === 'function' ? options.transRpxFn : function (match, $1) {
11
+ if ($1 === '0') return $1
12
+ return `${$1 * rpx2vwRatio}vw`
13
+ }
14
+ function transVw (declaration) {
15
+ if (rpxRegExp.test(declaration.value)) {
16
+ declaration.value = declaration.value.replace(rpxRegExpG, transRpxFn)
17
+ }
18
+ }
19
+
20
+ root.walkRules(rule => {
21
+ rule.walkDecls(declaration => {
22
+ transVw(declaration)
23
+ })
24
+ })
15
25
  }
16
26
  }
27
+ }
17
28
 
18
- root.walkRules(rule => {
19
- rule.walkDecls(declaration => {
20
- transVw(declaration)
21
- })
22
- })
23
- })
29
+ module.exports.postcss = true
@@ -1619,7 +1619,9 @@ function processClass (el, meta) {
1619
1619
  staticClass = staticClass.replace(/\s+/g, ' ')
1620
1620
  if (dynamicClass) {
1621
1621
  let staticClassExp = parseMustache(staticClass).result
1622
- let dynamicClassExp = transDynamicClassExpr(parseMustache(dynamicClass).result)
1622
+ let dynamicClassExp = transDynamicClassExpr(parseMustache(dynamicClass).result, {
1623
+ error: error$1
1624
+ })
1623
1625
  addAttrs(el, [{
1624
1626
  name: targetType,
1625
1627
  // swan中externalClass是通过编译时静态实现,因此需要保留原有的staticClass形式避免externalClass失效
@@ -53,7 +53,8 @@ module.exports = function (raw) {
53
53
  externalClasses,
54
54
  hasScoped,
55
55
  moduleId,
56
- filePath: this.resourcePath,
56
+ // 这里需传递resourcePath和wxsContentMap保持一致
57
+ filePath: resourcePath,
57
58
  i18n,
58
59
  checkUsingComponents: mpx.checkUsingComponents,
59
60
  globalComponents: Object.keys(mpx.usingComponents),
@@ -1,27 +1,32 @@
1
1
  const babylon = require('@babel/parser')
2
2
  const t = require('@babel/types')
3
3
  const generate = require('@babel/generator').default
4
- const dash2hump = require('../utils/hump-dash').dash2hump
5
4
 
6
- module.exports = function transDynamicClassExpr (expr) {
7
- expr = babylon.parseExpression(expr, {
8
- plugins: [
9
- 'objectRestSpread'
10
- ]
11
- })
12
- if (t.isObjectExpression(expr)) {
13
- expr.properties.forEach((property) => {
14
- if (t.isObjectProperty(property) && !property.computed) {
15
- const propertyName = property.key.name || property.key.value
16
- if (/-/.test(propertyName)) {
17
- property.key = t.identifier(dash2hump(propertyName) + 'MpxDash')
18
- } else {
19
- property.key = t.identifier(propertyName)
20
- }
21
- }
5
+ module.exports = function transDynamicClassExpr (expr, { error } = {}) {
6
+ try {
7
+ const ast = babylon.parseExpression(expr, {
8
+ plugins: [
9
+ 'objectRestSpread'
10
+ ]
22
11
  })
12
+ if (t.isObjectExpression(ast)) {
13
+ ast.properties.forEach((property) => {
14
+ if (t.isObjectProperty(property) && !property.computed) {
15
+ const propertyName = property.key.name || property.key.value
16
+ if (/-/.test(propertyName)) {
17
+ if (/\$/.test(propertyName)) {
18
+ error && error(`Dynamic classname [${propertyName}] is not supported, which includes [-] char and [$] char at the same time.`)
19
+ } else {
20
+ property.key = t.identifier(propertyName.replace(/-/g, '$$') + 'MpxDash')
21
+ }
22
+ }
23
+ }
24
+ })
25
+ }
26
+ return generate(ast, {
27
+ compact: true
28
+ }).code
29
+ } catch (e) {
30
+ return expr
23
31
  }
24
- return generate(expr, {
25
- compact: true
26
- }).code
27
32
  }
@@ -96,7 +96,7 @@ module.exports = function (template, {
96
96
  // todo 后续输出web也采用mpx的scoped处理
97
97
  hasScoped: false,
98
98
  moduleId,
99
- filePath: loaderContext.resourcePath,
99
+ filePath: resourcePath,
100
100
  i18n: null,
101
101
  checkUsingComponents,
102
102
  // web模式下全局组件不会被合入usingComponents中,故globalComponents可以传空
@@ -17,129 +17,133 @@ const modulesScope = require('postcss-modules-scope')
17
17
  const modulesValues = require('postcss-modules-values')
18
18
  const valueParser = require('postcss-value-parser')
19
19
  const isUrlRequest = require('../utils/is-url-request')
20
+ // css-loader-parser
20
21
 
21
- const parserPlugin = postcss.plugin('css-loader-parser', function (options) {
22
- return function (css) {
23
- const imports = {}
24
- let exports = {}
25
- const importItems = []
26
- const urlItems = []
22
+ const parserPlugin = function (options) {
23
+ return {
24
+ postcssPlugin: 'css-loader-parser',
25
+ Once (css) {
26
+ const imports = {}
27
+ let exports = {}
28
+ const importItems = []
29
+ const urlItems = []
30
+
31
+ function replaceImportsInString (str) {
32
+ if (options.import) {
33
+ const tokens = valueParser(str)
34
+ tokens.walk(function (node) {
35
+ if (node.type !== 'word') {
36
+ return
37
+ }
38
+ const token = node.value
39
+ const importIndex = imports['$' + token]
40
+ if (typeof importIndex === 'number') {
41
+ node.value = '___CSS_LOADER_IMPORT___' + importIndex + '___'
42
+ }
43
+ })
44
+ return tokens.toString()
45
+ }
46
+ return str
47
+ }
27
48
 
28
- function replaceImportsInString (str) {
29
49
  if (options.import) {
30
- const tokens = valueParser(str)
31
- tokens.walk(function (node) {
32
- if (node.type !== 'word') {
50
+ css.walkAtRules(/^import$/i, function (rule) {
51
+ const values = Tokenizer.parseValues(rule.params)
52
+ let url = values.nodes[0].nodes[0]
53
+ if (url && url.type === 'url') {
54
+ url = url.url
55
+ } else if (url && url.type === 'string') {
56
+ url = url.value
57
+ } else throw rule.error('Unexpected format ' + rule.params)
58
+ if (!url.replace(/\s/g, '').length) {
33
59
  return
34
60
  }
35
- const token = node.value
36
- const importIndex = imports['$' + token]
37
- if (typeof importIndex === 'number') {
38
- node.value = '___CSS_LOADER_IMPORT___' + importIndex + '___'
61
+ values.nodes[0].nodes.shift()
62
+ const mediaQuery = Tokenizer.stringifyValues(values)
63
+
64
+ if (isUrlRequest(url, options.root)) {
65
+ url = loaderUtils.urlToRequest(url, options.root)
39
66
  }
67
+
68
+ importItems.push({
69
+ url: url,
70
+ mediaQuery: mediaQuery
71
+ })
72
+ rule.remove()
40
73
  })
41
- return tokens.toString()
42
74
  }
43
- return str
44
- }
45
-
46
- if (options.import) {
47
- css.walkAtRules(/^import$/i, function (rule) {
48
- const values = Tokenizer.parseValues(rule.params)
49
- let url = values.nodes[0].nodes[0]
50
- if (url && url.type === 'url') {
51
- url = url.url
52
- } else if (url && url.type === 'string') {
53
- url = url.value
54
- } else throw rule.error('Unexpected format ' + rule.params)
55
- if (!url.replace(/\s/g, '').length) {
56
- return
57
- }
58
- values.nodes[0].nodes.shift()
59
- const mediaQuery = Tokenizer.stringifyValues(values)
60
75
 
61
- if (isUrlRequest(url, options.root)) {
62
- url = loaderUtils.urlToRequest(url, options.root)
63
- }
64
-
65
- importItems.push({
66
- url: url,
67
- mediaQuery: mediaQuery
76
+ const icss = icssUtils.extractICSS(css)
77
+ exports = icss.icssExports
78
+ Object.keys(icss.icssImports).forEach(function (key) {
79
+ const url = loaderUtils.parseString(key)
80
+ Object.keys(icss.icssImports[key]).forEach(function (prop) {
81
+ imports['$' + prop] = importItems.length
82
+ importItems.push({
83
+ url: url,
84
+ export: icss.icssImports[key][prop]
85
+ })
68
86
  })
69
- rule.remove()
70
87
  })
71
- }
72
88
 
73
- const icss = icssUtils.extractICSS(css)
74
- exports = icss.icssExports
75
- Object.keys(icss.icssImports).forEach(function (key) {
76
- const url = loaderUtils.parseString(key)
77
- Object.keys(icss.icssImports[key]).forEach(function (prop) {
78
- imports['$' + prop] = importItems.length
79
- importItems.push({
80
- url: url,
81
- export: icss.icssImports[key][prop]
82
- })
89
+ Object.keys(exports).forEach(function (exportName) {
90
+ exports[exportName] = replaceImportsInString(exports[exportName])
83
91
  })
84
- })
85
-
86
- Object.keys(exports).forEach(function (exportName) {
87
- exports[exportName] = replaceImportsInString(exports[exportName])
88
- })
89
92
 
90
- function isAlias (url) {
91
- // Handle alias starting by / and root disabled
92
- return url !== options.resolve(url)
93
- }
93
+ function isAlias (url) {
94
+ // Handle alias starting by / and root disabled
95
+ return url !== options.resolve(url)
96
+ }
94
97
 
95
- function processNode (item) {
96
- switch (item.type) {
97
- case 'value':
98
- item.nodes.forEach(processNode)
99
- break
100
- case 'nested-item':
101
- item.nodes.forEach(processNode)
102
- break
103
- case 'item':
104
- const importIndex = imports['$' + item.name]
105
- if (typeof importIndex === 'number') {
106
- item.name = '___CSS_LOADER_IMPORT___' + importIndex + '___'
107
- }
108
- break
109
- case 'url':
110
- if (options.url && item.url.replace(/\s/g, '').length && !/^#/.test(item.url) && (isAlias(item.url) || isUrlRequest(item.url, options.root))) {
111
- // Strip quotes, they will be re-added if the module needs them
112
- item.stringType = ''
113
- delete item.innerSpacingBefore
114
- delete item.innerSpacingAfter
115
- const url = item.url
116
- item.url = '___CSS_LOADER_URL___' + urlItems.length + '___'
117
- urlItems.push({
118
- url: url
119
- })
120
- }
121
- break
98
+ function processNode (item) {
99
+ switch (item.type) {
100
+ case 'value':
101
+ item.nodes.forEach(processNode)
102
+ break
103
+ case 'nested-item':
104
+ item.nodes.forEach(processNode)
105
+ break
106
+ case 'item':
107
+ const importIndex = imports['$' + item.name]
108
+ if (typeof importIndex === 'number') {
109
+ item.name = '___CSS_LOADER_IMPORT___' + importIndex + '___'
110
+ }
111
+ break
112
+ case 'url':
113
+ if (options.url && item.url.replace(/\s/g, '').length && !/^#/.test(item.url) && (isAlias(item.url) || isUrlRequest(item.url, options.root))) {
114
+ // Strip quotes, they will be re-added if the module needs them
115
+ item.stringType = ''
116
+ delete item.innerSpacingBefore
117
+ delete item.innerSpacingAfter
118
+ const url = item.url
119
+ item.url = '___CSS_LOADER_URL___' + urlItems.length + '___'
120
+ urlItems.push({
121
+ url: url
122
+ })
123
+ }
124
+ break
125
+ }
122
126
  }
123
- }
124
127
 
125
- css.walkDecls(function (decl) {
126
- const values = Tokenizer.parseValues(decl.value)
127
- values.nodes.forEach(function (value) {
128
- value.nodes.forEach(processNode)
128
+ css.walkDecls(function (decl) {
129
+ const values = Tokenizer.parseValues(decl.value)
130
+ values.nodes.forEach(function (value) {
131
+ value.nodes.forEach(processNode)
132
+ })
133
+ decl.value = Tokenizer.stringifyValues(values)
134
+ })
135
+ css.walkAtRules(function (atrule) {
136
+ if (typeof atrule.params === 'string') {
137
+ atrule.params = replaceImportsInString(atrule.params)
138
+ }
129
139
  })
130
- decl.value = Tokenizer.stringifyValues(values)
131
- })
132
- css.walkAtRules(function (atrule) {
133
- if (typeof atrule.params === 'string') {
134
- atrule.params = replaceImportsInString(atrule.params)
135
- }
136
- })
137
140
 
138
- options.importItems = importItems
139
- options.urlItems = urlItems
140
- options.exports = exports
141
+ options.importItems = importItems
142
+ options.urlItems = urlItems
143
+ options.exports = exports
144
+ }
141
145
  }
142
- })
146
+ }
143
147
 
144
148
  module.exports = function processCss (inputSource, inputMap, options, callback) {
145
149
  const query = options.query
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mpxjs/webpack-plugin",
3
- "version": "2.7.1-beta.9",
3
+ "version": "2.7.1",
4
4
  "description": "mpx compile core",
5
5
  "keywords": [
6
6
  "mpx"
@@ -46,14 +46,14 @@
46
46
  "lru-cache": "^4.1.2",
47
47
  "mime": "^2.2.2",
48
48
  "object-assign": "^4.1.1",
49
- "postcss": "^6.0.19",
50
- "postcss-load-config": "^1.2.0",
51
- "postcss-modules-extract-imports": "^1.2.0",
52
- "postcss-modules-local-by-default": "^1.2.0",
53
- "postcss-modules-scope": "^1.1.0",
54
- "postcss-modules-values": "^1.3.0",
55
- "postcss-selector-parser": "^2.0.0",
56
- "postcss-value-parser": "^3.3.0",
49
+ "postcss": "^8.4.5",
50
+ "postcss-load-config": "^3.1.1",
51
+ "postcss-modules-extract-imports": "^3.0.0",
52
+ "postcss-modules-local-by-default": "^4.0.0",
53
+ "postcss-modules-scope": "^3.0.0",
54
+ "postcss-modules-values": "^4.0.0",
55
+ "postcss-selector-parser": "^6.0.8",
56
+ "postcss-value-parser": "^4.0.2",
57
57
  "source-list-map": "^2.0.0"
58
58
  },
59
59
  "peerDependencies": {
@@ -80,5 +80,5 @@
80
80
  "engines": {
81
81
  "node": ">=14.14.0"
82
82
  },
83
- "gitHead": "1db86dfb15540cb9e65acf8066e517bf48be29fd"
83
+ "gitHead": "a672cdbf1689bb4d7f1a0fbcb1037d9f99e5d015"
84
84
  }