-
-
Notifications
You must be signed in to change notification settings - Fork 518
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Module format in lib/module is using cjs not esm #1908
Comments
Hey! 👋 The issue doesn't seem to contain a minimal reproduction. Could you provide a snack or a link to a GitHub repository under your username that reproduces the problem? |
It doesn’t have a minimal repro, but it’s easy to see the commonjs and esm export are mixed inside lib/modules/index.native.js |
Hi @natew, thanks for reporting this issue! If you feel strong enough and you want to contribute a fix for that - please go ahead! We've already got this in a roadmap, but any help is appreciated 🙏 |
This is an issue I personally feel strongly about. Unfortunately I probably can't contribute a fix as I'm just a lowly web dev (I'm building on Firstly, I came across this tool: it appears to be a great reference for all the things that probably need to be updated in order to achieve semantically correct CJS/ESM exports: https://publint.dev/react-native-screens@3.27.0 Regarding the issue Nate raised here, I think he's primarily referring to the use of CJS The first image below shows some imports from The second screenshot below now shows the CommonJS build; as we can see, this block of imports is identical to the ESM module file. As I understand it, this is problematic because ESM generally doesn't support dynamic imports like they're being used here (this would break static analysis tools—treeshaking bundlers can't accurately detect which files should be included in the output of the final application code consuming Now, something I've noticed is many of the major RN libraries (i.e. this definitely isn't specific to I think this poses a long-term issue with modern JS looking to be trending towards isomorphic development (e.g. React Server Components). And the main value proposition of ESM is arguably to provide a unified standard adopted by both server and client, and Vite is an ESM-first bundler which is becoming the de facto choice for most new JS projects today. So, why should RN libraries care? Because there may now be an upcoming generation of developers who want to use RN in different environments (e.g. https://stereobooster.com/posts/react-native-web-with-vite). However, its ecosystem is so tightly coupled to only working with Metro & Babel. Thus using other bundlers is so difficult it may as well be impossible. This problem is compounded by RN's main libs essential for scaffolding basic functionality (e.g. navigation, views) being heavily dependent on one another. If a dev can't get one of these dependencies working in an app, then it's likely none of the others can be integrated either. In summary: if my reasoning above is correct, then this is a big shame... because there's so much potential innovation that will never be realised. 😢 |
Hi @natew @jkhaui! I've managed to remove CJS files while bundling the project, resulting in building only ESM files. I believe this should fix this issue, but I need your assistance 🕵️ "react-native-screens": "software-mansion/react-native-screens#@tboba/remove-mixed-cjs" Let me know what do you think about it. |
Hi @natew @jkhaui, right now I'm trying to create an example with react-native-web and vite (to test changes from PR #1982) but unfortunately I'm stuck with couple of errors. Because of how react-native-screens is made, Vite is complaining about
As you can see, this error refers to the React Native internals, so probably changing this file manually from My vite.config.js configuration:import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
// https://tamagui.dev/docs/intro/installation
const extensions = [
".web.tsx",
".tsx",
".web.ts",
".ts",
".web.jsx",
".jsx",
".web.js",
".js",
".css",
".json",
".mjs",
];
const development = process.env.NODE_ENV === "development";
// https://vitejs.dev/config/
export default defineConfig({
clearScreen: true,
plugins: [react()],
define: {
// https://github.com/bevacqua/dragula/issues/602#issuecomment-1296313369
global: "window",
__DEV__: JSON.stringify(development),
// https://tamagui.dev/docs/intro/installation
DEV: JSON.stringify(development),
"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV),
},
resolve: {
extensions: extensions,
alias: [
{
find: /^react-native$/,
replacement: "react-native-web",
}
]
},
optimizeDeps: {
exclude: ["react-native"],
esbuildOptions: {
resolveExtensions: extensions,
// https://github.com/vitejs/vite-plugin-react/issues/192#issuecomment-1627384670
jsx: "automatic",
// need either this or the plugin below
loader: { ".js": "jsx" },
// plugins: [
// esbuildFlowPlugin(/\.(flow|jsx?)$/, (path) =>
// /\.jsx$/.test(path) ? "jsx" : "jsx"
// ),
// ],
},
},
}); |
Small update from me: I've managed to run the example app with two screens in a navigator, but with use of |
## Description Users are reporting that on Vite they cannot build their project with react-native-screens because of the mixed CJS/ESM files that are being created while building a bundle (you can see [here](https://publint.dev/react-native-screens@3.27.0) that some package managers reports errors about mixed CJS/ESM files). To reduce that behavior I've decided to remove CJS completely while bundling the project, resulting in building only ESM files. Unfortunately because of that I had to remove optional requiring process inside the index.native.tsx file, but this shouldn't have a large impact while using rn-screens. I also decided to move some parts of the screens implementation to separate files - this should improve readability, better understanding of code for newcomers and should improve developer experience overall. Having only imports and exports in index files is also a good practice - this was my main reason why I've planned to do that. Closes #1908 - I'll try to ensure that this will fix Vite for sure 👍 ## Changes - Disable bundling CJS files from react-native-screens - Refactorize index.native.tsx files to separate files ## Test code and steps to reproduce First, try to bundle the project - you can see that inside `lib` there shouldn't be `common` directory with the CJS files. Then, try to run FabricTestExample with a couple of tests. Application should work properly as usual. ## Developer notes There are some points that I stumbled upon and I need to mention here. - I've managed to move all of the native components from class to function components, **except**: - **Screen:** Unfortunately we need to stay with class components there, as for now we would like to keep behavior of using `setNativeProps` for a screen (does anybody do that? Or is react-native calling this method for a screen wherever? There's a field for a discussion). - **SearchBar:** Because of managing ref's state and dropping it down to the methods responsible for commands I was also unable to convert this to functional component. - I tried to also refactor index.tsx file, but I see no reason to do this. For now I'm keeping it as it is (with only a slight changes to this file): - Because of a conflict of naming between SearchBarCommands (from types.tsx) and SearchBarCommands as a native component -> it's not that easy to fix, so I suggest fixing this in a future (might be also a good first issue). - I also tried to move `index.native.tsx` to `index.tsx` and to move `index.tsx` to `index.web.tsx`, but because of a conflict I described above and because I don't see the point of rendering conditionally native components depending if `Platform.OS !== 'web'` (and rendering a `View` if Platform.OS is web) I'm keeping the current naming. - Let me know what do you think about the refactor of index.native.tsx! This change is a **Proof of concept** and I codenamed it as a second stage of this PR, so we might give it a try, but I'm all ears about your opinion - IMO it is worth merging . ## Checklist - [X] Ensured that nothing changed while refactoring index.native.tsx - [X] Ensured that CI passes
…mansion#1982) ## Description Users are reporting that on Vite they cannot build their project with react-native-screens because of the mixed CJS/ESM files that are being created while building a bundle (you can see [here](https://publint.dev/react-native-screens@3.27.0) that some package managers reports errors about mixed CJS/ESM files). To reduce that behavior I've decided to remove CJS completely while bundling the project, resulting in building only ESM files. Unfortunately because of that I had to remove optional requiring process inside the index.native.tsx file, but this shouldn't have a large impact while using rn-screens. I also decided to move some parts of the screens implementation to separate files - this should improve readability, better understanding of code for newcomers and should improve developer experience overall. Having only imports and exports in index files is also a good practice - this was my main reason why I've planned to do that. Closes software-mansion#1908 - I'll try to ensure that this will fix Vite for sure 👍 ## Changes - Disable bundling CJS files from react-native-screens - Refactorize index.native.tsx files to separate files ## Test code and steps to reproduce First, try to bundle the project - you can see that inside `lib` there shouldn't be `common` directory with the CJS files. Then, try to run FabricTestExample with a couple of tests. Application should work properly as usual. ## Developer notes There are some points that I stumbled upon and I need to mention here. - I've managed to move all of the native components from class to function components, **except**: - **Screen:** Unfortunately we need to stay with class components there, as for now we would like to keep behavior of using `setNativeProps` for a screen (does anybody do that? Or is react-native calling this method for a screen wherever? There's a field for a discussion). - **SearchBar:** Because of managing ref's state and dropping it down to the methods responsible for commands I was also unable to convert this to functional component. - I tried to also refactor index.tsx file, but I see no reason to do this. For now I'm keeping it as it is (with only a slight changes to this file): - Because of a conflict of naming between SearchBarCommands (from types.tsx) and SearchBarCommands as a native component -> it's not that easy to fix, so I suggest fixing this in a future (might be also a good first issue). - I also tried to move `index.native.tsx` to `index.tsx` and to move `index.tsx` to `index.web.tsx`, but because of a conflict I described above and because I don't see the point of rendering conditionally native components depending if `Platform.OS !== 'web'` (and rendering a `View` if Platform.OS is web) I'm keeping the current naming. - Let me know what do you think about the refactor of index.native.tsx! This change is a **Proof of concept** and I codenamed it as a second stage of this PR, so we might give it a try, but I'm all ears about your opinion - IMO it is worth merging . ## Checklist - [X] Ensured that nothing changed while refactoring index.native.tsx - [X] Ensured that CI passes
Description
This is causing vite to blow up, and it's really hard to fix without patching the package. I can help contribute a fix just want to get confirmation this is ok to change.
Steps to reproduce
transformMixedEsModules
git clone git@github.com:tamagui/tamagui.git
yarn
yarn tamastack
Snack or a link to a repository
https://github.com/tamagui/tamagui
Screens version
3.22.1
React Native version
0.72.0
Platforms
iOS
JavaScript runtime
None
Workflow
None
Architecture
None
Build type
None
Device
None
Device model
No response
Acknowledgements
Yes
The text was updated successfully, but these errors were encountered: