Hacker News new | past | comments | ask | show | jobs | submit login
Next.js 3.0 Preview: Static Exports and Dynamic Imports (zeit.co)
126 points by Rauchg on May 15, 2017 | hide | past | favorite | 50 comments



I used Next.js to build http://user-agent.io/ over a weekend and I'm really happy with the results so far. Dynamic url routing is a bit awkward, but not onerously so. (It also uses Express to handle WebSockets and dynamic routing for the share/host pages.)

Source is at https://github.com/nfriedly/user-agent.io if anyone is interested.

I'm thinking about switching some of my work projects over to it sometime soon.


Just a heads up you're using the development version of React which is very very slow. You'd want to switch to the production version, not sure how that works in next but you generally build your React with NODE_ENV set to `production` for this to happen.


Hum, that's interesting. I do have NODE_ENV=production set. I'll have to see if Next.js needs something additional.

Although, with server-side rendering (which is part of what I really like about Next.js), the impact should be reduced somewhat.


Update: with some serious help from Arunoda, I've learned that it was due to the react-google-ad component I was using bundling it's own copy of react. So, while the rest of the site was using production-mode React, that one component wasn't and that was enough to trigger the warning in the Chrome extension.

I sent a pull request to fix it: https://github.com/lukehansell/react-google-ad/pull/5


I'm afraid it won't reduce the impact, your server takes the initial load of rendering instead of the browser, and the browser takes over for each re-render.

Not sure how Next.js does it but you should probably try putting NODE_ENV=production in the "build" script in package.json like in "start"?

I had a quick glance over Next.js's docs and it looks like they should handle this automatically just by `next build`. ¯\_(ツ)_/¯


That's a good thought with the build script, but I tried it locally and it didn't seem to make a difference.


"Very very slow" might be a bit of an overstatement. The initial React render for that page takes 200ms on a MacBook. A release build will speed that up slightly, and cut down the bundle a little, but in the scheme of things it's not going to be noticeable to the end user.

If you actually wanted the page to feel fast you would probably do something like <script>document.write(window.navigator.userAgent)</script>


Possibility of 3x-5x perf impact according to Dan Abramov. https://github.com/facebook/react/issues/2608#issuecomment-2...

I did not expect to argue in HN of all places whether it's OK or not to run the development mode of a library in production when it's so simple not to and the authors are trying so hard to prevent people from doing that.


LOL, that's prettymuch what the previous version of the site did. The new one is fancy partially to learn some new things, and partially to enable the host/share feature.


200ms on your high end laptop is what on a mid-range mobile phone? Probably 5-6 seconds, users will notice that.


On GitHub, it seems like the javascript sources behind your pages is throwing their syntax highlighting off. Seems like when you embed HTML it hiccups. Any idea how one would fix this?


Oh, hah, it's getting bit by lone single quotes, (AKA apostrophes). I think it's something GitHub would have to fix, although perhaps a .jsx extension would help.

Update: Yep, GitHub highlights correctly with a .jsx extension - see https://github.com/nfriedly/user-agent.io/blob/jsx-test/page... - but then Next.js can't "see" the page :(

So, I'm going to have to stick with .js for now.


I evaluated Next.js recently, and while it looks excellent on the surface, there were a couple of red flags:

- Devs insisting (incorrectly) that they _have_ to ship the component source code _inline_ in the server-rendered HTML. I commented on this issue here: https://github.com/zeit/next.js/issues/427#issuecomment-2908...

- The same transpiled code is used both server-side and client-side. Code which should be strictly server-only, e.g. getInitialProps(), is visible client-side as well.


I can only comment about `getInitialProps()`. Of course it's should be on client-side as well, that's the whole point of universal rendering. In combination with isomorphic-fetch you can use your (Rest) API and have nothing to change on the code. I think it's an excellent design decision to makes components actually independent and easily composable.


You are right about that, I admit.

Still, using the same transpiled code both client-side and server-side is suboptimal at least. E.g. if I target Node 7.x on the server, I don't need to transpile async functions for example (and screw stacktraces in the process).


Also, I might still want to do some things differently server-side in getInitialProps(), despite most of the code being shared. For example, clients might access the API through a load-balanced frontend, while on the server I might want to prefer talking to an API process on the same machine. Authentication might also be different. Of course these things (e.g. the API endpoint) shouldn't be hardcoded, but even then you need to get them somewhere, most likely a configuration file or an environment variable. And sharing these details (names of environment variables for example) with the client is not something I particularly like.


Instead of fetch, I'm using feathersjs that layers over axios and socketio.


A bit off topic but since it's mentioned in the article: how does the unlimited free static hosting compare with netlify's offering?


I'm in the market for a good React Universal boilerplate and am considering Next.js for my next project...

A couple of things:

1) Why do you not use React Router? How does your own router play with Redux?

2) Is it possible to strip out now.sh? I appreciate it's how you make money but I want to deploy to my own infrastructure.


It's more of a framework than a boilerplate solution, but highly recommend checking it out!

To answer your questions:

1) Because the router in next.js embeds really well into the model of pages, prefetching, etc. while still keeping the mechanisms simple, here's how to use with redux: https://github.com/zeit/next.js/tree/master/examples/with-re... 2) now.sh is in no way mandatory. To deploy anywhere, `next build` and `next start` will run the node.js server, so you're free to deploy it anywhere you'd like: https://github.com/zeit/next.js#production-deployment


1. We have plenty of examples with interoperation with Redux. Check out the `./examples` folder :)

We currently use global state at https://zeit.co to keep the authenticated user in memory without re-checking for every page transition.

You can think of Next.js's Router as a "strict subset" of RR. Definitely possible for us to simplify our codebase by switching to RR in the future.

2. Nothing about this framework is dependent on now.sh. We, however, did design now.sh to make deployment of applications as this as easy, fast and scalable as possible with collaboration in mind.


I tried to do a project with next.js but their router was just too awkward and limiting. Unless you're doing straight 1:1 route to code, you're basically on your own.

https://github.com/zeit/next.js#custom-server-and-routing


That's the opposite of what that page is trying to explain. We'll take a look at the wording in case it's confusing.

tl;DR: You can do any sort of routing! We use a /:org/:project scheme similar to GitHub at https://zeit.co :)

Some examples:

- https://github.com/zeit/next.js/tree/master/examples/paramet...

- https://github.com/zeit/next.js/tree/master/examples/with-ne...

- https://github.com/zeit/next.js/tree/master/examples/with-pr...


The named routes example is probably pretty close to what I was looking for. Oh well, maybe next time.


Does next-routes work in a static build?


Is http://mern.io/ still cool? What problems did it have that made people look for something else?


2. You can deploy it anywhere! :)


I'm very impressed by the quality of the Next.js framework and how lightweight it is. Glad to see it move forward!


I am wondering why server-side rendering? I thought that stage was passed and everyone was doing client-side stuff? Please forgive a web n00b for asking.


You can get a faster initial load going with SSR since you're basically skipping a round trip. The really smart SSR's like Redfin's react-server (https://github.com/redfin/react-server) give you faster "above the fold" rendering too.

Also, while Google can deal with them, a lot of crawlers don't understand SPA's. So if someone links to you from Facebook for example, their auto content loading doesn't work.


I really like a static website command, NextJS impresses me every time.


can anyone compare with meteor please?


1. Embraces React exclusively[1]. We at ZEIT think the React Component model is the de-facto component model of the web and mobile.

In practical terms, this means that every "page" or "entry point" to your app is just an exported component `function` or `class`. `export default () => <p>My component!</p>`.

At the expense of a storm of HN downvotes, it's "more PHP than Meteor" :)

2. No data layer built in, syncing, Models, etc. We added an extra lifecycle hook called `getInitialProps` (think of it as the counterpart to `getInitialState`) whose contract is returning data as a `Promise`.

This allows you to combine and compose different approaches to data retrieval. It works just as well with REST as it does with GraphQL or Socket.IO or server-sent-events or offline-only or…

3. It hides configuration details but allows you to tap into them.

It's powered by `Babel` and `webpack`, which are exposed as a single command (`next` and `next build`), but you can completely override and customize them.

These are just some ideas. We created it to power the team collaboration aspects of our Web UI (https://zeit.co). We are committed to supporting it because we use it and we love it.

[1] Also React alternatives like Inferno and Preact (https://github.com/zeit/next.js/tree/master/examples/using-p...)


> more PHP than Meteor

That made me laugh. But, really, it's true. Adding a new page is as simple as adding a new file. No importing, routing, etc. required. That's one thing that I think PHP got right.


Just curious: is Typescript supported out of the box?


To answer my own question to those that stumble upon this via google or whatever. It doesn't appear to be. However this example was pretty helpful (as of 20170518):

https://github.com/zeit/next.js/tree/d08e027a8c1d9bfe773a8b3...


As it previously said it's two different projects. Meteor is a full stack framework where it does everything from data to rendering.

But Next.js is not like this. It's only for the UI (rendering) You can build server rendered React apps pretty easily. It supports dynamic imports, prefetching, preloading and you name it.

Now you can export any Next.js app into a static app too.

Recently, Meteor adds some new JS features into it's build setup too.


Meteor is (to my understanding) an all-in-one framework with database access and realtime stuff built in.

Next.js is sort of a React project bootstrap/boilerplate that has some pre-selected configuration for things like styling components and server side rendering.


Next.js is not a boilerplate. It's kind a mini framework comes with it's own simple Router.

Basically it makes building client side apps faster and fun. Check this for more info: https://learnnextjs.com/


Next and Meteor are two separate types of projects.


How does Next.js' static export feature compare to using Gatsby.js?


Interesting concept, but it seems rather heavy. Installing it from npm pulls in over 400 packages, weighing in at about 60MB.


Try installing non-dev dependencies.. That's where a lot of your weight comes from, which is not in production.


So, I just did "npm install next react react-dom" which isn't bringing in next's development dependencies. Is there something that I'm missing?


    npm install next react react-dom --production


That gets me the exact same thing. And afaik what you get from --production is the default behavior when you install a package directly from npm.


What's the contents of your $HOME/.npmrc file? Because it shouldn't be unless you have `production = true` set.


> dynamic import

Umm... you mean like AMD? Yeah, it's awesome (edit I mean, was a solved problem years ago). Somebody explain to me how people live without this.


AMD was a handy workaround, but better solutions exist now.

For one thing, each and every little module doesn't need to be written with knowledge of AMD or how it's going to be imported at all. If you used AMD with this component example, every single component you write would need to be wrapped in a `define()`. This has no wrapping, just standard JS exports.

Secondly, each module doesn't need to know its own name (to pass to the `define()` call), or even have a static name at all, it can effectively be anonymous & truly dynamic.

And finally, AMD modules make assumptions about the environment – for example, that you have control over `window.define`. If you're a third-party script trying to load things on someone else's website, good luck – you either just told someone else's module handler that you loaded, and have no visibility into it, or you clobbered the existing `window.define` and broke other people's scripts. (My former company's product was a third-party JS widget, and co-existing with dozens of other scripts and module loaders was a huge problem.)


These are all valid points... but I'm curious what you mean by "better solutions exist now." Basically everybody's agreed to use a transpiler for the foreseeable future [0]. How is that not a workaround?

[0] This is my first time to see that any browser has actually shipped ES6 modules: http://caniuse.com/#feat=es6-module




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: