6

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 angular-fire and firebase to its latest version, tried ng add @angular/fire, configured custom webpack.config.ts, tried rolling back to every suggested previous version. None fixed this issue.

The Actual Error:

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.<anonymous> (/home/de-10/Desktop/dist/server.js:125276:18)
    at __webpack_require__ (/home/de-10/Desktop/dist/server.js:20:30)
    at Module.<anonymous> (/home/de-10/Desktop/dist/server.js:125199:70)
    at __webpack_require__ (/home/de-10/Desktop/dist/server.js:20:30)
    at Module.<anonymous> (/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' ]
}

And I can't let go of Firebase cause then I face:

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<unknown>'.

29                 id: snap.payload.doc.id,
                                        ~~
app/services/notification.service.ts:68:35 - error TS2339: Property 'type' does not exist on type 'DocumentChange<unknown>'.

68               return snap.payload.type
                                     ~~~~
.
.
.

package.json

{
  "name": "universal-ssr",
  "version": "0.0.0",
  "license": "MIT",
  "scripts": {
    "ng": "ng",
    "start": "npm run build:ssr",
    "staging": "npm run build:ssr-staging && npm run serve:ssr",
    "production": "npm run build:ssr && npm run serve:ssr",
    "prod": "npm run build:ssr-production && 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 && npm run webpack:server",
    "build:ssr-staging": "npm run build:client-and-server-bundles-staging && npm run webpack:server",
    "build:ssr-production": "npm run build:client-and-server-bundles-production && npm run webpack:server",
    "serve:ssr": "node dist/server.js",
    "build:client-and-server-bundles": "ng build --prod --build-optimizer && ng run universal-ssr:server --bundleDependencies all",
    "build:client-and-server-bundles-staging": "ng build --c=staging --build-optimizer=true --stats-json  && ng run universal-ssr:server",
    "build:client-and-server-bundles-production": "ng build --c=production --build-optimizer=true  && 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"
  }
}

webpack.config.js:

// 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'),
      {}
    )
  ]
};

server.ts:

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) => {
  res.render('index', { req });
});

// Start up the Node server
app.listen(PORT, () => {
  console.log(`Node Express server listening on http://localhost:${PORT}`);
});

2 Answers 2

4

You're getting this error because you're excluding firebase dependencies with this =>

const regex = /firebase\/(app|firestore)/;
module.exports = {
  // 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();
  }],
};

Remove this

    if (regex.test(request)) {
      return callback(null, 'commonjs ' + request);
    }

and your app will be fine.

Sign up to request clarification or add additional context in comments.

Comments

0

One workaround is to install npm packages (firebase and @angular/fire) beside the dist folder and then run the deployment script.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.