@tamagui/static 1.0.1-beta.99 → 1.0.1-rc.0

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.
Files changed (269) hide show
  1. package/dist/{cjs/constants.js → constants.js} +9 -4
  2. package/dist/constants.js.map +7 -0
  3. package/dist/{cjs/extractor → extractor}/accessSafe.js +14 -2
  4. package/dist/{esm/extractor → extractor}/accessSafe.js.map +2 -2
  5. package/dist/{cjs/extractor → extractor}/babelParse.js +5 -1
  6. package/dist/extractor/babelParse.js.map +7 -0
  7. package/dist/{cjs/extractor → extractor}/buildClassName.js +40 -9
  8. package/dist/extractor/buildClassName.js.map +7 -0
  9. package/dist/extractor/bundle.js +117 -0
  10. package/dist/extractor/bundle.js.map +7 -0
  11. package/dist/{cjs/extractor → extractor}/createEvaluator.js +11 -8
  12. package/dist/extractor/createEvaluator.js.map +7 -0
  13. package/dist/extractor/createExtractor.js +1623 -0
  14. package/dist/extractor/createExtractor.js.map +7 -0
  15. package/dist/{cjs/extractor → extractor}/ensureImportingConcat.js +18 -6
  16. package/dist/extractor/ensureImportingConcat.js.map +7 -0
  17. package/dist/{cjs/extractor → extractor}/evaluateAstNode.js +14 -4
  18. package/dist/extractor/evaluateAstNode.js.map +7 -0
  19. package/dist/{cjs/extractor → extractor}/extractHelpers.js +83 -12
  20. package/dist/extractor/extractHelpers.js.map +7 -0
  21. package/dist/{cjs/extractor → extractor}/extractMediaStyle.js +46 -42
  22. package/dist/extractor/extractMediaStyle.js.map +7 -0
  23. package/dist/{cjs/extractor → extractor}/extractToClassNames.js +144 -73
  24. package/dist/extractor/extractToClassNames.js.map +7 -0
  25. package/dist/{cjs/extractor → extractor}/findTopmostFunction.js +1 -0
  26. package/dist/{cjs/extractor → extractor}/findTopmostFunction.js.map +2 -2
  27. package/dist/{cjs/extractor → extractor}/generatedUid.js +9 -2
  28. package/dist/{cjs/extractor → extractor}/generatedUid.js.map +3 -3
  29. package/dist/{cjs/extractor → extractor}/getPrefixLogs.js +1 -0
  30. package/dist/extractor/getPrefixLogs.js.map +7 -0
  31. package/dist/{cjs/extractor → extractor}/getPropValueFromAttributes.js +24 -13
  32. package/dist/extractor/getPropValueFromAttributes.js.map +7 -0
  33. package/dist/{cjs/extractor → extractor}/getSourceModule.js +5 -1
  34. package/dist/{esm/extractor → extractor}/getSourceModule.js.map +3 -3
  35. package/dist/{cjs/extractor → extractor}/getStaticBindingsForScope.js +89 -35
  36. package/dist/extractor/getStaticBindingsForScope.js.map +7 -0
  37. package/dist/{cjs/extractor → extractor}/hoistClassNames.js +5 -1
  38. package/dist/{jsx/extractor → extractor}/hoistClassNames.js.map +3 -3
  39. package/dist/{cjs/extractor → extractor}/literalToAst.js +26 -30
  40. package/dist/{jsx/extractor → extractor}/literalToAst.js.map +2 -2
  41. package/dist/extractor/loadFile.js +21 -0
  42. package/dist/extractor/loadFile.js.map +7 -0
  43. package/dist/extractor/loadTamagui.js +427 -0
  44. package/dist/extractor/loadTamagui.js.map +7 -0
  45. package/dist/{cjs/extractor → extractor}/logLines.js +2 -1
  46. package/dist/extractor/logLines.js.map +7 -0
  47. package/dist/{cjs/extractor → extractor}/normalizeTernaries.js +13 -34
  48. package/dist/extractor/normalizeTernaries.js.map +7 -0
  49. package/dist/{cjs/extractor → extractor}/removeUnusedHooks.js +5 -1
  50. package/dist/extractor/removeUnusedHooks.js.map +7 -0
  51. package/dist/{cjs/extractor → extractor}/timer.js +9 -1
  52. package/dist/extractor/timer.js.map +7 -0
  53. package/dist/{cjs/extractor → extractor}/validHTMLAttributes.js +1 -0
  54. package/dist/{jsx/extractor → extractor}/validHTMLAttributes.js.map +2 -2
  55. package/dist/getPragmaOptions.js +68 -0
  56. package/dist/getPragmaOptions.js.map +7 -0
  57. package/dist/helpers/memoize.js +46 -0
  58. package/dist/helpers/memoize.js.map +7 -0
  59. package/dist/{cjs/index.js → index.js} +10 -8
  60. package/dist/index.js.map +7 -0
  61. package/dist/require.js +86 -0
  62. package/dist/require.js.map +7 -0
  63. package/dist/{cjs/types.js → types.js} +1 -0
  64. package/dist/types.js.map +7 -0
  65. package/dist/webpackPlugin.js +35 -0
  66. package/dist/webpackPlugin.js.map +7 -0
  67. package/package.json +40 -36
  68. package/src/constants.ts +2 -1
  69. package/src/extractor/babelParse.ts +3 -2
  70. package/src/extractor/buildClassName.ts +21 -5
  71. package/src/extractor/bundle.ts +110 -0
  72. package/src/extractor/createEvaluator.ts +10 -12
  73. package/src/extractor/createExtractor.ts +1702 -1523
  74. package/src/extractor/ensureImportingConcat.ts +4 -11
  75. package/src/extractor/evaluateAstNode.ts +1 -1
  76. package/src/extractor/extractHelpers.ts +93 -10
  77. package/src/extractor/extractMediaStyle.ts +18 -11
  78. package/src/extractor/extractToClassNames.ts +104 -47
  79. package/src/extractor/getPrefixLogs.ts +1 -1
  80. package/src/extractor/getPropValueFromAttributes.ts +4 -3
  81. package/src/extractor/getSourceModule.ts +2 -0
  82. package/src/extractor/getStaticBindingsForScope.ts +90 -46
  83. package/src/extractor/loadFile.ts +17 -0
  84. package/src/extractor/loadTamagui.ts +448 -103
  85. package/src/extractor/logLines.ts +1 -1
  86. package/src/extractor/normalizeTernaries.ts +2 -2
  87. package/src/extractor/removeUnusedHooks.ts +2 -0
  88. package/src/extractor/timer.ts +12 -1
  89. package/src/getPragmaOptions.ts +53 -0
  90. package/src/helpers/memoize.ts +21 -0
  91. package/src/index.ts +9 -8
  92. package/src/require.ts +103 -0
  93. package/src/types.ts +33 -31
  94. package/src/webpackPlugin.ts +9 -0
  95. package/tamagui.tsconfig.json +5 -0
  96. package/types/constants.d.ts +6 -0
  97. package/types/extractor/accessSafe.d.ts +3 -0
  98. package/types/extractor/babelParse.d.ts +6 -0
  99. package/types/extractor/buildClassName.d.ts +5 -2
  100. package/types/extractor/bundle.d.ts +13 -0
  101. package/types/extractor/createEvaluator.d.ts +3 -3
  102. package/types/extractor/createExtractor.d.ts +25 -9
  103. package/types/extractor/ensureImportingConcat.d.ts +4 -0
  104. package/types/extractor/evaluateAstNode.d.ts +3 -0
  105. package/types/extractor/extractHelpers.d.ts +15 -3
  106. package/types/extractor/extractMediaStyle.d.ts +3 -3
  107. package/types/extractor/extractToClassNames.d.ts +5 -4
  108. package/types/extractor/findTopmostFunction.d.ts +4 -0
  109. package/types/extractor/generatedUid.d.ts +5 -0
  110. package/types/extractor/getPrefixLogs.d.ts +1 -1
  111. package/types/extractor/getPropValueFromAttributes.d.ts +19 -0
  112. package/types/extractor/getSourceModule.d.ts +16 -0
  113. package/types/extractor/getStaticBindingsForScope.d.ts +5 -0
  114. package/types/extractor/hoistClassNames.d.ts +6 -0
  115. package/types/extractor/literalToAst.d.ts +4 -0
  116. package/types/extractor/loadFile.d.ts +1 -0
  117. package/types/extractor/loadTamagui.d.ts +15 -5
  118. package/types/extractor/logLines.d.ts +2 -0
  119. package/types/extractor/normalizeTernaries.d.ts +1 -1
  120. package/types/extractor/removeUnusedHooks.d.ts +3 -0
  121. package/types/extractor/timer.d.ts +5 -0
  122. package/types/extractor/validHTMLAttributes.d.ts +98 -0
  123. package/types/getPragmaOptions.d.ts +9 -0
  124. package/types/helpers/memoize.d.ts +8 -0
  125. package/types/index.d.ts +9 -8
  126. package/types/require.d.ts +4 -0
  127. package/types/types.d.ts +28 -27
  128. package/types/webpackPlugin.d.ts +4 -0
  129. package/dist/cjs/constants.js.map +0 -7
  130. package/dist/cjs/extractor/accessSafe.js.map +0 -7
  131. package/dist/cjs/extractor/babelParse.js.map +0 -7
  132. package/dist/cjs/extractor/buildClassName.js.map +0 -7
  133. package/dist/cjs/extractor/createEvaluator.js.map +0 -7
  134. package/dist/cjs/extractor/createExtractor.js +0 -1394
  135. package/dist/cjs/extractor/createExtractor.js.map +0 -7
  136. package/dist/cjs/extractor/ensureImportingConcat.js.map +0 -7
  137. package/dist/cjs/extractor/evaluateAstNode.js.map +0 -7
  138. package/dist/cjs/extractor/extractHelpers.js.map +0 -7
  139. package/dist/cjs/extractor/extractMediaStyle.js.map +0 -7
  140. package/dist/cjs/extractor/extractToClassNames.js.map +0 -7
  141. package/dist/cjs/extractor/getPrefixLogs.js.map +0 -7
  142. package/dist/cjs/extractor/getPropValueFromAttributes.js.map +0 -7
  143. package/dist/cjs/extractor/getSourceModule.js.map +0 -7
  144. package/dist/cjs/extractor/getStaticBindingsForScope.js.map +0 -7
  145. package/dist/cjs/extractor/hoistClassNames.js.map +0 -7
  146. package/dist/cjs/extractor/literalToAst.js.map +0 -7
  147. package/dist/cjs/extractor/loadTamagui.js +0 -139
  148. package/dist/cjs/extractor/loadTamagui.js.map +0 -7
  149. package/dist/cjs/extractor/logLines.js.map +0 -7
  150. package/dist/cjs/extractor/normalizeTernaries.js.map +0 -7
  151. package/dist/cjs/extractor/removeUnusedHooks.js.map +0 -7
  152. package/dist/cjs/extractor/timer.js.map +0 -7
  153. package/dist/cjs/extractor/validHTMLAttributes.js.map +0 -7
  154. package/dist/cjs/index.js.map +0 -7
  155. package/dist/cjs/types.js.map +0 -7
  156. package/dist/esm/constants.js +0 -14
  157. package/dist/esm/constants.js.map +0 -7
  158. package/dist/esm/extractor/accessSafe.js +0 -8
  159. package/dist/esm/extractor/babelParse.js +0 -28
  160. package/dist/esm/extractor/babelParse.js.map +0 -7
  161. package/dist/esm/extractor/buildClassName.js +0 -37
  162. package/dist/esm/extractor/buildClassName.js.map +0 -7
  163. package/dist/esm/extractor/createEvaluator.js +0 -53
  164. package/dist/esm/extractor/createEvaluator.js.map +0 -7
  165. package/dist/esm/extractor/createExtractor.js +0 -1379
  166. package/dist/esm/extractor/createExtractor.js.map +0 -7
  167. package/dist/esm/extractor/ensureImportingConcat.js +0 -21
  168. package/dist/esm/extractor/ensureImportingConcat.js.map +0 -7
  169. package/dist/esm/extractor/evaluateAstNode.js +0 -91
  170. package/dist/esm/extractor/evaluateAstNode.js.map +0 -7
  171. package/dist/esm/extractor/extractHelpers.js +0 -97
  172. package/dist/esm/extractor/extractHelpers.js.map +0 -7
  173. package/dist/esm/extractor/extractMediaStyle.js +0 -161
  174. package/dist/esm/extractor/extractMediaStyle.js.map +0 -7
  175. package/dist/esm/extractor/extractToClassNames.js +0 -294
  176. package/dist/esm/extractor/extractToClassNames.js.map +0 -7
  177. package/dist/esm/extractor/findTopmostFunction.js +0 -20
  178. package/dist/esm/extractor/findTopmostFunction.js.map +0 -7
  179. package/dist/esm/extractor/generatedUid.js +0 -25
  180. package/dist/esm/extractor/generatedUid.js.map +0 -7
  181. package/dist/esm/extractor/getPrefixLogs.js +0 -8
  182. package/dist/esm/extractor/getPrefixLogs.js.map +0 -7
  183. package/dist/esm/extractor/getPropValueFromAttributes.js +0 -46
  184. package/dist/esm/extractor/getPropValueFromAttributes.js.map +0 -7
  185. package/dist/esm/extractor/getSourceModule.js +0 -66
  186. package/dist/esm/extractor/getStaticBindingsForScope.js +0 -132
  187. package/dist/esm/extractor/getStaticBindingsForScope.js.map +0 -7
  188. package/dist/esm/extractor/hoistClassNames.js +0 -40
  189. package/dist/esm/extractor/hoistClassNames.js.map +0 -7
  190. package/dist/esm/extractor/literalToAst.js +0 -90
  191. package/dist/esm/extractor/literalToAst.js.map +0 -7
  192. package/dist/esm/extractor/loadTamagui.js +0 -117
  193. package/dist/esm/extractor/loadTamagui.js.map +0 -7
  194. package/dist/esm/extractor/logLines.js +0 -20
  195. package/dist/esm/extractor/logLines.js.map +0 -7
  196. package/dist/esm/extractor/normalizeTernaries.js +0 -79
  197. package/dist/esm/extractor/normalizeTernaries.js.map +0 -7
  198. package/dist/esm/extractor/removeUnusedHooks.js +0 -76
  199. package/dist/esm/extractor/removeUnusedHooks.js.map +0 -7
  200. package/dist/esm/extractor/timer.js +0 -22
  201. package/dist/esm/extractor/timer.js.map +0 -7
  202. package/dist/esm/extractor/validHTMLAttributes.js +0 -102
  203. package/dist/esm/extractor/validHTMLAttributes.js.map +0 -7
  204. package/dist/esm/index.js +0 -15
  205. package/dist/esm/index.js.map +0 -7
  206. package/dist/esm/types.js +0 -1
  207. package/dist/esm/types.js.map +0 -7
  208. package/dist/jsx/constants.js +0 -14
  209. package/dist/jsx/constants.js.map +0 -7
  210. package/dist/jsx/extractor/accessSafe.js +0 -8
  211. package/dist/jsx/extractor/accessSafe.js.map +0 -7
  212. package/dist/jsx/extractor/babelParse.js +0 -28
  213. package/dist/jsx/extractor/babelParse.js.map +0 -7
  214. package/dist/jsx/extractor/buildClassName.js +0 -37
  215. package/dist/jsx/extractor/buildClassName.js.map +0 -7
  216. package/dist/jsx/extractor/createEvaluator.js +0 -53
  217. package/dist/jsx/extractor/createEvaluator.js.map +0 -7
  218. package/dist/jsx/extractor/createExtractor.js +0 -1343
  219. package/dist/jsx/extractor/createExtractor.js.map +0 -7
  220. package/dist/jsx/extractor/ensureImportingConcat.js +0 -21
  221. package/dist/jsx/extractor/ensureImportingConcat.js.map +0 -7
  222. package/dist/jsx/extractor/evaluateAstNode.js +0 -91
  223. package/dist/jsx/extractor/evaluateAstNode.js.map +0 -7
  224. package/dist/jsx/extractor/extractHelpers.js +0 -97
  225. package/dist/jsx/extractor/extractHelpers.js.map +0 -7
  226. package/dist/jsx/extractor/extractMediaStyle.js +0 -146
  227. package/dist/jsx/extractor/extractMediaStyle.js.map +0 -7
  228. package/dist/jsx/extractor/extractToClassNames.js +0 -280
  229. package/dist/jsx/extractor/extractToClassNames.js.map +0 -7
  230. package/dist/jsx/extractor/findTopmostFunction.js +0 -20
  231. package/dist/jsx/extractor/findTopmostFunction.js.map +0 -7
  232. package/dist/jsx/extractor/generatedUid.js +0 -25
  233. package/dist/jsx/extractor/generatedUid.js.map +0 -7
  234. package/dist/jsx/extractor/getPrefixLogs.js +0 -9
  235. package/dist/jsx/extractor/getPrefixLogs.js.map +0 -7
  236. package/dist/jsx/extractor/getPropValueFromAttributes.js +0 -46
  237. package/dist/jsx/extractor/getPropValueFromAttributes.js.map +0 -7
  238. package/dist/jsx/extractor/getSourceModule.js +0 -66
  239. package/dist/jsx/extractor/getSourceModule.js.map +0 -7
  240. package/dist/jsx/extractor/getStaticBindingsForScope.js +0 -132
  241. package/dist/jsx/extractor/getStaticBindingsForScope.js.map +0 -7
  242. package/dist/jsx/extractor/hoistClassNames.js +0 -40
  243. package/dist/jsx/extractor/literalToAst.js +0 -75
  244. package/dist/jsx/extractor/loadTamagui.js +0 -102
  245. package/dist/jsx/extractor/loadTamagui.js.map +0 -7
  246. package/dist/jsx/extractor/logLines.js +0 -20
  247. package/dist/jsx/extractor/logLines.js.map +0 -7
  248. package/dist/jsx/extractor/normalizeTernaries.js +0 -50
  249. package/dist/jsx/extractor/normalizeTernaries.js.map +0 -7
  250. package/dist/jsx/extractor/removeUnusedHooks.js +0 -77
  251. package/dist/jsx/extractor/removeUnusedHooks.js.map +0 -7
  252. package/dist/jsx/extractor/timer.js +0 -22
  253. package/dist/jsx/extractor/timer.js.map +0 -7
  254. package/dist/jsx/extractor/validHTMLAttributes.js +0 -102
  255. package/dist/jsx/index.js +0 -15
  256. package/dist/jsx/index.js.map +0 -7
  257. package/dist/jsx/types.js +0 -1
  258. package/dist/jsx/types.js.map +0 -7
  259. package/types/extractor/buildClassName.d.ts.map +0 -1
  260. package/types/extractor/createEvaluator.d.ts.map +0 -1
  261. package/types/extractor/createExtractor.d.ts.map +0 -1
  262. package/types/extractor/extractHelpers.d.ts.map +0 -1
  263. package/types/extractor/extractMediaStyle.d.ts.map +0 -1
  264. package/types/extractor/extractToClassNames.d.ts.map +0 -1
  265. package/types/extractor/getPrefixLogs.d.ts.map +0 -1
  266. package/types/extractor/loadTamagui.d.ts.map +0 -1
  267. package/types/extractor/normalizeTernaries.d.ts.map +0 -1
  268. package/types/index.d.ts.map +0 -1
  269. package/types/types.d.ts.map +0 -1
