github.com/evanw/esbuild@v0.21.4/internal/graph/meta.go (about) 1 package graph 2 3 // The code in this file represents data that is required by the compile phase 4 // of the bundler but that is not required by the scan phase. 5 6 import ( 7 "github.com/evanw/esbuild/internal/ast" 8 "github.com/evanw/esbuild/internal/helpers" 9 "github.com/evanw/esbuild/internal/js_ast" 10 "github.com/evanw/esbuild/internal/logger" 11 ) 12 13 type WrapKind uint8 14 15 const ( 16 WrapNone WrapKind = iota 17 18 // The module will be bundled CommonJS-style like this: 19 // 20 // // foo.ts 21 // let require_foo = __commonJS((exports, module) => { 22 // exports.foo = 123; 23 // }); 24 // 25 // // bar.ts 26 // let foo = flag ? require_foo() : null; 27 // 28 WrapCJS 29 30 // The module will be bundled ESM-style like this: 31 // 32 // // foo.ts 33 // var foo, foo_exports = {}; 34 // __export(foo_exports, { 35 // foo: () => foo 36 // }); 37 // let init_foo = __esm(() => { 38 // foo = 123; 39 // }); 40 // 41 // // bar.ts 42 // let foo = flag ? (init_foo(), __toCommonJS(foo_exports)) : null; 43 // 44 WrapESM 45 ) 46 47 // This contains linker-specific metadata corresponding to a "file" struct 48 // from the initial scan phase of the bundler. It's separated out because it's 49 // conceptually only used for a single linking operation and because multiple 50 // linking operations may be happening in parallel with different metadata for 51 // the same file. 52 type JSReprMeta struct { 53 // This is only for TypeScript files. If an import symbol is in this map, it 54 // means the import couldn't be found and doesn't actually exist. This is not 55 // an error in TypeScript because the import is probably just a type. 56 // 57 // Normally we remove all unused imports for TypeScript files during parsing, 58 // which automatically removes type-only imports. But there are certain re- 59 // export situations where it's impossible to tell if an import is a type or 60 // not: 61 // 62 // import {typeOrNotTypeWhoKnows} from 'path'; 63 // export {typeOrNotTypeWhoKnows}; 64 // 65 // Really people should be using the TypeScript "isolatedModules" flag with 66 // bundlers like this one that compile TypeScript files independently without 67 // type checking. That causes the TypeScript type checker to emit the error 68 // "Re-exporting a type when the '--isolatedModules' flag is provided requires 69 // using 'export type'." But we try to be robust to such code anyway. 70 IsProbablyTypeScriptType map[ast.Ref]bool 71 72 // Imports are matched with exports in a separate pass from when the matched 73 // exports are actually bound to the imports. Here "binding" means adding non- 74 // local dependencies on the parts in the exporting file that declare the 75 // exported symbol to all parts in the importing file that use the imported 76 // symbol. 77 // 78 // This must be a separate pass because of the "probably TypeScript type" 79 // check above. We can't generate the part for the export namespace until 80 // we've matched imports with exports because the generated code must omit 81 // type-only imports in the export namespace code. And we can't bind exports 82 // to imports until the part for the export namespace is generated since that 83 // part needs to participate in the binding. 84 // 85 // This array holds the deferred imports to bind so the pass can be split 86 // into two separate passes. 87 ImportsToBind map[ast.Ref]ImportData 88 89 // This includes both named exports and re-exports. 90 // 91 // Named exports come from explicit export statements in the original file, 92 // and are copied from the "NamedExports" field in the AST. 93 // 94 // Re-exports come from other files and are the result of resolving export 95 // star statements (i.e. "export * from 'foo'"). 96 ResolvedExports map[string]ExportData 97 ResolvedExportStar *ExportData 98 ResolvedExportTypos *helpers.TypoDetector 99 100 // Never iterate over "resolvedExports" directly. Instead, iterate over this 101 // array. Some exports in that map aren't meant to end up in generated code. 102 // This array excludes these exports and is also sorted, which avoids non- 103 // determinism due to random map iteration order. 104 SortedAndFilteredExportAliases []string 105 106 // This is merged on top of the corresponding map from the parser in the AST. 107 // You should call "TopLevelSymbolToParts" to access this instead of accessing 108 // it directly. 109 TopLevelSymbolToPartsOverlay map[ast.Ref][]uint32 110 111 // If this is an entry point, this array holds a reference to one free 112 // temporary symbol for each entry in "sortedAndFilteredExportAliases". 113 // These may be needed to store copies of CommonJS re-exports in ESM. 114 CJSExportCopies []ast.Ref 115 116 // The index of the automatically-generated part used to represent the 117 // CommonJS or ESM wrapper. This part is empty and is only useful for tree 118 // shaking and code splitting. The wrapper can't be inserted into the part 119 // because the wrapper contains other parts, which can't be represented by 120 // the current part system. Only wrapped files have one of these. 121 WrapperPartIndex ast.Index32 122 123 // The index of the automatically-generated part used to handle entry point 124 // specific stuff. If a certain part is needed by the entry point, it's added 125 // as a dependency of this part. This is important for parts that are marked 126 // as removable when unused and that are not used by anything else. Only 127 // entry point files have one of these. 128 EntryPointPartIndex ast.Index32 129 130 // This is true if this file is affected by top-level await, either by having 131 // a top-level await inside this file or by having an import/export statement 132 // that transitively imports such a file. It is forbidden to call "require()" 133 // on these files since they are evaluated asynchronously. 134 IsAsyncOrHasAsyncDependency bool 135 136 Wrap WrapKind 137 138 // If true, we need to insert "var exports = {};". This is the case for ESM 139 // files when the import namespace is captured via "import * as" and also 140 // when they are the target of a "require()" call. 141 NeedsExportsVariable bool 142 143 // If true, the "__export(exports, { ... })" call will be force-included even 144 // if there are no parts that reference "exports". Otherwise this call will 145 // be removed due to the tree shaking pass. This is used when for entry point 146 // files when code related to the current output format needs to reference 147 // the "exports" variable. 148 ForceIncludeExportsForEntryPoint bool 149 150 // This is set when we need to pull in the "__export" symbol in to the part 151 // at "nsExportPartIndex". This can't be done in "createExportsForFile" 152 // because of concurrent map hazards. Instead, it must be done later. 153 NeedsExportSymbolFromRuntime bool 154 155 // Wrapped files must also ensure that their dependencies are wrapped. This 156 // flag is used during the traversal that enforces this invariant, and is used 157 // to detect when the fixed point has been reached. 158 DidWrapDependencies bool 159 } 160 161 type ImportData struct { 162 // This is an array of intermediate statements that re-exported this symbol 163 // in a chain before getting to the final symbol. This can be done either with 164 // "export * from" or "export {} from". If this is done with "export * from" 165 // then this may not be the result of a single chain but may instead form 166 // a diamond shape if this same symbol was re-exported multiple times from 167 // different files. 168 ReExports []js_ast.Dependency 169 170 NameLoc logger.Loc // Optional, goes with sourceIndex, ignore if zero 171 Ref ast.Ref 172 SourceIndex uint32 173 } 174 175 type ExportData struct { 176 // Export star resolution happens first before import resolution. That means 177 // it cannot yet determine if duplicate names from export star resolution are 178 // ambiguous (point to different symbols) or not (point to the same symbol). 179 // This issue can happen in the following scenario: 180 // 181 // // entry.js 182 // export * from './a' 183 // export * from './b' 184 // 185 // // a.js 186 // export * from './c' 187 // 188 // // b.js 189 // export {x} from './c' 190 // 191 // // c.js 192 // export let x = 1, y = 2 193 // 194 // In this case "entry.js" should have two exports "x" and "y", neither of 195 // which are ambiguous. To handle this case, ambiguity resolution must be 196 // deferred until import resolution time. That is done using this array. 197 PotentiallyAmbiguousExportStarRefs []ImportData 198 199 Ref ast.Ref 200 201 // This is the file that the named export above came from. This will be 202 // different from the file that contains this object if this is a re-export. 203 NameLoc logger.Loc // Optional, goes with sourceIndex, ignore if zero 204 SourceIndex uint32 205 }