Aurelia failing to start due to missing HTML module

Hey There!

I’m trying to learn how to use Aurelia with Webpack (I’m new to both these technologies) and while I’ve managed to get the the source code to bundle and Aurelia to bootstrap, every time I run my site I get the following error:

Uncaught (in promise) Error: Unable to find module with ID: routing.html
at WebpackLoader.<anonymous> (vendors.66d6ee110672fb689536.js:7713)
at step (vendors.66d6ee110672fb689536.js:7574)
at Object.next (vendors.66d6ee110672fb689536.js:7555)
at vendors.66d6ee110672fb689536.js:7549
at new Promise (<anonymous>)
at push../node_modules/aurelia-loader-webpack/dist/native-modules/aurelia-loader-webpack.js.__awaiter (vendors.66d6ee110672fb689536.js:7545)
at WebpackLoader.push../node_modules/aurelia-loader-webpack/dist/native-modules/aurelia-loader-webpack.js.WebpackLoader._import (vendors.66d6ee110672fb689536.js:7680)
at WebpackLoader.<anonymous> (vendors.66d6ee110672fb689536.js:7778)
at step (vendors.66d6ee110672fb689536.js:7574)
at Object.next (vendors.66d6ee110672fb689536.js:7555)

This is my current project structure:

  • /root/
    • /dist/
    • /src/
      • /app/
      • /css/
      • main.ts
      • routing.html
      • routing.ts

Inside /app/ and /css/ are the various components and their views. /dist/ is where Webpack outputs the vendor.js, runtime.js and app.js chunks as well as my index.html page and any transpiled css files. /dist/ also acts as the root directory for the website.

This is my Webpack config file (it currently runs as a build script)

const compiler = webpack(
{
mode: "development",
devtool: false,
    context: __dirname + "/../",
entry: 
{ 
	app: ["aurelia-bootstrapper"]
},
output:
{
	path: __dirname + "/../dist",
    filename: "[name].[contenthash].js"
   },    
   optimization:
  {
    runtimeChunk: "single",
    splitChunks: 
    {
        cacheGroups: 
        {
            vendor: 
            {
                test: /[\\/]node_modules[\\/]/,
                name: "vendors",
                chunks: "all"
            }
        }
    }
},
module: 
{
	rules: 
	[
		{ test: /\.ts$/, use: "ts-loader", exclude: "/node_modules/" },            
        { test: /\.html$/i, use: "html-loader" },            
	]
},
resolve: 
{
	extensions: [".ts", ".js", ".html" ],
    modules: [ "./src", "./node_modules" ]
},
plugins: [new HtmlWebpackPlugin({ template:"./index.html", title: "This is my site" }), new AureliaPlugin() ]
});

the index.html file sitting in dist looks like this:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Aurelia Test</title>
</head>
<body aurelia-app="main">	
     <script type="text/javascript" src="runtime.01308d7cc7f8f5e719e6.js"></script>
     <script type="text/javascript" src="vendors.66d6ee110672fb689536.js"></script>
     <script type="text/javascript" src="app.25a8bf1c34ff7b3997ab.js"></script>
</body>
</html>

my main.ts file contains:

import { Aurelia } from "aurelia-framework"
import { PLATFORM } from "aurelia-pal";

export function configure(aurelia: Aurelia)
{
    aurelia.use.basicConfiguration();
    aurelia.start().then(() => aurelia.setRoot( PLATFORM.moduleName("routing") ));
}

Looking at the app bundle, all the necessary code needed to run the app is there. So the problem is why it can’t find the routing.html file (also, why is it treating the html file like a module?). Any help would be appreciated. Let me know if you need any more information.

Thanks!

Looks good at first sight.

I’m suspecting the splitChunksis interfering. Can you try to run without optimizations?

Unfortunately, you can’t move everything to chunks. I know for sure that aurelia-loader-webpack has to stay in your entry chunk.

BTW, I’m not monitoring discourse. You can ping me on Github or Discord.

Thanks for the response!

Unfortunately, the only reason I’m using the split chunks stuff is because of this problem, I thought it would help me figure out what was actually being included in the main entry chunk in order to better diagnose the problem. So the problem appeared before I started using split chunks.

Should I be bundling the html files as modules though? The error I’m getting makes it seem as if it believes the html for the routing component is bundled with the rest of the app and not sitting in a separate HTML file on the server. Is that a thing with bundling? Or am I misinterpreting the error I’m getting? I’m completely new to this so I’m not sure what the correct way to do things is.

Thanks,

HTML views are loaded by aurelia-loader and when you use Webpack it means they’re bundled with the rest of the application. Yes, this is normal behavior.

