I’m working on a hybrid Angular 13 application, and using webpack to package it for production, but I’m having an issue the ng-bootrap library. There are AngularJS components in the application using modules from the angular-ui library, I’m not sure if this is part of the issue.
I’ve added the ng-bootstrap library to package.json, so I can use the modules in the application, without causing any issue, but when I add any module to the app.module file, the production build will not open in a browser. However, the development build opens without issue
these are the relevant entries in the package.json file
"dependencies": {
...,
"@ng-bootstrap/ng-bootstrap": "^12.1.2",
"@popperjs/core": "^2.10.2"
},
"devDependencies": {
...,
"@ngtools/webpack": "^13.3.9",
"@types/webpack": "^5.28.0",
"@types/webpack-env": "^1.16.3",
"clean-webpack-plugin": "^3.0.0",
"copy-webpack-plugin": "^8.1.1",
"css-minimizer-webpack-plugin": "^3.0.1",
"html-webpack-plugin": "^5.5.0",
"image-webpack-loader": "^7.0.1",
"karma-webpack": "^5.0.0",
"webpack": "^5.39.1",
"webpack-bundle-analyzer": "^4.4.2",
"webpack-cli": "^4.7.2",
"webpack-dev-server": "^3.11.2",
"webpack-manifest-plugin": "^5.0.0",
"webpack-merge": "^5.8.0",
"webpack-nano": "^1.1.1"
}
app.module.ts
import { NgbAlertModule } from '@ng-bootstrap/ng-bootstrap';
@NgModule({
imports: [
...,
NgbAlertModule
],
The build does complete successfully, but when I open a browser, I get this exception in the console log
app-6279414c.346772f…ed2a2ea.bundle.js:1 Uncaught TypeError: Cannot read properties of undefined (reading 'call')
at d (app-6279414c.346772f….bundle.js:1:160677)
at i (app-6279414c.346772f….bundle.js:1:164659)
at 3268 (common-b48beae3.f498…7.bundle.js:2:12304)
Is there anything missing from the webpack production file(below), or do any of the existing options need to be modified?
webpack.production.js
const webpack = require("webpack");
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const { AngularWebpackPlugin } = require('@ngtools/webpack');
const { WebpackManifestPlugin } = require('webpack-manifest-plugin');
module.exports = {
entry: {
'polyfills': './src/project/ng2/polyfills.ts',
'vendor': './src/project/ng2/vendors.aot.ts',
'ng1': './src/project/app.module.ajs.ts',
'app': './src/project/ng2/main.aot.ts'
},
output: {
filename: '[name].[contenthash].bundle.js',
path: path.resolve(__dirname, './src/app'),
publicPath: ''
},
mode: 'production',
resolve: {
extensions: [".ts", ".tsx", ".js"]
},
module: {
rules: [{
test: /.css$/,
use: [ MiniCssExtractPlugin.loader, 'css-loader' ]
}, {
test: /.tsx?$/,
enforce: 'pre',
loader: 'ts-loader',
options: {
configFile: 'tsconfig.json'
},
exclude: [
path.resolve(__dirname, './src/project/ng2'),
/node_modules/
],
}, {
test: /.[jt]sx?$/,
loader: '@ngtools/webpack',
include: [
path.resolve(__dirname, './src/project/ng2'),
/node_modules/
],
}, {
test: /.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/env'],
plugins: ['@babel/plugin-proposal-class-properties', 'angularjs-annotate']
}
}
}, {
test: /.html$/,
exclude: /node_modules/,
include: [ path.resolve(__dirname, './src/project/ng2') ],
loader: 'html-loader'
}, {
test: /.html$/,
exclude: [
path.resolve(__dirname, './src/project/ng2'),
/node_modules/
],
loader: 'raw-loader'
}, {
test: /.(png|woff|woff2|eot|ttf|svg|gif)$/,
use: [{
loader: 'url-loader',
options: {
limit: 5000,
name: 'images/[name].[ext]'
}
}]
}, {
test: /.mjs$/,
use: {
loader: 'babel-loader',
options: {
plugins: ['@angular/compiler-cli/linker/babel'],
compact: false,
cacheDirectory: true,
}
}
}]
},
plugins: [
new HtmlWebpackPlugin({
template: 'src/project/index.html',
minify: true,
scriptLoading: 'defer',
inject: true
}),
new MiniCssExtractPlugin({
filename: 'styles.[contenthash].css'
}),
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: ['**/*']
}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
"window.jQuery": "jquery",
moment: 'moment'
}),
new CopyWebpackPlugin({
patterns: [{
context: './src/project',
from: '**/*.html',
globOptions: {
dot: true,
gitignore: true,
ignore: ["**/*index.html", "**/ignored-directory/**"],
},
to: './',
force: true
}]
}),
new webpack.IgnorePlugin({
resourceRegExp: /^./locale$/,
contextRegExp: /moment$/,
}),
new webpack.ContextReplacementPlugin(/./locale$/, 'empty-module', false, /js$/),
new webpack.optimize.ModuleConcatenationPlugin(),
new AngularWebpackPlugin({
tsconfig: './tsconfig.aot.json',
entryModule: path.resolve(__dirname, './src/project/ng2/app.module#AppModule'),
skipCodeGeneration: true
}),
new WebpackManifestPlugin()
],
optimization: {
moduleIds: 'deterministic',
mangleWasmImports: true,
mergeDuplicateChunks: true,
minimizer: [
`...`,
new CssMinimizerPlugin(),
],
splitChunks: {
chunks: 'all',
minSize: 3000,
minRemainingSize: 0,
minChunks: 1,
maxAsyncRequests: 30,
maxInitialRequests: 30,
enforceSizeThreshold: 50000,
maxSize: 600000,
name: 'common',
cacheGroups: {
vendors: {
test: /[\/]node_modules[\/]/,
priority: -10,
reuseExistingChunk: true,
idHint: 'node_module_vendor'
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
idHint: 'ng2'
}
},
usedExports: true
}
}
};