Aurelia Bundler - Bootstrap 3 is included twice in vendor bundle

Good Day

I have converted our Aurelia application to the new bundler format. The application is dependent on Bootstrap and JQuery as well as a few other 3rd party libraries. The application loads and works as expected. The only problem is that the popup menus do not activate when clicking on the link.

It looks like bootstrap is added twice to the vendor bundle, which I suspect is the problem.

Here is my aurelia.json

{
	"name": "web-client",
	"type": "project:application",
	"bundler": {
		"id": "cli",
		"displayName": "Aurelia-CLI"
	},
	"build": {
		"targets": [
			{
				"id": "web",
				"displayName": "Web",
				"port": 9001,
				"index": "index.html",
				"baseDir": ".",
				"output": "scripts"
			}
		],
		"options": {
			"minify": "stage & prod",
			"sourcemaps": "dev & stage",
			"rev": false,
			"cache": "dev & stage"
		},
		"bundles": [
			{
				"name": "app-bundle.js",
				"source": [
					"**/*.{js,css,html}"
				]
			},
			{
				"name": "vendor-bundle.js",
				"prepend": [
					"node_modules/bluebird/js/browser/bluebird.core.js",
					{
						"path": "node_modules/aurelia-cli/lib/resources/scripts/configure-bluebird-no-long-stacktraces.js",
						"env": "stage & prod"
					},
					{
						"path": "node_modules/aurelia-cli/lib/resources/scripts/configure-bluebird.js",
						"env": "dev"
					},
					"node_modules/requirejs/require.js",
					"node_modules/jquery/dist/jquery.js",
					"node_modules/bootstrap/dist/js/bootstrap.js"
				],
				"dependencies": [
					"aurelia-bootstrapper",
					"aurelia-loader-default",
					"aurelia-pal-browser",
					{
						"name": "aurelia-testing",
						"env": "dev"
					},
					"text",
					"aurelia-resize",
					"aurelia-chart",
					{
						"name": "aurelia-chart",
						"path": "../node_modules/aurelia-chart/dist/amd",
						"main": "index",
						"resources": [
							"elements/chart-element.js",
							"elements/chart-element.html",
							"attributes/chart-attribute.js"
						]
					}
				]
			}
		],
		"loader": {
			"type": "require",
			"configTarget": "vendor-bundle.js",
			"includeBundleMetadataInConfig": "auto",
			"plugins": [
				{
					"name": "text",
					"extensions": [
						".html",
						".css"
					],
					"stub": true
				}
			]
		}
	},
	"platform": {
		"id": "web",
		"displayName": "Web",
		"port": 9001,
		"index": "index.html",
		"baseDir": ".",
		"output": "scripts"
	},
	"transpiler": {
		"id": "typescript",
		"displayName": "TypeScript",
		"fileExtension": ".ts",
		"dtsSource": [
			"./custom_typings/**/*.d.ts"
		],
		"source": "src/**/*.ts"
	},
	"markupProcessor": {
		"id": "maximum",
		"displayName": "Maximum Minification",
		"fileExtension": ".html",
		"source": "src/**/*.html"
	},
	"cssProcessor": {
		"id": "sass",
		"displayName": "Sass",
		"fileExtension": ".scss",
		"source": "sass/**/*.scss",
		"dest": "style/"
	},
	"jsonschema": {
		"schemaDir": "./schemas",
		"modelsDir": "./src/common/models"
	},
	"editor": {
		"id": "webstorm",
		"displayName": "WebStorm"
	},
	"unitTestRunners": [
		{
			"id": "jest",
			"displayName": "Jest",
			"source": "test/unit/**/*.ts"
		}
	],
	"integrationTestRunner": {
		"id": "protractor",
		"displayName": "Protractor"
	},
	"paths": {
		"root": "src",
		"resources": "resources",
		"elements": "resources/elements",
		"attributes": "resources/attributes",
		"valueConverters": "resources/value-converters",
		"bindingBehaviors": "resources/binding-behaviors"
	},
	"testFramework": {
		"id": "jasmine",
		"displayName": "Jasmine"
	},
	"packageManager": "npm",
	"lint": [
		{
			"files": "src/**/*.ts",
			"project": "src/tsconfig.app.json"
		},
		{
			"files": "src/**/*.ts",
			"project": "src/tsconfig.spec.json"
		},
		{
			"files": "src/**/*.ts",
			"project": "e2e/tsconfig.e2e.json"
		}
	]
}

Here is the package.json file:

