nativewind: v3: A never finished building

Describe the bug building stuck on Done copying assets when i use withNativewind(config)

To Reproduce Steps to reproduce the behavior:

run on xcode

Screenshots

image

Additional context

const {getDefaultConfig} = require('metro-config')
const withNativewind = require('nativewind/metro')

module.exports = (async () => {
  const {
    resolver: {sourceExts, assetExts},
  } = await getDefaultConfig()

  const config = {
    transformer: {
      getTransformOptions: async () => ({
        transform: {
          experimentalImportSupport: false,
          inlineRequires: true,
        },
      }),
      babelTransformerPath: require.resolve('react-native-svg-transformer'),
    },
    resolver: {
      assetExts: assetExts.filter(ext => ext !== 'svg'),
      sourceExts: [...sourceExts, 'svg'],
    },
  }

  // return withNativewind(config) // stuck ❌
  return config // build success ✅
})()

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 4
  • Comments: 26 (4 by maintainers)

Most upvoted comments

I got it to work in eas build. As pointed by @chenhb23 this issue is with node env variable. I have used patch-package to fix this line. Below are the steps

  1. Install patch-package and post-install yarn add patch-package postinstall-postinstall
  2. In package.json add this under scripts "postinstall": "patch-package"
  3. create patches folder in root of your app and paste attached file in the folder.

Now eas build works

nativewind+3.0.0-next.34.patch

This worked great, thank you! I hope this gets added to the library.

I got it to work in eas build. As pointed by @chenhb23 this issue is with node env variable. I have used patch-package to fix this line. Below are the steps

  1. Install patch-package and post-install yarn add patch-package postinstall-postinstall
  2. In package.json add this under scripts "postinstall": "patch-package"
  3. create patches folder in root of your app and paste attached file in the folder.

Now eas build works

nativewind+3.0.0-next.34.patch

I have investigated this problem in more detail.

It seems like expo/metro somehow explicitely wait till a spawned process is finished. And if nativewind starts tailwind in watchmode this never happens. I also tried to start it delayed by wrapping it with a setTimeout. But metro seems to also wait for all timeouts being finished till continueing.

Furthermore I discovered that the “getTransformOptions” method is sometimes called multiple times, so even if metro would not block, this method seems not to be ideal to hook into.

In General neither metro nor expo seem to have any kind of hook or middleware concept that would work for nativewinds purpose.

I guess it would be the easiest to keep the non watch mode inside the “getTransformOptions” and extract the watch mode into a cli, that one can put into a script inside the package.json to run alongside the expo cli.

I’m just coming back from break so I’ll look into it soon. It could very well be the same issue, just getting stuck on a different output. It does seem like EAS/Metro has changed how they spawn children processes (as seen above with the different env).

I got it to work in eas build. As pointed by @chenhb23 this issue is with node env variable. I have used patch-package to fix this line. Below are the steps

  1. Install patch-package and post-install yarn add patch-package postinstall-postinstall
  2. In package.json add this under scripts "postinstall": "patch-package"
  3. create patches folder in root of your app and paste attached file in the folder.

Now eas build works

nativewind+3.0.0-next.34.patch

This fixed my issues.

EAS Build was working fine with Nativewind v3 until I added expo-updates then the builds started timing out. Now things work again with this patch.

Thanks for the help with this!

Awesome, @anurag-alla, thanks for tracking this bug down.

Here is the code in question.

const isDevelopment = process.env.NODE_ENV !== "production";

The problem is EAS uses the NODE_ENV variable to determine the build environment (staging, beta, production, etc). But nativewind@next is using NODE_ENV !== ‘production’ to enable fast-refresh. Setting isDevelopment to false, enables non-production EAS building, but disables fast-refresh in development.

It cannot be assumed that EAS will only be used for production, but fast-refresh in development would be helpful.

A better solution, I think, is to check the process.env.CI variable and disable fast-refresh if run in CI. (EXPO EAS also sets the CI env variable for builds).

  const notCI = !(process.env.CI)
  if (isDevelopment && notCI) {

I am seeing the same issue with Nativewind v3 and Expo EAS. Unfortunately, @allpwrfulroot’s suggestion did not work for me with 3.0.0-854ccd0.0. I am using a monorepo very similar to expo-monorepo-example with the following metro config:

// Learn more https://docs.expo.dev/guides/monorepos
const { getDefaultConfig } = require('expo/metro-config');
const { FileStore } = require('metro-cache');
const path = require('path');
const withNativewind = require("nativewind/metro");

const projectRoot = __dirname;
const workspaceRoot = path.resolve(projectRoot, '../..');

const config = getDefaultConfig(projectRoot);

// #1 - Watch all files in the monorepo
config.watchFolders = [workspaceRoot];
// #3 - Force resolving nested modules to the folders below
config.resolver.disableHierarchicalLookup = true;
// #2 - Try resolving with project modules first, then workspace modules
config.resolver.nodeModulesPaths = [
  path.resolve(projectRoot, 'node_modules'),
  path.resolve(workspaceRoot, 'node_modules'),
];

// Remove all console logs in production...
// https://docs.expo.dev/guides/customizing-metro/
config.transformer.minifierConfig.compress.drop_console = true;

// Use turborepo to restore the cache when possible
config.cacheStores = [
  new FileStore({ root: path.join(projectRoot, 'node_modules', '.cache', 'metro') }),
];

module.exports = withNativewind(config);

I can replicate this issue locally using with the --local flag:

eas build --platform ios --local

Removing withNativewind from the metro.config.js builds successfully.