Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] Semantic validation across multiple editor instances #2976

Open
1 of 2 tasks
foyzhao opened this issue Feb 16, 2022 · 7 comments · May be fixed by #4672
Open
1 of 2 tasks

[Bug] Semantic validation across multiple editor instances #2976

foyzhao opened this issue Feb 16, 2022 · 7 comments · May be fixed by #4672
Assignees
Labels
bug Issue identified by VS Code Team member as probable bug typescript typescript-multifile

Comments

@foyzhao
Copy link

foyzhao commented Feb 16, 2022

Reproducible in vscode.dev or in VS Code Desktop?

  • Not reproducible in vscode.dev or VS Code Desktop

Reproducible in the monaco editor playground?

Monaco Editor Playground Code

monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
  noSyntaxValidation: false,
  noSemanticValidation: false
})

monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
  allowJs: true,
  checkJs: true,
  allowNonTsExtensions: true
})

monaco.editor.create(document.getElementById('container1'), {
  model: monaco.editor.createModel('const abc = 1', 'javascript', monaco.Uri.parse('file:///a.js'))
})

monaco.editor.create(document.getElementById('container2'), {
  model: monaco.editor.createModel('const abc = 2', 'javascript', monaco.Uri.parse('file:///b.js'))
})

<div id="container1" style="height: 50%"></div>
<div id="container2" style="height: 50%"></div>

Actual Behavior

Both editor instances prompt "Cannot redeclare block-scoped variable 'abc'." error.

Expected Behavior

No error prompt. It should be possible to use variables with the same name in two different files.

Additional Context

No response

@hediet hediet added the bug Issue identified by VS Code Team member as probable bug label Feb 16, 2022
@reinaldoarrosi
Copy link

Are there any known workarounds for this issue while the bug is not fixed?
This bug makes it almost impossible to use multiple code editors in a single page.

Besides that, with some pointers in the right direction, I might be able to submit a PR for this :)

@hediet
Copy link
Member

hediet commented Apr 19, 2022

All the typescript related code is here: https://github.com/microsoft/monaco-editor/tree/main/src/language/typescript

Unfortunately, I don't know that code very well.

@pf-costa
Copy link

Having the same issue while having an editor in the UI and trying to validate the syntax of the code in a completely separate model.

@virtual-marat
Copy link

I solved this problem with the setting - I marked the modules as isolated in the compiler options:

monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
    isolatedModules: true,
});

But I'm not sure, if this applies to all issues here.

@bru02
Copy link

bru02 commented Jun 17, 2023

There is a new moduleDetection option in Typescript 4.7, which should fix the problem when set to force.

But the option isn't present in Monaco's CompilerOptions, despite monaco using ts 5.0.

Plus, when setting it manually it doesn't address the issue:

monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
  allowJs: true,
  checkJs: true,
  allowNonTsExtensions: true,
  isolatedModules: true,
  moduleDetection: 'force'
})

@blixt
Copy link

blixt commented Sep 6, 2024

TLDR: Use moduleDetection: 3 as a workaround for now.


I've been digging into the code in Monaco and it seems the compiler options are all passed through, so whether or not the moduleDetection property is in the type shouldn't matter too much, though it would be helpful if it was added.
(Edit: See bottom of this comment – this actually seems quite important after all!)

I also found that when setting the compiler option moduleDetection: "force" using setCompilerOptions, it's ignored, because this error shouldn't be possible in that case:
image

So trying to figure out why that is, I dug deeper into the language service and I found that it actually uses numeric constants for these options, not strings! So the solution is to set moduleDetection: 3 instead.

Here's the relevant code in the language service that gave me the hint that internally it uses numeric constants:

        moduleDetection: {
          dependencies: ["module", "target"],
          computeValue: (compilerOptions) => {
            return compilerOptions.moduleDetection || (computedOptions.module.computeValue(compilerOptions) === 100 /* Node16 */ || computedOptions.module.computeValue(compilerOptions) === 199 /* NodeNext */ ? 3 /* Force */ : 2 /* Auto */);
          }
        },

It seems as if all other options have enums defined and are type safe so people don't run into this trap, however because the moduleDetection option is not in the CompilerOptions interface, plus there is no ModuleDetectionKind enum, this is very easy to encounter.

Here's another enum similar to this one, as an example, we would just need one that is called ModuleDetectionKind with the three possible cases:

export enum ModuleResolutionKind {
Classic = 1,
NodeJs = 2
}

@Torsten85
Copy link

I'm facing the same problem in my app where two editors are visible at the same time but should not share any context.

Setting moduleDetection: 3 helps with the Cannot redeclare block-scoped variable error, but I can still define a global variable in one editor like e.g. with

declare global {
  var NEW_GLOBAL: string;
}

and the other editor can access said global.

how to make two full isolated and standalone versions of monaco? Is there maybe a way to set different workers for different editors?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue identified by VS Code Team member as probable bug typescript typescript-multifile
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants