@@ -1772,6 +1772,87 @@ test.serial(
17721772 ] ) ;
17731773 } finally {
17741774 await bundle . close ( ) ;
1775+ // tidy emitted file to avoid cross-test interference if ordering changes
1776+ if ( fs . existsSync ( outputJs ) ) fs . unlinkSync ( outputJs ) ;
17751777 }
17761778 }
17771779) ;
1780+
1781+ test . serial ( 'recreates typeChecker-based transformers per rebuild in watch mode' , async ( t ) => {
1782+ const observations = [ ] ;
1783+
1784+ const dirName = path . join ( __dirname , 'fixtures' , 'transformers' ) ;
1785+ const outputJs = path . join ( dirName , 'main.js' ) ;
1786+
1787+ // ensure a clean slate for emitted file
1788+ if ( fs . existsSync ( outputJs ) ) {
1789+ fs . unlinkSync ( outputJs ) ;
1790+ }
1791+
1792+ const bundle = await rollup ( {
1793+ input : 'fixtures/transformers/main.ts' ,
1794+ plugins : [
1795+ typescript ( {
1796+ tsconfig : false ,
1797+ compilerOptions : { module : 'esnext' } ,
1798+ // Fake TS that simulates two watch rebuilds, each returning a distinct TypeChecker
1799+ typescript : fakeTypescript ( {
1800+ createWatchProgram ( host ) {
1801+ const makeBuilder = ( id , value ) => {
1802+ const innerTypeChecker = { id : `tc-${ id } ` } ;
1803+ const innerProgram = {
1804+ getTypeChecker ( ) {
1805+ return innerTypeChecker ;
1806+ }
1807+ } ;
1808+ return {
1809+ getProgram ( ) {
1810+ return innerProgram ;
1811+ } ,
1812+ emit ( _ , writeFile ) {
1813+ writeFile ( outputJs , `export default ${ value } ;` ) ;
1814+ }
1815+ } ;
1816+ } ;
1817+
1818+ const p1 = makeBuilder ( 'one' , 101 ) ;
1819+ host . afterProgramCreate ( p1 ) ;
1820+ p1 . emit ( ) ;
1821+
1822+ const p2 = makeBuilder ( 'two' , 202 ) ;
1823+ host . afterProgramCreate ( p2 ) ;
1824+ p2 . emit ( ) ;
1825+
1826+ return { close ( ) { } } ;
1827+ }
1828+ } ) ,
1829+ transformers : {
1830+ before : [
1831+ {
1832+ type : 'typeChecker' ,
1833+ factory ( typeChecker ) {
1834+ observations . push ( typeChecker && typeChecker . id ) ;
1835+ // no-op transformer
1836+ return function passthroughFactory ( context ) {
1837+ return function passthrough ( source ) {
1838+ return ts . visitEachChild ( source , ( n ) => n , context ) ;
1839+ } ;
1840+ } ;
1841+ }
1842+ }
1843+ ]
1844+ }
1845+ } )
1846+ ] ,
1847+ onwarn
1848+ } ) ;
1849+
1850+ try {
1851+ await getCode ( bundle , { format : 'esm' , dir : dirName } , true ) ;
1852+ t . deepEqual ( observations , [ 'tc-one' , 'tc-two' ] ) ;
1853+ } finally {
1854+ await bundle . close ( ) ;
1855+ // tidy emitted file to avoid cross-test interference if ordering changes
1856+ if ( fs . existsSync ( outputJs ) ) fs . unlinkSync ( outputJs ) ;
1857+ }
1858+ } ) ;
0 commit comments