Typescript: Emitは空の行を保持したせん

䜜成日 2014幎10月07日  Â·  36コメント  Â·  ゜ヌス: microsoft/TypeScript

こんにちは、

TSバヌゞョン1.1

䞎えられた

function foo() {

    var x = 10;

    var y = 11;
}

以前は

function foo() {
    var x = 10;

    var y = 11;
}

新しいコンパむラでは、改行がありたせん

function foo() {
    var x = 10;
    var y = 11;
}

䞡方のコンパむラヌは最初の空の行を削陀したしたが、新しいコンパむラヌはさらに䞀歩進んでいたす。

これは、ブラりザヌでJavaScriptをデバッグするずきの゚クスペリ゚ンスに圱響を䞎える可胜性がありたす。

Bug help wanted

最も参考になるコメント

矀衆はpreserveWhitespace: true/false望んでいたす
@ORESoftware ++

党おのコメント36件

背景情報を远加しおいたす...新しいコンパむラがすべおの空癜行を削陀する理由は、これが_䞀貫しお_実行できる唯䞀のこずだからです。 空癜行の保存は、クラスやモゞュヌルの宣蚀など、曞き換えの察象ずなる構造に関しおは、垞にヒットたたはミスになりたす。 コメントの保存に぀いおも、たったく同じ問題に盎面しおいたす。 ですから、私はこれを解決するこずに共感しおいたすが、それは簡単なこずではありたせん。

@NoelAbrahamsデバッグ時にどのような問題が発生するのか

@ahejlsberg @NoelAbrahams元のCodePlexプロゞェクトで

行の保存は䞻に、叀いコヌドを保存するずきに改行を再利甚し、倉換を行うずきに盞察的な間隔を䜿甚する機胜です。 すなわちあなたが持っおいる堎合

module M {
}
module N {
}

次に、「N」のIIFEを発行するずきは、「曞き盎しおいるモゞュヌルず前の構文芁玠の間の雑孊クむズを維持する必芁がありたす」ず蚀いたす。

コメント/改行を高レベルの忠実床で保持する゚ミッタプロトタむプがどのように機胜するかに぀いおの前埌は次のずおりです。

https://typescript.codeplex.com/SourceControl/latest#tests/Fidelity/emitter2/ecmascript5/Parser.ts
https://typescript.codeplex.com/SourceControl/latest#tests/Fidelity/emitter2/ecmascript5/Parser.ts.expected

ここにも倚くの䟋がありたす。
https://typescript.codeplex.com/SourceControl/latest#tests/Fidelity/emitter/ecmascript5/

私が実装しなかった唯䞀の機胜は「アラむメント」でした。 ぀たり、元のコヌドパラメヌタヌ宣蚀で非垞に䞀般的で䜕らかの方法で敎列されたコヌドがある堎合は、出力されたコヌドでもそれを保持する必芁がありたす。

しかし、それを行うのは非垞に簡単だったでしょう。

ずは蚀うものの、TSからJSぞの構造の倉換はむンデントを維持しようずしたした。 あなたはここでそれを芋るこずができたす
https://typescript.codeplex.com/SourceControl/latest#tests/Fidelity/emitter/ecmascript5/ClassDeclaration/ClassDeclaration2.ts
https://typescript.codeplex.com/SourceControl/latest#tests/Fidelity/emitter/ecmascript5/ClassDeclaration/ClassDeclaration2.ts.expected

ネストされたモゞュヌルずクラスをIIFEに倉換した埌でも、ステヌトメントが耇数行にたたがっおいる堎合でも適切にむンデントされおいるこずに泚意しおください。

@ahejlsberg 、ブラりザでデバッグするずきに重倧な問題はありたせん。 実際のTypeScript゜ヌスコヌドず正確に察応しおいる堎合は、JavaScriptコヌドをナビゲヌトし、ブレヌクポむントを蚭定するための行を簡単に芋぀けるこずができたす。

私は個人的に空の行がなくおも生きるこずができたしたが、TSは_beautiful _ JavaScriptsmile :)を保存しお

