From 3c2f6b9846a13760dbdfd0e91b3d77aedfba0623 Mon Sep 17 00:00:00 2001
From: Adam Hines <ahines@factset.com>
Date: Wed, 11 Jan 2023 17:40:42 -0700
Subject: [PATCH] fix(treeshaking): allowing treeshaking in terser

The code currently generated by this plugin looks something like the following when building a library:

src/index.js
```js
export {default as Foo} from './component.vue';
```

```js
var __component__ = /*#__PURE__*/ normalizeComponent(...)
var Foo = __component__.exports
```

In the event you aren't actually using the Foo export, this code is unable to be dropped because Terser assumes that property access (__component__.exports) is not side-effect free and as a result it decides it can not drop it, and thus it can't drop the rest of the component code.

To work around this, I have wrapped the `__component__.exports` statement in a function so that we can mark the function invokation as `#__PURE__` and thus allow for unused components to be dropped fully.

The resulting code looks like:
```js
var __component__ = /*#__PURE__*/ normalizeComponent(...)
var Foo = /*#__PURE__*/  getExports(__component__)
```
---
 src/main.ts                      | 4 ++--
 src/utils/componentNormalizer.ts | 7 ++++++-
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/src/main.ts b/src/main.ts
index 27d0752..9426879 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -74,7 +74,7 @@ export async function transformMain(
 
   output.push(
     `/* normalize component */
-import __normalizer from "${NORMALIZER_ID}"
+import {normalizeComponent as __normalizer, getExports as __getExports} from "${NORMALIZER_ID}"
 var __component__ = /*#__PURE__*/__normalizer(
   _sfc_main,
   _sfc_render,
@@ -137,7 +137,7 @@ var __component__ = /*#__PURE__*/__normalizer(
 
   let resolvedMap: RawSourceMap | undefined = scriptMap
 
-  output.push(`export default __component__.exports`)
+  output.push(`export default /*#__PURE__*/ __getExports(__component__)`)
 
   // handle TS transpilation
   let resolvedCode = output.join('\n')
diff --git a/src/utils/componentNormalizer.ts b/src/utils/componentNormalizer.ts
index f1c6cee..5b02535 100644
--- a/src/utils/componentNormalizer.ts
+++ b/src/utils/componentNormalizer.ts
@@ -4,7 +4,12 @@ export const NORMALIZER_ID = '\0plugin-vue2:normalizer'
 // This module is a runtime utility for cleaner component module output and will
 // be included in the final webpack user bundle.
 export const normalizerCode = `
-export default function normalizeComponent (
+// Used to facilitate tree-shaking since property access is not guaranteed to be pure
+export function getExports(component) {
+  return component.exports
+}
+
+export function normalizeComponent (
     scriptExports,
     render,
     staticRenderFns,