Closed crutchcorn closed 1 month ago
Actually I figure it out without need to change the file extension. This happens because react-native-vector-icons
contains jsx code (e.g. <Text>
) inside .js
file.
First, I need to add files with .web
to the extensions (the order of the item in the array actually matters):
const extensions = [
'.mjs',
'.web.tsx',
'.tsx',
'.web.ts',
'.ts',
'.web.jsx',
'.jsx',
'.web.js',
'.js',
'.css',
'.json',
];
Add these extensions to resolve:
export default defineConfig({
...
resolve: {
extensions,
...
Then inside defineConfig
, I added to optimizeDeps to resolve js files using jsx loader:
optimizeDeps: {
esbuildOptions: {
resolveExtensions: extensions,
jsx: "automatic",
loader: { ".js": "jsx" },
},
},
When I serve up the web app, I will get this error message:
MaterialCommunityIcon.tsx:49 Error: Dynamic require of "react-native-vector-icons/MaterialCommunityIcons" is not supported
So my web app's index.html, I need to add:
<style type="text/css">
@font-face {
font-family: 'MaterialCommunityIcons';
src: url('/MaterialCommunityIcons.ttf') format('truetype');
}
</style>
Now the serve command is working. However, the build command still does not work with the same error.
I created a rollup plugin:
const rollupPlugin = (matchers: RegExp[]) => ({
name: 'js-in-jsx',
load(id: string) {
if (
matchers.some((matcher) => matcher.test(id)) &&
id.endsWith('.js')
) {
const file = readFileSync(id, { encoding: 'utf-8' });
return esbuild.transformSync(file, { loader: 'jsx', jsx: 'automatic' });
}
},
});
Then add this plugin to the vite config:
build: {
rollupOptions: {
plugins: [rollupPlugin([/react-native-vector-icons/])],
},
},
Now build command should work.
Another issue I notice: In the web browser, I got this error:
NavigationContainer.tsx:29 Uncaught ReferenceError: global is not defined
In vite.config.ts, add:
define: {
global: "window",
},
The final vite.config.ts:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import * as esbuild from 'esbuild';
import { readFileSync } from 'fs';
const extensions = [
'.mjs',
'.web.tsx',
'.tsx',
'.web.ts',
'.ts',
'.web.jsx',
'.jsx',
'.web.js',
'.js',
'.css',
'.json',
];
const rollupPlugin = (matchers: RegExp[]) => ({
name: 'js-in-jsx',
load(id: string) {
if (matchers.some((matcher) => matcher.test(id)) && id.endsWith('.js')) {
const file = readFileSync(id, { encoding: 'utf-8' });
return esbuild.transformSync(file, { loader: 'jsx', jsx: 'automatic' });
}
},
});
export default defineConfig({
cacheDir: '../../node_modules/.vite/techy-jokes-web',
define: {
global: 'window',
},
resolve: {
extensions,
alias: {
'react-native': 'react-native-web',
},
},
build: {
rollupOptions: {
plugins: [rollupPlugin([/react-native-vector-icons/])],
},
},
server: {
port: 4200,
host: 'localhost',
},
preview: {
port: 4300,
host: 'localhost',
},
optimizeDeps: {
esbuildOptions: {
resolveExtensions: extensions,
jsx: 'automatic',
loader: { '.js': 'jsx' },
},
},
plugins: [react()],
test: {
globals: true,
cache: { dir: '../../node_modules/.vitest' },
environment: 'jsdom',
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
},
});
Dude I love you! thanks for this!
I'm not familiar with vite, is there anything we could do in our library to make this more seamless? Would simply renaming js to hsx solve the issue?
Indeed @johnf - I could even test any alpha releases against our production Vite setup and would be happy to make a PR to do so
Thanks a ton for the config, this was super helpful!
If anyone faces this same issue with expo vector icons (which is built on top of react-native-vector-icons), you can get the above config working with minimal changes:
build: {
commonjsOptions: { transformMixedEsModules: true },
rollupOptions: {
plugins: [
rollupPlugin([/react-native-vector-icons/, /@expo\/vector-icons/]),
],
},
},
Is your feature request related to a problem? Please describe. A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
I'm attempting to use this package with Vite to bundle a React Native Web project. On doing so, it's been quite a challenge to use the
.js
files with.jsx
syntax, as Vite likes the throw the following errors:Describe the solution you'd like A clear and concise description of what you want to happen.
While there might be a way to migrate around this, I've spent some time with it and haven't made much headway. The official Vite team themselves suggests moving
.js
files to.jsx
to side-step detection frustrations in doing this.Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered.
I could use
patch-package
, and likely may do this in the interim, but this wouldn't be much help in the long run.Additional context Add any other context or screenshots about the feature request here.
I'm happy to make a PR renaming files to
.jsx
and fixing any related packaging errors that might arise from this.