【问题标题】:How is a merge conflict valid in a React, Typescript project合并冲突在 React、Typescript 项目中如何有效
【发布时间】:2018-02-28 03:49:22
【问题描述】:

我在下面签入到我们的 React/Typescript - JSX/TSX 项目中找到了粘贴的代码。它包含尚未解决的 Git 合并冲突。

代码构建(通过 Fuse-box)并在浏览器中运行!

“转译”代码导致顶部元素被解析为我们组件的根元素,而第二个元素(以“.app-container”开头)被忽略。

看来,在某些情况下,可以通过 TSX/JSX 解释/解析/转译忽略 git 合并冲突。

我的问题是:这是如何工作的?这种行为是故意的吗?

export const App: SFC = () => (
<<<<<<< HEAD
    <Provider store={window.uglySolution}>
        <Router history={customHistory}>
            <Switch>
                <Route exact path='/' component={Welcome}/>
                <Route exact path='/advice' component={PageLayout}/>
                <Route exact path='/login' component={Login}/>
                <Route exact path='/manage' component={ManageLayout}/>
            </Switch>
        </Router>
    </Provider>
=======
    <div className='app-container'>
        <Provider store={window.uglySolution}>
            <Router history={customHistory}>
                <Switch>
                    <Route exact path='/' component={Welcome}/>
                    <Route exact path='/advice' component={PageLayout}/>
                    <Route exact path='/login' component={Login}/>
                    <Route exact path='/manage' component={ManageLayout}/>
                </Switch>
            </Router>
        </Provider>
    </div>
>>>>>>> f81b0b1b458e3d41f91faa2e726be6d88a35d9f8
);

【问题讨论】:

  • 如果没有另行通知,tsc 会这样做,最好忽略您可能拥有的任何错误代码。即使输入错误,这也可能会生成有效代码。这是默认行为,但我不会指望它..解决您的冲突。 :)
  • 另外,在这种情况下.. 我会假设来自 git 的合并文本只是在模板中结束.. 因为从 tsc 的角度来看将是文本
  • @toskv - 我如何告诉 Typescript 忽略“错误代码”(在这种情况下是您的“否则”声明)?
  • 这是--noEmitOnError 编译器选项控制发生的事情,默认为false。您可以在此处查看所有配置。 typescriptlang.org/docs/handbook/compiler-options.html
  • 在您的情况下,您所拥有的可能是有效的 jsx,因为 git 标记被认为是 html 文本并被编译器忽略。你可以责怪 git 没有更好的合并机制.. :D

标签: javascript git reactjs typescript jsx


【解决方案1】:

我知道这是一个相当晚的答案(差不多一年后),但万一有人在谷歌上搜索这个并想知道同样的事情。是的,故意在打字稿词法分析器上有代码来处理 git 合并冲突的行为!注意:在解析器上跳过琐事默认为 true。

if (isConflictMarkerTrivia(text, pos)) {
  pos = scanConflictMarkerTrivia(text, pos, error);
  if (skipTrivia) {
    continue;
}
else {
    return token = SyntaxKind.ConflictMarkerTrivia;
  }
}

以下是处理合并冲突的代码:

function scanConflictMarkerTrivia(text: string, pos: number, error?: (diag: DiagnosticMessage, pos?: number, len?: number) => void) {
    if (error) {
        error(Diagnostics.Merge_conflict_marker_encountered, pos, mergeConflictMarkerLength);
    }

    const ch = text.charCodeAt(pos);
    const len = text.length;

    if (ch === CharacterCodes.lessThan || ch === CharacterCodes.greaterThan) {
        while (pos < len && !isLineBreak(text.charCodeAt(pos))) {
            pos++;
        }
    }
    else {
        Debug.assert(ch === CharacterCodes.bar || ch === CharacterCodes.equals);
        // Consume everything from the start of a ||||||| or ======= marker to the start
        // of the next ======= or >>>>>>> marker.
        while (pos < len) {
            const currentChar = text.charCodeAt(pos);
            if ((currentChar === CharacterCodes.equals || currentChar === CharacterCodes.greaterThan) && currentChar !== ch && isConflictMarkerTrivia(text, pos)) {
                break;
            }

            pos++;
        }
    }

    return pos;
}

来源: https://github.com/Microsoft/TypeScript/blob/0ef0b7adea643a4a28cf9ada1476ff5650a1a9f2/src/compiler/scanner.ts#L1604 https://github.com/Microsoft/TypeScript/blob/0ef0b7adea643a4a28cf9ada1476ff5650a1a9f2/src/compiler/scanner.ts#L565

【讨论】:

    【解决方案2】:

    看来,在某些情况下 git 合并冲突可以通过 Tax/JSX 解释/解析/转译来解决。

    给定的代码是一个编译错误。也就是说编译错误并不意味着你没有生成任何 JS。有一个选项noEmitOnError 可以防止这种情况发生,但是即使没有此选项,您也应该看到编译错误并修复它。

    更多

    https://basarat.gitbooks.io/typescript/content/docs/why-typescript.html

    【讨论】:

      猜你喜欢
      • 2012-10-06
      • 2012-12-08
      • 2022-06-24
      • 2023-03-20
      • 1970-01-01
      • 2019-10-18
      • 2011-08-10
      • 2010-09-11
      • 2018-12-31
      相关资源
      最近更新 更多