Angular-cli: nameLazyFiles - ugly/unexpected names

Created on 1 Mar 2018  路  15Comments  路  Source: angular/angular-cli

Versions

@ngtools/webpack: 6.0.0-beta.4

Repro steps

  • Create app with lazy loaded routes where modules are in some subdirectory (not in the root directory).
  • Compile app using webpack AngularCompilerPlugin with nameLazyFiles set to true + output.chunkFilename set to '[name].chunk.js',

Observed behavior

Relative filesystem path to the compiled module is:
.\SubjectCommon\js\controllers\credit\credit.module.ts
and the name of the coresponding chunk is:
SubjectCommon-js-controllers-credit-credit-module-ngfactory.chunk.js

Desired behavior

Chunk name should be:
credit.module.chunk.js

Mention any other details that might be useful (optional)

I belive that option "nameLazyFiles" should replace existing plugin NamedLazyChunksWebpackPlugin (from previous version of CLI). But it works differently. NamedLazyChunksWebpackPlugin generated correct name "credit.module.chunk.js".
The problem is on this line:

https://github.com/angular/angular-cli/blob/71f38222c02f0a25c6278cd256663f9e8812a8bb/packages/%40ngtools/webpack/src/angular_compiler_plugin.ts#L598

"importPath" contains path to the factory file without any extension (regex is not correct because it expect extension). And just the name of the factory file should be used. Not whole path.

devkibuild-angular RFC / discussion / question faq feature

Most helpful comment

we are having issue that I belive might be related...
When building the naming becomes like:
chunk {5} contact-us-contact-us-module-ngfactory.js, contact-us-contact-us-module-ngfactory.js.map (contact-us-contact-us-module-ngfactory) 10.1 kB [rendered]

But then we also have another strange file being generated...
chunk {2} default~checkout-checkout-module-ngfactory~registration-registration-module-ngfactory.js, default~checkout-checkout-module-ngfactory~registration-registration-module-ngfactory.js.map (default~checkout-checkout-module-ngfactory~registration-registration-module-ngfactory) 23.8 kB [rendered]

By the looks of the naming it looks like it has merged 2 modules?

I believe that this is causing our site to crash currently..

All 15 comments

Beyond the ngfactory segment, this change was intentional. The named chunks are intended to be a development aid and not meant for production builds. The path from the project root is used to simplify debugging scenarios. However, the main benefit is actually to allow more clear differentiation of identically named but differently located modules (e.g., app/lazy/lazy.module.ts & app/somewhere/lazy/lazy.module.ts). The index approach would produce lazy-module.0.js and lazy-module.1.js which, while less verbose, provides little insight into which source module each references.

@clydin I understand the benefit you're pointing out, but for the common case, it's a bit weird.

If you have a single module UsersModule in a sub-directory modules/users, we used to have a file named users.module.chunk.js and now we have a modules-users-users-module-ngfactory.js file. Which is (I think) less readable (even without the ngfactory bit).

And maybe that should probably be noted in the breaking changes, as some users might rely on the former names to do some things in their builds (like tracking build sizes...)?

we are having issue that I belive might be related...
When building the naming becomes like:
chunk {5} contact-us-contact-us-module-ngfactory.js, contact-us-contact-us-module-ngfactory.js.map (contact-us-contact-us-module-ngfactory) 10.1 kB [rendered]

But then we also have another strange file being generated...
chunk {2} default~checkout-checkout-module-ngfactory~registration-registration-module-ngfactory.js, default~checkout-checkout-module-ngfactory~registration-registration-module-ngfactory.js.map (default~checkout-checkout-module-ngfactory~registration-registration-module-ngfactory) 23.8 kB [rendered]

By the looks of the naming it looks like it has merged 2 modules?

I believe that this is causing our site to crash currently..

@clydin if it's not intended for production then perhaps it should be stated in the docs? Or perhaps it should throw a warning in the console?

The setting is off by default and not included in the default production configuration. However, there is nothing wrong with using it in production. It鈥檚 similar to source maps or other development related settings that aid in debugging. Generally for deployed builds, details of the source are preferred to be minimized where possible (which is why source maps are also off for production builds by default).

