Azure / Azure/bicep

Re-export imported elements

Open
#13,670 7 comments 6 reactions 0 assignees View on GitHub
enhancement Needs: Upvote
Dominant language
Bicep
Stars
3.6k
Forks
830
Avg merge
1d 4h
Merged PRs (30d)
81

Description

I've run into an issue around user-defined types, which is that I can only export them up one level of consumption, and that's not always enough. As an example, suppose I have the following modules:

firstModule.bicep:
```
@export()
type firstType = {
propX: string
propY: int
}
param firstParam firstType

....

```

secondModule.bicep:
```
@export()
type secondType = {
propA: string
propB: int
}
param secondParam secondType

....

```

compositeModule.bicep:
```
import {firstType} from 'firstModule.bicep'
import {secondType} from 'secondModule.bicep'

param firstParam firstType
param secondParam secondType

module firstMod 'firstModule.bicep' = {
name: 'firstMod'
params: {
firstParam: firstParam
}
}

module secondMod 'secondModule.bicep' = {
name: 'secondMod'
params: {
secondParam: secondParam
}
}

```

So far, so good. I reuse the types to ensure that the params passed into my composite module have the same type as the individual modules those params will be passed along to.

The problem is that I want to share compositeModule.bicep with my consumers by publishing it to a private registry, and I don't want to publish firstModule.bicep or secondModule.bicep (because nobody should be directly using those modules). I want my consumers to be able to reuse the same user-defined types, but they don't have access to them - they're not exported from compositeModule.bicep, and the consumer doesn't have access to firstModule.bicep or secondModule.bicep.

I know that I could separate out the types into a separate file or two, and publish that/those file(s) to the registry, but this decouples the type from the content it's related to, which I don't really like as a solution.

What I would love to see is the ability to re-export imported elements. If I could do something like this in compositeModule.bicep:
```
@export()
import {firstType} from 'firstModule.bicep'
@export()
import {secondType} from 'secondModule.bicep'
```

And then my consumer could get those types from compositeModule.bicep without even needing to know that those types originated in another module. This would make these types more reusable without having to completely detach them from the content they're related to. It also provides a level of encapsulation because the consumer doesn't need to know what's going on under the hood in compositeModule.bicep.

I'm sure there's some complexity that will come into play with aliases for imports, especially if multiple imports with different aliases have same-named elements, but that feels like it should be solvable.

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the example with firstModule.bicep, secondModule.bicep, and compositeModule.bicep, then trace how imported and @export() elements are resolved across module boundaries. Done means a consumer of compositeModule.bicep can reuse firstType and secondType without accessing the underlying modules, including when imported names need aliases.

Written by the indexing model from the issue text.

Assessment

Tech stack
azure
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.