From 3c2f6b9846a13760dbdfd0e91b3d77aedfba0623 Mon Sep 17 00:00:00 2001 From: Adam Hines 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,