Search code examples
angulartypescripttsconfigangular17angular17-ssr

Angular 17 SSR Separate tsconfig for browser and server


In the recent versions of angular, there is only tsconfig.app.json which inherits from tsconfig.json. The file is used for the browser and server. There is no anymore separate tsconfig.server.json.

I have installed a module that uses document object, which is not supported by SSR. To bypass this, I have created a stub Module, which I would like to replace in the tsconfig, in short like this:

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "paths": {
      "ng2-dragula": [
        "./src/app/stubs/dragula/dragula.module"
      ]
    },
  },
}

So the browser would use the real module, but the SSR the stub module. However, I am not able to specify to use of a separate tsconfig for the SSR.

I use the latest Angular version 17.2.


Solution

  • There is no way to use a separate tsconfig.json for the server version of the app just because there is no separate server version anymore. But it seems that it is an A/B problem and what you want to do is to make your app using ng2-dragula work with SSR.

    Here is how you can do this. If you're using standalone components that import DragulaModule you can wrap them into @defer block so angular extracts them into separate chunks that won't be run on the server.

    Example:

    @Component({
      selector: 'app-root',
      standalone: true,
      imports: [WithDragulaComponent],
      template: `
        @defer{
          <app-with-dragula/>
        } @error {
          Something went wrong :(
        }`,
      styleUrl: './app.component.scss'
    })
    export class AppComponent {}
    
    @Component({
      selector: 'app-with-dragula',
      standalone: true,
      imports: [DragulaModule],
      template: `
        <div class="container" dragula="DRAGULA_FACTS">
          <div>You can move these elements between these two containers</div>
          <div>Moving them anywhere else isn't quite possible</div>
          <div>There's also the possibility of moving elements around in the same container, changing their position</div>
        </div>
      `,
      styleUrl: './with-dragula.component.scss'
    })
    export class WithDragulaComponent {
    
    }
    

    Don't forget to add another ng2-dragula required workaround to the main.ts:

    (window as any).global = window;