| 468 | } |
| 469 | |
| 470 | function genModulePreamble( |
| 471 | ast: RootNode, |
| 472 | context: CodegenContext, |
| 473 | genScopeId: boolean, |
| 474 | inline?: boolean, |
| 475 | ) { |
| 476 | const { |
| 477 | push, |
| 478 | newline, |
| 479 | optimizeImports, |
| 480 | runtimeModuleName, |
| 481 | ssrRuntimeModuleName, |
| 482 | } = context |
| 483 | |
| 484 | // generate import statements for helpers |
| 485 | if (ast.helpers.size) { |
| 486 | const helpers = Array.from(ast.helpers) |
| 487 | if (optimizeImports) { |
| 488 | // when bundled with webpack with code-split, calling an import binding |
| 489 | // as a function leads to it being wrapped with `Object(a.b)` or `(0,a.b)`, |
| 490 | // incurring both payload size increase and potential perf overhead. |
| 491 | // therefore we assign the imports to variables (which is a constant ~50b |
| 492 | // cost per-component instead of scaling with template size) |
| 493 | push( |
| 494 | `import { ${helpers |
| 495 | .map(s => helperNameMap[s]) |
| 496 | .join(', ')} } from ${JSON.stringify(runtimeModuleName)}\n`, |
| 497 | NewlineType.End, |
| 498 | ) |
| 499 | push( |
| 500 | `\n// Binding optimization for webpack code-split\nconst ${helpers |
| 501 | .map(s => `_${helperNameMap[s]} = ${helperNameMap[s]}`) |
| 502 | .join(', ')}\n`, |
| 503 | NewlineType.End, |
| 504 | ) |
| 505 | } else { |
| 506 | push( |
| 507 | `import { ${helpers |
| 508 | .map(s => `${helperNameMap[s]} as _${helperNameMap[s]}`) |
| 509 | .join(', ')} } from ${JSON.stringify(runtimeModuleName)}\n`, |
| 510 | NewlineType.End, |
| 511 | ) |
| 512 | } |
| 513 | } |
| 514 | |
| 515 | if (ast.ssrHelpers && ast.ssrHelpers.length) { |
| 516 | push( |
| 517 | `import { ${ast.ssrHelpers |
| 518 | .map(s => `${helperNameMap[s]} as _${helperNameMap[s]}`) |
| 519 | .join(', ')} } from "${ssrRuntimeModuleName}"\n`, |
| 520 | NewlineType.End, |
| 521 | ) |
| 522 | } |
| 523 | |
| 524 | if (ast.imports.length) { |
| 525 | genImports(ast.imports, context) |
| 526 | newline() |
| 527 | } |