diff --git a/package-lock.json b/package-lock.json index e15e031d24..237d24764a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,10 +4,10 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "caniuse-lite": { - "version": "1.0.30000738", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000738.tgz", - "integrity": "sha1-GCDDya25oRfjEaW9yh0lvDQojro=", + "@types/webpack-env": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.13.1.tgz", + "integrity": "sha512-oHyg0NssP2RCpCvE35hhbSqMJRsc5lSW+GFe+Vc65JL+kHII1VMYM+0KeV/z4utFuUqPoQRmq8KMMp7ba0dj6Q==", "dev": true } } diff --git a/package.json b/package.json index cb5bcbf02a..fbb4c54b48 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "clean:log": "rimraf *.log*", "clean:json": "rimraf *.records.json", "clean:node": "rimraf node_modules", - "clean:prod": "yarn run clean:coverage && yarn run clean:doc && yarn run clean:dist && yarn run clean:log && yarn run clean:json ", + "clean:prod": "yarn run clean:coverage && yarn run clean:doc && yarn run clean:dist && yarn run clean:log && yarn run clean:json", "clean": "yarn run clean:prod && yarn run clean:node", "prebuild": "yarn run clean:dist", "prebuild:aot": "yarn run prebuild", @@ -122,7 +122,7 @@ "@types/jasmine": "2.6.0", "@types/memory-cache": "0.0.31", "@types/mime": "2.0.0", - "@types/node": "8.0.31", + "@types/node": "8.0.26", "@types/serve-static": "1.7.32", "@types/source-map": "0.5.1", "@types/webfontloader": "1.6.29", diff --git a/src/app/browser-app.module.ts b/src/app/browser-app.module.ts index 7ba050668c..1fcf82215e 100644 --- a/src/app/browser-app.module.ts +++ b/src/app/browser-app.module.ts @@ -1,5 +1,6 @@ import { NgModule, APP_INITIALIZER } from '@angular/core'; import { Http } from '@angular/http'; +import { HttpClientModule, HttpClient } from '@angular/common/http'; import { RouterModule } from '@angular/router'; import { BrowserModule } from '@angular/platform-browser'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; @@ -34,8 +35,8 @@ export function init(cache: TransferState) { }; } -export function HttpLoaderFactory(http: Http) { - return new TranslateHttpLoader(http, 'assets/i18n/', '.json'); +export function createTranslateLoader(http: HttpClient) { + return new TranslateHttpLoader(http, './assets/i18n/', '.json'); } @NgModule({ @@ -44,13 +45,14 @@ export function HttpLoaderFactory(http: Http) { BrowserModule.withServerTransition({ appId: 'ds-app-id' }), + HttpClientModule, IdlePreloadModule.forRoot(), // forRoot ensures the providers are only created once RouterModule.forRoot([], { useHash: false, preloadingStrategy: IdlePreload }), TranslateModule.forRoot({ loader: { provide: TranslateLoader, - useFactory: HttpLoaderFactory, - deps: [Http] + useFactory: (createTranslateLoader), + deps: [HttpClient] } }), NgbModule.forRoot(), diff --git a/src/app/server-app.module.ts b/src/app/server-app.module.ts index cd5c24034d..ed54351654 100644 --- a/src/app/server-app.module.ts +++ b/src/app/server-app.module.ts @@ -48,7 +48,7 @@ export function boot(cache: TransferState, appRef: ApplicationRef, store: Store< }); }; } -export function UniversalLoaderFactory() { +export function createTranslateLoader() { return new TranslateUniversalLoader('dist/assets/i18n', '.json'); } @@ -63,7 +63,7 @@ export function UniversalLoaderFactory() { TranslateModule.forRoot({ loader: { provide: TranslateLoader, - useFactory: UniversalLoaderFactory, + useFactory: (createTranslateLoader), deps: [] } }), diff --git a/src/app/store.actions.ts b/src/app/store.actions.ts index bc504b2437..be36012ce5 100644 --- a/src/app/store.actions.ts +++ b/src/app/store.actions.ts @@ -10,6 +10,7 @@ export const StoreActionTypes = { export class StoreAction implements Action { type: string; payload: AppState | Action[]; + // tslint:disable-next-line:no-shadowed-variable constructor(type: string, payload: AppState | Action[]) { this.type = type; this.payload = payload; diff --git a/src/main.server.aot.ts b/src/main.server.aot.ts deleted file mode 100644 index 1d536260ed..0000000000 --- a/src/main.server.aot.ts +++ /dev/null @@ -1,148 +0,0 @@ -/** - * This file should be temporary - * See https://github.com/angular/angular-cli/pull/5194 - */ -import 'zone.js/dist/zone-node'; -import 'reflect-metadata'; -import 'rxjs/Rx'; - -import * as fs from 'fs'; -import * as pem from 'pem'; -import * as https from 'https'; -import * as morgan from 'morgan'; -import * as express from 'express'; -import * as bodyParser from 'body-parser'; -import * as session from 'express-session'; -import * as compression from 'compression'; -import * as cookieParser from 'cookie-parser'; - -import { enableProdMode } from '@angular/core'; - -import { ServerAppModuleNgFactory } from './aot/app/server-app.module.ngfactory'; -import { ngExpressEngine } from '@nguniversal/express-engine'; - -import { serverApi, createMockApi } from './backend/api'; - -import { ROUTES } from './routes'; -import { ENV_CONFIG } from './config'; - -const app = express(); - -const port = ENV_CONFIG.ui.port ? ENV_CONFIG.ui.port : 80; - -if (ENV_CONFIG.production) { - // TODO: set config for morgan.log location - const accessLogStream = fs.createWriteStream(ENV_CONFIG.logDirectory + '/morgan.log', { flags: 'a' }); - - enableProdMode(); - app.use(compression()); - - app.use(morgan('common', { - skip: (req, res) => res.statusCode < 400, - stream: accessLogStream - })); -} else { - app.use(morgan('dev')); -} - -app.use(cookieParser()); -app.use(bodyParser.json()); - -app.engine('html', ngExpressEngine({ - bootstrap: ServerAppModuleNgFactory -})); - -app.set('view engine', 'html'); -app.set('views', 'src'); - -function cacheControl(req, res, next) { - // instruct browser to revalidate - res.header('Cache-Control', ENV_CONFIG.cache.control || 'max-age=60'); - next(); -} - -app.use('/', cacheControl, express.static('dist', { index: false })); - -// TODO: either remove or update mock backend -// app.get('/data.json', serverApi); -// app.use('/api', createMockApi()); - -function ngApp(req, res) { - - function onHandleError(parentZoneDelegate, currentZone, targetZone, error) { - console.warn('Error in SSR, serving for direct CSR'); - res.sendFile('index.csr.html', { root: './src' }); - } - - if (ENV_CONFIG.universal.preboot) { - Zone.current.fork({ name: 'CSR fallback', onHandleError }).run(() => { - res.render('../dist/index', { - req, - res, - preboot: ENV_CONFIG.universal.preboot, - async: ENV_CONFIG.universal.async, - time: ENV_CONFIG.universal.time, - baseUrl: ENV_CONFIG.ui.nameSpace, - originUrl: ENV_CONFIG.ui.baseUrl, - requestUrl: req.originalUrl - }); - }); - } else { - console.log('Universal off, serving for direct CSR'); - res.sendFile('index.csr.html', { root: './src' }); - } -} - -ROUTES.forEach((route: string) => { - app.get(route, ngApp); -}); - -function serverStarted() { - console.log(`[${new Date().toTimeString()}] Listening at ${ENV_CONFIG.ui.baseUrl}`); -} - -function createHttpsServer(keys) { - https.createServer({ - key: keys.serviceKey, - cert: keys.certificate - }, app).listen(port, ENV_CONFIG.ui.host, () => { - serverStarted(); - }); -} - -if (ENV_CONFIG.ui.ssl) { - let serviceKey; - try { - serviceKey = fs.readFileSync('./config/ssl/key.pem'); - } catch (e) { - console.warn('Service key not found at ./config/ssl/key.pem'); - } - - let certificate; - try { - certificate = fs.readFileSync('./config/ssl/cert.pem'); - } catch (e) { - console.warn('Certificate not found at ./config/ssl/key.pem'); - } - - if (serviceKey && certificate) { - createHttpsServer({ - serviceKey: serviceKey, - certificate: certificate - }); - } else { - - process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; - - pem.createCertificate({ - days: 1, - selfSigned: true - }, (error, keys) => { - createHttpsServer(keys); - }); - } -} else { - app.listen(port, ENV_CONFIG.ui.host, () => { - serverStarted(); - }); -} diff --git a/src/main.server.ts b/src/main.server.ts index f681e5c3ab..f787f30514 100644 --- a/src/main.server.ts +++ b/src/main.server.ts @@ -12,11 +12,13 @@ import * as session from 'express-session'; import * as compression from 'compression'; import * as cookieParser from 'cookie-parser'; +import { platformServer, renderModuleFactory } from '@angular/platform-server'; import { enableProdMode } from '@angular/core'; -import { ServerAppModule } from './app/server-app.module'; import { ngExpressEngine } from '@nguniversal/express-engine'; +import { ServerAppModule } from './app/server-app.module'; + import { serverApi, createMockApi } from './backend/api'; import { ROUTES } from './routes'; diff --git a/src/tsconfig.browser.json b/src/tsconfig.browser.json index d04b9e603d..a14de3972a 100644 --- a/src/tsconfig.browser.json +++ b/src/tsconfig.browser.json @@ -2,8 +2,5 @@ "extends": "../tsconfig.json", "angularCompilerOptions": { "entryModule": "./app/browser-app.module#BrowserAppModule" - }, - "exclude": [ - "./main.server.aot.ts" - ] + } } diff --git a/src/tsconfig.server.aot.json b/src/tsconfig.server.aot.json deleted file mode 100644 index e3638f4fb1..0000000000 --- a/src/tsconfig.server.aot.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "./tsconfig.server.json", - "angularCompilerOptions": { - "genDir": "aot", - "entryModule": "./app/server-app.module#ServerAppModule" - }, - "exclude": [ - "./main.browser.ts", - "./main.server.ts" - ] -} diff --git a/src/tsconfig.server.json b/src/tsconfig.server.json index 6fecd0553a..b86ab358f9 100644 --- a/src/tsconfig.server.json +++ b/src/tsconfig.server.json @@ -2,8 +2,5 @@ "extends": "../tsconfig.json", "angularCompilerOptions": { "entryModule": "./app/server-app.module#ServerAppModule" - }, - "exclude": [ - "./main.server.aot.ts" - ] + } } diff --git a/src/tsconfig.test.json b/src/tsconfig.test.json index 98be2bb0f2..32a466a3e9 100644 --- a/src/tsconfig.test.json +++ b/src/tsconfig.test.json @@ -5,8 +5,5 @@ }, "angularCompilerOptions": { "entryModule": "./app/browser-app.module#BrowserAppModule" - }, - "exclude": [ - "./main.server.aot.ts" - ] + } } diff --git a/tsconfig.json b/tsconfig.json index 1f78aba403..90fdb4dd35 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,19 +1,40 @@ { "compilerOptions": { - "moduleResolution": "node", - "module": "es2015", "target": "es5", - "noImplicitAny": false, - "sourceMap": false, - "skipLibCheck": true, - "experimentalDecorators": true, + "module": "es2015", + "moduleResolution": "node", "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "allowSyntheticDefaultImports": true, + "sourceMap": true, + "noEmit": true, + "noEmitHelpers": true, + "importHelpers": true, + "noImplicitAny": false, + "strictNullChecks": false, + "baseUrl": ".", + "paths": {}, + "typeRoots": [ + "node_modules/@types" + ], + "types": [ + "jasmine", + "node" + ], "lib": [ - "dom", - "es2016" + "es2016", + "dom" ] }, - "include": [ - "src" - ] + "exclude": [ + "node_modules", + "dist", + "src/**/*.spec.ts", + "src/**/*.e2e.ts" + ], + "compileOnSave": false, + "buildOnSave": false, + "atom": { + "rewriteTsconfig": false + } } diff --git a/webpack.config.ts b/webpack.config.js similarity index 72% rename from webpack.config.ts rename to webpack.config.js index 0f4278feb7..003088b123 100644 --- a/webpack.config.ts +++ b/webpack.config.js @@ -5,8 +5,8 @@ const serverPartial = require('./webpack/webpack.server'); const prodPartial = require('./webpack/webpack.prod'); const { - AotPlugin -} = require('@ngtools/webpack'); + getAotPlugin +} = require('./webpack/webpack.aot'); const { root @@ -20,21 +20,14 @@ module.exports = function(options, webpackOptions) { } let serverConfig = webpackMerge({}, commonPartial, serverPartial, { - entry: options.aot ? './src/main.server.aot.ts' : serverPartial.entry, // Temporary plugins: [ - new AotPlugin({ - tsConfigPath: root(options.aot ? './src/tsconfig.server.aot.json' : './src/tsconfig.server.json'), - skipCodeGeneration: !options.aot - }) + getAotPlugin('server', !!options.aot) ] }); let clientConfig = webpackMerge({}, commonPartial, clientPartial, { plugins: [ - new AotPlugin({ - tsConfigPath: root('./src/tsconfig.browser.json'), - skipCodeGeneration: !options.aot - }) + getAotPlugin('client', !!options.aot) ] }); diff --git a/webpack/webpack.aot.js b/webpack/webpack.aot.js new file mode 100644 index 0000000000..b1d981a981 --- /dev/null +++ b/webpack/webpack.aot.js @@ -0,0 +1,30 @@ +const { + root +} = require('./helpers'); + +const { + AotPlugin +} = require('@ngtools/webpack'); + +const tsconfigs = { + client: root('./src/tsconfig.browser.json'), + server: root('./src/tsconfig.server.json') +}; + +/** + * Generates a AotPlugin for @ngtools/webpack + * + * @param {string} platform Should either be client or server + * @param {boolean} aot Enables/Disables AoT Compilation + * @returns {AotPlugin} Configuration of AotPlugin + */ +function getAotPlugin(platform, aot) { + return new AotPlugin({ + tsConfigPath: tsconfigs[platform], + skipCodeGeneration: !aot + }); +} + +module.exports = { + getAotPlugin: getAotPlugin +}; diff --git a/webpack/webpack.server.js b/webpack/webpack.server.js index a52e0546a4..7585fe917d 100644 --- a/webpack/webpack.server.js +++ b/webpack/webpack.server.js @@ -11,6 +11,6 @@ module.exports = { }, target: 'node', externals: [nodeExternals({ - whitelist: [/@ng/] + whitelist: [/@angular/, /@ng/] })], }; diff --git a/yarn.lock b/yarn.lock index 76cb582b02..644a6ecdc1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -213,9 +213,9 @@ version "8.0.14" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.14.tgz#4a19dc6bb61d16c01cbadc7b30ac23518fff176b" -"@types/node@8.0.31": - version "8.0.31" - resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.31.tgz#d9af61093cf4bfc9f066ca34de0175012cfb0ce9" +"@types/node@8.0.26": + version "8.0.26" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.26.tgz#4d58be925306fd22b1141085535a0268b8beb189" "@types/node@^6.0.46": version "6.0.52"