@dcloudio/uni-preprocess 3.0.0-alpha-4000020231226001
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -0
- package/dist/index.cjs.js +151 -0
- package/dist/index.es.js +145 -0
- package/dist/uni-preprocess.d.ts +19 -0
- package/package.json +25 -0
package/README.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
### usage
|
|
2
|
+
|
|
3
|
+
```ts
|
|
4
|
+
import { preprocess } from '@dcloudio/uni-preprocess'
|
|
5
|
+
|
|
6
|
+
const { code, map } = preprocess(
|
|
7
|
+
`a
|
|
8
|
+
// #ifdef B
|
|
9
|
+
b
|
|
10
|
+
// #endif
|
|
11
|
+
// #ifdef C
|
|
12
|
+
c
|
|
13
|
+
// #endif
|
|
14
|
+
// #ifndef D
|
|
15
|
+
d
|
|
16
|
+
// #endif
|
|
17
|
+
e
|
|
18
|
+
`,
|
|
19
|
+
{
|
|
20
|
+
/**
|
|
21
|
+
* 可选值 js | html | auto
|
|
22
|
+
* 如果是处理 js、ts、uts、css、scss、less 等文件(识别的是单行或多行注释`// #ifdef `和`\/* #ifdef *\/`),可以传 js
|
|
23
|
+
* 如果是处理 html 等模板文件(识别的是<!-- #ifdef -->),可以传 html
|
|
24
|
+
* 如果是处理 vue、nvue、uvue 文件(需要同时识别上述两种),可以传 auto
|
|
25
|
+
**/
|
|
26
|
+
type: 'js',
|
|
27
|
+
context: { B: true },
|
|
28
|
+
sourceMap: {
|
|
29
|
+
/**
|
|
30
|
+
* Whether the mapping should be high-resolution.
|
|
31
|
+
* Hi-res mappings map every single character, meaning (for example) your devtools will always
|
|
32
|
+
* be able to pinpoint the exact location of function calls and so on.
|
|
33
|
+
* With lo-res mappings, devtools may only be able to identify the correct
|
|
34
|
+
* line - but they're quicker to generate and less bulky.
|
|
35
|
+
* You can also set `"boundary"` to generate a semi-hi-res mappings segmented per word boundary
|
|
36
|
+
* instead of per character, suitable for string semantics that are separated by words.
|
|
37
|
+
* If sourcemap locations have been specified with s.addSourceMapLocation(), they will be used here.
|
|
38
|
+
*/
|
|
39
|
+
hires: true,
|
|
40
|
+
/**
|
|
41
|
+
* The filename where you plan to write the sourcemap.
|
|
42
|
+
*/
|
|
43
|
+
file: 'test',
|
|
44
|
+
/**
|
|
45
|
+
* The filename of the file containing the original source.
|
|
46
|
+
*/
|
|
47
|
+
source: 'test.uts',
|
|
48
|
+
/**
|
|
49
|
+
* Whether to include the original content in the map's sourcesContent array.
|
|
50
|
+
*/
|
|
51
|
+
includeContent: false,
|
|
52
|
+
},
|
|
53
|
+
}
|
|
54
|
+
)
|
|
55
|
+
console.log('code:\n', code)
|
|
56
|
+
console.log('sourceMap:\n', map)
|
|
57
|
+
```
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var MagicString = require('magic-string');
|
|
4
|
+
var xregexp = require('xregexp');
|
|
5
|
+
|
|
6
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
|
+
|
|
8
|
+
var MagicString__default = /*#__PURE__*/_interopDefault(MagicString);
|
|
9
|
+
|
|
10
|
+
function preprocess(source, options) {
|
|
11
|
+
if (!source.includes('#endif')) {
|
|
12
|
+
return {
|
|
13
|
+
code: source,
|
|
14
|
+
map: null,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
const context = options.context || {};
|
|
18
|
+
const s = new MagicString__default.default(source);
|
|
19
|
+
function preprocessByType(type) {
|
|
20
|
+
replaceRecursive(type, source, s, (s, startMatches, endMatches, include, recurse) => {
|
|
21
|
+
// I need to recurse first, so I don't catch "inner" else-directives
|
|
22
|
+
recurse(include.value, include.start);
|
|
23
|
+
const variant = startMatches.value[1];
|
|
24
|
+
const test = (startMatches.value[2] || '').trim();
|
|
25
|
+
switch (variant) {
|
|
26
|
+
case 'ifdef':
|
|
27
|
+
if (testPasses(test, context)) {
|
|
28
|
+
s.remove(startMatches.start, startMatches.end);
|
|
29
|
+
s.remove(endMatches.start, endMatches.end);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
s.remove(startMatches.start, endMatches.end);
|
|
33
|
+
}
|
|
34
|
+
return;
|
|
35
|
+
case 'ifndef':
|
|
36
|
+
if (!testPasses(test, context)) {
|
|
37
|
+
s.remove(startMatches.start, startMatches.end);
|
|
38
|
+
s.remove(endMatches.start, endMatches.end);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
s.remove(startMatches.start, endMatches.end);
|
|
42
|
+
}
|
|
43
|
+
return;
|
|
44
|
+
default:
|
|
45
|
+
throw new Error('Unknown if variant ' + variant + '.');
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
const type = options.type || 'auto';
|
|
50
|
+
if (type === 'auto' || type === 'js') {
|
|
51
|
+
preprocessByType(TYPES.js);
|
|
52
|
+
}
|
|
53
|
+
if (type === 'auto' || type === 'html') {
|
|
54
|
+
preprocessByType(TYPES.html);
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
code: s.toString(),
|
|
58
|
+
map: options.sourceMap ? s.generateMap(options.sourceMap) : null,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
const startPattern = '[ \t]*(?://|/\\*)[ \t]*#(ifndef|ifdef)[ \t]+([^\n*]*)(?:\\*(?:\\*|/))?(?:[ \t]*\n+)?';
|
|
62
|
+
const endPattern = '[ \t]*(?://|/\\*)[ \t]*#endif[ \t]*(?:\\*(?:\\*|/))?(?:[ \t]*\n)?';
|
|
63
|
+
const startPatternHTML = '[ \t]*<!--[ \t]*#(ifndef|ifdef|if)[ \t]+(.*?)[ \t]*(?:-->|!>)(?:[ \t]*\n+)?';
|
|
64
|
+
const endPatternHTML = '[ \t]*<!(?:--)?[ \t]*#endif[ \t]*(?:-->|!>)(?:[ \t]*\n)?';
|
|
65
|
+
const TYPES = {
|
|
66
|
+
js: {
|
|
67
|
+
start: {
|
|
68
|
+
pattern: startPattern,
|
|
69
|
+
regex: new RegExp(startPattern, 'mi'),
|
|
70
|
+
},
|
|
71
|
+
end: {
|
|
72
|
+
pattern: endPattern,
|
|
73
|
+
regex: new RegExp(endPattern, 'mi'),
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
html: {
|
|
77
|
+
start: {
|
|
78
|
+
pattern: startPatternHTML,
|
|
79
|
+
regex: new RegExp(startPatternHTML, 'mi'),
|
|
80
|
+
},
|
|
81
|
+
end: {
|
|
82
|
+
pattern: endPatternHTML,
|
|
83
|
+
regex: new RegExp(endPatternHTML, 'mi'),
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
function replaceRecursive(type, source, s, processor) {
|
|
88
|
+
function matchReplacePass(content, startOffset = 0) {
|
|
89
|
+
const matches = xregexp.matchRecursive(content, type.start.pattern, type.end.pattern, 'gmi', {
|
|
90
|
+
valueNames: ['between', 'left', 'match', 'right'],
|
|
91
|
+
});
|
|
92
|
+
let left = null;
|
|
93
|
+
let match = null;
|
|
94
|
+
let right = null;
|
|
95
|
+
matches.forEach(function ({ name, value, start, end }) {
|
|
96
|
+
start = start + startOffset;
|
|
97
|
+
end = end + startOffset;
|
|
98
|
+
switch (name) {
|
|
99
|
+
case 'between':
|
|
100
|
+
break;
|
|
101
|
+
case 'left':
|
|
102
|
+
left = {
|
|
103
|
+
start,
|
|
104
|
+
end,
|
|
105
|
+
value: type.start.regex.exec(value),
|
|
106
|
+
};
|
|
107
|
+
break;
|
|
108
|
+
case 'match':
|
|
109
|
+
match = {
|
|
110
|
+
start,
|
|
111
|
+
end,
|
|
112
|
+
value,
|
|
113
|
+
};
|
|
114
|
+
break;
|
|
115
|
+
case 'right':
|
|
116
|
+
right = {
|
|
117
|
+
start,
|
|
118
|
+
end,
|
|
119
|
+
value: type.end.regex.exec(value),
|
|
120
|
+
};
|
|
121
|
+
if (left && match && right) {
|
|
122
|
+
processor(s, left, right, match, matchReplacePass);
|
|
123
|
+
left = null;
|
|
124
|
+
match = null;
|
|
125
|
+
right = null;
|
|
126
|
+
}
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
matchReplacePass(source);
|
|
132
|
+
}
|
|
133
|
+
function getTestTemplate(test) {
|
|
134
|
+
test = test || 'true';
|
|
135
|
+
test = test.trim();
|
|
136
|
+
// force single equals replacement
|
|
137
|
+
// 不替换,会影响 >= 等判断
|
|
138
|
+
// test = test.replace(/([^=!])=([^=])/g, '$1==$2');
|
|
139
|
+
test = test.replace(/-/g, '_');
|
|
140
|
+
return new Function('context', 'with (context||{}){ return ( ' + test + ' ); }');
|
|
141
|
+
}
|
|
142
|
+
function testPasses(test, context) {
|
|
143
|
+
var testFn = getTestTemplate(test);
|
|
144
|
+
try {
|
|
145
|
+
return testFn(context);
|
|
146
|
+
}
|
|
147
|
+
catch (e) { }
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
exports.preprocess = preprocess;
|
package/dist/index.es.js
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import MagicString from 'magic-string';
|
|
2
|
+
import { matchRecursive } from 'xregexp';
|
|
3
|
+
|
|
4
|
+
function preprocess(source, options) {
|
|
5
|
+
if (!source.includes('#endif')) {
|
|
6
|
+
return {
|
|
7
|
+
code: source,
|
|
8
|
+
map: null,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
const context = options.context || {};
|
|
12
|
+
const s = new MagicString(source);
|
|
13
|
+
function preprocessByType(type) {
|
|
14
|
+
replaceRecursive(type, source, s, (s, startMatches, endMatches, include, recurse) => {
|
|
15
|
+
// I need to recurse first, so I don't catch "inner" else-directives
|
|
16
|
+
recurse(include.value, include.start);
|
|
17
|
+
const variant = startMatches.value[1];
|
|
18
|
+
const test = (startMatches.value[2] || '').trim();
|
|
19
|
+
switch (variant) {
|
|
20
|
+
case 'ifdef':
|
|
21
|
+
if (testPasses(test, context)) {
|
|
22
|
+
s.remove(startMatches.start, startMatches.end);
|
|
23
|
+
s.remove(endMatches.start, endMatches.end);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
s.remove(startMatches.start, endMatches.end);
|
|
27
|
+
}
|
|
28
|
+
return;
|
|
29
|
+
case 'ifndef':
|
|
30
|
+
if (!testPasses(test, context)) {
|
|
31
|
+
s.remove(startMatches.start, startMatches.end);
|
|
32
|
+
s.remove(endMatches.start, endMatches.end);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
s.remove(startMatches.start, endMatches.end);
|
|
36
|
+
}
|
|
37
|
+
return;
|
|
38
|
+
default:
|
|
39
|
+
throw new Error('Unknown if variant ' + variant + '.');
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
const type = options.type || 'auto';
|
|
44
|
+
if (type === 'auto' || type === 'js') {
|
|
45
|
+
preprocessByType(TYPES.js);
|
|
46
|
+
}
|
|
47
|
+
if (type === 'auto' || type === 'html') {
|
|
48
|
+
preprocessByType(TYPES.html);
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
code: s.toString(),
|
|
52
|
+
map: options.sourceMap ? s.generateMap(options.sourceMap) : null,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
const startPattern = '[ \t]*(?://|/\\*)[ \t]*#(ifndef|ifdef)[ \t]+([^\n*]*)(?:\\*(?:\\*|/))?(?:[ \t]*\n+)?';
|
|
56
|
+
const endPattern = '[ \t]*(?://|/\\*)[ \t]*#endif[ \t]*(?:\\*(?:\\*|/))?(?:[ \t]*\n)?';
|
|
57
|
+
const startPatternHTML = '[ \t]*<!--[ \t]*#(ifndef|ifdef|if)[ \t]+(.*?)[ \t]*(?:-->|!>)(?:[ \t]*\n+)?';
|
|
58
|
+
const endPatternHTML = '[ \t]*<!(?:--)?[ \t]*#endif[ \t]*(?:-->|!>)(?:[ \t]*\n)?';
|
|
59
|
+
const TYPES = {
|
|
60
|
+
js: {
|
|
61
|
+
start: {
|
|
62
|
+
pattern: startPattern,
|
|
63
|
+
regex: new RegExp(startPattern, 'mi'),
|
|
64
|
+
},
|
|
65
|
+
end: {
|
|
66
|
+
pattern: endPattern,
|
|
67
|
+
regex: new RegExp(endPattern, 'mi'),
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
html: {
|
|
71
|
+
start: {
|
|
72
|
+
pattern: startPatternHTML,
|
|
73
|
+
regex: new RegExp(startPatternHTML, 'mi'),
|
|
74
|
+
},
|
|
75
|
+
end: {
|
|
76
|
+
pattern: endPatternHTML,
|
|
77
|
+
regex: new RegExp(endPatternHTML, 'mi'),
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
function replaceRecursive(type, source, s, processor) {
|
|
82
|
+
function matchReplacePass(content, startOffset = 0) {
|
|
83
|
+
const matches = matchRecursive(content, type.start.pattern, type.end.pattern, 'gmi', {
|
|
84
|
+
valueNames: ['between', 'left', 'match', 'right'],
|
|
85
|
+
});
|
|
86
|
+
let left = null;
|
|
87
|
+
let match = null;
|
|
88
|
+
let right = null;
|
|
89
|
+
matches.forEach(function ({ name, value, start, end }) {
|
|
90
|
+
start = start + startOffset;
|
|
91
|
+
end = end + startOffset;
|
|
92
|
+
switch (name) {
|
|
93
|
+
case 'between':
|
|
94
|
+
break;
|
|
95
|
+
case 'left':
|
|
96
|
+
left = {
|
|
97
|
+
start,
|
|
98
|
+
end,
|
|
99
|
+
value: type.start.regex.exec(value),
|
|
100
|
+
};
|
|
101
|
+
break;
|
|
102
|
+
case 'match':
|
|
103
|
+
match = {
|
|
104
|
+
start,
|
|
105
|
+
end,
|
|
106
|
+
value,
|
|
107
|
+
};
|
|
108
|
+
break;
|
|
109
|
+
case 'right':
|
|
110
|
+
right = {
|
|
111
|
+
start,
|
|
112
|
+
end,
|
|
113
|
+
value: type.end.regex.exec(value),
|
|
114
|
+
};
|
|
115
|
+
if (left && match && right) {
|
|
116
|
+
processor(s, left, right, match, matchReplacePass);
|
|
117
|
+
left = null;
|
|
118
|
+
match = null;
|
|
119
|
+
right = null;
|
|
120
|
+
}
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
matchReplacePass(source);
|
|
126
|
+
}
|
|
127
|
+
function getTestTemplate(test) {
|
|
128
|
+
test = test || 'true';
|
|
129
|
+
test = test.trim();
|
|
130
|
+
// force single equals replacement
|
|
131
|
+
// 不替换,会影响 >= 等判断
|
|
132
|
+
// test = test.replace(/([^=!])=([^=])/g, '$1==$2');
|
|
133
|
+
test = test.replace(/-/g, '_');
|
|
134
|
+
return new Function('context', 'with (context||{}){ return ( ' + test + ' ); }');
|
|
135
|
+
}
|
|
136
|
+
function testPasses(test, context) {
|
|
137
|
+
var testFn = getTestTemplate(test);
|
|
138
|
+
try {
|
|
139
|
+
return testFn(context);
|
|
140
|
+
}
|
|
141
|
+
catch (e) { }
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export { preprocess };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { SourceMap } from 'magic-string';
|
|
2
|
+
import { SourceMapOptions } from 'magic-string';
|
|
3
|
+
|
|
4
|
+
export declare function preprocess(source: string, options: PreprocessOptions): {
|
|
5
|
+
code: string;
|
|
6
|
+
map: SourceMap | null;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export declare interface PreprocessOptions {
|
|
10
|
+
type?: 'js' | 'html';
|
|
11
|
+
context: ProcessContext;
|
|
12
|
+
sourceMap?: SourceMapOptions;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export declare type ProcessContext = Record<string, any>;
|
|
16
|
+
|
|
17
|
+
export { SourceMapOptions }
|
|
18
|
+
|
|
19
|
+
export { }
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dcloudio/uni-preprocess",
|
|
3
|
+
"version": "3.0.0-alpha-4000020231226001",
|
|
4
|
+
"description": "@dcloudio/uni-preprocess",
|
|
5
|
+
"main": "dist/index.cjs.js",
|
|
6
|
+
"module": "dist/index.es.js",
|
|
7
|
+
"types": "dist/uni-preprocess.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"sideEffects": false,
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/dcloudio/uni-app.git",
|
|
15
|
+
"directory": "packages/uni-preprocess"
|
|
16
|
+
},
|
|
17
|
+
"license": "Apache-2.0",
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/dcloudio/uni-app/issues"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"magic-string": "^0.30.0",
|
|
23
|
+
"xregexp": "^5.1.1"
|
|
24
|
+
}
|
|
25
|
+
}
|