So I've got a monorepo I am trying to use based on this one:
https://github.com/GeekyAnts/nativebase-templates/tree/master/solito-universal-app-template-nativebase-typescript
This repo has 4 separate places where there is a package.json (and theoretically a tsconfig.json) - the app is partially TypeScript and partially Javascript (re-writing it gradually in TypeScript as time goes along)
Basically the directory structure looks like this:
/ - root directory
/apps/expo - expo-related packages, configurations, functions, etc
/apps/next - next-related packages, configuration, functions, etc
/packages/app/ - general business logic, code, pages, etc
No matter what I am trying to do or where I am trying to setup the routing, it isn't working.
Inside my tsconfig.json in my root folder, I have this (I have also tried putting it in the individual tsconfig.json files of the individual folders):
"paths": {
"app/*": ["./packages/app/*"],
"components/*": ["./packages/app/components"],
"config/*": ["./packages/app/config"],
"controllers/*": ["./packages/app/controllers"],
"pages/*": ["./packages/app/pages"],
"reducers/*": ["./packages/app/redux"],
"resources/*": ["./packages/app/resources"],
"revenuecat/*": ["./packages/app/revenuecat"],
"routing/*": ["./packages/app/routing"],
"utils/*": ["./packages/app/utils"],
"interfaces/*": ["./packages/app/interfaces"],
"root/*": ["./*"]
}
But none of these paths are recognized in my Next app.
I've tried putting in the babel.config.js of the Expo folder inside my plugins:
[
'module-resolver',
{
root: '../../packages',
alias: {
app: '../../packages/app',
components: '../../packages/app/components',
config: '../../packages/app/config',
controllers: '../../packages/app/controllers',
pages: '../../packages/app/pages',
reducers: '../../packages/app/redux',
resources: '../../packages/app/resources',
revenuecat: '../../packages/app/revenuecat',
routing: '../../packages/app/routing',
utils: '../../packages/app/utils',
interfaces: '../../packages/app/interfaces',
},
},
]
I've tried putting them in the .babelrc of the Next folder, also in my plugins:
[
"module-resolver",
{
"root": "../../packages",
"alias": {
"app/*": "../../packages/app",
"components": "../../packages/app/components",
"config": "../../packages/app/config",
"controllers": "../../packages/app/controllers",
"pages": "../../packages/app/pages",
"reducers": "../../packages/app/redux",
"resources": "../../packages/app/resources",
"revenuecat": "../../packages/app/revenuecat",
"routing": "../../packages/app/routing",
"utils": "../../packages/app/utils",
"interfaces": "../../packages/app/interfaces"
}
}
]
The code I am trying to run is my _app.js which calls my Footer file in my /packages/app/components/main folder. The _app.js works fine and it gets to my Footer.web.js file, but then I get:
error - ../../packages/app/components/main/Footer.web.js:4:0
Module not found: Can't resolve 'components/main/AppButtons'
2 | import { FontAwesome } from '@expo/vector-icons';
3 | import moment from 'moment';
> 4 | import AppButtonGroup from 'components/main/AppButtons';
5 | import {
6 | Row,
7 | Column,
Now Appbuttons.tsx is in the same folder as Footer.web.js
My guess is that I need another .babelrc file for my /packages/app folder? Or is it another error?
My workspaces are set like this in my root package.json:
"workspaces": [
"apps/*",
"packages/*"
],
What is causing this to not work? Why is my pathing not working in my /packages/app folder?
tsconfig.json, also add "baseURL": "./".{
"compilerOptions": {
+ "baseUrl": "./",
"strictNullChecks": true,
"noUncheckedIndexedAccess": true,
"paths": {
"app/*": ["./packages/app/*"],
+ "components/*": ["./packages/app/components/*"],
+ "config/*": ["./packages/app/config"],
// ...
next, install tsconfig-paths-webpack-plugin, go to apps/next/next.config.js and apply this plugin:const path = require('node:path');
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
// ...
module.exports = withNativebase({
// ...
nextConfig: {
webpack: (config, options) => {
// ...
config.resolve.plugins = [
...config.resolve.plugins,
new TsconfigPathsPlugin({
// Use the root `tsconfig.json`!
configFile: path.resolve(__dirname, '../../tsconfig.json'),
}),
]
return config
},
expo, go to apps/expo/babel.config.js:const path = require('node:path');
// ...
plugins: [
'react-native-reanimated/plugin',
[
'module-resolver',
{
root: path.resolve(__dirname, '../../'),
alias: {
app: './packages/app',
components: './packages/app/components',
// ...
},
},
]
]
First of all, let's me spit it out, I personally would've just use "app/components/*" as alias, so to avoid this config madness. But since you asked, here's the answer. See above for the solution, and below is some nerdy explanation on technical details. Skip if you don't care.
app/* pseudo-aliasWithout above config, only app/* alias works. But the reason's kinda special: this is NOT a real (in bundle tool's term) alias. It's in fact a real filesystem symlink <root>/node_modules/app -> <root>/packages/app.
This symlink is created by yarn/npm's workspace mechanism. Because it lives in <root>/node_modules, the alias-ish app/* path is actually resolved as if it's a real npm package.
Now if you want to add your own real alias, you'll have to wrestle with build tools.
The template you use has two tooling setup: next for web, expo for native. You need to address them separately.
In this case, tsconfig.json -> compilerOptions.paths is mainly for IDE hint (e.g. vscode jump to definition). By default it's not used by either tools. So you still need to manually config alias via plugins like I've shown in solution section.
So yeah, 3 configs for 3 tools, madness.
Another solution is to leverage the workspace mechanism to create pseudo-alias, like in the case of app/*. For example, if you want components/* as "alias". You need to:
<root>/packages/components/package.json and give it a "name": "components".A lil twist: if you use
"name": "duck"for whatever reason, your pseudo-alias will becomeduck/*, i.e., folder name does NOT matter. Only package name matters.
cd back to project root dir, and simply run yarn, you should now see a symlink at <root>/node_modules/components.
(optional step) You are supposed to add into "dependencies": { "components": "*" } in other workspace package's package.json (e.g., apps/next/package.json) if you want to use this components/* "alias", because it's in fact is another package named "components" that you depend on. It's a good practice to add dep package into "dependencies" field.
Quite laborious too, I know. But still an option.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With