@@ -1,145 +1,490 @@
1
- import { join } from 'path'
1
+ import { readFileSync } from 'fs'
2
+ /* eslint-disable no-console */
3
+ import { basename, dirname, extname, join, relative, sep } from 'path'
2
4
 
3
- import type { StaticConfig, TamaguiComponent, TamaguiInternalConfig } from '@tamagui/core'
5
+ import generate from '@babel/generator'
6
+ import traverse from '@babel/traverse'
7
+ import * as t from '@babel/types'
8
+ import { Color, colorLog } from '@tamagui/cli-color'
9
+ import { getDefaultTamaguiConfig } from '@tamagui/config-default-node'
10
+ import type { StaticConfigParsed, TamaguiInternalConfig } from '@tamagui/core-node'
4
11
  import { createTamagui } from '@tamagui/core-node'
12
+ import esbuild from 'esbuild'
13
+ import { ensureDir, existsSync, removeSync, writeFileSync } from 'fs-extra'
5
14
 
6
- let loadedTamagui: any = null
15
+ import { SHOULD_DEBUG } from '../constants.js'
16
+ import { getNameToPaths, registerRequire, unregisterRequire } from '../require.js'
17
+ import { babelParse } from './babelParse'
18
+ import { bundle } from './bundle'
7
19
 
