繁体   English   中英

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

[英]Babel-node can't process flowtype files imported in Typescript file?

我遇到了一个奇怪的情况,我在互联网上找不到答案。 在这种情况下,我认为我在以标准方式做错或不正确的事情。

语境

问题

我的问题是运行 TypeORM CLI 以在本地生成甚至运行迁移以进行手动测试。

失败的尝试

使用 ts-node

根据有关 Typescript 中实体文件的 TypeORM 文档,我必须以某种方式运行ts-node才能使其工作。 我的问题似乎是在我的实体中,我导入了一些用 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.

好的,所以。 我用 Typescript ( ListAttachment.ts ) 编写的实体有一个import * as RNFS from 'react-native-fs'; . 这个库是用 Flow 编写的 据我了解, ts-node只会将 Typescript 转换为 Javascript,因此当它遇到.js文件时,它无法解释// @flow注释并尝试将其解释为普通的 JS。 于是失败。

使用 babel 节点

好的,所以。 我的想法是使用 Babel 来处理两种语言,但问题是一样的。 据我了解,Babel 将使用基于文件扩展名的转译器。 因此,如果我的主文件是 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)

提问时间!

但是 React-Native 的 Metro 如何处理这些混合导入呢?

我应该从我的实体中删除任何外部导入吗? (最佳实践?)

我做错了吗? (当然:D)

谢谢各位开发者🙏

文件参考

babel.config.js

module.exports = {
    presets: ['module:metro-react-native-babel-preset'],
    plugins: [['@babel/plugin-proposal-decorators', { legacy: true }]],
};

配置文件

{
  "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

[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

使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM