17

我的项目中有一个假设的 Typescript 文件(简化示例)。

实用程序.ts

import * as HelperFromNodeModules from 'helper-from-node-modules';

class Utils {
  static foo() {
    return HelperFromNodeModules.parse(...);
  }
}

导入helper-from-node-modules包含一个 Javascript 文件。

helper-from-node-modules.js

const dep = require('foo');
function parse(...) {
   return bar.map((e) => {...});
}

@types/helper-from-node-modules index.d.ts

export function parse(...);

其中tsconfig.json包括以下内容:

{
  ...
  "target": "es5",
  "lib": ["es2015.collection","es6", "dom"],
  "sourceMap": true,
  "allowJs": true,
  ...
}

所以我的问题是 Typescript 编译器的输出文件是我编译的源代码加上所有体面的巨大串联。由于helper-from-node-modules始终是一个.js文件,因此编译器似乎只是将其内容附加到输出文件中。因此,尽管"target": "es5"输出文件仍然包含es6工件,例如const(e) => {...},导致后面的东西出现错误,这些东西严格要求 es5 javascript。

有没有办法告诉 Typescript 编译器/转译器也在javascript 依赖项上输出es5 ?

上下文如果你关心:

我犯了一个可怕的错误,使用react-create-app-typescriptandreact-scripts-ts作为我的 React 应用程序的样板。内置的 webpack 堆栈对于源代码应该来自哪里以及编译后的源代码必须es5非常固执己见。如果尝试缩小任何es6工件,打包的 minifier/uglifier 将崩溃。我知道我可以运行和修改各种配置脚本,但我试图避免这种混乱。我很想将源代码编译为es6而不会弄乱他们的 webpack 堆栈。npm run-script eject

4

2 回答 2

10

不幸的是,没有办法将依赖项从 ES6 转换为 ES5。该选项tsconfig.json仅影响 TypeScript 代码的转译方式。你应该做的是使用 ES5 版本的helper-from-node-modules. 例如,Angular 分发了几个包,用于 ES5 (umd)、ES5、ES6 ... 然后,在package.json库中,有选项告诉打包器(通常是 webpack)使用什么版本,具体取决于目标使用对于打字稿。

如果您使用的库不支持该库,您唯一的选择就是自己将其转换为 ES5,可能使用 babel,或者使用替代方法。然而,对于一个仅作为 ES6 分发的库来说,这很奇怪。

于 2018-04-29T21:19:51.913 回答
4

我唯一想到的就是挂钩到编译过程并在它们被 TypeScript 处理之前转换你的依赖项。这需要TypeScript 转换器

转换器是您的程序的 AST 所公开的函数。一个基本的例子:

import * as ts from 'typescript';

export default (program: ts.Program) => {
    return (ctx: ts.TransformationContext) => {
        return (sourceFile: ts.SourceFile) => {
            function visitor(node: ts.Node): ts.Node {
                /**
                 * If that's the kind of node you were looking for,
                 * do something with it and return it. Otherwise:
                 */
                return ts.visitEachChild(node, visitor, ctx);
            }

            return ts.visitEachChild(sourceFile, visitor, ctx);
        };
    };
}

如果你使用的是 Webpack,你可以将它插入到你的 Webpack 配置文件中的构建管道中。

webpack.config.js

const transformer = require('./your-custom-transformer');

module.exports = {
  /* ... */
  module: {
    rules: [
      {
        test: /\.ts$/,
        loader: 'ts-loader', // (or 'awesome-typescript-loader')
        options: {
          getCustomTransformers: program => ({
            before: [
              transformer(program)
            ]
          })
        }
      }
    ]
  }
};
于 2019-03-02T18:52:07.257 回答