如何在Nx项目中实现React与React Native共享资源
Nx架构下React与React Native共享资源方案
核心问题说明
你之前在project.json中配置的"assets": { "glob": "**/*", "input": "libs/assets/src/lib/", "output": "/assets/" }仅适配Web端(React),React Native的资源处理逻辑与Web完全不同,直接照搬无法让RN识别共享库中的图片。
可行实现步骤
1. 调整shared-assets库的结构与配置
- 在
libs/shared-assets/src下新建assets目录,统一存放所有共享图片(例如logo.png) - 修改该库的
project.json,添加Web与RN的差异化配置:"targets": { "build": { "executor": "@nx/js:tsc", "options": { "outputPath": "dist/libs/shared-assets", "main": "libs/shared-assets/src/index.ts", "tsConfig": "libs/shared-assets/tsconfig.lib.json", "assets": [ // Web端资源拷贝规则 { "glob": "**/*", "input": "libs/shared-assets/src/assets", "output": "./assets" } ] } }, // 新增RN专用的资源拷贝命令 "copy-assets-to-rn": { "executor": "@nx/workspace:run-commands", "options": { "command": "cp -r libs/shared-assets/src/assets apps/mobile/src/assets/shared" } } } - 在
libs/shared-assets/src/index.ts中导出适配双端的图片路径:// Web端使用打包后的资源路径 export const sharedAssets = { logo: '/assets/logo.png' }; // RN端使用本地资源引用(资源将拷贝到RN项目目录) export const sharedAssetsRN = { logo: require('./assets/logo.png') };
2. 配置React Web应用
- 在Web应用的
project.json中,确保构建时引入共享库的资源:"targets": { "build": { "options": { "assets": [ // 原有Web本地资源 "apps/web/src/favicon.ico", "apps/web/src/assets", // 引入共享库的打包后资源 { "glob": "**/*", "input": "dist/libs/shared-assets/assets", "output": "/assets" } ] } } } - 在React组件中直接导入使用:
import { sharedAssets } from '@your-workspace/shared-assets'; function Header() { return <img src={sharedAssets.logo} alt="Logo" />; }
3. 配置React Native应用
- 在RN应用的
project.json中,将资源拷贝命令加入启动/构建流程:"targets": { "build": { "dependsOn": ["shared-assets:copy-assets-to-rn"] }, "start": { "dependsOn": ["shared-assets:copy-assets-to-rn"] } } - 在RN组件中导入使用:
import { Image } from 'react-native'; import { sharedAssetsRN } from '@your-workspace/shared-assets'; function Header() { return <Image source={sharedAssetsRN.logo} style={{ width: 100, height: 100 }} />; }
4. 可选优化方案
- 用Nx官方的
@nx/react-native:assets执行器替代手动拷贝命令,更贴合Nx生态:"copy-assets-to-rn": { "executor": "@nx/react-native:assets", "options": { "assets": ["libs/shared-assets/src/assets"], "projectRoot": "apps/mobile" } } - 若不想拷贝资源,可配置
babel-plugin-module-resolver路径别名,并修改metro.config.js监听共享库目录:// metro.config.js module.exports = { watchFolders: [require('path').resolve(__dirname, '../../libs/shared-assets')] };
内容的提问来源于stack exchange,提问作者Blaque_Mani
相关产品推荐
相关产品推荐