The thing is, when routing.ts is an Aurelia dependency, AureliaPlugin should automatically include routing.html as a dependency as well.

First thing to figure out here is:

  • Is routing.html included in the bundle or not?
  • If it is, what is its module id and why is it not the id that Aurelia expects?

Those questions can be answered by looking at the output of webpack --display-modules

Alright, so I think I’ve figured out the original problem. I mentioned in my first post that I was actually using the webpack API to do the bundling from a build script instead of using the CLI. In order to run the bundler with --display-modules parameter I switched to using the CLI. Using the exact same config file the CLI built the app with the HTML files bundled as modules. Using the API for some reason does not bundle the HTML files. So I think the original issue was just me not using the API correctly.

The new issue is that it cannot find the routing module for some reason:

Uncaught (in promise) Error: Unable to find module with ID: Routing
at WebpackLoader.<anonymous> (vendors.d9a29c87d67ecd9c5782.js:7713)
at step (vendors.d9a29c87d67ecd9c5782.js:7574)
at Object.next (vendors.d9a29c87d67ecd9c5782.js:7555)
at vendors.d9a29c87d67ecd9c5782.js:7549
at new Promise (<anonymous>)
at push../node_modules/aurelia-loader-webpack/dist/native-modules/aurelia-loader-webpack.js.__awaiter (vendors.d9a29c87d67ecd9c5782.js:7545)
at WebpackLoader.push../node_modules/aurelia-loader-webpack/dist/native-modules/aurelia-loader-webpack.js.WebpackLoader._import (vendors.d9a29c87d67ecd9c5782.js:7680)
at WebpackLoader.<anonymous> (vendors.d9a29c87d67ecd9c5782.js:7778)
at step (vendors.d9a29c87d67ecd9c5782.js:7574)
at Object.next (vendors.d9a29c87d67ecd9c5782.js:7555)

Which is weird because if I open up the app bundle js file, this is one of the modules:

/***/ "Routing?8064":
/*!*************************************************!*\
!*** C:/Work/AureliaTest/WebApp/src/Routing.ts ***!
\*************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const aurelia_pal_1 = __webpack_require__(/*! aurelia-pal */ "./node_modules/aurelia-pal/dist/native-modules/aurelia-pal.js");
class Routing {
    configureRouter(config, router) {
        config.title = "Aurelia Test";
        config.map([
            { route: ["", "login"], name: "login", moduleId: 'app/pages/login/login', nav: true, title: "Login" }
        ]);
        this.router = router;
    }
}
exports.Routing = Routing;
/***/ }),

The fail seems to be from the main.ts file which is:

import { Aurelia } from "aurelia-framework"
import { PLATFORM } from "aurelia-pal";

export function configure(aurelia: Aurelia)
{
    console.log("Starting Aurelia configuration...")

    aurelia.use.basicConfiguration();
    aurelia.start().then(() => aurelia.setRoot( PLATFORM.moduleName("Routing") ));
}

Does this look right?

I recall someone opened an issue about Webpack CLI working but not API.
I never looked deeply into it and gut feeling is that if Webpack CLI and API don’t work the same then it’s a problem with Webpack…

Unless it’s a problem with the folder where the build actually runs? As I said I didn’t look deeply into this. Maybe resovling stuff like resolve.modules to absolute paths could help (but then again, maybe not).

Regarding your new problem: the module id is Routing?8064. This is why it’s not found, it should be Routing. The ?8064 part is weird, do you know where it comes from?

1 Like

Oh I didn’t even spot the name mangling there. I’m not sure why it did it, but, I have one other .ts/.html combination for a login component and its also mangling the name there as well, almost as if it’s attempting to prevent duplicate names for the modules. But I managed to resolve it by changing this in the config file:

resolve:
{
    extensions: [".ts", ".js", ".html"],
    modules: ["./src", "./node_modules"]
},

to this:

resolve:
{
    extensions: [".ts", ".js"],
    modules: ["./src", "./node_modules"]
},

I don’t know why removing the html file extension fixed that but now its producing the right module names and the app is loading without error! I’m still staring at a white page instead of the login component I expected to see, but I’ll hammer away at that problem now that its actually running without errors.

Thanks for the help though jods, you’re a life saver, really appreciate the time you took to help with this!

Quick guess but extensions can be ommitted.
When you import "Router" webpack will fulfill that module with Router.js or Router.ts.

Indeed, having .html in the list means Router can be either Router.ts and Router.html which are two different module in your webpack bundle. That’s probably why Webpack adds the module id as a dedup.