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

next.js project #2

Open
SilentImp opened this issue May 27, 2019 · 11 comments
Open

next.js project #2

SilentImp opened this issue May 27, 2019 · 11 comments

Comments

@SilentImp
Copy link

Hi, I have added the plugin to next.js project.

npm install -D babel-plugin-esx-ssr

and added the plugin to .babelrc:

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "modules": false,
        "debug": false,
        "useBuiltIns": "usage",
        "targets": {
          "browsers": [">0.2%", "not dead", "not ie < 11", "not op_mini all"]
        }
      }
    ],
    "next/babel"
  ],
  "plugins": ["macros", "esx-ssr"]
}

but get this error:

> Using external babel configuration
> Location: "/path/to/Project/.babelrc"
[ error ] ./pages/_app.js
Module not found: Can't resolve 'esx' in '/path/to/Project/pages'
🚀🚀 Ready on http://localhost:3000
[ wait ]  compiling ...
[ error ] ./pages/_app.js
Module not found: Can't resolve 'esx' in '/path/to/Project/pages'

Any ideas?
With all best Regards. Anton.

@davidmarkclements
Copy link
Member

can you please put the modified repo on gh and link?

@SilentImp
Copy link
Author

I can't, sorry, it's under NDA.
I may try to create «testcase», but not sure if it will work like that.

@davidmarkclements
Copy link
Member

yeah it doesn't have to be your project, I just need a repo that reproduces the issue

@SilentImp
Copy link
Author

@davidmarkclements I have created a test case. Error is reproducible.
https://github.com/SilentImp/esx

[ error ] ./pages/index.js
Module not found: Can't resolve 'esx' in '/path/to/project/nextjs/pages'
ModuleNotFoundError: Module not found: Error: Can't resolve 'esx' in '/path/to/project/nextjs/pages'

@SilentImp
Copy link
Author

Hi, @davidmarkclements any updates?

@davidmarkclements
Copy link
Member

only just got the chance to look at it.. the main thing is, is we need to differentiate between server side and client side here. For server transpiling we need to ensure that template literals aren't transpiled. I'm pretty sure the webpack error ("can't resolve esx" is coming from webpack) would also be resolved by differentiating between client/server transpiling.

So this might not be a bug with esx, but rather something we need to define/document: how do you integrate esx with next.js.

I'm going to have to look more into this to answer that, @timneutkens @rauchg any tips would be appreciated :D

@SilentImp
Copy link
Author

So, I should use the plugin only for backend part, but exclude it from the client, right?

@davidmarkclements
Copy link
Member

davidmarkclements commented Jun 3, 2019 via email

@davidmarkclements
Copy link
Member

oh..holdup – lol - you can fix the failing server by installing esx

npm install esx

Not sure how well the optimization will go though (because of the template transpiling)

@davidmarkclements
Copy link
Member

yep so it's currently 20% slower, there's two reasons for this:

The first is that this optimization has an inverse correlation to the amount of html nodes rendered, when it's very small react is actually faster. The bigger the react app gets, the bigger the improvement on performance when esx is used. So it's possible that for this specific example it will always be slow.

The second reason is the real problem. Because next's internal babel settings force compilation of template strings (no matter how I adjust the targets option, it won't override this setting, maybe there's a way with next.config.js) we get output like the following:

function _templateObject2() {
  var data = _taggedTemplateLiteral(["\n    <main>\n      <Component value=\"text\"/>\n    </main>\n  "]);

and then esx is used like this:

var Index = function Index() {
  return esx(_templateObject2());
};

This will totally destroy the optimization – the reason it works is down to really cool characteristic of tagged template literals - the strings array is always the same object:

var x = null
const f = (strings) => { x = strings } 
const render = (somevar) => f `some thing: ${somevar}`
render()
var x2 = x
x = null
render()
console.log(x === x2) // true

So we use the strings array as a key in a WeakMap to calculated state, this way we amortize the cost of parsing. But in Babel's transpiled tagged template literals, they use a new array every time. Which will create a memory leak, and parse every single time.

It looks like some work was going on here to resolve it: babel/babel#7350 but it's either not made it in or next.js is using an older version.

Next.js doesn't allow separate client/server builds, so I'm going to have ponder a workaround

@davidmarkclements
Copy link
Member

work is on-going here: https://github.com/esxjs/next-esx

Improvements to https://github.com/esxjs/to-esx are needed in order to transpile next-server to using esx.renderToString

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants