These configs are to use Vue3 and typescript; that is why its complex and manual

This is a dull article to save me time during a sprint. Merging your separate JS libraries into a bigger blob reduces the impact of the overheads of a HTTP transaction. Most webrowsers will only allow streaming of two assets at a time per domain. Merging all CSS and JS into fewer bigger blobs stops this from being a bottleneck. Sometimes people are running compiling tools to change from the version of JS that they want to write (code aesthetics) in to a maximum compatibility version.
Pls see js-modules-notes and js-classloader for older work in this space. I have been waiting for several years for JS module support 1 to climb, as it is a better way to solve the problem. Modules mean we go back to not having global variables again. If a feature has been decomposed into many JS files, its a good idea to merge them before transmission to the client side.
The most widely used transpiler/ bundler is still babeljs with webpack 2 3 docs. The newest version is 7.18 released on May 19, 2022 4. This is popular, but I don't like the config file very much; they look like 5 6.

module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset',
  ],
};

As I am now using typescript, I am now using at least one tsconfig file in each project. The documentation for this mentions 3-4 different file names (tsconfig.js, .tsconfigrc.js tsconfig.json, tsconfig.build.json and so on). The documentation is 7 8. The standard tool for typescript claims responsibility for type checking, generating meta data files and sometimes generating JS from the TS; not bundling.

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "strict": true,
    "jsx": "preserve",
    "experimentalDecorators": true,
	"strictPropertyInitialization":false,
	"emitDecoratorMetadata": true,
    "allowJs": true,
	"isolatedModules": true,
    "moduleResolution": "node",
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "forceConsistentCasingInFileNames": true,
    "useDefineForClassFields": true,
    "sourceMap": true,
	"skipLibCheck": true,
    "baseUrl": ".",
    "types": [ "src/types/vue3-touch-events.d.ts" ],
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
	},
  "exclude": [
    "node_modules"
  ]
}

The best tool for linting JS and TS that I have found was eslint; as it supplies alot of information. This is managed by in-source-comments that start "// eslint” 9 and by a config file called ".eslintrc.json” 10 11. I like that the eslint tool doesn't get in your way most of the time, and does offer a "--fix” option for things it cares about that no human should (i.e. are you using double or single quotes for string delimiting, or whether your IDE has expanded tabs or not).

{
  "root":true,
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaVersion": 2021,
    "sourceType": "module"
  },
  "plugins": ["@typescript-eslint/eslint-plugin", "eslint-plugin-vue"],
  "extends": ["plugin:@typescript-eslint/recommended", "plugin:vue/vue3-essential"],
  "rules":{ "strict":1 }
}

If you look at building failures in shopping-list, I have had to iterate tooling frequently. I have achieved partial success with rollupjs. This has a plain JS file for a config, but mostly you add more plugins to get behaviour 12 13 14.

import vue from 'rollup-plugin-vue';
import typescript from 'rollup-plugin-typescript2';
import replace from '@rollup/plugin-replace';
// import nodeResolve from '@rollup/plugin-node-resolve';
var fs = require('fs');

function presetSCF(nom, format) {
	let nom2='./build/components/'+nom+'.vue';
	if(! fs.existsSync( nom2 ) ) {
		nom2='./build/'+nom+'.vue';
	}

	const tt={
  input: nom2,
  treeshake: true,
  output: 	{
    intro: '//    INTERMEDIATE FILE, PLEASE DO NOT EDIT THIS.  \n//   Edit the original typescript files.\n//  Author: Owen Beresford, $mailaddress \n//   Licence: AGPL-3 https://www.gnu.org/licenses/agpl-3.0.en.html\n', 
    format: format,
    name: 'test',
    file: nom2.includes('components')?'./build/components/'+nom+'.js':'./build/'+nom+'.js',
 	 },
  plugins: [  
	typescript({
		check: false,
      module: 'esnext',
		 }),
    vue({ css: false }),
  ],
  external: [ 'vue', 'vue-router', "reflect-metadata", "ts-json-object", "vector2d", "vue3-touch-events", "vuex", "AList", "ListService", "LocalCopy", "URLs", "FAKE1_Factory", "Localisation", "InstallWorker", "MotionStream", "util"  ],
		};

	return tt;	
}

