@tamagui/static 1.15.33 → 1.15.35

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 (47) hide show
  1. package/dist/cjs/extractor/bundleConfig.js +129 -87
  2. package/dist/cjs/extractor/bundleConfig.js.map +1 -1
  3. package/dist/cjs/extractor/createExtractor.js +9 -17
  4. package/dist/cjs/extractor/createExtractor.js.map +1 -1
  5. package/dist/cjs/extractor/generateTamaguiStudioConfig.js +101 -0
  6. package/dist/cjs/extractor/generateTamaguiStudioConfig.js.map +6 -0
  7. package/dist/cjs/extractor/loadTamagui.js +65 -75
  8. package/dist/cjs/extractor/loadTamagui.js.map +1 -1
  9. package/dist/cjs/require.js +7 -10
  10. package/dist/cjs/require.js.map +1 -1
  11. package/dist/esm/extractor/bundleConfig.js +127 -87
  12. package/dist/esm/extractor/bundleConfig.js.map +1 -1
  13. package/dist/esm/extractor/bundleConfig.mjs +127 -87
  14. package/dist/esm/extractor/bundleConfig.mjs.map +1 -1
  15. package/dist/esm/extractor/createExtractor.js +9 -17
  16. package/dist/esm/extractor/createExtractor.js.map +1 -1
  17. package/dist/esm/extractor/createExtractor.mjs +9 -17
  18. package/dist/esm/extractor/createExtractor.mjs.map +1 -1
  19. package/dist/esm/extractor/generateTamaguiStudioConfig.js +66 -0
  20. package/dist/esm/extractor/generateTamaguiStudioConfig.js.map +6 -0
  21. package/dist/esm/extractor/generateTamaguiStudioConfig.mjs +66 -0
  22. package/dist/esm/extractor/generateTamaguiStudioConfig.mjs.map +6 -0
  23. package/dist/esm/extractor/loadTamagui.js +70 -76
  24. package/dist/esm/extractor/loadTamagui.js.map +1 -1
  25. package/dist/esm/extractor/loadTamagui.mjs +70 -76
  26. package/dist/esm/extractor/loadTamagui.mjs.map +1 -1
  27. package/dist/esm/require.js +6 -8
  28. package/dist/esm/require.js.map +1 -1
  29. package/dist/esm/require.mjs +6 -8
  30. package/dist/esm/require.mjs.map +1 -1
  31. package/package.json +14 -14
  32. package/src/extractor/bundleConfig.ts +160 -112
  33. package/src/extractor/createExtractor.ts +10 -18
  34. package/src/extractor/generateTamaguiStudioConfig.ts +99 -0
  35. package/src/extractor/loadTamagui.ts +85 -95
  36. package/src/require.ts +6 -8
  37. package/types/extractor/bundleConfig.d.ts +10 -7
  38. package/types/extractor/bundleConfig.d.ts.map +1 -1
  39. package/types/extractor/createExtractor.d.ts.map +1 -1
  40. package/types/extractor/generateTamaguiConfig.d.ts +2 -1
  41. package/types/extractor/generateTamaguiStudioConfig.d.ts +8 -0
  42. package/types/extractor/generateTamaguiStudioConfig.d.ts.map +1 -0
  43. package/types/extractor/loadTamagui.d.ts +18 -7
  44. package/types/extractor/loadTamagui.d.ts.map +1 -1
  45. package/types/require.d.ts +1 -2
  46. package/types/require.d.ts.map +1 -1
  47. package/src/extractor/generateTamaguiConfig.ts +0 -65
@@ -9,6 +9,8 @@ import type { StaticConfigParsed, TamaguiInternalConfig } from '@tamagui/web'
9
9
  import esbuild from 'esbuild'
10
10
  import { ensureDir, removeSync, writeFileSync } from 'fs-extra'
11
11
 
12
+ import { registerRequire } from '../require.js'
13
+ import { TamaguiOptions } from '../types.js'
12
14
  import { babelParse } from './babelParse.js'
13
15
  import { bundle } from './bundle.js'
