jnotelddim
jnotelddim

Reputation: 2045

Webpack: Unable to find module with ID: main -- (Aurelia App)

TLDR: Aurelia app, bundled with webpack, can't load in browser - console shows error: can't find module with id: main. I think that means it can't find the entrypoint. Running out of things to try.


The error is:

Error: Unable to find module with ID: main

at WebpackLoader. (https://localhost:44399/dist/app.bundle.js?v=18.11.05&v=QnXnhS1zNjvTNWq1CN7QzBCr2ti1BVIVEjGB_ewbuj0:9435:35)

at step (https://localhost:44399/dist/app.bundle.js?v=18.11.05&v=QnXnhS1zNjvTNWq1CN7QzBCr2ti1BVIVEjGB_ewbuj0:9296:23)

If I'm understanding correctly (I'm not the developer who set this app up, and he's no longer around), the "main" being referenced in the error comes from the aurelia-app="main" attribute within the <body> element in wwwroot/dist/index.html :

(see bottom for directory stucture)

index.html

<html>
  <head>
    <meta charset="utf-8">
    <title>Aurelia Navigation Skeleton</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <base href="/">
    <!-- imported CSS are concatenated and added automatically -->
  </head>
  <body aurelia-app="main">

  <script type="text/javascript" src="/app.bundle.js"></script><script type="text/javascript" src="/vendor.bundle.js"></script></body>
</html>

the value "main", I believe is supposed to reference the src/main.ts:

(I've tried changing it to: main.ts, src/main.ts, src/main, ../../src/main.ts, etc -- none of them worked or even changed the error message, which makes me feel like that's not the right place to be looking.)

main.ts

// we want font-awesome to load as soon as possible to show the fa-spinner
import {Aurelia} from 'aurelia-framework'
import environment from './environment';
import {PLATFORM} from 'aurelia-pal';
import * as Bluebird from 'bluebird';

// remove if you don't want a Promise polyfill (remove also from webpack.config.js)
Bluebird.config({ warnings: { wForgottenReturn: false } });

export function configure(aurelia: Aurelia) {
    aurelia.use
        .standardConfiguration()
        .plugin(PLATFORM.moduleName('aurelia-dialog'))
    //.feature(PLATFORM.moduleName('resources/index'))
    //.plugin(PLATFORM.moduleName('aurelia-ui-virtualization')) 
    .globalResources(
        [
            //Converters
            PLATFORM.moduleName('converters/decimal-format'), 
            PLATFORM.moduleName('converters/unit-selection-format'), 
            PLATFORM.moduleName('converters/sort'), 
            PLATFORM.moduleName('converters/date-format'),

            //Custom Element Registrations
            //base-level components (standalone)
            //PLATFORM.moduleName('components/custom-elements/table-cell-text-element'),
            PLATFORM.moduleName('components/custom-elements/text-div-element'),
            PLATFORM.moduleName('components/custom-elements/icon-button-element'),
            PLATFORM.moduleName('components/custom-elements/checkbox-div-element'),
            PLATFORM.moduleName('components/custom-elements/range-selector-element'),
            PLATFORM.moduleName('components/custom-elements/unit-selector-element'),

            //mid-level components (groupings/dependent on others)
            PLATFORM.moduleName('components/custom-elements/content-header-element'),
            PLATFORM.moduleName('components/custom-elements/table-configurable-element'),
            PLATFORM.moduleName('components/custom-elements/table-tiered-element'),
            PLATFORM.moduleName('components/custom-elements/grid-selector-element'),

            //high-level components (groups of mid-level)
            PLATFORM.moduleName('components/custom-elements/grid-selector-group-element'),
            PLATFORM.moduleName('components/custom-elements/dropdown-select-element'),
            PLATFORM.moduleName('components/custom-elements/alert-element'),

            //Rate Components 
            PLATFORM.moduleName('components/custom-elements/base-charge-element'),
            PLATFORM.moduleName('components/custom-elements/tiered-rate-element'),
            PLATFORM.moduleName('components/custom-elements/tiered-per-unit-charge-element'),
            PLATFORM.moduleName('components/custom-elements/rate-component-element'),
            PLATFORM.moduleName('components/custom-elements/meter-charge-element')
        ]);


  // Uncomment the line below to enable animation.
  // aurelia.use.plugin(PLATFORM.moduleName('aurelia-animator-css'));
  // if the css animator is enabled, add swap-order="after" to all router-view elements

  // Anyone wanting to use HTMLImports to load views, will need to install the following plugin.
  // aurelia.use.plugin(PLATFORM.moduleName('aurelia-html-import-template-loader'));

  if (environment.debug) {
    aurelia.use.developmentLogging();
  }

  if (environment.testing) {
    aurelia.use.plugin(PLATFORM.moduleName('aurelia-testing'));
    }



  aurelia.start().then(() => {aurelia.setRoot(PLATFORM.moduleName('app'))});
}

which, I'm fairly sure, has nothing wrong in it - because it was working fine at the end of last week and hasn't changed since.

one noteworthy thing is that we altered the ModuleDependenciesPlugin section in our webpack.config.js. We added an entry: "aurelia-dialog": ['./aurelia-dialog', './ux-dialog-header', './ux-dialog-body', -dialog-footer', './attach-focus'] which was necessary to get the custom components from aurelia-dialog to load (see below). This change didn't break the app initially. It was working fine for about a week, I'd say?

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const project = require('./aurelia_project/aurelia.json');
const { AureliaPlugin, ModuleDependenciesPlugin } = require('aurelia-webpack-plugin');
const { ProvidePlugin } = require('webpack');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');

// config helpers:
const ensureArray = (config) => config && (Array.isArray(config) ? config : [config]) || [];
const when = (condition, config, negativeConfig) =>
  condition ? ensureArray(config) : ensureArray(negativeConfig);

// primary config:
const title = 'Aurelia Navigation Skeleton';
const outDir = path.resolve(__dirname, 'wwwroot/dist');
const srcDir = path.resolve(__dirname, 'src');
const nodeModulesDir = path.resolve(__dirname, 'node_modules');
const baseUrl = '/';

const cssRules = [
  { loader: 'css-loader' },
];

module.exports = ({production, server, extractCss, coverage, analyze} = {}) => ({
  resolve: {
    extensions: ['.ts', '.js'],
    modules: [srcDir, 'node_modules'],
  },
  entry: {
    app: ['aurelia-bootstrapper'],
    vendor: ['bluebird'],
  },
  mode: production ? 'production' : 'development',
  output: {
    path: outDir,
    publicPath: baseUrl,
    filename: production ? '[name].[chunkhash].bundle.js' : '[name].bundle.js',
    sourceMapFilename: production ? '[name].[chunkhash].bundle.map' : '[name].bundle.map',
    chunkFilename: production ? '[name].[chunkhash].chunk.js' : '[name].chunk.js'
  },
  performance: { hints: false },
  devServer: {
    contentBase: outDir,
    // serve index.html for all 404 (required for push-state)
    historyApiFallback: true
  },
  devtool: 'source-map',
  module: {
    rules: [
      // CSS required in JS/TS files should use the style-loader that auto-injects it into the website
      // only when the issuer is a .js/.ts file, so the loaders are not applied inside html templates
      {
        test: /\.css$/i,
        issuer: [{ not: [{ test: /\.html$/i }] }],
        use: extractCss ? ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: cssRules
        }) : ['style-loader', ...cssRules],
      },
      {
        test: /\.css$/i,
        issuer: [{ test: /\.html$/i }],
        // CSS required in templates cannot be extracted safely
        // because Aurelia would try to require it again in runtime
        use: cssRules
      },
      {test: /\.js\.map$/,  loader: 'ignore-loader' },
      {test: /\.ts\.orig$/,  loader: 'ignore-loader' },
      {test: /\.html\.orig$/,  loader: 'ignore-loader' },
      {test: /\.tst$/,  loader: 'ignore-loader' },
      { test: /\.html$/i, loader: 'html-loader' },
      { test: /\.tsx?$/, loader: "ts-loader" },
      //{ test: /\.json$/i, loader: 'json-loader' },
      // use Bluebird as the global Promise implementation:
      { test: /[\/\\]node_modules[\/\\]bluebird[\/\\].+\.js$/, loader: 'expose-loader?Promise' },
      // embed small images and fonts as Data Urls and larger ones as files:
      { test: /\.(png|gif|jpg|cur)$/i, loader: 'url-loader', options: { limit: 8192 } },
      { test: /\.woff2(\?v=[0-9]\.[0-9]\.[0-9])?$/i, loader: 'url-loader', options: { limit: 10000, mimetype: 'application/font-woff2' } },
      { test: /\.woff(\?v=[0-9]\.[0-9]\.[0-9])?$/i, loader: 'url-loader', options: { limit: 10000, mimetype: 'application/font-woff' } },
      // load these fonts normally, as files:
      { test: /\.(ttf|eot|svg|otf)(\?v=[0-9]\.[0-9]\.[0-9])?$/i, loader: 'file-loader' },
      ...when(coverage, {
        test: /\.[jt]s$/i, loader: 'istanbul-instrumenter-loader',
        include: srcDir, exclude: [/\.{spec,test}\.[jt]s$/i],
        enforce: 'post', options: { esModules: true },
      })
    ]
  },
    plugins: [
        //new AureliaWebpackPlugin({
        //    includeSubModules: [{
        //        moduleId: 'aurelia-dialog'
        //    },
        //    ],
        //    contextMap: {
        //        'aurelia-dialog': 'node_modules/aurelia-dialog/dist/commonjs/aurelia-dialog.js'
        //    }
        //}),
    new AureliaPlugin({includeAll: "src"}),
    new ProvidePlugin({
      'Promise': 'bluebird'
    }),
    new ModuleDependenciesPlugin({
        'aurelia-testing': ['./compile-spy', './view-spy'],
        "aurelia-dialog": ['./aurelia-dialog', './ux-dialog-header', './ux-dialog-body',
            './ux-dialog-footer', './attach-focus']
    }),
    new HtmlWebpackPlugin({
      template: 'index.ejs',
      minify: production ? {
        removeComments: true,
        collapseWhitespace: true
      } : undefined,
      metadata: {
        // available in index.ejs //
        title, server, baseUrl
      }
    }),
    ...when(extractCss, new ExtractTextPlugin({
      filename: production ? '[contenthash].css' : '[id].css',
      allChunks: true
    })),
    ...when(production, new CopyWebpackPlugin([
      { from: 'static/favicon.ico', to: 'favicon.ico' }])),
    ...when(analyze, new BundleAnalyzerPlugin())
  ]
});

package.json

{
  "name": "webui",
  "description": "An Aurelia client application.",
  "version": "0.1.0",
  "repository": {
    "type": "???",
    "url": "???"
  },
  "license": "MIT",
  "dependencies": {
    "@types/plotly.js": "^1.38.3",
    "aurelia-animator-css": "^1.0.4",
    "aurelia-bootstrapper": "^2.2.0",
    "aurelia-dialog": "^1.1.0",
    "aurelia-polyfills": "^1.3.0",
    "bluebird": "^3.5.1",
    "core-decorators": "^0.2.0",
    "lit-html": "^1.0.0"
  },
  "peerDependencies": {},
  "devDependencies": {
    "@types/bootstrap": "^4.1.2",
    "@types/jest": "^22.2.0",
    "@types/lodash": "^4.14.105",
    "@types/node": "^9.6.23",
    "@types/pikaday": "^1.6.3",
    "@types/webpack": "^4.1.1",
    "ajv": "^6.0.0",
    "aspnet-webpack": "^2.0.3",
    "aurelia-cli": "^0.35.1",
    "aurelia-loader-nodejs": "^1.0.1",
    "aurelia-pal-nodejs": "^1.0.0-beta.3.2.0",
    "aurelia-protractor-plugin": "^1.0.6",
    "aurelia-testing": "^1.0.0-beta.4.0.0",
    "aurelia-tools": "^2.0.0",
    "aurelia-webpack-plugin": "^3.0.0-rc.1",
    "clean-webpack-plugin": "^0.1.19",
    "copy-webpack-plugin": "^4.5.1",
    "core-js": "^2.5.7",
    "css-loader": "^0.28.11",
    "cypress": "^3.1.0",
    "d3": "^5.1.0",
    "del": "^3.0.0",
    "dropzone": "^5.4.0",
    "expose-loader": "^0.7.5",
    "extract-text-webpack-plugin": "^3.0.2",
    "file-loader": "^1.1.11",
    "gulp": "4.0",
    "gulp-rename": "^1.2.2",
    "gulp-util": "^3.0.8",
    "html-loader": "^0.5.5",
    "html-webpack-plugin": "^3.0.6",
    "ignore-loader": "^0.1.2",
    "intro.js": "^2.9.3",
    "istanbul-instrumenter-loader": "^3.0.0",
    "iterall": "^1.2.2",
    "jest": "^22.4.2",
    "jest-cli": "^23.0.0-alpha.0",
    "jquery": "^3.3.1",
    "jquery-sparkline": "^2.4.0",
    "json-loader": "^0.5.7",
    "minimatch": "^3.0.4",
    "nouislider": "^11.1.0",
    "nps": "^5.8.2",
    "nps-utils": "^1.5.0",
    "numeral": "^2.0.6",
    "opn": "^5.3.0",
    "pikaday": "^1.7.0",
    "plotly.js": "^1.44.2",
    "protractor": "^5.3.0",
    "style-loader": "^0.20.3",
    "through2": "^2.0.3",
    "tinymce": "^4.7.11",
    "ts-jest": "^22.4.1",
    "ts-loader": "^4.0.1",
    "ts-node": "^5.0.1",
    "typescript": "^2.7.2",
    "uglify-js": "^3.3.15",
    "url-loader": "^1.0.1",
    "vinyl-fs": "^3.0.2",
    "wait-on": "^2.1.0",
    "webpack": "^4.29.3",
    "webpack-bundle-analyzer": "latest",
    "webpack-cli": "^3.1.1",
    "webpack-dev-server": "^3.1.14",
    "webpack-hot-middleware": "^2.21.2",
    "wnumb": "^1.1.0",
    "wormhole.js": "^0.10.1"
  },
  "jest": {
    "modulePaths": [
      "<rootDir>/src",
      "<rootDir>/node_modules"
    ],
    "moduleFileExtensions": [
      "js",
      "json",
      "ts"
    ],
    "transform": {
      "^.+\\.(ts|tsx)$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
    },
    "testRegex": "\\.spec\\.(ts|js)x?$",
    "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"
    ]
  },
  "engines": {
    "node": ">= 6.0.0"
  },
  "scripts": {
    "build": "webpack",
    "start": "nps",
    "test": "nps test",
    "webpack-watch": "webpack --watch --info-verbosity verbose",
    "webpack-display-errors": "webpack --display-error-details",
    "compile": "tsc -w",
    "compile-tests": "tsc -p cypress  -w"
  },
  "main": "dist/app.bundle.js",
  "-vs-binding": {
    "ProjectOpened": [
      "compile-tests",
      "compile",
      "webpack-watch"
    ]
  }
}

