React Native – babel.config.js别名无法看到当前工作目录外的文件。

huangapple go评论62阅读模式
英文:

React Native - babel.config.js alias not seeing files outside the current working directory

问题

Here's the translated content you requested:

所以,我的项目是一个 monorepo(单一仓库)。其中包含了用于 web 应用程序、移动应用程序等的文件夹。还有一个 common 文件夹,其中包含了所有可重用的组件和工具。

<repo-name>
├── app // 移动应用程序
│   ├── node_modules
│   ├── src
│   │   ├── views
│   │   │   ├── Homepage
│   │   │   │   └── index.tsx
│   │   └── App.tsx
│   ├── babel.config.js
│   ├── tsconfig.json
│   └── ...
├── common
│   ├── utils
│   │   └── format.ts
├── web
│   ├── app
│   │   ├── tsconfig.json
│   │   └── ...
│   ├── landing
│   │   ├── tsconfig.json
│   │   └── ...

App.tsx 大致具有以下内容:

import React from "react"
import Homepage from "views/Homepage"
import { someFunction } from "@common/utils/format"

export default class App extends React.Component<any, any> {
    render() {
        return <>
            <h1>{someFunction("kappa")}</h1>
            <Homepage />
        </>
    }
}

移动应用程序的 tsconfig.json 如下所示:

{
	"extends": "@tsconfig/react-native/tsconfig.json",
	"compilerOptions": {
		"baseUrl": ".",
		"experimentalDecorators": true,
		"useDefineForClassFields": true,
		"strictNullChecks": true,
		"noUnusedLocals": true,
		"noUnusedParameters": true,
		"paths": {
			"@common/*": [
				"../common/*",
			],
			"*": [
				"./src/*",
				"node_modules",
			],
		}
	}
}

babel.config.js 则是这样的:

module.exports = {
	presets: ['module:metro-react-native-babel-preset'],
	plugins: [
		[
			"@babel/plugin-transform-flow-strip-types",
			{ legacy: true },
		],
		[
			"@babel/plugin-proposal-decorators",
			{ legacy: true },
		],
		[
			"@babel/plugin-proposal-class-properties",
			{ "loose": false }
		],
		[
			'module-resolver',
			{
				root: ['./src'],
				extensions: ['.ios.js', '.android.js', '.js', '.ts', '.tsx', '.json'],
				alias: {
					"@common": "../common",
				}
			}
		]
	]
};

基本上,发生了什么情况。我为 common 文件夹的内容创建了别名,可以通过 @common/... 导入。此外,可以在不使用相对路径的情况下导入 src 文件夹中的所有内容。

这些别名在 tsconfig.jsonbabel.config.json 中都进行了配置。我使用的是 VSCode,在 @common 别名的自动完成方面运行良好。

但是在运行时(在 Metro CLI 中),我遇到了以下错误:

Error: 从 /home/<username>/projects/<project>/<repo-name>/app/src/App.tsx 无法解析模块 ../../common/utils/format:

这些文件均不存在:
  * ../common/utils/format(.native|.android.js|.native.js|.js|.android.jsx|.native.jsx|.jsx|.android.json|.native.json|.json|.android.ts|.native.ts|.ts|.android.tsx|.native.tsx)
  * ../common/utils/format/index(.native|.android.js|.native.js|.js|.android.jsx|.native.jsx|.jsx|.android.json|.native.json|.json|.android.ts|.native.ts|.ts|.android.tsx|.native.tsx)

如您所见,@common 的路径被完美解析,但出于某种原因,Babel 却看不到 format.ts 文件。

我做错了什么?是否有任何注意事项或解决方法?非常感谢您的帮助。我在这个问题上已经花了大约 4 小时,但没有找到有用的信息。提前感谢。

英文:

So, my project is monorepo. There are folders for web application, mobile application, etc. And there is also a common folder, where gathered all the reusable components and utils.

&lt;repo-name&gt;
├── app // mobile app
│   ├── node_modules
│   ├── src
│   │   ├── views
│   │   │   ├── Homepage
│   │   │   │   └── index.tsx
│   │   └── App.tsx
│   ├── babel.config.js
│   ├── tsconfig.json
│   └── ...
├── common
│   ├── utils
│   │   └── format.ts
├── web
│   ├── app
│   │   ├── tsconfig.json
│   │   └── ...
│   ├── landing
│   │   ├── tsconfig.json
│   │   └── ...

App.tsx has schematically the next content:

import React from &quot;react&quot;
import Homepage from &quot;views/Homepage&quot;
import { someFunction } from &quot;@common/utils/format&quot;

export default
class App
extends React.Component&lt;any, any&gt; {
    render() {
        return &lt;&gt;
            &lt;h1&gt;{someFunction(&quot;kappa&quot;)}&lt;/h1&gt;
            &lt;Homepage /&gt;
        &lt;&gt;
    }
}