Not sure why but it generates a bug for us when using named chunks. (as mentioned above)
When setting is true, first load always return a blank page with the follow error.
image

Setting it to false makes it work again..

Any idea? Or just a direction would be appreciated :)

The problem with using the full path in the file name is that it chops off the end after a certain number of characters. I understand that the file name is supposed to be the combination of lazy modules that use the code in the chunk, but using the full path means that in some cases (e.g. if you have over 3 or 4 lazy modules sharing the same code that is not part of the main bundle), the names of those modules will get cut off.

e.g.

  • Chunk used by Feature A, Feature B and Feature C: my-directory-path-feature-a-module-ngfactory~my-directory-path-feature-b-module-ngfactory~my-dir~5cc13a5a.d7fdc7d0fad47c2a9f72.js
  • Chunk used by Feature A, Feature B and Feature D: my-directory-path-feature-a-module-ngfactory~my-directory-path-feature-b-module-ngfactory~my-dir~45c9bbbc.88f2dc0cdf8a7c002bd4.js

Looking at the above chunk names, I have no idea which of the two the chunk used by Feature C and which is used by Feature D.

If we just included the module names instead of the entire path, we could have fit all the module names in (e.g. feature-a-module~feature-b-module~feature-c-module.d7fdc7d0fad47c2a9f72.js and feature-a-module~feature-b-module~feature-d-module.88f2dc0cdf8a7c002bd4.js).

Conclusion: If you have a lazy loaded module with an empty path, be sure to put it at the end of your defined routes or it will be loaded unnecessarily. (or possibly use pathMatch: 'full')


@mackelito did you ever figure out what was happening with your default~ chunk?

I have something very similar, with these 3 modules being loaded when I access 'account'

default~sections-homepage-homepage-module~sections-products-products-module.js
sections-homepage-homepage-module.js
sections-account-account-module.js

On further inspection it seems that it's the empty path for the 'homepage' module that causes this.

{
    path: 'products',
    loadChildren: './sections/products/products.module#ProductsModule',
},
{
    path: '',
    loadChildren: './sections/homepage/homepage.module#HomepageModule',
},
{
    path: 'admin',
    loadChildren: './sections/admin/admin.module#AdminModule',
},

So if I hit /admin then that triggers the empty path and also loads Homepage module. Quite why the default~... module contains products I'm not sure - but in any case changing the '' to 'home' stopped the unneeded modules from being loaded.

Anyway, so notice how the homepage module is defined between products and admin? Moving it until the last item in the list prevents the homepage module loading if you're not even on the homepage! So this immediately made things a lot more efficient. I didn't experiment with pathMatch here, but none of my module routes currently have it.

Still curious exactly how it decided to combine homepage and products modules together - maybe it determined the common things between them? Would be interested to know exactly what it does.

@simeyla We just changed namedChunks to false.. not what we wanted but it did the trick..

I am also facing the same issue, my app lazyloaded module chunk are being named as - feature-admin-admin-module-ngfactory.0ce6a7ea5a3fecc4d102. I am hosted this app using AWS S3 and cloudfront where in cloud front i need to protect some module files based on signed cookie. I am relying on file name to configure cloud front behavior based on file name. But chunk name issue certainly causing me issue to achieve that.

Hope this helps:

I had the same issue that commonChunks with default~ .... where generated.

use in you angular.json (where you have "aot": true ... etc.):

"commonChunk": false

@andreElrico but that removes an important optimization afaik.

Ran into this issue also, was fixed by setting "namedChunks": false, in angular.json. Though i think the issue stems from the server not correctly routing to files with ~ in the name?

Closing as this is working as intended.

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._

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sysmat picture sysmat  路  3Comments

JanStureNielsen picture JanStureNielsen  路  3Comments

daBishMan picture daBishMan  路  3Comments

donaldallen picture donaldallen  路  3Comments

gotschmarcel picture gotschmarcel  路  3Comments