Angular server side rendering issue [Zone already loaded] - node.js

I am able to build app for server side rendering but when i run server.ts file i get this error.
Commands:
"build:ssr": "npm run build:client-and-server-bundles && npm run webpack:server",
"serve:ssr": "node dist/server.js",
"build:client-and-server-bundles": "ng build --prod && ng build --prod --app 1 --output-hashing=false",
"webpack:server": "node --max_old_space_size=5110 ./node_modules/webpack/bin/webpack.js --config webpack.server.config.js --progress --colors",
I tried to find zone.js in whole project but only find it in polyfills.js and server.ts file. I tried to comment and in server.ts file zone import line and build it again, but it din't work. I also tried to comment it in polyfills.js and build it again but it did not work.
I am not able to find issue what cause it? Any help would be appreciated. You can find some configuration file below. If you need any other file, comment it.
This issue only occurs when i tried to implement server side rendering. Otherwise without it, it is working fine.
.angular-cli.json
{
"$schema": "./node_modules/#angular/cli/lib/config/schema.json",
"project": {
"version": "1.0.0",
"name": "demo"
},
"apps": [
{
"root": "src",
"outDir": "dist/browser",
"assets": [
"assets"
],
"index": "index.html",
"main": "main.ts",
"polyfills": "polyfills.ts",
"test": "test.ts",
"tsconfig": "tsconfig.app.json",
"testTsconfig": "tsconfig.spec.json",
"prefix": "app",
"styles": [
"../node_modules/font-awesome/scss/font-awesome.scss",
"../node_modules/simple-line-icons/css/simple-line-icons.css",
"scss/style.scss",
"../node_modules/primeng/resources/themes/omega/theme.scss",
"../node_modules/primeng/resources/primeng.min.css",
"../node_modules/ng2-toastr/bundles/ng2-toastr.min.css",
"../node_modules/npm-font-open-sans/open-sans.scss"
],
"scripts": [
],
"environmentSource": "environments/environment.ts",
"environments": {
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
}
},
{
"platform": "server",
"root": "src",
"outDir": "dist/server",
"assets": [
"assets",
"assets"
],
"index": "index.html",
"main": "main.server.ts",
"test": "test.ts",
"tsconfig": "tsconfig.server.json",
"testTsconfig": "tsconfig.spec.json",
"prefix": "app",
"styles": [
"../node_modules/font-awesome/scss/font-awesome.scss",
"../node_modules/simple-line-icons/css/simple-line-icons.css",
"scss/style.scss",
"../node_modules/primeng/resources/themes/omega/theme.scss",
"../node_modules/primeng/resources/primeng.min.css",
"../node_modules/ng2-toastr/bundles/ng2-toastr.min.css",
"../node_modules/npm-font-open-sans/open-sans.scss"
],
"scripts": [],
"environmentSource": "environments/environment.ts",
"environments": {
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
}
}
],
"e2e": {
"protractor": {
"config": "./protractor.conf.js"
}
},
"lint": [
{
"project": "src/tsconfig.app.json"
},
{
"project": "src/tsconfig.spec.json"
},
{
"project": "e2e/tsconfig.e2e.json"
}
],
"test": {
"karma": {
"config": "./karma.conf.js"
}
},
"defaults": {
"styleExt": "scss",
"prefixInterfaces": false
}
}
webpack.server.config.js
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: { server: './server.ts' },
resolve: { extensions: ['.js', '.ts'] },
target: 'node',
// this makes sure we include node_modules and other 3rd party libraries
externals: [/(node_modules|main\..*\.js)/],
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].js'
},
module: {
rules: [
{ test: /\.ts$/, loader: 'ts-loader' },
{ test: /\.(ts|js)$/, loader: 'regexp-replace-loader', query: { match: { pattern: '\\[(Mouse|Keyboard)Event\\]', flags: 'g' }, replaceWith: '[]', } }
]
},
plugins: [
// Temporary Fix for issue: https://github.com/angular/angular/issues/11580
// for "WARNING Critical dependency: the request of a dependency is an expression"
new webpack.ContextReplacementPlugin(
/(.+)?angular(\\|\/)core(.+)?/,
path.join(__dirname, 'src'), // location of your src
{} // a map of your routes
),
new webpack.ContextReplacementPlugin(
/(.+)?express(\\|\/)(.+)?/,
path.join(__dirname, 'src'),
{}
)
]
}
server.ts
//import 'zone.js/dist/zone-node';
import 'reflect-metadata';
import { renderModuleFactory } from '#angular/platform-server';
import { enableProdMode } from '#angular/core';
import * as express from 'express';
import { join } from 'path';
import { readFileSync } from 'fs';
// Faster server renders w/ Prod mode (dev mode never needed)
enableProdMode();
// Express server
const app = express();
const PORT = process.env.PORT || 4000;
const DIST_FOLDER = join(process.cwd(), 'dist');
// Our index.html we'll use as our template
const template = readFileSync(join(DIST_FOLDER, 'browser', 'index.html')).toString();
// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./dist/server/main.bundle');
const { provideModuleMap } = require('#nguniversal/module-map-ngfactory-loader');
app.engine('html', (_, options, callback) => {
renderModuleFactory(AppServerModuleNgFactory, {
// Our index.html
document: template,
url: options.req.url,
// DI so that we can get lazy-loading to work differently (since we need it to just instantly render it)
extraProviders: [
provideModuleMap(LAZY_MODULE_MAP)
]
}).then(html => {
callback(null, html);
});
});
app.set('view engine', 'html');
app.set('views', join(DIST_FOLDER, 'browser'));
// Server static files from /browser
app.get('*.*', express.static(join(DIST_FOLDER, 'browser')));
// All regular routes use the Universal engine
app.get('*', (req, res) => {
res.render(join(DIST_FOLDER, 'browser', 'index.html'), { req });
});
// Start up the Node server
app.listen(PORT, () => {
console.log(`Node server listening on http://localhost:${PORT}`);
});
Package.json
{
"name": "test",
"version": "1.0.0",
"description": "desc",
"author": "",
"homepage": "http://www.test.com/",
"copyright": "Copyright 2017",
"license": "MIT",
"scripts": {
"ng": "ng",
"start": "ng serve --port=3333 --live-reload false",
"build": "ng build --prod --aot=true",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"build:ssr": "npm run build:client-and-server-bundles && npm run webpack:server",
"serve:ssr": "node dist/server.js",
"build:client-and-server-bundles": "ng build --prod && ng build --prod --app 1 --output-hashing=false",
"webpack:server": "node --max_old_space_size=5110 ./node_modules/webpack/bin/webpack.js --config webpack.server.config.js --progress --colors",
"compile": "node_modules\\.bin\\webpack.cmd"
},
"private": true,
"dependencies": {
"#angular-devkit/core": "^0.6.0",
"#angular/animations": "5.2.0", // old: 5.2.3
"#angular/common": "5.2.0", // old: 5.2.3
"#angular/compiler": "5.2.0", // old: 5.2.3
"#angular/core": "5.2.0", // old: 5.2.3
"#angular/forms": "5.2.0", // old: 5.2.3
"#angular/http": "5.2.0", // old: 5.2.3
"#angular/platform-browser": "5.2.0", // old: 5.2.3
"#angular/platform-browser-dynamic": "5.2.0", // old: 5.2.3
"#angular/platform-server": "5.2.0", // old: 5.2.3
"#angular/router": "5.2.0", // old: 5.2.3
"#angular/upgrade": "5.2.0", // old: 5.2.3
"#nguniversal/module-map-ngfactory-loader": "^5.0.0",
"#swimlane/ngx-charts": "^7.1.1",
"amazon-cognito-identity-js": "^2.0.2",
"aws-sdk": "^2.212.1",
"bootstrap": "4.0.0",
"core-js": "2.5.3",
"d3": "^5.0.0",
"font-awesome": "^4.7.0",
"moment": "2.20.1",
"ng2-toastr": "^4.1.2",
"ngx-bootstrap": "2.0.2",
"ngx-loading": "^1.0.14",
"ngx-treeview": "^2.0.5",
"npm-font-open-sans": "^1.1.0",
"primeng": "^5.2.0-rc.2",
"regexp-replace-loader": "^1.0.1",
"rxjs": "5.5.6",
"simple-line-icons": "^2.4.1",
"string-replace-loader": "^2.1.1",
"ts-helpers": "1.1.2",
"ts-loader": "^4.2.0",
"webpack": "^4.6.0",
"webpack-dev-server": "^3.1.1",
"zone.js": "0.8.12" // old: 0.8.20
},
"devDependencies": {
"#angular/cli": "1.6.3", // old: 1.6.6
"#angular/compiler-cli": "5.2.0", // old: 5.2.3
"#types/jasmine": "2.8.6",
"#types/node": "^10.0.3",
"codelyzer": "4.1.0",
"jasmine-core": "2.9.1",
"jasmine-spec-reporter": "4.2.1",
"karma": "2.0.0",
"karma-chrome-launcher": "2.2.0",
"karma-cli": "1.0.1",
"karma-coverage-istanbul-reporter": "1.4.1",
"karma-jasmine": "1.1.1",
"karma-jasmine-html-reporter": "0.2.2",
"protractor": "5.3.0",
"ts-node": "4.1.0",
"tslint": "5.9.1",
"typescript": "^2.6.0-rc", // old: 2.6.6
"webpack-cli": "^2.1.2"
},
"engines": {
"node": ">= 6.9.0",
"npm": ">= 3.0.0"
}
}

