Use the AOT compiler to compile angular libraries suitable for AOT and JIT consumption.
- Compile resources (HTML, CSS, SCSS etc..) through webpack loaders
- Use same configuration for development and library production build.
- Inline resources
The @ngtools/webpack
package is built for webpack bundling and does not
support the process of generating libraries for angular.
Library compilation has a specific process where each TS file is compiled to JS a file without bundling the output.
@angular/compiler-cli
supports this mode. By using the proper
configuration you can compile TS to JS for libraries with full AOT support.
The problem with using the @angular/compiler-cli
is that it does not
know about webpack, resources will not go through the loader chain and so
using formats not supported the the angular cli will not work (SCSS, LESS etc).
Additionally, templareUrl
and stylesUrls
are left as is which is not
suitable for libraries, they most be inlined into the sources code (JS)
and the AOT generated metadata.json
files.
ngc-webpack
library mode allows AOT compilation from libraries through
a CLI interface or directly using it via node API.
Using library mode, ngc-webpack
will use webpack
to pass all resources
through the loader chain and passing the output to the angular AOT compiler.
Using webpack
ensures consistency, whatever loaders you used to build
your demo app are also used to build the library.
ngc-webpack
can also inline your resources to both JS output files and
to the .metadata.json
files generated by angular. Inlining is automatically
applied based on your AOT configuration set on tsconfig
Library mode does not require specific configuration, it is configured
using existing configuration in tsconfig
and webpack.config
.
The output is controlled by the tsconfig
supplied.
ngc-webpack
will inline all resources to both metadata.json
files and js
source code.
If skipTemplateCodegen
is set to false the compiler will emit source code for all resource in dedicated modules
and so ngc-webpack
will not perform the inline operation.
The examples refers to a typical library project structure where a demo app is used in development and consumes the library.
ngc-w --webpack webpack.config.packge.js
You'r webpack config should contain the loaders you use in your dev and
prod builds and NgcWebpackPlugin
instance must exists in the plugins collection.
The NgcWebpackPlugin
instance option's tsConfigPath
property should
point to a tsconfig
file that is properly set for library compilation.
Another options is to use the webpack config you are using for prod/dev
with a command line param pointing at the tsconfig, ngc-webpack
will
replace the tsConfigPath
in run time.
ngc-w --webpack webpack.config.app.js -p tsconfig.package.json
Angular CLI does not support library builds out of the box but with some
magic it is possible.
As we now know, webpack
is not used for bundling when compiling libraries
so actually what we need is only the webpack configuration that the cli creates.
ngc-webpack
invokes the cli and captures the configuration files and then
uses it with a different tsconfig
to build the library.
ngc-w-cli build -p tsconfig.package.json
We do not need to specify a webpack config, we get it from the cli but
we do need to specify the build
command so the cli will not complain.
The tsconfig (-p) is not mandatory, if not set it is taken from the plugin
but ofcourse this is not recommended so your will need to set it.
TODO...
For now, see the test (`cli.spec.ts)
A tsconfig
for library compilation is quite similar to your application
configuration with some modification:
-
You can not use
include
, a specificfiles
entry must be set with 1ts
module set at index 0 (and optional d.ts afterwards) -
An
outDir
must be set, this is where the output of the compilation is saved -
declaration
should be set to true sod.ts
files are shipped with your library. -
angularCompilerOptions
should be set for flat module output and other instructions:
angularCompilerOptions: {
annotateForClosureCompiler: true,
skipMetadataEmit: false,
skipTemplateCodegen: true,
strictMetadataEmit: true,
flatModuleOutFile: 'my-lib.ng-flat.js',
flatModuleId: 'my-lib'
}
Mono-repos are a great way to publish libraries under the same npm scope or as part of a big project.
ngc-webpack
library mode can work well with monorepo setup, the trick
with monorepo setup is configuration, especially paths
For a fully managed monorepo solution, integrated with the angular-cli
you can use nrwl's Nx
For a custom setup, please take a look at angular-library-starter
which has a setup running with the library mode of ngc-webpack