aurelia.json

  "name": "WebUIFinal",
  "type": "project:application",
  "bundler": {
    "id": "webpack",
    "displayName": "Webpack"
  },
  "build": {
    "options": {
      "server": "dev",
      "extractCss": "prod",
      "coverage": false
    }
  },
  "platform": {
    "id": "aspnetcore",
    "displayName": "ASP.NET Core",
    "port": 8080,
    "hmr": false,
    "open": false,
    "output": "wwwroot/dist"
  },
  "loader": {
    "id": "none",
    "displayName": "None"
  },
  "transpiler": {
    "id": "typescript",
    "displayName": "TypeScript",
    "fileExtension": ".ts"
  },
  "markupProcessor": {
    "id": "minimum",
    "displayName": "Minimal Minification",
    "fileExtension": ".html"
  },
  "cssProcessor": {
    "id": "none",
    "displayName": "None",
    "fileExtension": ".css"
  },
  "editor": {
    "id": "none",
    "displayName": "None"
  },
  "unitTestRunner": [
    {
      "id": "jest",
      "displayName": "Jest"
    }
  ],
  "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"
  }
}

My coworker and I have both spent the past couple days on this trying to get it figured out - so any help is appreciated.

I've tried resetting all the changes (including going back to before aurelia-dialog was added), have tried changing the aurelia-app attribute's value. Cleaned & rebuilt a few times. Restarted the computed. Re-cloned the repository....