To fix this you have to search for zone.js/dist/zone import in node modules and then you have two variants to fix this. First is to comment this import or just update library (in my case (ng2-dnd) in a new release this line was gone). But I'm pretty sure that when you fix this error you'll get something like "Cannot find module '.'". This error was caused by #swimlane/ngx-charts library. Some charts cause an error, in my case it's ngx-charts-line-chart.
Hope this will be helpful for you and will save someone's time in the future (I waste three days to solve this).

This issue will be better handled in the next version of zone.js, if zone is loaded, we will not throw error when reloading.

Related

Why is contextBridge not being imported in my Electron app?

I'm writing an Electron app with React and Typescript, using Webpack, Babel and ESLint but I'm having trouble setting:
mainWindow = new BrowserWindow({
title: "Biomech",
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
enableRemoteModule: false,
sandbox: true,
preload: path.join(__dirname, "./preload.js"),
nativeWindowOpen: true,
},
});
which I want as a security measure.
The reason being that, if I set the webPreferences as specified above, I need to use contextBridge and a preload script that binds the functions that are using IPC to the window. And the problem is that contextBridge is not being properly imported in my preload.ts:
import { contextBridge, ipcRenderer } from "electron";
import { readFileSync } from 'fs';
import { History } from 'history';
import { LIST_DRIVE_FILES_CHANNEL, LOAD_PREV_TEST_RESULTS_CHANNEL, OAUTH2_ACCESS_TOKEN_REQUEST_CHANNEL } from "../src/constants/ipcChannels";
import { VISUALIZE_RESULTS_PATH } from "../src/constants/urls";
// Expose protected methods that allow the renderer process to use
// the ipcRenderer without exposing the entire object
contextBridge.exposeInMainWorld(
"api", {
exchangeCodeForAccessToken: (code: string) => {
ipcRenderer.invoke(OAUTH2_ACCESS_TOKEN_REQUEST_CHANNEL, code);
},
listDriveFiles: (accessToken: string) => {
ipcRenderer.invoke(LIST_DRIVE_FILES_CHANNEL, accessToken);
},
openDirectoryDialog: (history: History) => {
ipcRenderer.invoke(LOAD_PREV_TEST_RESULTS_CHANNEL).then((dialog: any) => {
if (dialog.canceled) { // canceled with one l is correct
return;
} else {
const selectedDirectory = dialog.filePaths[0];
console.log(readFileSync(selectedDirectory + "/README.md", 'utf-8'));
history.push(VISUALIZE_RESULTS_PATH);
}
})
}
}
);
The way I see it it's properly used like the examples I've seen here in SO, or in the Electron docs. But when I run my main process script: npm run dev:electron which is specified in my package.json:
{
"name": "electron-react-ts-app",
"version": "1.0.0",
"description": "Electron + React + Typescript",
"main": "./dist/main.js",
"preload": "./dist/preload.js",
"scripts": {
"dev": "concurrently --success first \"npm run dev:electron\" \"npm run dev:react\" -k",
"dev:electron": "NODE_ENV=development webpack --config webpack.electron.config.js --mode development && electron .",
"dev:react": "NODE_ENV=development webpack serve --config webpack.react.config.js --mode development",
"build:electron": "NODE_ENV=production webpack --config webpack.electron.config.js --mode production",
"build:react": "NODE_ENV=production webpack --config webpack.react.config.js --mode production",
"build": "npm run build:electron && npm run build:react",
"pack": "electron-builder --dir",
"dist": "electron-builder",
"lint": "eslint .",
"format": "prettier --write \"**/*.+(js|jsx|json|yml|yaml|css|md|vue)\""
},
"keywords": [],
"license": "MIT",
"build": {
"files": [
"dist/",
"node_modules/",
"package.json"
],
"productName": "Example",
"appId": "com.example.app",
"directories": {
"output": "dist"
}
},
"devDependencies": {
"#babel/preset-env": "^7.9.5",
"#babel/preset-react": "^7.9.4",
"#babel/preset-typescript": "^7.9.0",
"#types/electron-devtools-installer": "^2.2.0",
"#types/react-router-dom": "^5.1.7",
"#types/regenerator-runtime": "^0.13.0",
"dpdm": "^3.6.0",
"electron": "^11.2.1",
"electron-builder": "^22.7.0",
"electron-devtools-installer": "^3.1.1",
"eslint": "^7.18.0",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^4.5.1",
"husky": "^4.3.8",
"lint-staged": "^10.5.3",
"prettier": "^2.2.1",
"react-router-dom": "^5.2.0",
"webpack": "^5.11.1",
"webpack-cli": "^4.3.1",
"webpack-dev-server": "^3.11.1"
},
"dependencies": {
"#babel/core": "^7.12.10",
"#popperjs/core": "^2.6.0",
"#types/node": "^14.14.22",
"#types/react": "^17.0.0",
"#types/react-dom": "^17.0.0",
"axios": "^0.21.1",
"babel-loader": "^8.2.2",
"bootstrap": "^4.5.3",
"chokidar": "^3.5.1",
"core-js": "^3.8.3",
"css-loader": "^5.0.1",
"electron-fetch": "^1.7.3",
"fsevents": "^2.3.1",
"ini": "^2.0.0",
"jquery": "^3.5.1",
"react": "^17.0.1",
"react-bootstrap": "^1.4.0",
"react-dom": "^17.0.1",
"react-google-login": "^5.2.2",
"style-loader": "^2.0.0"
},
"husky": {
"hooks": {
"pre-commit": "npm run lint && npm run format"
}
},
"lint-staged": {
"*.+(js|jsx)": "eslint --fix",
"*.+(json|css|md)": "prettier --write"
}
}
I get the following error: Cannot read property 'exposeInMainWorld' of undefined
webpack 5.19.0 compiled successfully in 1793 ms
App threw an error during load
TypeError: Cannot read property 'exposeInMainWorld' of undefined
at Object../electron/preload.ts (/Users/lucas_sg/Documents/ITBA/PF/pf-biomech/dist/preload.js:24:53)
at __webpack_require__ (/Users/lucas_sg/Documents/ITBA/PF/pf-biomech/dist/preload.js:128:41)
at /Users/lucas_sg/Documents/ITBA/PF/pf-biomech/dist/preload.js:252:11
at Object.<anonymous> (/Users/lucas_sg/Documents/ITBA/PF/pf-biomech/dist/preload.js:254:12)
at Module._compile (internal/modules/cjs/loader.js:1152:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1173:10)
at Module.load (internal/modules/cjs/loader.js:992:32)
at Module._load (internal/modules/cjs/loader.js:885:14)
at Function.f._load (electron/js2c/asar_bundle.js:5:12738)
at Module.require (internal/modules/cjs/loader.js:1032:19)
I've checked out this repo regarding Electron security and it doesn't look like he's doing things too different, at least at first glance, but I'm clearly messing something up.
Here's my webpack config (webpack.electron.config.js) in case it's useful:
const path = require("path");
module.exports = [
{
resolve: {
extensions: [".tsx", ".ts", ".js"],
},
devtool: "source-map",
entry: {
main: {
import: "./electron/main.ts",
dependOn: "preload"
},
preload: "./electron/preload.ts"
},
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name].js",
},
target: "electron-main",
module: {
rules: [
{
test: /\.(js|ts|tsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
},
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
],
},
node: {
__dirname: false,
},
},
];
I think the issue resides in you webpack.config file:
entry: {
main: {
import: "./electron/main.ts",
dependOn: "preload"
},
preload: "./electron/preload.ts"
},
Might be that webpack tries to resolve all "preload.ts" dependency at compile time, plus tries to bundle it together with main.ts file. And in such case it will never get access to contextBridge. The preload.js file should only be run in a separate "context" - "Isolated World" as they refer in the docs.
What I would try is:
remove the dependOn: and preload: lines from you webpack config.
convert preload.ts file to JS (ie. to CommonJS format) - try doing that with TS CLI for now
Your preload.js file should look more or less like this:
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld(
'electron',
{
doThing: () => ipcRenderer.send('do-a-thing')
}
)
copy preload.js to a __dirname (in my case it was /dist)
run electron again
That was the only way I could access "contextBridge" object.

