@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 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;
@@ -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
+ }