@tamagui/static 1.0.1-beta.192 → 1.0.1-beta.194
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/dist/extractor/babelParse.js.map +2 -2
- package/dist/extractor/bundle.js +117 -0
- package/dist/extractor/bundle.js.map +7 -0
- package/dist/extractor/createExtractor.js +147 -79
- package/dist/extractor/createExtractor.js.map +3 -3
- package/dist/extractor/extractHelpers.js +41 -6
- package/dist/extractor/extractHelpers.js.map +2 -2
- package/dist/extractor/extractToClassNames.js +2 -1
- package/dist/extractor/extractToClassNames.js.map +2 -2
- package/dist/extractor/getPropValueFromAttributes.js.map +2 -2
- package/dist/extractor/loadTamagui.js +219 -117
- package/dist/extractor/loadTamagui.js.map +3 -3
- package/dist/extractor/normalizeTernaries.js.map +2 -2
- package/dist/getPragmaOptions.js +1 -1
- package/dist/getPragmaOptions.js.map +2 -2
- package/dist/index.js +0 -1
- package/dist/index.js.map +2 -2
- package/dist/require.js +13 -7
- package/dist/require.js.map +2 -2
- package/dist/tamagui-node/tamagui.config.js +6781 -0
- package/dist/tamagui-node/tamaguicore-components.config.js +0 -0
- package/dist/tamagui-node/tamaguitestdesignsystem-components.config.js +31 -0
- package/dist/types.js.map +1 -1
- package/package.json +20 -17
- package/src/extractor/babelParse.ts +3 -2
- package/src/extractor/bundle.ts +110 -0
- package/src/extractor/createExtractor.ts +167 -70
- package/src/extractor/extractHelpers.ts +57 -10
- package/src/extractor/extractToClassNames.ts +12 -9
- package/src/extractor/getPropValueFromAttributes.ts +1 -1
- package/src/extractor/loadTamagui.ts +256 -145
- package/src/extractor/normalizeTernaries.ts +1 -1
- package/src/getPragmaOptions.ts +2 -1
- package/src/index.ts +0 -1
- package/src/require.ts +16 -8
- package/src/types.ts +5 -1
- package/types/extractor/babelParse.d.ts +2 -1
- package/types/extractor/bundle.d.ts +13 -0
- package/types/extractor/extractHelpers.d.ts +13 -3
- package/types/extractor/extractToClassNames.d.ts +3 -2
- package/types/extractor/findTopmostFunction.d.ts +1 -1
- package/types/extractor/loadTamagui.d.ts +9 -2
- package/types/index.d.ts +0 -1
- package/types/types.d.ts +4 -1
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
|
-
import
|
|
2
|
+
import { basename, join, relative } from 'path'
|
|
3
3
|
|
|
4
|
-
import traverse, { NodePath,
|
|
4
|
+
import traverse, { NodePath, TraverseOptions } from '@babel/traverse'
|
|
5
5
|
import * as t from '@babel/types'
|
|
6
6
|
import {
|
|
7
7
|
PseudoStyles,
|
|
8
8
|
StaticConfigParsed,
|
|
9
|
-
createDOMProps,
|
|
10
9
|
expandStyles,
|
|
11
10
|
getSplitStyles,
|
|
12
11
|
getStylesAtomic,
|
|
@@ -14,6 +13,7 @@ import {
|
|
|
14
13
|
proxyThemeVariables,
|
|
15
14
|
pseudoDescriptors,
|
|
16
15
|
} from '@tamagui/core-node'
|
|
16
|
+
import { createDOMProps } from '@tamagui/rnw'
|
|
17
17
|
import type { ViewStyle } from 'react-native'
|
|
18
18
|
|
|
19
19
|
import { FAILED_EVAL } from '../constants.js'
|
|
@@ -29,12 +29,25 @@ import type {
|
|
|
29
29
|
} from '../types.js'
|
|
30
30
|
import { createEvaluator, createSafeEvaluator } from './createEvaluator.js'
|
|
31
31
|
import { evaluateAstNode } from './evaluateAstNode.js'
|
|
32
|
-
import {
|
|
32
|
+
import {
|
|
33
|
+
attrStr,
|
|
34
|
+
findComponentName,
|
|
35
|
+
getValidComponent,
|
|
36
|
+
getValidImport,
|
|
37
|
+
isPresent,
|
|
38
|
+
isValidImport,
|
|
39
|
+
objToStr,
|
|
40
|
+
} from './extractHelpers.js'
|
|
33
41
|
import { findTopmostFunction } from './findTopmostFunction.js'
|
|
34
42
|
import { getPrefixLogs } from './getPrefixLogs.js'
|
|
35
43
|
import { cleanupBeforeExit, getStaticBindingsForScope } from './getStaticBindingsForScope.js'
|
|
36
44
|
import { literalToAst } from './literalToAst.js'
|
|
37
|
-
import {
|
|
45
|
+
import {
|
|
46
|
+
LoadedComponents,
|
|
47
|
+
TamaguiProjectInfo,
|
|
48
|
+
loadTamagui,
|
|
49
|
+
loadTamaguiSync,
|
|
50
|
+
} from './loadTamagui.js'
|
|
38
51
|
import { logLines } from './logLines.js'
|
|
39
52
|
import { normalizeTernaries } from './normalizeTernaries.js'
|
|
40
53
|
import { removeUnusedHooks } from './removeUnusedHooks.js'
|
|
@@ -71,6 +84,8 @@ export type Extractor = ReturnType<typeof createExtractor>
|
|
|
71
84
|
|
|
72
85
|
type FileOrPath = NodePath<t.Program> | t.File
|
|
73
86
|
|
|
87
|
+
let hasLoggedBaseInfo = false
|
|
88
|
+
|
|
74
89
|
export function createExtractor({ logger = console }: ExtractorOptions = { logger: console }) {
|
|
75
90
|
if (!process.env.TAMAGUI_TARGET) {
|
|
76
91
|
console.log('⚠️ Please set process.env.TAMAGUI_TARGET to either "web" or "native"')
|
|
@@ -156,6 +171,7 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
156
171
|
disableExtractVariables,
|
|
157
172
|
disableDebugAttr,
|
|
158
173
|
disableExtractFoundComponents,
|
|
174
|
+
includeExtensions = ['.tsx', '.jsx'],
|
|
159
175
|
extractStyledDefinitions = false,
|
|
160
176
|
prefixLogs,
|
|
161
177
|
excludeProps,
|
|
@@ -165,7 +181,7 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
165
181
|
|
|
166
182
|
let shouldPrintDebug = options.shouldPrintDebug || false
|
|
167
183
|
|
|
168
|
-
if (disable) {
|
|
184
|
+
if (disable === true || (Array.isArray(disable) && disable.includes(sourcePath))) {
|
|
169
185
|
return null
|
|
170
186
|
}
|
|
171
187
|
if (sourcePath === '') {
|
|
@@ -174,6 +190,20 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
174
190
|
if (!components) {
|
|
175
191
|
throw new Error(`Must provide components`)
|
|
176
192
|
}
|
|
193
|
+
if (includeExtensions && !includeExtensions.some((ext) => sourcePath.endsWith(ext))) {
|
|
194
|
+
if (shouldPrintDebug) {
|
|
195
|
+
logger.info(
|
|
196
|
+
`Ignoring file due to includeExtensions: ${sourcePath}, includeExtensions: ${includeExtensions.join(
|
|
197
|
+
', '
|
|
198
|
+
)}`
|
|
199
|
+
)
|
|
200
|
+
}
|
|
201
|
+
return null
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Step 1: Determine if importing any statically extractable components
|
|
206
|
+
*/
|
|
177
207
|
|
|
178
208
|
const isTargetingHTML = target === 'html'
|
|
179
209
|
const ogDebug = shouldPrintDebug
|
|
@@ -181,10 +211,31 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
181
211
|
const propsWithFileInfo: TamaguiOptionsWithFileInfo = {
|
|
182
212
|
...options,
|
|
183
213
|
sourcePath,
|
|
214
|
+
allLoadedComponents: [...components],
|
|
184
215
|
}
|
|
185
216
|
|
|
186
|
-
if (
|
|
187
|
-
|
|
217
|
+
if (!hasLoggedBaseInfo) {
|
|
218
|
+
hasLoggedBaseInfo = true
|
|
219
|
+
if (shouldPrintDebug) {
|
|
220
|
+
logger.info(
|
|
221
|
+
[
|
|
222
|
+
'loaded components:',
|
|
223
|
+
propsWithFileInfo.allLoadedComponents
|
|
224
|
+
.map((comp) => Object.keys(comp.nameToInfo).join(', '))
|
|
225
|
+
.join(', '),
|
|
226
|
+
].join(' ')
|
|
227
|
+
)
|
|
228
|
+
}
|
|
229
|
+
if (process.env.DEBUG?.startsWith('tamagui')) {
|
|
230
|
+
const next = [...propsWithFileInfo.allLoadedComponents].map((info) => {
|
|
231
|
+
const nameToInfo = { ...info.nameToInfo }
|
|
232
|
+
for (const key in nameToInfo) {
|
|
233
|
+
delete nameToInfo[key].staticConfig.validStyles
|
|
234
|
+
}
|
|
235
|
+
return { ...info, nameToInfo }
|
|
236
|
+
})
|
|
237
|
+
logger.info(['loaded:', JSON.stringify(next, null, 2)].join('\n'))
|
|
238
|
+
}
|
|
188
239
|
}
|
|
189
240
|
|
|
190
241
|
tm.mark('load-tamagui', !!shouldPrintDebug)
|
|
@@ -194,13 +245,12 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
194
245
|
|
|
195
246
|
if (!firstTheme || typeof firstTheme !== 'object') {
|
|
196
247
|
console.error(`Missing theme, an error occurred when importing your config`)
|
|
197
|
-
console.log(`Got
|
|
248
|
+
console.log(`Got config:`, tamaguiConfig)
|
|
198
249
|
console.log(`Looking for theme:`, firstThemeName)
|
|
199
250
|
process.exit(0)
|
|
200
251
|
}
|
|
201
252
|
|
|
202
253
|
const proxiedTheme = proxyThemeVariables(firstTheme)
|
|
203
|
-
|
|
204
254
|
type AccessListener = (key: string) => void
|
|
205
255
|
const themeAccessListeners = new Set<AccessListener>()
|
|
206
256
|
const defaultTheme = new Proxy(proxiedTheme, {
|
|
@@ -215,19 +265,7 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
215
265
|
// @ts-ignore
|
|
216
266
|
const body = fileOrPath.type === 'Program' ? fileOrPath.get('body') : fileOrPath.program.body
|
|
217
267
|
|
|
218
|
-
|
|
219
|
-
* Step 1: Determine if importing any statically extractable components
|
|
220
|
-
*/
|
|
221
|
-
|
|
222
|
-
const validComponents: { [key: string]: any } = Object.keys(components)
|
|
223
|
-
// check if uppercase to avoid hitting media query proxy before init
|
|
224
|
-
.filter((key) => key[0].toUpperCase() === key[0] && !!components[key]?.staticConfig)
|
|
225
|
-
.reduce((obj, name) => {
|
|
226
|
-
obj[name] = components[name]
|
|
227
|
-
return obj
|
|
228
|
-
}, {})
|
|
229
|
-
|
|
230
|
-
if (Object.keys(validComponents).length === 0) {
|
|
268
|
+
if (Object.keys(components).length === 0) {
|
|
231
269
|
console.warn(`Warning: Tamagui didn't find any valid components (DEBUG=tamagui for more)`)
|
|
232
270
|
if (process.env.DEBUG === 'tamagui') {
|
|
233
271
|
console.log(`components`, Object.keys(components), components)
|
|
@@ -235,27 +273,33 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
235
273
|
}
|
|
236
274
|
|
|
237
275
|
if (shouldPrintDebug === 'verbose') {
|
|
238
|
-
logger.info(
|
|
276
|
+
logger.info(
|
|
277
|
+
`allLoadedComponent modules ${propsWithFileInfo.allLoadedComponents
|
|
278
|
+
.map((k) => k.moduleName)
|
|
279
|
+
.join(', ')}`
|
|
280
|
+
)
|
|
239
281
|
}
|
|
240
282
|
|
|
241
283
|
let doesUseValidImport = false
|
|
242
284
|
let hasImportedTheme = false
|
|
243
285
|
|
|
286
|
+
const importDeclarations: t.ImportDeclaration[] = []
|
|
287
|
+
|
|
244
288
|
for (const bodyPath of body) {
|
|
245
289
|
if (bodyPath.type !== 'ImportDeclaration') continue
|
|
246
290
|
const node = ('node' in bodyPath ? bodyPath.node : bodyPath) as t.ImportDeclaration
|
|
247
|
-
const
|
|
291
|
+
const moduleName = node.source.value
|
|
292
|
+
|
|
293
|
+
// if importing valid module
|
|
294
|
+
const valid = isValidImport(propsWithFileInfo, moduleName)
|
|
248
295
|
|
|
249
|
-
|
|
250
|
-
|
|
296
|
+
if (valid) {
|
|
297
|
+
importDeclarations.push(node)
|
|
298
|
+
}
|
|
251
299
|
|
|
252
300
|
if (extractStyledDefinitions) {
|
|
253
301
|
if (valid) {
|
|
254
|
-
if (
|
|
255
|
-
node.specifiers.some((specifier) => {
|
|
256
|
-
return specifier.local.name === 'styled'
|
|
257
|
-
})
|
|
258
|
-
) {
|
|
302
|
+
if (node.specifiers.some((specifier) => specifier.local.name === 'styled')) {
|
|
259
303
|
doesUseValidImport = true
|
|
260
304
|
break
|
|
261
305
|
}
|
|
@@ -264,10 +308,12 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
264
308
|
|
|
265
309
|
if (valid) {
|
|
266
310
|
const names = node.specifiers.map((specifier) => specifier.local.name)
|
|
267
|
-
const isValidComponent = names.some((name) =>
|
|
311
|
+
const isValidComponent = names.some((name) =>
|
|
312
|
+
Boolean(isValidImport(propsWithFileInfo, moduleName, name) || validHooks[name])
|
|
313
|
+
)
|
|
268
314
|
if (shouldPrintDebug === 'verbose') {
|
|
269
315
|
logger.info(
|
|
270
|
-
`import ${names.join(', ')} from ${
|
|
316
|
+
`import ${names.join(', ')} from ${moduleName} isValidComponent ${isValidComponent}`
|
|
271
317
|
)
|
|
272
318
|
}
|
|
273
319
|
if (isValidComponent) {
|
|
@@ -278,13 +324,23 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
278
324
|
}
|
|
279
325
|
|
|
280
326
|
if (shouldPrintDebug) {
|
|
281
|
-
logger.info(`
|
|
327
|
+
logger.info(`file: ${sourcePath} ${JSON.stringify({ doesUseValidImport, hasImportedTheme })}`)
|
|
282
328
|
}
|
|
283
329
|
|
|
284
330
|
if (!doesUseValidImport) {
|
|
285
331
|
return null
|
|
286
332
|
}
|
|
287
333
|
|
|
334
|
+
function getValidImportedComponent(componentName: string) {
|
|
335
|
+
const importDeclaration = importDeclarations.find((dec) =>
|
|
336
|
+
dec.specifiers.some((spec) => spec.local.name === componentName)
|
|
337
|
+
)
|
|
338
|
+
if (!importDeclaration) {
|
|
339
|
+
return null
|
|
340
|
+
}
|
|
341
|
+
return getValidImport(propsWithFileInfo, importDeclaration.source.value, componentName)
|
|
342
|
+
}
|
|
343
|
+
|
|
288
344
|
tm.mark('import-check', !!shouldPrintDebug)
|
|
289
345
|
|
|
290
346
|
let couldntParse = false
|
|
@@ -293,10 +349,14 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
293
349
|
// only keeping a cache around per-file, reset it if it changes
|
|
294
350
|
const bindingCache: Record<string, string | null> = {}
|
|
295
351
|
|
|
296
|
-
const callTraverse = (a:
|
|
352
|
+
const callTraverse = (a: TraverseOptions<any>) => {
|
|
297
353
|
return fileOrPath.type === 'File' ? traverse(fileOrPath, a) : fileOrPath.traverse(a)
|
|
298
354
|
}
|
|
299
355
|
|
|
356
|
+
const shouldDisableExtraction =
|
|
357
|
+
disableExtraction === true ||
|
|
358
|
+
(Array.isArray(disableExtraction) && disableExtraction.includes(sourcePath))
|
|
359
|
+
|
|
300
360
|
/**
|
|
301
361
|
* Step 2: Statically extract from JSX < /> nodes
|
|
302
362
|
*/
|
|
@@ -311,6 +371,7 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
311
371
|
}
|
|
312
372
|
|
|
313
373
|
callTraverse({
|
|
374
|
+
// @ts-ignore
|
|
314
375
|
Program: {
|
|
315
376
|
enter(path) {
|
|
316
377
|
programPath = path
|
|
@@ -319,7 +380,7 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
319
380
|
|
|
320
381
|
// styled() calls
|
|
321
382
|
CallExpression(path) {
|
|
322
|
-
if (disable ||
|
|
383
|
+
if (disable || shouldDisableExtraction || extractStyledDefinitions === false) {
|
|
323
384
|
return
|
|
324
385
|
}
|
|
325
386
|
|
|
@@ -331,20 +392,31 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
331
392
|
t.isVariableDeclarator(path.parent) && t.isIdentifier(path.parent.id)
|
|
332
393
|
? path.parent.id.name
|
|
333
394
|
: 'unknown'
|
|
395
|
+
|
|
334
396
|
const definition = path.node.arguments[1]
|
|
335
397
|
|
|
336
398
|
if (!name || !definition || !t.isObjectExpression(definition)) {
|
|
337
399
|
return
|
|
338
400
|
}
|
|
339
401
|
|
|
340
|
-
let Component =
|
|
402
|
+
let Component = getValidImportedComponent(name)
|
|
341
403
|
|
|
342
404
|
if (!Component) {
|
|
343
|
-
if (disableExtractFoundComponents) {
|
|
405
|
+
if (disableExtractFoundComponents === true) {
|
|
406
|
+
return
|
|
407
|
+
}
|
|
408
|
+
if (
|
|
409
|
+
Array.isArray(disableExtractFoundComponents) &&
|
|
410
|
+
disableExtractFoundComponents.includes(name)
|
|
411
|
+
) {
|
|
344
412
|
return
|
|
345
413
|
}
|
|
346
414
|
|
|
347
415
|
try {
|
|
416
|
+
if (shouldPrintDebug) {
|
|
417
|
+
logger.info(`Unknown component ${name}, attempting dynamic load: ${sourcePath}`)
|
|
418
|
+
}
|
|
419
|
+
|
|
348
420
|
const out = loadTamaguiSync({
|
|
349
421
|
// TODO would extract more, is NO-OP for now..
|
|
350
422
|
forceExports: true,
|
|
@@ -352,16 +424,22 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
352
424
|
components: [sourcePath],
|
|
353
425
|
})
|
|
354
426
|
|
|
355
|
-
if (out
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
427
|
+
if (!out?.components) {
|
|
428
|
+
if (shouldPrintDebug) {
|
|
429
|
+
logger.info(`Couldn't load, got ${out}`)
|
|
430
|
+
}
|
|
431
|
+
return
|
|
359
432
|
}
|
|
360
433
|
|
|
361
|
-
|
|
434
|
+
propsWithFileInfo.allLoadedComponents = [
|
|
435
|
+
...propsWithFileInfo.allLoadedComponents,
|
|
436
|
+
...out.components,
|
|
437
|
+
]
|
|
438
|
+
|
|
439
|
+
Component = out.components.flatMap((x) => x.nameToInfo[name] ?? [])[0]
|
|
362
440
|
|
|
363
441
|
if (shouldPrintDebug) {
|
|
364
|
-
logger.info([`Loaded`,
|
|
442
|
+
logger.info([`Tamagui Loaded`, JSON.stringify(out.components), !!Component].join(' '))
|
|
365
443
|
}
|
|
366
444
|
} catch (err: any) {
|
|
367
445
|
if (shouldPrintDebug) {
|
|
@@ -411,7 +489,7 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
411
489
|
const attemptEval = !evaluateVars
|
|
412
490
|
? evaluateAstNode
|
|
413
491
|
: createEvaluator({
|
|
414
|
-
props:
|
|
492
|
+
props: propsWithFileInfo,
|
|
415
493
|
staticNamespace,
|
|
416
494
|
sourcePath,
|
|
417
495
|
shouldPrintDebug,
|
|
@@ -492,6 +570,10 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
492
570
|
},
|
|
493
571
|
|
|
494
572
|
JSXElement(traversePath) {
|
|
573
|
+
if (shouldDisableExtraction) {
|
|
574
|
+
return
|
|
575
|
+
}
|
|
576
|
+
|
|
495
577
|
tm.mark('jsx-element', !!shouldPrintDebug)
|
|
496
578
|
|
|
497
579
|
const node = traversePath.node.openingElement
|
|
@@ -506,6 +588,7 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
506
588
|
|
|
507
589
|
// validate its a proper import from tamagui (or internally inside tamagui)
|
|
508
590
|
const binding = traversePath.scope.getBinding(node.name.name)
|
|
591
|
+
let modulePath = ''
|
|
509
592
|
|
|
510
593
|
if (binding) {
|
|
511
594
|
if (!t.isImportDeclaration(binding.path.parent)) {
|
|
@@ -514,24 +597,16 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
514
597
|
}
|
|
515
598
|
return
|
|
516
599
|
}
|
|
517
|
-
|
|
518
|
-
if (!isValidImport(propsWithFileInfo,
|
|
600
|
+
modulePath = binding.path.parent.source.value
|
|
601
|
+
if (!isValidImport(propsWithFileInfo, modulePath, binding.identifier.name)) {
|
|
519
602
|
if (shouldPrintDebug) {
|
|
520
|
-
logger.info(` - Binding not internal import or from components ${
|
|
521
|
-
}
|
|
522
|
-
return
|
|
523
|
-
}
|
|
524
|
-
if (!validComponents[binding.identifier.name]) {
|
|
525
|
-
if (shouldPrintDebug) {
|
|
526
|
-
logger.info(
|
|
527
|
-
` - Binding not valid component (binding.identifier.name) ${binding.identifier.name}`
|
|
528
|
-
)
|
|
603
|
+
logger.info(` - Binding not internal import or from components ${modulePath}`)
|
|
529
604
|
}
|
|
530
605
|
return
|
|
531
606
|
}
|
|
532
607
|
}
|
|
533
608
|
|
|
534
|
-
const component =
|
|
609
|
+
const component = getValidComponent(propsWithFileInfo, modulePath, node.name.name)
|
|
535
610
|
if (!component || !component.staticConfig) {
|
|
536
611
|
if (shouldPrintDebug) {
|
|
537
612
|
logger.info(` - No Tamagui conf on this: ${node.name.name}`)
|
|
@@ -557,7 +632,8 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
557
632
|
.filter(
|
|
558
633
|
(n) => t.isJSXAttribute(n) && t.isJSXIdentifier(n.name) && n.name.name === 'debug'
|
|
559
634
|
)
|
|
560
|
-
|
|
635
|
+
// @ts-ignore
|
|
636
|
+
.map((n: t.JSXAttribute) => {
|
|
561
637
|
if (n.value === null) return true
|
|
562
638
|
if (t.isStringLiteral(n.value)) return n.value.value as 'verbose'
|
|
563
639
|
return false
|
|
@@ -658,7 +734,7 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
658
734
|
const attemptEval = !evaluateVars
|
|
659
735
|
? evaluateAstNode
|
|
660
736
|
: createEvaluator({
|
|
661
|
-
props:
|
|
737
|
+
props: propsWithFileInfo,
|
|
662
738
|
staticNamespace,
|
|
663
739
|
sourcePath,
|
|
664
740
|
traversePath,
|
|
@@ -1405,7 +1481,11 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
1405
1481
|
traversePath.node.children.every((x) => x.type === 'JSXText')))
|
|
1406
1482
|
|
|
1407
1483
|
const themeVal = inlined.get('theme')
|
|
1408
|
-
|
|
1484
|
+
|
|
1485
|
+
// on native we can't flatten when theme prop is set
|
|
1486
|
+
if (target !== 'native') {
|
|
1487
|
+
inlined.delete('theme')
|
|
1488
|
+
}
|
|
1409
1489
|
|
|
1410
1490
|
for (const [key] of [...inlined]) {
|
|
1411
1491
|
const isStaticObjectVariant = staticConfig.variants?.[key] && variantValues.has(key)
|
|
@@ -1416,13 +1496,14 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
1416
1496
|
|
|
1417
1497
|
const canFlattenProps = inlined.size === 0
|
|
1418
1498
|
|
|
1419
|
-
let shouldFlatten =
|
|
1499
|
+
let shouldFlatten = Boolean(
|
|
1420
1500
|
flatNode &&
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1501
|
+
!shouldDeopt &&
|
|
1502
|
+
canFlattenProps &&
|
|
1503
|
+
!hasSpread &&
|
|
1504
|
+
staticConfig.neverFlatten !== true &&
|
|
1505
|
+
(staticConfig.neverFlatten === 'jsx' ? hasOnlyStringChildren : true)
|
|
1506
|
+
)
|
|
1426
1507
|
|
|
1427
1508
|
const shouldWrapTheme = shouldFlatten && themeVal
|
|
1428
1509
|
const usedThemeKeys = new Set<string>()
|
|
@@ -1432,7 +1513,7 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
1432
1513
|
themeAccessListeners.add((key) => {
|
|
1433
1514
|
shouldFlatten = false
|
|
1434
1515
|
usedThemeKeys.add(key)
|
|
1435
|
-
if (shouldPrintDebug) {
|
|
1516
|
+
if (shouldPrintDebug === 'verbose') {
|
|
1436
1517
|
logger.info([' ! accessing theme key, avoid flatten', key].join(' '))
|
|
1437
1518
|
}
|
|
1438
1519
|
})
|
|
@@ -1517,6 +1598,9 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
1517
1598
|
}
|
|
1518
1599
|
|
|
1519
1600
|
if (shouldDeopt) {
|
|
1601
|
+
if (shouldPrintDebug) {
|
|
1602
|
+
logger.info(`Deopting`)
|
|
1603
|
+
}
|
|
1520
1604
|
node.attributes = ogAttributes
|
|
1521
1605
|
return
|
|
1522
1606
|
}
|
|
@@ -1852,6 +1936,7 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
1852
1936
|
},
|
|
1853
1937
|
undefined,
|
|
1854
1938
|
undefined,
|
|
1939
|
+
undefined,
|
|
1855
1940
|
debugPropValue
|
|
1856
1941
|
)
|
|
1857
1942
|
|
|
@@ -1882,6 +1967,15 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
1882
1967
|
throw new Error(`Impossible, no styles`)
|
|
1883
1968
|
}
|
|
1884
1969
|
|
|
1970
|
+
const isNativeNotFlat = !shouldFlatten && target === 'native'
|
|
1971
|
+
if (isNativeNotFlat) {
|
|
1972
|
+
if (shouldPrintDebug) {
|
|
1973
|
+
logger.info(`Disabled flattening except for simple cases on native for now`)
|
|
1974
|
+
node.attributes = ogAttributes
|
|
1975
|
+
return null
|
|
1976
|
+
}
|
|
1977
|
+
}
|
|
1978
|
+
|
|
1885
1979
|
let getStyleError: any = null
|
|
1886
1980
|
|
|
1887
1981
|
// fix up ternaries, combine final style values
|
|
@@ -1925,7 +2019,7 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
1925
2019
|
if (getStyleError) {
|
|
1926
2020
|
logger.info([' ⚠️ postprocessing error, deopt', getStyleError].join(' '))
|
|
1927
2021
|
node.attributes = ogAttributes
|
|
1928
|
-
return
|
|
2022
|
+
return null
|
|
1929
2023
|
}
|
|
1930
2024
|
|
|
1931
2025
|
// final lazy extra loop:
|
|
@@ -1996,9 +2090,11 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
1996
2090
|
if (shouldPrintDebug) {
|
|
1997
2091
|
logger.info([' [✅] flattening', originalNodeName, flatNode].join(' '))
|
|
1998
2092
|
}
|
|
2093
|
+
// @ts-ignore
|
|
1999
2094
|
node.name.name = flatNode
|
|
2000
2095
|
res.flattened++
|
|
2001
2096
|
if (closingElement) {
|
|
2097
|
+
// @ts-ignore
|
|
2002
2098
|
closingElement.name.name = flatNode
|
|
2003
2099
|
}
|
|
2004
2100
|
}
|
|
@@ -2010,6 +2106,7 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
2010
2106
|
}
|
|
2011
2107
|
|
|
2012
2108
|
onExtractTag({
|
|
2109
|
+
parserProps: propsWithFileInfo,
|
|
2013
2110
|
attrs,
|
|
2014
2111
|
node,
|
|
2015
2112
|
lineNumbers,
|
|
@@ -2018,7 +2115,7 @@ export function createExtractor({ logger = console }: ExtractorOptions = { logge
|
|
|
2018
2115
|
jsxPath: traversePath,
|
|
2019
2116
|
originalNodeName,
|
|
2020
2117
|
isFlattened: shouldFlatten,
|
|
2021
|
-
programPath
|
|
2118
|
+
programPath: programPath!,
|
|
2022
2119
|
completeProps,
|
|
2023
2120
|
staticConfig,
|
|
2024
2121
|
})
|
|
@@ -58,7 +58,7 @@ export const ternaryStr = (x: Ternary) => {
|
|
|
58
58
|
? x.test.name
|
|
59
59
|
: t.isMemberExpression(x.test)
|
|
60
60
|
? [x.test.object['name'], x.test.property['name']]
|
|
61
|
-
: generate(x.test).code
|
|
61
|
+
: generate(x.test as any).code
|
|
62
62
|
return [
|
|
63
63
|
'ternary(',
|
|
64
64
|
conditional,
|
|
@@ -118,9 +118,9 @@ export function isValidThemeHook(
|
|
|
118
118
|
return true
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
export const isInsideComponentPackage = (props: TamaguiOptionsWithFileInfo,
|
|
121
|
+
export const isInsideComponentPackage = (props: TamaguiOptionsWithFileInfo, moduleName: string) => {
|
|
122
122
|
return getValidComponentsPaths(props).some((path) => {
|
|
123
|
-
return
|
|
123
|
+
return moduleName.startsWith(path)
|
|
124
124
|
})
|
|
125
125
|
}
|
|
126
126
|
|
|
@@ -130,15 +130,62 @@ export const isComponentPackage = (props: TamaguiOptionsWithFileInfo, srcName: s
|
|
|
130
130
|
})
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
export
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
133
|
+
export function getValidComponent(
|
|
134
|
+
props: TamaguiOptionsWithFileInfo,
|
|
135
|
+
moduleName: string,
|
|
136
|
+
componentName: string
|
|
137
|
+
) {
|
|
138
|
+
// must be uppercase of course
|
|
139
|
+
if (componentName[0].toUpperCase() !== componentName[0]) {
|
|
137
140
|
return false
|
|
138
141
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
+
|
|
143
|
+
for (const loaded of props.allLoadedComponents) {
|
|
144
|
+
const isInModule = moduleName === '*' || moduleName.startsWith(loaded.moduleName)
|
|
145
|
+
const foundComponent = loaded.nameToInfo[componentName]
|
|
146
|
+
// eslint-disable-next-line no-console
|
|
147
|
+
if (isInModule && foundComponent) {
|
|
148
|
+
return foundComponent
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return null
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export const isValidModule = (props: TamaguiOptionsWithFileInfo, moduleName: string) => {
|
|
156
|
+
if (typeof moduleName !== 'string') {
|
|
157
|
+
throw new Error(`No module name`)
|
|
158
|
+
}
|
|
159
|
+
const isLocal = moduleName.startsWith('.')
|
|
160
|
+
return {
|
|
161
|
+
isLocal,
|
|
162
|
+
isValid: isLocal
|
|
163
|
+
? isInsideComponentPackage(props, moduleName)
|
|
164
|
+
: isComponentPackage(props, moduleName),
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export const getValidImport = (
|
|
169
|
+
props: TamaguiOptionsWithFileInfo,
|
|
170
|
+
moduleName: string,
|
|
171
|
+
componentName?: string
|
|
172
|
+
) => {
|
|
173
|
+
const { isValid, isLocal } = isValidModule(props, moduleName)
|
|
174
|
+
if (!isValid || !componentName) {
|
|
175
|
+
return null
|
|
176
|
+
}
|
|
177
|
+
return getValidComponent(props, isLocal ? '*' : moduleName, componentName) || null
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export const isValidImport = (
|
|
181
|
+
props: TamaguiOptionsWithFileInfo,
|
|
182
|
+
moduleName: string,
|
|
183
|
+
componentName?: string
|
|
184
|
+
) => {
|
|
185
|
+
if (!componentName) {
|
|
186
|
+
return isValidModule(props, moduleName).isValid
|
|
187
|
+
}
|
|
188
|
+
return Boolean(getValidImport(props, moduleName, componentName))
|
|
142
189
|
}
|
|
143
190
|
|
|
144
191
|
const getValidComponentPackages = memoize((props: TamaguiOptionsWithFileInfo) => {
|
|
@@ -36,19 +36,21 @@ export type ExtractedResponse = {
|
|
|
36
36
|
map: any // RawSourceMap from 'source-map'
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
export type ExtractToClassNamesProps = {
|
|
40
|
+
extractor: Extractor
|
|
41
|
+
source: string | Buffer
|
|
42
|
+
sourcePath: string
|
|
43
|
+
options: TamaguiOptions
|
|
44
|
+
shouldPrintDebug: boolean | 'verbose'
|
|
45
|
+
}
|
|
46
|
+
|
|
39
47
|
export async function extractToClassNames({
|
|
40
48
|
extractor,
|
|
41
49
|
source,
|
|
42
50
|
sourcePath,
|
|
43
51
|
options,
|
|
44
52
|
shouldPrintDebug,
|
|
45
|
-
}: {
|
|
46
|
-
extractor: Extractor
|
|
47
|
-
source: string | Buffer
|
|
48
|
-
sourcePath: string
|
|
49
|
-
options: TamaguiOptions
|
|
50
|
-
shouldPrintDebug: boolean | 'verbose'
|
|
51
|
-
}): Promise<ExtractedResponse | null> {
|
|
53
|
+
}: ExtractToClassNamesProps): Promise<ExtractedResponse | null> {
|
|
52
54
|
const tm = timer()
|
|
53
55
|
|
|
54
56
|
if (typeof source !== 'string') {
|
|
@@ -98,6 +100,7 @@ export async function extractToClassNames({
|
|
|
98
100
|
return tag
|
|
99
101
|
},
|
|
100
102
|
onExtractTag: ({
|
|
103
|
+
parserProps,
|
|
101
104
|
attrs,
|
|
102
105
|
node,
|
|
103
106
|
attemptEval,
|
|
@@ -223,7 +226,7 @@ export async function extractToClassNames({
|
|
|
223
226
|
}
|
|
224
227
|
case 'ternary': {
|
|
225
228
|
const mediaExtraction = extractMediaStyle(
|
|
226
|
-
|
|
229
|
+
parserProps,
|
|
227
230
|
attr.value,
|
|
228
231
|
jsxPath,
|
|
229
232
|
extractor.getTamagui()!,
|
|
@@ -383,7 +386,7 @@ export async function extractToClassNames({
|
|
|
383
386
|
.trim()
|
|
384
387
|
|
|
385
388
|
const result = generate(
|
|
386
|
-
ast,
|
|
389
|
+
ast as any,
|
|
387
390
|
{
|
|
388
391
|
concise: false,
|
|
389
392
|
filename: sourcePath,
|
|
@@ -70,7 +70,7 @@ export function getPropValueFromAttributes(
|
|
|
70
70
|
return false
|
|
71
71
|
}
|
|
72
72
|
throw new Error(
|
|
73
|
-
`unsupported spread of type "${attr.argument.type}": ${generate(attr).code}`
|
|
73
|
+
`unsupported spread of type "${attr.argument.type}": ${generate(attr as any).code}`
|
|
74
74
|
)
|
|
75
75
|
}
|
|
76
76
|
return false
|