Possible to change a plugin's source and watch changes in the consuming application

Hi all,

My team is looking into using Aurelia plugins as the backbone for a microfrontend architecture.

We would like to be able to make changes to a local copy of the plugin while running the SPA that consumes the plugin and get live updated via the --watch flag. Is there any way we can achieve this?

So far we’ve tried creating an aurelia plugin in a folder, “project1”, then copying “project1” to “project2” and changed all the values of the “paths” object in the aurelia.json from “…/src” to “…/…/project2/src”. But I got the following error:

ERROR [PackageAnalyzer] Unable to load package metadata (package.json) of resources:
INFO [PackageAnalyzer] Error: cannot resolve npm package folder for “resources”
ERROR [Bundler] Unable to analyze resources
INFO [Bundler] Error: Unable to find package metadata (package.json) of resources
ERROR [Bundler] Failed to add Nodejs module resources
INFO [Bundler] Error: Unable to find package metadata (package.json) of resources

Has anyone tried something similar or know how to achieve this goal?

1 Like

I resolved those errors by replacing all references in aurelia.json from ../src to ../../project2/src.

However the watch command is not completely working. It detects the changes, but does not add the path to pendingRefreshPaths in watch.ts. Looks like I’ll be making some changes there.

1 Like

You can have a look at ux, we are doing similar in there. It may or maybe be applicable for your app setup though https://github.com/aurelia/ux/tree/master/app

1 Like

That was helpful, but not quite what I’m trying to get setup.

I created a repo to help demonstrate what I’m trying to do.

Essentially, I’m trying to have two projects: 1 SPA and 1 plugin. I would like to have the SPA use the plugin and watch for changes in the plugin’s src so that as the SPA gets refreshed/updated when the plugin’s source changes.

I made the following changes to try to accomplish this:

I successfully have webpack watching for changes in the plugin’s src directory and refreshing the SPA as needed, but Aurelia does not seem to be able to resolve the plugin’s Module IDs registered in aurelia-plugin/src/index.ts

I’m getting a runtime error from aurelia-loader-webpack, saying Error: "Unable to find module with ID: local-plugin/elements/hello-world"

If I change PLATFORM.moduleName('./elements/hello-world') to PLATFORM.moduleName('elements/hello-world') in aurelia-plugin/src/index.ts the error seems to go away, but I still cannot use the hello-world element. It seems to be that Aurelia is having trouble detecting what type of resource hello-world is.

So if I then go into hello-world.ts and add @customElement('hello-world'), I get another error: Error: "Cannot determine default view strategy for object.". And if I then go and add @useView('./hello-world.html') I get yet another error: @useView('./hello-world.html').

I’m probably going down the wrong path here, but have no clue where to go from here to get these modules to resolve.

1 Like

I feel you. It’s a big difficult to setup in that way, as there’s a slight difference in behavior between compile time module resolution & how aurelia loader works at runtime. That’s why I was suggesting you to have a look at the ux repo, as it was done similarly. I was able to get your setup to work, you can have a look here:

2 notes:

  • you already aliased local-plugin, so there’s no need to add localPluginDir to module resolution I think, it may mess webpack module resolution up (and I couldn’t get it to work with this)
-    modules: [srcDir, localPluginDir, 'node_modules'],
+    modules: [srcDir, 'node_modules'],
  • I think you are right about using @useView, it’s the simplest way to get things work with the comnbination of plugin/alias/webpack etc…

Can you give that a try and let me know if it works for you?

1 Like

Thank you, this worked perfectly. This also resolved my issue in Plugin skeleton with webpack with the aurelia-loader-webpack not being able to resolve relative module names!

The only caveat we have now is needing to use @useView, but that’s no real issue for us.

1 Like

There is a way to make it work without @useView as well, but I was a bit too lazy :stuck_out_tongue:

1 Like

That would be awesome. It’s always great to trim down on boilerplate. Do you think you can give me a bit of background info or point me in the right direction so I could give it a shot?

I think theres a way to fo it, though it requires more trials & errors. Thats why im saying lazy. For the direction, im not sure, but it would be similar to how we do it in ux, with rhe link i sent you above

1 Like

Ah yes, it looks I would just need to add the .html as a dependency using the ModuleDependenciesPlugin.

Alternatively I can tell webpack to register it as a dependency by calling PLATFORM.moduleName() in the configure method!

I think I’ll just write a short utility for this. Thanks again!
edit: Looks like I can’t write a utility for this because PLATFORM.moduleName()needs to have the string in there for static analysis by webpack. I’ll just have to write it out!

2 Likes

I found a way to resolve html files without hard code all of them. This answer was the reference.
So, in webpack.config.js, I changed this

-    plugins: [
-   new AureliaPlugin(),

to this

+    plugins: [
+    new AureliaPlugin({
+        viewsFor: '{,../my-plugin/src/}**/!(tslib)*.{ts,js}' 
+    }),

p.s. I got the default value from here and changed it accordingly.

1 Like

I think if you change the following, you can also get rid of all aurelia aliases in webpack.config.js too

-    modules: [srcDir, 'node_modules'],
+    modules: [srcDir, path.resolve(__dirname, 'node_modules')],
1 Like

It’s worth noting the Webpack docs for modules which say that it treats absolute and relative module paths differently.

If you pass node_modules as a string it will continue resolving up through directories using standard node resolution. If you pass an absolute path to node_modules it will not traverse up and resolve other node_modules directories.

You want the traversal to occur if you’re loading packages in local directories that also have their own node_modules directory.

1 Like