title: Cannot find module 'firebase/app' while deploying Angular Universal app
body: <p>I'm dealing with this issue for almost two weeks now. I tried a lot of workarounds but none seems to be working. I've installed <code>angular-fire</code> and <code>firebase</code> to its latest version, tried <code>ng add @angular/fire</code>, configured custom <code>webpack.config.ts</code>, tried rolling back to every suggested previous version. None fixed this issue.</p>
  
  <p>The Actual Error:</p>
  
  <pre class="lang-sh prettyprint-override"><code>de-10@de10-LIFEBOOK-A555:~/Desktop$ node dist/server.js 
  internal/modules/cjs/loader.js:797
      throw err;
      ^
  
  Error: Cannot find module 'firebase/app'
  Require stack:
  - /home/de-10/Desktop/dist/server.js
      at Function.Module._resolveFilename (internal/modules/cjs/loader.js:794:15)
      at Function.Module._load (internal/modules/cjs/loader.js:687:27)
      at Module.require (internal/modules/cjs/loader.js:849:19)
      at require (internal/modules/cjs/helpers.js:74:18)
      at Object.&lt;anonymous&gt; (/home/de-10/Desktop/dist/server.js:125276:18)
      at __webpack_require__ (/home/de-10/Desktop/dist/server.js:20:30)
      at Module.&lt;anonymous&gt; (/home/de-10/Desktop/dist/server.js:125199:70)
      at __webpack_require__ (/home/de-10/Desktop/dist/server.js:20:30)
      at Module.&lt;anonymous&gt; (/home/de-10/Desktop/dist/server.js:124984:78)
      at __webpack_require__ (/home/de-10/Desktop/dist/server.js:20:30) {
    code: 'MODULE_NOT_FOUND',
    requireStack: [ '/home/de-10/Desktop/dist/server.js' ]
  }
  </code></pre>
  
  <p>And I can't let go of Firebase cause then I face:</p>
  
  <pre class="lang-sh prettyprint-override"><code>ERROR in ../node_modules/@angular/fire/auth/auth.d.ts:4:28 - error TS2307: Cannot find module 'firebase/app'.
  
  4 import { User, auth } from 'firebase/app';
                               ~~~~~~~~~~~~~~
  ../node_modules/@angular/fire/firebase.app.module.d.ts:2:74 - error TS2307: Cannot find module 'firebase/app'.
  
  2 import { auth, database, messaging, storage, firestore, functions } from 'firebase/app';
                                                                             ~~~~~~~~~~~~~~
  ../node_modules/@angular/fire/firestore/collection-group/collection-group.d.ts:2:27 - error TS2307: Cannot find module 'firebase/app'.
                              ~~~~~~~~~~~~~
  .
  .
  .
  app/services/notification.service.ts:29:38 - error TS2339: Property 'id' does not exist on type 'QueryDocumentSnapshot&lt;unknown&gt;'.
  
  29                 id: snap.payload.doc.id,
                                          ~~
  app/services/notification.service.ts:68:35 - error TS2339: Property 'type' does not exist on type 'DocumentChange&lt;unknown&gt;'.
  
  68               return snap.payload.type
                                       ~~~~
  .
  .
  .
  </code></pre>
  
  <p>package.json</p>
  
  <pre><code>{
    "name": "universal-ssr",
    "version": "0.0.0",
    "license": "MIT",
    "scripts": {
      "ng": "ng",
      "start": "npm run build:ssr",
      "staging": "npm run build:ssr-staging &amp;&amp; npm run serve:ssr",
      "production": "npm run build:ssr &amp;&amp; npm run serve:ssr",
      "prod": "npm run build:ssr-production &amp;&amp; npm run serve:ssr",
      "build": "ng build --prod",
      "test": "ng test",
      "dev-start": "ng serve",
      "ng serve": "ng serve --aot",
      "lint": "ng lint",
      "e2e": "ng e2e",
      "build:ssr": "npm run build:client-and-server-bundles &amp;&amp; npm run webpack:server",
      "build:ssr-staging": "npm run build:client-and-server-bundles-staging &amp;&amp; npm run webpack:server",
      "build:ssr-production": "npm run build:client-and-server-bundles-production &amp;&amp; npm run webpack:server",
      "serve:ssr": "node dist/server.js",
      "build:client-and-server-bundles": "ng build --prod --build-optimizer &amp;&amp; ng run universal-ssr:server --bundleDependencies all",
      "build:client-and-server-bundles-staging": "ng build --c=staging --build-optimizer=true --stats-json  &amp;&amp; ng run universal-ssr:server",
      "build:client-and-server-bundles-production": "ng build --c=production --build-optimizer=true  &amp;&amp; ng run universal-ssr:server --bundleDependencies all",
      "webpack:server": "webpack --config webpack.config.js --progress --colors",
      "webpack:analyzer": "webpack-bundle-analyzer dist/browser/stats.json",
      "compodoc": "npx compodoc -p src/tsconfig.app.json -o"
    },
    "private": true,
    "dependencies": {
      "@angular/animations": "^8.2.14",
      "@angular/cdk": "^5.2.5",
      "@angular/common": "^8.2.14",
      "@angular/compiler": "^8.2.14",
      "@angular/core": "^8.2.14",
      "@angular/fire": "^5.4.2",
      "@angular/forms": "^8.2.14",
      "@angular/material": "^5.2.5",
      "@angular/platform-browser": "^8.2.14",
      "@angular/platform-browser-dynamic": "^8.2.14",
      "@angular/platform-server": "^8.2.14",
      "@angular/pwa": "^0.803.24",
      "@angular/router": "^8.2.14",
      "@angular/service-worker": "^8.2.14",
      "@ng-bootstrap/ng-bootstrap": "^4.0.0",
      "@nguniversal/express-engine": "^6.1.0",
      "@nguniversal/module-map-ngfactory-loader": "^6.1.0",
      "angular2-datetimepicker": "^1.1.1",
      "bootstrap": "^4.4.1",
      "city-timezones": "^1.2.0",
      "core-js": "^2.6.11",
      "cors": "^2.8.4",
      "express": "^4.17.1",
      "firebase": "^7.13.1",
      "jquery": "^3.4.1",
      "moment-timezone": "^0.5.27",
      "ng-bootstrap": "^1.6.3",
      "ng2-search-filter": "^0.5.1",
      "ngx-clipboard": "12.2.1",
      "ngx-google-places-autocomplete": "^2.0.4",
      "ngx-pagination": "^3.3.1",
      "ngx-spinner": "^2.0.0",
      "ngx-toggle-switch": "^2.0.5",
      "ngx-ui-switch": "^8.3.0",
      "rxjs": "^6.5.4",
      "rxjs-compat": "^6.0.0",
      "save": "^2.4.0",
      "ts-loader": "^4.0.0",
      "tslib": "^1.10.0",
      "uuid": "^3.4.0",
      "zone.js": "~0.9.1"
    },
    "devDependencies": {
      "@angular-devkit/build-angular": "~0.803.23",
      "@angular/cli": "^8.3.23",
      "@angular/compiler-cli": "^8.2.14",
      "@angular/http": "^7.2.16",
      "@angular/language-service": "^8.2.14",
      "@types/jasmine": "2.8.3",
      "@types/jasminewd2": "^2.0.8",
      "@types/node": "^6.14.9",
      "codelyzer": "^5.0.1",
      "jasmine-core": "~2.8.0",
      "jasmine-spec-reporter": "~4.2.1",
      "karma": "^4.4.1",
      "karma-chrome-launcher": "~2.2.0",
      "karma-coverage-istanbul-reporter": "^2.1.1",
      "karma-jasmine": "~1.1.0",
      "karma-jasmine-html-reporter": "^0.2.2",
      "protractor": "5.4.2",
      "ts-node": "~4.1.0",
      "tslint": "~5.9.1",
      "typescript": "~3.5.3",
      "webpack-cli": "^3.1.0"
    }
  }
  </code></pre>
  
  <p>webpack.config.js:</p>
  
  <pre class="lang-js prettyprint-override"><code>// Work around for https://github.com/angular/angular-cli/issues/7200
  
  const path = require('path');
  const webpack = require('webpack');
  // change the regex to include the packages you want to exclude
  const regex = /firebase\/(app|firestore)/;
  
  
  module.exports = {
    mode: 'production',
    entry: {
      // This is our Express server for Dynamic universal
      server: './server.ts'
    },
    externals: {
      './dist/server/main': 'require("./server/main")'
    },
    target: 'node',
    node: {
      __dirname: false,
      __filename: false,
    },
    resolve: { extensions: ['.ts', '.js'] },
    target: 'node',
    mode: 'none',
    // this makes sure we include node_modules and other 3rd party libraries
    externals: [/node_modules/, function (context, request, callback) {
      // exclude firebase products from being bundled, so they will be loaded using require() at runtime.
      if (regex.test(request)) {
        return callback(null, 'commonjs ' + request);
      }
      callback();
    }],
    optimization: {
      minimize: false
    },
    output: {
      // Puts the output at the root of the dist folder
      path: path.join(__dirname, 'dist'),
      filename: '[name].js'
    },
    module: {
      noParse: /polyfills-.*\.js/,
      rules: [
        { test: /\.ts$/, loader: 'ts-loader' },
        {
          // Mark files inside `@angular/core` as using SystemJS style dynamic imports.
          // Removing this will cause deprecation warnings to appear.
          test: /(\\|\/)@angular(\\|\/)core(\\|\/).+\.js$/,
          parser: { system: true },
        },
      ]
    },
    plugins: [
      new webpack.ContextReplacementPlugin(
        // fixes WARNING Critical dependency: the request of a dependency is an expression
        /(.+)?angular(\\|\/)core(.+)?/,
        path.join(__dirname, 'src'), // location of your src
        {} // a map of your routes
      ),
      new webpack.ContextReplacementPlugin(
        // fixes WARNING Critical dependency: the request of a dependency is an expression
        /(.+)?express(\\|\/)(.+)?/,
        path.join(__dirname, 'src'),
        {}
      )
    ]
  };
  </code></pre>
  
  <p>server.ts:</p>
  
  <pre><code>import 'zone.js/dist/zone-node';
  import * as express from 'express';
  /* const express = require('express');
  const join = require('path'); */
  const compression = require('compression')
  import { join } from 'path';
  // Express server
  
  const app = express();
  // gzip
  app.use(compression())
  
  
  const PORT = process.env.PORT || 4000;
  const DIST_FOLDER = join(__dirname, 'browser');/* 'dist/browser' */
  // * NOTE :: leave this as require() since this file is built Dynamically from webpack
  const { AppServerModuleNgFactory, LAZY_MODULE_MAP, ngExpressEngine, provideModuleMap } = require('./dist/server/main');
  // Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
  app.engine('html', ngExpressEngine({
    bootstrap: AppServerModuleNgFactory,
    providers: [
      provideModuleMap(LAZY_MODULE_MAP)
    ]
  }));
  
  app.set('view engine', 'html');
  app.set('views', DIST_FOLDER);
  
  // Serve static files from /browser
  app.get('*.*', express.static(DIST_FOLDER, {
    maxAge: '1y'
  }));
  
  // All regular routes use the Universal engine
  app.get('*', (req, res) =&gt; {
    res.render('index', { req });
  });
  
  // Start up the Node server
  app.listen(PORT, () =&gt; {
    console.log(`Node Express server listening on http://localhost:${PORT}`);
  });
  </code></pre>