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

Separate client and server import? #2582

Closed
stevefan1999-personal opened this issue Jul 17, 2017 · 4 comments
Closed

Separate client and server import? #2582

stevefan1999-personal opened this issue Jul 17, 2017 · 4 comments

Comments

@stevefan1999-personal
Copy link

Developing a sophisticated website product with Next.js, Express and a database, I'm using REST and isomorphic fetch for my API abstraction, which is unfortunately also the bottleneck.

I can import the underlying API classes directly from my pages, but I don't want to risk my API being leaked indirectly by exploiting modules. What should I do now?

@unregistered
Copy link
Contributor

#1117 suggests alternative ways of achieving that, might help. There's also https://arunoda.me/blog/ssr-and-server-only-modules

@stevefan1999-personal
Copy link
Author

stevefan1999-personal commented Jul 27, 2017

The problem is that next build generates a pre-transpiled dist folder in .next that mimic the imported modules based on webpack, I'm importing my entire server API into a module, and I will call the method I wanted in getInitialProps in order to evade the round-tripping issue with fetch in server-side(so I wanted to use next.js like PHP I will have to admit it), if I ignores my entire server API in webpack level, then my server API modules is also not transpiled hence not copied to .next/dist and when I tried to run production server

Some examples:
pages/blog.js

import React from 'react'
import ServerApi from 'api/server'

const Blog = ({ id }) => (
  <div>{id}</div>
)

Blog.getInitialProps = () => {
  return { id: !process.browser ? ServerApi.getRandomId() : 42 }
}

export default Blog

api/server/index.js (this should not be included in the client bundle)

export default class ServerApi {
  static getRandomId() {
    return Math.random() * 1000
  }
}

After pseudo-transpliation: (still ES2015)
pages/blogs.js (for webpack bundle)

import React from 'react'

const Blog = ({ id }) => (
  <div>{id}</div>
)

Blog.getInitialProps = () => {
  return { id: 42 }
}

export default Blog

pages/blogs.js (for dist)

import React from 'react'
import ServerApi from 'api/server'

const Blog = ({ id }) => (
  <div>{id}</div>
)

Blog.getInitialProps = () => {
  return { id: ServerApi.getRandomId() }
}

export default Blog

Then I could have my production server to dehydrate getInitialProps with server API invoked directly while keeping my business logic away from malicious people.

#1117 did no help, and neither the SSR and Server Only Modules did too.

@stevefan1999-personal
Copy link
Author

I see in #1117 (comment), it seems like the philosophy of next.js is focusing on state consistency, not flexibility and isolation. Hmm, maybe isomorphic-fetch is the only way to go.

@stevefan1999-personal
Copy link
Author

stevefan1999-personal commented Jul 27, 2017

Also another point is that, yes, I couldn't preserve my API state because each page is stateless in server render. I admit what I'm trying to approach is a complete failure.

Maybe I will have to consider using global objects and only the name of my internal API will be leaked, but it's an enough workaround as the implementation in server is fully-opaque to the client-side

Edit:
✓ global objects worked out for me
Now it's the matter of dealing with memory leaks and type correction and minimizing the damage with more obfuscation to secure my API.

Edit 2:
Try to add this in your next.config.js::webpack()

webpack (config, { dev }) {
  if (!dev) {
      const defs = config.plugins.filter(p => p.constructor.name === 'DefinePlugin')[0].definitions
      defs['process.browser'] = true
  }
}

With this hack, all process.browser will be translated to true, and just let UglifyJs/Babili to do his job.

@lock lock bot locked as resolved and limited conversation to collaborators May 11, 2018
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

3 participants