Polymer / tools

Polymer Tools Monorepo
BSD 3-Clause "New" or "Revised" License
430 stars 200 forks source link

App shell failed to load when the build is bundled #3318

Closed tekreme73 closed 5 years ago

tekreme73 commented 5 years ago

Description

When building the app with a bundled build, I got the following error:

Uncaught TypeError: (0 , _mpApp.html) is not a function

This variable seems to be an instance of my app shell. When I inspect the generated code, the _mpApp variable is an empty Object/is not initialized.

Problematic variable

problematic variable

Where the error is thrown

where the error is thrown

I tried to remove paper-tooltip to give it a try but it does the same thing with another element. Its just not initialized.

Versions & Environment

polymer-cli: 1.9.3 node: v10.9.0 npm:: 6.5.0 OS: Windows 10

Steps to Reproduce

$ polymer build
$ polymer serve build/es5-bundled/

Build configuration

$ cat polymer.json

{
  "entrypoint": "index.html",
  "shell": "src/mp-app.js",
  "fragments":  [
    "src/routes/mp-home.js",
    ...
  ],
  "builds": [
    {
      "preset": "es5-bundled",
      "name": "es5-unbundled",
      "bundle": false
    },
    {
      "preset": "es5-bundled"
    }
  ],
  "sources": [
    "src/**/*",
    ...
  ],
  "extraDependencies": [
    "node_modules/@webcomponents/webcomponentsjs/**",
    ...
  ],
  "moduleResolution": "node",
  "npm": true,
  "lint": {
    "rules": ["polymer-3"]
  }
}

Expected result

To have a working es5-bundled build to serve the app from IE11 and others. It was working with the same configuration when my app was built with Polymer2.

Actual result

es5-bundled build is not working in any brower.

es5-unbundled is working in Chrome, Firefox, Edge and IE11.

keanulee commented 5 years ago

Tried but couldn't repro this with a similar setup in pwa-starter-kit. Do you see something like _exports.html= in the built mp-app.js? Can you try using the following polymer.json build config instead of the preset?

    {
      "name": "es5-bundled",
      "js": {
        "compile": "es5",
        "minify": true,
        "transformModulesToAmd": true
      },
      "css": {
        "minify": true
      },
      "html": {
        "minify": true
      },
      "bundle": true,
      "addServiceWorker": true
    }
tekreme73 commented 5 years ago

The _export.html thing exists in my mp-app.js generated file when I use the preset es5-bundled:

[...]=_exports.html$3=_exports.html$2=_exports.html$4=_exports.html$1=_exports.html=html=[...]=void 0; _exports.html$3=_exports.html$2=_exports.html$4=_exports.html$1=_exports.html=html;

And nothing changed when I use your build config. I have done many try with different build configurations and nothing changed.


I have managed to find what is the issue.

In my app, I load all the routes/pages dynamically using dynamic import. Except for 'home', I eager load it. Like the following:

home_import_for_eager_loading page_import dynamic_import

This was working with Polymer2. But it's this configuration that make the error Uncaught TypeError: (0 , _mpApp.html) is not a function with Polymer3.


I tried to remove this eager load and everything is working fine now. The build es5-bundled is working.

I removed the static import of home route at the top and change imports to the following:

page_import_without_eager_loading dynamic_import_without_eager_loading

So this build configuration is working when there is no eager load.

    {
      "preset": "es5-bundled"
    }

By importing everything dynamically, it solves my problem but I can't do eager loading anymore.

I think it's an issue to look at from the analyzer or the bundler.

Or do you have an example of how you manage to do eager loading?

keanulee commented 5 years ago

Don't see a reason why eager-loading one particular route wouldn't work; we do that for shop-home.js in Polymer/Shop. I also tried doing the same thing to my-view1.js in polymer-starter-kit and it works.

Looking at the screenshots in your original post, I see there's a screenshot for mp-home.js. If mp-home.js is statically imported and bundled, then there shouldn't be a built version of it (since its contents would be in mp-app.js). Are you sure there isn't an import('./routes/mp-home.js') statement somewhere in the project? (I don't know what the behavior is when you statically and dynamically import the same file.)

tekreme73 commented 5 years ago

I will give it a try.

It may also be an issue if a "fragment" is defined in the polymer.json file for the mp-home, isn't it?

keanulee commented 5 years ago

Oh yes, defining it as a fragment has the same effect as import().

With ES modules now, you don't have to define "fragments" anymore since they're automatically created for each import() statement.

tekreme73 commented 5 years ago

Ok, I have removed "fragments" from polymer.json and redo the eager loading for my homepage and its working nicely.

I just find the documentation saying that "fragments" are not required when dynamic import is done. It may be an issue from the upgrade guide from Polymer 2 to Polymer 3(?). There is no information about this "fragment" change.

But yeah, thanks a lot for your help! 🥇