8
20
  type NameToPaths = {
9
21
  [key: string]: Set<string>
10
22
  }
11
23
 
24
+ export type LoadedComponents = {
25
+ moduleName: string
26
+ nameToInfo: Record<
27
+ string,
28
+ {
29
+ staticConfig: StaticConfigParsed
30
+ }
31
+ >
32
+ }
33
+
12
34
  export type TamaguiProjectInfo = {
13
- components: Record<string, TamaguiComponent>
35
+ components: LoadedComponents[]
14
36
  tamaguiConfig: TamaguiInternalConfig
15
37
  nameToPaths: NameToPaths
16
38
  }
17
39
 
18
- export function loadTamagui(props: { components: string[]; config: string }): TamaguiProjectInfo {
19
- if (loadedTamagui) {
20
- return loadedTamagui
21
- }
40
+ type Props = {
41
+ components: string[]
42
+ config?: string
43
+ forceExports?: boolean
44
+ }
45
+
46
+ const cache = {}
22
47
 
23
- const configPath = join(process.cwd(), props.config)
48
+ // TODO needs a plugin for webpack / vite to run this once at startup and not again until changed...
24
49
 
25
- const { unregister } = require('esbuild-register/dist/node').register({
26
- target: 'es2019',
27
- format: 'cjs',
50
+ export async function loadTamagui(props: Props): Promise<TamaguiProjectInfo> {
51
+ const key = JSON.stringify(props)
52
+ if (cache[key]) {
53
+ if (cache[key] instanceof Promise) {
54
+ return await cache[key]
55
+ }
56
+ return cache[key]
57
+ }
58
+
59
+ let resolver: Function = () => {}
60
+ cache[key] = new Promise((res) => {
61
+ resolver = res
28
62
  })
29
63
 
64
+ const tmpDir = join(process.cwd(), '.tamagui')
65
+ const configOutPath = join(tmpDir, `tamagui.config.js`)
66
+ const baseComponents = props.components.filter((x) => x !== '@tamagui/core')
67
+ const componentOutPaths = baseComponents.map((componentModule) =>
68
+ join(
69
+ tmpDir,
70
+ `${componentModule
71
+ .split(sep)
72
+ .join('-')
73
+ .replace(/[^a-z0-9]+/gi, '')}-components.config.js`
74
+ )
75
+ )
76
+
77
+ const external = ['@tamagui/core', '@tamagui/core-node', 'react', 'react-dom', 'react-native-svg']
78
+ const configEntry = props.config ? join(process.cwd(), props.config) : ''
79
+
80
+ if (process.env.NODE_ENV === 'development' && process.env.DEBUG?.startsWith('tamagui')) {
81
+ console.log(`Building config entry`, configEntry)
82
+ }
83
+
84
+ // build them to node-compat versions
85
+ try {
86
+ await ensureDir(tmpDir)
87
+ } catch {
88
+ //
89
+ }
90
+
91
+ colorLog(
92
+ Color.FgYellow,
93
+ `
94
+ Tamagui built config and components:`
95
+ )
96
+ colorLog(
97
+ Color.Dim,
98
+ `
99
+ Config .${sep}${relative(process.cwd(), configOutPath)}
100
+ Components ${componentOutPaths
101
+ .map((p) => `.${sep}${relative(process.cwd(), p)}`)
102
+ .join('\n ')}
103
+ `
104
+ )
105
+
106
+ await Promise.all([
107
+ props.config
108
+ ? bundle({
109
+ entryPoints: [configEntry],
110
+ external,
111
+ outfile: configOutPath,
112
+ })
113
+ : null,
114
+ ...baseComponents.map((componentModule, i) => {
115
+ return bundle({
116
+ entryPoints: [componentModule],
117
+ resolvePlatformSpecificEntries: true,
118
+ external,
119
+ outfile: componentOutPaths[i],
120
+ })
121
+ }),
122
+ ])
123
+
30
124
  try {
125
+ registerRequire()
126
+ const out = require(configOutPath)
127
+ const config = out.default || out
128
+
129
+ if (!config) {
130
+ throw new Error(`No config: ${config}`)
131
+ }
132
+
133
+ let components = loadComponents({
134
+ ...props,
135
+ components: componentOutPaths,
136
+ })
137
+
138
+ if (!components) {
139
+ throw new Error(`No components found: ${componentOutPaths.join(', ')}`)
140
+ }
141
+
142
+ // map from built back to original module names
143
+ for (const component of components) {
144
+ component.moduleName = baseComponents[componentOutPaths.indexOf(component.moduleName)]
145
+ if (!component.moduleName) {
146
+ throw new Error(`Tamagui internal err`)
147
+ }
148
+ }
149
+
150
+ // always load core so we can optimize if directly importing
151
+ const coreComponents = loadComponents({
152
+ ...props,
153
+ components: ['@tamagui/core-node'],
154
+ })
155
+ if (coreComponents) {
156
+ coreComponents[0].moduleName = '@tamagui/core'
157
+ components = [...components, ...coreComponents]
158
+ }
159
+
160
+ if (process.env.NODE_ENV === 'development' && process.env.DEBUG?.startsWith('tamagui')) {
161
+ console.log('Loaded components', components)
162
+ }
163
+
164
+ cache[key] = {
165
+ components,
166
+ nameToPaths: {},
167
+ tamaguiConfig: config,
168
+ }
169
+
170
+ // init core-node
171
+ createTamagui(cache[key].tamaguiConfig)
172
+
173
+ resolver(cache[key])
174
+
175
+ return cache[key]
176
+ } finally {
177
+ unregisterRequire()
178
+ }
179
+ }
180
+
181
+ export function resolveWebOrNativeSpecificEntry(entry: string) {
182
+ const resolved = require.resolve(entry)
183
+ const ext = extname(resolved)
184
+ const fileName = basename(resolved).replace(ext, '')
185
+ const specificExt = process.env.TAMAGUI_TARGET === 'web' ? 'web' : 'native'
186
+ const specificFile = join(dirname(resolved), fileName + '.' + specificExt + ext)
187
+ if (existsSync(specificFile)) {
188
+ return specificFile
189
+ }
190
+ return entry
191
+ }
192
+
193
+ const esbuildOptions = {
194
+ loader: 'tsx',
195
+ target: 'es2018',
196
+ format: 'cjs',
197
+ jsx: 'transform',
198
+ platform: 'node',
199
+ } as const
200
+
201
+ // loads in-process using esbuild-register
202
+ export function loadTamaguiSync(props: Props): TamaguiProjectInfo {
203
+ const key = JSON.stringify(props)
204
+ if (cache[key]) {
205
+ return cache[key]
206
+ }
207
+
208
+ const { unregister } = require('esbuild-register/dist/node').register(esbuildOptions)
209
+
210
+ try {
211
+ registerRequire()
212
+
31
213
  // lets shim require and avoid importing react-native + react-native-web
32
214
  // we just need to read the config around them
33
215
  process.env.IS_STATIC = 'is_static'
34
- // @ts-ignore
35
- if (typeof globalThis['__DEV__'] === 'undefined') {
36
- // @ts-ignore
37
- globalThis['__DEV__'] = process.env.NODE_ENV === 'development'
38
- }
216
+ const devValueOG = globalThis['__DEV__' as any]
217
+ globalThis['__DEV__' as any] = process.env.NODE_ENV === 'development'
39
218
 
40
- const proxyWorm = require('@tamagui/proxy-worm')
41
- const rnw = require('react-native-web')
42
- const Mod = require('module')
43
- const og = Mod.prototype.require
44
- const nameToPaths: NameToPaths = {}
219
+ try {
220
+ // config
221
+ let tamaguiConfig: TamaguiInternalConfig | null = null
222
+ if (props.config) {
223
+ const configPath = join(process.cwd(), props.config)
224
+ const exp = require(configPath)
225
+ tamaguiConfig = (exp['default'] || exp) as TamaguiInternalConfig
226
+ if (!tamaguiConfig || !tamaguiConfig.parsed) {
227
+ const confPath = require.resolve(configPath)
228
+ throw new Error(`Can't find valid config in ${confPath}:
229
+
230
+ Be sure you "export default" the config.`)
231
+ }
232
+ }
45
233
 
46
- Mod.prototype.require = function (path: string) {
47
- if (path.endsWith('.css')) {
48
- return {}
234
+ // components
235
+ const components = loadComponents(props)
236
+ if (!components) {
237
+ throw new Error(`No components loaded`)
49
238
  }
50
- if (
51
- path === '@gorhom/bottom-sheet' ||
52
- path.startsWith('react-native-reanimated') ||
53
- path === 'expo-linear-gradient'
54
- ) {
55
- return proxyWorm
239
+ if (process.env.DEBUG === 'tamagui') {
240
+ console.log(`components`, components)
56
241
  }
57
- if (
58
- path.startsWith('react-native') &&
59
- // allow our rnw.tsx imports through
60
- !path.startsWith('react-native-web/dist/cjs/exports')
61
- ) {
62
- return rnw
242
+
243
+ // undo shims
244
+ process.env.IS_STATIC = undefined
245
+ globalThis['__DEV__' as any] = devValueOG
246
+
247
+ // set up core-node
248
+ if (props.config && tamaguiConfig) {
249
+ createTamagui(tamaguiConfig as any)
63
250
  }
64
- try {
65
- const out = og.apply(this, arguments)
66
- if (!nameToPaths[path]) {
67
- if (out && typeof out === 'object') {
68
- for (const key in out) {
69
- try {
70
- const conf = out[key]?.staticConfig as StaticConfig
71
- if (conf) {
72
- if (conf.componentName) {
73
- nameToPaths[conf.componentName] ??= new Set()
74
- const fullName = path.startsWith('.')
75
- ? join(`${this.path.replace(/dist(\/cjs)?/, 'src')}`, path)
76
- : path
77
- nameToPaths[conf.componentName].add(fullName)
78
- } else {
79
- // console.log('no name component', path)
80
- }
81
- }
82
- } catch {
83
- // ok
84
- }
85
- }
86
- }
251
+
252
+ cache[key] = {
253
+ components,
254
+ tamaguiConfig,
255
+ nameToPaths: getNameToPaths(),
256
+ }
257
+ } catch (err) {
258
+ if (err instanceof Error) {
259
+ console.warn(
260
+ `Error loading tamagui.config.ts (set DEBUG=tamagui to see full stack), running tamagui without custom config`
261
+ )
262
+ console.log(`\n\n ${err.message}\n\n`)
263
+ if (SHOULD_DEBUG) {
264
+ console.log(err.stack)
87
265
  }
88
- return out
89
- } catch (err: any) {
90
- console.error('Tamagui error loading file:\n', path, err.message, '\n', err.stack)
91
- // avoid infinite loops
92
- process.exit(1)
266
+ } else {
267
+ console.error(`Error loading tamagui.config.ts`, err)
268
+ }
269
+ return {
270
+ components: [],
271
+ tamaguiConfig: getDefaultTamaguiConfig(),
272
+ nameToPaths: {},
93
273
  }
94
274
  }
95
275
 
96
- // import config
97
- const exp = require(configPath)
98
- const tamaguiConfig = (exp['default'] || exp) as TamaguiInternalConfig
276
+ return cache[key]
277
+ } finally {
278
+ unregister()
279
+ unregisterRequire()
280
+ }
281
+ }
99
282
 
100
- if (!tamaguiConfig || !tamaguiConfig.parsed) {
101
- try {
102
- const confPath = require.resolve(configPath)
103
- console.log(`Received:`, tamaguiConfig)
104
- throw new Error(`Can't find valid config in ${confPath}`)
105
- } catch (err) {
106
- throw err
283
+ function interopDefaultExport(mod: any) {
284
+ return mod?.default ?? mod
285
+ }
286
+
287
+ const cacheComponents: Record<string, LoadedComponents[]> = {}
288
+
289
+ function transformAddExports(ast: t.File) {
290
+ const usedNames = new Set<string>()
291
+
292
+ // avoid clobbering
293
+ traverse(ast, {
294
+ ExportNamedDeclaration(nodePath) {
295
+ if (nodePath.node.specifiers) {
296
+ for (const spec of nodePath.node.specifiers) {
297
+ usedNames.add(t.isIdentifier(spec.exported) ? spec.exported.name : spec.exported.value)
298
+ }
107
299
  }
108
- }
300
+ },
301
+ })
109
302
 
110
- // import components
111
- const components = {}
112
- for (const moduleName of props.components) {
113
- const exported = require(moduleName)
114
- for (const Name in exported) {
115
- const val = exported[Name]
116
- const staticConfig = val?.staticConfig as StaticConfig | undefined
117
- if (staticConfig) {
118
- // remove non-stringifyable
119
- const { Component, reactNativeWebComponent, ...sc } = staticConfig
120
- Object.assign(components, { [Name]: { staticConfig: sc } })
303
+ traverse(ast, {
304
+ VariableDeclaration(nodePath) {
305
+ // top level only
306
+ if (!t.isProgram(nodePath.parent)) return
307
+ const decs = nodePath.node.declarations
308
+ if (decs.length > 1) return
309
+ const [dec] = decs
310
+ if (!t.isIdentifier(dec.id)) return
311
+ if (!dec.init) return
312
+ if (usedNames.has(dec.id.name)) return
313
+ usedNames.add(dec.id.name)
314
+ nodePath.replaceWith(
315
+ t.exportNamedDeclaration(t.variableDeclaration('let', [dec]), [
316
+ t.exportSpecifier(t.identifier(dec.id.name), t.identifier(dec.id.name)),
317
+ ])
318
+ )
319
+ },
320
+ })
321
+
322
+ return generate(ast as any, {
323
+ concise: false,
324
+ filename: 'test.tsx',
325
+ retainLines: false,
326
+ sourceMaps: false,
327
+ }).code
328
+ }
329
+
330
+ const esbuildit = (src: string, target?: 'modern') =>
331
+ esbuild.transformSync(src, {
332
+ ...esbuildOptions,
333
+ ...(target === 'modern' && {
334
+ target: 'es2022',
335
+ jsx: 'transform',
336
+ loader: 'tsx',
337
+ platform: 'neutral',
338
+ format: 'esm',
339
+ }),
340
+ }).code
341
+
342
+ function loadComponents(props: Props): null | LoadedComponents[] {
343
+ const componentsModules = props.components
344
+ const key = componentsModules.join('')
345
+ if (cacheComponents[key]) {
346
+ return cacheComponents[key]
347
+ }
348
+ try {
349
+ const info: LoadedComponents[] = componentsModules.flatMap((name) => {
350
+ const extension = extname(name)
351
+ const isLocal = Boolean(extension)
352
+ // during props.config pass we are passing in pre-bundled stuff
353
+ const isDynamic = isLocal && !props.config
354
+
355
+ if (isDynamic && !process.env.TAMAGUI_ENABLE_DYNAMIC_LOAD) {
356
+ return []
357
+ }
358
+
359
+ const fileContents = isDynamic ? readFileSync(name, 'utf-8') : ''
360
+ const loadModule = isDynamic
361
+ ? join(dirname(name), `.tamagui-dynamic-eval-${basename(name)}.tsx`)
362
+ : name
363
+ let writtenContents = fileContents
364
+ let didBabel = false
365
+
366
+ function attemptLoad({ forceExports = false } = {}) {
367
+ // need to write to tsx to enable reading it properly (:/ esbuild-register)
368
+ if (isDynamic) {
369
+ writtenContents = forceExports
370
+ ? esbuildit(transformAddExports(babelParse(esbuildit(fileContents, 'modern'))))
371
+ : esbuildit(fileContents)
372
+
373
+ writeFileSync(loadModule, writtenContents)
374
+ }
375
+
376
+ if (process.env.DEBUG === 'tamagui') {
377
+ console.log(`loadModule`, loadModule, require.resolve(loadModule))
378
+ }
379
+
380
+ return {
381
+ moduleName: name,
382
+ nameToInfo: getComponentStaticConfigByName(
383
+ name,
384
+ interopDefaultExport(require(loadModule))
385
+ ),
121
386
  }
122
387
  }
123
- }
124
388
 
125
- // undo shims
126
- process.env.IS_STATIC = undefined
127
- Mod.prototype.require = og
389
+ const dispose = () => {
390
+ isDynamic && removeSync(loadModule)
391
+ }
128
392
 
129
- // set up core-node
130
- createTamagui(tamaguiConfig as any)
393
+ try {
394
+ const res = attemptLoad({
395
+ forceExports: true,
396
+ })
397
+ didBabel = true
398
+ return res
399
+ } catch (err) {
400
+ console.log('babel err', err, writtenContents)
401
+ // ok
402
+ writtenContents = fileContents
403
+ if (process.env.DEBUG?.startsWith('tamagui')) {
404
+ console.log(`Error parsing babel likely`, err)
405
+ }
406
+ } finally {
407
+ dispose()
408
+ }
131
409
 
132
- loadedTamagui = {
133
- components,
134
- tamaguiConfig,
135
- nameToPaths,
136
- }
410
+ try {
411
+ return attemptLoad({
412
+ forceExports: false,
413
+ })
414
+ } catch (err) {
415
+ if (!process.env.TAMAGUI_DISABLE_WARN_DYNAMIC_LOAD) {
416
+ console.log(`
417
+
418
+ Tamagui attempted but failed to dynamically load components in:
419
+ ${name}
420
+
421
+ This will leave some styled() tags unoptimized.
422
+ Disable this file (or dynamic loading altogether):
423
+
424
+ disableExtractFoundComponents: ['${name}'] | true
137
425
 
138
- return loadedTamagui
426
+ Quiet this warning with environment variable:
427
+
428
+ TAMAGUI_DISABLE_WARN_DYNAMIC_LOAD=1
429
+
430
+ `)
431
+ console.log(err)
432
+ console.log(
433
+ `At: ${loadModule}`,
434
+ `\ndidBabel: ${didBabel}`,
435
+ `\nIn:`,
436
+ writtenContents,
437
+ `\nisDynamic: `,
438
+ isDynamic
439
+ )
440
+ }
441
+ return []
442
+ } finally {
443
+ dispose()
444
+ }
445
+ })
446
+ cacheComponents[key] = info
447
+ return info
448
+ } catch (err: any) {
449
+ console.log(`Tamagui error bundling components`, err.message, err.stack)
450
+ return null
451
+ }
452
+ }
453
+
454
+ function getComponentStaticConfigByName(name: string, exported: any) {
455
+ const components: Record<string, { staticConfig: StaticConfigParsed }> = {}
456
+ try {
457
+ if (!exported || typeof exported !== 'object' || Array.isArray(exported)) {
458
+ throw new Error(`Invalid export from package ${name}: ${typeof exported}`)
459
+ }
460
+ for (const key in exported) {
461
+ const found = getTamaguiComponent(key, exported[key])
462
+ if (found) {
463
+ // remove non-stringifyable
464
+ const { Component, ...sc } = found.staticConfig
465
+ components[key] = { staticConfig: sc }
466
+ }
467
+ }
139
468
  } catch (err) {
140
- console.log('Error loading Tamagui', err)
141
- throw err
142
- } finally {
143
- unregister()
469
+ if (process.env.TAMAGUI_DISABLE_WARN_DYNAMIC_LOAD !== '1') {
470
+ console.error(
471
+ `Tamagui failed getting from ${name} (Disable error by setting environment variable TAMAGUI_DISABLE_WARN_DYNAMIC_LOAD=1)`
472
+ )
473
+ console.error(err)
474
+ }
475
+ }
476
+ return components
477
+ }
478
+
479
+ function getTamaguiComponent(
480
+ name: string,
481
+ Component: any
482
+ ): undefined | { staticConfig: StaticConfigParsed } {
483
+ if (name[0].toUpperCase() !== name[0]) {
484
+ return
485
+ }
486
+ const staticConfig = Component?.staticConfig as StaticConfigParsed | undefined
487
+ if (staticConfig) {
488
+ return Component
144
489
  }
145
490
  }
@@ -4,7 +4,7 @@ export const logLines = (str: string, singleLine = false) => {
4
4
  if (singleLine) {
5
5
  return prefix + str.split(' ').join(`\n${prefix}`)
6
6
  }
7
- let lines: string[] = ['']
7
+ const lines: string[] = ['']
8
8
  const items = str.split(' ')
9
9
  for (const item of items) {
10
10
  if (item.length + lines[lines.length - 1].length > 85) {
@@ -2,7 +2,7 @@ import generate from '@babel/generator'
2
2
  import * as t from '@babel/types'
3
3
  import invariant from 'invariant'
4
4
 
5
- import { Ternary } from '../types'
5
+ import { Ternary } from '../types.js'
6
6
 
7
7
  export function normalizeTernaries(ternaries: Ternary[]) {
8
8
  invariant(
@@ -38,7 +38,7 @@ export function normalizeTernaries(ternaries: Ternary[]) {
38
38
  }
39
39
  }
40
40
 
41
- const key = generate(ternaryTest).code
41
+ const key = generate(ternaryTest as any).code
42
42
 
43
43
  if (!ternariesByKey[key]) {
44
44
  ternariesByKey[key] = {
@@ -11,6 +11,7 @@ export function removeUnusedHooks(compFn: NodePath<any>, shouldPrintDebug: boole
11
11
  // check the top level statements
12
12
  let bodyStatements = compFn?.get('body')
13
13
  if (!bodyStatements) {
14
+ // eslint-disable-next-line no-console
14
15
  console.log('no body statemnts?', compFn)
15
16
  return
16
17
  }
@@ -68,6 +69,7 @@ export function removeUnusedHooks(compFn: NodePath<any>, shouldPrintDebug: boole
68
69
  if (shouldRemove) {
69
70
  declarator.remove()
70
71
  if (shouldPrintDebug) {
72
+ // eslint-disable-next-line no-console
71
73
  console.log(` [🪝] removed ${id.node['name'] ?? ''}`)
72
74
  }
73
75
  }
@@ -6,12 +6,23 @@ export const timer = () => {
6
6
  if (print) {
7
7
  const took = Date.now() - last
8
8
  last = Date.now()
9
+ // eslint-disable-next-line no-console
9
10
  console.log(`Time ${name}: ${took}ms`)
11
+ if (took > 10) {
12
+ // eslint-disable-next-line no-console
13
+ console.log(' long timer')
14
+ }
10
15
  }
11
16
  },
12
17
  done: (print = false) => {
13
18
  if (print) {
14
- console.log(`Total time: ${Date.now() - start}ms`)
19
+ const total = Date.now() - start
20
+ // eslint-disable-next-line no-console
21
+ console.log(`Total time: ${total}ms`)
22
+ if (total > 50) {
23
+ // eslint-disable-next-line no-console
24
+ console.log(' long timer')
25
+ }
15
26
  }
16
27
  },
17
28
  }