The directory structure is

WebUIFinal/
├── wwwroot/
│   └── dist/
│        ├── index.html
│        ├── 0.chunk.js
│        ├── ...
│        ├── vendor.bundle.js
│        └── app.bundle.js
├── aurelia-project/
│   └── aurelia.json
├── src/
│   ├── app.ts
│   └── main.ts
├── package.json
└── webpack.config.js
(plus a bunch of other stuff, of course -- this is just what I deemed relevant)

Upvotes: 2

Views: 2608

Answers (1)

bigopon
bigopon

Reputation: 1964

EDIT:

After a debugging session, the issue with module with ID: main not found was simply resolved by changing Webpack AureliaPlugin to its simplest form:

plugins: [
  new AureliaPlugin()
]

As the built code is in a format that Webpack can understand easily, no need for any configuration.

Also, it'd be easier for debugging. if configure function in main is wrapped in a try catch, or catch(ex =>) of promise, so you can see any issues coming up, instead of a silently fail and a forever loading screen.


With the latest release of dialog, you should not have to manually include ModuleDependenciesPlugin for dialog anymore, as it uses dynamic import API, which is understood by Webpack naturally. So I would suggest going back to your original one, and delete that configuration.

new ModuleDependenciesPlugin({
    'aurelia-testing': ['./compile-spy', './view-spy'],
    // "aurelia-dialog": ['./aurelia-dialog', './ux-dialog-header', './ux-dialog-body', './ux-dialog-footer', './attach-focus']
})

Upvotes: 3

Related Questions