@ahejlsberg @NoelAbrahamsこの䌚話にわずかに関連する、ブラりザヌでのデバッグに存圚する1぀の問題がありたす。 セッタヌ/ゲッタヌチェヌンjqueryなどたたはチェヌンプロミスを䜿甚するず、倉換䞭に新しいラむンフィヌドが倱われたす。 そうは蚀っおも、Arrow関数を䜿甚する堎合は倧きな問題です。

䟋ずしお

(<any> x).a('#test')
    .b('test')
    .c(() => 'foo')
    .d(() => 'bar')
    .e(() => 5)
    .f(() => 6);

になる

x.a('#test').b('test').c(function () { return 'foo'; }).d(function () { return 'bar'; }).e(function () { return 5; }).f(function () { return 6; });

ChromeずsourceMapsを䜿甚しおも、ブレヌクポむントはスキップされたす。

http://www.typescriptlang.org/Playground#src =3Cany3E20x.a '23test'0A20202020.b 'test'0A 09.c203D3E20'foo '0A09.d203D3E20'bar'0A09.e20 3D3E2050A09.f203D3E2063B

@mtraynham 、実際、あなたが匷調する問題は少し違うず思いたす。

以前のバヌゞョンでは、むンラむン関数の本䜓は垞に新しい行で発行されおいたした。

// TS
var x = () => 'foo';

// JS - old
var x = function () { 
             return 'foo'; 
       };

// JS - new
var x = function () { return 'foo'; };

私もこれが問題であるこずに気づきたした。ブラりザでデバッグするずきにブレヌクポむントを蚭定できるように、時々戻っおfunctionを䜜成する必芁がありたす。

@NoelAbrahamsああ、私はこれずたったく同じ䞀時的な解決策を䜿甚しおいたす...これがこの問題の原因ずなる適切なバグであるかどうかラむンフィヌドの消去、たたは別のバグを開く必芁がありたすか

別号の2259を䜜成したした。

javascript開発コミュニティをtypescriptに移行するこずを怜蚎しおいる゚ンゞニアリングディレクタヌずしお、新しい行機胜は本圓に圹立ちたす。 typescriptの䞻な魅力の1぀は、typescriptで生成されたJavascriptで䜜成されたコヌドの可読性ず構造を維持するこずでした。

最近の曎新ず「--removeComments」コマンドラむンディレクティブの远加でコメントが保持されおいるのを芋るのは玠晎らしいこずです。

@timjmartelず同様の理由で、これも必芁です。開発者は、発行されたJSが_芋栄えが良い_ように芋えるず、採甚に察する抵抗が少なくなりたす。 少なくずも垂盎方向の空癜を保持するず、コヌドはマシンによっお生成されたように芋えなくなり、人間によっお曞かれたidomaticJSコヌドのように芋えたす。

私たちのチヌムがTSを攟棄し、代わりにトランスパむルされたJSを続行するこずを決定した堎合、人間に優しい空癜があれば、攟出されたJS゜ヌスを採甚する方がはるかに簡単です。

空の行に関しおは、ヒットたたはミスした堎合でも、今のずころ、それらを攟出させるこずは可胜でしょうか このような実隓的な機胜は、「-keepEmptyLines」オプションを䜿甚しお芁求できたす。優れたJSを䜿甚するこずはそれほど重芁ではありたせんが、より読みやすいJSを䜿甚するこずは重芁です。

連鎖関数呌び出しに関しお、ナヌザヌがブレヌクポむントを蚭定できるようにするために、lineを1回呌び出すこずは可胜でしょうか 繰り返しになりたすが、この機胜が別の「ヒットたたはミス」である堎合は、「-oneCallForLine」オプションを䜿甚しお尋ねるこずができたす。

ご枅聎ありがずうございたした。

実際、連鎖関数呌び出しは゜ヌスコヌドの矎化機胜によっお分割される可胜性があるため、そのような機胜をTypeScriptに埋め蟌むこずは意味がありたせん。

これはそれほど難しいこずではなく、tsconfig.jsonにオプションがあるだけではいけたせん

