Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(@ngtools/webpack): Handle factory files for the LAZY_MODULE_MAP #8157

Merged
merged 1 commit into from
Oct 23, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { oneLine, stripIndent } from 'common-tags';
import { transformTypescript } from './ast_helpers';
import { exportLazyModuleMap } from './export_lazy_module_map';

describe('@ngtools/webpack transformers', () => {
describe('replace_resources', () => {
describe('export_lazy_module_map', () => {
it('should create module map for JIT', () => {
it('should replace resources', () => {
const input = stripIndent`
export { AppModule } from './app/app.module';
Expand All @@ -27,4 +27,28 @@ describe('@ngtools/webpack transformers', () => {
expect(oneLine`${result}`).toEqual(oneLine`${output}`);
});
});

it('should create module map for AOT', () => {
const input = stripIndent`
export { AppModule } from './app/app.module';
`;
// tslint:disable:max-line-length
const output = stripIndent`
import * as __lazy_0__ from "app/lazy/lazy.module.ts";
import * as __lazy_1__ from "app/lazy2/lazy2.module.ts";
export { AppModule } from './app/app.module';
export var LAZY_MODULE_MAP = { "./lazy/lazy.module#LazyModule": __lazy_0__.LazyModule, "./lazy2/lazy2.module#LazyModule2": __lazy_1__.LazyModule2 };
`;
// tslint:enable:max-line-length

const transformOpsCb = (sourceFile: ts.SourceFile) => exportLazyModuleMap(sourceFile, {
'./lazy/lazy.module.ngfactory#LazyModuleNgFactory':
'/project/src/app/lazy/lazy.module.ngfactory.ts',
'./lazy2/lazy2.module.ngfactory#LazyModule2NgFactory':
'/project/src/app/lazy2/lazy2.module.ngfactory.ts',
});
const result = transformTypescript(input, transformOpsCb);

expect(oneLine`${result}`).toEqual(oneLine`${output}`);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,16 @@ export function exportLazyModuleMap(

const modules = Object.keys(lazyRoutes)
.map((loadChildrenString) => {
const [, moduleName] = loadChildrenString.split('#');
const modulePath = lazyRoutes[loadChildrenString];
let [, moduleName] = loadChildrenString.split('#');
let modulePath = lazyRoutes[loadChildrenString];

if (modulePath.endsWith('.ngfactory.ts')) {
modulePath = modulePath.replace('.ngfactory', '');
moduleName = moduleName.replace('NgFactory', '');
loadChildrenString = loadChildrenString
.replace('.ngfactory', '')
.replace('NgFactory', '');
}

return {
modulePath,
Expand Down
131 changes: 131 additions & 0 deletions tests/e2e/tests/build/platform-server-lazy-module-map.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import { normalize } from 'path';

import { updateJsonFile, updateTsConfig } from '../../utils/project';
import {
expectFileToMatch,
writeFile,
replaceInFile,
prependToFile,
appendToFile,
} from '../../utils/fs';
import { ng, silentNpm, exec } from '../../utils/process';
import { getGlobalVariable } from '../../utils/env';
import { expectToFail } from '../../utils/utils';

export default function () {
// Skip this in Appveyor tests.
if (getGlobalVariable('argv').appveyor) {
return Promise.resolve();
}

// Skip this for ejected tests.
if (getGlobalVariable('argv').eject) {
return Promise.resolve();
}

let platformServerVersion = '^4.0.0';

if (getGlobalVariable('argv').nightly) {
platformServerVersion = 'github:angular/platform-server-builds';
}

return Promise.resolve()
.then(() => updateJsonFile('.angular-cli.json', configJson => {
const app = configJson['apps'][0];
delete app['polyfills'];
delete app['styles'];
app['platform'] = 'server';
}))
.then(() => updateJsonFile('package.json', packageJson => {
const dependencies = packageJson['dependencies'];
dependencies['@angular/platform-server'] = platformServerVersion;
}))
.then(() => updateTsConfig(tsConfig => {
tsConfig.compilerOptions.types = ['node'];
tsConfig['angularCompilerOptions'] = {
entryModule: 'app/app.module#AppModule'
};
}))
.then(() => writeFile('./src/main.ts', 'export { AppModule } from \'./app/app.module\';'))
.then(() => prependToFile('./src/app/app.module.ts',
'import { ServerModule } from \'@angular/platform-server\';'))
.then(() => replaceInFile('./src/app/app.module.ts', /\[\s*BrowserModule/g,
`[BrowserModule.withServerTransition(\{ appId: 'app' \}), ServerModule`))
.then(() => silentNpm('install'))
.then(() => ng('build'))
// files were created successfully
.then(() => expectFileToMatch('dist/main.bundle.js',
/__webpack_exports__, "AppModule"/))
.then(() => writeFile('./index.js', `
require('zone.js/dist/zone-node');
require('reflect-metadata');
const fs = require('fs');
const \{ AppModule \} = require('./dist/main.bundle');
const \{ renderModule \} = require('@angular/platform-server');

renderModule(AppModule, \{
url: '/',
document: '<app-root></app-root>'
\}).then(html => \{
fs.writeFileSync('dist/index.html', html);
\});
`))
.then(() => exec(normalize('node'), 'index.js'))
.then(() => expectFileToMatch('dist/index.html',
new RegExp('<h2 _ngcontent-c0="">Here are some links to help you start: </h2>')))
.then(() => ng('build', '--aot'))
// files were created successfully
.then(() => replaceInFile('./index.js', /AppModule/g, 'AppModuleNgFactory'))
.then(() => replaceInFile('./index.js', /renderModule/g, 'renderModuleFactory'))
.then(() => exec(normalize('node'), 'index.js'))

// Check externals.
.then(() => prependToFile('./src/app/app.module.ts', `
import 'zone.js/dist/zone-node';
import 'reflect-metadata';
`)
.then(() => appendToFile('./src/app/app.module.ts', `
import * as fs from 'fs';
import { renderModule } from '@angular/platform-server';

renderModule(AppModule, \{
url: '/',
document: '<app-root></app-root>'
\}).then(html => \{
fs.writeFileSync('dist/index.html', html);
\});
`)))
.then(() => ng('generate', 'module', 'lazy', '--routing'))
.then(() =>
writeFile('src/app/app.module.ts', `
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import { AppComponent } from './app.component';
import { RouterModule } from '@angular/router';

@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
RouterModule.forRoot([
{ path: 'lazy', loadChildren: './lazy/lazy.module#LazyModule' }
])
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
`
))
.then(() => ng('build', '--aot'))
// should not contain ".ngfactory#" or "NgFactory"
.then(() => expectFileToMatch('dist/main.bundle.js',
'var LAZY_MODULE_MAP = { "./lazy/lazy.module#LazyModule"'));
}