Need help migrating from JSPM to Webpack

UPDATE: babel issues solved and webpack is behaving well. However, I am still having Aurelia complain about not being able to find modules:

in ./wwwroot/main.js Module not found: Error: Can't resolve '/aurelia-app/shared/loading-indicator' in 'D:\Source\GitHub\aurelia-razor-netcore2-skeleton\Aurelia.Skeleton.NetCore.Razor\wwwroot'

That module is specified as a global resource, as follows:

.globalResources([
    PLATFORM.moduleName('/aurelia-app/shared/loading-indicator')
]);

Worked fine in JSPM. How do I solve for Webpack?

Try removing leading slash.

PLATFORM.moduleName('aurelia-app/shared/loading-indicator')

If that doesn’t work, use relative path.

PLATFORM.moduleName('./aurelia-app/shared/loading-indicator')

Thanks for the response. The relative path gives the exact same error, but the first one (remove leading slash) seems to work. However, that has caused a new error as follows:

Error: Template markup must be wrapped in a <template> element e.g. <template> <!-- markup here --> </template>

  • It doesn’t specify which view this is for
  • I can’t find anywhere in my code that doesn’t have markup wrapped in a <template> element
  • This issue did not happen with JSPM

Is it possible that it’s trying to load html from one of the npm packages or something?

Did you turn on developmentLogging? The log should tell you what it tries to load before the error.

Yes, I have development logging enabled. The output is as follows:

As you can see, it breaks at app.js, which is a file webpack created from this config:

return [{
    target: "web",
    mode: isDevBuild ? "development" : "production",
    entry: {
        app: ['aurelia-bootstrapper'], // <-- here
        vendor: ['bluebird', 'jquery', 'bootstrap'],
    },
    // etc...

Hope you can help.

If you would like to debug the issue by seeing it, you can get the feature/webpack branch of my small project here: https://github.com/gordon-matt/aurelia-razor-netcore2-skeleton/tree/feature/webpack

Sorry, I don’t use webpack.

But I guess you can print log for your dynamically loaded route PLATFORM.moduleName(item.moduleId),. It looks like one of item.moduleId's template file.

Sorry, I’m not sure what you mean about printing log for the dynamically loaded route. Also, are you sure that you are looking at the correct app.js? Because there are 2 of them… 1 is the Aurelia app.js where I load the dynamic routes (./aurelia-app/app.js) and the other one is a file created by webpack (./dist/app.js)

Right, nvm, I was looking at aurelia-app/app.js.

@gordon-matt I’m not sure you will be able to achieve what you want (template html generated by asp.net) with webpack… html templates need to be in the bundle - this is where aurelia loader looks for them. Yours don’t exist when you bundle, only at runtime. It worked with jspm but won’t with webpack. I’m afraid you’ll have to code them in good old html files near your view models.

Also, PLATFORM.moduleName(item.moduleId) will not work - you need strings as parameters, not variables.

Regardless, I have to say, it is a very non-traditional architecture and hard to navigate too.

1 Like

If dynamic modules are absolute must in your project you have the following options

  • stay on jspm
  • tell webpack to split your code into separate bundles (this can be done with the second parameter to moduleName function). But you’ll still need hard html files
  • migrate to require

Thanks for your response. Yes, dynamic modules are an absolute must in my real application. I need to move away from JSPM because although it’s very easy to use, it’s unfortunately far too slow. I didn’t realize RequireJS was an option for Aurelia. I used RequireJS before in an older project of mine which uses Durandal in pretty much the same way I am attempting to use Aurelia. I’ve just made the repo public a few days ago, so if you’re interested, you can see it here: https://github.com/gordon-matt/KoreCMS. Anyway, can I assume setting up RequireJS in Aurelia will be very similar to doing so with Durandal? Do you have a link to any good skeleton projects or tutorials using that option?

What you really need to do is install the latest CLI and try generating new projects with webpack and requires. Then try dynamic modules in both and then decide how to migrate your app.

How dynamic you want them to be? Are they plugins or just a way to reduce the traffic?

If the latter then webpack is a better choice. Otherwise, only requirejs, plus you won’t be able to use the transpiler as you did with jspm because of decorators and browser compatibility.

@MaximBalaganskiy I’ve just discovered the Aurelia CLI and already did generate a new project using RequireJS. I am attempting to integrate what I see there into my test project, but I’m getting a real headache trying to do so… for example, I’ve swapped out systemJS for requireJS in the markup like so:

<script src="~/vendor/requirejs/require.js" data-main="/vendor/aurelia-bootstrapper/dist/aurelia-bootstrapper"></script>

It seems to try starting up (I see my loading screen, btu then it throws an error as follows:

import declarations may only appear at top level of a module

It seems to be an issue with ES6 syntax I guess, but not sure why because I also copied the babel config from the Aurelia CLI generated template…

This is making me crazy and on top of it, I’m getting the flu… gonna be a bad weekend LOL. I’ll have to give it another try when I’m feeling better in a few days. In the meantime, if anyone has a good guide for me, or could fork the master branch of my code and swap out JSPM for RequireJS, that would be really nice. I understand if you’re too busy though. Thanks in any case for all the advice given so far.

@gordon-matt you didn’t reply to my question :slight_smile: how dynamic you want your modules to be? It’s hard to advise not knowing the details.

Very dynamic. You can see my framework/CMS that I linked to above which uses Durandal… I am basically moving that old project from MVC5 and Durandal to .NET Core and Aurelia… it’s a very complex project with ability to add plugins, etc… so yeah; I won’t know all the JS files and views beforehand… so, very, very, very dynamic :slight_smile:

By the way, I’ll be making the .NET Core version open source as well… so we will have an open source framework/CMS written in .NET Core using Aurelia for the admin area… :slight_smile:

I’m experimenting with dynamic modules in CLI+require… bear with me

OK, I’ve created a proof of concept which does what you need, but it’s not gonna be easy.
Just swapping JSPM with requireJS will not work. Here is what I would do

  • au new to generate a fresh project with requireJS and Typescript (optional :slight_smile: )
  • learn how to configure cli bundling
  • include only core elements and modules to your app bundle

At this point you will have a working app which won’t be able to load anything.
Next

  • create another project (it can be just a duplicate of the one you created above)
  • add a dynamic module to it and configure CLI to bundle its template and view module to a separate bundle
  • build the project and copy the generated dynamic module bundle to the first project
  • CRITICAL BIT: add the following code to the index.html, which will add your bundle to the requirejs
    <script>
  requirejs.config({
    "paths": {
      "home-bundle": "../scripts/home-bundle"
    },
    "bundles": {
      "home-bundle": [
        "home"
      ]
    }
  })
    </script>

Repeating steps 4-7 you can build bundles which can be added to the core app.
Everything above means that you just can’t use Razor for the templates.

As an easier option, stay with JSPM and transpile to ES5 on build, not with JSPM itself. This will improve performance significantly. It’ll still be a bit slower but not drammaticaly.

This is just a rough technique, the whole task is massive - let users create new modules, bundle them on a server and save to scripts folder, on navigation add requirejs config script to the DOM and only then perform navigation.

Thanks everyone for your suggestions. I’ve decided that the first thing to do is to attempt JSPM bundling. I have opened a new help request for this: JSPM Bundling throws error: `(SystemJS) System.registry is undefined`