From c693730ed8d37d40372ece0791e77cafbbcbaf25 Mon Sep 17 00:00:00 2001 From: Evan Wallace Date: Sat, 10 Apr 2021 23:48:55 -0700 Subject: [PATCH] move additional files into module --- internal/bundler/bundler.go | 37 ++++++++++--------------------------- internal/bundler/linker.go | 31 ++++++++++++++----------------- internal/graph/module.go | 17 +++++++++++++++++ pkg/api/api_impl.go | 5 +++-- 4 files changed, 44 insertions(+), 46 deletions(-) diff --git a/internal/bundler/bundler.go b/internal/bundler/bundler.go index 540bb3e6..0d193c35 100644 --- a/internal/bundler/bundler.go +++ b/internal/bundler/bundler.go @@ -67,11 +67,6 @@ type file struct { // corresponding entry point chunk. entryPointChunkIndex uint32 - // If this file ends up being used in the bundle, these are additional files - // that must be written to the output directory. It's used by the "file" - // loader. - additionalFiles []OutputFile - // This file is an entry point if and only if this is not "entryPointNone". // Note that dynamically-imported files are allowed to also be specified by // the user as top-level entry points, so some dynamically-imported files @@ -350,10 +345,10 @@ func parseFile(args parseArgs) { // Copy the file using an additional file payload to make sure we only copy // the file if the module isn't removed due to tree shaking. - result.file.additionalFiles = []OutputFile{{ + result.file.module.AdditionalFiles = []graph.OutputFile{{ AbsPath: args.fs.Join(args.options.AbsOutputDir, relPath), Contents: []byte(source.Contents), - jsonMetadataChunk: jsonMetadataChunk, + JSONMetadataChunk: jsonMetadataChunk, }} default: @@ -1837,18 +1832,6 @@ func DefaultExtensionToLoaderMap() map[string]config.Loader { } } -type OutputFile struct { - AbsPath string - Contents []byte - - // If "AbsMetadataFile" is present, this will be filled out with information - // about this file in JSON format. This is a partial JSON file that will be - // fully assembled later. - jsonMetadataChunk string - - IsExecutable bool -} - func applyOptionDefaults(options *config.Options) { if options.ExtensionToLoader == nil { options.ExtensionToLoader = DefaultExtensionToLoaderMap() @@ -1881,7 +1864,7 @@ func applyOptionDefaults(options *config.Options) { } } -func (b *Bundle) Compile(log logger.Log, options config.Options) ([]OutputFile, string) { +func (b *Bundle) Compile(log logger.Log, options config.Options) ([]graph.OutputFile, string) { start := time.Now() if log.Debug { log.AddDebug(nil, logger.Loc{}, "Started the compile phase") @@ -1900,15 +1883,15 @@ func (b *Bundle) Compile(log logger.Log, options config.Options) ([]OutputFile, // Compute source map data in parallel with linking dataForSourceMaps := b.computeDataForSourceMapsInParallel(&options, allReachableFiles) - var resultGroups [][]OutputFile + var resultGroups [][]graph.OutputFile if options.CodeSplitting { // If code splitting is enabled, link all entry points together c := newLinkerContext(&options, log, b.fs, b.res, b.files, b.entryPoints, allReachableFiles, dataForSourceMaps) - resultGroups = [][]OutputFile{c.link()} + resultGroups = [][]graph.OutputFile{c.link()} } else { // Otherwise, link each entry point with the runtime file separately waitGroup := sync.WaitGroup{} - resultGroups = make([][]OutputFile, len(b.entryPoints)) + resultGroups = make([][]graph.OutputFile, len(b.entryPoints)) for i, entryPoint := range b.entryPoints { waitGroup.Add(1) go func(i int, entryPoint entryMeta) { @@ -1923,7 +1906,7 @@ func (b *Bundle) Compile(log logger.Log, options config.Options) ([]OutputFile, } // Join the results in entry point order for determinism - var outputFiles []OutputFile + var outputFiles []graph.OutputFile for _, group := range resultGroups { outputFiles = append(outputFiles, group...) } @@ -2098,7 +2081,7 @@ func (b *Bundle) computeDataForSourceMapsInParallel(options *config.Options, rea } } -func (b *Bundle) generateMetadataJSON(results []OutputFile, allReachableFiles []uint32, asciiOnly bool) string { +func (b *Bundle) generateMetadataJSON(results []graph.OutputFile, allReachableFiles []uint32, asciiOnly bool) string { sb := strings.Builder{} sb.WriteString("{\n \"inputs\": {") @@ -2125,7 +2108,7 @@ func (b *Bundle) generateMetadataJSON(results []OutputFile, allReachableFiles [] isFirst = true paths := make(map[string]bool) for _, result := range results { - if len(result.jsonMetadataChunk) > 0 { + if len(result.JSONMetadataChunk) > 0 { path := b.res.PrettyPath(logger.Path{Text: result.AbsPath, Namespace: "file"}) if paths[path] { // Don't write out the same path twice (can happen with the "file" loader) @@ -2139,7 +2122,7 @@ func (b *Bundle) generateMetadataJSON(results []OutputFile, allReachableFiles [] } paths[path] = true sb.WriteString(fmt.Sprintf("%s: ", js_printer.QuoteForJSON(path, asciiOnly))) - sb.WriteString(result.jsonMetadataChunk) + sb.WriteString(result.JSONMetadataChunk) } } diff --git a/internal/bundler/linker.go b/internal/bundler/linker.go index d3d49271..2797674a 100644 --- a/internal/bundler/linker.go +++ b/internal/bundler/linker.go @@ -376,7 +376,7 @@ func (c *linkerContext) generateUniqueKeyPrefix() bool { return true } -func (c *linkerContext) link() []OutputFile { +func (c *linkerContext) link() []graph.OutputFile { if !c.generateUniqueKeyPrefix() { return nil } @@ -384,7 +384,7 @@ func (c *linkerContext) link() []OutputFile { // Stop now if there were errors if c.log.HasErrors() { - return []OutputFile{} + return []graph.OutputFile{} } c.markPartsReachableFromEntryPoints() @@ -442,7 +442,7 @@ func (c *linkerContext) enforceNoCyclicChunkImports(chunks []chunkInfo) { } } -func (c *linkerContext) generateChunksInParallel(chunks []chunkInfo) []OutputFile { +func (c *linkerContext) generateChunksInParallel(chunks []chunkInfo) []graph.OutputFile { // Generate each chunk on a separate goroutine generateWaitGroup := sync.WaitGroup{} generateWaitGroup.Add(len(chunks)) @@ -484,16 +484,16 @@ func (c *linkerContext) generateChunksInParallel(chunks []chunkInfo) []OutputFil // Generate the final output files by joining file pieces together var resultsWaitGroup sync.WaitGroup - results := make([][]OutputFile, len(chunks)) + results := make([][]graph.OutputFile, len(chunks)) resultsWaitGroup.Add(len(chunks)) for chunkIndex, chunk := range chunks { go func(chunkIndex int, chunk chunkInfo) { - var outputFiles []OutputFile + var outputFiles []graph.OutputFile // Each file may optionally contain additional files to be copied to the // output directory. This is used by the "file" loader. for _, sourceIndex := range chunk.filesInChunkInOrder { - outputFiles = append(outputFiles, c.files[sourceIndex].additionalFiles...) + outputFiles = append(outputFiles, c.files[sourceIndex].module.AdditionalFiles...) } // Path substitution for the chunk itself @@ -527,10 +527,10 @@ func (c *linkerContext) generateChunksInParallel(chunks []chunkInfo) []OutputFil // Potentially write the external source map file switch c.options.SourceMap { case config.SourceMapLinkedWithComment, config.SourceMapInlineAndExternal, config.SourceMapExternalWithoutComment: - outputFiles = append(outputFiles, OutputFile{ + outputFiles = append(outputFiles, graph.OutputFile{ AbsPath: c.fs.Join(c.options.AbsOutputDir, finalRelPathForSourceMap), Contents: outputSourceMap, - jsonMetadataChunk: fmt.Sprintf( + JSONMetadataChunk: fmt.Sprintf( "{\n \"imports\": [],\n \"exports\": [],\n \"inputs\": {},\n \"bytes\": %d\n }", len(outputSourceMap)), }) } @@ -550,10 +550,10 @@ func (c *linkerContext) generateChunksInParallel(chunks []chunkInfo) []OutputFil } // Generate the output file for this chunk - outputFiles = append(outputFiles, OutputFile{ + outputFiles = append(outputFiles, graph.OutputFile{ AbsPath: c.fs.Join(c.options.AbsOutputDir, chunk.finalRelPath), Contents: outputContents, - jsonMetadataChunk: jsonMetadataChunk, + JSONMetadataChunk: jsonMetadataChunk, IsExecutable: chunk.isExecutable, }) @@ -568,7 +568,7 @@ func (c *linkerContext) generateChunksInParallel(chunks []chunkInfo) []OutputFil for _, result := range results { outputFilesLen += len(result) } - outputFiles := make([]OutputFile, 0, outputFilesLen) + outputFiles := make([]graph.OutputFile, 0, outputFilesLen) for _, result := range results { outputFiles = append(outputFiles, result...) } @@ -1103,12 +1103,8 @@ func (c *linkerContext) scanImportsAndExports() { file := &c.files[sourceIndex] switch repr := file.module.Repr.(type) { case *graph.CSSRepr: - // We shouldn't need to clone this because it should be empty for CSS files - if file.additionalFiles != nil { - panic("Internal error") - } - // Inline URLs for non-CSS files into the CSS file + var additionalFiles []graph.OutputFile for importRecordIndex := range repr.AST.ImportRecords { if record := &repr.AST.ImportRecords[importRecordIndex]; record.SourceIndex.IsValid() { otherFile := &c.files[record.SourceIndex.GetIndex()] @@ -1118,10 +1114,11 @@ func (c *linkerContext) scanImportsAndExports() { record.SourceIndex = ast.Index32{} // Copy the additional files to the output directory - file.additionalFiles = append(file.additionalFiles, otherFile.additionalFiles...) + additionalFiles = append(additionalFiles, otherFile.module.AdditionalFiles...) } } } + file.module.AdditionalFiles = additionalFiles case *graph.JSRepr: for importRecordIndex := range repr.AST.ImportRecords { diff --git a/internal/graph/module.go b/internal/graph/module.go index 8bbba374..ae15eea2 100644 --- a/internal/graph/module.go +++ b/internal/graph/module.go @@ -14,6 +14,23 @@ type Module struct { Repr ModuleRepr Loader config.Loader SideEffects SideEffects + + // If this file ends up being used in the bundle, these are additional files + // that must be written to the output directory. It's used by the "file" + // loader. + AdditionalFiles []OutputFile +} + +type OutputFile struct { + AbsPath string + Contents []byte + + // If "AbsMetadataFile" is present, this will be filled out with information + // about this file in JSON format. This is a partial JSON file that will be + // fully assembled later. + JSONMetadataChunk string + + IsExecutable bool } type SideEffects struct { diff --git a/pkg/api/api_impl.go b/pkg/api/api_impl.go index bce8c1d8..239d5ce3 100644 --- a/pkg/api/api_impl.go +++ b/pkg/api/api_impl.go @@ -19,6 +19,7 @@ import ( "github.com/evanw/esbuild/internal/compat" "github.com/evanw/esbuild/internal/config" "github.com/evanw/esbuild/internal/fs" + "github.com/evanw/esbuild/internal/graph" "github.com/evanw/esbuild/internal/js_ast" "github.com/evanw/esbuild/internal/js_lexer" "github.com/evanw/esbuild/internal/js_parser" @@ -937,7 +938,7 @@ func rebuildImpl( waitGroup := sync.WaitGroup{} waitGroup.Add(len(results)) for _, result := range results { - go func(result bundler.OutputFile) { + go func(result graph.OutputFile) { fs.BeforeFileOpen() defer fs.AfterFileClose() if err := os.MkdirAll(realFS.Dir(result.AbsPath), 0755); err != nil { @@ -1274,7 +1275,7 @@ func transformImpl(input string, transformOpts TransformOptions) TransformResult options.Mode = config.ModeConvertFormat } - var results []bundler.OutputFile + var results []graph.OutputFile // Stop now if there were errors if !log.HasErrors() {