1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 | 'use strict';
|
22 | const fs = require('fs');
|
23 | const path = require('path');
|
24 | const MODULE_REGEX = /require\s?\(([0-9]+)[^)]*\)/g;
|
25 | const EXPR_STMT = 'ExpressionStatement';
|
26 | const EMPTY_STMT = 'EmptyStatement';
|
27 | const IF_STMT = 'IfStatement';
|
28 |
|
29 | const BINARY_EXPR = 'BinaryExpression';
|
30 | const LOGICAL_EXPR = 'LogicalExpression';
|
31 | const UNARY_EXPR = 'UnaryExpression';
|
32 | const CALL_EXPR = 'CallExpression';
|
33 | const FUNC_EXPR = 'FunctionExpression';
|
34 | const COND_EXPR = 'ConditionalExpression';
|
35 | const IDENTIFIER = 'Identifier';
|
36 | const LITERAL_NUM = 'NumericLiteral';
|
37 | const LITERAL_STR = 'StringLiteral';
|
38 |
|
39 | import type {Config} from '../flow/types';
|
40 |
|
41 | const DEFAULT_ASSET_EXTS = [
|
42 | 'bmp', 'gif', 'jpg', 'jpeg', 'png', 'psd', 'svg', 'webp',
|
43 | 'm4v', 'mov', 'mp4', 'mpeg', 'mpg', 'webm',
|
44 | 'aac', 'aiff', 'caf', 'm4a', 'mp3', 'wav',
|
45 | 'html', 'pdf',
|
46 | ];
|
47 |
|
48 | export function isReactNativeEntry(moduleName : string) : boolean {
|
49 | return moduleName === 'react-native-implementation' ||
|
50 | moduleName === 'react-native/Libraries/react-native/react-native.js';
|
51 | }
|
52 |
|
53 | export function isAssetModule(moduleName : string) : boolean {
|
54 | let ext = moduleName.substring(moduleName.lastIndexOf('.') + 1);
|
55 | return DEFAULT_ASSET_EXTS.indexOf(ext) > 0;
|
56 | }
|
57 |
|
58 | export function isEmptyStmt(node : any) : boolean {
|
59 | try {
|
60 | return node.type === EMPTY_STMT;
|
61 | } catch (e) {
|
62 | return false;
|
63 | }
|
64 | }
|
65 |
|
66 | export function getAssetConfig(node: any) : any {
|
67 | const func = node.expression.arguments[0];
|
68 | const rhs = func.body.body[0].expression.right;
|
69 | const propNode = rhs.arguments[0].properties;
|
70 | const assetConfig = {
|
71 | code: {
|
72 | start : rhs.arguments[0].start,
|
73 | end: rhs.arguments[0].end
|
74 | }
|
75 | };
|
76 | propNode.forEach(prop => {
|
77 | let key = prop.key.value ? prop.key.value : prop.key.name;
|
78 | if (key === 'scales') {
|
79 | let value = [];
|
80 | prop.value.elements.forEach(scaleNode => {
|
81 | value.push(scaleNode.value);
|
82 | });
|
83 | assetConfig[key] = value;
|
84 | } else {
|
85 | assetConfig[key] = prop.value.value;
|
86 | }
|
87 | });
|
88 | return assetConfig;
|
89 | }
|
90 |
|
91 | export function isModuleCall(node : any) : boolean {
|
92 | try {
|
93 | return node.type === EXPR_STMT
|
94 | && node.expression.type === CALL_EXPR
|
95 | && node.expression.callee.type === IDENTIFIER
|
96 | && node.expression.callee.name === 'require'
|
97 | && node.expression.arguments.length === 1
|
98 | && node.expression.arguments[0].type === LITERAL_NUM;
|
99 | } catch (e) {
|
100 | return false;
|
101 | }
|
102 | }
|
103 |
|
104 | export function isRequirePolyfillCondition(node: any, dev: boolean) : boolean {
|
105 | if (node.type === IF_STMT
|
106 | && node.test.type === LOGICAL_EXPR
|
107 | && node.test.left.name === '__DEV__'
|
108 | && node.test.operator === '&&'
|
109 | && node.test.right.type === BINARY_EXPR) {
|
110 | let binaryExpr = node.test.right;
|
111 | if (dev) {
|
112 | return binaryExpr.left.operator === 'typeof'
|
113 | && binaryExpr.operator === '==='
|
114 | && binaryExpr.right.type === LITERAL_STR;
|
115 | } else {
|
116 | return binaryExpr.left.type === LITERAL_STR
|
117 | && binaryExpr.operator === '=='
|
118 | && binaryExpr.right.operator === 'typeof';
|
119 | }
|
120 | }
|
121 | }
|
122 |
|
123 | export function isPolyfillCall(node : any, dev : boolean) : boolean {
|
124 | try {
|
125 | let isPolyfillCallExpr = (expr: any) => {
|
126 | return expr.type === CALL_EXPR
|
127 | && expr.callee.type === FUNC_EXPR
|
128 | && expr.callee.params.length === 1
|
129 | && expr.callee.params[0].type === IDENTIFIER
|
130 | && expr.arguments.length === 1
|
131 | && expr.arguments[0].type === COND_EXPR;
|
132 | };
|
133 | if (dev) {
|
134 | return node.type === EXPR_STMT && isPolyfillCallExpr(node.expression);
|
135 | } else {
|
136 | return node.type === EXPR_STMT
|
137 | && node.expression.type === UNARY_EXPR
|
138 | && isPolyfillCallExpr(node.expression.argument);
|
139 | }
|
140 | } catch (e) {
|
141 | return false;
|
142 | }
|
143 | }
|
144 |
|
145 | export function isModuleDeclaration(node : any) : boolean {
|
146 | try {
|
147 | return node.type === EXPR_STMT
|
148 | && node.expression.type === CALL_EXPR
|
149 | && node.expression.callee.type === IDENTIFIER
|
150 | && node.expression.callee.name === '__d';
|
151 | } catch (e) {
|
152 | return false;
|
153 | }
|
154 | }
|
155 |
|
156 | export function replaceModuleIdWithName(codeBlob : string, modules : any) : string {
|
157 | let dependencies = getModuleDependencyCodeRange(codeBlob, 0, codeBlob.length);
|
158 | if (dependencies) {
|
159 | dependencies.forEach(deps => {
|
160 | let moduleName = modules[deps.module].name;
|
161 | codeBlob = codeBlob.replace(deps.code, 'require(\"' + moduleName + '\")');
|
162 | });
|
163 | }
|
164 | return codeBlob;
|
165 | }
|
166 |
|
167 | export function getModuleDependency(codeBlob : string, start : number, end : number) : Array<number> {
|
168 | const dependency = [];
|
169 | const bodyString = codeBlob.substring(start, end);
|
170 | let result;
|
171 | while(result = MODULE_REGEX.exec(bodyString)) {
|
172 | dependency.push(parseInt(result[1]));
|
173 | }
|
174 | return dependency;
|
175 | }
|
176 |
|
177 | export function getModuleDependencyCodeRange(codeBlob : string, start : number, end : number) : Array<any> {
|
178 | const dependency = [];
|
179 | const bodyString = codeBlob.substring(start, end);
|
180 | let result;
|
181 | while(result = MODULE_REGEX.exec(bodyString)) {
|
182 | dependency.push({
|
183 | code: result[0],
|
184 | module: parseInt(result[1])
|
185 | });
|
186 | }
|
187 | return dependency;
|
188 | }
|
189 |
|
190 | export function ensureFolder(dir : string) {
|
191 | try {
|
192 | fs.accessSync(dir, fs.F_OK);
|
193 | return true;
|
194 | } catch (e) {
|
195 | fs.mkdirSync(dir);
|
196 | return false;
|
197 | }
|
198 | }
|
199 |
|
200 |
|
201 |
|
202 |
|
203 | export function mkdirsSync(dirname) {
|
204 |
|
205 | if (fs.existsSync(dirname)) {
|
206 | return true;
|
207 | } else {
|
208 | if (mkdirsSync(path.dirname(dirname))) {
|
209 | fs.mkdirSync(dirname);
|
210 | return true;
|
211 | }
|
212 | }
|
213 | }
|
214 |
|
215 |
|
216 |
|
217 |
|
218 |
|
219 |
|
220 |
|
221 |
|
222 |
|
223 |
|
224 |
|
225 |
|
226 |
|
227 |
|
228 |
|
229 |
|