我们可以使用以下CLI命令创建一个新的React-Native项目:
react-native init AwesomeProject
我们可以对create a new ReactJS project使用npx:
npx create-react-app my-app
如果我想使用monorepo在React-Native和ReactJS之间共享代码怎么办? (除了UI渲染代码,还要共享它们)
选项:
1)创建一个新的React-Native项目并手动导入ReactJs文件和文件夹? (不确定如何操作,例如如何管理package.json和node_modules)
2)创建一个新的ReactJS项目并手动导入React-Native文件和文件夹? (不确定如何操作,例如如何管理package.json和node_modules)
3)使用3个仓库(一个用于react-native,一个用于reactjs web,一个用于共享代码),我们将分别在React-Native repo和ReactJs repo中将共享代码作为npm包导入。 -想要使用这种方法,但是由于客户端的限制,我无法上传任何npm软件包,甚至是私有软件包。
还有其他更好/更常见的建议吗?
更新:
根据this tutorial,我们可以创建自己的本地npm软件包。但是,如果软件包已更新(例如,如果我们更改了一些redux代码),则需要每次运行“ npm pack”和“ npm install ../package-name-0.0.0.tgz”。这将很耗时。这是更新本地软件包的正确方法吗?
答案 0 :(得分:0)
您应该结帐Learna。
从具有
的根文件夹开始/main (root directory)
/main/native (react-native project)
/main/state (possibly redux or mobx)
/main/web (create-react-app)
/main/VR (in case you want to consume state here)
现在,使用此结构,您可以维护一个monorepo,并使您的状态逻辑分离,并使用该状态逻辑的多个UI。
答案 1 :(得分:0)
您可以阅读有关Share React Native components to multiple projects的文章,我建议了3种在项目之间共享代码的方式。
我的案子几乎和你的一样。我有一个 React Native项目,一个 ReactJS Web应用,一个共享库和服务器代码,它们是 Google Cloud Firebase Functions < / em>用于nodejs。我使用了 Babel 和 Metro Bundler 的第三种方法。
我们可以为我们的Library目录创建一个git repo,然后让NPM直接从该repo安装它。可以,但是每次对Library进行更改后,我们都必须同步(提交/推送)git repos,这对于处理本地项目来说不太实际。有关更多详细信息,请检查此Q / A How to install an npm package from GitHub directly?。
Git子模块是在项目中共享代码的一种非常好的方法,它需要经常更改。我一直在寻找这种解决方案,当我看到使用这种方法的潜力时,我感到很兴奋,但是后来我以为我对git子模块不是很熟悉,当然也不想做任何事情并弄乱git repos和然后很难解决git问题。如果您熟悉使用git子模块,那么这就是方法。
我们可以使用module-resolver包来配置目录别名。我们通常为RN和ReactJS创建两个项目,并初始化firebase函数项目,而不必将Library初始化为nodejs项目:
目录结构:
MyProject-RNApp\
MyProject-ReactJSApp\
MyProject-Backend\
MyProject-Library\
每个使用的软件包,必须为将要使用的项目安装。例如,如果我们的库中有一个使用validator的通用函数,那么对于每个使用它的节点项目,我们都必须npm install
打包。
首先在.babelrc
内,我们为每个目录定义别名。在这里,我们可以添加RN应用程序根目录之外的目录:
{
"presets": ["module:metro-react-native-babel-preset"],
"env": {
"production": {
"plugins": ["transform-remove-console", "react-native-paper/babel"]
}
},
"plugins": [
"@babel/plugin-transform-runtime",
[
"module-resolver",
{
"root": ["./"],
"extensions": [".js", ".jsx", ".ts", ".tsx"],
"stripExtensions": [".js", ".jsx", ".ts", ".tsx"],
"alias": {
"@components": "./components",
"@screens": "./screens",
"@utils": "./utils",
"@data": "./data",
"@assets": "./assets",
"@app": "./",
"@myprojectlib": "../MyProject-Library",
"@myprojecti18n": "../MyProject-Library/i18n/rn",
"@myprojectbackend": "../MyProject-Backend/firebase/functions",
}
}
]
]
}
在这里,您必须小心路径,但是相对路径也可以正常工作。另外,在配置 RN 项目时,您不必为每个软件包添加别名,因为您将在下面使用 Metro Bundler 配置进行此操作。您只需要为 ReachJS 和 Backend Babel项目创建包别名:
{
"plugins": [
[
"module-resolver",
{
"root": "../",
"alias": {
"@app": "./resources/js/app",
"@graphics": "./resources/js/app/graphics",
"@styles": "./resources/js/app/styles",
"@components": "./resources/js/app/components",
"@screens": "./resources/js/app/screens",
"@panels": "./resources/js/app/panels",
"@stores": "./resources/js/app/stores",
"@utils": "./resources/js/app/utils",
"@dialogs": "./resources/js/app/dialogs",
"@data": "./resources/js/app/data",
"@myprojectlib": process.env.MYPROJECT_LIBRARY_PATH,
"@myprojectbrain": process.env.MYPROJECT_BRAIN_PATH,
"@myprojecti18n": `${process.env.MYPROJECT_LIBRARY_PATH}/i18n`,
// Add module paths for external myproject, else it wont work!
"react": "./node_modules/react",
"react-flag-icon-css": "./node_modules/react-flag-icon-css",
"react-hot-loader": "./node_modules/react-hot-loader",
"react-localization": "./node_modules/react-localization",
"prop-types": "./node_modules/prop-types",
"@material-ui/pickers": "./node_modules/@material-ui/pickers",
"@material-ui/core": "./node_modules/@material-ui/core",
"classnames": "./node_modules/classnames",
"qs": "./node_modules/qs",
"luxon": "./node_modules/luxon",
"@babel/runtime": "./node_modules/@babel/runtime",
}
}
]
]
}
然后针对 RN ,我们在项目根目录中创建一个metro.config.js
文件,以便配置RN Metro Bundler来解析每个目录和共享的npm软件包,如下所示:>
var path = require("path");
var config = {
projectRoot: path.resolve(__dirname),
watchFolders: [
// Let's add the root folder to the watcher
// for live reload purpose
path.resolve(__dirname, "../MyProject-Library"),
path.resolve(__dirname, "../MyProject-Backend")
],
resolver: {
sourceExts: ['js', 'jsx', 'ts', 'tsx'],
extraNodeModules: {
// Here I reference my upper folder
"myprojectlib": path.resolve(__dirname, "../MyProject-Library"),
"myprojectbackend": path.resolve(__dirname, "../MyProject-Backend/firebase/functions"),
// Important, those are all the dependencies
// asked by the "../MyProject-Library" but which
// are not present in the ROOT/node_modules
// So install it in your RN project and reference them here
// "expo": path.resolve(__dirname, "node_modules/expo"),
// "lodash.merge": path.resolve(__dirname, "node_modules/lodash.merge"),
"dinero.js": path.resolve(__dirname, "node_modules/dinero.js"),
"luxon": path.resolve(__dirname, "node_modules/luxon"),
"validator": path.resolve(__dirname, "node_modules/validator"),
"react-native-reanimated": path.resolve(__dirname, "node_modules/react-native-reanimated"),
"react-native-gesture-handler": path.resolve(__dirname, "node_modules/react-native-gesture-handler"),
"react-native-vector-icons": path.resolve(__dirname, "node_modules/react-native-vector-icons"),
"react-native-navigation": path.resolve(__dirname, "node_modules/react-native-navigation"),
"react-native-firebase": path.resolve(__dirname, "node_modules/react-native-firebase"),
"prop-types": path.resolve(__dirname, "node_modules/prop-types"),
"react-native": path.resolve(__dirname, "node_modules/react-native"),
"react": path.resolve(__dirname, "node_modules/react"),
"@babel/runtime": path.resolve(__dirname, "node_modules/@babel/runtime"),
"@jsassets": path.resolve(__dirname, "./jsassets"),
"@data": path.resolve(__dirname, "./data"),
"@components": path.resolve(__dirname, "./components"),
"@app": path.resolve(__dirname),
}
}
}
module.exports = config;
我们必须在resolver.extraNodeModules
中定义每个共享软件包和公共目录;我们甚至必须定义react
和react-native
,以便库中的共享代码能够具有组件并访问 React 和 RN 功能。
当我们运行yarn start
(或npm run start
)时,我们会看到Metro Bundler在所有fc中寻找JS文件。
+ RNApp, Library, Backend
:
答案 2 :(得分:0)
您可以有3个存储库(如消息中所述)。
示例:
<h1> Class Calculator</h1>
<p>Current grade: <input id="cg" min="1" max="120"
onchange="computeGrade()"></input></p>
<p>Desired grade: <input id="dg" min="1" max="120"
onchange="computeGrade()"></input></p>
<p>Final weight: <input id="wof" min="1" max="100"
onchange="computeGrade()"</input></p>
<p><button>Submit</button></p>
<h2 id="ng"></h2>
每个存储库将包含一个具有不同名称的react-native
react
common
文件(例如,基本目录名称= package.json
的名称)。
此后,您可以从package.json
项目中执行npm link ../common
,然后将https://github.com/javico2609/flutter-challenges/blob/master/lib/pages/code_examples/pdf_and_csv/pdf.dart链接到npm link项目中,将公共软件包链接到其他存储库中,您将能够像其他任何库一样使用它,这是开发新库的常用方法。
奖金,因为这是一个符号链接,所以对react-native
软件包所做的所有更改都将反映在react
上(可能需要手动刷新,因为react-native不会刷新{{1} })和common
项目。
每次运行
react-native
时都必须再次运行node_modules