jFrenetic
jFrenetic

Reputation: 5552

Customize output directory for lazy loaded chunks in Angular 4

Is there a way to customize the output directory where some of the lazy loaded chunks will be stored? By default, all artifacts go to dist folder. But I need to store some of them in a sub-directory of dist (these are the chunks for modules that will be customized, and the client wants to keep them separate).

Example:

Before:

enter image description here

After:

enter image description here

I'm very new to Angular, and it seems that the only way to customize the build output is by doing ng eject, and taking the full control over the build configuration, which doesn't seem ideal. But even then, I'm not sure where to start.

Upvotes: 3

Views: 1659

Answers (3)

Vortilion
Vortilion

Reputation: 424

I managed to achieve the solution by just adding another parameter to the lazyLoad-Resolve cause I was having a similar problem:

lazyLoad: ['$q', '$transition$', function($q, $transition$) {
                const deferred = $q.defer();
                const $ocLazyLoad = $transition$.injector().get("$ocLazyLoad");

                // Async require => Split point
                require.ensure([], () => {
                    //
                    // All the code here, plus the required modules
                    // will be bundled in a separate file.
                    let module = require('../secure/app.secure.module.ajs');
                    //
                    // OCLazyLoad's 'load' function loads the Angular module.
                    $ocLazyLoad.load({name: 'collphir.customer-secure'});

                    deferred.resolve(module);
                }, 'secure/secure');

                return deferred.promise;
            }]

The line

}**, 'secure/secure'**);

is the solution. Took me a while to find this one on the internet... No need for the extra-webpack.config.js. Also, there is a weird thing with the solution suggestion by @Cofad: Only the lazy chunk runs through this switch-case, so actually it is not necessary to differentiate. Also, I can't use the lazy-chunk's [name] cause it doesn't have one so I tried it with the [id], but this does change when building in prod-mode. So I tried it with the [debugId] which seemed to stay the same. It felt very unstable to me though...

Upvotes: 0

Cofad
Cofad

Reputation: 184

For Angular 7+, you could use @angular-builders/custom-webpack.

Here's how to use it for Angular 12:

  1. Install @angular-builder/custom-webpack:

    npm i -D @angular-builders/custom-webpack
    
  2. Update angular.json to use custom webpack file:

    "projects": {
      ...
      "example-app": {
        ...
        "architect": {
          ...
          "build": {
            "builder": "@angular-builders/custom-webpack:browser",
            "options": {
              "customWebpackConfig": {
                  "path": "./extra-webpack.config.js"
              }
            }
          }
        }
      }
    }
    
  3. Create "extra-webpack.config.js" in project root directory. Update the case values as needed for your files. This is a modified example from the webpack Output documentation

    module.exports = {
      output: {
        chunkFilename: (pathData) => {
          let fileName;
    
          switch (pathData.chunk.id) {
            case 1:
              fileName = 'custom_dir/[name].js';
              break;
            case 3:
              fileName = 'custom_dir/[name].js';
              break;
            default:
              fileName = '[name].js';
          }
    
          return fileName;
        }
      }
    };
    
    
  4. Run ng build to generate dist folder with sub-directories.

Upvotes: 0

Phil
Phil

Reputation: 7607

Check out NRWL's NX to see how to build an enterprise angular application with separation in apps and libs. Your client probably wants the code related to him to be in a lib rather than the app itself. For the lib you can define an own tsconfig, which is extending the main project's tsconfig. Here is an example: https://github.com/nrwl/nx-examples/blob/master/libs/login/tsconfig.lib.json

Pay attention to the line

    "outDir": "../../out-tsc/libs/login",

which specifies where the output will be built.

Upvotes: 1

Related Questions