Angular 9 Node.js AWS - Compile errors after adding import AWS from 'aws-sdk'

I have been trying everything on the web on this topic with no luck, this is my first post to StackOverflow, sorry if I'm not doing the best job.
ERROR :
node_modules/aws-sdk/clients/dynamodbstreams.d.ts:92:38 - error TS2591: Cannot find name 'Buffer'. Do you need to install type definitions for node? Try `npm i #types/node` and then add `node` to the types field in your tsconfig.
92 export type BinaryAttributeValue = Buffer|Uint8Array|Blob|string;
~~~~~~
node_modules/aws-sdk/clients/ec2.d.ts:4439:23 - error TS2591: Cannot find name 'Buffer'. Do you need to install type definitions for node? Try `npm i #types/node` and then add `node` to the types field in your tsconfig.
4439 export type _Blob = Buffer|Uint8Array|Blob|string;
~~~~~~
node_modules/aws-sdk/clients/ecr.d.ts:990:31 - error TS2591: Cannot find name 'Buffer'. Do you need to install type definitions for node? Try `npm i #types/node` and then add `node` to the types field in your tsconfig.
990 export type LayerPartBlob = Buffer|Uint8Array|Blob|string;
~~~~~~
node_modules/aws-sdk/clients/firehose.d.ts:206:22 - error TS2591: Cannot find name 'Buffer'. Do you need to install type definitions for node? Try `npm i #types/node` and then add `node` to the types field in your tsconfig.
STEPS Taken
npm -i -d #types/node
removed types from the tsconfig files
added the polyfills.ts fix :
(window as any).global = window;
(window as any).process = {
env: { DEBUG: undefined },
};
Files
**angular.json:**
{
"$schema": "./node_modules/#angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"emsForest": {
"projectType": "application",
"schematics": {},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "#angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/emsForest",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"aot": false,
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.scss"
],
"scripts": []
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "10mb",
"maximumError": "20mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb",
"maximumError": "10kb"
}
]
}
}
},
"serve": {
"builder": "#angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "emsForest:build"
},
"configurations": {
"production": {
"browserTarget": "emsForest:build:production"
}
}
},
"extract-i18n": {
"builder": "#angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "emsForest:build"
}
},
"test": {
"builder": "#angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.scss"
],
"scripts": []
}
},
"lint": {
"builder": "#angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"tsconfig.app.json",
"tsconfig.spec.json",
"e2e/tsconfig.json"
],
"exclude": [
"**/node_modules/**"
]
}
},
"e2e": {
"builder": "#angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "emsForest:serve"
},
"configurations": {
"production": {
"devServerTarget": "emsForest:serve:production"
}
}
}
}
}
},
"defaultProject": "emsForest",
"cli": {
"analytics": "4b8ead9f-656d-4d3f-8080-037f834cd184"
},
"schematics": {
"#schematics/angular:component": {
"styleext": "scss"
}
}
}
package.json
{
"name": "ems-forest",
"version": "1.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"build:browser:prod": "ng build --prod",
"build:browser:serverless": "ng build --prod --base-href /production/",
"build:serverless": "npm run build:browser:serverless && npm run build:server:serverless",
"build:prod": "npm run build:browser:prod && npm run build:server:prod",
"server": "node local.js",
"build:prod:deploy": "npm run build:prod && npm run deploy",
"build:serverless:deploy": "npm run build:serverless && npm run deploy",
"deploy": "serverless deploy",
"build:server:prod": "webpack --config webpack.server.config.js --progress --colors",
"build:server:serverless": "webpack --config webpack.server.config.js --progress --colors"
},
"private": true,
"dependencies": {
"#angular/animations": "~9.1.1",
"#angular/cdk": "^9.2.0",
"#angular/common": "^9.1.1",
"#angular/compiler": "~9.1.1",
"#angular/core": "~9.1.1",
"#angular/forms": "~9.1.1",
"#angular/localize": "^9.1.1",
"#angular/material": "^9.2.0",
"#angular/platform-browser": "~9.1.1",
"#angular/platform-browser-dynamic": "~9.1.1",
"#angular/router": "~9.1.1",
"#ng-toolkit/serverless": "^8.1.0",
"#types/gzip-js": "^0.3.1",
"#types/hammerjs": "^2.0.36",
"#types/lodash": "^4.14.149",
"angular-bootstrap-md": "^9.0.1",
"aws-sdk": "^2.655.0",
"aws-serverless-express": "^3.3.8",
"axios": "^0.19.2",
"bootstrap": "^4.4.1",
"buffer": "^5.5.0",
"core-js": "^3.6.4",
"cors": "~2.8.4",
"cp-cli": "^1.1.0",
"enhanced-resolve": "^4.1.1",
"fetch": "^1.1.0",
"file-saver": "^2.0.2",
"fs": "0.0.1-security",
"gzip-js": "^0.3.2",
"hammerjs": "^2.0.8",
"igniteui-angular": "^9.0.9",
"igniteui-angular-core": "^9.0.1",
"igniteui-angular-excel": "^9.0.1",
"igniteui-angular-spreadsheet": "^9.0.1",
"jszip": "^3.3.0",
"lodash": "^4.17.15",
"lzutf8": "^0.5.5",
"minireset.css": "~0.0.4",
"ngx-webstorage-service": "^4.1.0",
"node-sass": "^4.13.1",
"resize-observer-polyfill": "^1.5.1",
"rxjs": "^6.5.5",
"sass": "^1.26.3",
"stream": "0.0.2",
"tslib": "^1.11.1",
"web-animations-js": "^2.3.2",
"xlsx": "^0.15.6",
"zone.js": "^0.10.3"
},
"devDependencies": {
"#angular-devkit/build-angular": "^0.901.0",
"#types/aws-sdk": "^2.7.0",
"#angular/cli": "^9.1.0",
"#angular/compiler-cli": "~9.1.1",
"#angular/language-service": "~9.1.1",
"#igniteui/angular-schematics": "~9.0.500",
"#types/jasmine": "~3.3.8",
"#types/jasminewd2": "~2.0.3",
"#types/jquery": "^3.3.34",
"#types/node": "^12.12.34",
"codelyzer": "^5.2.2",
"igniteui-cli": "~5.0.1",
"jasmine-core": "^3.5.0",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~4.1.0",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~2.0.1",
"karma-jasmine": "~2.0.1",
"karma-jasmine-html-reporter": "^1.5.3",
"opencollective": "^1.0.3",
"protractor": "^5.4.3",
"serverless": "1.40.0",
"serverless-apigw-binary": "^0.4.4",
"ts-loader": "4.2.0",
"ts-node": "~7.0.0",
"tslint": "~5.15.0",
"typescript": "~3.8.3",
"webpack-cli": "^3.3.11"
}
}
tsconfig.app.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/app",
},
"files": [
"src/main.ts",
"src/polyfills.ts"
],
"include": [
"src/**/*.d.ts"
],
"exclude": [
"src/test.ts",
"src/**/*.spec.ts"
]
}
src\tsconfig.app.json
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/app",
},
"exclude": [
"test.ts",
"**/*.spec.ts"
]
}
The TS file if the: "import AWS from 'aws-sdk'" is removed the code complies ok
import { Component, OnInit } from '#angular/core';
import * as AWS from 'aws-sdk';
#Component({
selector: 'app-admin-portal',
templateUrl: './admin-portal.component.html',
styleUrls: ['./admin-portal.component.scss']
})
export class AdminPortalComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
In the api docs, it is mentioned that you either add "types": ["node"] to the project's tsconfig.app.json file, or remove the "types" field entirely.
It is working on my side after adding the node in the array:
"compilerOptions": {
"outDir": "./out-tsc/app",
"types": ["node"]
}
I hope this helps.

Blank Page after deploying Angular 6 to heroku

I've tried deploying my mean app to heroku, Angular 6. The deployment was successful without any errors but the page was blank.
my package.json file is:
{
"name": "koko-and-friend",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "node server.js",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"postinstall": "ng build --aot --prod",
"preinstall": "npm install -g #angular/cli #angular/compiler-cli typescript #angular-devkit/build-angular"
},
"private": true,
"dependencies": {
"#angular/animations": "^6.0.2",
"#angular/common": "^6.0.2",
"#angular/compiler": "^6.0.2",
"#angular/core": "^6.0.2",
"#angular/forms": "^6.0.2",
"#angular/http": "^6.0.2",
"#angular/platform-browser": "^6.0.2",
"#angular/platform-browser-dynamic": "^6.0.2",
"#angular/router": "^6.0.2",
"bootstrap": "^4.1.1",
"core-js": "^2.5.4",
"express": "^4.16.3",
"font-awesome": "^4.7.0",
"jquery": "^3.3.1",
"popper.js": "^1.14.3",
"primeng": "^6.0.0-alpha.1",
"rxjs": "^6.0.0",
"zone.js": "^0.8.26"
},
"devDependencies": {
"#angular/compiler-cli": "^6.0.2",
"#angular-devkit/build-angular": "~0.6.3",
"typescript": "~2.7.2",
"#angular/cli": "~6.0.3",
"#angular/language-service": "^6.0.2",
"#types/jasmine": "~2.8.6",
"#types/jasminewd2": "~2.0.3",
"#types/node": "~8.9.4",
"codelyzer": "~4.2.1",
"jasmine-core": "~2.99.1",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~1.7.1",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~1.4.2",
"karma-jasmine": "~1.1.1",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "~5.3.0",
"ts-node": "~5.0.1",
"tslint": "~5.9.1"
},
"engines": {
"node": "8.11.2",
"npm": "6.0.1"
}
}
my server.js:
const path = require('path');
const express = require('express');
const app = express();
app.use(express.static(path.join(__dirname, '/dist')));
app.get('/*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist/koko-and-friend/index.html'));
});
app.listen(process.env.PORT || 4201, () => {
console.log('Connected to Port'); //Listening on port 4201
});
my angular.json
{
"$schema": "./node_modules/#angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"koko-and-friend": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {
"#schematics/angular:component": {
"styleext": "sass"
}
},
"architect": {
"build": {
"builder": "#angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/koko-and-friend",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"./src/assets/styles/bootstrap.min.css",
"./node_modules/font-awesome/css/font-awesome.min.css",
"./node_modules/primeng/resources/themes/omega/theme.css",
"src/styles.scss"
],
"scripts": [
"./node_modules/jquery/dist/jquery.min.js",
"./node_modules/popper.js/dist/umd/popper.min.js",
"./node_modules/bootstrap/dist/js/bootstrap.min.js"
]
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true
}
}
},
"serve": {
"builder": "#angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "koko-and-friend:build"
},
"configurations": {
"production": {
"browserTarget": "koko-and-friend:build:production"
}
}
},
"extract-i18n": {
"builder": "#angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "koko-and-friend:build"
}
},
"test": {
"builder": "#angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.spec.json",
"karmaConfig": "src/karma.conf.js",
"styles": [
"src/styles.sass"
],
"scripts": [],
"assets": [
"src/favicon.ico",
"src/assets"
]
}
},
"lint": {
"builder": "#angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"src/tsconfig.app.json",
"src/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
},
"koko-and-friend-e2e": {
"root": "e2e/",
"projectType": "application",
"architect": {
"e2e": {
"builder": "#angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "koko-and-friend:serve"
}
},
"lint": {
"builder": "#angular-devkit/build-angular:tslint",
"options": {
"tsConfig": "e2e/tsconfig.e2e.json",
"exclude": [
"**/node_modules/**"
]
}
}
}
}
},
"defaultProject": "koko-and-friend"
}
When I check the heroku console using bash 'dir', the dist/koko-and-friend folder after the angular app was built is there. This is weird because I'm using this same option for angular 4 exluding the #angular-devkit/build-angular in preinstall. I also checked heroku logs and there's no error.
Try to replace following line in your server.js
app.use(express.static(path.join(__dirname, '/dist')));
with
app.use( express.static(path.join(__dirname, '/dist/koko-and-friend')));
Your NPM scripts don't have any logic about moving your content to a specific folder.
This means that your page should be on dist/index.html, not dist/koko-and-friend/index.html.
Please, also post the content of your angular-cli.json (v5) or angular.json (v6) file.

