【问题标题】:Typescript transpile es6 .js dependency to es5Typescript 将 es6 .js 依赖项转换为 es5
【发布时间】:2018-10-09 23:39:25
【问题描述】:

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

Utils.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-modulesindex.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 的错误。 p>

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

如果你关心上下文:

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

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      我想到的唯一一件事就是挂钩到编译过程并在它们被 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)
                  ]
                })
              }
            }
          ]
        }
      };
      

      【讨论】:

        猜你喜欢
        • 2021-12-18
        • 1970-01-01
        • 1970-01-01
        • 2019-09-24
        • 2020-05-29
        • 2016-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多