@@ -40,6 +40,7 @@ const PURE_FUNCTIONS = new Set([
4040const EXTENSIONS = [ '' , '.ts' , '.js' ]
4141
4242const SRC_DIR = path . resolve ( __dirname , '../src' )
43+ const DIST_DIR = path . resolve ( __dirname , '../dist' )
4344const VSCODE_DIR = path . resolve ( __dirname , '../vscode' )
4445const NODE_MODULES_DIR = path . resolve ( __dirname , '../node_modules' )
4546const MONACO_EDITOR_DIR = path . resolve ( NODE_MODULES_DIR , './monaco-editor' )
@@ -88,13 +89,13 @@ const external: rollup.ExternalOption = (source) => {
8889 return externals . some ( external => source === external || source . startsWith ( `${ external } /` ) )
8990}
9091
91- export default ( args : Record < string , string > ) : rollup . RollupOptions => {
92+ export default ( args : Record < string , string > ) : rollup . RollupOptions [ ] => {
9293 const vscodeVersion = args [ 'vscode-version' ]
9394 delete args [ 'vscode-version' ]
9495 if ( vscodeVersion == null ) {
9596 throw new Error ( 'Vscode version is mandatory' )
9697 }
97- return rollup . defineConfig ( {
98+ return rollup . defineConfig ( [ {
9899 cache : false ,
99100 treeshake : {
100101 annotations : true ,
@@ -303,17 +304,85 @@ export default (args: Record<string, string>): rollup.RollupOptions => {
303304 right : ').then(module => module.default ?? module)'
304305 }
305306 }
306- } , {
307- name : 'cleanup' ,
308- renderChunk ( code ) {
309- return cleanup ( code , null , {
310- comments : 'none' ,
311- sourcemap : false
312- } ) . code
313- }
314307 }
315308 ]
316- } )
309+ } , {
310+ // 2nd pass to improve treeshaking
311+ cache : false ,
312+ treeshake : {
313+ annotations : true ,
314+ preset : 'smallest' ,
315+ propertyReadSideEffects : false ,
316+ moduleSideEffects ( id ) {
317+ return id . startsWith ( DIST_DIR ) || id . endsWith ( '.css' )
318+ }
319+ } ,
320+ external,
321+ input : Object . values ( input ) . map ( f => `./dist/${ path . basename ( f , '.ts' ) } ` ) ,
322+ output : [ {
323+ format : 'esm' ,
324+ dir : 'dist' ,
325+ entryFileNames : '[name].js' ,
326+ chunkFileNames : '[name].js' ,
327+ hoistTransitiveImports : false
328+ } ] ,
329+ plugins : [ {
330+ name : 'improve-treeshaking' ,
331+ transform ( code ) {
332+ const ast = recast . parse ( code , {
333+ parser : require ( 'recast/parsers/babylon' )
334+ } )
335+ let transformed : boolean = false
336+ function addComment ( node : recast . types . namedTypes . NewExpression | recast . types . namedTypes . CallExpression ) {
337+ if ( ! ( node . comments ?? [ ] ) . some ( comment => comment . value === PURE_ANNO ) ) {
338+ transformed = true
339+ node . comments = [ recast . types . builders . commentBlock ( PURE_ANNO , true ) ]
340+ return recast . types . builders . parenthesizedExpression ( node )
341+ }
342+ return node
343+ }
344+ recast . visit ( ast . program . body , {
345+ visitCallExpression ( path ) {
346+ const node = path . node
347+ if ( node . callee . type === 'MemberExpression' ) {
348+ if ( node . callee . property . type === 'Identifier' ) {
349+ const name = getMemberExpressionPath ( node . callee )
350+ if ( ( name != null && PURE_FUNCTIONS . has ( name ) ) || PURE_FUNCTIONS . has ( node . callee . property . name ) ) {
351+ path . replace ( addComment ( node ) )
352+ }
353+ }
354+ } else if ( node . callee . type === 'Identifier' && PURE_FUNCTIONS . has ( node . callee . name ) ) {
355+ path . replace ( addComment ( node ) )
356+ } else if ( node . callee . type === 'FunctionExpression' ) {
357+ // Mark IIFE as pure, because typescript compile enums as IIFE
358+ path . replace ( addComment ( node ) )
359+ }
360+ this . traverse ( path )
361+ return undefined
362+ } ,
363+ visitThrowStatement ( ) {
364+ return false
365+ }
366+ } )
367+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
368+ if ( transformed ) {
369+ code = recast . print ( ast ) . code
370+ code = code . replace ( / \/ \* # _ _ P U R E _ _ \* \/ \s + / g, '/*#__PURE__*/ ' ) // Remove space after PURE comment
371+ }
372+ return code
373+ }
374+ } , nodeResolve ( {
375+ extensions : EXTENSIONS
376+ } ) , {
377+ name : 'cleanup' ,
378+ renderChunk ( code ) {
379+ return cleanup ( code , null , {
380+ comments : 'none' ,
381+ sourcemap : false
382+ } ) . code
383+ }
384+ } ]
385+ } ] )
317386}
318387
319388function resolve ( _path : string , fromPaths : string [ ] ) {
0 commit comments