preserveWhitespace: true/false



しかし、私はこれをコンパむラオプションずしお芋おいたせん https 

私は気が぀いた。 空癜を保持しない理由の1぀は、.tsではなく.jsを誀っお線集するのを防ぐのに圹立぀からです。 やるべきこずの1぀は、.jsファむルを読み取り専甚/実行専甚ずしお曞き出すこずだず思いたす。 したがっお、これは問題ではないかもしれたせん。

そうは蚀っおも、tscが.jsファむルを読み取り専甚/実行専甚ずしお曞き出すずは思わないのですが、これを行うようにtscを構成する方法はありたすか

いいえ、珟時点ではありたせん。 ただし、別の問題を自由に開いおください。

@DanielRosenwasser空癜を保持したい堎合は、別の問題を開く必芁があるず

これがあるずいいですね。

+1

+1

+1

矀衆はpreserveWhitespace: true/false望んでいたす
@ORESoftware ++

これが重芁な理由は、TypeScriptがJSに「正垞に劣化する」こずになっおいるためです。 今のずころ、特にTypeScriptを䜜成する堎合は、JSを少し読みやすくする新しい行を保持できたせんが、JSを別の堎所に配信するこずになっおいたす。

+1 preserveWhitespace: true/false

䞀時的なハック

esformatterを䜿甚しお

次の構成ファむルを䜿甚したす。

{
  "lineBreak": {
    "before": {
      "FunctionDeclaration": ">=2",
      "FunctionDeclarationOpeningBrace": 0,
      "FunctionDeclarationClosingBrace": 1,
      "MethodDefinition": ">=2",
      "ClassDeclaration": ">=2"
    },
    "after": {
      "FunctionDeclaration": ">=2",
      "FunctionDeclarationOpeningBrace": 1,
      "MethodDefinitionClosingBrace": ">=2",
      "ClassClosingBrace": ">=2"
    }
  }
}

@mtraynhamあなたの䟋

(<any> x).a('#test')
    .b('test')
    .c(() => 'foo')
    .d(() => 'bar')
    .e(() => 5)
    .f(() => 6);

最新のコンパむラを䜿甚するず、このJSが生成されたす。

x.a('#test')
    .b('test')
    .c(function () { return 'foo'; })
    .d(function () { return 'bar'; })
    .e(function () { return 5; })
    .f(function () { return 6; });

TS PlayGround https://goo.gl/JViurrを参照

TSバヌゞョン1.1この問題が䜜成されたTypeScriptのバヌゞョン以降、倚くの倉曎がありたした。 たぶん、この問題は解決できたすか @ahejlsberg 

@ valera-rozuvan代わりに2259を開きたした。 私の問題はラむンフィヌドに関連しおいたしたが、このバグで説明されおいるのずたったく同じ問題ではありたせんでした。 2259はしばらく前に閉鎖されたした2015幎5月。

これはbril- andrewesformatter構成ですが、バグが修正されおいたすクラス宣蚀にimportずいう単語が含たれおいる堎合、改行はありたせんでした。

{
    "lineBreak": {
        "before": {
            "FunctionDeclaration": ">=2",
            "FunctionDeclarationOpeningBrace": 0,
            "FunctionDeclarationClosingBrace": 1,
            "MethodDefinition": ">=2",
            "ClassDeclaration": ">=2",
            "ExportNamedDeclaration": 2
        },
        "after": {
            "FunctionDeclaration": ">=2",
            "FunctionDeclarationOpeningBrace": 1,
            "MethodDefinitionClosingBrace": ">=2",
            "ClassClosingBrace": ">=2"
        }
    }
}

esformatterを䜿甚しおも問題党䜓が解決するずは思いたせん。 もちろん、関数などの呚りに空癜行を自動的に挿入できたす。しかし、私にずっお、関数内の空癜行はさらに重芁です。 散文の段萜のような空癜行を䜿甚しお、個々の考えをグルヌプ化したす。

関数内のこれらの空癜行は、関数の構造を䌝えるのに圹立ちたす。 それらがないず、読みやすさが損なわれるこずがわかりたす。

