使用 TypeScript 和 Babel 的 Gulp 源图

我目前正在编写一个辅助项目,在那里我可以了解有关 TypeScript 和 ES6(使用 babel)的更多信息.

I am currently writing a side project where I can learn more about TypeScript and ES6 (using babel).

我想在我的 TypeScript 中使用 ES6,所以我选择了以下工作流程.

I wanted to use ES6 with my TypeScript, so I settled on the following workflow.

Typescript (ES6) ->通天塔 (ES6) ->ES5

现在我正在使用 Gulp 自动执行所有这些操作,但我很难正确生成源映射.我应该提到这种风格是由/r/typescript 上的用户向我建议的,所以我什至不确定它是否可能.

Now I am using Gulp to automate all of this, and I am having a hard time getting the sourcemaps to generate properly. I should mention that this style was suggested to me by a user on /r/typescript so I am not even sure if it is possible.

无论如何,这是我当前的 gulp 任务

Anyways here is my current gulp task

var server = $.typescript.createProject('src/server/tsconfig.json');
gulp.task('build', ['vet'], function () {
  var sourceRoot = path.join(__dirname, 'src/server/**/*.ts');
  return gulp.src('src/server/**/*.ts')
    .pipe($.sourcemaps.init())
      .pipe($.typescript(server))
      .pipe($.babel())
    .pipe($.sourcemaps.write('.', { sourceRoot: sourceRoot}))
    .pipe(gulp.dest('build/server'));
});

我尝试了许多不同的方法,但都没有奏效.在 VSCode 中调试时,我的应用程序的入口点:build/server/index.js 正确加载并找到源文件 src/server/index.ts.

I have tried many different approaches, but none work. When debugging in VSCode, the entrypoint of my app: build/server/index.js loads and finds the source file src/server/index.ts properly.

但是,当 VSCode 尝试进入另一个文件说 build/server/utils/logger/index.js 时,它会寻找 src/server/utils/logger/index.js 它没有找到,因为它应该在寻找 *.ts 文件.

However when VSCode attempts to step into another file say build/server/utils/logger/index.js it looks for src/server/utils/logger/index.js which it doesn't find because it should be looking for a *.ts file.

那我做错了什么?或者这甚至可能吗?我已经盯着这个大约5个小时了.所以任何见解都会很棒.

So what am I doing wrong? Or is this even possible? I've been staring at this for about 5 hours now. So any insight would be great.

VSCode 0.9.x 也显示 '.../.js' file not found 并且 VSCode 1.0 只是默默地失败.

Also VSCode 0.9.x displays the '.../.js' file not found and VSCode 1.0 just fails silently.

我的 tsconfig.json,它是由 $.typescript.createProject()

my tsconfig.json, it gets passed in by $.typescript.createProject()

{
  "compilerOptions": {
    "module": "commonjs",
    "noImplicitAny": true,
    "removeComments": true,
    "preserveConstEnums": true,
    "target": "ES6",
    "sourceMap": true,
    "outDir": "build/server"
  }
}

.babelrc

{
  "presets": ["es2015"]
}

这里是相关的 npm 包

Here is the relevant npm packages

"devDependencies": {
    "babel-polyfill": "^6.2.0",
    "babel-preset-es2015": "^6.1.18",
    "gulp-babel": "^6.1.0",
    "gulp-sourcemaps": "^1.6.0",
    "gulp-typescript": "^2.9.2"
}

我已经对 gulp-sourcemaps 进行了一些调查,当不使用 babel 时,sourcemaps 可以正常工作.(删除所有无关信息)

I have done some investigating into the gulp-sourcemaps, and when not using babel the sourcemaps work properly. (Removed all irrelevant info)

src/server/up/up2/four.ts - 没有通天塔

{
  "history": [ "/home/user/code/test/src/server/up/up2/four.js" ],
  "base": "/home/user/code/test/src/server/",
  "sourceMap": {
    "sources": ["up/up2/four.ts"],
    "file": "up/up2/four.js"
  }
}

注意 sourceMap.sources 它如何列出正确的源文件 up/up2/four.ts

Notice how in sourceMap.sources it lists the proper source file up/up2/four.ts

下面是我将 gulp-babel 添加到任务中的示例.

Now here is an example when I add gulp-babel into the task.

src/server/up/up2/four.ts - 使用 Babel

{
  "history": [ "/home/user/code/test/src/server/up/up2/four.js" ],
  "base": "/home/user/code/test/src/server/",
  "sourceMap": {
    "sources": ["four.js"],
    "file": "up/up2/four.js"
  },
  "babel": {
    "...": "..."
  }
}

注意 sourceMap.sources 现在如何错误地显示 four.js 而不是 typescript 文件.

Notice how the sourceMap.sources now incorrectly shows the four.js instead of the typescript file.

奇怪的是,只要 typescript 文件位于根目录 src/server 中,它们就可以很好地构建源映射.

Curiously enough, as long as the typescript files are in the root directory src/server they build the source maps just fine.

src/server/two.ts - 使用 Babel

{
  "history": [ "/home/user/code/test/src/server/two.js" ],
  "base": "/home/user/code/test/src/server/",
  "sourceMap": {
    "sources": ["two.ts"],
    "file": "two.js"
  },
  "babel": {
    "...": "..."
  }
}

推荐答案

更新

看来这个问题中的具体问题与 Babel 为不在工作目录中的文件生成不正确的源映射有关.这里已经提交了一个问题.

对于像乙烯基文件这样的对象

For a vinyl File object like

new File({
  cwd: '.',
  base: './test/',
  path: './test/some/file.js'
  ...
});

生成的源地图应该有类似

the generated source map should have something like

{
  ...
  "sources": ["some/file.js"]
  ...
}

但是 gulp-babel 给出了

{
  ...
  "sources": ["file.js"]
  ...
}

这会导致 Typescript 源映射和 Babel 源映射被错误地合并,但仅当文件比工作目录更深时.

This causes the Typescript source maps and Babel source maps to be incorrectly merged, but only when the file is deeper than the working directory.

虽然这个问题正在解决,但我建议使用 Typescript 以 ES5 为目标,并完全绕过 Babel.这会生成正确的源映射.

While this issue is being resolved, I recommend targeting ES5 with Typescript and bypassing Babel completely. This produces correct source maps.

gulp.task('build', function () {
  return gulp.src('src/server/**/*.ts')
    .pipe(sourcemaps.init())
    .pipe(typescript({
      noImplicitAny: true,
      removeComments: true,
      preserveConstEnums: true,
      target: 'es5',
      module: 'commonjs'
    }))
    .pipe(sourcemaps.write('.', { sourceRoot: 'src/server' }))
    .pipe(gulp.dest('build/server'));
});

<小时>

上一个答案

您很接近,但我注意到您的配置中有几个错误:


Previous Answer

You are close, but there are a couple mistakes I noticed in your configuration:

  1. "module": "commonjs""target": "es6" 不兼容.使用 Typescript 输出 ES6 模块,然后让 Babel 将它们转译为 CommonJS.
  2. "outDir" 在使用 Gulp 时不是必需的,因为您正在使用流.中间结果(即 Typescript 的结果)根本不会写入磁盘.
  3. "sourceMap": true 不需要与 Gulp sourcemaps 一起使用.
  1. "module": "commonjs" is incompatible with "target": "es6". Output ES6 modules with Typescript and let Babel transpile them to CommonJS.
  2. "outDir" is not necessary when using Gulp since you are working with a stream. Intermediate results (i.e. results of Typescript) are not written to disk at all.
  3. "sourceMap": true is not necessary together with Gulp sourcemaps.

我创建了一个为我编译的项目,使用 babel@6.1.18 和 typescript@1.6.2.

I have created a project which compiled for me, with babel@6.1.18 and typescript@1.6.2.

目录结构

.
├── gulpfile.js
└── src
    └── server
        ├── one.ts
        └── two.ts

one.ts

export class One {};

两个.ts

import { One } from './one';

export class Two extends One {}

gulpfile.js

为了简洁起见,我已经内联了所有配置,但是您应该能够同样轻松地使用配置文件.

I have inlined all configurations for terseness, but you should be able to use config files just as easily.

var gulp = require('gulp');

var sourcemaps = require('gulp-sourcemaps');
var typescript = require('gulp-typescript');
var babel = require('gulp-babel');

gulp.task('build', function () {
  return gulp.src('src/server/**/*.ts')
    .pipe(sourcemaps.init())
    .pipe(typescript({
      noImplicitAny: true,
      removeComments: true,
      preserveConstEnums: true,
      target: 'es6'
    }))
    .pipe(babel({
      presets: [ 'es2015' ]
    }))
    .pipe(sourcemaps.write('.', { sourceRoot: 'src/server' }))
    .pipe(gulp.dest('build/server'));
});

相关文章