Skip to content

feat(@angular/cli): add ability to build bundle for node #6913

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

Merged
merged 1 commit into from
Jul 20, 2017

Conversation

FrozenPandaz
Copy link
Contributor

@FrozenPandaz FrozenPandaz commented Jul 7, 2017

This adds the ability to create a commonjs bundle which contains the application module/ngfactory which can be used in node environments

Here's an example of how a project using this feature would look https://github.com/FrozenPandaz/u-cli-app

@FrozenPandaz FrozenPandaz force-pushed the serverbuild branch 3 times, most recently from 31c8e93 to 160ca2c Compare July 10, 2017 23:57
hansl
hansl previously requested changes Jul 11, 2017
Copy link
Contributor

@hansl hansl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 question for now

@@ -4,5 +4,5 @@ import {DOCUMENT} from '@angular/platform-browser';

@Injectable()
export class MyInjectable {
constructor(public viewContainer: ViewContainerRef, @Inject(DOCUMENT) public doc) {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VCR is not an ordinary injectable

It can only be injected from a component and it's value is the VCR of the specific instance of the component.

A service/ injectable is not able to inject a VCR

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to test the downgrading of a non-annotated Angular class. I think the test needs to happen, I don't care much with which class. Does this test makes your code fail? How so?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is done in the normal webpack tests.

This test makes my tests fail because I am actually executing the application and it fails to bootstrap because the service is not able to find the VCR.

Is it fine to remove it from this set of tests because the functionality is covered in the other webpack tests?

@FrozenPandaz FrozenPandaz force-pushed the serverbuild branch 5 times, most recently from df8d278 to 2602917 Compare July 11, 2017 04:11
+ 'type: undefined, decorators.*Inject.*args: .*DOCUMENT.*'))
.then(() => expectFileToMatch('dist/app.main.js',
new RegExp('AppComponent.ctorParameters = .*MyInjectable'))
.then(() => expectFileToMatch('dist/app.main.js',
/AppModule \*\/\].*\.testProp = \'testing\'/))
.then(() => expectFileToMatch('dist/app.main.js',
/renderModuleFactory \*\/\].*\/\* AppModuleNgFactory \*\/\]/))
/renderModuleFactory \*\/\].*\/\* AppModuleNgFactory \*\/\]/))
.then(() => exec(normalize('rm'),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Considering there's no path, normalize('rm') is a noop.

@@ -83,6 +83,11 @@
"type": "string",
"description": "Base url for the application being built."
},
"platform": {
"type": "string",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be an enum, not a generic stsring.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is done.

@FrozenPandaz FrozenPandaz force-pushed the serverbuild branch 2 times, most recently from eb675f2 to 04d605e Compare July 14, 2017 06:14
@@ -436,6 +436,9 @@ export default Task.extend({
if (project.root === path.resolve(outputPath)) {
throw new SilentError ('Output path MUST not be project root directory!');
}
if (appConfig.platform && appConfig.platform === 'server') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

appConfig.platform is redundant here.

@@ -464,11 +533,14 @@ export function ngcLoader(this: LoaderContext & { _compilation: any }, source: s
if (!plugin.skipCodeGeneration) {
return Promise.resolve()
.then(() => _removeDecorators(refactor))
.then(() => _refactorBootstrap(plugin, refactor));
.then(() => _refactorBootstrap(plugin, refactor))
.then(() => _stuff(plugin, refactor))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_stuff? I'm sure you can do better ;)

@FrozenPandaz FrozenPandaz force-pushed the serverbuild branch 4 times, most recently from d6e695d to ed7f5f0 Compare July 18, 2017 03:07
});

const dirName = path.normalize(path.dirname(refactor.fileName));
let exportStatement = `export const moduleMap = ${JSON.stringify(map)};`;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change this to not use JSON.stringify and instead properly build up the export map without string replacement hacks.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, let's rename the exported symbol to LAZY_MODULE_FACTORY_MAP.

return {
loadChildrenString: routeKey,
path: plugin.lazyRoutes[lazyRouteKey],
name: routeKey.split('#')[1]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add validation that the loadChildren format is correct.

@FrozenPandaz FrozenPandaz force-pushed the serverbuild branch 2 times, most recently from e127c52 to a2d4ddb Compare July 19, 2017 01:22
@alxhub alxhub dismissed hansl’s stale review July 19, 2017 18:43

Jason has addressed the issues

refactor.prependBefore(node, `import * as __lazy_${index}__ from './${relativePath}'`);
return `"${routeKey}": __lazy_${index}__.${moduleName}`;
})
.join();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait, how are these separated. Shouldn't it be joined with a comma or something?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Never mind, apparently comma is the default for join().


const modulePath = plugin.lazyRoutes[lazyRouteKey];
const relativePath = path.relative(dirName, modulePath).replace(/\\/g, '/');
refactor.prependBefore(node, `import * as __lazy_${index}__ from './${relativePath}'`);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's weird for .map to have side effects. Can we move this out to a separate .forEach iteration through the keys?

refactor.prependBefore(node, `import * as __lazy_${index}__ from './${relativePath}'`);
return `"${routeKey}": __lazy_${index}__.${moduleName}`;
})
.join();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Never mind, apparently comma is the default for join().

@FrozenPandaz FrozenPandaz force-pushed the serverbuild branch 2 times, most recently from eafa684 to b6ae689 Compare July 20, 2017 18:53
alxhub
alxhub previously approved these changes Jul 20, 2017
@hansl
Copy link
Contributor

hansl commented Jul 20, 2017

Just confirmed locally that the e2e tests are flakes and everything is green. Cheers.

@hansl hansl merged commit 6f23636 into angular:master Jul 20, 2017
@intellix
Copy link
Contributor

intellix commented Jul 22, 2017

Was just playing with this and found an issue with a particular export pattern in barrels that is broken: intellix/universal-cli@8ed967d#diff-a44e09a3c12667be300e8cb75d793c5dR1

Worked inside @app/user/index.ts:

export * from './user.module';
export * from './user.service';

Didn't work inside app/user/index.ts:

export { UserModule } from './user.module';
export { UserService } from './user.service';

Build error:

Date: 2017-07-22T06:19:07.696Z
Hash: f089fcd9ebdfb15dd64e
Time: 2950ms
chunk {main} main.bundle.js (main) 20.8 kB [entry] [rendered]
chunk {polyfills} polyfills.bundle.js (polyfills) 6.35 kB [entry] [rendered]
chunk {styles} styles.bundle.js (styles) 13.7 kB [entry] [rendered]


ERROR in ./src/app/user/index.ts
Module parse failed: /Users/dominic/Sites/test/universal/node_modules/@ngtools/webpack/src/index.js!/Users/dominic/Sites/test/universal/src/app/user/index.ts Duplicate export 'LAZY_MODULE_MAP' (5:11)
You may need an appropriate loader to handle this file type.
| export var LAZY_MODULE_MAP = { "./lazy/lazy.module#LazyModule": __lazy_0__.LazyModule };
| export { UserService } from './user.service';
| export var LAZY_MODULE_MAP = { "./lazy/lazy.module#LazyModule": __lazy_0__.LazyModule };
| //# sourceMappingURL=index.js.map
@ ./src/app/app.module.ts 12:0-36
@ ./src/main.server.ts
@ multi ./src/main.server.ts

@FrozenPandaz FrozenPandaz deleted the serverbuild branch July 23, 2017 18:13
@FrozenPandaz
Copy link
Contributor Author

@intellix Thank you for testing this feature and for the replication for the issue.

I have prepared a fix for this issue but would you do the honors of logging it as an issue in this GitHub repo?

Thank you

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 12, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants