Skip to content

Commit

Permalink
feat: ✨ support sideEffects option for strict tree shaking
Browse files Browse the repository at this point in the history
  • Loading branch information
hemengke1997 committed Dec 4, 2022
1 parent 48d3ff5 commit 1348438
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 3 deletions.
Binary file removed screenshots/ts.gif
Binary file not shown.
6 changes: 6 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ export interface VitePluginOptions {
* @default true
*/
hash?: boolean
/**
* @description treat `input` as sideEffect or not
* @see https://esbuild.github.io/api/#tree-shaking-and-side-effects
*/
sideEffects?: boolean
}

const defaultOptions: Required<VitePluginOptions> = {
Expand All @@ -47,6 +52,7 @@ const defaultOptions: Required<VitePluginOptions> = {
hash: true,
ssrBuild: false,
esbuildOptions: {},
sideEffects: false,
}

export function publicTypescript(options: VitePluginOptions): PluginOption {
Expand Down
29 changes: 26 additions & 3 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { WebSocketServer } from 'vite'
import { normalizePath } from 'vite'
import fg from 'fast-glob'
import fs from 'fs-extra'
import type { BuildResult } from 'esbuild'
import type { BuildResult, Plugin } from 'esbuild'
import { build as esbuild } from 'esbuild'
import type { VitePluginOptions } from '..'
import { name } from '../../package.json'
Expand All @@ -21,11 +21,32 @@ type BuildOptions = {
buildLength: number
} & Required<VitePluginOptions>

const noSideEffectsPlugin: Plugin = {
name: 'no-side-effects',
setup(build) {
// https://github.com/evanw/esbuild/issues/1895#issuecomment-1003404929
build.onResolve({ filter: /.*/ }, async (args) => {
if (args.pluginData) return

const { path, ...rest } = args
rest.pluginData = true
const result = await build.resolve(path, rest)

result.sideEffects = false
return result
})
},
}

export async function build(options: BuildOptions) {
const { filePath, publicDir, esbuildOptions, outputDir } = options
const { filePath, publicDir, esbuildOptions, outputDir, sideEffects } = options

const fileName = path.basename(filePath, path.extname(filePath))

const { plugins = [], ...rest } = esbuildOptions

const esbuildPlugins = sideEffects ? [noSideEffectsPlugin, ...plugins] : plugins

let res: BuildResult
try {
res = await esbuild({
Expand All @@ -38,7 +59,9 @@ export async function build(options: BuildOptions) {
treeShaking: true,
splitting: false,
minify: true,
...esbuildOptions,
plugins: esbuildPlugins,
logLevel: sideEffects ? undefined : 'error',
...rest,
})
} catch (e) {
console.error(`${name} esbuild error:`, e)
Expand Down

0 comments on commit 1348438

Please sign in to comment.