Вот проблема, которую я не могу понять:)
Я создаю мультиплатформенное нативное + веб-приложение, все было хорошо. Но в какой-то момент мне пришлось добавить реагирующую навигацию v3, которая должна быть веб-совместимой.
По некоторым причинам некоторые реактивные require
терпят неудачу:
ERROR in ./node_modules/react-native/Libraries/Components/Touchable/Touchable.js
Module not found: Error: Can't resolve 'BoundingDimensions' in 'C:\Users\root\Desktop\Dev\GG\node_modules\react-native\Libraries\Components\Touchable'
@ ./node_modules/react-native/Libraries/Components/Touchable/Touchable.js 1:338-367
@ ./node_modules/react-native-gesture-handler/GestureHandler.js
@ ./node_modules/react-native-gesture-handler/index.js
@ ./node_modules/react-navigation-stack/dist/views/StackView/StackViewLayout.js
@ ./node_modules/react-navigation-stack/dist/index.js
@ ./node_modules/react-navigation/src/react-navigation.js
@ ./src/navigator/AppsNavigator.tsx
@ ./src/App.tsx
@ ./index.web.ts
@ multi (webpack)-dev-server/client?http://localhost:3001 (webpack)/hot/dev-server.js ./index.web.ts
То есть BoundingDimensions
и Touchable
находятся в одном каталоге, но const BoundingDimensions = require('BoundingDimensions');
, который находится в реагирующем пакете, завершается ошибкой. Почему?
Обратите внимание, что теперь я также сталкиваюсь с некоторыми предупреждениями:
WARNING in ./node_modules/React/cjs/react.development.js
There are multiple modules with names that only differ in casing.
This can lead to unexpected behavior when compiling on a filesystem with other case-semantic.
Use equal casing. Compare these module identifiers:
* C:\Users\root\Desktop\Dev\GG\node_modules\React\cjs\react.development.js
Used by 1 module(s), i. e.
C:\Users\root\Desktop\Dev\GG\node_modules\React\index.js
* C:\Users\root\Desktop\Dev\GG\node_modules\react\cjs\react.development.js
Used by 1 module(s), i. e.
C:\Users\root\Desktop\Dev\GG\node_modules\react\index.js
@ ./node_modules/React/cjs/react.development.js
@ ./node_modules/React/index.js
@ ./node_modules/react-native/Libraries/Components/Touchable/Touchable.js
@ ./node_modules/react-native-gesture-handler/GestureHandler.js
@ ./node_modules/react-native-gesture-handler/index.js
@ ./node_modules/react-navigation-stack/dist/views/StackView/StackViewLayout.js
@ ./node_modules/react-navigation-stack/dist/index.js
@ ./node_modules/react-navigation/src/react-navigation.js
@ ./src/navigator/AppsNavigator.tsx
@ ./src/App.tsx
@ ./index.web.ts
@ multi (webpack)-dev-server/client?http://localhost:3001 (webpack)/hot/dev-server.js ./index.web.ts
Контекст:
React + React-native-web + webpack project
Пакеты
"dependencies": {
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@clarketm/saga-monitor": "^1.0.8",
"@types/react": "^16.7.18",
"@types/react-navigation": "^3.0.1",
"@types/uuid": "^3.4.4",
"formik": "^1.4.1",
"lodash.throttle": "^4.1.1",
"native-base": "^2.8.0",
"react": "16.7.0",
"react-art": "16.7.0",
"react-dom": "16.7.0",
"react-native": "0.57.8",
"react-native-crypto": "^2.1.0",
"react-native-formik": "^1.7.0",
"react-native-gesture-handler": "^1.0.12",
"react-native-randombytes": "^3.0.0",
"react-native-web": "^0.9.13",
"react-navigation": "^3.0.9",
"react-redux": "^6.0.0",
"react-router-dom": "^4.3.1",
"redux": "^4.0.1",
"redux-logger": "^3.0.6",
"redux-saga": "^0.16.2",
"stream": "^0.0.2",
"url-loader": "^1.1.2",
"uuid": "^3.3.2",
"vm": "^0.1.0",
"yup": "^0.26.6"
},
"devDependencies": {
"@babel/core": "^7.2.2",
"@babel/plugin-proposal-class-properties": "^7.2.3",
"@babel/preset-env": "^7.2.3",
"@babel/preset-react": "^7.0.0",
"babel-jest": "23.6.0",
"babel-loader": "^8.0.4",
"babel-plugin-dynamic-import-node": "^2.2.0",
"babel-plugin-react-native-web": "^0.9.13",
"css-loader": "^2.1.0",
"file-loader": "^3.0.1",
"jest": "23.6.0",
"metro-react-native-babel-preset": "0.51.1",
"mini-css-extract-plugin": "^0.5.0",
"node-sass": "^4.11.0",
"react-test-renderer": "16.7.0",
"rn-nodeify": "^10.0.1",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"tslint": "^5.12.0",
"typescript": "^3.2.2",
"webpack": "^4.28.3",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.14"
}
`` `
Webpack
`` `
const path = require ('path');
const webpack = require ('webpack');
const appDirectory = path.resolve(__dirname, '../../');
const modulesDirectory = path.resolve(appDirectory, 'node_modules');
const babelLoaderConfiguration = {
test: /\.(js|jsx|tsx|ts)$/,
include: [
path.resolve(appDirectory, 'src'),
path.resolve(modulesDirectory, 'react-native-uncompiled'),
path.resolve(modulesDirectory, "native-base-shoutem-theme"),
path.resolve(modulesDirectory, "react-navigation"),
path.resolve(modulesDirectory, "react-native-easy-grid"),
path.resolve(modulesDirectory, "react-native-drawer"),
path.resolve(modulesDirectory, "react-native-safe-area-view"),
path.resolve(modulesDirectory, "react-native-vector-icons"),
path.resolve(modulesDirectory, "react-native-keyboard-aware-scroll-view"),
path.resolve(modulesDirectory, "react-native-web"),
path.resolve(modulesDirectory, "react-native-tab-view"),
path.resolve(modulesDirectory, "static-container"),
path.resolve(modulesDirectory, "@clarketm", "saga-monitor"),
path.resolve(modulesDirectory, "normalize-css-color"),
path.resolve(modulesDirectory, "react-navigation-stack"),
path.resolve(modulesDirectory, "react-native-gesture-handler"),
path.resolve(modulesDirectory, "react-native"),
path.resolve(modulesDirectory, "react-navigation-drawer"),
path.resolve(modulesDirectory, "@react-navigation"),
path.resolve(modulesDirectory, "@bam.tech", "react-native-root-siblings"),
path.resolve(modulesDirectory, "@bam.tech", "react-native-modalbox"),
path.resolve(modulesDirectory, "react-router-dom"),
],
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true,
presets: ["module:metro-react-native-babel-preset"],
plugins: ['react-native-web', "@babel/plugin-syntax-dynamic-import"],
}
}
};
// This is needed for webpack to import static images in JavaScript files.
const imageLoaderConfiguration = {
test: /\.(gif|jpe?g|png|svg)$/,
use: {
loader: 'url-loader',
options: {
name: '[name].[ext]'
}
}
};
const cssConfiguration = {
include: [
path.resolve(appDirectory, 'web', 'public'),
path.resolve(appDirectory, 'dist'),
],
test: /\.(scss|css)$/,
loader: 'style-loader!css-loader!sass-loader',
};
const fontConfiguration = {
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: './fonts/'
}
}]
};
module.exports = {
mode: 'development',
stats: "verbose",
entry: [
path.resolve(appDirectory, 'index.web.ts'),
],
output: {
filename: 'bundle.js',
path: path.resolve(appDirectory, 'web', 'public'),
publicPath: '/'
},
module: {
rules: [
babelLoaderConfiguration,
imageLoaderConfiguration,
cssConfiguration,
fontConfiguration,
{
// Many react-native libraries do not compile their ES6 JS.
test: /\.js$/,
include: /node_modules\/react-native-/,
// react-native-web is already compiled.
exclude: /node_modules\/react-native-web\//,
loader: 'babel-loader',
query: {
cacheDirectory: true
},
},
]
},
resolve: {
// This will only alias the exact import "react-native"
alias: {
// RN Web
'react-native$': 'react-native-web',
// For NativeBase (http://docs.nativebase.io/docs/GetStarted.html)
"react-native/Libraries/Renderer/shims/ReactNativePropRegistry": "react-native-web/dist/modules/ReactNativePropRegistry",
},
// If you're working on a multi-platform React Native app, web-specific
// module implementations should be written in files using the extension
// `.web.js`.
extensions: ['.web.js', '.web.ts', '.web.tsx', '.js', '.jsx', '.ts', '.tsx'],
},
devServer: {
contentBase: path.join(__dirname, "../public"),
compress: false,
port: 9000,
//host: "0.0.0.0"
}
}