forcedotcom / salesforcedx-vscode

Salesforce Extensions for VS Code
https://developer.salesforce.com/tools/vscode
BSD 3-Clause "New" or "Revised" License
954 stars 406 forks source link

jsconfig.json regeneration issues #4822

Open stashymane opened 1 year ago

stashymane commented 1 year ago

I currently have a project with a custom jsconfig.json in the root project directory (force-app/main/default). It has specific options to allow me to have proper intellisense & automatic imports between different LWC components for all sub-projects. The project layout is this, more or less:

The problem - the SFDX VSCode extension automatically creates default jsconfig.json files for every sub-project every time VSCode starts, which completely undoes the config I set up in the main project directory.

Creating config files on startup is not a common pattern, and is detrimental to custom configurations. A decent solution would be to create them only when creating a new subdirectory, or a new project in general. Otherwise I have to duplicate the jsconfig.json file in every single subdirectory, which will eventually become unmaintainable. Or, at least a configuration option to disable this feature would work great.

There already are issues regarding this, however they are closed as either resolved or as a duplicate, without an actual resolution:

TLDR; please allow us to have an option whether to generate the jsconfig.json file on startup or not. We cannot have proper IntelliSense any other way, at least currently.

stashymane commented 1 year ago

Another issue related to this, if I do set up jsconfig.json files for every lwc subdirectory, the extension modifies them on startup as well, introducing a few incompatible changes:

  1. Includes a paths entry in the root object - the paths entry should be included in the compilerOptions block, not in the root.

image

  1. Adds an incompatible include path - the first two elements were added by me and are based on the relative path to the current module, to index all components in the entire project. The SFDX typing path is correct and is not regenerated or mangled, however the additional **/* makes IntelliSense recurse through the current path twice, as it is already included by the first line. Every time I remove this wildcard it is regenerated on the next start.

image

Even if the first point is configured correctly (the paths block is moved into compilerOptions), one bug remains due to the structure of LWC components - automatic imports will duplicate the component name, as VSCode has no idea how to deal with the folder structure. The resulting import will be c/componentName/componentName, as VSCode looks at the component purely as a folder.
I have resolved this bug by including index.js files in every component that re-export every export in the main component, which does not change any functionality in Salesforce, however it lets VSCode realise the entire directory can be counted as a valid import.

The second point is a slightly easier fix, which is either to outright stop modifying the jsconfig.json file, or to check whether this path is included by any other include entry.

zerkz commented 1 year ago

@stashymane I just discovered the same issue with paths recently. You make some good points in general. JSConfig needs to be generated in order to point vscode towards the types generated by the Apex? language server.

One thing I wanted to mention is the subproject structure you have is not officially supported, but you can have multiple package directories . But -- since you're breaking away from the convention with your structure, is there any real need to having the subfolder of the module folders be named lwc? The extension may leave you alone there if you name it to components or something else.

stashymane commented 1 year ago

Yes, the subproject structure is definitely non-standard, but if I made multiple project directories, I would still have to include every other project in each jsconfig as well, though with less nesting. If the jsconfig file wouldn't regenerate, the current subproject structure wouldn't have any issues at all. I have not tried renaming the folders to something other than LWC yet, will attempt later.

nwcm commented 4 months ago

Having similar issues, while you can directly map components in the root jsconfig.json it will be broken by the subfolder automatic jsconfig.json

"paths": {
      "c/utils": ["utilities/lwc/utils/utils.js"]
    }

Our structure follows

nwcm commented 4 months ago

An option to disable this generation would be very useful, I am happy to make a PR for this if someone points me towards the source location to do such

rahulgawale commented 4 months ago

I am trying to use tsconfig.json and the jsconfig.json is annoying me. Need a way to "Do not regenerate" and "Do not overwrite" flags for the extension. The auto-create annoys me. Has anyone find any workaround to suppress it?

nwcm commented 3 months ago

I have a somewhat functional work around. yarn gen:paths which needs to be run every opening of vscode.

Basically remove all jsconfig.js from the sf plugin and manually generate. This makes for a much better auto complete and hinting in vscode

"gen:paths": "pwsh tools/generateLwcImportPaths.ps1 && pwsh tools/removeLwcJsConfigs.ps1",

generateLwcImportPaths

# This script generates lwc c/ import paths for jsconfig that are needed for auto completion in vscode

$lwcComps = Get-ChildItem -Path "force-app/main/*/lwc/*/" -Recurse -Include "*.js-meta.xml" | Sort-Object -Property BaseName

$jsconfig = Get-Content force-app\jsconfig.json -Raw | ConvertFrom-json -Depth 99 -AsHashtable
$jsconfig.compilerOptions.paths = [ordered]@{}

$jsconfig.compilerOptions.paths["test/utils"] = @('../../force-app/test/utils.js')

foreach($lwcComp in $lwcComps){
    $name = $lwcComp.Name.Replace('.js-meta.xml','')
    $pathTo = ($lwcComp.FullName | Resolve-Path -Relative -RelativeBasePath force-app).Replace('\','/').Replace('-meta.xml','')
    $jsconfig.compilerOptions.paths["c/$name"] = @($pathTo)
}

Set-Content -Path force-app\jsconfig.json -Value ($jsconfig | ConvertTo-JSON -Depth 99) -Force

removeLwcJsConfigs

Remove-Item -Path "force-app/main/*/lwc" -Include "jsconfig.json" -Recurse
stashymane commented 3 months ago

From what I can remember, you can also regenerate the jsconfig with a sf cli plugin, as I had a somewhat-working POC at some point. That is long gone however, as I no longer work with Salesforce.