Typescript transile es6 .js依赖于es5

时间:2018-04-29 20:27:01

标签: javascript typescript ecmascript-6 tsconfig react-create-app

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

Utils.ts

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

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

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

辅助-从节点-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-typescriptreact-scripts-ts作为我的React app的样板。内置的webpack堆栈非常认为源代码应该来自何处以及编译后的源必须 es5 。如果尝试缩小任何 es6 工件,则打包的minifier / uglifier将崩溃。我知道我可以运行npm run-script eject并修改各种配置脚本,但我试图避免这种混乱。我很想得到编译到 es6 的源代码,而不是弄乱他们的webpack堆栈。

2 个答案:

答案 0 :(得分:5)

不幸的是,没有办法将依赖项从ES6转换为ES5。 tsconfig.json中的该选项仅影响TypeScript代码的转换方式。您应该使用的是helper-from-node-modules的ES5版本。例如,Angular与几个软件包一起分发,用于ES5(umd),ES5,ES6 ......然后,在库的package.json中有一些选项可以告诉打包者(通常是webpack)使用什么版本,取决于TypeScript的目标用途。

如果您使用的库不支持,您唯一的选择是自己将其转换为ES5,可能使用babel,或使用替代品。 然而,奇怪的是,图书馆只能作为ES6发布。

答案 1 :(得分:0)

我唯一想到的是进入编译过程并在之前转换您的依赖项,这些依赖项将由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)
            ]
          })
        }
      }
    ]
  }
};