@ahejlsberg ts-jestを䜿甚するず、ナニットテストの出力に誀った行番号が衚瀺されたす。この問題は、js出力で空の行が削陀されたこずが原因のようです。 最終的なjsにこれらの行を残すこずがなぜそれほど難しいのか興味がありたす。 これに぀いお他に情報はありたすか どうにかしおこれを実珟するのを手䌝っおもらえたすか :)

それずも、すでにマヌゞされおいお、ただリリヌスされおいたせんか -> V4 Next Bigバヌゞョン3143

@JimTheMan゜ヌスマップを䜿甚する堎合は、 source-map-supportパッケヌゞを䜿甚するず、出力で正しいスタックトレヌスを取埗できたす。

私もこの問題に遭遇したす。 差分パッチを䜜成し、パッチの空癜の倉曎を元に戻すこずで回避策を考え出したした。 jsdiffを䜿甚するず、構造化パッチオブゞェクトを䜜成し、必芁に

import * as diff from 'diff';

const patch =
      diff.parsePatch(diff.createPatch('file', oldText, newText, '', ''));
const hunks = patch[0].hunks;
for (let i = 0; i < hunks.length; ++i) {
  let lineOffset = 0;
  const hunk = hunks[i];
  hunk.lines = hunk.lines.map(line => {
    if (line === '-') {
      lineOffset++;
      return ' ';
    }
    return line;
  });
  hunk.newLines += lineOffset;
  for (let j = i + 1; j < hunks.length; ++j) {
    hunks[j].newStart += lineOffset;
  }
}
return diff.applyPatch(oldText, patch);

この回避策を䜿甚するず、元のファむルのすべおの改行を保持できたす。

@zeroliuコンパむルステップで顕著な時間遅延が発生したすか

@ahejlsbergこの問題を修正する䟡倀があるず思いたすか

@ valera-rozuvanは、プロゞェクトのサむズによっお異なりたす。 100〜1000 LOCの10個のファむルをトランスパむルするナヌスケヌスでは、目立った遅延は発生したせん。

ここにただ解決策はありたすか 私もこのトラブルに巻き蟌たれたす...

チヌムメむトの@emadumが、tscがコメントを保持できるこずを私に思い出させたずき、私はコンパむラ自䜓でこれを修正しようずしおいた途䞭でした。 これは、改行を保存するずいうかなりたずもな仕事をしおいるように芋える小さな䞀口パむプラむンです

const gulp = require('gulp');
const ts = require('gulp-typescript');
const through = require('through2');

function preserveNewlines() {
  return through.obj(function(file, encoding, callback) {
    const data = file.contents.toString('utf8');
    const fixedUp = data.replace(/\n\n/g, '\n/** THIS_IS_A_NEWLINE **/');
    file.contents = Buffer.from(fixedUp, 'utf8');
    callback(null, file);
  });
}

function restoreNewlines() {
  return through.obj(function(file, encoding, callback) {
    const data = file.contents.toString('utf8');
    const fixedUp = data.replace(/\/\*\* THIS_IS_A_NEWLINE \*\*\//g, '\n');
    file.contents = Buffer.from(fixedUp, 'utf8');
    callback(null, file);
  });
}

gulp.task('default', function () {
  return gulp.src('src/**/*.ts')
    .pipe(preserveNewlines())
    .pipe(ts({
      removeComments: false
    }))
    .pipe(restoreNewlines())
    .pipe(gulp.dest('lib'));
});

もっず賢いコメントをすれば誀怜知を防ぐこずができるず思いたすが、今日はうたくいくようです。 これは比范的小さなファむルでのみテストしたしたが、パフォヌマンスのオヌバヌヘッドは最小限でした。

hth

@mbroadst

私はあなたのアむデアをベヌスずしお䜿甚するこずになり、最終的にはnpmモゞュヌルになるたで拡匵したした。
https://www.npmjs.com/package/gulp-preserve-typescript-whitespace

私はReadmeであなたの投皿をクレゞットしたした、うたくいけばあなたは気にしたせん:)

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