@tamagui/static 1.0.0-alpha.1 → 1.0.0-alpha.10
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/LICENSE +21 -0
- package/dist/extractor/createExtractor.js +80 -53
- package/dist/extractor/createExtractor.js.map +2 -2
- package/dist/extractor/extractHelpers.js +3 -1
- package/dist/extractor/extractHelpers.js.map +2 -2
- package/dist/extractor/extractToClassNames.js +11 -21
- package/dist/extractor/extractToClassNames.js.map +2 -2
- package/dist/extractor/logLines.js +17 -0
- package/dist/extractor/logLines.js.map +7 -0
- package/dist/index.cjs +127 -80
- package/dist/index.cjs.map +3 -3
- package/dist/patchReactNativeWeb.js +18 -3
- package/dist/patchReactNativeWeb.js.map +2 -2
- package/package.json +24 -22
- package/src/extractor/createExtractor.ts +101 -76
- package/src/extractor/extractHelpers.ts +12 -3
- package/src/extractor/extractToClassNames.ts +7 -21
- package/src/extractor/logLines.ts +11 -0
- package/src/patchReactNativeWeb.ts +21 -5
- package/src/types.ts +12 -3
- package/types.d.ts +219 -0
|
@@ -4,8 +4,24 @@ import * as fs from "fs";
|
|
|
4
4
|
import path from "path";
|
|
5
5
|
function patchReactNativeWeb() {
|
|
6
6
|
const rootDir = require.resolve("react-native-web").replace(/\/dist.*/, "");
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
const modulePath = path.join(rootDir, "dist", "tamagui-exports.js");
|
|
8
|
+
const cjsPath = path.join(rootDir, "dist", "cjs", "tamagui-exports.js");
|
|
9
|
+
const isEqual = (() => {
|
|
10
|
+
let res = false;
|
|
11
|
+
try {
|
|
12
|
+
res = fs.readFileSync(modulePath, "utf-8") === moduleExports && fs.readFileSync(cjsPath, "utf-8") == cjsExports;
|
|
13
|
+
} catch {
|
|
14
|
+
res = false;
|
|
15
|
+
}
|
|
16
|
+
return res;
|
|
17
|
+
})();
|
|
18
|
+
if (!isEqual) {
|
|
19
|
+
console.log("\u{1F95A} Tamagui patching react-native-web to share atomic styling primitives");
|
|
20
|
+
console.log(" > adding", modulePath);
|
|
21
|
+
console.log(" > adding", cjsPath);
|
|
22
|
+
fs.writeFileSync(modulePath, moduleExports);
|
|
23
|
+
fs.writeFileSync(cjsPath, cjsExports);
|
|
24
|
+
}
|
|
9
25
|
const moduleEntry = path.join(rootDir, "dist", "index.js");
|
|
10
26
|
const moduleEntrySrc = fs.readFileSync(moduleEntry, "utf-8");
|
|
11
27
|
if (!moduleEntrySrc.includes("// tamagui-patch-v4")) {
|
|
@@ -26,7 +42,6 @@ export const TamaguiExports = TExports
|
|
|
26
42
|
exports.TamaguiExports = _interopRequireDefault(require("./tamagui-exports"));
|
|
27
43
|
// tamagui-patch-end
|
|
28
44
|
`);
|
|
29
|
-
console.log(`Tamagui patched react-native-web`);
|
|
30
45
|
}
|
|
31
46
|
}
|
|
32
47
|
__name(patchReactNativeWeb, "patchReactNativeWeb");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/patchReactNativeWeb.ts"],
|
|
4
|
-
"sourcesContent": ["import * as fs from 'fs'\nimport path from 'path'\n\n// were patching react-native-web so we can use some internal methods\n// we do it this way because we need to rely on webpack or bundler config to determine cjs vs esm\n// so we can't just require it all directly\n// would be nice in the future to be able to eject from react-native-web entirely optionally\n\n// keep it sync\nexport function patchReactNativeWeb() {\n const rootDir = require.resolve('react-native-web').replace(/\\/dist.*/, '')\n
|
|
5
|
-
"mappings": ";;AAAA;AACA;AAQO,+BAA+B;AACpC,QAAM,UAAU,AAAgB,oCAAoB,QAAQ,YAAY;
|
|
4
|
+
"sourcesContent": ["import * as fs from 'fs'\nimport path from 'path'\n\n// were patching react-native-web so we can use some internal methods\n// we do it this way because we need to rely on webpack or bundler config to determine cjs vs esm\n// so we can't just require it all directly\n// would be nice in the future to be able to eject from react-native-web entirely optionally\n\n// keep it sync\nexport function patchReactNativeWeb() {\n const rootDir = require.resolve('react-native-web').replace(/\\/dist.*/, '')\n const modulePath = path.join(rootDir, 'dist', 'tamagui-exports.js')\n const cjsPath = path.join(rootDir, 'dist', 'cjs', 'tamagui-exports.js')\n\n const isEqual = (() => {\n let res = false\n try {\n res =\n fs.readFileSync(modulePath, 'utf-8') === moduleExports &&\n fs.readFileSync(cjsPath, 'utf-8') == cjsExports\n } catch {\n res = false\n }\n return res\n })()\n\n if (!isEqual) {\n console.log('\uD83E\uDD5A Tamagui patching react-native-web to share atomic styling primitives')\n console.log(' > adding', modulePath)\n console.log(' > adding', cjsPath)\n fs.writeFileSync(modulePath, moduleExports)\n fs.writeFileSync(cjsPath, cjsExports)\n }\n\n // if entry files not patched, patch them:\n const moduleEntry = path.join(rootDir, 'dist', 'index.js')\n const moduleEntrySrc = fs.readFileSync(moduleEntry, 'utf-8')\n if (!moduleEntrySrc.includes('// tamagui-patch-v4')) {\n fs.writeFileSync(\n moduleEntry,\n `${removePatch(moduleEntrySrc)}\n\n// tamagui-patch-v4\nimport * as TExports from './tamagui-exports'\nexport const TamaguiExports = TExports\n// tamagui-patch-end\n`\n )\n }\n const cjsEntry = path.join(rootDir, 'dist', 'cjs', 'index.js')\n const cjsEntrySrc = fs.readFileSync(cjsEntry, 'utf-8')\n if (!cjsEntrySrc.includes('// tamagui-patch-v4')) {\n fs.writeFileSync(\n cjsEntry,\n `${removePatch(cjsEntrySrc)}\n\n// tamagui-patch-v4\nexports.TamaguiExports = _interopRequireDefault(require(\"./tamagui-exports\"));\n// tamagui-patch-end\n`\n )\n }\n}\n\nfunction removePatch(source: string) {\n return source.replace(/\\/\\/ tamagui-patch([.\\s\\S]*)/g, '')\n}\n\n// view exports/View.ts\nconst forwardedPropsObj = `{\n ...fwdProps.defaultProps,\n ...fwdProps.accessibilityProps,\n ...fwdProps.clickProps,\n ...fwdProps.focusProps,\n ...fwdProps.keyboardProps,\n ...fwdProps.mouseProps,\n ...fwdProps.touchProps,\n ...fwdProps.styleProps,\n href: true,\n lang: true,\n onScroll: true,\n onWheel: true,\n pointerEvents: true\n}\n`\n\nconst moduleExports = `\nexport { atomic } from './exports/StyleSheet/compile'\nexport { default as createCompileableStyle } from './exports/StyleSheet/createCompileableStyle'\nexport { default as createReactDOMStyle } from './exports/StyleSheet/createReactDOMStyle'\nexport { default as i18Style } from './exports/StyleSheet/i18nStyle'\nexport { default as createDOMProps } from './modules/createDOMProps'\nexport { default as AccessibilityUtil } from './modules/AccessibilityUtil'\nexport { default as createElement } from './exports/createElement'\nexport { default as css } from './exports/StyleSheet/css'\nexport { default as TextAncestorContext } from './exports/Text/TextAncestorContext'\nexport { default as pick } from './modules/pick'\nexport { default as useElementLayout } from './modules/useElementLayout'\nexport { default as useMergeRefs } from './modules/useMergeRefs'\nexport { default as usePlatformMethods } from './modules/usePlatformMethods'\nexport { default as useResponderEvents } from './modules/useResponderEvents'\nimport * as fwdProps from './modules/forwardedProps'\nexport const forwardedProps = ${forwardedPropsObj}\n`\n\nconst cjsExports = `\nexports.atomic = require('./exports/StyleSheet/compile').atomic\nexports.createCompileableStyle = require('./exports/StyleSheet/createCompileableStyle')\nexports.createReactDOMStyle = require('./exports/StyleSheet/createReactDOMStyle')\nexports.i18Style = require('./exports/StyleSheet/i18nStyle')\nexports.createDOMProps = require('./modules/createDOMProps')\nexports.AccessibilityUtil = require('./modules/AccessibilityUtil')\nexports.createElement = require('./exports/createElement')\nexports.css = require('./exports/StyleSheet/css')\nexports.TextAncestorContext = require('./exports/Text/TextAncestorContext')\nexports.pick = require('./modules/pick')\nexports.useElementLayout = require('./modules/useElementLayout')\nexports.useMergeRefs = require('./modules/useMergeRefs')\nexports.usePlatformMethods = require('./modules/usePlatformMethods')\nexports.useResponderEvents = require('./modules/useResponderEvents')\nconst fwdProps = require('./modules/forwardedProps')\nexports.forwardedProps = ${forwardedPropsObj}\n`\n"],
|
|
5
|
+
"mappings": ";;AAAA;AACA;AAQO,+BAA+B;AACpC,QAAM,UAAU,AAAgB,oCAAoB,QAAQ,YAAY;AACxE,QAAM,aAAa,KAAK,KAAK,SAAS,QAAQ;AAC9C,QAAM,UAAU,KAAK,KAAK,SAAS,QAAQ,OAAO;AAElD,QAAM,UAAW,OAAM;AACrB,QAAI,MAAM;AACV,QAAI;AACF,YACE,GAAG,aAAa,YAAY,aAAa,iBACzC,GAAG,aAAa,SAAS,YAAY;AAAA,YACvC;AACA,YAAM;AAAA;AAER,WAAO;AAAA;AAGT,MAAI,CAAC,SAAS;AACZ,YAAQ,IAAI;AACZ,YAAQ,IAAI,eAAe;AAC3B,YAAQ,IAAI,eAAe;AAC3B,OAAG,cAAc,YAAY;AAC7B,OAAG,cAAc,SAAS;AAAA;AAI5B,QAAM,cAAc,KAAK,KAAK,SAAS,QAAQ;AAC/C,QAAM,iBAAiB,GAAG,aAAa,aAAa;AACpD,MAAI,CAAC,eAAe,SAAS,wBAAwB;AACnD,OAAG,cACD,aACA,GAAG,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASnB,QAAM,WAAW,KAAK,KAAK,SAAS,QAAQ,OAAO;AACnD,QAAM,cAAc,GAAG,aAAa,UAAU;AAC9C,MAAI,CAAC,YAAY,SAAS,wBAAwB;AAChD,OAAG,cACD,UACA,GAAG,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA7CL;AAuDhB,qBAAqB,QAAgB;AACnC,SAAO,OAAO,QAAQ,iCAAiC;AAAA;AADhD;AAKT,MAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiB1B,MAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gCAgBU;AAAA;AAGhC,MAAM,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,2BAgBQ;AAAA;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tamagui/static",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.10",
|
|
4
4
|
"source": "src/index.ts",
|
|
5
5
|
"main": "dist/index.cjs",
|
|
6
6
|
"module": "dist/index.js",
|
|
7
7
|
"typings": "types.d.ts",
|
|
8
8
|
"files": [
|
|
9
|
+
"types.d.ts",
|
|
9
10
|
"dist",
|
|
10
11
|
"src"
|
|
11
12
|
],
|
|
@@ -25,48 +26,49 @@
|
|
|
25
26
|
},
|
|
26
27
|
"license": "MIT",
|
|
27
28
|
"devDependencies": {
|
|
28
|
-
"@babel/core": "^7.15.5",
|
|
29
|
-
"@babel/generator": "^7.15.4",
|
|
30
|
-
"@babel/helper-plugin-utils": "^7.14.5",
|
|
31
|
-
"@babel/parser": "^7.15.7",
|
|
32
29
|
"@babel/plugin-syntax-typescript": "^7.14.5",
|
|
33
|
-
"@babel/traverse": "^7.15.4",
|
|
34
30
|
"@babel/types": "^7.15.6",
|
|
35
|
-
"@dish/babel-preset": "^0.0.6",
|
|
36
|
-
"@expo/match-media": "^0.1.0",
|
|
37
|
-
"@tamagui/build": "^1.0.0-alpha.1",
|
|
38
|
-
"@tamagui/core": "^1.0.0-alpha.1",
|
|
39
31
|
"@testing-library/react": "13.0.0-alpha.4",
|
|
40
32
|
"@types/jest": "*",
|
|
41
33
|
"@types/node": "^16.11.9",
|
|
42
34
|
"@types/react-native": "^0.64.2",
|
|
43
35
|
"@types/webpack": "^4.41.26",
|
|
44
|
-
"babel-literal-to-ast": "^2.1.0",
|
|
45
36
|
"babel-loader": "^8.2.2",
|
|
46
37
|
"css-loader": "^5.2.4",
|
|
47
|
-
"esbuild": "^
|
|
48
|
-
"find-cache-dir": "^3.3.1",
|
|
49
|
-
"fs-extra": "^9.0.0",
|
|
50
|
-
"invariant": "^2.2.4",
|
|
38
|
+
"esbuild-loader": "^2.16.0",
|
|
51
39
|
"jest": "^27.3.1",
|
|
52
40
|
"loader-utils": "^2.0.0",
|
|
53
|
-
"lodash": "^4.17.20",
|
|
54
41
|
"react": "*",
|
|
55
42
|
"react-dom": "*",
|
|
56
43
|
"react-test-renderer": "18.0.0-beta-149b420f6-20211119",
|
|
57
44
|
"style-loader": "^3.3.0",
|
|
58
|
-
"tamagui": "^1.0.0-alpha.1",
|
|
59
45
|
"typescript": "^4.4.4",
|
|
60
46
|
"webpack": "^5.58.1"
|
|
61
47
|
},
|
|
62
48
|
"dependencies": {
|
|
63
|
-
"@
|
|
64
|
-
"@
|
|
65
|
-
"@
|
|
66
|
-
"
|
|
49
|
+
"@babel/core": "^7.15.5",
|
|
50
|
+
"@babel/generator": "^7.15.4",
|
|
51
|
+
"@babel/helper-plugin-utils": "^7.14.5",
|
|
52
|
+
"@babel/parser": "^7.15.7",
|
|
53
|
+
"@babel/traverse": "^7.15.4",
|
|
54
|
+
"@dish/babel-preset": "^0.0.6",
|
|
55
|
+
"@expo/match-media": "^0.1.0",
|
|
56
|
+
"@tamagui/build": "^1.0.0-alpha.8",
|
|
57
|
+
"@tamagui/core": "^1.0.0-alpha.10",
|
|
58
|
+
"@tamagui/core-node": "^1.0.0-alpha.10",
|
|
59
|
+
"@tamagui/fake-react-native": "^1.0.0-alpha.2",
|
|
60
|
+
"@tamagui/helpers": "^1.0.0-alpha.8",
|
|
61
|
+
"babel-literal-to-ast": "^2.1.0",
|
|
62
|
+
"esbuild": "^0.13.12",
|
|
63
|
+
"esbuild-register": "^3.1.2",
|
|
64
|
+
"find-cache-dir": "^3.3.1",
|
|
65
|
+
"fs-extra": "^9.0.0",
|
|
66
|
+
"invariant": "^2.2.4",
|
|
67
|
+
"lodash": "^4.17.20",
|
|
68
|
+
"tamagui": "^1.0.0-alpha.10"
|
|
67
69
|
},
|
|
68
70
|
"peerDependencies": {
|
|
69
71
|
"react-native-web": "*"
|
|
70
72
|
},
|
|
71
|
-
"gitHead": "
|
|
73
|
+
"gitHead": "f72a2645a07a1ef9ee6719e464e1c28798cb52be"
|
|
72
74
|
}
|
|
@@ -13,6 +13,7 @@ import { findTopmostFunction } from './findTopmostFunction'
|
|
|
13
13
|
import { getStaticBindingsForScope } from './getStaticBindingsForScope'
|
|
14
14
|
import { literalToAst } from './literalToAst'
|
|
15
15
|
import { loadTamagui } from './loadTamagui'
|
|
16
|
+
import { logLines } from './logLines'
|
|
16
17
|
import { normalizeTernaries } from './normalizeTernaries'
|
|
17
18
|
import { removeUnusedHooks } from './removeUnusedHooks'
|
|
18
19
|
|
|
@@ -51,9 +52,10 @@ export function createExtractor() {
|
|
|
51
52
|
})
|
|
52
53
|
|
|
53
54
|
let loadedTamaguiConfig: TamaguiInternalConfig
|
|
55
|
+
let hasLogged = false
|
|
54
56
|
|
|
55
57
|
return {
|
|
56
|
-
|
|
58
|
+
getTamagui() {
|
|
57
59
|
return loadedTamaguiConfig
|
|
58
60
|
},
|
|
59
61
|
parse: (
|
|
@@ -66,7 +68,9 @@ export function createExtractor() {
|
|
|
66
68
|
sourcePath = '',
|
|
67
69
|
onExtractTag,
|
|
68
70
|
getFlattenedNode,
|
|
69
|
-
|
|
71
|
+
disableExtraction,
|
|
72
|
+
disableExtractInlineMedia,
|
|
73
|
+
disableDebugAttr,
|
|
70
74
|
...props
|
|
71
75
|
}: ExtractorParseProps
|
|
72
76
|
) => {
|
|
@@ -87,26 +91,25 @@ export function createExtractor() {
|
|
|
87
91
|
loadedTamaguiConfig = tamaguiConfig
|
|
88
92
|
|
|
89
93
|
const defaultTheme = tamaguiConfig.themes[Object.keys(tamaguiConfig.themes)[0]]
|
|
90
|
-
|
|
91
|
-
// TODO this can be passed in / set based on if source changed
|
|
92
|
-
// const shouldReCheckTheme = false //Date.now() - hasParsedFileLast > 600
|
|
93
|
-
// hasParsedFileLast = Date.now()
|
|
94
|
-
|
|
95
|
-
let doesUseValidImport = false
|
|
96
94
|
const body = fileOrPath.type === 'Program' ? fileOrPath.get('body') : fileOrPath.program.body
|
|
97
95
|
|
|
98
96
|
/**
|
|
99
97
|
* Step 1: Determine if importing any statically extractable components
|
|
100
98
|
*/
|
|
101
|
-
const isInternalImport = (importStr: string) =>
|
|
102
|
-
isInsideTamagui(sourcePath) && importStr[0] === '.'
|
|
99
|
+
const isInternalImport = (importStr: string) => {
|
|
100
|
+
return isInsideTamagui(sourcePath) && importStr[0] === '.'
|
|
101
|
+
}
|
|
102
|
+
|
|
103
103
|
const validComponents: { [key: string]: any } = Object.keys(components)
|
|
104
|
-
|
|
104
|
+
// check if uppercase to avoid hitting media query proxy before init
|
|
105
|
+
.filter((key) => key[0].toUpperCase() === key[0] && !!components[key]?.staticConfig)
|
|
105
106
|
.reduce((obj, name) => {
|
|
106
107
|
obj[name] = components[name]
|
|
107
108
|
return obj
|
|
108
109
|
}, {})
|
|
109
110
|
|
|
111
|
+
let doesUseValidImport = false
|
|
112
|
+
|
|
110
113
|
for (const bodyPath of body) {
|
|
111
114
|
if (bodyPath.type !== 'ImportDeclaration') continue
|
|
112
115
|
const node = ('node' in bodyPath ? bodyPath.node : bodyPath) as any
|
|
@@ -147,6 +150,12 @@ export function createExtractor() {
|
|
|
147
150
|
*/
|
|
148
151
|
let programPath: NodePath<t.Program>
|
|
149
152
|
|
|
153
|
+
const res = {
|
|
154
|
+
flattened: 0,
|
|
155
|
+
optimized: 0,
|
|
156
|
+
modified: 0,
|
|
157
|
+
}
|
|
158
|
+
|
|
150
159
|
callTraverse({
|
|
151
160
|
Program: {
|
|
152
161
|
enter(path) {
|
|
@@ -185,8 +194,41 @@ export function createExtractor() {
|
|
|
185
194
|
return
|
|
186
195
|
}
|
|
187
196
|
|
|
188
|
-
const { staticConfig } = component
|
|
189
197
|
const originalNodeName = node.name.name
|
|
198
|
+
|
|
199
|
+
if (shouldPrintDebug) {
|
|
200
|
+
console.log(`\n<${originalNodeName} />`)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const filePath = sourcePath.replace(process.cwd(), '.')
|
|
204
|
+
const lineNumbers = node.loc
|
|
205
|
+
? node.loc.start.line +
|
|
206
|
+
(node.loc.start.line !== node.loc.end.line ? `-${node.loc.end.line}` : '')
|
|
207
|
+
: ''
|
|
208
|
+
|
|
209
|
+
// add data-is
|
|
210
|
+
if (shouldAddDebugProp && !disableDebugAttr) {
|
|
211
|
+
const preName = componentName ? `${componentName}:` : ''
|
|
212
|
+
res.modified++
|
|
213
|
+
node.attributes.unshift(
|
|
214
|
+
t.jsxAttribute(
|
|
215
|
+
t.jsxIdentifier('data-is'),
|
|
216
|
+
t.stringLiteral(
|
|
217
|
+
` ${preName}${node.name.name} ${filePath.replace('./', '')}:${lineNumbers} `
|
|
218
|
+
)
|
|
219
|
+
)
|
|
220
|
+
)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (disableExtraction) {
|
|
224
|
+
if (!hasLogged) {
|
|
225
|
+
console.log('🥚 Tamagui disableExtraction set: no CSS or optimizations will be run')
|
|
226
|
+
hasLogged = true
|
|
227
|
+
}
|
|
228
|
+
return
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const { staticConfig } = component
|
|
190
232
|
const isTextView = staticConfig.isText || false
|
|
191
233
|
const validStyles = staticConfig?.validStyles ?? {}
|
|
192
234
|
|
|
@@ -223,10 +265,6 @@ export function createExtractor() {
|
|
|
223
265
|
return res
|
|
224
266
|
}
|
|
225
267
|
|
|
226
|
-
if (shouldPrintDebug) {
|
|
227
|
-
console.log(`\n<${originalNodeName} />`)
|
|
228
|
-
}
|
|
229
|
-
|
|
230
268
|
// Generate scope object at this level
|
|
231
269
|
const staticNamespace = getStaticBindingsForScope(
|
|
232
270
|
traversePath.scope,
|
|
@@ -399,9 +437,9 @@ export function createExtractor() {
|
|
|
399
437
|
}
|
|
400
438
|
const propName = prop.key['name']
|
|
401
439
|
if (!isStaticAttributeName(propName) && propName !== 'tag') {
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
440
|
+
if (shouldPrintDebug) {
|
|
441
|
+
console.log(' not a valid style prop!', propName)
|
|
442
|
+
}
|
|
405
443
|
return false
|
|
406
444
|
}
|
|
407
445
|
return true
|
|
@@ -489,7 +527,9 @@ export function createExtractor() {
|
|
|
489
527
|
const [test, alt, cons] = conditional
|
|
490
528
|
if (!test) throw new Error(`no test`)
|
|
491
529
|
if ([alt, cons].some((side) => side && !isExtractable(side))) {
|
|
492
|
-
|
|
530
|
+
if (shouldPrintDebug) {
|
|
531
|
+
console.log('not extractable', alt, cons)
|
|
532
|
+
}
|
|
493
533
|
return attr
|
|
494
534
|
}
|
|
495
535
|
// split into individual ternaries per object property
|
|
@@ -539,6 +579,11 @@ export function createExtractor() {
|
|
|
539
579
|
|
|
540
580
|
// shorthand media queries
|
|
541
581
|
if (name[0] === '$' && t.isJSXExpressionContainer(attribute?.value)) {
|
|
582
|
+
// allow disabling this extraction
|
|
583
|
+
if (disableExtractInlineMedia) {
|
|
584
|
+
return attr
|
|
585
|
+
}
|
|
586
|
+
|
|
542
587
|
const shortname = name.slice(1)
|
|
543
588
|
if (mediaQueryConfig[shortname]) {
|
|
544
589
|
const expression = attribute.value.expression
|
|
@@ -590,8 +635,8 @@ export function createExtractor() {
|
|
|
590
635
|
// if value can be evaluated, extract it and filter it out
|
|
591
636
|
const styleValue = attemptEvalSafe(value)
|
|
592
637
|
|
|
593
|
-
//
|
|
594
|
-
//
|
|
638
|
+
// never flatten if a prop isn't a valid static attribute
|
|
639
|
+
// only post prop-mapping
|
|
595
640
|
if (!isStaticAttributeName(name)) {
|
|
596
641
|
let keys = [name]
|
|
597
642
|
if (staticConfig.propMapper) {
|
|
@@ -621,6 +666,8 @@ export function createExtractor() {
|
|
|
621
666
|
return {
|
|
622
667
|
type: 'style',
|
|
623
668
|
value: { [name]: styleValue },
|
|
669
|
+
name,
|
|
670
|
+
attr: path.node,
|
|
624
671
|
}
|
|
625
672
|
}
|
|
626
673
|
|
|
@@ -752,7 +799,7 @@ export function createExtractor() {
|
|
|
752
799
|
|
|
753
800
|
// see if we can filter them
|
|
754
801
|
if (shouldPrintDebug) {
|
|
755
|
-
console.log(' - attrs (before)
|
|
802
|
+
console.log(' - attrs (before):\n', logLines(attrs.map(attrStr).join(', ')))
|
|
756
803
|
}
|
|
757
804
|
|
|
758
805
|
// now update to new values
|
|
@@ -772,12 +819,6 @@ export function createExtractor() {
|
|
|
772
819
|
modifiedComponents.add(parentFn)
|
|
773
820
|
}
|
|
774
821
|
|
|
775
|
-
const filePath = sourcePath.replace(process.cwd(), '.')
|
|
776
|
-
const lineNumbers = node.loc
|
|
777
|
-
? node.loc.start.line +
|
|
778
|
-
(node.loc.start.line !== node.loc.end.line ? `-${node.loc.end.line}` : '')
|
|
779
|
-
: ''
|
|
780
|
-
|
|
781
822
|
// combine ternaries
|
|
782
823
|
let ternaries: Ternary[] = []
|
|
783
824
|
attrs = attrs
|
|
@@ -867,29 +908,27 @@ export function createExtractor() {
|
|
|
867
908
|
if (cur.type === 'style') {
|
|
868
909
|
// TODO need to loop over initial props not just style props
|
|
869
910
|
for (const key in cur.value) {
|
|
870
|
-
const
|
|
871
|
-
!!(
|
|
872
|
-
staticConfig.ensureOverriddenProp?.[key] // || staticConfig.defaultProps?.[key]
|
|
873
|
-
)
|
|
911
|
+
const shouldEnsureOverridden = !!staticConfig.ensureOverriddenProp?.[key]
|
|
874
912
|
const isSetInAttrsAlready = attrs.some(
|
|
875
913
|
(x) =>
|
|
876
914
|
x.type === 'attr' &&
|
|
877
915
|
x.value.type === 'JSXAttribute' &&
|
|
878
916
|
x.value.name.name === key
|
|
879
917
|
)
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
918
|
+
|
|
919
|
+
if (!isSetInAttrsAlready) {
|
|
920
|
+
const isVariant = !!staticConfig.variants?.[cur.name || '']
|
|
921
|
+
if (isVariant || shouldEnsureOverridden) {
|
|
922
|
+
acc.push({
|
|
923
|
+
type: 'attr',
|
|
924
|
+
value:
|
|
925
|
+
cur.attr ||
|
|
926
|
+
t.jsxAttribute(
|
|
927
|
+
t.jsxIdentifier(key),
|
|
928
|
+
t.jsxExpressionContainer(t.nullLiteral())
|
|
929
|
+
),
|
|
930
|
+
})
|
|
931
|
+
}
|
|
893
932
|
}
|
|
894
933
|
}
|
|
895
934
|
}
|
|
@@ -899,7 +938,7 @@ export function createExtractor() {
|
|
|
899
938
|
}
|
|
900
939
|
|
|
901
940
|
if (shouldPrintDebug) {
|
|
902
|
-
console.log(' - attrs (flattened):
|
|
941
|
+
console.log(' - attrs (flattened): \n', logLines(attrs.map(attrStr).join(', ')))
|
|
903
942
|
}
|
|
904
943
|
|
|
905
944
|
// evaluate away purely style props
|
|
@@ -925,7 +964,7 @@ export function createExtractor() {
|
|
|
925
964
|
}, [])
|
|
926
965
|
|
|
927
966
|
if (shouldPrintDebug) {
|
|
928
|
-
console.log(' - attrs (evaluated styles):
|
|
967
|
+
console.log(' - attrs (evaluated styles): \n', logLines(attrs.map(attrStr).join(', ')))
|
|
929
968
|
}
|
|
930
969
|
|
|
931
970
|
// combine styles, leave undefined values
|
|
@@ -943,7 +982,7 @@ export function createExtractor() {
|
|
|
943
982
|
}, [])
|
|
944
983
|
|
|
945
984
|
if (shouldPrintDebug) {
|
|
946
|
-
console.log(' - attrs (combined 🔀):
|
|
985
|
+
console.log(' - attrs (combined 🔀): \n', logLines(attrs.map(attrStr).join(', ')))
|
|
947
986
|
}
|
|
948
987
|
|
|
949
988
|
// post process
|
|
@@ -958,9 +997,10 @@ export function createExtractor() {
|
|
|
958
997
|
const out = postProcessStyles(props, staticConfig, defaultTheme)
|
|
959
998
|
const next = out?.style ?? props
|
|
960
999
|
if (shouldPrintDebug) {
|
|
961
|
-
console.log('
|
|
962
|
-
console.log('
|
|
963
|
-
console.log('
|
|
1000
|
+
console.log(' getStyles props >>\n', logLines(objToStr(props)))
|
|
1001
|
+
console.log(' getStyles next >>\n', logLines(objToStr(next)))
|
|
1002
|
+
console.log(' getStyles style >>\n', logLines(objToStr(out.style)))
|
|
1003
|
+
console.log(' getStyles viewp >>\n', logLines(objToStr(out.viewProps)))
|
|
964
1004
|
}
|
|
965
1005
|
if (staticConfig.validStyles) {
|
|
966
1006
|
for (const key in next) {
|
|
@@ -972,10 +1012,6 @@ export function createExtractor() {
|
|
|
972
1012
|
return next
|
|
973
1013
|
}
|
|
974
1014
|
|
|
975
|
-
if (shouldPrintDebug) {
|
|
976
|
-
console.log(' staticConfig.defaultProps', staticConfig.defaultProps)
|
|
977
|
-
}
|
|
978
|
-
|
|
979
1015
|
// used to ensure we pass the entire prop bundle to getStyles
|
|
980
1016
|
const completeStylesProcessed = getStyles({
|
|
981
1017
|
...staticConfig.defaultProps,
|
|
@@ -1004,9 +1040,9 @@ export function createExtractor() {
|
|
|
1004
1040
|
|
|
1005
1041
|
if (shouldPrintDebug) {
|
|
1006
1042
|
// prettier-ignore
|
|
1007
|
-
console.log('
|
|
1043
|
+
console.log(' completeStaticProps\n', logLines(objToStr(completeStaticProps)))
|
|
1008
1044
|
// prettier-ignore
|
|
1009
|
-
console.log('
|
|
1045
|
+
console.log(' completeStylesProcessed\n', logLines(objToStr(completeStylesProcessed)))
|
|
1010
1046
|
}
|
|
1011
1047
|
|
|
1012
1048
|
for (const attr of attrs) {
|
|
@@ -1045,22 +1081,7 @@ export function createExtractor() {
|
|
|
1045
1081
|
}
|
|
1046
1082
|
|
|
1047
1083
|
if (shouldPrintDebug) {
|
|
1048
|
-
console.log(' - attrs (after)
|
|
1049
|
-
}
|
|
1050
|
-
|
|
1051
|
-
// add data-is
|
|
1052
|
-
if (shouldAddDebugProp) {
|
|
1053
|
-
const preName = componentName ? `${componentName}:` : ''
|
|
1054
|
-
// unshift so spreads/nesting overwrite
|
|
1055
|
-
attrs.unshift({
|
|
1056
|
-
type: 'attr',
|
|
1057
|
-
value: t.jsxAttribute(
|
|
1058
|
-
t.jsxIdentifier('data-is'),
|
|
1059
|
-
t.stringLiteral(
|
|
1060
|
-
` ${preName}${node.name.name} ${filePath.replace('./', '')}:${lineNumbers} `
|
|
1061
|
-
)
|
|
1062
|
-
),
|
|
1063
|
-
})
|
|
1084
|
+
console.log(' - attrs (after):\n', logLines(attrs.map(attrStr).join(', ')))
|
|
1064
1085
|
}
|
|
1065
1086
|
|
|
1066
1087
|
if (shouldFlatten) {
|
|
@@ -1070,7 +1091,7 @@ export function createExtractor() {
|
|
|
1070
1091
|
}
|
|
1071
1092
|
isFlattened = true
|
|
1072
1093
|
node.name.name = flatNode
|
|
1073
|
-
|
|
1094
|
+
res.flattened++
|
|
1074
1095
|
if (closingElement) {
|
|
1075
1096
|
closingElement.name.name = flatNode
|
|
1076
1097
|
}
|
|
@@ -1079,9 +1100,11 @@ export function createExtractor() {
|
|
|
1079
1100
|
if (shouldPrintDebug) {
|
|
1080
1101
|
// prettier-ignore
|
|
1081
1102
|
console.log(' [❊] inline props ', inlinePropCount, shouldDeopt ? ' deopted' : '', hasSpread ? ' spread' : '', '!flatten', staticConfig.neverFlatten)
|
|
1082
|
-
console.log(' - attrs (end)
|
|
1103
|
+
console.log(' - attrs (end):\n', logLines(attrs.map(attrStr).join(', ')))
|
|
1083
1104
|
}
|
|
1084
1105
|
|
|
1106
|
+
res.optimized++
|
|
1107
|
+
|
|
1085
1108
|
onExtractTag({
|
|
1086
1109
|
attrs,
|
|
1087
1110
|
node,
|
|
@@ -1108,6 +1131,8 @@ export function createExtractor() {
|
|
|
1108
1131
|
removeUnusedHooks(comp, shouldPrintDebug)
|
|
1109
1132
|
}
|
|
1110
1133
|
}
|
|
1134
|
+
|
|
1135
|
+
return res
|
|
1111
1136
|
},
|
|
1112
1137
|
}
|
|
1113
1138
|
}
|
|
@@ -21,7 +21,10 @@ export const attrStr = (attr: ExtractedAttr) => {
|
|
|
21
21
|
|
|
22
22
|
export const objToStr = (obj: any) => {
|
|
23
23
|
return Object.entries(obj)
|
|
24
|
-
.map(
|
|
24
|
+
.map(
|
|
25
|
+
([k, v]) =>
|
|
26
|
+
`${k}:${Array.isArray(v) ? `[...]` : v && typeof v === 'object' ? `{${objToStr(v)}}` : v}`
|
|
27
|
+
)
|
|
25
28
|
.join(', ')
|
|
26
29
|
}
|
|
27
30
|
|
|
@@ -69,7 +72,11 @@ export function findComponentName(scope) {
|
|
|
69
72
|
return componentName
|
|
70
73
|
}
|
|
71
74
|
|
|
72
|
-
export function isValidThemeHook(
|
|
75
|
+
export function isValidThemeHook(
|
|
76
|
+
jsxPath: NodePath<t.JSXElement>,
|
|
77
|
+
n: t.MemberExpression,
|
|
78
|
+
sourcePath: string
|
|
79
|
+
) {
|
|
73
80
|
if (!t.isIdentifier(n.object) || !t.isIdentifier(n.property)) return false
|
|
74
81
|
const bindings = jsxPath.scope.getAllBindings()
|
|
75
82
|
const binding = bindings[n.object.name]
|
|
@@ -90,4 +97,6 @@ export function isValidThemeHook(jsxPath: NodePath<t.JSXElement>, n: t.MemberExp
|
|
|
90
97
|
return true
|
|
91
98
|
}
|
|
92
99
|
|
|
93
|
-
export const isInsideTamagui = (srcName: string) =>
|
|
100
|
+
export const isInsideTamagui = (srcName: string) => {
|
|
101
|
+
return srcName.includes('/tamagui/_jsx') || srcName.includes('/core/src')
|
|
102
|
+
}
|
|
@@ -18,6 +18,7 @@ import { ensureImportingConcat } from './ensureImportingConcat'
|
|
|
18
18
|
import { isSimpleSpread } from './extractHelpers'
|
|
19
19
|
import { extractMediaStyle } from './extractMediaStyle'
|
|
20
20
|
import { hoistClassNames } from './hoistClassNames'
|
|
21
|
+
import { logLines } from './logLines'
|
|
21
22
|
|
|
22
23
|
export const CONCAT_CLASSNAME_IMPORT = 'concatClassName'
|
|
23
24
|
|
|
@@ -79,17 +80,11 @@ export function extractToClassNames({
|
|
|
79
80
|
const cssMap = new Map<string, { css: string; commentTexts: string[] }>()
|
|
80
81
|
const existingHoists: { [key: string]: t.Identifier } = {}
|
|
81
82
|
|
|
82
|
-
|
|
83
|
-
let optimized = 0
|
|
84
|
-
|
|
85
|
-
extractor.parse(ast, {
|
|
83
|
+
const res = extractor.parse(ast, {
|
|
86
84
|
sourcePath,
|
|
87
85
|
shouldPrintDebug,
|
|
88
86
|
...options,
|
|
89
87
|
getFlattenedNode: ({ tag }) => tag,
|
|
90
|
-
onDidFlatten() {
|
|
91
|
-
flattened++
|
|
92
|
-
},
|
|
93
88
|
onExtractTag: ({
|
|
94
89
|
attrs,
|
|
95
90
|
node,
|
|
@@ -100,8 +95,6 @@ export function extractToClassNames({
|
|
|
100
95
|
lineNumbers,
|
|
101
96
|
programPath,
|
|
102
97
|
}) => {
|
|
103
|
-
optimized++
|
|
104
|
-
|
|
105
98
|
let finalClassNames: ClassNameObject[] = []
|
|
106
99
|
let finalAttrs: (t.JSXAttribute | t.JSXSpreadAttribute)[] = []
|
|
107
100
|
let finalStyles: StyleObject[] = []
|
|
@@ -144,10 +137,6 @@ export function extractToClassNames({
|
|
|
144
137
|
case 'style':
|
|
145
138
|
const styles = addStyles(attr.value)
|
|
146
139
|
const newClassNames = concatClassName(styles.map((x) => x.identifier).join(' '))
|
|
147
|
-
if (shouldPrintDebug) {
|
|
148
|
-
// console.log(' style', attr.value)
|
|
149
|
-
console.log(' classnames', newClassNames, finalClassNames)
|
|
150
|
-
}
|
|
151
140
|
// prettier-ignore
|
|
152
141
|
const existing = finalClassNames.find((x) => x.type == 'StringLiteral') as t.StringLiteral | null
|
|
153
142
|
if (existing) {
|
|
@@ -157,7 +146,7 @@ export function extractToClassNames({
|
|
|
157
146
|
}
|
|
158
147
|
if (shouldPrintDebug) {
|
|
159
148
|
// prettier-ignore
|
|
160
|
-
console.log(' classnames (after)', finalClassNames.map(x => x['value']).join(' '))
|
|
149
|
+
console.log(' classnames (after)\n', logLines(finalClassNames.map(x => x['value']).join(' ')))
|
|
161
150
|
}
|
|
162
151
|
break
|
|
163
152
|
case 'attr':
|
|
@@ -190,7 +179,7 @@ export function extractToClassNames({
|
|
|
190
179
|
const mediaExtraction = extractMediaStyle(
|
|
191
180
|
attr.value,
|
|
192
181
|
jsxPath,
|
|
193
|
-
extractor.
|
|
182
|
+
extractor.getTamagui(),
|
|
194
183
|
sourcePath,
|
|
195
184
|
lastMediaImportance,
|
|
196
185
|
shouldPrintDebug
|
|
@@ -276,15 +265,12 @@ export function extractToClassNames({
|
|
|
276
265
|
},
|
|
277
266
|
})
|
|
278
267
|
|
|
279
|
-
if (!
|
|
268
|
+
if (!res || !res.modified) {
|
|
280
269
|
return null
|
|
281
270
|
}
|
|
282
271
|
|
|
283
272
|
const styles = Array.from(cssMap.values())
|
|
284
|
-
.map((x) =>
|
|
285
|
-
// remove comments
|
|
286
|
-
return x.css //shouldInternalDedupe ? x.css : `${x.commentTexts.join('\n')}\n${x.css}`
|
|
287
|
-
})
|
|
273
|
+
.map((x) => x.css)
|
|
288
274
|
.join('\n')
|
|
289
275
|
.trim()
|
|
290
276
|
|
|
@@ -325,7 +311,7 @@ export function extractToClassNames({
|
|
|
325
311
|
const memUsed =
|
|
326
312
|
Math.round(((process.memoryUsage().heapUsed - mem.heapUsed) / 1024 / 1204) * 10) / 10
|
|
327
313
|
// prettier-ignore
|
|
328
|
-
console.log(` 🥚 ${basename(sourcePath).padStart(40)} ${`${Date.now() - start}`.padStart(3)}ms ׁ· ${`${optimized}`.padStart(4)} optimized · ${flattened} flattened ${memUsed > 10 ? `used ${memUsed}MB` : ''}`)
|
|
314
|
+
console.log(` 🥚 ${basename(sourcePath).padStart(40)} ${`${Date.now() - start}`.padStart(3)}ms ׁ· ${`${res.optimized}`.padStart(4)} optimized · ${res.flattened} flattened ${memUsed > 10 ? `used ${memUsed}MB` : ''}`)
|
|
329
315
|
}
|
|
330
316
|
|
|
331
317
|
return {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export const logLines = (str: string) => {
|
|
2
|
+
let lines: string[] = ['']
|
|
3
|
+
const items = str.split(' ')
|
|
4
|
+
for (const item of items) {
|
|
5
|
+
if (item.length + lines[lines.length - 1].length > 100) {
|
|
6
|
+
lines.push('')
|
|
7
|
+
}
|
|
8
|
+
lines[lines.length - 1] += item + ' '
|
|
9
|
+
}
|
|
10
|
+
return lines.map((line, i) => ' ' + (i == 0 ? '' : ' ') + line.trim()).join('\n')
|
|
11
|
+
}
|