@mpxjs/webpack-plugin 2.10.15 → 2.10.16-beta.3
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/AppEntryDependency.js +2 -2
- package/lib/dependencies/DynamicEntryDependency.js +1 -1
- package/lib/dependencies/ImportDependency.js +102 -0
- package/lib/dependencies/RecordModuleIdMapDependency.js +49 -0
- package/lib/dependencies/ResolveDependency.js +1 -1
- package/lib/{retry-runtime-module.js → dependencies/RetryRuntimeModule.js} +1 -1
- package/lib/helpers.js +2 -0
- package/lib/index.js +51 -25
- package/lib/json-compiler/helper.js +72 -2
- package/lib/json-compiler/index.js +14 -54
- package/lib/json-compiler/plugin.js +2 -2
- package/lib/loader.js +6 -2
- package/lib/native-loader.js +6 -3
- package/lib/platform/json/wx/index.js +24 -29
- package/lib/platform/style/wx/index.js +8 -1
- package/lib/platform/template/wx/component-config/button.js +12 -3
- package/lib/platform/template/wx/component-config/camera.js +12 -0
- package/lib/platform/template/wx/component-config/component.js +31 -33
- package/lib/platform/template/wx/component-config/slider.js +12 -0
- package/lib/platform/template/wx/component-config/unsupported.js +1 -1
- package/lib/react/processJSON.js +39 -71
- package/lib/react/processStyles.js +3 -2
- package/lib/react/processTemplate.js +6 -6
- package/lib/react/script-helper.js +6 -16
- package/lib/react/style-helper.js +10 -2
- package/lib/resolver/AddEnvPlugin.js +13 -0
- package/lib/resolver/AddModePlugin.js +18 -0
- package/lib/runtime/components/react/context.ts +2 -0
- package/lib/runtime/components/react/dist/context.js +1 -0
- package/lib/runtime/components/react/dist/mpx-camera.jsx +102 -0
- package/lib/runtime/components/react/dist/mpx-image.jsx +81 -37
- package/lib/runtime/components/react/dist/mpx-keyboard-avoiding-view.jsx +19 -4
- package/lib/runtime/components/react/dist/mpx-picker-view/index.jsx +3 -2
- package/lib/runtime/components/react/dist/mpx-picker-view-column/index.jsx +9 -6
- package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewColumnItem.jsx +8 -11
- package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewColumnItemLite.jsx +20 -0
- package/lib/runtime/components/react/dist/mpx-portal/index.jsx +5 -1
- package/lib/runtime/components/react/dist/mpx-progress.jsx +26 -22
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +6 -14
- package/lib/runtime/components/react/dist/mpx-slider.jsx +321 -0
- package/lib/runtime/components/react/dist/mpx-text.jsx +33 -5
- package/lib/runtime/components/react/dist/mpx-view.jsx +8 -11
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +1 -1
- package/lib/runtime/components/react/dist/utils.jsx +16 -6
- package/lib/runtime/components/react/mpx-camera.tsx +167 -0
- package/lib/runtime/components/react/mpx-image.tsx +89 -42
- package/lib/runtime/components/react/mpx-keyboard-avoiding-view.tsx +31 -4
- package/lib/runtime/components/react/mpx-picker-view/index.tsx +4 -1
- package/lib/runtime/components/react/mpx-picker-view-column/index.tsx +19 -8
- package/lib/runtime/components/react/mpx-picker-view-column/pickerViewColumnItem.tsx +8 -12
- package/lib/runtime/components/react/mpx-picker-view-column/pickerViewColumnItemLite.tsx +55 -0
- package/lib/runtime/components/react/mpx-portal/index.tsx +8 -2
- package/lib/runtime/components/react/mpx-progress.tsx +26 -24
- package/lib/runtime/components/react/mpx-scroll-view.tsx +6 -17
- package/lib/runtime/components/react/mpx-slider.tsx +444 -0
- package/lib/runtime/components/react/mpx-text.tsx +38 -5
- package/lib/runtime/components/react/mpx-view.tsx +8 -11
- package/lib/runtime/components/react/mpx-web-view.tsx +1 -1
- package/lib/runtime/components/react/utils.tsx +15 -6
- package/lib/runtime/components/web/mpx-input.vue +1 -1
- package/lib/runtime/components/web/mpx-scroll-view.vue +7 -1
- package/lib/runtime/components/web/mpx-video.vue +12 -1
- package/lib/runtime/optionProcessor.js +3 -1
- package/lib/runtime/optionProcessorReact.js +4 -2
- package/lib/script-setup-compiler/index.js +2 -2
- package/lib/style-compiler/index.js +3 -2
- package/lib/style-compiler/load-postcss-config.js +1 -1
- package/lib/style-compiler/plugins/trans-special.js +10 -2
- package/lib/style-compiler/strip-conditional-loader.js +155 -15
- package/lib/template-compiler/compiler.js +262 -61
- package/lib/template-compiler/gen-node-react.js +18 -6
- package/lib/template-compiler/index.js +6 -4
- package/lib/template-compiler/parse-exps.js +1 -1
- package/lib/utils/chain-assign.js +47 -0
- package/lib/utils/check-core-version-match.js +75 -15
- package/lib/utils/const.js +2 -1
- package/lib/utils/dom-tag-config.js +1 -1
- package/lib/utils/env.js +6 -1
- package/lib/utils/get-build-tag-component.js +35 -0
- package/lib/utils/pre-process-json.js +5 -0
- package/lib/web/processJSON.js +44 -16
- package/lib/web/processScript.js +1 -1
- package/lib/web/processTemplate.js +4 -4
- package/lib/web/script-helper.js +19 -9
- package/lib/wxs/pre-loader.js +6 -6
- package/lib/wxss/loader.js +1 -9
- package/package.json +14 -5
- package/LICENSE +0 -433
- package/lib/dependencies/ImportDependencyTemplate.js +0 -50
|
@@ -287,16 +287,13 @@ function backgroundSize (imageProps: ImageProps, preImageInfo: PreImageInfo, ima
|
|
|
287
287
|
} else { // 数值类型 ImageStyle
|
|
288
288
|
// 数值类型设置为 stretch
|
|
289
289
|
imageProps.resizeMode = 'stretch'
|
|
290
|
-
if (type === 'linear') {
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
height: dimensionHeight
|
|
298
|
-
} as { width: NumberVal, height: NumberVal }
|
|
299
|
-
}
|
|
290
|
+
if (type === 'linear' && (!layoutWidth || !layoutHeight)) {
|
|
291
|
+
// ios 上 linear 组件只要重新触发渲染,在渲染过程中外层容器 width 或者 height 被设置为 0,通过设置 % 的方式会渲染不出来,即使后面再更新为正常宽高也渲染不出来
|
|
292
|
+
// 所以 hack 手动先将 linear 宽高也设置为 0,后面再更新为正确的数值或 %。
|
|
293
|
+
dimensions = {
|
|
294
|
+
width: 0,
|
|
295
|
+
height: 0
|
|
296
|
+
} as { width: NumberVal, height: NumberVal }
|
|
300
297
|
} else {
|
|
301
298
|
dimensions = {
|
|
302
299
|
width: isPercent(width) ? width : +width,
|
|
@@ -504,7 +501,7 @@ function parseBgImage (text: string): {
|
|
|
504
501
|
type?: 'image' | 'linear'
|
|
505
502
|
src?: string
|
|
506
503
|
} {
|
|
507
|
-
if (!text) return {}
|
|
504
|
+
if (!text || text === 'none') return {}
|
|
508
505
|
|
|
509
506
|
const src = parseUrl(text)
|
|
510
507
|
if (src) return { src, type: 'image' }
|
|
@@ -226,7 +226,7 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
|
|
|
226
226
|
}
|
|
227
227
|
break
|
|
228
228
|
case 'postMessage':
|
|
229
|
-
bindmessage && bindmessage(getCustomEvent('
|
|
229
|
+
bindmessage && bindmessage(getCustomEvent('message', {}, { // RN组件销毁顺序与小程序不一致,所以改成和支付宝消息一致
|
|
230
230
|
detail: {
|
|
231
231
|
data: params[0]?.data
|
|
232
232
|
}
|
|
@@ -215,24 +215,33 @@ function resolveVar (input: string, varContext: Record<string, any>) {
|
|
|
215
215
|
const parsed = parseFunc(input, 'var')
|
|
216
216
|
const replaced = new ReplaceSource(input)
|
|
217
217
|
|
|
218
|
-
|
|
218
|
+
for (const { start, end, args } of parsed) {
|
|
219
219
|
const varName = args[0]
|
|
220
|
-
const fallback = args[1]
|
|
220
|
+
const fallback = args[1]
|
|
221
221
|
let varValue = hasOwn(varContext, varName) ? varContext[varName] : fallback
|
|
222
|
+
if (varValue === undefined) return
|
|
222
223
|
if (varUseRegExp.test(varValue)) {
|
|
223
|
-
varValue =
|
|
224
|
+
varValue = resolveVar(varValue, varContext)
|
|
225
|
+
if (varValue === undefined) return
|
|
224
226
|
} else {
|
|
225
|
-
varValue =
|
|
227
|
+
varValue = global.__formatValue(varValue)
|
|
226
228
|
}
|
|
227
229
|
replaced.replace(start, end - 1, varValue)
|
|
228
|
-
}
|
|
230
|
+
}
|
|
231
|
+
|
|
229
232
|
return global.__formatValue(replaced.source())
|
|
230
233
|
}
|
|
231
234
|
|
|
232
235
|
function transformVar (styleObj: Record<string, any>, varKeyPaths: Array<Array<string>>, varContext: Record<string, any>, visitOther: (arg: VisitorArg) => void) {
|
|
233
236
|
varKeyPaths.forEach((varKeyPath) => {
|
|
234
237
|
setStyle(styleObj, varKeyPath, ({ target, key, value }) => {
|
|
235
|
-
|
|
238
|
+
const resolved = resolveVar(value, varContext)
|
|
239
|
+
if (resolved === undefined) {
|
|
240
|
+
delete target[key]
|
|
241
|
+
error(`Can not resolve css var at ${varKeyPath.join('.')}:${value}.`)
|
|
242
|
+
return
|
|
243
|
+
}
|
|
244
|
+
target[key] = resolved
|
|
236
245
|
visitOther({ target, key, value: target[key], keyPath: varKeyPath })
|
|
237
246
|
})
|
|
238
247
|
})
|
|
@@ -4,10 +4,12 @@
|
|
|
4
4
|
import { processSize } from '../../utils'
|
|
5
5
|
import BScroll from '@better-scroll/core'
|
|
6
6
|
import PullDown from '@better-scroll/pull-down'
|
|
7
|
+
import MouseWheel from '@better-scroll/mouse-wheel'
|
|
7
8
|
import throttle from 'lodash/throttle'
|
|
8
9
|
import debounce from 'lodash/debounce'
|
|
9
10
|
|
|
10
11
|
BScroll.use(PullDown)
|
|
12
|
+
BScroll.use(MouseWheel)
|
|
11
13
|
|
|
12
14
|
let mutationObserver = null
|
|
13
15
|
let resizeObserver = null
|
|
@@ -222,7 +224,11 @@
|
|
|
222
224
|
bounce: false,
|
|
223
225
|
stopPropagation: true,
|
|
224
226
|
bindToWrapper: true,
|
|
225
|
-
eventPassthrough: (this.scrollX && 'vertical') || (this.scrollY && 'horizontal') || ''
|
|
227
|
+
eventPassthrough: (this.scrollX && 'vertical') || (this.scrollY && 'horizontal') || '',
|
|
228
|
+
mouseWheel: {
|
|
229
|
+
speed: 20,
|
|
230
|
+
easeTime: 300
|
|
231
|
+
}
|
|
226
232
|
}
|
|
227
233
|
if (this.refresherEnabled) {
|
|
228
234
|
originBsOptions.bounce = true
|
|
@@ -148,6 +148,11 @@
|
|
|
148
148
|
},
|
|
149
149
|
controls: function (show) {
|
|
150
150
|
this.$emit('controlstoggle', inheritEvent('controlstoggle', {}, { show }))
|
|
151
|
+
},
|
|
152
|
+
objectFit (val) {
|
|
153
|
+
if (this._player && this._player.video) {
|
|
154
|
+
this._player.video.style.objectFit = val
|
|
155
|
+
}
|
|
151
156
|
}
|
|
152
157
|
},
|
|
153
158
|
mounted () {
|
|
@@ -189,6 +194,9 @@
|
|
|
189
194
|
if (this.initialTime) {
|
|
190
195
|
this._player.seek(this.initialTime)
|
|
191
196
|
}
|
|
197
|
+
if (this.objectFit) {
|
|
198
|
+
this._player.video.style.objectFit = this.objectFit
|
|
199
|
+
}
|
|
192
200
|
},
|
|
193
201
|
initStyle () {
|
|
194
202
|
|
|
@@ -239,7 +247,10 @@
|
|
|
239
247
|
|
|
240
248
|
this._player.on('progress', (e) => {
|
|
241
249
|
const eNode = e.target
|
|
242
|
-
|
|
250
|
+
let buffered = 0
|
|
251
|
+
if (eNode?.buffered && eNode.buffered.length > 0) {
|
|
252
|
+
buffered = (eNode.buffered.end(0)) / (eNode?.duration)
|
|
253
|
+
}
|
|
243
254
|
this.$emit('progress', inheritEvent('progress', e, { buffered: buffered * 100 }))
|
|
244
255
|
})
|
|
245
256
|
|
|
@@ -108,7 +108,9 @@ registered in parent context!`)
|
|
|
108
108
|
export function getComponent (component, extendOptions) {
|
|
109
109
|
component = component.__esModule ? component.default : component
|
|
110
110
|
// eslint-disable-next-line
|
|
111
|
-
if (extendOptions
|
|
111
|
+
if (extendOptions && !component.__mpxExtended) {
|
|
112
|
+
extend(component, extendOptions, { __mpxExtended: true })
|
|
113
|
+
}
|
|
112
114
|
return component
|
|
113
115
|
}
|
|
114
116
|
|
|
@@ -5,7 +5,9 @@ import { extend } from './utils'
|
|
|
5
5
|
export function getComponent (component, extendOptions) {
|
|
6
6
|
component = component.__esModule ? component.default : component
|
|
7
7
|
// eslint-disable-next-line
|
|
8
|
-
if (extendOptions
|
|
8
|
+
if (extendOptions && !component.__mpxExtended) {
|
|
9
|
+
extend(component, extendOptions, { __mpxExtended: true })
|
|
10
|
+
}
|
|
9
11
|
return component
|
|
10
12
|
}
|
|
11
13
|
|
|
@@ -15,7 +17,7 @@ export function getAsyncSuspense (commonProps) {
|
|
|
15
17
|
result = memo(forwardRef(function (props, ref) {
|
|
16
18
|
return createElement(AsyncSuspense,
|
|
17
19
|
extend({}, commonProps, {
|
|
18
|
-
innerProps:
|
|
20
|
+
innerProps: extend({}, props, { ref })
|
|
19
21
|
})
|
|
20
22
|
)
|
|
21
23
|
}))
|
|
@@ -98,7 +98,7 @@ function compileScriptSetup (
|
|
|
98
98
|
) {
|
|
99
99
|
if (node) {
|
|
100
100
|
throw new Error(
|
|
101
|
-
`[
|
|
101
|
+
`[Mpx script error]: ${msg}\n\n${filePath}\n${formatCodeFrame(
|
|
102
102
|
content,
|
|
103
103
|
node.start + startOffset,
|
|
104
104
|
end
|
|
@@ -106,7 +106,7 @@ function compileScriptSetup (
|
|
|
106
106
|
)
|
|
107
107
|
} else {
|
|
108
108
|
throw new Error(
|
|
109
|
-
`[
|
|
109
|
+
`[Mpx script error]: ${msg}\n\n${filePath}\n`
|
|
110
110
|
)
|
|
111
111
|
}
|
|
112
112
|
}
|
|
@@ -18,7 +18,8 @@ module.exports = function (css, map) {
|
|
|
18
18
|
const { resourcePath, queryObj } = parseRequest(this.resource)
|
|
19
19
|
const mpx = this.getMpx()
|
|
20
20
|
const mpxStyleOptions = (queryObj.mpxStyleOptions && JSON.parse(queryObj.mpxStyleOptions)) || {}
|
|
21
|
-
const id = queryObj.moduleId || mpxStyleOptions.mid || mpx.getModuleId(resourcePath)
|
|
21
|
+
const id = queryObj.moduleId || mpxStyleOptions.mid || mpx.getModuleId(resourcePath, false, (queryObj.moduleId || mpxStyleOptions.mid) ? null : this)
|
|
22
|
+
|
|
22
23
|
const appInfo = mpx.appInfo
|
|
23
24
|
const defs = mpx.defs
|
|
24
25
|
const mode = mpx.mode
|
|
@@ -55,7 +56,7 @@ module.exports = function (css, map) {
|
|
|
55
56
|
}
|
|
56
57
|
|
|
57
58
|
if (isReact(mode)) {
|
|
58
|
-
plugins.push(transSpecial({ id }))
|
|
59
|
+
plugins.push(transSpecial({ id, transPage: true }))
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
// plugins.push(pluginCondStrip({
|
|
@@ -29,7 +29,7 @@ module.exports = function loadPostcssConfig (loaderContext, inlineConfig = {}) {
|
|
|
29
29
|
if (err.message.indexOf('No PostCSS Config found') >= 0) {
|
|
30
30
|
return
|
|
31
31
|
}
|
|
32
|
-
loaderContext.emitWarning(`Error loading PostCSS config: ${err.message}`)
|
|
32
|
+
loaderContext.emitWarning(`[Mpx style warning]: Error loading PostCSS config: ${err.message}`)
|
|
33
33
|
})
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
const selectorParser = require('postcss-selector-parser')
|
|
2
|
+
const { MPX_TAG_PAGE_SELECTOR } = require('../../utils/const')
|
|
2
3
|
// trans-special
|
|
3
4
|
|
|
4
|
-
module.exports = ({ id }) => {
|
|
5
|
+
module.exports = ({ id, transPage = false }) => {
|
|
5
6
|
return {
|
|
6
7
|
postcssPlugin: 'trans-special',
|
|
7
8
|
Once: (root) => {
|
|
@@ -13,7 +14,14 @@ module.exports = ({ id }) => {
|
|
|
13
14
|
if (/^:host$/.test(n.value)) {
|
|
14
15
|
const compoundSelectors = n.nodes
|
|
15
16
|
n.replaceWith(selectorParser.className({
|
|
16
|
-
value:
|
|
17
|
+
value: `host-${id}`
|
|
18
|
+
}))
|
|
19
|
+
selector.insertAfter(n, compoundSelectors)
|
|
20
|
+
}
|
|
21
|
+
if (transPage && /^page$/.test(n.value)) {
|
|
22
|
+
const compoundSelectors = n.nodes || []
|
|
23
|
+
n.replaceWith(selectorParser.className({
|
|
24
|
+
value: MPX_TAG_PAGE_SELECTOR
|
|
17
25
|
}))
|
|
18
26
|
selector.insertAfter(n, compoundSelectors)
|
|
19
27
|
}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
+
const fs = require('fs/promises')
|
|
2
|
+
const parseRequest = require('../utils/parse-request')
|
|
3
|
+
const atImport = require('postcss-import')
|
|
4
|
+
const { default: postcss } = require('postcss')
|
|
5
|
+
|
|
1
6
|
class Node {
|
|
2
|
-
constructor
|
|
7
|
+
constructor(type, condition = null) {
|
|
3
8
|
this.type = type // 'If', 'ElseIf', 'Else' 或 'Text'
|
|
4
9
|
this.condition = condition // If 或 Elif 的条件
|
|
5
10
|
this.children = []
|
|
@@ -8,7 +13,7 @@ class Node {
|
|
|
8
13
|
}
|
|
9
14
|
|
|
10
15
|
// 提取 css string 为 token
|
|
11
|
-
function tokenize
|
|
16
|
+
function tokenize(cssString) {
|
|
12
17
|
const regex = /\/\*\s*@mpx-(if|elif|else|endif)(?:\s*\((.*?)\))?\s*\*\//g
|
|
13
18
|
const tokens = []
|
|
14
19
|
let lastIndex = 0
|
|
@@ -37,12 +42,12 @@ function tokenize (cssString) {
|
|
|
37
42
|
}
|
|
38
43
|
|
|
39
44
|
// parse:将生成的 token 数组构造成嵌套的 AST
|
|
40
|
-
function parse
|
|
45
|
+
function parse(cssString) {
|
|
41
46
|
const tokens = tokenize(cssString)
|
|
42
47
|
const ast = []
|
|
43
48
|
const nodeStack = []
|
|
44
49
|
let currentChildren = ast
|
|
45
|
-
tokens.forEach(token => {
|
|
50
|
+
tokens.forEach((token) => {
|
|
46
51
|
if (token.type === 'text') {
|
|
47
52
|
const node = new Node('Text')
|
|
48
53
|
node.value = token.content
|
|
@@ -54,7 +59,7 @@ function parse (cssString) {
|
|
|
54
59
|
currentChildren = node.children
|
|
55
60
|
} else if (token.type === 'elif') {
|
|
56
61
|
if (nodeStack.length === 0) {
|
|
57
|
-
throw new Error('elif without a preceding if')
|
|
62
|
+
throw new Error('[Mpx style error]: elif without a preceding if')
|
|
58
63
|
}
|
|
59
64
|
currentChildren = nodeStack[nodeStack.length - 1]
|
|
60
65
|
const node = new Node('ElseIf', token.condition)
|
|
@@ -62,7 +67,7 @@ function parse (cssString) {
|
|
|
62
67
|
currentChildren = node.children
|
|
63
68
|
} else if (token.type === 'else') {
|
|
64
69
|
if (nodeStack.length === 0) {
|
|
65
|
-
throw new Error('else without a preceding if')
|
|
70
|
+
throw new Error('[Mpx style error]: else without a preceding if')
|
|
66
71
|
}
|
|
67
72
|
currentChildren = nodeStack[nodeStack.length - 1]
|
|
68
73
|
const node = new Node('Else')
|
|
@@ -77,23 +82,23 @@ function parse (cssString) {
|
|
|
77
82
|
return ast
|
|
78
83
|
}
|
|
79
84
|
|
|
80
|
-
function evaluateCondition
|
|
85
|
+
function evaluateCondition(condition, defs) {
|
|
81
86
|
try {
|
|
82
87
|
const keys = Object.keys(defs)
|
|
83
|
-
const values = keys.map(key => defs[key])
|
|
88
|
+
const values = keys.map((key) => defs[key])
|
|
84
89
|
/* eslint-disable no-new-func */
|
|
85
90
|
const func = new Function(...keys, `return (${condition});`)
|
|
86
91
|
return func(...values)
|
|
87
92
|
} catch (e) {
|
|
88
|
-
console.error(`Error evaluating condition: ${condition}`, e)
|
|
93
|
+
console.error(`[Mpx style error]:Error evaluating condition: ${condition}`, e)
|
|
89
94
|
return false
|
|
90
95
|
}
|
|
91
96
|
}
|
|
92
97
|
|
|
93
|
-
function traverseAndEvaluate
|
|
98
|
+
function traverseAndEvaluate(ast, defs) {
|
|
94
99
|
let output = ''
|
|
95
100
|
let batchedIf = false
|
|
96
|
-
function traverse
|
|
101
|
+
function traverse(nodes) {
|
|
97
102
|
for (const node of nodes) {
|
|
98
103
|
if (node.type === 'Text') {
|
|
99
104
|
output += node.value
|
|
@@ -118,10 +123,145 @@ function traverseAndEvaluate (ast, defs) {
|
|
|
118
123
|
return output
|
|
119
124
|
}
|
|
120
125
|
|
|
121
|
-
|
|
126
|
+
/**
|
|
127
|
+
*
|
|
128
|
+
* @param {string} content
|
|
129
|
+
* @param {Record<string, any>} defs
|
|
130
|
+
* @returns
|
|
131
|
+
*/
|
|
132
|
+
function stripCondition(content, defs) {
|
|
133
|
+
const ast = parse(content)
|
|
134
|
+
const result = traverseAndEvaluate(ast, defs)
|
|
135
|
+
return result
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* @typedef {Object} StripByPostcssOption
|
|
140
|
+
* @property {string} lang 样式语法格式
|
|
141
|
+
* @property {string} resourcePath 文件路径
|
|
142
|
+
* @property {string} css 源文件
|
|
143
|
+
* @property {Record<string, any>} defs 条件定义
|
|
144
|
+
* @property {import('webpack').LoaderContext<any>['resolve']} resolve webpack resolve 方法
|
|
145
|
+
*/
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* @typedef {Object} AtImportConfig
|
|
149
|
+
* @property {string} from 当前文件路径
|
|
150
|
+
* @property {(filename: string) => Promise<string> | string;} load 加载文件内容的函数
|
|
151
|
+
* @property {(id: string, base: string) => Promise<string | null> | string | null;} resolve 解析文件路径的函数
|
|
152
|
+
*/
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
*
|
|
156
|
+
* @param {Function} callback
|
|
157
|
+
* @param {string} name
|
|
158
|
+
* @returns
|
|
159
|
+
*/
|
|
160
|
+
const shouldInstallWarning = (callback, name) => {
|
|
161
|
+
return () => {
|
|
162
|
+
try {
|
|
163
|
+
return callback()
|
|
164
|
+
} catch (error) {
|
|
165
|
+
throw new Error(
|
|
166
|
+
`[mpx-strip-conditional-loader]: ${name} is not installed, please install it first.\norginal Error: ${
|
|
167
|
+
error?.message ?? error.toString()
|
|
168
|
+
}`,
|
|
169
|
+
{
|
|
170
|
+
cause: error
|
|
171
|
+
}
|
|
172
|
+
)
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
*
|
|
178
|
+
* @typedef {import('postcss').ProcessOptions} ProcessOptions
|
|
179
|
+
* @typedef {import('postcss').Root} Root
|
|
180
|
+
*
|
|
181
|
+
* @type {Record<string, ProcessOptions['syntax']>}
|
|
182
|
+
*/
|
|
183
|
+
const styleSyntaxProcesserMap = {
|
|
184
|
+
stylus: shouldInstallWarning(() => require('postcss-styl'), 'postcss-styl'),
|
|
185
|
+
less: shouldInstallWarning(() => require('postcss-less'), 'postcss-less'),
|
|
186
|
+
scss: shouldInstallWarning(() => require('postcss-scss'), 'postcss-scss')
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* @param {StripByPostcssOption} options
|
|
191
|
+
*/
|
|
192
|
+
async function stripByPostcss(options) {
|
|
193
|
+
const syntax = styleSyntaxProcesserMap[options.lang]?.()
|
|
194
|
+
const defs = options.defs ?? {}
|
|
195
|
+
|
|
196
|
+
const afterConditionStrip = stripCondition(options.css, defs)
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* @type {import('postcss').AcceptedPlugin[]}
|
|
200
|
+
*/
|
|
201
|
+
const plugins = [
|
|
202
|
+
atImport({
|
|
203
|
+
async load(filename) {
|
|
204
|
+
let content = await fs.readFile(filename, 'utf-8')
|
|
205
|
+
const processer = postcss(plugins)
|
|
206
|
+
|
|
207
|
+
content = stripCondition(content, defs)
|
|
208
|
+
|
|
209
|
+
const { css } = await processer.process(content, {
|
|
210
|
+
syntax,
|
|
211
|
+
from: filename,
|
|
212
|
+
to: options.resourcePath
|
|
213
|
+
})
|
|
214
|
+
return css
|
|
215
|
+
},
|
|
216
|
+
resolve: (id, base) => {
|
|
217
|
+
return new Promise((resolve, reject) => {
|
|
218
|
+
options.resolve(base, id, (err, res) => {
|
|
219
|
+
if (err) return reject(err)
|
|
220
|
+
if (typeof res !== 'string') {
|
|
221
|
+
return reject(
|
|
222
|
+
new Error(
|
|
223
|
+
`[mpx-strip-conditional-loader]: Cannot resolve ${id} from ${base}`
|
|
224
|
+
)
|
|
225
|
+
)
|
|
226
|
+
}
|
|
227
|
+
resolve(res)
|
|
228
|
+
})
|
|
229
|
+
})
|
|
230
|
+
}
|
|
231
|
+
})
|
|
232
|
+
]
|
|
233
|
+
|
|
234
|
+
const processer = postcss(plugins)
|
|
235
|
+
|
|
236
|
+
return processer.process(afterConditionStrip, {
|
|
237
|
+
from: options.resourcePath,
|
|
238
|
+
syntax
|
|
239
|
+
})
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
*
|
|
244
|
+
* @this {import('webpack').LoaderContext<any>}
|
|
245
|
+
* @param {string} css
|
|
246
|
+
*/
|
|
247
|
+
module.exports = async function (css) {
|
|
122
248
|
this.cacheable()
|
|
249
|
+
|
|
250
|
+
const callback = this.async()
|
|
251
|
+
|
|
123
252
|
const mpx = this.getMpx()
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
253
|
+
const { resourcePath, queryObj } = parseRequest(this.resource)
|
|
254
|
+
|
|
255
|
+
const result = await stripByPostcss({
|
|
256
|
+
lang: queryObj.lang,
|
|
257
|
+
resourcePath,
|
|
258
|
+
css,
|
|
259
|
+
defs: mpx.defs,
|
|
260
|
+
resolve: this.resolve.bind(this)
|
|
261
|
+
})
|
|
262
|
+
|
|
263
|
+
callback(null, result.css, result.map)
|
|
127
264
|
}
|
|
265
|
+
|
|
266
|
+
module.exports.stripByPostcss = stripByPostcss
|
|
267
|
+
module.exports.stripCondition = stripCondition
|