@tamagui/static 1.0.1-beta.59 → 1.0.1-beta.62
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/cjs/extractor/createExtractor.js +49 -21
- package/dist/cjs/extractor/createExtractor.js.map +2 -2
- package/dist/cjs/extractor/extractMediaStyle.js +1 -1
- package/dist/cjs/extractor/extractMediaStyle.js.map +2 -2
- package/dist/cjs/extractor/extractToClassNames.js +1 -1
- package/dist/cjs/extractor/extractToClassNames.js.map +2 -2
- package/dist/esm/extractor/createExtractor.js +54 -24
- package/dist/esm/extractor/createExtractor.js.map +2 -2
- package/dist/esm/extractor/extractMediaStyle.js +1 -1
- package/dist/esm/extractor/extractMediaStyle.js.map +2 -2
- package/dist/esm/extractor/extractToClassNames.js +1 -1
- package/dist/esm/extractor/extractToClassNames.js.map +2 -2
- package/dist/jsx/extractor/createExtractor.js +54 -24
- package/dist/jsx/extractor/extractMediaStyle.js +1 -1
- package/dist/jsx/extractor/extractToClassNames.js +1 -1
- package/package.json +9 -7
- package/src/constants.ts +13 -0
- package/src/extractor/accessSafe.ts +18 -0
- package/src/extractor/babelParse.ts +27 -0
- package/src/extractor/buildClassName.ts +61 -0
- package/src/extractor/createEvaluator.ts +69 -0
- package/src/extractor/createExtractor.ts +1725 -0
- package/src/extractor/ensureImportingConcat.ts +39 -0
- package/src/extractor/evaluateAstNode.ts +121 -0
- package/src/extractor/extractHelpers.ts +119 -0
- package/src/extractor/extractMediaStyle.ts +192 -0
- package/src/extractor/extractToClassNames.ts +426 -0
- package/src/extractor/findTopmostFunction.ts +22 -0
- package/src/extractor/generatedUid.ts +43 -0
- package/src/extractor/getPrefixLogs.ts +6 -0
- package/src/extractor/getPropValueFromAttributes.ts +92 -0
- package/src/extractor/getSourceModule.ts +101 -0
- package/src/extractor/getStaticBindingsForScope.ts +183 -0
- package/src/extractor/hoistClassNames.ts +45 -0
- package/src/extractor/literalToAst.ts +84 -0
- package/src/extractor/loadTamagui.ts +139 -0
- package/src/extractor/logLines.ts +16 -0
- package/src/extractor/normalizeTernaries.ts +63 -0
- package/src/extractor/removeUnusedHooks.ts +76 -0
- package/src/extractor/timer.ts +18 -0
- package/src/extractor/validHTMLAttributes.ts +99 -0
- package/src/index.ts +9 -0
- package/src/patchReactNativeWeb.ts +165 -0
- package/src/types.ts +97 -0
- package/types/extractor/createExtractor.d.ts +14 -1
- package/types/extractor/createExtractor.d.ts.map +1 -1
- package/types/extractor/extractMediaStyle.d.ts.map +1 -1
- package/types/extractor/extractToClassNames.d.ts.map +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/extractor/extractToClassNames.ts"],
|
|
4
|
-
"sourcesContent": ["import * as path from 'path'\nimport { basename } from 'path'\nimport * as util from 'util'\n\nimport generate from '@babel/generator'\nimport * as t from '@babel/types'\nimport { getStylesAtomic } from '@tamagui/core-node'\nimport { concatClassName } from '@tamagui/helpers'\nimport invariant from 'invariant'\nimport { ViewStyle } from 'react-native'\nimport { LoaderContext } from 'webpack'\n\nimport { CONCAT_CLASSNAME_IMPORT } from '../constants'\nimport { ClassNameObject, StyleObject, TamaguiOptions, Ternary } from '../types'\nimport { babelParse } from './babelParse'\nimport { buildClassName } from './buildClassName'\nimport { Extractor } from './createExtractor'\nimport { ensureImportingConcat } from './ensureImportingConcat'\nimport { isSimpleSpread } from './extractHelpers'\nimport { extractMediaStyle } from './extractMediaStyle'\nimport { getPrefixLogs } from './getPrefixLogs'\nimport { hoistClassNames } from './hoistClassNames'\nimport { literalToAst } from './literalToAst'\nimport { logLines } from './logLines'\nimport { timer } from './timer'\n\nconst mergeStyleGroups = {\n shadowOpacity: true,\n shadowRadius: true,\n shadowColor: true,\n shadowOffset: true,\n}\n\nexport type ExtractedResponse = {\n js: string | Buffer\n styles: string\n stylesPath?: string\n ast: t.File\n map: any // RawSourceMap from 'source-map'\n}\n\nexport function extractToClassNames({\n loader,\n extractor,\n source,\n sourcePath,\n options,\n shouldPrintDebug,\n cssLoaderPath,\n threaded,\n cssPath,\n}: {\n loader: LoaderContext<any>\n cssLoaderPath: string\n extractor: Extractor\n source: string | Buffer\n sourcePath: string\n options: TamaguiOptions\n shouldPrintDebug: boolean | 'verbose'\n cssPath: string\n threaded?: boolean\n}): ExtractedResponse | null {\n const tm = timer()\n\n if (typeof source !== 'string') {\n throw new Error('`source` must be a string of javascript')\n }\n invariant(\n typeof sourcePath === 'string' && path.isAbsolute(sourcePath),\n '`sourcePath` must be an absolute path to a .js file'\n )\n\n const shouldLogTiming = options.logTimings ?? true\n const start = Date.now()\n const mem = shouldLogTiming ? process.memoryUsage() : null\n\n // Using a map for (officially supported) guaranteed insertion order\n let ast: t.File\n\n try {\n // @ts-ignore\n ast = babelParse(source)\n } catch (err) {\n console.error('babel parse error:', sourcePath)\n throw err\n }\n\n tm.mark(`babel-parse`, shouldPrintDebug === 'verbose')\n\n const cssMap = new Map<string, { css: string; commentTexts: string[] }>()\n const existingHoists: { [key: string]: t.Identifier } = {}\n\n let hasFlattened = false\n\n const res = extractor.parse(ast, {\n sourcePath,\n shouldPrintDebug,\n ...options,\n target: 'html',\n getFlattenedNode: ({ tag }) => {\n hasFlattened = true\n return tag\n },\n onExtractTag: ({\n attrs,\n node,\n attemptEval,\n jsxPath,\n originalNodeName,\n filePath,\n lineNumbers,\n programPath,\n isFlattened,\n }) => {\n let finalClassNames: ClassNameObject[] = []\n let finalAttrs: (t.JSXAttribute | t.JSXSpreadAttribute)[] = []\n let finalStyles: StyleObject[] = []\n\n let viewStyles = {}\n for (const attr of attrs) {\n if (attr.type === 'style') {\n viewStyles = {\n ...viewStyles,\n ...attr.value,\n }\n }\n }\n\n const ensureNeededPrevStyle = (style: ViewStyle) => {\n // ensure all group keys are merged\n const keys = Object.keys(style)\n if (!keys.some((key) => mergeStyleGroups[key])) {\n return style\n }\n for (const k in mergeStyleGroups) {\n if (k in viewStyles) {\n style[k] = style[k] ?? viewStyles[k]\n }\n }\n return style\n }\n\n const addStyles = (style: ViewStyle | null): StyleObject[] => {\n if (!style) return []\n const styleWithPrev = ensureNeededPrevStyle(style)\n const res = getStylesAtomic(styleWithPrev)\n if (res.length) {\n finalStyles = [...finalStyles, ...res]\n }\n return res\n }\n\n // 1 to start above any :hover styles\n let lastMediaImportance = 1\n for (const attr of attrs) {\n switch (attr.type) {\n case 'style':\n if (!isFlattened) {\n // only ever one at a time i believe so we can be lazy with this access\n const { hoverStyle, pressStyle, focusStyle } = attr.value\n const pseudos = [\n ['hoverStyle', hoverStyle],\n ['pressStyle', pressStyle],\n ['focusStyle', focusStyle],\n ] as const\n\n const styles = getStylesAtomic(attr.value, {\n splitTransforms: true,\n })\n finalStyles = [...finalStyles, ...styles]\n\n for (const [key, value] of pseudos) {\n if (value && Object.keys(value).length) {\n finalAttrs.push(\n t.jsxAttribute(\n t.jsxIdentifier(key),\n t.jsxExpressionContainer(literalToAst(value))\n )\n )\n }\n }\n\n for (const style of styles) {\n if (style.pseudo) {\n continue\n }\n // leave them as attributes\n finalAttrs.push(\n t.jsxAttribute(t.jsxIdentifier(style.property), t.stringLiteral(style.identifier))\n )\n }\n\n // for (const key in attr.value) {\n // if (pseudos.some((x) => x[0] === key)) {\n // // we handled pseudos above...\n // continue\n // }\n // // leave them as attributes\n // finalAttrs.push(\n // t.jsxAttribute(t.jsxIdentifier(key), t.stringLiteral(attr.value[key]))\n // )\n // }\n } else {\n const styles = addStyles(attr.value)\n const newClassNames = concatClassName(styles.map((x) => x.identifier).join(' '))\n const existing = finalClassNames.find(\n (x) => x.type == 'StringLiteral'\n ) as t.StringLiteral | null\n\n // const newClassNames = concatClassName(Object.values(attr.value))\n // const existing = finalClassNames.find(\n // (x) => x.type == 'StringLiteral'\n // ) as t.StringLiteral | null\n\n if (existing) {\n existing.value = `${existing.value} ${newClassNames}`\n } else {\n finalClassNames = [...finalClassNames, t.stringLiteral(newClassNames)]\n }\n }\n\n break\n case 'attr':\n const val = attr.value\n if (t.isJSXSpreadAttribute(val)) {\n if (isSimpleSpread(val)) {\n finalClassNames.push(\n t.logicalExpression(\n '&&',\n val.argument,\n t.memberExpression(val.argument, t.identifier('className'))\n )\n )\n }\n } else if (val.name.name === 'className') {\n const value = val.value\n if (value) {\n try {\n const evaluatedValue = attemptEval(value)\n finalClassNames.push(t.stringLiteral(evaluatedValue))\n } catch (e) {\n finalClassNames.push(value['expression'])\n }\n }\n continue\n }\n finalAttrs.push(val)\n break\n case 'ternary':\n const mediaExtraction = extractMediaStyle(\n attr.value,\n jsxPath,\n extractor.getTamagui(),\n sourcePath,\n lastMediaImportance,\n shouldPrintDebug\n )\n if (shouldPrintDebug) {\n if (mediaExtraction) {\n // prettier-ignore\n console.log('ternary (mediaStyles)', mediaExtraction.ternaryWithoutMedia?.inlineMediaQuery ?? '', mediaExtraction.mediaStyles.map((x) => x.identifier).join('.'))\n }\n }\n if (!mediaExtraction) {\n addTernaryStyle(\n attr.value,\n addStyles(attr.value.consequent),\n addStyles(attr.value.alternate)\n )\n continue\n }\n lastMediaImportance++\n if (mediaExtraction.mediaStyles) {\n finalStyles = [...finalStyles, ...mediaExtraction.mediaStyles]\n }\n if (mediaExtraction.ternaryWithoutMedia) {\n addTernaryStyle(mediaExtraction.ternaryWithoutMedia, mediaExtraction.mediaStyles, [])\n } else {\n finalClassNames = [\n ...finalClassNames,\n ...mediaExtraction.mediaStyles.map((x) => t.stringLiteral(x.identifier)),\n ]\n }\n break\n }\n }\n\n function addTernaryStyle(ternary: Ternary, a: any, b: any) {\n const cCN = a.map((x) => x.identifier).join(' ')\n const aCN = b.map((x) => x.identifier).join(' ')\n if (a.length && b.length) {\n finalClassNames.push(\n t.conditionalExpression(ternary.test, t.stringLiteral(cCN), t.stringLiteral(aCN))\n )\n } else {\n finalClassNames.push(\n t.conditionalExpression(\n ternary.test,\n t.stringLiteral(' ' + cCN),\n t.stringLiteral(' ' + aCN)\n )\n )\n }\n }\n\n if (shouldPrintDebug) {\n // prettier-ignore\n console.log(' finalClassNames\\n', logLines(finalClassNames.map(x => x['value']).join(' ')))\n }\n\n node.attributes = finalAttrs\n\n if (finalClassNames.length) {\n // inserts the _cn variable and uses it for className\n let names = buildClassName(finalClassNames)\n if (t.isStringLiteral(names)) {\n names.value = concatClassName(names.value)\n }\n const nameExpr = names ? hoistClassNames(jsxPath, existingHoists, names) : null\n let expr = nameExpr\n\n // if has some spreads, use concat helper\n if (nameExpr && !t.isIdentifier(nameExpr)) {\n if (!hasFlattened) {\n // not flat\n } else {\n ensureImportingConcat(programPath)\n const simpleSpreads = attrs.filter(\n (x) => t.isJSXSpreadAttribute(x.value) && isSimpleSpread(x.value)\n )\n expr = t.callExpression(t.identifier(CONCAT_CLASSNAME_IMPORT), [\n expr,\n ...simpleSpreads.map((val) => val.value['argument']),\n ])\n }\n }\n\n node.attributes.push(\n t.jsxAttribute(t.jsxIdentifier('className'), t.jsxExpressionContainer(expr))\n )\n }\n\n const comment = util.format('/* %s:%s (%s) */', filePath, lineNumbers, originalNodeName)\n\n for (const { className, rules, identifier, value } of finalStyles) {\n // console.log('backvalue', identifier, value)\n // ast.program.body.unshift(\n // t.expressionStatement(\n // t.callExpression(\n // t.memberExpression(\n // t.callExpression(t.identifier('require'), [t.stringLiteral('@tamagui/core')]),\n // t.identifier('setIdentifierValue')\n // ),\n // [t.stringLiteral(identifier), t.stringLiteral(value)]\n // )\n // )\n // )\n\n if (cssMap.has(className)) {\n if (comment) {\n const val = cssMap.get(className)!\n val.commentTexts.push(comment)\n cssMap.set(className, val)\n }\n } else if (rules.length) {\n if (rules.length > 1) {\n console.log(' rules error', { rules })\n throw new Error(`Shouldn't have more than one rule`)\n }\n cssMap.set(className, {\n css: rules[0],\n commentTexts: [comment],\n })\n }\n }\n },\n })\n\n if (!res || (!res.modified && !res.optimized && !res.flattened)) {\n if (shouldPrintDebug) {\n console.log('no res or none modified', res)\n }\n return null\n }\n\n const styles = Array.from(cssMap.values())\n .map((x) => x.css)\n .join('\\n')\n .trim()\n\n if (styles) {\n const cssQuery = threaded\n ? `cssData=${Buffer.from(styles).toString('base64')}`\n : `cssPath=${cssPath}`\n const remReq = loader.remainingRequest\n const importPath = `${cssPath}!=!${cssLoaderPath}?${cssQuery}!${remReq}`\n ast.program.body.unshift(t.importDeclaration([], t.stringLiteral(importPath)))\n }\n\n const result = generate(\n ast,\n {\n concise: false,\n filename: sourcePath,\n // this makes the debug output terrible, and i think sourcemap works already\n retainLines: false,\n sourceFileName: sourcePath,\n sourceMaps: true,\n },\n source\n )\n\n if (shouldPrintDebug) {\n console.log(\n '\\n -------- output code ------- \\n\\n',\n result.code\n .split('\\n')\n .filter((x) => !x.startsWith('//'))\n .join('\\n')\n )\n console.log('\\n -------- output style -------- \\n\\n', styles)\n }\n\n if (shouldLogTiming) {\n const memUsed = mem\n ? Math.round(((process.memoryUsage().heapUsed - mem.heapUsed) / 1024 / 1204) * 10) / 10\n : 0\n const path = basename(sourcePath)\n .replace(/\\.[jt]sx?$/, '')\n .slice(0, 22)\n .trim()\n .padStart(24)\n const numOptimized = `${res.optimized}`.padStart(3)\n const numFound = `${res.found}`.padStart(3)\n const numFlattened = `${res.flattened}`.padStart(3)\n const memory = process.env.DEBUG && memUsed > 10 ? ` ${memUsed}MB` : ''\n const timing = Date.now() - start\n const timingWarning = timing > 50 ? '\u26A0\uFE0F' : timing > 150 ? '\u2622\uFE0F' : ''\n const timingStr = `${timing}ms${timingWarning}`.padStart(6)\n console.log(\n `${getPrefixLogs(\n options\n )} ${path} ${numFound} \u00B7 ${numOptimized} \u00B7 ${numFlattened} ${timingStr} ${\n memory ? `(${memory})` : ''\n }`\n )\n }\n\n return {\n ast,\n styles,\n js: result.code,\n map: result.map,\n }\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import * as path from 'path'\nimport { basename } from 'path'\nimport * as util from 'util'\n\nimport generate from '@babel/generator'\nimport * as t from '@babel/types'\nimport { getStylesAtomic } from '@tamagui/core-node'\nimport { concatClassName } from '@tamagui/helpers'\nimport invariant from 'invariant'\nimport { ViewStyle } from 'react-native'\nimport { LoaderContext } from 'webpack'\n\nimport { CONCAT_CLASSNAME_IMPORT } from '../constants'\nimport { ClassNameObject, StyleObject, TamaguiOptions, Ternary } from '../types'\nimport { babelParse } from './babelParse'\nimport { buildClassName } from './buildClassName'\nimport { Extractor } from './createExtractor'\nimport { ensureImportingConcat } from './ensureImportingConcat'\nimport { isSimpleSpread } from './extractHelpers'\nimport { extractMediaStyle } from './extractMediaStyle'\nimport { getPrefixLogs } from './getPrefixLogs'\nimport { hoistClassNames } from './hoistClassNames'\nimport { literalToAst } from './literalToAst'\nimport { logLines } from './logLines'\nimport { timer } from './timer'\n\nconst mergeStyleGroups = {\n shadowOpacity: true,\n shadowRadius: true,\n shadowColor: true,\n shadowOffset: true,\n}\n\nexport type ExtractedResponse = {\n js: string | Buffer\n styles: string\n stylesPath?: string\n ast: t.File\n map: any // RawSourceMap from 'source-map'\n}\n\nexport function extractToClassNames({\n loader,\n extractor,\n source,\n sourcePath,\n options,\n shouldPrintDebug,\n cssLoaderPath,\n threaded,\n cssPath,\n}: {\n loader: LoaderContext<any>\n cssLoaderPath: string\n extractor: Extractor\n source: string | Buffer\n sourcePath: string\n options: TamaguiOptions\n shouldPrintDebug: boolean | 'verbose'\n cssPath: string\n threaded?: boolean\n}): ExtractedResponse | null {\n const tm = timer()\n\n if (typeof source !== 'string') {\n throw new Error('`source` must be a string of javascript')\n }\n invariant(\n typeof sourcePath === 'string' && path.isAbsolute(sourcePath),\n '`sourcePath` must be an absolute path to a .js file'\n )\n\n const shouldLogTiming = options.logTimings ?? true\n const start = Date.now()\n const mem = shouldLogTiming ? process.memoryUsage() : null\n\n // Using a map for (officially supported) guaranteed insertion order\n let ast: t.File\n\n try {\n // @ts-ignore\n ast = babelParse(source)\n } catch (err) {\n console.error('babel parse error:', sourcePath)\n throw err\n }\n\n tm.mark(`babel-parse`, shouldPrintDebug === 'verbose')\n\n const cssMap = new Map<string, { css: string; commentTexts: string[] }>()\n const existingHoists: { [key: string]: t.Identifier } = {}\n\n let hasFlattened = false\n\n const res = extractor.parse(ast, {\n sourcePath,\n shouldPrintDebug,\n ...options,\n target: 'html',\n getFlattenedNode: ({ tag }) => {\n hasFlattened = true\n return tag\n },\n onExtractTag: ({\n attrs,\n node,\n attemptEval,\n jsxPath,\n originalNodeName,\n filePath,\n lineNumbers,\n programPath,\n isFlattened,\n }) => {\n let finalClassNames: ClassNameObject[] = []\n let finalAttrs: (t.JSXAttribute | t.JSXSpreadAttribute)[] = []\n let finalStyles: StyleObject[] = []\n\n let viewStyles = {}\n for (const attr of attrs) {\n if (attr.type === 'style') {\n viewStyles = {\n ...viewStyles,\n ...attr.value,\n }\n }\n }\n\n const ensureNeededPrevStyle = (style: ViewStyle) => {\n // ensure all group keys are merged\n const keys = Object.keys(style)\n if (!keys.some((key) => mergeStyleGroups[key])) {\n return style\n }\n for (const k in mergeStyleGroups) {\n if (k in viewStyles) {\n style[k] = style[k] ?? viewStyles[k]\n }\n }\n return style\n }\n\n const addStyles = (style: ViewStyle | null): StyleObject[] => {\n if (!style) return []\n const styleWithPrev = ensureNeededPrevStyle(style)\n const res = getStylesAtomic(styleWithPrev)\n if (res.length) {\n finalStyles = [...finalStyles, ...res]\n }\n return res\n }\n\n // 1 to start above any :hover styles\n let lastMediaImportance = 1\n for (const attr of attrs) {\n switch (attr.type) {\n case 'style':\n if (!isFlattened) {\n // only ever one at a time i believe so we can be lazy with this access\n const { hoverStyle, pressStyle, focusStyle } = attr.value\n const pseudos = [\n ['hoverStyle', hoverStyle],\n ['pressStyle', pressStyle],\n ['focusStyle', focusStyle],\n ] as const\n\n const styles = getStylesAtomic(attr.value, {\n splitTransforms: true,\n })\n finalStyles = [...finalStyles, ...styles]\n\n for (const [key, value] of pseudos) {\n if (value && Object.keys(value).length) {\n finalAttrs.push(\n t.jsxAttribute(\n t.jsxIdentifier(key),\n t.jsxExpressionContainer(literalToAst(value))\n )\n )\n }\n }\n\n for (const style of styles) {\n if (style.pseudo) {\n continue\n }\n // leave them as attributes\n finalAttrs.push(\n t.jsxAttribute(t.jsxIdentifier(style.property), t.stringLiteral(style.identifier))\n )\n }\n } else {\n const styles = addStyles(attr.value)\n const newClassNames = concatClassName(styles.map((x) => x.identifier).join(' '))\n const existing = finalClassNames.find(\n (x) => x.type == 'StringLiteral'\n ) as t.StringLiteral | null\n\n if (existing) {\n existing.value = `${existing.value} ${newClassNames}`\n } else {\n finalClassNames = [...finalClassNames, t.stringLiteral(newClassNames)]\n }\n }\n\n break\n case 'attr':\n const val = attr.value\n if (t.isJSXSpreadAttribute(val)) {\n if (isSimpleSpread(val)) {\n finalClassNames.push(\n t.logicalExpression(\n '&&',\n val.argument,\n t.memberExpression(val.argument, t.identifier('className'))\n )\n )\n }\n } else if (val.name.name === 'className') {\n const value = val.value\n if (value) {\n try {\n const evaluatedValue = attemptEval(value)\n finalClassNames.push(t.stringLiteral(evaluatedValue))\n } catch (e) {\n finalClassNames.push(value['expression'])\n }\n }\n continue\n }\n finalAttrs.push(val)\n break\n case 'ternary':\n const mediaExtraction = extractMediaStyle(\n attr.value,\n jsxPath,\n extractor.getTamagui(),\n sourcePath,\n lastMediaImportance,\n shouldPrintDebug\n )\n if (shouldPrintDebug) {\n if (mediaExtraction) {\n // prettier-ignore\n console.log('ternary (mediaStyles)', mediaExtraction.ternaryWithoutMedia?.inlineMediaQuery ?? '', mediaExtraction.mediaStyles.map((x) => x.identifier).join('.'))\n }\n }\n if (!mediaExtraction) {\n addTernaryStyle(\n attr.value,\n addStyles(attr.value.consequent),\n addStyles(attr.value.alternate)\n )\n continue\n }\n lastMediaImportance++\n if (mediaExtraction.mediaStyles) {\n finalStyles = [...finalStyles, ...mediaExtraction.mediaStyles]\n }\n if (mediaExtraction.ternaryWithoutMedia) {\n addTernaryStyle(mediaExtraction.ternaryWithoutMedia, mediaExtraction.mediaStyles, [])\n } else {\n finalClassNames = [\n ...finalClassNames,\n ...mediaExtraction.mediaStyles.map((x) => t.stringLiteral(x.identifier)),\n ]\n }\n break\n }\n }\n\n function addTernaryStyle(ternary: Ternary, a: any, b: any) {\n const cCN = a.map((x) => x.identifier).join(' ')\n const aCN = b.map((x) => x.identifier).join(' ')\n if (a.length && b.length) {\n finalClassNames.push(\n t.conditionalExpression(ternary.test, t.stringLiteral(cCN), t.stringLiteral(aCN))\n )\n } else {\n finalClassNames.push(\n t.conditionalExpression(\n ternary.test,\n t.stringLiteral(' ' + cCN),\n t.stringLiteral(' ' + aCN)\n )\n )\n }\n }\n\n if (shouldPrintDebug) {\n // prettier-ignore\n console.log(' finalClassNames\\n', logLines(finalClassNames.map(x => x['value']).join(' ')))\n }\n\n node.attributes = finalAttrs\n\n if (finalClassNames.length) {\n // inserts the _cn variable and uses it for className\n let names = buildClassName(finalClassNames)\n if (t.isStringLiteral(names)) {\n names.value = concatClassName(names.value)\n }\n const nameExpr = names ? hoistClassNames(jsxPath, existingHoists, names) : null\n let expr = nameExpr\n\n // if has some spreads, use concat helper\n if (nameExpr && !t.isIdentifier(nameExpr)) {\n if (!hasFlattened) {\n // not flat\n } else {\n ensureImportingConcat(programPath)\n const simpleSpreads = attrs.filter(\n (x) => t.isJSXSpreadAttribute(x.value) && isSimpleSpread(x.value)\n )\n expr = t.callExpression(t.identifier(CONCAT_CLASSNAME_IMPORT), [\n expr,\n ...simpleSpreads.map((val) => val.value['argument']),\n ])\n }\n }\n\n node.attributes.push(\n t.jsxAttribute(t.jsxIdentifier('className'), t.jsxExpressionContainer(expr))\n )\n }\n\n const comment = util.format('/* %s:%s (%s) */', filePath, lineNumbers, originalNodeName)\n\n for (const { className, rules } of finalStyles) {\n if (cssMap.has(className)) {\n if (comment) {\n const val = cssMap.get(className)!\n val.commentTexts.push(comment)\n cssMap.set(className, val)\n }\n } else if (rules.length) {\n if (rules.length > 1) {\n console.log(' rules error', { rules })\n throw new Error(`Shouldn't have more than one rule`)\n }\n cssMap.set(className, {\n css: rules[0],\n commentTexts: [comment],\n })\n }\n }\n },\n })\n\n if (!res || (!res.modified && !res.optimized && !res.flattened)) {\n if (shouldPrintDebug) {\n console.log('no res or none modified', res)\n }\n return null\n }\n\n const styles = Array.from(cssMap.values())\n .map((x) => x.css)\n .join('\\n')\n .trim()\n\n if (styles) {\n const cssQuery = threaded\n ? `cssData=${Buffer.from(styles).toString('base64')}`\n : `cssPath=${cssPath}`\n const remReq = loader.remainingRequest\n const importPath = `${cssPath}!=!${cssLoaderPath}?${cssQuery}!${remReq}`\n ast.program.body.unshift(t.importDeclaration([], t.stringLiteral(importPath)))\n }\n\n const result = generate(\n ast,\n {\n concise: false,\n filename: sourcePath,\n // this makes the debug output terrible, and i think sourcemap works already\n retainLines: false,\n sourceFileName: sourcePath,\n sourceMaps: true,\n },\n source\n )\n\n if (shouldPrintDebug) {\n console.log(\n '\\n -------- output code ------- \\n\\n',\n result.code\n .split('\\n')\n .filter((x) => !x.startsWith('//'))\n .join('\\n')\n )\n console.log('\\n -------- output style -------- \\n\\n', styles)\n }\n\n if (shouldLogTiming) {\n const memUsed = mem\n ? Math.round(((process.memoryUsage().heapUsed - mem.heapUsed) / 1024 / 1204) * 10) / 10\n : 0\n const path = basename(sourcePath)\n .replace(/\\.[jt]sx?$/, '')\n .slice(0, 22)\n .trim()\n .padStart(24)\n const numOptimized = `${res.optimized}`.padStart(3)\n const numFound = `${res.found}`.padStart(3)\n const numFlattened = `${res.flattened}`.padStart(3)\n const memory = process.env.DEBUG && memUsed > 10 ? ` ${memUsed}MB` : ''\n const timing = Date.now() - start\n const timingWarning = timing > 50 ? '\u26A0\uFE0F' : timing > 150 ? '\u2622\uFE0F' : ''\n const timingStr = `${timing}ms${timingWarning}`.padStart(6)\n console.log(\n `${getPrefixLogs(\n options\n )} ${path} ${numFound} \u00B7 ${numOptimized} \u00B7 ${numFlattened} ${timingStr} ${\n memory ? `(${memory})` : ''\n }`\n )\n }\n\n return {\n ast,\n styles,\n js: result.code,\n map: result.map,\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -4,6 +4,7 @@ import { relative } from "path";
|
|
|
4
4
|
import traverse from "@babel/traverse";
|
|
5
5
|
import * as t from "@babel/types";
|
|
6
6
|
import {
|
|
7
|
+
expandStyles,
|
|
7
8
|
getSplitStyles,
|
|
8
9
|
mediaQueryConfig,
|
|
9
10
|
normalizeStyleObject,
|
|
@@ -97,7 +98,16 @@ function createExtractor() {
|
|
|
97
98
|
}
|
|
98
99
|
tm.mark("load-tamagui", shouldPrintDebug === "verbose");
|
|
99
100
|
loadedTamaguiConfig = tamaguiConfig;
|
|
100
|
-
const
|
|
101
|
+
const proxiedTheme = proxyThemeVariables(tamaguiConfig.themes[Object.keys(tamaguiConfig.themes)[0]]);
|
|
102
|
+
const themeAccessListeners = /* @__PURE__ */ new Set();
|
|
103
|
+
const defaultTheme = new Proxy(proxiedTheme, {
|
|
104
|
+
get(target2, key) {
|
|
105
|
+
if (key[0] === "$") {
|
|
106
|
+
themeAccessListeners.forEach((cb) => cb(String(key)));
|
|
107
|
+
}
|
|
108
|
+
return Reflect.get(target2, key);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
101
111
|
const body = fileOrPath.type === "Program" ? fileOrPath.get("body") : fileOrPath.program.body;
|
|
102
112
|
const isInternalImport = /* @__PURE__ */ __name((importStr) => {
|
|
103
113
|
return isInsideTamagui(sourcePath) && importStr[0] === ".";
|
|
@@ -333,7 +343,7 @@ function createExtractor() {
|
|
|
333
343
|
let keys = [name];
|
|
334
344
|
let out = null;
|
|
335
345
|
if (staticConfig.propMapper) {
|
|
336
|
-
out = staticConfig.propMapper(name, styleValue, defaultTheme, staticConfig.defaultProps, { resolveVariablesAs: "auto" });
|
|
346
|
+
out = staticConfig.propMapper(name, styleValue, defaultTheme, staticConfig.defaultProps, { resolveVariablesAs: "auto" }, void 0, shouldPrintDebug);
|
|
337
347
|
if (out) {
|
|
338
348
|
if (!Array.isArray(out)) {
|
|
339
349
|
console.warn(`Error expected array but got`, out);
|
|
@@ -362,7 +372,7 @@ function createExtractor() {
|
|
|
362
372
|
attr: path.node
|
|
363
373
|
};
|
|
364
374
|
}
|
|
365
|
-
if (validHTMLAttributes[key]) {
|
|
375
|
+
if (validHTMLAttributes[key] || key.startsWith("aria-") || key.startsWith("data-")) {
|
|
366
376
|
return attr;
|
|
367
377
|
}
|
|
368
378
|
if (shouldPrintDebug) {
|
|
@@ -832,6 +842,14 @@ function createExtractor() {
|
|
|
832
842
|
const shouldWrapThme = allOtherPropsExtractable && !!themeVal;
|
|
833
843
|
const canFlattenProps = inlined.size === 0 || shouldWrapThme || allOtherPropsExtractable;
|
|
834
844
|
let shouldFlatten = !shouldDeopt && canFlattenProps && !hasSpread && staticConfig.neverFlatten !== true && (staticConfig.neverFlatten === "jsx" ? hasOnlyStringChildren : true);
|
|
845
|
+
if (disableExtractVariables) {
|
|
846
|
+
themeAccessListeners.add((key) => {
|
|
847
|
+
shouldFlatten = false;
|
|
848
|
+
if (shouldPrintDebug) {
|
|
849
|
+
console.log(" ! accessing theme key, avoid flatten", key);
|
|
850
|
+
}
|
|
851
|
+
});
|
|
852
|
+
}
|
|
835
853
|
if (shouldPrintDebug) {
|
|
836
854
|
console.log(" - flatten?", objToStr({ hasSpread, shouldDeopt, shouldFlatten, canFlattenProps, shouldWrapThme, allOtherPropsExtractable, hasOnlyStringChildren }));
|
|
837
855
|
}
|
|
@@ -977,35 +995,47 @@ function createExtractor() {
|
|
|
977
995
|
press: false,
|
|
978
996
|
pressIn: false
|
|
979
997
|
};
|
|
980
|
-
|
|
981
|
-
|
|
998
|
+
let foundStaticProps = {};
|
|
999
|
+
for (const key in attrs) {
|
|
1000
|
+
const cur = attrs[key];
|
|
982
1001
|
if (cur.type === "style") {
|
|
983
1002
|
normalizeStyleObject(cur.value);
|
|
984
|
-
|
|
1003
|
+
foundStaticProps = {
|
|
1004
|
+
...foundStaticProps,
|
|
1005
|
+
...expandStyles(cur.value)
|
|
1006
|
+
};
|
|
1007
|
+
continue;
|
|
985
1008
|
}
|
|
986
1009
|
if (cur.type === "attr") {
|
|
987
1010
|
if (t.isJSXSpreadAttribute(cur.value)) {
|
|
988
|
-
|
|
1011
|
+
continue;
|
|
989
1012
|
}
|
|
990
1013
|
if (!t.isJSXIdentifier(cur.value.name)) {
|
|
991
|
-
|
|
1014
|
+
continue;
|
|
992
1015
|
}
|
|
993
|
-
const
|
|
1016
|
+
const key2 = cur.value.name.name;
|
|
994
1017
|
const value = attemptEvalSafe(cur.value.value || t.booleanLiteral(true));
|
|
995
|
-
if (value
|
|
996
|
-
|
|
1018
|
+
if (value !== FAILED_EVAL) {
|
|
1019
|
+
foundStaticProps = {
|
|
1020
|
+
...foundStaticProps,
|
|
1021
|
+
[key2]: value
|
|
1022
|
+
};
|
|
997
1023
|
}
|
|
998
|
-
acc[key] = value;
|
|
999
1024
|
}
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
const
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1025
|
+
}
|
|
1026
|
+
const completeProps = {};
|
|
1027
|
+
for (const key in staticConfig.defaultProps) {
|
|
1028
|
+
if (!(key in foundStaticProps)) {
|
|
1029
|
+
completeProps[key] = staticConfig.defaultProps[key];
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
for (const key in foundStaticProps) {
|
|
1033
|
+
completeProps[key] = foundStaticProps[key];
|
|
1034
|
+
}
|
|
1006
1035
|
if (shouldPrintDebug) {
|
|
1007
1036
|
console.log(" - attrs (combined \u{1F500}): \n", logLines(attrs.map(attrStr).join(", ")));
|
|
1008
1037
|
console.log(" - defaultProps: \n", logLines(objToStr(staticConfig.defaultProps)));
|
|
1038
|
+
console.log(" - foundStaticProps: \n", logLines(objToStr(foundStaticProps)));
|
|
1009
1039
|
console.log(" - completeProps: \n", logLines(objToStr(completeProps)));
|
|
1010
1040
|
}
|
|
1011
1041
|
const getStyles = /* @__PURE__ */ __name((props2, debugName = "") => {
|
|
@@ -1027,7 +1057,7 @@ function createExtractor() {
|
|
|
1027
1057
|
const out = getSplitStyles(props2, staticConfig, defaultTheme, {
|
|
1028
1058
|
...state,
|
|
1029
1059
|
fallbackProps: completeProps
|
|
1030
|
-
});
|
|
1060
|
+
}, void 0, props2["debug"]);
|
|
1031
1061
|
const outStyle = {
|
|
1032
1062
|
...out.style,
|
|
1033
1063
|
...out.pseudos
|
|
@@ -1051,7 +1081,7 @@ function createExtractor() {
|
|
|
1051
1081
|
if (!completeStyles) {
|
|
1052
1082
|
throw new Error(`Impossible, no styles`);
|
|
1053
1083
|
}
|
|
1054
|
-
const addInitialStyleKeys = shouldFlatten ? difference(Object.keys(completeStyles), Object.keys(
|
|
1084
|
+
const addInitialStyleKeys = shouldFlatten ? difference(Object.keys(completeStyles), Object.keys(foundStaticProps)) : [];
|
|
1055
1085
|
if (addInitialStyleKeys.length) {
|
|
1056
1086
|
const toAdd = pick(completeStyles, ...addInitialStyleKeys);
|
|
1057
1087
|
const firstGroup = attrs.find((x) => x.type === "style");
|
|
@@ -1067,14 +1097,11 @@ function createExtractor() {
|
|
|
1067
1097
|
}
|
|
1068
1098
|
if (shouldPrintDebug) {
|
|
1069
1099
|
console.log(" -- addInitialStyleKeys", addInitialStyleKeys.join(", "), { shouldFlatten });
|
|
1070
|
-
console.log(" -- completeStaticProps:\n", logLines(objToStr(completeStaticProps)));
|
|
1071
1100
|
console.log(" -- completeStyles:\n", logLines(objToStr(completeStyles)));
|
|
1072
1101
|
}
|
|
1073
1102
|
let getStyleError = null;
|
|
1074
1103
|
for (const attr of attrs) {
|
|
1075
1104
|
try {
|
|
1076
|
-
if (shouldPrintDebug)
|
|
1077
|
-
console.log(" *", attrStr(attr));
|
|
1078
1105
|
switch (attr.type) {
|
|
1079
1106
|
case "ternary":
|
|
1080
1107
|
const a = getStyles(attr.value.alternate, "ternary.alternate");
|
|
@@ -1088,7 +1115,7 @@ function createExtractor() {
|
|
|
1088
1115
|
continue;
|
|
1089
1116
|
case "style":
|
|
1090
1117
|
if (shouldPrintDebug)
|
|
1091
|
-
console.log(" * styles in",
|
|
1118
|
+
console.log(" * styles in", attr.value);
|
|
1092
1119
|
const styles = getStyles(attr.value, "style");
|
|
1093
1120
|
if (shouldPrintDebug)
|
|
1094
1121
|
console.log(" * styles out", logLines(objToStr(styles)));
|
|
@@ -1101,6 +1128,9 @@ function createExtractor() {
|
|
|
1101
1128
|
getStyleError = err;
|
|
1102
1129
|
}
|
|
1103
1130
|
}
|
|
1131
|
+
if (shouldPrintDebug) {
|
|
1132
|
+
console.log(" - attrs (ternaries/combined):\n", logLines(attrs.map(attrStr).join(", ")));
|
|
1133
|
+
}
|
|
1104
1134
|
tm.mark("jsx-element-styles", shouldPrintDebug === "verbose");
|
|
1105
1135
|
if (getStyleError) {
|
|
1106
1136
|
console.log(" \u26A0\uFE0F postprocessing error, deopt", getStyleError);
|
|
@@ -43,7 +43,7 @@ function extractMediaStyle(ternary, jsxPath, tamaguiConfig, sourcePath, importan
|
|
|
43
43
|
const screenStr = negate ? "not all" : "screen";
|
|
44
44
|
const mediaQuery = `${screenStr} and ${mediaSelector}`;
|
|
45
45
|
const precendencePrefix = mediaKeyPrecendence[key];
|
|
46
|
-
const styleInner = style.rules
|
|
46
|
+
const styleInner = style.rules.map((rule) => rule.replace(style.identifier, identifier)).join(";");
|
|
47
47
|
let styleRule = "";
|
|
48
48
|
if (styleInner.includes("@media")) {
|
|
49
49
|
styleRule = styleInner.replace("{", ` and ${mediaQuery} {`);
|
|
@@ -230,7 +230,7 @@ function extractToClassNames({
|
|
|
230
230
|
node.attributes.push(t.jsxAttribute(t.jsxIdentifier("className"), t.jsxExpressionContainer(expr)));
|
|
231
231
|
}
|
|
232
232
|
const comment = util.format("/* %s:%s (%s) */", filePath, lineNumbers, originalNodeName);
|
|
233
|
-
for (const { className, rules
|
|
233
|
+
for (const { className, rules } of finalStyles) {
|
|
234
234
|
if (cssMap.has(className)) {
|
|
235
235
|
if (comment) {
|
|
236
236
|
const val = cssMap.get(className);
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tamagui/static",
|
|
3
|
-
"version": "1.0.1-beta.
|
|
3
|
+
"version": "1.0.1-beta.62",
|
|
4
4
|
"source": "src/index.ts",
|
|
5
5
|
"types": "./types/index.d.ts",
|
|
6
6
|
"main": "dist/cjs",
|
|
7
7
|
"module": "dist/esm",
|
|
8
8
|
"module:jsx": "dist/jsx",
|
|
9
9
|
"files": [
|
|
10
|
+
"src",
|
|
10
11
|
"types",
|
|
11
12
|
"dist"
|
|
12
13
|
],
|
|
@@ -16,6 +17,7 @@
|
|
|
16
17
|
"clean": "tamagui-build clean",
|
|
17
18
|
"clean:build": "tamagui-build clean:build",
|
|
18
19
|
"test": "NODE_ENV=test TAMAGUI_COMPILE_PROCESS=1 jest --forceExit",
|
|
20
|
+
"test:babel": "yarn test tests/babel-test.tsx",
|
|
19
21
|
"test:debug": "NODE_ENV=test TAMAGUI_COMPILE_PROCESS=1 DEBUG_FILE=extract-specs.tsx DEBUG=1 yarn test",
|
|
20
22
|
"test:watch": "NODE_ENV=test TAMAGUI_COMPILE_PROCESS=1 yarn test --watch",
|
|
21
23
|
"test:update-snapshots": "NODE_ENV=test jest --updateSnapshot"
|
|
@@ -34,11 +36,11 @@
|
|
|
34
36
|
"@babel/parser": "^7.15.7",
|
|
35
37
|
"@babel/traverse": "^7.15.4",
|
|
36
38
|
"@expo/match-media": "^0.3.0",
|
|
37
|
-
"@tamagui/build": "^1.0.1-beta.
|
|
38
|
-
"@tamagui/core-node": "^1.0.1-beta.
|
|
39
|
-
"@tamagui/fake-react-native": "^1.0.1-beta.
|
|
40
|
-
"@tamagui/helpers": "^1.0.1-beta.
|
|
41
|
-
"@tamagui/proxy-worm": "^1.0.1-beta.
|
|
39
|
+
"@tamagui/build": "^1.0.1-beta.62",
|
|
40
|
+
"@tamagui/core-node": "^1.0.1-beta.62",
|
|
41
|
+
"@tamagui/fake-react-native": "^1.0.1-beta.62",
|
|
42
|
+
"@tamagui/helpers": "^1.0.1-beta.62",
|
|
43
|
+
"@tamagui/proxy-worm": "^1.0.1-beta.62",
|
|
42
44
|
"babel-literal-to-ast": "^2.1.0",
|
|
43
45
|
"esbuild": "^0.14.36",
|
|
44
46
|
"esbuild-register": "^3.3.2",
|
|
@@ -46,7 +48,7 @@
|
|
|
46
48
|
"fs-extra": "^9.1.0",
|
|
47
49
|
"invariant": "^2.2.4",
|
|
48
50
|
"lodash": "^4.17.21",
|
|
49
|
-
"tamagui": "^1.0.1-beta.
|
|
51
|
+
"tamagui": "^1.0.1-beta.62"
|
|
50
52
|
},
|
|
51
53
|
"devDependencies": {
|
|
52
54
|
"@babel/plugin-syntax-typescript": "^7.14.5",
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import findCacheDir from 'find-cache-dir'
|
|
2
|
+
|
|
3
|
+
export const CSS_FILE_NAME = '__snack.css'
|
|
4
|
+
|
|
5
|
+
// ENSURE THIS ISNT THE SAME AS THE SEPARATOR USED FOR STYLE KEYS
|
|
6
|
+
// SEE matching one in concatClassName
|
|
7
|
+
export const MEDIA_SEP = '_'
|
|
8
|
+
|
|
9
|
+
// ensure cache dir
|
|
10
|
+
export const cacheDir = findCacheDir({ name: 'tamagui', create: true })
|
|
11
|
+
|
|
12
|
+
export const FAILED_EVAL = Symbol('failed_style_eval')
|
|
13
|
+
export const CONCAT_CLASSNAME_IMPORT = 'concatClassName'
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as t from '@babel/types'
|
|
2
|
+
|
|
3
|
+
// accessSafe wraps memberExpressions in object/null checks
|
|
4
|
+
// TODO: inject this as a function? this gets pretty repetitive
|
|
5
|
+
export function accessSafe(obj: t.Expression, member: string): t.LogicalExpression {
|
|
6
|
+
return t.logicalExpression(
|
|
7
|
+
'&&',
|
|
8
|
+
t.logicalExpression(
|
|
9
|
+
'&&',
|
|
10
|
+
// typeof obj === 'object
|
|
11
|
+
t.binaryExpression('===', t.unaryExpression('typeof', obj), t.stringLiteral('object')),
|
|
12
|
+
// obj !== null
|
|
13
|
+
t.binaryExpression('!==', obj, t.nullLiteral())
|
|
14
|
+
),
|
|
15
|
+
// obj.member
|
|
16
|
+
t.memberExpression(obj, t.identifier(member), false)
|
|
17
|
+
)
|
|
18
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as babelParser from '@babel/parser'
|
|
2
|
+
|
|
3
|
+
const plugins: babelParser.ParserPlugin[] = [
|
|
4
|
+
'asyncGenerators',
|
|
5
|
+
'classProperties',
|
|
6
|
+
'dynamicImport',
|
|
7
|
+
'functionBind',
|
|
8
|
+
'jsx',
|
|
9
|
+
'numericSeparator',
|
|
10
|
+
'objectRestSpread',
|
|
11
|
+
'optionalCatchBinding',
|
|
12
|
+
'decorators-legacy',
|
|
13
|
+
'typescript',
|
|
14
|
+
'optionalChaining',
|
|
15
|
+
'nullishCoalescingOperator',
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
export const parserOptions: babelParser.ParserOptions = Object.freeze({
|
|
19
|
+
plugins,
|
|
20
|
+
sourceType: 'module',
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
const parser = babelParser.parse.bind(babelParser)
|
|
24
|
+
|
|
25
|
+
export function babelParse(code: string | Buffer): any {
|
|
26
|
+
return parser(code.toString(), parserOptions)
|
|
27
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import * as t from '@babel/types'
|
|
2
|
+
|
|
3
|
+
import { ClassNameObject } from '../types'
|
|
4
|
+
|
|
5
|
+
export function buildClassName(
|
|
6
|
+
classNameObjects: ClassNameObject[]
|
|
7
|
+
): t.Expression | t.StringLiteral | null {
|
|
8
|
+
return classNameObjects.reduce<t.Expression | null>((acc, val) => {
|
|
9
|
+
if (acc == null) {
|
|
10
|
+
if (
|
|
11
|
+
// pass conditional expressions through
|
|
12
|
+
t.isConditionalExpression(val) ||
|
|
13
|
+
// pass non-null literals through
|
|
14
|
+
t.isStringLiteral(val) ||
|
|
15
|
+
t.isNumericLiteral(val)
|
|
16
|
+
) {
|
|
17
|
+
return val
|
|
18
|
+
}
|
|
19
|
+
return t.logicalExpression('||', val, t.stringLiteral(''))
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let inner: t.Expression
|
|
23
|
+
if (t.isStringLiteral(val)) {
|
|
24
|
+
if (t.isStringLiteral(acc)) {
|
|
25
|
+
// join adjacent string literals
|
|
26
|
+
return t.stringLiteral(`${acc.value} ${val.value}`)
|
|
27
|
+
}
|
|
28
|
+
inner = t.stringLiteral(` ${val.value}`)
|
|
29
|
+
} else if (t.isLiteral(val)) {
|
|
30
|
+
inner = t.binaryExpression('+', t.stringLiteral(' '), val)
|
|
31
|
+
} else if (t.isConditionalExpression(val) || t.isBinaryExpression(val)) {
|
|
32
|
+
if (t.isStringLiteral(acc)) {
|
|
33
|
+
return t.binaryExpression('+', t.stringLiteral(`${acc.value} `), val)
|
|
34
|
+
}
|
|
35
|
+
inner = t.binaryExpression('+', t.stringLiteral(' '), val)
|
|
36
|
+
} else if (t.isIdentifier(val) || t.isMemberExpression(val)) {
|
|
37
|
+
// identifiers and member expressions make for reasonable ternaries
|
|
38
|
+
inner = t.conditionalExpression(
|
|
39
|
+
val,
|
|
40
|
+
t.binaryExpression('+', t.stringLiteral(' '), val),
|
|
41
|
+
t.stringLiteral('')
|
|
42
|
+
)
|
|
43
|
+
} else {
|
|
44
|
+
if (t.isStringLiteral(acc)) {
|
|
45
|
+
return t.binaryExpression(
|
|
46
|
+
'+',
|
|
47
|
+
t.stringLiteral(`${acc.value} `),
|
|
48
|
+
t.logicalExpression('||', val, t.stringLiteral(''))
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
// use a logical expression for more complex prop values
|
|
52
|
+
inner = t.binaryExpression(
|
|
53
|
+
'+',
|
|
54
|
+
t.stringLiteral(' '),
|
|
55
|
+
t.logicalExpression('||', val, t.stringLiteral(''))
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return t.binaryExpression('+', acc, inner)
|
|
60
|
+
}, null)
|
|
61
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import vm from 'vm'
|
|
2
|
+
|
|
3
|
+
import generate from '@babel/generator'
|
|
4
|
+
import { NodePath } from '@babel/traverse'
|
|
5
|
+
import * as t from '@babel/types'
|
|
6
|
+
import type { TamaguiConfig } from '@tamagui/core'
|
|
7
|
+
import { createCSSVariable } from '@tamagui/core-node'
|
|
8
|
+
|
|
9
|
+
import { FAILED_EVAL } from '../constants'
|
|
10
|
+
import { evaluateAstNode } from './evaluateAstNode'
|
|
11
|
+
import { isValidThemeHook } from './extractHelpers'
|
|
12
|
+
|
|
13
|
+
export function createEvaluator({
|
|
14
|
+
tamaguiConfig,
|
|
15
|
+
staticNamespace,
|
|
16
|
+
sourcePath,
|
|
17
|
+
traversePath,
|
|
18
|
+
shouldPrintDebug,
|
|
19
|
+
}: {
|
|
20
|
+
tamaguiConfig: TamaguiConfig
|
|
21
|
+
staticNamespace: Record<string, any>
|
|
22
|
+
sourcePath: string
|
|
23
|
+
traversePath: NodePath<t.JSXElement>
|
|
24
|
+
shouldPrintDebug: boolean | 'verbose'
|
|
25
|
+
}) {
|
|
26
|
+
// called when evaluateAstNode encounters a dynamic-looking prop
|
|
27
|
+
const evalFn = (n: t.Node) => {
|
|
28
|
+
// themes
|
|
29
|
+
if (
|
|
30
|
+
t.isMemberExpression(n) &&
|
|
31
|
+
t.isIdentifier(n.property) &&
|
|
32
|
+
isValidThemeHook(traversePath, n, sourcePath)
|
|
33
|
+
) {
|
|
34
|
+
const key = n.property.name
|
|
35
|
+
if (shouldPrintDebug) {
|
|
36
|
+
console.log(' > found theme prop', key)
|
|
37
|
+
}
|
|
38
|
+
console.log('SHOULD FIND THEME (NESTED NOW)', key) // tamaguiConfig.themes)
|
|
39
|
+
// if (!themeKeys.has(key)) {
|
|
40
|
+
// throw new Error(` > accessing non-existent theme key: ${key}`)
|
|
41
|
+
// }
|
|
42
|
+
return createCSSVariable(key)
|
|
43
|
+
}
|
|
44
|
+
// variable
|
|
45
|
+
if (t.isIdentifier(n) && staticNamespace.hasOwnProperty(n.name)) {
|
|
46
|
+
return staticNamespace[n.name]
|
|
47
|
+
}
|
|
48
|
+
const evalContext = vm.createContext(staticNamespace)
|
|
49
|
+
const code = `(${generate(n as any).code})`
|
|
50
|
+
// if (shouldPrintDebug) {
|
|
51
|
+
// console.log('evaluating', { n, code, evalContext })
|
|
52
|
+
// }
|
|
53
|
+
return vm.runInContext(code, evalContext)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return (n: t.Node) => {
|
|
57
|
+
return evaluateAstNode(n, evalFn)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function createSafeEvaluator(attemptEval: (n: t.Node) => any) {
|
|
62
|
+
return (n: t.Node) => {
|
|
63
|
+
try {
|
|
64
|
+
return attemptEval(n)
|
|
65
|
+
} catch (err) {
|
|
66
|
+
return FAILED_EVAL
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|