简体   繁体   English

Babel-node 无法处理在 Typescript 文件中导入的 flowtype 文件?

[英]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.在这种情况下,我认为我在以标准方式做错或不正确的事情。

Context语境

Problem问题

My Problem is running TypeORM CLI to generate or even run migration locally for manual testing.我的问题是运行 TypeORM CLI 以在本地生成甚至运行迁移以进行手动测试。

Failed tries失败的尝试

Using ts-node使用 ts-node

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-fsreact-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.于是失败。

Using babel-node使用 babel 节点

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)

Question time!提问时间!

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 🙏谢谢各位开发者🙏

File references文件参考

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.

相关问题 无法在打字稿中导入节点 js 集群 - Node js clusters can't be imported in typescript 带有 typescript 的 babel-node 在命令行中抛出“不能在模块外使用导入语句” - babel-node with typescript throws "Cannot use import statement outside a module" in command line Typescript编译器无法跳过导入的js文件 - Typescript compiler can't skip imported js file 尝试禁止在Node环境中使用JavaScript或TypeScript文件 - Trying to babel either JavaScript OR TypeScript files for use in Node environment Service Worker 文件找不到导入的文件 - Service worker file can't find imported files Babel 模块解析器无法按预期工作(节点 + 打字稿) - Babel module resolver doesn't work as expected (node + typescript) 无法从导入的模块的类型文件解析typescript类,但可以使用绝对路径 - Can't resolve typescript class from typings file of imported module but works with absolute path 无法让打字稿与 webpack 中的 babel 完美配合 - Can't get typescript to play nicely with babel in webpack TypeScript React Babel ReferenceError:找不到变量:regeneratorRuntime - TypeScript React Babel ReferenceError: Can't find variable: regeneratorRuntime 无法让 babel 在 typescript 上使用插值编译字符串文字类型 - Can't get babel to compile string literal type with interpolation on typescript
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM