facebook / metro

🚇 The JavaScript bundler for React Native
https://metrobundler.dev
MIT License
5.25k stars 627 forks source link

expo 49 not supporting i18n-js #1064

Closed albandum closed 1 year ago

albandum commented 1 year ago

Bug

What is the current behavior?

Upgrading to Expo SDK 49 makes i18n-js fail.

Android Bundling failed 1186ms
Unable to resolve "make-plural" from "node_modules/i18n-js/dist/import/Pluralization.js"

Basically the same thing that was mentionned here but the issue is closed

Please provide your exact Metro configuration and mention your Metro, node, yarn/npm version and operating system.

// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require('expo/metro-config');

module.exports = getDefaultConfig(__dirname);

Yarn v1.22.15 ProductName: macOS ProductVersion: 12.2.1

"dependencies": {
    "@expo/webpack-config": "^18.1.2",
    "@react-native-async-storage/async-storage": "1.18.2",
    "@react-navigation/native": "^6.1.6",
    "@react-navigation/native-stack": "^6.9.12",
    "expo": "^49.0.8",
    "expo-av": "~13.4.1",
    "expo-dev-client": "~2.4.8",
    "expo-device": "~5.4.0",
    "expo-file-system": "~15.4.3",
    "expo-keep-awake": "~12.3.0",
    "expo-linking": "~5.0.2",
    "expo-localization": "~14.3.0",
    "expo-network": "~5.4.0",
    "expo-notifications": "~0.20.1",
    "expo-secure-store": "~12.3.1",
    "expo-splash-screen": "~0.20.5",
    "expo-status-bar": "~1.6.0",
    "i18n-js": "^4.3.0",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-native": "0.72.4",
    "react-native-autosize-image": "^0.1.3",
    "react-native-flash-message": "^0.4.1",
    "react-native-gesture-handler": "~2.12.0",
    "react-native-get-random-values": "~1.9.0",
    "react-native-purchases": "^6.1.0",
    "react-native-reanimated": "~3.3.0",
    "react-native-reanimated-carousel": "^3.4.0",
    "react-native-safe-area-context": "4.6.3",
    "react-native-screens": "~3.22.0",
    "react-native-snap-carousel": "^3.9.1",
    "react-native-web": "~0.19.6",
    "uuid": "^9.0.0"
  },
kasaiee commented 1 year ago

I have the problem too

kasaiee commented 1 year ago

go to node_modules/i18n-js/dist/import/Pluralization.js and replace the code with the following code:

// import { en } from "make-plural";
export function useMakePlural({ pluralizer, includeZero = true, ordinal = false, }) {
    return function (_i18n, count) {
        return [
            includeZero && count === 0 ? "zero" : "",
            pluralizer(count, ordinal),
        ].filter(Boolean);
    };
}
export const defaultPluralizer = useMakePlural({
    pluralizer: (n: number | string, ord?: boolean) => "one" | "two" | "few" | "other",
    includeZero: true,
});
export class Pluralization {
    constructor(i18n) {
        this.i18n = i18n;
        this.registry = {};
        this.register("default", defaultPluralizer);
    }
    register(locale, pluralizer) {
        this.registry[locale] = pluralizer;
    }
    get(locale) {
        return (this.registry[locale] ||
            this.registry[this.i18n.locale] ||
            this.registry["default"]);
    }
}
//# sourceMappingURL=Pluralization.js.map

it silent the error temporarily

sebas-deedee commented 1 year ago

Any final solution on this?

robhogan commented 1 year ago

make-plural relies on support for resolving .mjs extensions, which Metro supports by default but it looks like Expo overrides.

@EvanBacon / @byCedric - .mjs (and .cjs) support is implemented through watcher.additionalExts (here's why), and it seems Expo overrides that to watch env files - with a fresh create-expo-app project I see Metro is being passed:

additionalExts: [ 'env.development.local', 'env.local', 'env.development', 'env' ],

This is overriding Metro's default, so that .mjs and .cjs files aren't crawled or watched: https://github.com/facebook/metro/blob/c2d7539dfc10aacb2f99fcc2f268a3b53e867a90/packages/metro-config/src/defaults/defaults.js#L58

Could Expo add to Metro's defaults instead?

robhogan commented 1 year ago

Workaround

Add config.watcher.additionalExts.push('mjs', 'cjs'); to your metro.config.js, ie:

// metro.config.js - see https://docs.expo.dev/guides/customizing-metro/#customizing
const { getDefaultConfig } = require('expo/metro-config');

const config = getDefaultConfig(__dirname);

config.watcher.additionalExts.push('mjs', 'cjs');

module.exports = config;

Closing as this issue is specific to Expo's configuration overrides (see above) and needs to be fixed there.

germanmedinasl commented 1 year ago

Following @robhogan 's tip, I replaced the code of metro-config.js: module.exports = require('@expo/metro-config'); to the code shown above. However I still get the same error. Should I place it in the ts file as well?