Re-export imported elements
- 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
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