[英]Babel-node can't process flowtype files imported in Typescript file?
I got, it seems, an odd situation where I can't find an answer on the Interwebs.我遇到了一个奇怪的情况,我在互联网上找不到答案。 In those case, I think I'm doing something incorrectly or not in a standard way.
在这种情况下,我认为我在以标准方式做错或不正确的事情。
My Problem is running TypeORM CLI to generate or even run migration locally for manual testing.我的问题是运行 TypeORM CLI 以在本地生成甚至运行迁移以进行手动测试。
Per TypeORM docs regarding entity files in Typescript , I have to run ts-node
somehow in order to make it work.根据有关 Typescript 中实体文件的 TypeORM 文档,我必须以某种方式运行
ts-node
才能使其工作。 My problem seems to be that in my entities, I have some import of modules written in Flow , like react-native-fs
or react-native-device-info
.我的问题似乎是在我的实体中,我导入了一些用 Flow 编写的模块,例如
react-native-fs
或react-native-device-info
。
$ yarn run typeorm migration:run
yarn run v1.22.17
warning ../package.json: No license field
$ node --require ts-node/register ./node_modules/typeorm/cli.js migration:run
Error during migration run:
/path/to/app/node_modules/react-native-fs/FS.common.js:30
var normalizeFilePath = (path: string) => (path.startsWith('file://') ? path.slice(7) : path);
^
SyntaxError: Unexpected token ':'
at Object.compileFunction (node:vm:352:18)
at wrapSafe (node:internal/modules/cjs/loader:1025:15)
at Module._compile (node:internal/modules/cjs/loader:1059:27)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1147:10)
at Module.load (node:internal/modules/cjs/loader:975:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:999:19)
at require (node:internal/modules/cjs/helpers:102:18)
at Object.<anonymous> (/path/to/app/src/entities/Lists/ListAttachment.ts:2:1)
at Module._compile (node:internal/modules/cjs/loader:1095:14)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
OK, so.好的,所以。 My Entity written in Typescript (
ListAttachment.ts
) has an import * as RNFS from 'react-native-fs';
我用 Typescript (
ListAttachment.ts
) 编写的实体有一个import * as RNFS from 'react-native-fs';
. . This lib is written in Flow .
这个库是用 Flow 编写的。 As I understand,
ts-node
will simply transpile Typescript to Javascript, so when it encounters a .js
file, it can't interpret the // @flow
annotation and tries to interpret it as plain JS.据我了解,
ts-node
只会将 Typescript 转换为 Javascript,因此当它遇到.js
文件时,它无法解释// @flow
注释并尝试将其解释为普通的 JS。 Thus the failure.于是失败。
Ok, so.好的,所以。 My thought would be to use Babel to handle both languages, but the problem is the same.
我的想法是使用 Babel 来处理两种语言,但问题是一样的。 As I understand, Babel will use the transpiler based on the file extension.
据我了解,Babel 将使用基于文件扩展名的转译器。 So if my main file is Typescript, it will not switch to another transpiler (the Flow one) if an import is in Flow.
因此,如果我的主文件是 Typescript,那么如果导入在 Flow 中,它就不会切换到另一个转译器(Flow 转译器)。
$ ./node_modules/.bin/babel-node --extensions ".flow,.js,.ts" ./node_modules/typeorm/cli.js migration:run
Error during migration run:
/path/to/app/node_modules/react-native-fs/FS.common.js:30
var normalizeFilePath = (path: string) => (path.startsWith('file://') ? path.slice(7) : path);
^
SyntaxError: Unexpected token ':'
at compileFunction (<anonymous>)
at Object.compileFunction (node:vm:352:18)
at wrapSafe (node:internal/modules/cjs/loader:1025:15)
at Module._compile (node:internal/modules/cjs/loader:1059:27)
at Module._compile (/path/to/app/node_modules/pirates/lib/index.js:99:24)
at Module._extensions..js (node:internal/modules/cjs/loader:1147:10)
at Object.newLoader [as .js] (/path/to/app/node_modules/pirates/lib/index.js:104:7)
at Module.load (node:internal/modules/cjs/loader:975:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:999:19)
But how can React-Native's Metro handle those mixed imports?但是 React-Native 的 Metro 如何处理这些混合导入呢?
Should I remove any external import from my entities?我应该从我的实体中删除任何外部导入吗? (Best Practice?)
(最佳实践?)
Am I doing it wrong?我做错了吗? (certainly :D)
(当然:D)
Thank you fellow developers 🙏谢谢各位开发者🙏
babel.config.js babel.config.js
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: [['@babel/plugin-proposal-decorators', { legacy: true }]],
};
tsconfig.json配置文件
{
"compilerOptions": {
"baseUrl": ".",
"paths": { "*": ["types/*"] },
/* Basic Options */
"target": "esnext", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"jsx": "react-native", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
"noEmit": true, /* Do not emit outputs. */
/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
"strictNullChecks": true, /* Enable strict null checks. */
/* Module Resolution Options */
"moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
"allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
/* Experimental Options */
"experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
"emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
"skipLibCheck": true
},
"exclude": [
"node_modules",
],
}
.flowconfig .flowconfig
[ignore]
; We fork some components by platform
.*/*[.]android.js
; Ignore templates for 'react-native init'
<PROJECT_ROOT>/template/.*
; Ignore the Dangerfile
<PROJECT_ROOT>/bots/dangerfile.js
; Ignore "BUCK" generated dirs
<PROJECT_ROOT>/\.buckd/
; These should not be required directly
; require from fbjs/lib instead: require('fbjs/lib/warning')
.*/node_modules/warning/.*
; Flow doesn't support platforms
.*/Libraries/Utilities/LoadingView.js
[untyped]
.*/node_modules/@react-native-community/cli/.*/.*
[include]
[declarations]
.*/node_modules/.*
[libs]
interface.js
flow/
[options]
emoji=true
esproposal.optional_chaining=enable
esproposal.nullish_coalescing=enable
exact_by_default=true
module.file_ext=.js
module.file_ext=.json
module.file_ext=.ios.js
munge_underscores=true
module.name_mapper='^react-native$' -> '<PROJECT_ROOT>/index.js'
module.name_mapper='^react-native/\(.*\)$' -> '<PROJECT_ROOT>/\1'
module.name_mapper='^@?[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '<PROJECT_ROOT>/Libraries/Image/RelativeImageStub'
suppress_type=$FlowIssue
suppress_type=$FlowFixMe
suppress_type=$FlowFixMeProps
suppress_type=$FlowFixMeState
suppress_type=$FlowFixMeEmpty
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)?:? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
experimental.well_formed_exports=true
experimental.types_first=true
experimental.abstract_locations=true
[lints]
sketchy-null-number=warn
sketchy-null-mixed=warn
sketchy-number=warn
untyped-type-import=warn
nonstrict-import=warn
deprecated-type=warn
unsafe-getters-setters=warn
inexact-spread=warn
unnecessary-invariant=warn
signature-verification-failure=warn
deprecated-utility=error
[strict]
deprecated-type
nonstrict-import
sketchy-null
unclear-type
unsafe-getters-setters
untyped-import
untyped-type-import
[version]
^0.113.0
Using babel-node
should work (as AFAIK the TypeScript compiler - that ts-node
uses - cannot strip Flow types), but you'd need a Babel config that both uses @babel/preset-flow
on .js
files & @babel/typescript
on .ts
files, eg (not tested):使用
babel-node
应该可以工作(就像 AFAIK 的 TypeScript 编译器 - ts-node
使用的 - 不能剥离 Flow 类型),但是你需要一个 Babel 配置,它在.js
文件和@babel/typescript
上都使用@babel/preset-flow
.ts
文件上的@babel/typescript
,例如(未测试):
module.exports = {
presets: ['module:metro-react-native-babel-preset', '@babel/preset-flow'],
overrides: {
test: /\.tsx?$/,
presets: [
'@babel/preset-env',
'@babel/preset-react',
[
'@babel/typescript',
{
allExtensions: true,
isTSX: true,
},
],
],
plugins: [['@babel/plugin-proposal-decorators', { legacy: true }]],
},
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.