14
16
 
@@ -34,12 +36,6 @@ export type TamaguiProjectInfo = {
34
36
  nameToPaths: NameToPaths
35
37
  }
36
38
 
37
- export type Props = {
38
- components: string[]
39
- config?: string
40
- forceExports?: boolean
41
- }
42
-
43
39
  const external = [
44
40
  '@tamagui/core',
45
41
  '@tamagui/web',
@@ -57,131 +53,176 @@ export const esbuildOptions = {
57
53
  platform: 'node',
58
54
  } as const
59
55
 
60
- export async function bundleConfig(props: Props) {
61
- const configEntry = props.config ? join(process.cwd(), props.config) : ''
62
- const tmpDir = join(process.cwd(), '.tamagui')
63
- const configOutPath = join(tmpDir, `tamagui.config.cjs`)
64
- const baseComponents = props.components.filter((x) => x !== '@tamagui/core')
65
- const componentOutPaths = baseComponents.map((componentModule) =>
66
- join(
67
- tmpDir,
68
- `${componentModule
69
- .split(sep)
70
- .join('-')
71
- .replace(/[^a-z0-9]+/gi, '')}-components.config.cjs`
72
- )
73
- )
56
+ export type BundledConfig = Awaited<ReturnType<typeof bundleConfig>>
74
57
 
75
- if (
76
- process.env.NODE_ENV === 'development' &&
77
- process.env.DEBUG?.startsWith('tamagui')
78
- ) {
79
- console.log(`Building config entry`, configEntry)
58
+ // will use cached one if watching
59
+ let currentConfig: BundledConfig
60
+ let isBundling = false
61
+ const waitForBundle = new Set<Function>()
62
+
63
+ let last: BundledConfig | undefined
64
+ export async function hasBundledConfigChanged() {
65
+ if (last === currentConfig) {
66
+ return false
80
67
  }
68
+ last = currentConfig
69
+ return true
70
+ }
81
71
 
82
- // build them to node-compat versions
83
- try {
84
- await ensureDir(tmpDir)
85
- } catch {
86
- //
72
+ export async function getBundledConfig(props: TamaguiOptions, rebuild = false) {
73
+ if (isBundling) {
74
+ await new Promise((res) => {
75
+ waitForBundle.add(res)
76
+ })
77
+ } else if (!currentConfig || rebuild) {
78
+ await bundleConfig(props)
87
79
  }
80
+ return currentConfig
81
+ }
88
82
 
89
- if (!loggedOutputInfo) {
90
- loggedOutputInfo = true
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 ${[
101
- ...componentOutPaths.map((p) => `.${sep}${relative(process.cwd(), p)}`),
102
- ].join('\n ')}
103
- `
83
+ export async function bundleConfig(props: TamaguiOptions) {
84
+ try {
85
+ isBundling = true
86
+
87
+ const configEntry = props.config ? join(process.cwd(), props.config) : ''
88
+ const tmpDir = join(process.cwd(), '.tamagui')
89
+
90
+ const configOutPath = join(tmpDir, `tamagui.config.cjs`)
91
+
92
+ const baseComponents = props.components.filter((x) => x !== '@tamagui/core')
93
+ const componentOutPaths = baseComponents.map((componentModule) =>
94
+ join(
95
+ tmpDir,
96
+ `${componentModule
97
+ .split(sep)
98
+ .join('-')
99
+ .replace(/[^a-z0-9]+/gi, '')}-components.config.cjs`
100
+ )
104
101
  )
105
- }
106
102
 
107
- await Promise.all([
108
- props.config
109
- ? bundle({
110
- entryPoints: [configEntry],
103
+ if (
104
+ process.env.NODE_ENV === 'development' &&
105
+ process.env.DEBUG?.startsWith('tamagui')
106
+ ) {
107
+ console.log(`Building config entry`, configEntry)
108
+ }
109
+
110
+ // build them to node-compat versions
111
+ try {
112
+ await ensureDir(tmpDir)
113
+ } catch {
114
+ //
115
+ }
116
+
117
+ const start = Date.now()
118
+
119
+ await Promise.all([
120
+ props.config
121
+ ? bundle({
122
+ entryPoints: [configEntry],
123
+ external,
124
+ outfile: configOutPath,
125
+ })
126
+ : null,
127
+ ...baseComponents.map((componentModule, i) => {
128
+ return bundle({
129
+ entryPoints: [componentModule],
130
+ resolvePlatformSpecificEntries: true,
111
131
  external,
112
- outfile: configOutPath,
132
+ outfile: componentOutPaths[i],
113
133
  })
114
- : null,
115
- ...baseComponents.map((componentModule, i) => {
116
- return bundle({
117
- entryPoints: [componentModule],
118
- resolvePlatformSpecificEntries: true,
119
- external,
120
- outfile: componentOutPaths[i],
121
- })
122
- }),
123
- ])
134
+ }),
135
+ ])
124
136
 
125
- // get around node.js's module cache to get the new config...
126
- delete require.cache[path.resolve(configOutPath)]
137
+ if (!loggedOutputInfo) {
138
+ loggedOutputInfo = true
139
+ colorLog(
140
+ Color.FgYellow,
141
+ `
142
+ Tamagui built config and components (${Date.now() - start}ms):`
143
+ )
144
+ colorLog(
145
+ Color.Dim,
146
+ `
147
+ Config .${sep}${relative(process.cwd(), configOutPath)}
148
+ Components ${[
149
+ ...componentOutPaths.map((p) => `.${sep}${relative(process.cwd(), p)}`),
150
+ ].join('\n ')}
151
+ `
152
+ )
153
+ }
127
154
 
128
- const out = require(configOutPath)
155
+ // get around node.js's module cache to get the new config...
156
+ delete require.cache[path.resolve(configOutPath)]
129
157
 
130
- const config = out.default || out
131
- if (!config) {
132
- throw new Error(`No config: ${config}`)
133
- }
158
+ const out = require(configOutPath)
134
159
 
135
- let components = loadComponents({
136
- ...props,
137
- components: componentOutPaths,
138
- })
160
+ const config = out.default || out
161
+ if (!config) {
162
+ throw new Error(`No config: ${config}`)
163
+ }
139
164
 
140
- if (!components) {
141
- throw new Error(`No components found: ${componentOutPaths.join(', ')}`)
142
- }
165
+ let components = loadComponents({
166
+ ...props,
167
+ components: componentOutPaths,
168
+ })
143
169
 
144
- // map from built back to original module names
145
- for (const component of components) {
146
- component.moduleName = baseComponents[componentOutPaths.indexOf(component.moduleName)]
170
+ if (!components) {
171
+ throw new Error(`No components found: ${componentOutPaths.join(', ')}`)
172
+ }
147
173
 
148
- if (!component.moduleName) {
149
- console.warn(
150
- `⚠️ no module name found: ${component.moduleName} ${JSON.stringify(
151
- baseComponents
152
- )} in ${JSON.stringify(componentOutPaths)}`
153
- )
174
+ // map from built back to original module names
175
+ for (const component of components) {
176
+ component.moduleName =
177
+ baseComponents[componentOutPaths.indexOf(component.moduleName)]
178
+
179
+ if (!component.moduleName) {
180
+ console.warn(
181
+ `⚠️ no module name found: ${component.moduleName} ${JSON.stringify(
182
+ baseComponents
183
+ )} in ${JSON.stringify(componentOutPaths)}`
184
+ )
185
+ }
186
+
187
+ // if (!component.moduleName) {
188
+ // throw new Error(`Tamagui internal err`)
189
+ // }
154
190
  }
155
191
 
156
- // if (!component.moduleName) {
157
- // throw new Error(`Tamagui internal err`)
158
- // }
159
- }
192
+ // always load core so we can optimize if directly importing
193
+ const coreComponents = loadComponents({
194
+ ...props,
195
+ components: ['@tamagui/core-node'],
196
+ })
197
+ if (coreComponents) {
198
+ coreComponents[0].moduleName = '@tamagui/core'
199
+ components = [...components, ...coreComponents]
200
+ }
160
201
 
161
- // always load core so we can optimize if directly importing
162
- const coreComponents = loadComponents({
163
- ...props,
164
- components: ['@tamagui/core-node'],
165
- })
166
- if (coreComponents) {
167
- coreComponents[0].moduleName = '@tamagui/core'
168
- components = [...components, ...coreComponents]
169
- }
202
+ if (
203
+ process.env.NODE_ENV === 'development' &&
204
+ process.env.DEBUG?.startsWith('tamagui')
205
+ ) {
206
+ console.log('Loaded components', components)
207
+ }
170
208
 
171
- if (
172
- process.env.NODE_ENV === 'development' &&
173
- process.env.DEBUG?.startsWith('tamagui')
174
- ) {
175
- console.log('Loaded components', components)
176
- }
177
- return {
178
- components,
179
- nameToPaths: {},
180
- tamaguiConfig: config,
209
+ const res = {
210
+ components,
211
+ nameToPaths: {},
212
+ tamaguiConfig: config,
213
+ }
214
+
215
+ currentConfig = res
216
+
217
+ return res
218
+ } finally {
219
+ isBundling = false
220
+ waitForBundle.forEach((cb) => cb())
221
+ waitForBundle.clear()
181
222
  }
182
223
  }
183
224
 
184
- export function loadComponents(props: Props): null | LoadedComponents[] {
225
+ export function loadComponents(props: TamaguiOptions): null | LoadedComponents[] {
185
226
  const componentsModules = props.components
186
227
  const key = componentsModules.join('')
187
228
  if (cacheComponents[key]) {
@@ -221,12 +262,19 @@ export function loadComponents(props: Props): null | LoadedComponents[] {
221
262
  console.log(`loadModule`, loadModule, require.resolve(loadModule))
222
263
  }
223
264
 
224
- return {
225
- moduleName: name,
226
- nameToInfo: getComponentStaticConfigByName(
265
+ const unregister = registerRequire()
266
+ try {
267
+ const nameToInfo = getComponentStaticConfigByName(
227
268
  name,
228
269
  interopDefaultExport(require(loadModule))
229
- ),
270
+ )
271
+
272
+ return {
273
+ moduleName: name,
274
+ nameToInfo,
275
+ }
276
+ } finally {
277
+ unregister()
230
278
  }
231
279
  }
232
280
 
@@ -105,17 +105,11 @@ export function createExtractor(
105
105
  // otherwise we'd import `rnw` and cause it to evaluate react-native-web which causes errors
106
106
 
107
107
  function loadSync(props: TamaguiOptions) {
108
- return (projectInfo ||= loadTamaguiSync({
109
- config: props.config || 'tamagui.config.ts',
110
- components: props.components || ['tamagui'],
111
- }))
108
+ return (projectInfo ||= loadTamaguiSync(props))
112
109
  }
113
110
 
114
111
  async function load(props: TamaguiOptions) {
115
- return (projectInfo ||= await loadTamagui({
116
- config: props.config || 'tamagui.config.ts',
117
- components: props.components || ['tamagui'],
118
- }))
112
+ return (projectInfo ||= await loadTamagui(props))
119
113
  }
120
114
 
121
115
  return {
@@ -196,8 +190,8 @@ export function createExtractor(
196
190
  return false
197
191
  }
198
192
  return !!(
199
- !!staticConfig.validStyles?.[name] ||
200
- !!pseudoDescriptors[name] ||
193
+ staticConfig.validStyles?.[name] ||
194
+ pseudoDescriptors[name] ||
201
195
  // dont disable variants or else you lose many things flattening
202
196
  staticConfig.variants?.[name] ||
203
197
  projectInfo?.tamaguiConfig.shorthands[name] ||
@@ -231,14 +225,12 @@ export function createExtractor(
231
225
  )
232
226
  }
233
227
  if (process.env.DEBUG?.startsWith('tamagui')) {
234
- const next = [...propsWithFileInfo.allLoadedComponents].map((info) => {
235
- const nameToInfo = { ...info.nameToInfo }
236
- for (const key in nameToInfo) {
237
- delete nameToInfo[key].staticConfig.validStyles
238
- }
239
- return { ...info, nameToInfo }
240
- })
241
- logger.info(['loaded:', JSON.stringify(next, null, 2)].join('\n'))
228
+ logger.info(
229
+ [
230
+ 'loaded:',
231
+ JSON.stringify(propsWithFileInfo.allLoadedComponents, null, 2),
232
+ ].join('\n')
233
+ )
242
234
  }
243
235
  }
244
236
 
@@ -0,0 +1,99 @@
1
+ import { join } from 'path'
2
+
3
+ import { getVariableValue } from '@tamagui/core-node'
4
+ import { TamaguiOptions } from '@tamagui/types'
5
+ import fs from 'fs-extra'
6
+
7
+ import { BundledConfig, getBundledConfig } from './bundleConfig.js'
8
+
9
+ const confFile = join(process.cwd(), '.tamagui', 'tamagui.config.json')
10
+
11
+ /**
12
+ * Sort of a super-set of bundleConfig(), this code needs some refactoring ideally
13
+ */
14
+
15
+ export async function generateTamaguiStudioConfig(
16
+ tamaguiOptions: TamaguiOptions,
17
+ configIn?: BundledConfig | null,
18
+ rebuild = false
19
+ ) {
20
+ const config = configIn ?? (await getBundledConfig(tamaguiOptions, rebuild))
21
+ await fs.writeJSON(
22
+ confFile,
23
+ {
24
+ ...config,
25
+ tamaguiConfig: transformConfig(config),
26
+ },
27
+ {
28
+ spaces: 2,
29
+ }
30
+ )
31
+ }
32
+
33
+ export function generateTamaguiStudioConfigSync(
34
+ _tamaguiOptions: TamaguiOptions,
35
+ config: BundledConfig
36
+ ) {
37
+ fs.writeJSONSync(
38
+ confFile,
39
+ {
40
+ ...config,
41
+ tamaguiConfig: transformConfig(config),
42
+ },
43
+ {
44
+ spaces: 2,
45
+ }
46
+ )
47
+ }
48
+
49
+ function transformConfig(config: BundledConfig) {
50
+ // ensure we don't mangle anything in the original
51
+ const next = JSON.parse(JSON.stringify(config))
52
+
53
+ const { components, nameToPaths } = next
54
+ const { themes, tokens } = next.tamaguiConfig
55
+
56
+ // reduce down to usable, smaller json
57
+
58
+ // slim themes, add name
59
+ for (const key in themes) {
60
+ const theme = themes[key]
61
+ // @ts-ignore
62
+ theme.id = key
63
+ for (const tkey in theme) {
64
+ theme[tkey] = getVariableValue(theme[tkey])
65
+ }
66
+ }
67
+
68
+ // flatten variables
69
+ for (const key in tokens) {
70
+ const token = { ...tokens[key] }
71
+ for (const tkey in token) {
72
+ token[tkey] = getVariableValue(token[tkey])
73
+ }
74
+ }
75
+
76
+ // remove bulky stuff in components
77
+ for (const component of components) {
78
+ for (const _ in component.nameToInfo) {
79
+ // avoid mutating
80
+ const compDefinition = { ...component.nameToInfo[_] }
81
+ component.nameToInfo[_] = compDefinition
82
+
83
+ const { parentStaticConfig, ...rest } = compDefinition.staticConfig
84
+ compDefinition.staticConfig = rest
85
+ }
86
+ }
87
+
88
+ // set to array
89
+ for (const key in nameToPaths) {
90
+ // @ts-ignore
91
+ nameToPaths[key] = [...nameToPaths[key]]
92
+ }
93
+
94
+ // remove stuff we dont need to send
95
+ const { fontsParsed, getCSS, tokensParsed, themeConfig, ...cleanedConfig } =
96
+ next.tamaguiConfig
97
+
98
+ return cleanedConfig
99
+ }