aurelia / dialog

A dialog plugin for Aurelia.
MIT License
106 stars 115 forks source link

Dialog does not open when webpack bundle is built in production mode #361

Open shabalin opened 5 years ago

shabalin commented 5 years ago

I'm submitting a bug report

We were very excited with the news that there is no more need to PLATFORM.moduleName dialog view models, so we decided to give it a try.

https://aurelia.io/blog/2018/09/06/aurelia-release-notes-early-september-2018

Usage of Origin.get was removed; we now depend on the built-in support for class references from the CompositionEngine. What does this mean? Usage of class references for .viewModel should no longer cause issues with Webpack when PLATFORM.moduleName() is not used.

We removed all dialog VMs PLATFORM.moduleName() statements in our codebase, and were very happy to see dialogs working when we run app in webpack development mode. Unfortunately, the behavior is different in production mode. We prepared a repo based on Aurelia CLI app template that reproduces and issue.

Please tell us about your environment:

Current behavior: If i build a bundle with mode: "production" I am getting the following error on dialog opening.

aurelia-templating.js:792 Uncaught (in promise) Error: Cannot determine default view strategy for object.
    at e.getViewStrategy (aurelia-templating.js:792)
    at aurelia-templating.js:4802

in development mode dialog does open with no errors

I was able to reproduce the issue for the clean Aurelia App template (created using latest AURELIA CLI) https://github.com/shabalin/aurelia-dialog-issue-361

StrahilKazlachev commented 5 years ago

For this to work you will either need to pass the .view(moduleId or ViewStrategy) or use @view()/static $view on the view model class.

shabalin commented 5 years ago

@useView('dialog/dialog.html') on dialog ViewModel fixes the problem, I it would be great to understand how production mode affects the runtime.

StrahilKazlachev commented 5 years ago
  1. production mode is quite broad - it varies between webpack, jspm, aurelia-cli and all their configuration options.
  2. Just to be clear, I suggested using @view(), not @useView(). With @useView() you are basically specifying the moduleId of the view to use. So if you are trying to move away from the use of moduleId this will not help.
shabalin commented 5 years ago
  1. sorry for not making this clear, I referred to https://webpack.js.org/concepts/mode/#mode-production
  2. Unfortunately I wasn't able to find any documentation about @view, it's not the same as @inlineView? Could you provide me a link, please? I think we just try to make Aurelia conventions work for the production webpack build.
shabalin commented 5 years ago

Finally we figured a root cause - webpack in production mode does Module Concatenation (ModuleConcatenationPlugin enabled in production mode by default) which makes view model inlined into the class that uses it (If you refer to the same VM in multiple places it wouldn't happen). So one line in webpack config fixes the problem:

  optimization: {
    concatenateModules: false,
  },

Aurelia Webpack Plugin, we suppose, should somehow prevent inlining, like what it does when it processes Platform.moduleName'd module ref.

ggayowsky commented 3 years ago

I just stumbled across this issue a few moment ago.

The application I am working on is a mixed JS and TS. I have only noticed this problem occurring on view models which are typescript files. JS file seem to work just fine.

Hopefully, that sheds some light on this issue

bigopon commented 3 years ago

@ggayowsky can you give this comment (a the comments after it as well, there's extra example) a look https://discourse.aurelia.io/t/production-build-issue/3774/3 and see if it's somewhat matches your scenario.

An explanation in our Discord chat at https://discord.com/channels/448698263508615178/448699089513611266/755368450058092555

PLATFORM.moduleName when used with webpack will tell Webpack to remove some optimization related to the module being referenced, which will ensures the export names are not mangled to a single letter, or removed entirely when modules are concatenated. If there's no module, Aurelia cannot figure out a view module from the view model, and will result in runtime error. What you can do, if you'd like to use import is use @inlineView, or @useView, or static view via static $view = '