Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CONTEXT.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ Metro integration:
- `withUniwindConfig(config, uniwindConfig)` patches Metro graph support for uncached modules.
- Metro adds `css` as source extension and removes it from asset extensions.
- Metro transformer handles the configured CSS entry file specially.
- `experimental.optimizeClasslessComponents` (off by default) compiles classless native elements
to raw React Native components; styled or uncertain references keep existing wrappers.
- Metro transformer worker selection is lazy, cached per Expo/non-Expo config type, and follows Expo transformer paths or Expo-specific config markers.
- Native platform CSS transforms into a JS module that calls `Uniwind.__reinit(...)`.
- Web platform CSS transforms into CSS plus web runtime setup.
Expand Down
1 change: 1 addition & 0 deletions PR.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Litwo! Ojczyzno moja! ty jesteś jak zdrowie;
5 changes: 5 additions & 0 deletions packages/uniwind/build.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ export default defineBuildConfig({
input: './src/bundler/adapters/metro/transformer.ts',
name: 'metro/transformer',
},
{
builder: 'rollup',
input: './src/bundler/adapters/metro/babel-transformer.ts',
name: 'metro/babel-transformer',
},
{
builder: 'mkdist',
input: './src/bundler/adapters/metro',
Expand Down
1 change: 1 addition & 0 deletions packages/uniwind/jest.config.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export default {
],
moduleNameMapper: {
'^react-native$': '<rootDir>/../../node_modules/react-native',
'^yaml$': '<rootDir>/../../node_modules/yaml/dist/index.js',
'^@/(.*)$': '<rootDir>/src/$1',
},
}
62 changes: 62 additions & 0 deletions packages/uniwind/src/bundler/adapters/metro/babel-transformer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import type {
BabelTransformer,
BabelTransformerArgs,
} from 'metro-babel-transformer'
import { componentTransform } from './component-transform'
import {
TRANSFORM_COMPONENTS,
UPSTREAM_BABEL_TRANSFORMER,
} from './constants'

type BabelTransformerModule = BabelTransformer & {
default?: BabelTransformer
}

const transformerCache = new Map<string, BabelTransformer>()

const getTransformer = (transformerPath: string) => {
const cached = transformerCache.get(transformerPath)
if (cached) {
return cached
}

const module = require(transformerPath) as BabelTransformerModule
const transformer = typeof module.transform === 'function'
? module
: module.default

if (!transformer || typeof transformer.transform !== 'function') {
throw new Error(`Uniwind: Invalid upstream Babel transformer at ${transformerPath}`)
}

transformerCache.set(transformerPath, transformer)

return transformer
}

export const transform = (args: BabelTransformerArgs) => {
const customOptions = args.options.customTransformOptions ?? {}
const upstreamPath = customOptions[UPSTREAM_BABEL_TRANSFORMER]

if (typeof upstreamPath !== 'string') {
throw new Error('Uniwind: Missing upstream Babel transformer path')
}

const {
[TRANSFORM_COMPONENTS]: shouldTransform,
[UPSTREAM_BABEL_TRANSFORMER]: _upstreamPath,
...upstreamCustomOptions
} = customOptions
const transformer = getTransformer(upstreamPath)

return transformer.transform({
...args,
options: {
...args.options,
customTransformOptions: upstreamCustomOptions,
},
plugins: shouldTransform
? [...args.plugins ?? [], componentTransform]
: args.plugins,
})
}
Loading