Multi-root Workspaces in VSCode for AL Development

You might have figured – I’m a VSCode fanboy.  One of many.  You might remember the session I did on NAVTechDays 2017 (Rock ‘n Roll with VSCode), where I dove quite a bit into the possibilities this great tool comes with.  But I didn’t talk about the concept of “Multi-root Workspaces”: an ability of VSCode for you to work on multiple “projects” at the same time, in one environment.

2 years later, last NAVTechDays, I talked about Dependencies quite a lot, and when you think of it – in terms of dependencies in AL for Business Central, these “Multi-root Workspaces” might make a lot of sense, because when you have all these apps, you might have to work on multiple apps at the same time. 

Even more, in that same video, you’ll see that I ALWAYS have at least 2 apps: an app, and its test-app.  So in terms of “Test Driven Development” (a methodology I believe is indispensable), you will always have an app, and a dependent app, and you will always work on both apps at the same time.  So – “Multi Root” to the rescue!


Well, the concept of “multi-root workspaces” is actually most simply explained by: opening multiple projects (workspaces) at the same time, to be able to work on multiple pieces of software at the same time.  Or in terms of Business Central: to work (compile, publish, develop, …) on multiple apps at the same time.

The concept is quite well explained on the docs-page for VSCode:

VSCode Extensions

The one downside of this concept is that not every VSCode extension might be ready in a Multi-root environment.  In fact, it took a while to get my own extension (the CRS AL Language Extension) ready for Multi-root workspaces (and there still might be issues with it ;-)).

Same for Microsoft’s AL Language Extension.  It took a while – but just imagine:

  • When you’re working on extension A, from which Extension B is dependent – Extension B will recognize the symbols of Ext A without even having to create (compile) an app file – just because Ext B is in your Multi Root Workspace
  • When you’re debugging, you’re able to go to definition into al-files of other apps you’re debugging – not just the only-one-level-dal-files.  Just because you have the dependent app in your workspace.
  • Whenever you compile a main app, the symbol files of the dependent apps are updated with the new version of the main app.  Just because it’s in your multi-root workspace.

All this is already possible!

And that’s what a real “Multi-root” experience can give you – and why I think we should always look into this.  It makes all the sense in the world – in a world with “lots” of apps and dependencies, to work on them simultaneously.  And I’m sure – if you’re not yet doing it – it can speed up your development process even more!

In Practice

May be a few screenshots that can show you how it could look like.

In this case, I’m actually working on 7 apps at the  same time, with all of them having a test-app as well (which we use for unit-testing).  The last app is the integration-test-app.

How does it determine what app I’m working in?

Well, simply by the active editor.  If I would want to compile and publish the BASE-App, I would open one of the files of that app, and simply press F5. 

Symbols constantly updated over all workspaces

In my case, the BASE App is a library-app for all other apps.  And if I would simply start coding in that BASE-App, like this useless codeunit:

codeunit 2036640 
O references 
procedure Test() 

I would – without even compiling my app – be able to code against this in any app that is dependent from that BASE-App:

codeunit 2039040 TestSymb01s 
O references 
local procedure MyProcedure() 
Test . 

Basically meaning: I can code against all apps at the same time, without even downloading/updating symbols, or compiling or publishing.

Updating Symbols

Even, when you hit compile, you’ll notice that the symbol files in the .alpackages-folder are updated for all apps that depend from the app that you’re compiling.  Very cool!

Can I control this a bit?

Well – you do have the “dependencyPublishingOption” in the launch.json, which has 3 options:

  • Default: set dependency publishing will be applied
  • Ignore: Only the current project is published, dependencies are ignored.
  • Strict: Publishing will fail if the project has apps that not part of the workspace and depend on it

I like the default setting – something it takes a little longer to include all dependencies in the compile – but at least you’re checking all dependencies .. So that must be good ;-).  But, in some cases – especially in case of big apps with many objects – you might want to avoid unnecessary recompiles of dependent apps.. .

Does this mean everything needs to be in one (Git) repository?

No!  VSCode is smart enough to handle multiple workspaces at the same time.  In case of the screenshot above – and as mentioned in a recent webcast I did about handling dependencies in DevOps – all my apps are in separate repos, together with their Test-apps.  So in case of the screenshot, it would be a collection of about 8 GIT repositories.  When you switch to the “Source Control” window, VSCode clearly shows all states of the repositories, like you see here in the screenshot:

File Edit Selection View Go 
FIN Git 
Cl.-IF Git 
Distri Apps 

You can simply see when repos need attention (new/modified/delete files), what branches, and what the synchronization state is.  From this window, you can obviously also change branches, sync, and so on.. . 

There is more …

And I have more for you.  To make working in multiple workspaces more easy, I’m working on a set of scripts, which you find on my PowerShell repository:

I will maintain a set of scripts in the folder ./PSScripts/NAV Extensions v2/MultiRootWorkspaces/ .  Today, I have foreseen:

  • LaunchJson_CopyToAll.ps1: If you change docker image or whatever – this script will simply copy one launch.json to all other workspaces so that you will easily publish other dependent apps to the same sandbox
  • Symbol_Cleanup.ps1: This script removes all symbol files – just imagine when you want to publish against another version (localization, insider, ..), you can simply cleanupt all files and even invoke the next script, which will …
  • Symbol_Download.ps1: This script will download as many symbols as possible for all workspaces that are available in your multiroot workspace.

I’m also working on a “CompileAll” script – would be nice to have one script that figures our the dependency tree (I already got that one), and invoke start compiling all the apps – and – may be – if possible – even starts publishing them to the server instance ;-).  Let’s see where we end up with that one ;-).

There might be issues with the scripts – they are brand new  – but please, use, abuse .. and contribute ;-).

Enjoy going Multi-root!

Comment List