Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shared App from module cannot be invoked without 'new' #8358

Closed
kinetifex opened this issue Aug 13, 2019 · 10 comments
Closed

Shared App from module cannot be invoked without 'new' #8358

kinetifex opened this issue Aug 13, 2019 · 10 comments

Comments

@kinetifex
Copy link
Contributor

Bug report

Describe the bug

We have several apps who's _app.js exports a common structure from a shared module that is a dependency of each app. This has worked well for use with previous versions of next, but is failing under v9.

To Reproduce

git clone https://github.com/kinetifex/next-9-app-bug.git
cd ./next-9-app-bug
npm i
npm run build

This will fail with:

# TypeError: Class constructor App cannot be invoked without 'new'

Expected behavior

The app should build fine.

To see this working correctly with next@8.1.0, in the same example project:

git checkout works-with-8
npm i
npm run build

System information

  • OS: macOS
    - Browser (if applies) [e.g. chrome, safari]
  • Version of Next.js: 9.0.3

Additional context

I see other issues reporting App cannot be invoked without 'new', but under a different context to what we are experiencing.

@thundermiracle
Copy link
Contributor

Maybe this will help.
#8201 (comment)

@kinetifex
Copy link
Contributor Author

kinetifex commented Aug 14, 2019

@thundermiracle hmm I'm not really understanding that explanation. Seems like that would imply any modules that I import in _app.js would require some extra webpack config to get picked up, which is not the case.

For example, if I instead import a component from a shared module, that works fine:

import React from 'react';
import App, { Container } from 'next/app';
+ import { MyComponent } from 'shared-helpers'

class MyApp extends App {
  render() {
    const { Component, pageProps } = this.props;

    return (
      <Container>
+        <MyComponent />
        <Component {...pageProps} />
      </Container>
    )
  }
}

export default MyApp;

It is only an issue for App classes and looks like also Document from your issue.
Did you get your's fixed then? Do you have an example of the webpack config?

@Timer
Copy link
Member

Timer commented Aug 14, 2019

A custom App component must be compiled different for the server and client.

On the server, you need to emit ES6 Class syntax! Then the client needs to be transformed with the identical preset as your application code.

This entails making your custom .babelrc for the shared app retain ES6 Class syntax:

{
  "presets": [
    [
      "next/babel",
      {
        "preset-env": {
          "modules": "commonjs",
          "exclude": ["transform-classes"]
        }
      }
    ]
  ]
}

You'll also need to mark shared-helpers as non-external and include them in your babel compilation, similar to next-transpile-modules.

@Timer Timer closed this as completed Aug 14, 2019
@Timer
Copy link
Member

Timer commented Aug 14, 2019

☝️ by the way, once it's marked non-external you can stop compiling to the commonjs modules since it'll be bundled by webpack.

@kinetifex
Copy link
Contributor Author

kinetifex commented Aug 14, 2019

@Timer Thanks, adding "exclude": ["transform-classes"] to the shared moduled fixed this without needing to update webpack externals. Though I'm curious why only ES6 class syntax is required by the next server? What has changed that does not allow the previous approach?

@thundermiracle
Copy link
Contributor

I'm curious of what has changed makes the approach different too.

@indexzero
Copy link

My guess is that this is related to the TypeScript migration, but I'm not 100% positive about that.

@timneutkens
Copy link
Member

timneutkens commented Aug 15, 2019

It's related to our publishing process, we now publish default pages as "modern" code that is later compiled down to the version needed. This reduced bundle sizes for _app etc by quite a bit.

@indexzero
Copy link

💯

Was fortunate to have @Timer give me the heads up yesterday.

I, for one, welcome an IE11-free browser support matrix 😅

@balazsorban44
Copy link
Member

This issue has been automatically locked due to no recent activity. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@vercel vercel locked as resolved and limited conversation to collaborators Jan 30, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants