问题
After update to angular 9 and universal 9, a got error when i run npm run build:ssr && npm run serve:ssr
Error: Component 'HeaderComponent' is not resolved:
- templateUrl: ./header.component.html
- styleUrls: ["./header.component.scss"]
Did you run and wait for 'resolveComponentResources()'?
at Function.get (D:\projects\my-app\node_modules\@angular\core\bundles\core.umd.js:26828:31)
at getComponentDef (D:\projects\my-app\node_modules\@angular\core\bundles\core.umd.js:2021:20)
at verifyDeclarationsHaveDefinitions (D:\projects\my-app\node_modules\@angular\core\bundles\core.umd.js:26519:23)
at Array.forEach (<anonymous>)
at verifySemanticsOfNgModuleDef (D:\projects\my-app\node_modules\@angular\core\bundles\core.umd.js:26494:22)
at D:\projects\my-app\node_modules\@angular\core\bundles\core.umd.js:26491:13
at Array.forEach (<anonymous>)
at verifySemanticsOfNgModuleDef (D:\projects\my-app\node_modules\@angular\core\bundles\core.umd.js:26489:64)
at D:\projects\my-app\node_modules\@angular\core\bundles\core.umd.js:26491:13
at Array.forEach (<anonymous>)
package.json
"scripts": {
"ng": "ng",
"start": "npm-run-all -p client server",
"client": "ng serve --proxy-config server.conf.json",
"server": "nodemon --watch server.ts --exec ts-node server.ts",
"build": "ng build",
"test": "ng test --source-map=false",
"tests-coverage": "ng test --source-map=false --code-coverage",
"lint": "ng lint ng-universal-demo",
"build:client-and-server-bundles": "ng build --prod && ng run ng-universal-demo:server:production",
"build:prerender": "npm run build:client-and-server-bundles && npm run webpack:server && npm run generate:prerender",
"build:ssr": "npm run build:client-and-server-bundles && npm run webpack:server",
"generate:prerender": "cd dist && node prerender",
"webpack:server": "webpack --config webpack.server.config.js --progress --colors",
"serve:prerender": "cd dist/browser && http-server",
"serve:ssr": "node dist/server",
"ssr": "npm run build:ssr && npm run serve:ssr",
"e2e": "start-server-and-test ssr http://localhost:4100 wdio",
"allure": "allure generate --clean",
},
"pre-commit": [],
"private": true,
"dependencies": {
"@angular-builders/custom-webpack": "8.4.1",
"@angular/animations": "9.1.0",
"@angular/cdk": "9.2.0",
"@angular/common": "9.1.0",
"@angular/compiler": "9.1.0",
"@angular/core": "9.1.0",
"@angular/forms": "9.1.0",
"@angular/http": "7.2.15",
"@angular/material": "9.2.0",
"@angular/material-moment-adapter": "9.2.0",
"@angular/platform-browser": "9.1.0",
"@angular/platform-browser-dynamic": "9.1.0",
"@angular/platform-server": "9.1.0",
"@angular/router": "9.0.7",
"@fullcalendar/core": "^4.4.0",
"@gfx/zopfli": "1.0.14",
"@nguniversal/express-engine": "9.1.0",
"@ngx-translate/core": "11.0.1",
"@types/es6-promise": "3.3.0",
"@wdio/dot-reporter": "^5.18.6",
"accept-language-parser": "^1.5.0",
"arraybuffer-concat": "0.0.1",
"aws-sdk": "2.518.0",
"axios": "0.19.0",
"basic-auth-connect": "1.0.0",
"body-parser": "1.19.0",
"chart.js": "^2.8.0",
"classlist.js": "1.1.20150312",
"compression-webpack-plugin": "3.0.1",
"core-js": "3.2.1",
"detect-browser": "^4.6.0",
"dot-object": "^1.9.0",
"ecstatic": "4.1.2",
"express-enforces-ssl": "1.1.0",
"express-http-proxy": "^1.5.1",
"express-static-gzip": "2.0.3",
"file-saver": "2.0.2",
"hammerjs": "2.0.8",
"helmet": "3.21.2",
"html2canvas": "1.0.0-rc.3",
"iframe-resizer": "^4.1.1",
"jsonwebtoken": "8.5.1",
"jwks-rsa": "1.6.0",
"lodash": "4.17.15",
"moment": "2.24.0",
"ng4-click-outside": "1.0.1",
"ngx-device-detector": "^1.3.20",
"ngx-img-cropper": "9.0.1",
"ngx-infinite-scroll": "8.0.0",
"ngx-perfect-scrollbar": "8.0.0",
"ngx-web-worker": "8.0.0",
"node-fetch": "2.6.0",
"normalize.css": "8.0.1",
"npm-run-all": "^4.1.5",
"pdfmake": "0.1.58",
"primeicons": "2.0.0",
"primeng": "9.0.5",
"quill": "^1.3.6",
"rxjs": "^6.5.4",
"spdy": "4.0.1",
"text-encoding": "^0.7.0",
"tslib": "^1.10.0",
"unorm": "^1.6.0",
"uuid": "3.3.3",
"web-animations-js": "2.3.2",
"webpack-cli": "3.3.11",
"webpack-node-externals": "^1.7.2",
"whatwg-fetch": "3.0.0",
"xhr2": "^0.2.0",
"zone.js": "0.10.3"
},
"devDependencies": {
"@angular-devkit/build-angular": "^0.900.7",
"@angular/cli": "9.1.0",
"@angular/compiler-cli": "9.1.0",
"@angular/language-service": "9.1.0",
"@babel/cli": "^7.8.0",
"@babel/core": "^7.8.0",
"@babel/preset-env": "^7.8.2",
"@babel/register": "^7.8.0",
"@biesbjerg/ngx-translate-extract": "3.0.4",
"@types/iframe-resizer": "3.5.7",
"@types/jasmine": "3.5.0",
"@types/lodash": "4.14.144",
"@types/node": "12.11.1",
"@wdio/allure-reporter": "^5.18.6",
"@wdio/cli": "^5.18.4",
"@wdio/firefox-profile-service": "^5.16.11",
"@wdio/local-runner": "^5.18.6",
"@wdio/mocha-framework": "^5.18.6",
"@wdio/selenium-standalone-service": "^5.16.10",
"@wdio/spec-reporter": "^5.18.6",
"@wdio/sync": "^5.18.6",
"agent": "0.2.1",
"allure-commandline": "^2.13.0",
"chromedriver": "^79.0.3",
"codelyzer": "5.1.0",
"cors-anywhere": "0.4.1",
"cpy-cli": "2.0.0",
"express": "4.17.1",
"form-data": "2.5.0",
"googledrive-i18n": "^1.2.4",
"http-server": "0.11.1",
"jasmine-core": "3.4.0",
"jasmine-spec-reporter": "4.2.1",
"karma": "4.3.0",
"karma-chrome-launcher": "3.1.0",
"karma-cli": "2.0.0",
"karma-coverage-istanbul-reporter": "2.1.0",
"karma-jasmine": "2.0.1",
"karma-jasmine-html-reporter": "1.4.2",
"karma-parallel": "^0.3.1",
"karma-phantomjs-launcher": "1.0.4",
"karma-remap-istanbul": "0.6.0",
"nodemon": "^2.0.2",
"pre-commit": "1.2.2",
"prettier": "1.18.2",
"protractor": "5.4.2",
"puppeteer": "1.19.0",
"reflect-metadata": "0.1.13",
"request": "2.88.0",
"start-server-and-test": "^1.10.8",
"superagent": "5.1.0",
"terser": "4.2.1",
"ts-loader": "6.0.4",
"ts-node": "8.3.0",
"tslint": "5.19.0",
"tslint-microsoft-contrib": "^6.2.0",
"typescript": "3.7.5",
"wdio-chromedriver-service": "^5.0.2",
"ws": "^7.2.3",
"xmlhttprequest": "^1.8.0"
},
server.ts
import 'reflect-metadata';
import { enableProdMode } from '@angular/core';
import AWS = require('aws-sdk');
import * as express from 'express';
import EES = require('express-enforces-ssl');
import ESG = require('express-static-gzip');
import fs = require('fs');
import helmet = require('helmet');
import https = require('https');
import fetch from 'node-fetch/lib/index.js';
import { join } from 'path';
import spdy = require('spdy');
import 'zone.js/dist/zone-node';
import { AppServerModule, ngExpressEngine } from './src/main.server';
import { environment } from './src/environments/environment';
const token = {
dev:
'blala1',
prod:
'blala2',
};
const patient_info_token = {
dev: 'blala1',
prod: 'blala2',
};
const PATIENT_INFO_SERVER = {
dev: 'blala2',
prod: 'blala2',
};
const bodyParser = require('body-parser');
// Browser detection
const { detect } = require('detect-browser');
// Accept-language-parser
const parser = require('accept-language-parser');
global['navigator'] = { onLine: true };
// Faster server renders w/ Prod mode (dev mode never needed)
enableProdMode();
// Express server
const server = express();
const proxy = require('express-http-proxy');
const SNS_TOPIC = `blala2`;
const AUTH_TYPE = environment.AUTH_TYPE;
// const request = require('request');
const PORT = process.env.PORT || 4100;
const HTTPS_PORT = process.env.HTTPS_PORT || 4200;
const DIST_FOLDER = join(process.cwd(), 'dist');
const PROJECT_FOLDER = join(process.cwd(), 'src');
const basicAuth = require('basic-auth-connect');
let privateKey;
let certificate;
try {
privateKey = fs.readFileSync('/blala2.pem').toString();
certificate = fs.readFileSync('/blala2.pem').toString();
server.enable('trust proxy');
server.use(helmet());
server.use(EES());
} catch (e) {}
// const agent = require('superagent');
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
server.engine(
'html',
ngExpressEngine({
bootstrap: AppServerModule,
}),
);
const session = {};
server.set('view engine', 'html');
server.set('views', join(DIST_FOLDER, 'browser'));
const credentials = blala2;
// const credentials = blala2;
AWS.config.credentials = credentials;
AWS.config.update({ region: process.env.AWS_REGION || 'eu-central-1' });
const SNS = new AWS.SNS();
server.post('/api/token', (req, res) => {
///
});
server.post('/api/token/refresh', bodyParser.json(), (req, res) => {
//
});
const auth = AUTH_TYPE === 'none' ? [] : [AUTH_TYPE === 'basic' ? basicAuthInited : formHandler];
// Server static files from /browser
server.get(
'*.*',
auth.concat([
checkUnsupportedBrowser,
ESG(join(DIST_FOLDER, 'browser'), undefined),
express.static(join(DIST_FOLDER, 'browser'), {
maxAge: '1y',
}),
]),
);
const unless = function(path) {
return function(req, res, next) {
const browser = detect(req.headers['user-agent']);
console.log('unless==>', req.headers['user-agent']);
if (path === req.path) {
return next();
} else if (browser && browser.name) {
switch (browser.name) {
case 'edge':
case 'edge-chromium':
case 'chromium-webview':
case 'chrome':
case 'firefox':
case 'safari':
case 'ios':
case 'ios-webview':
case 'fxios':
case 'crios':
// tslint:disable
const render = () => {
res.render('index', { req });
};
return AUTH_TYPE === 'none'
? render()
: AUTH_TYPE === 'basic'
? basicAuthInited(req, res, render)
: formHandler(req, res, render);
console.log(JSON.stringify(browser, undefined, 2));
console.log('default case');
next();
break;
default:
callUnsupportedBrowserHTML(req, res);
console.log(JSON.stringify(browser, undefined, 2));
console.log('ie case');
}
} else {
// tslint:disable
const render = () => {
res.render('index', { req });
};
return AUTH_TYPE === 'none'
? render()
: AUTH_TYPE === 'basic'
? basicAuthInited(req, res, render)
: formHandler(req, res, render);
}
};
};
// All regular routes use the Universal engine
server.use(unless('/favicon.ico'));
// Start up the Node server
if (privateKey && certificate) {
server.listen(PORT, () => {
console.log(`Node Express server listening on http://localhost:${PORT}`);
});
// Start up the Node server
spdy.createServer({ key: privateKey, cert: certificate }, server).listen(HTTPS_PORT, () => {
console.log(`Node Express secure server listening on http://localhost:${HTTPS_PORT}`);
});
} else {
// Start up when keys is not defined
server.listen(PORT, () => {
console.log(`Node Express server listening on http://localhost:${PORT}`);
});
}
回答1:
After 2 days of fixing this I got an answer. Part of angular.json with pror architect must be next:
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/test-ssr/browser",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"aot": true,
In my case builder was wrong "builder": "@angular-devkit/custom-webpack:browser",
and also I was using customWebpackConfig
"options": {
"customWebpackConfig": {
"path": "./config/custom.webpack.config.js",
"mergeStrategies": { "plugins": "append" }
},
That is usless for "builder": "@angular-devkit/build-angular:browser",
Also in packege.json version of this devDependencies must be next:
"devDependencies": {
"@angular-devkit/build-angular": "0.900.7",
"@angular-devkit/build-optimizer": "0.900.7",
Initially, I installed the 0.901.0 version, but it didn't work. Link to issue
I hope I will help someone.
来源:https://stackoverflow.com/questions/61026178/angular-9-universal-error-component-headercomponent-is-not-resolved