// Currently the automatic chunk generation algorithm should by construction
// never generate chunks that import each other since files are allocated to
// chunks based on which entry points they are reachable from.
//
// This will change in the future when we allow manual chunk labels. But before
// we allow manual chunk labels, we'll need to rework module initialization to
// allow code splitting chunks to be lazily-initialized.
//
// Since that work hasn't been finished yet, cycles in the chunk import graph
// can cause initialization bugs. So let's forbid these cycles for now to guard
// against code splitting bugs that could cause us to generate buggy chunks.
Currently the automatic chunk generation algorithm should by construction
never generate chunks that import each other since files are allocated to
chunks based on which entry points they are reachable from.

This will change in the future when we allow manual chunk labels. But before
we allow manual chunk labels, we'll need to rework module initialization to
allow code splitting chunks to be lazily-initialized.

Since that work hasn't been finished yet, cycles in the chunk import graph
can cause initialization bugs. So let's forbid these cycles for now to guard
against code splitting bugs that could cause us to generate buggy chunks.
// Currently the automatic chunk generation algorithm should by construction // never generate chunks that import each other since files are allocated to // chunks based on which entry points they are reachable from . // // This will change in the future when we allow manual chunk labels . But before // we allow manual chunk labels we ' ll need to rework module initialization to // allow code splitting chunks to be lazily - initialized . // // Since that work hasn ' t been finished yet cycles in the chunk import graph // can cause initialization bugs . So let ' s forbid these cycles for now to guard // against code splitting bugs that could cause us to generate buggy chunks .
func (c *linkerContext) enforceNoCyclicChunkImports(chunks []chunkInfo) {
	var validate func(int, []int)
	validate = func(chunkIndex int, path []int) {
		for _, otherChunkIndex := range path {
			if chunkIndex == otherChunkIndex {
				c.log.AddError(nil, logger.Loc{}, "Internal error: generated chunks contain a circular import")
				return
			}
		}
		path = append(path, chunkIndex)
		for _, chunkImport := range chunks[chunkIndex].crossChunkImports {
			if chunkImport.importKind != ast.ImportDynamic {
				validate(int(chunkImport.chunkIndex), path)
			}
		}
	}
	path := make([]int, 0, len(chunks))
	for i := range chunks {
		validate(i, path)
	}
}
func ( c * linkerContext ) enforceNoCyclicChunkImports ( chunks [ ] chunkInfo ) { var validate func ( int , [ ] int ) validate = func ( chunkIndex int , path [ ] int ) { for _ , otherChunkIndex := range path { if chunkIndex == otherChunkIndex { c . log . AddError ( nil , logger . Loc { } , " " ) return } } path = append ( path , chunkIndex ) for _ , chunkImport := range chunks [ chunkIndex ] . crossChunkImports { if chunkImport . importKind != ast . ImportDynamic { validate ( int ( chunkImport . chunkIndex ) , path ) } } } path := make ( [ ] int , 0 , len ( chunks ) ) for i := range chunks { validate ( i , path ) } }
Currently the automatic chunk generation algorithm should by construction
never generate chunks that import each other since files are allocated to
chunks based on which entry points they are reachable from.
Currently the automatic chunk generation algorithm should by construction never generate chunks that import each other since files are allocated to chunks based on which entry points they are reachable from .
// Ignore cycles caused by dynamic "import()" expressions. These are fine // because they don't necessarily cause initialization order issues and // they don't indicate a bug in our chunk generation algorithm. They arise // normally in real code (e.g. two files that import each other).