Angular universal - TypeError: Object(...) is not a function at new ApplicationRef

So i have a problem, i get error:
TypeError: Object(...) is not a function at new ApplicationRef
My webpack.server.config.js
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: { server: './server.ts' },
resolve: { extensions: ['.js', '.ts'] },
target: 'node',
externals: [/(node_modules|main\..*\.js)/],
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].js'
},
module: {
rules: [
{ test: /\.(ts|js)$/, loader: 'regexp-replace-loader', options: { match: { pattern: '\\[(Mouse|Keyboard|Focus)Event\\]', flags: 'g' }, replaceWith: '[]', } },
{ test: /\.ts$/, loader: 'ts-loader' },
]
},
plugins: [
new webpack.ContextReplacementPlugin(
/(.+)?angular(\\|\/)core(.+)?/,
path.join(__dirname, 'src'),
{}
),
new webpack.ContextReplacementPlugin(
/(.+)?express(\\|\/)(.+)?/,
path.join(__dirname, 'src'),
{}
)
]
};
angular-cli.json
{
"$schema": "./node_modules/#angular/cli/lib/config/schema.json",
"project": {
"name": "jinni-angular"
},
"apps": [
{
"root": "src",
"outDir": "dist/browser",
"assets": [
"assets",
"images",
"favicon.ico"
],
"index": "index.html",
"main": "main.ts",
"polyfills": "polyfills.ts",
"test": "test.ts",
"tsconfig": "tsconfig.app.json",
"testTsconfig": "tsconfig.spec.json",
"prefix": "app",
"styles": [
"styles.scss",
"../node_modules/owl.carousel/dist/assets/owl.carousel.css",
"../node_modules/owl.carousel/dist/assets/owl.theme.default.css"
],
"scripts": [
"../node_modules/jquery/dist/jquery.js",
"../node_modules/owl.carousel/dist/owl.carousel.js"
],
"environmentSource": "environments/environment.ts",
"environments": {
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
}
},
{
"platform": "server",
"root": "src",
"outDir": "dist/server",
"assets": [
"assets",
"images",
"favicon.ico"
],
"index": "index.html",
"main": "main.server.ts",
"test": "test.ts",
"tsconfig": "tsconfig.server.json",
"testTsconfig": "tsconfig.spec.json",
"prefix": "app",
"styles": [
"styles.scss"
],
"scripts": [
],
"environmentSource": "environments/environment.ts",
"environments": {
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
}
}
],
"e2e": {
"protractor": {
"config": "./protractor.conf.js"
}
},
"lint": [
{
"project": "src/tsconfig.app.json",
"exclude": "**/node_modules/**"
},
{
"project": "src/tsconfig.spec.json",
"exclude": "**/node_modules/**"
},
{
"project": "e2e/tsconfig.e2e.json",
"exclude": "**/node_modules/**"
}
],
"test": {
"karma": {
"config": "./karma.conf.js"
}
},
"defaults": {
"styleExt": "scss",
"component": {
}
}
}
Package.json
{
"name": "jinni-angular",
"version": "0.0.0",
"license": "MIT",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"build:universal": "npm run build:client-and-server-bundles && npm run webpack:server",
"serve:universal": "node dist/server.js",
"build:client-and-server-bundles": "ng build --prod && ng build --prod --app 1 --output-hashing=false",
"webpack:server": "webpack --config webpack.server.config.js --progress --colors"
},
"private": true,
"dependencies": {
"#angular/animations": "^6.0.0",
"#angular/cdk": "^5.2.4",
"#angular/common": "^5.0.0",
"#angular/compiler": "^5.0.0",
"#angular/core": "^6.0.0",
"#angular/forms": "^5.0.0",
"#angular/http": "^5.0.0",
"#angular/material": "^5.2.4",
"#angular/platform-browser": "^5.0.0",
"#angular/platform-browser-dynamic": "^5.0.0",
"#angular/platform-server": "^6.0.0",
"#angular/router": "^5.0.0",
"#nguniversal/express-engine": "^6.0.0",
"#nguniversal/module-map-ngfactory-loader": "^6.0.0",
"#ngx-translate/core": "^9.1.1",
"#ngx-translate/http-loader": "^2.0.1",
"#types/underscore": "^1.8.6",
"classlist.js": "^1.1.20150312",
"compression": "latest",
"cookie-parser": "latest",
"core-js": "^2.5.5",
"express": "latest",
"global": "^4.3.2",
"hammerjs": "^2.0.8",
"jquery": "latest",
"ng-custom-select": "^1.0.4",
"ng-select": "^1.0.0-rc.3",
"ng2-breadcrumbs": "^0.1.281",
"ng2-carouselamos": "^3.2.0",
"ng2-translate": "^5.0.0",
"ng4-click-outside": "^1.0.1",
"ng4-intl-phone": "^1.2.0",
"ngx-device-detector": "^1.2.2",
"ngx-dropdown": "0.0.22",
"ngx-owl-carousel": "^2.0.7",
"node": "^9.11.0",
"node-fetch": "^2.1.2",
"npm": "^5.8.0",
"regexp-replace-loader": "^1.0.1",
"rxjs": "^5.5.2",
"serve": "^6.5.3",
"ts-loader": "^3.5.0",
"uglifyjs-webpack-plugin": "^1.2.5",
"underscore": "^1.8.3",
"webpack": "^3.5.0",
"zone.js": "^0.8.14"
},
"devDependencies": {
"#angular/cli": "^1.7.4",
"#angular/compiler-cli": "^5.0.0",
"#angular/language-service": "^5.0.0",
"#types/compression": "0.0.36",
"#types/express": "^4.11.1",
"#types/jasmine": "~2.5.53",
"#types/jasminewd2": "~2.0.2",
"#types/node": "~6.0.60",
"codelyzer": "^4.0.1",
"jasmine-core": "~2.6.2",
"jasmine-spec-reporter": "~4.1.0",
"karma": "~1.7.0",
"karma-chrome-launcher": "~2.1.1",
"karma-cli": "~1.0.1",
"karma-coverage-istanbul-reporter": "^1.2.1",
"karma-jasmine": "~1.1.0",
"karma-jasmine-html-reporter": "^0.2.2",
"node-sass": "^4.7.2",
"protractor": "~5.1.2",
"ts-node": "~3.2.0",
"tslint": "~5.7.0",
"typescript": "~2.4.2",
"webpack-cli": "^2.1.3"
}
}
and at last server.ts
import 'zone.js/dist/zone-node';
import 'reflect-metadata';
import { renderModuleFactory } from '#angular/platform-server';
import { enableProdMode } from '#angular/core';
import * as express from 'express';
import { join } from 'path';
import { readFileSync } from 'fs';
enableProdMode();
const app = express();
const PORT = process.env.PORT || 4000;
const DIST_FOLDER = join(process.cwd(), 'dist');
const template = readFileSync(join(DIST_FOLDER, 'browser', 'index.html')).toString();
const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./dist/server/main.bundle');
const { provideModuleMap } = require('#nguniversal/module-map-ngfactory-loader');
app.engine('html', (_, options, callback) => {
renderModuleFactory(AppServerModuleNgFactory, {
document: template,
url: options.req.url,
extraProviders: [
provideModuleMap(LAZY_MODULE_MAP)
]
}).then(html => {
callback(null, html);
});
});
global['Event'] = null;
app.set('view engine', 'html');
app.set('views', join(DIST_FOLDER, 'browser'));
app.get('*.*', express.static(join(DIST_FOLDER, 'browser')));
app.get('*', (req, res) => {
res.render(join(DIST_FOLDER, 'browser', 'index.html'), { req });
});
app.listen(PORT, () => {
console.log(`Node server listening on http://localhost:${PORT}`);
});
after use serve:universal everything is fine but when i go to localhost:4000 i get an error TypeError: Object(...) is not a function
at new ApplicationRef
Any ideas?
full error:
TypeError: Object(...) is not a function
at new ApplicationRef (/.../dist/server.js:5838:64)
at _createClass (/..../dist/server.js:10145:20)
at _createProviderInstance$1 (/..../dist/server.js:10115:26)
at initNgModule (/..../dist/server.js:10051:32)
at new NgModuleRef_ (/..../dist/server.js:10767:9)
at Object.createNgModuleRef (/..../dist/server.js:10756:12)
at NgModuleFactory_.create (/..../dist/server.js:13289:25)
at /..../dist/server.js:5589:43
at ZoneDelegate.invoke (/...../dist/server.js:147664:26)
at Object.onInvoke (/...../dist/server.js:4931:33)