function presetTS(nom, format) {
	let nom2='/services/'+nom;
	if(! fs.existsSync( "./src"+nom2+".ts" ) ) {
		nom2='/'+nom;
	}

  const tt={
  input: "./build"+nom2+".ts",
  treeshake: true,
  output: 	{
    intro: '//    INTERMEDIATE FILE, PLEASE DO NOT EDIT THIS.  \n//   Edit the original typescript files.\n//  Author: Owen Beresford, $mailaddress \n//   Licence: AGPL-3 https://www.gnu.org/licenses/agpl-3.0.en.html\n', 
    format: format,
    name: 'test',
    file: './build'+nom2+'.js',
	 plugins: [ 

			], 
 	 },
  plugins: [  
 	replace({
		values:{
//      'process.env.NODE_ENV': JSON.stringify('production'),
//      __buildDate__: () => JSON.stringify(new Date()),
     'V2D.Vector':'Vector', 
	 "import \* as V2D from .*;": "import * as V2D from 'vector2d/src/Vector';",
	 ".vue'": "'",
			},
		preventAssignment:true,
    }), 
	typescript({
		check: false,
        module: 'esnext',
		 }),

  ],
  external: [  ],
		};

	return tt;	
}

function presetTS2(nom, format) {
	let nom2='/services/'+nom;
	if(! fs.existsSync( "./src"+nom2+".ts" ) ) {
		nom2='/'+nom;
	}

  const tt={
  input: "./build"+nom2+".ts",
  treeshake: true,
  output: 	{
    intro: '//    INTERMEDIATE FILE, PLEASE DO NOT EDIT THIS.  \n//   Edit the original typescript files.\n//  Author: Owen Beresford, $mailaddress \n//   Licence: AGPL-3 https://www.gnu.org/licenses/agpl-3.0.en.html\n', 
    format: format,
    name: 'test',
    file: './build'+nom2+'.js',
	 plugins: [ 

			], 
 	 },
  plugins: [  
 	replace({
		values:{
//      'process.env.NODE_ENV': JSON.stringify('production'),
//      __buildDate__: () => JSON.stringify(new Date()),
     'V2D.Vector':'Vector', 
	 "import \* as V2D from .*;": "import * as V2D from 'vector2d/src/Vector';",
	 ".vue'": "'",
			},
		preventAssignment:true,
    }), 
//	nodeResolve({ 
//		browser:true,
//		extensions:['.mjs', '.js', '.ts' ], 
//		moduleDirectories: ['node_modules', 'build' ],
//				}),	
	typescript({
		check: false,
        module: 'esnext',
		 }),

  ],
  external: [  ],
		};

	return tt;	
}

export default [
	presetSCF('EnterInput', 'es'),
	presetSCF('InterstitialView', 'es'),
	presetSCF('ListOfLists', 'es'),
	presetSCF('ThisList', 'es'),
	presetSCF('UnknownRoute', 'es'),
	presetSCF('TabBar', 'es'),
	presetSCF('App', 'es'),

	presetTS('Localisation', 'es'),
	presetTS('AList', 'es'),
	presetTS('Store', 'es'),
	presetTS('ListService', 'es'),
	presetTS('LocalCopy', 'es'),
	presetTS('URLs', 'es'),
	presetTS('MotionStream', 'es'),
	presetTS('FAKE1_Factory', 'es'),
	presetTS('util', 'es'),
	presetTS2('workers/InstallWorker', 'es'),
	presetTS2('components/Routing', 'es'),
	presetTS2('main', 'es'),

];

// and several more

I tried and failed to get Vite 15 16 (not vitebot, which is like selenium) to build front end code. Vite is very fast as it is correctly using JS modules. It is controlled via a config 17 18 that looks like this:

import { defineConfig } from 'vite';

// https://vitejs.dev/config/
export default defineConfig({
	plugins: [ ],
	root: '~/shopping/client-src/public',
	server: {
      hmr: false
	},
//	optimizeDeps: { 
//		include: [ "./build/*js", './build/components/*js', './build/services/*js']	
//	}
});

I haven't listed tools that I couldn't get to work; as I assume I would get the same fault in future. If I to need to pull those names, they are listed in the project article.

Some similar articles in research