Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
4fdc0f5
Initial plan
Copilot Jul 31, 2025
eef351e
Initial exploration and test setup for lib mode terser minification
Copilot Jul 31, 2025
05b379d
feat: enable minify for lib mode es output + build.minify: 'terser'
Copilot Jul 31, 2025
d828c58
feat: address PR feedback - remove ES lib condition and update terser…
Copilot Aug 1, 2025
2b0d3b3
feat: add pure annotation test and function call in lib mode
Copilot Aug 1, 2025
82eb360
Address PR review feedback: update regex pattern and simplify tests
Copilot Aug 1, 2025
9b92f43
test: update test description for pure annotations with terser
Copilot Aug 1, 2025
4685306
feat: update pure annotations test to check functional behavior inste…
Copilot Aug 1, 2025
98f797c
feat: implement Object.assign pure annotation as requested but preser…
Copilot Aug 1, 2025
4b346e4
remove drop_console
sapphi-red Aug 7, 2025
9365cb5
Address PR feedback: remove drop_console, add debugger test, and clea…
Copilot Aug 7, 2025
c2987ff
update
sapphi-red Aug 7, 2025
c76da0f
update
sapphi-red Aug 8, 2025
6b43682
update
sapphi-red Aug 8, 2025
811918c
update
sapphi-red Aug 8, 2025
55a32a8
update
sapphi-red Aug 8, 2025
59bdf7d
Address PR feedback: remove debugger test, update pure annotation tes…
Copilot Aug 8, 2025
43074bb
Revert "Address PR feedback: remove debugger test, update pure annota…
sapphi-red Aug 8, 2025
b01bef7
chore: update
sapphi-red Aug 12, 2025
dc3b0bf
chore: update
sapphi-red Aug 12, 2025
dbcbc41
test: add test for iife terser
sapphi-red Aug 20, 2025
51ad184
fix: respect `preserve_annotations` for non-es output
sapphi-red Aug 20, 2025
223dff8
chore: merge main
sapphi-red Aug 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions packages/vite/src/node/plugins/terser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,6 @@ export function terserPlugin(config: ResolvedConfig): Plugin {
return null
}

// Do not minify ES lib output since that would remove pure annotations
// and break tree-shaking.
if (config.build.lib && outputOptions.format === 'es') {
return null
}

// Lazy load worker.
worker ||= makeWorker()

Expand All @@ -110,6 +104,14 @@ export function terserPlugin(config: ResolvedConfig): Plugin {
const res = await worker.run(terserPath, code, {
safari10: true,
...terserOptions,
format: {
...terserOptions.format,
// For ES lib mode, preserve comments to keep pure annotations for tree-shaking
preserve_annotations:
config.build.lib && outputOptions.format === 'es'
? true
: terserOptions.format?.preserve_annotations,
},
sourceMap: !!outputOptions.sourcemap,
module: outputOptions.format.startsWith('es'),
toplevel: outputOptions.format === 'cjs',
Expand Down
15 changes: 15 additions & 0 deletions playground/lib/__tests__/lib.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,21 @@ describe.runIf(isBuild)('build', () => {
expect(umd).toMatch('process.env.NODE_ENV')
})

test('debugger statements are removed by terser for es', () => {
const terserEs = readFile('dist/terser/my-lib-custom-filename.js')
expect(terserEs).not.toMatch('debugger')
})

test('pure annotations are not removed by terser for es', () => {
const terserEs = readFile('dist/terser/my-lib-custom-filename.js')
expect(terserEs).toMatch(/[@#]__PURE__/)
})

test('pure annotations are removed by terser for non-es output', () => {
const terserIife = readFile('dist/terser/my-lib-custom-filename.iife.js')
expect(terserIife).not.toMatch(/[@#]__PURE__/)
})

test('single entry with css', () => {
const css = readFile('dist/css-single-entry/test-my-lib.css')
const js = readFile('dist/css-single-entry/test-my-lib.js')
Expand Down
6 changes: 6 additions & 0 deletions playground/lib/__tests__/serve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ export async function serve(): Promise<{ close(): Promise<void> }> {
configFile: path.resolve(__dirname, '../vite.css-code-split.config.js'),
})

await build({
root: rootDir,
logLevel: 'warn', // output esbuild warns
configFile: path.resolve(__dirname, '../vite.terser.config.js'),
})

// start static file server
const serve = sirv(path.resolve(rootDir, 'dist'))
const httpServer = http.createServer((req, res) => {
Expand Down
7 changes: 5 additions & 2 deletions playground/lib/src/main.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export default function myLib(sel) {
export default /* @__PURE__ */ Object.assign(function myLib(sel) {
// Force esbuild spread helpers (https://github.com/evanw/esbuild/issues/951)
console.log({ ...'foo' })

Expand All @@ -9,7 +9,10 @@ export default function myLib(sel) {

// make sure umd helper has been moved to the right position
console.log(`amd function(){ "use strict"; }`)
}

// eslint-disable-next-line no-debugger
debugger
})

// For triggering unhandled global esbuild helpers in previous regex-based implementation for injection
;(function () {})()?.foo
24 changes: 24 additions & 0 deletions playground/lib/vite.terser.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import path from 'node:path'
import { defineConfig } from 'vite'
import baseConfig from './vite.config'

export default defineConfig({
...baseConfig,
build: {
...baseConfig.build,
minify: 'terser',
terserOptions: {
compress: {
drop_debugger: true,
},
},
outDir: 'dist/terser',
lib: {
...baseConfig.build.lib,
entry: path.resolve(__dirname, 'src/main.js'),
formats: ['es', 'iife'],
},
},
plugins: [],
cacheDir: 'node_modules/.vite-terser',
})
Loading