Invalid configuration object -configuration.output.path after installing sass

I facing an issue while running webpack using the command npm run dev, after installing npm sass
"node-sass": "^4.5.2",
"sass-loader": "^6.0.3",
"style-loader": "^0.16.1",
Issue:
Invalid configuration object -configuration.output.path.
given my package.json and webpack.config.js.
Thanks in advance could somebody let me know what we went wrong, how could we resolve this issue.
Issue:
webpack.config.js
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/app.js',
output: {
path : ' dist',
filename : 'app.bundle.js'
},
module: {
rules: [
{ test: /\.scss$/, use: ['style-loader','css-loader', 'sass-loader'] }
]
},
plugins: [
new HtmlWebpackPlugin({
title: 'Index Project Template',
minify: {
collapseWhitespace: true
},
hash: true,
template: './src/indextemp.ejs', // Load a custom template (ejs by default see the FAQ for details)
})
]
}
package.json
{
"name": "webpacks",
"version": "1.0.0",
"description": "Webpack Start",
"main": "index.js",
"scripts": {
"dev": "webpack -d --watch",
"prod": "webpack -p"
},
"author": "",
"license": "ISC",
"devDependencies": {
"css-loader": "^0.28.0",
"html-webpack-plugin": "^2.28.0",
"node-sass": "^4.5.2",
"sass-loader": "^6.0.3",
"style-loader": "^0.16.1",
"webpack": "^2.4.1"
}
}

Resources