Mobile app's tsconfig.json looks like this:

{
	&quot;extends&quot;: &quot;@tsconfig/react-native/tsconfig.json&quot;,
	&quot;compilerOptions&quot;: {
		&quot;baseUrl&quot;: &quot;.&quot;,
		&quot;experimentalDecorators&quot;: true,
		&quot;useDefineForClassFields&quot;: true,
		&quot;strictNullChecks&quot;: true,
		&quot;noUnusedLocals&quot;: true,
		&quot;noUnusedParameters&quot;: true,
		&quot;paths&quot;: {
			&quot;@common/*&quot;: [
				&quot;../common/*&quot;,
			],
			&quot;*&quot;: [
				&quot;./src/*&quot;,
				&quot;node_modules&quot;,
			],
		}
	},
}

and the babel.config.js is this:

module.exports = {
	presets: [&#39;module:metro-react-native-babel-preset&#39;],
	plugins: [
		[
			&quot;@babel/plugin-transform-flow-strip-types&quot;,
			{ legacy: true },
		],
		[
			&quot;@babel/plugin-proposal-decorators&quot;,
			{ legacy: true },
		],
		[
			&quot;@babel/plugin-proposal-class-properties&quot;,
			{ &quot;loose&quot;: false }
		],
		[
			&#39;module-resolver&#39;,
			{
				root: [&#39;./src&#39;],
				extensions: [&#39;.ios.js&#39;, &#39;.android.js&#39;, &#39;.js&#39;, &#39;.ts&#39;, &#39;.tsx&#39;, &#39;.json&#39;],
				alias: {
					&quot;@common&quot;: &quot;../common&quot;,
				}
			}
		]
	]
};

Basically, what's going on.
I've created alias for common folder content to be imported as @common/...
Also, all content from src folder can be imported without relative paths.

This aliases are configured in both tsconfig.json and babel.config.json. I'm using VSCode, and autocomplete for @common alias works flawlessly.

But in runtime (inside Metro CLI) I'm getting this error:

Error: Unable to resolve module ../../common/utils/format from /home/&lt;username&gt;/projects/&lt;project&gt;/&lt;repo-name&gt;/app/src/App.tsx: 

None of these files exist:
  * ../common/utils/format(.native|.android.js|.native.js|.js|.android.jsx|.native.jsx|.jsx|.android.json|.native.json|.json|.android.ts|.native.ts|.ts|.android.tsx|.native.tsx|.tsx)
  * ../common/utils/format/index(.native|.android.js|.native.js|.js|.android.jsx|.native.jsx|.jsx|.android.json|.native.json|.json|.android.ts|.native.ts|.ts|.android.tsx|.native.tsx|.tsx)

As you can see, path for @common is resolved perfectly, but for some reason babel does not see format.ts file.

What I'm doing wrong? Is there any caveats, any workarounds?
Any help appreciated. Spent abount 4 hours on this problem and found nothing useful.
Thanks in advance

答案1

得分: 1

Okay, so, basically, this is not a problem of the Babel.
Turns out that Metro does not know a thing about folders outside the project.

Well, all you need is to add watchFolders property to metro.config.js:

/**
 * Metro configuration for React Native
 * https://github.com/facebook/react-native
 *
 * @format
 */

const path = require("path")

module.exports = {
  transformer: {
    getTransformOptions: async () => ({
      transform: {
        experimentalImportSupport: false,
        inlineRequires: true,
      },
    }),
  },
  // here we should set folders outside of the project folder
  // to be able to import modules from 'em
  watchFolders: [
    path.resolve(__dirname + "/../common")
  ]
};

Two days searching and the solution is, as always, just 4 rows

The beautiful world of javascript bundlers.
That's all folks!
¯\_(ツ)_/¯

英文:

Okay, so, basically, this is not a problem of the Babel.
Turns out that Metro does not know a thing about folders outside the project.

Well, all you need is to add watchFolders property to metro.config.js:

/**
 * Metro configuration for React Native
 * https://github.com/facebook/react-native
 *
 * @format
 */

const path = require(&quot;path&quot;)

module.exports = {
  transformer: {
    getTransformOptions: async () =&gt; ({
      transform: {
        experimentalImportSupport: false,
        inlineRequires: true,
      },
    }),
  },
  // here we should set folders outside of the project folder
  // to be able to import modules from &#39;em
  watchFolders: [
    path.resolve(__dirname + &quot;/../common&quot;)
  ]
};

Two days searching and the solution is, as always, just 4 rows

The beautiful world of javascript bundlers.
That's all folks!
¯\_(ツ)_/¯

huangapple
  • 本文由 发表于 2023年5月11日 19:43:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76227269.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定