Reputation: 131
Hi I am using angular 2 with universal.
I am trying to this.
First I create a new project :
ng new universaldemo.
I installed these packages :
npm install --save @angular/platform-server @nguniversal/module-map-ngfactory-loader ts-loader @nguniversal/express-engine
.
Here is my app.module.ts
:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule.withServerTransition({ appId: 'universaldemo' }),
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Here is my app.server.module.ts
import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server';
import { ModuleMapLoaderModule } from '@nguniversal/module-map-ngfactory-loader';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';
@NgModule({
imports: [
AppModule,
ServerModule,
ModuleMapLoaderModule
],
providers: [
// Add universal-only providers here
],
bootstrap: [ AppComponent ],
})
export class AppServerModule {}
Here is my server.ts
:
// These are important and needed before anything else
import 'zone.js/dist/zone-node';
import 'reflect-metadata';
import { enableProdMode } from '@angular/core';
import * as express from 'express';
import { join } from 'path';
// 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');
// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./dist/server/main.bundle');
// Express Engine
import { ngExpressEngine } from '@nguniversal/express-engine';
// Import module map for lazy loading
import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';
app.engine('html', ngExpressEngine({
bootstrap: AppServerModuleNgFactory,
providers: [
provideModuleMap(LAZY_MODULE_MAP)
]
}));
app.set('view engine', 'html');
app.set('views', join(DIST_FOLDER, 'browser'));
// TODO: implement data requests securely
app.get('/api/*', (req, res) => {
res.status(404).send('data requests are not supported');
});
// 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}`);
});
Here is 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',
// 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' }]
},
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'),
{}
)
]
};
Finally i create tsconfig.server.json
:
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/app",
"baseUrl": "./",
"module": "commonjs",
"types": []
},
"exclude": [
"test.ts",
"**/*.spec.ts"
],
"angularCompilerOptions": {
"entryModule": "app/app.server.module#AppServerModule"
}
}
Below lines are added to my package.json
:
"scripts": {
...
"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"
...
}
Here is my angular-Cli.json
:
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"project": {
"name": "angularuniversaldemo"
},
"apps": [
{
"root": "src",
"outDir": "dist",
"assets": [
"assets",
"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.css"
],
"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": "css",
"component": {}
}
}
I try to create build and serve my app :
npm run build:universal
npm run serve:universal.
Does not create build and run app.
I am getting these errors :
1.
ERROR in Error: Metadata version mismatch for module F:/anitha/projects/Universal/universaldemo/node_modules/@angular/platform-server/platform-server.d.ts, found version 4, expected 3...
npm ERR! Windows_NT 10.0.15063....
2.
Cannot find name 'process' and Cannot find name 'require'.
3.
Unable to find app with name or index. Verify the configuration in `.angular-cli.json`
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] build:client-and-server-bundles: `ng build --prod && ng build --prod --app 1 --output-hashing=false`
npm ERR! Exit status 1
I need run and build my app. How can I do this?
Kindly advice me,
Thanks.
Upvotes: 1
Views: 3674
Reputation: 4207
It looks like you're using a wrong version of the platform-server module.
You can try to force the dependency version to the one needed in your project directly in this file
You also have to you start your server.ts script with ts-node
rather than only node
:
npm install ts-node --save
and change your package.json
script with :
"serve:universal": "ts-node dist/server.ts
To differenciate builds, you can define multiple apps in your angular-cli.json
file, like this :
"apps": [
{
"name": "app",
"root": "src",
"outDir": "dist",
...
},
{
"name": "universal",
"root": "src",
"outDir": "dist-universal",
...
},
{
"name": "server",
"platform": "server",
"root": "src",
...
}
],
And then, you can choose which app to launch with the --app
flag :
ng build/serve --app app/universal/server
The name must match the ones in your angular-cli.json
file, so in your case your app must be named 1
.
Or, if you need only one app/config, you can run :ng build (--prod/aot...)
without --app
Be careful about the path of your dist
folder. Check these parameters :
tsconfig.**.json:
...
"genDir": "../dist"
...
angular-cli.json:
...
"outDir": "./dist",
...
These path are relative and have to match with path defined in your server.ts
file
Upvotes: 2