I’m trying to use react-native-web, three.js and react-native-fiber in react-native.
So, I installed the libraries as follows:
- package.json
"dependencies": {
"@react-three/drei": "^9.108.4",
"@react-three/fiber": "^8.16.8",
"expo": "^51.0.0",
"expo-gl": "~14.0.2",
"nativewind": "^2.0.11",
"react": "18.2.0",
"react-dom": "^18.2.0",
"react-native": "0.74.3",
"react-native-web": "^0.19.12",
"three": "^0.166.1"
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@babel/preset-env": "^7.20.0",
"@babel/runtime": "^7.20.0",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.15",
"@react-native/babel-preset": "0.74.85",
"@react-native/eslint-config": "0.74.85",
"@react-native/metro-config": "0.74.85",
"@react-native/typescript-config": "0.74.85",
"@types/react": "^18.2.6",
"@types/react-dom": "^18.2.0",
"@types/react-test-renderer": "^18.0.0",
"babel-jest": "^29.6.3",
"babel-loader": "^9.1.3",
"babel-plugin-react-native-web": "^0.19.12",
"eslint": "^8.19.0",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.6.0",
"jest": "^29.6.3",
"prettier": "2.8.8",
"react-refresh": "^0.14.2",
"react-test-renderer": "18.2.0",
"tailwindcss": "^3.3.2",
"typescript": "5.0.4",
"url-loader": "^4.1.1",
"webpack": "^5.93.0",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^5.0.4"
},
"engines": {
"node": ">=18"
}
- webpack.config.js
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
const appDirectory = path.resolve(__dirname, '../');
const babelConfig = require('../babel.config');
const babelLoaderConfiguration = {
test: /.(tsx|jsx|ts|js)?$/,
exclude: [
{
and: [
// babel will exclude these from transpling
path.resolve(appDirectory, 'node_modules'),
path.resolve(appDirectory, 'ios'),
path.resolve(appDirectory, 'android'),
],
// whitelisted modules to be transpiled by babel
not: [],
},
],
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true,
// Presets and plugins imported from main babel.config.js in root dir
presets: babelConfig.presets,
plugins: ['react-native-web', ...(babelConfig.plugins || [])],
},
},
};
const imageLoaderConfiguration = {
test: /.(gif|jpe?g|png|svg)$/,
use: {
loader: 'url-loader',
options: {
name: '[name].[ext]',
esModule: false,
},
},
};
const fileLoaderConfiguration = {
test: /.(woff(2)?|ttf|eot|svg)(?v=d+.d+.d+)?$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/',
},
},
],
};
module.exports = argv => {
return {
entry: path.resolve(appDirectory, 'index'),
output: {
clean: true,
path: path.resolve(appDirectory, 'web/dist'),
filename: '[name].[chunkhash].js',
sourceMapFilename: '[name].[chunkhash].map',
chunkFilename: '[id].[chunkhash].js',
},
resolve: {
extensions: [
'.web.ts',
'.js',
'.ts',
'.web.tsx',
'.tsx',
'.android.tsx',
'.ios.tsx',
],
},
module: {
rules: [
babelLoaderConfiguration,
imageLoaderConfiguration,
fileLoaderConfiguration,
],
},
plugins: [
new ReactRefreshWebpackPlugin(),
new HtmlWebpackPlugin({
template: path.resolve(appDirectory, 'web/public/index.html'),
}),
new webpack.DefinePlugin({
__DEV__: argv.mode !== 'production' || true,
process: {env: {}},
}),
],
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\/]node_modules[\/]/,
name: 'vendor',
chunks: 'initial',
},
},
},
},
};
};
and i use like this
import {Canvas} from '@react-three/fiber';
import {Main} from '../scene/main/main.tsx';
import React from 'react';
export const Root = () => {
return (
<Canvas>
<Main />
</Canvas>
);
};
import React from 'react';
import {Box} from '@react-three/drei';
export const Main = () => {
return (
<>
<Box />
</>
);
};
i got a error like this in web, but mobile is good work
ReferenceError
require is not defined
Call Stack
eval
test/./node_modules/its-fine/dist/index.js:2:28
./node_modules/its-fine/dist/index.js
vendor.c80b9357ea343f9f5d9c.js:11160:1
options.factory
main.8c818fb1382ff2d60299.js:725:31
__webpack_require__
main.8c818fb1382ff2d60299.js:86:32
fn
main.8c818fb1382ff2d60299.js:365:21
eval
test/./node_modules/@react-three/fiber/dist/react-three-fiber.esm.js:1:4391
./node_modules/@react-three/fiber/dist/react-three-fiber.esm.js
vendor.c80b9357ea343f9f5d9c.js:2009:1
options.factory
main.8c818fb1382ff2d60299.js:725:31
__webpack_require__
main.8c818fb1382ff2d60299.js:86:32
fn
main.8c818fb1382ff2d60299.js:365:21
When I change webpack.config.js as shown below, it works on web, but on mobile, an error ‘
Compiling JS failed: 70216:3:export declaration must be at top level of module Buffer size 18015911 starts with:…..
‘ occurs.
What should I do, so that both mobile and web can work without problems?
I would appreciate it if you could give me some hints……
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
const appDirectory = path.resolve(__dirname, '../');
const babelConfig = require('../babel.config');
const babelLoaderConfiguration = {
test: /.(tsx|jsx|ts|js)?$/,
exclude: /node_modules/(?!react-native|nativewind)/, // 'react-native' 및 'nativewind' 모듈을 제외하지 않음
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true,
presets: babelConfig.presets,
plugins: ['react-native-web', ...(babelConfig.plugins || [])],
},
},
};
const imageLoaderConfiguration = {
test: /.(gif|jpe?g|png|svg)$/,
use: {
loader: 'url-loader',
options: {
name: '[name].[ext]',
esModule: false,
},
},
};
const fileLoaderConfiguration = {
test: /.(woff(2)?|ttf|eot|svg)(?v=d+.d+.d+)?$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/',
},
},
],
};
module.exports = argv => {
return {
entry: path.resolve(appDirectory, 'index.js'),
output: {
clean: true,
path: path.resolve(appDirectory, 'web/dist'),
filename: '[name].[chunkhash].js',
sourceMapFilename: '[name].[chunkhash].map',
chunkFilename: '[id].[chunkhash].js',
},
resolve: {
extensions: [
'.web.ts',
'.js',
'.ts',
'.web.tsx',
'.tsx',
'.android.tsx',
'.ios.tsx',
],
alias: {
'react-native$': 'react-native-web',
},
fallback: {
process: require.resolve('process/browser'),
},
},
module: {
rules: [
babelLoaderConfiguration,
imageLoaderConfiguration,
fileLoaderConfiguration,
],
},
plugins: [
new ReactRefreshWebpackPlugin(),
new HtmlWebpackPlugin({
template: path.resolve(appDirectory, 'web/public/index.html'),
}),
new webpack.DefinePlugin({
__DEV__: argv.mode !== 'production' || true,
process: {env: {}},
}),
new webpack.ProvidePlugin({
process: 'process/browser',
}),
],
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\/]node_modules[\/]/,
name: 'vendor',
chunks: 'initial',
},
},
},
},
devServer: {
static: path.resolve(appDirectory, 'web/public'),
compress: true,
hot: true,
open: true,
port: 8080,
},
};
};