{
	"name": "*********",
	"description": "**********",
	"version": "1.0.0",
	"repository": {
		"type": "git",
		"url": "**************"
	},
	"dependencies": {
		"aurelia-animator-css": "^1.0.4",
		"aurelia-auth": "^3.0.5",
		"aurelia-bootstrap-datetimepicker": "^1.3.2",
		"aurelia-bootstrapper": "^2.3.0",
		"aurelia-chart": "^0.2.7",
		"aurelia-dialog": "^2.0.0-rc.3",
		"aurelia-fetch-client": "^1.6.0",
		"aurelia-google-maps": "^2.3.0",
		"aurelia-http-client": "^1.3.0",
		"aurelia-i18n": "^2.3.2",
		"aurelia-resize": "^1.1.2",
		"aurelia-store": "^1.3.1",
		"aurelia-validation": "^1.3.0",
		"bluebird": "^3.5.2",
		"bootstrap": "^3.4.0",
		"chart.js": "^2.7.3",
		"i18next": "^12.0.0",
		"i18next-browser-languagedetector": "^2.2.4",
		"i18next-xhr-backend": "^1.5.1",
		"jquery": "^3.1.1",
		"js-sha256": "^0.9.0",
		"ldclient-js": "^2.7.3",
		"lodash": "^4.17.11",
		"moment": "^2.22.2",
		"moment-timezone": "^0.5.23",
		"requirejs": "^2.3.6",
		"rxjs": "^6.3.3",
		"text": "github:requirejs/text#latest",
		"toastr": "^2.1.4",
		"webstomp-client": "^1.2.6"
	},
	"peerDependencies": {},
	"devDependencies": {
		"@types/jest": "^23.3.5",
		"@types/moment-timezone": "^0.5.9",
		"@types/lodash": "^4.14.92",
		"@types/node": "^10.11.6",
		"aurelia-cli": "^1.0.0-beta.4",
		"aurelia-loader-nodejs": "^1.0.1",
		"aurelia-pal-nodejs": "^1.1.1",
		"aurelia-protractor-plugin": "^1.0.6",
		"aurelia-testing": "^1.0.0",
		"aurelia-tools": "^2.0.0",
		"browser-sync": "^2.26.0",
		"compression": "^1.7.3",
		"connect-history-api-fallback": "^1.5.0",
		"debounce": "^1.2.0",
		"event-stream": "^4.0.1",
		"gulp": "^4.0.0",
		"gulp-changed-in-place": "^2.3.0",
		"gulp-clean": "^0.4.0",
		"gulp-htmlmin": "^5.0.1",
		"gulp-notify": "^3.2.0",
		"gulp-plumber": "^1.2.0",
		"gulp-protractor": "^4.1.0",
		"gulp-rename": "^1.4.0",
		"gulp-sass": "^4.0.1",
		"gulp-sourcemaps": "^2.6.4",
		"gulp-svgo": "^1.5.4",
		"gulp-svgstore": "^7.0.0",
		"gulp-tslint": "^8.1.3",
		"gulp-typescript": "^5.0.0-alpha.3",
		"gulp-watch": "^5.0.1",
		"html-minifier": "^3.5.20",
		"http-proxy-middleware": "^0.19.0",
		"jest": "^23.6.0",
		"jest-cli": "^23.6.0",
		"json-schema-to-typescript": "^6.0.2",
		"minimatch": "^3.0.4",
		"plugin-error": "^1.0.1",
		"protractor": "^5.4.1",
		"through2": "^2.0.3",
		"ts-jest": "^23.10.4",
		"ts-node": "^7.0.1",
		"tslint": "^5.11.0",
		"tslint-sonarts": "^1.8.0",
		"typescript": "^3.1.2",
		"vinyl-fs": "^3.0.3",
		"wait-on": "^3.1.0"
	},
	"jest": {
		"modulePaths": [
			"<rootDir>/src",
			"<rootDir>/node_modules"
		],
		"moduleFileExtensions": [
			"js",
			"json",
			"ts"
		],
		"transform": {
			"^.+\\.ts$": "ts-jest"
		},
		"testRegex": "\\.spec\\.(ts|js)$",
		"setupFiles": [
			"<rootDir>/test/jest-pretest.ts"
		],
		"testEnvironment": "node",
		"collectCoverage": true,
		"collectCoverageFrom": [
			"src/**/*.{js,ts}",
			"!**/*.spec.{js,ts}",
			"!**/node_modules/**",
			"!**/test/**"
		],
		"coverageDirectory": "<rootDir>/test/coverage-jest",
		"coverageReporters": [
			"json",
			"lcov",
			"text",
			"html"
		]
	}
}

Does anybody have an idea why the bootstrap js is included twice?
Thank you

1 Like

First remove these two
aurelia-resize", “aurelia-chart”. Cli can auto trace them.

Answer your question. You have duplicated bootstrap because you

  1. Added bootstrap to prepend (btw you added them after requirejs, which is wrong. requirejs must be the last item in prepend list). This will blindly pack the js before requirejs. Tracer has no idea what you added to prepend.
  2. You must used import "bootstrap";. That triggers the tracer to bundle bootstrap AFTER requirejs again.

So fix is simply remove the one in prepend.

Update: You are using bootstrap v3, not latest v4.

v3 has no native support of AMD (requirejs), so if you want to use import 'bootstrap';, you have to use shim config. Check here https://aurelia.io/docs/cli/cli-bundler/cook-book#bootstrap-css-v3-legacy

The other (better) option is:

  • add both jQuery and bootstrap to prepend, They have to be before requirejs, reorder them pls.
  • don’t use import 'jQuery'; and import 'bootstrap'; in source code, just use $ or jQuery as global variables.
  • to bypass eslint error on global variables, edit .eslintrc.json.
{
  //...
  "globals": {
    "$": true,
    "moment": true
  }
}
1 Like

Thank you very much for the feedback. I will try that