vercel / next.js

The React Framework
https://nextjs.org
MIT License
124.84k stars 26.65k forks source link

How to change where Next looks for pages? #4789

Closed bing1021 closed 6 years ago

bing1021 commented 6 years ago

Every .js file in pages becomes a route, can i change it?

I want use src/pages

egorovli commented 6 years ago

AFAIK, you cannot. You can disable file system routing via next.config.js.

egorovli commented 6 years ago

According to docs, dir specifies the location of the project, so the correct way would be to set it to ./src:

const next = require('next')({
  dev,
  dir: './src'
})

But it's only used in a programmatic API (with a custom server) and will affect the presumed location of other files as well (like next.config.js and static directory, I believe).

brainkim commented 6 years ago

No idea what these other comments are saying but you can configure which directory next.js looks for pages from the command-line:

$ next ./src
$ next dev ./src
$ next build ./src
$ next start ./src -p 8080
timneutkens commented 6 years ago

You can't change the directory, and we're not planning to change this, please search for an issue on the issue tracker (including closed issues) in the future before posting an issue, as this question has come up quite a few times.

Carduelis commented 5 years ago

@timneutkens don't be like maintainer of moment.js, who rejected optimization for client-side apps, what is led to custom configs in a lot of projects, even in CRA. A lot of project boilerplates has an src folder, where files lay.

cryptiklemur commented 5 years ago

As this is currently the first result on google when searching for this, maybe it would be beneficial to explain the reasoning behind that decision @timneutkens ?

msegers commented 5 years ago

As stated by @brainkim jus append your package json scripts with ./src. What you also might want to do is configure the next dist folder (I wanted dist in root).

Note that we prepend the folder with ../.

// src/next.config.js
module.exports = {
  distDir: '../dist'
}
// package.json
  "scripts": {
    "dev": "next ./src",
    "build": "next build ./src",
    "start": "next start ./src",
    ..
  },
ivan-kleshnin commented 5 years ago

@msegers I'm trying to follow this setup and getting tons of errors like this:

Cannot find module 'next/document' Cannot find module 'next/error' ...

on HTTP request (no errors at the import phase). Any idea how to fix that?

The requirement of having pages at root really drives me nuts – for anything realistically big, things start to pile up at the root uncontrollably: styles, components, client store, config files, etc. Wish there were a workaround.

Addition: tried to symlink pages to client/pages. Most of the stuff seems working, except Hot Reload. Sad :(

folofse commented 5 years ago

@msegers Suggestion worked for me.

If you use next-i18next make sure you set the correct localePath in the NextI18 config:localePath: 'src/static/locales/',

Like this :

NextI18NextInstance = new NextI18Next({
  defaultLanguage: 'en',
  otherLanguages: ['en'],
  debug: true,
  localePath: 'src/static/locales/',
});
malimccalla commented 5 years ago

There seems to be quite an appetite for this - would love to be able to configure where my top level pages are looked for.

slaterbbx commented 5 years ago

@malimccalla You can, check out here: https://github.com/slaterbbx/fullstackinator

Caveat

You can't change the name of the folder as far as I know, needs to stay "pages"

How

Look in the client folder, notice there are a few key things needed to make this happen. The example I show is for a custom server scenario + typescript, but its basically the same thing, the core things are.

  1. In the scripts in package.json, make sure to point to the folder ( next ./client ) instead of just ( next ) for "npm run dev" / do the same for build script
  2. In that folder ( ./client ) you will need a next.config.js file. Then simply have in it the following:
    module.exports = {
    distDir: '../.next' // so that you can tell it to go up a folder for the dev and prod files.
    }

    If you have any questions, feel free to shoot me an email or here is fine too.

UPDATE: I just noticed that above @brainkim gives the exact same explanation.. Sorry, I will leave this though because the linked example shows a much more complex use case for anyone seeking such an example.

malimccalla commented 5 years ago

Thanks for this @slaterbbx

My issue is that I am trying to co-locate conceptually related code. I have the following structure

├── components
|   ├──  GridItem.tsx
|   ├──  Avatar.tsx
|   └──  Button.tsx
├── pages
|   └── profile
|       └── components
|       |   ├── CoverPhoto.tsx
|       |   └── UserInterests.tsx
|       ├── data.ts
|       ├── styles.ts
|       └── index.tsx

The issue with this approach (as pointed out by @timneutkens) is that all the files within pages are treated as webpack entry points so in turn considered for the commonchunks config. As it currently stands Next only supports top level page components within pages. If I could configure where pages are looked for I could keep this (reasonable?) structure. I imagine something like this in the config

pages: ["./pages/*/index.tsx"]

It could also be used for projects that store pages in multiple locations

pages: ["./pages/*", "./admin-pages/*"]

or projects that want to store their top level components in a folder named something differently

pages: ["./views/*"]

or projects that just want to customise the path

pages: ["./src/custom/path/to/pages/*"]

I believe this is a fair feature to have and it does not feel like a radical pattern (yarn workspaces use the same pattern to locate workspaces, a pattern Next.js itself implements).

slaterbbx commented 5 years ago

@malimccalla ah, yea, totally understand your grief, I also desire a fully flexible solution. Possibly something worth contributing an effort too, but I have read that they are not interested in offering a solution ( somewhere, but don't quote me on that ) so I fear that investing such time into such a feature could be a lost cause. Unless of course they confirm that they would be interested in such a contribution, then again, might be a project to consider undertaking 🙋‍♂️

joncursi commented 5 years ago

@malimccalla were you able to get next to play nicely with your desired project structure, or did you end up flattening out your pages directory and storing the page sub-components elsewhere?

malimccalla commented 5 years ago

@joncursi I managed to work around by renaming pages directory to views and then creating a new pages directory thats sole purpose is exporting the top level page components.

for example pages/profile.tsx now looks like this:

export { default } from "../views/profile"  

it's by no means ideal but allows me to keep my desired project structure

AmazingTurtle commented 5 years ago

@folofse changing the i18n localePath works when it comes to scanning the directory. But when resolving language files it is removing src again. What to do?

I enabled debug to provide the logs as follows (i18next)

...
  localePath: 'src/static/locales',
  localeStructure: '{{lng}}/{{ns}}',
  localeSubpaths: 'foreign',
  backend:
   { loadPath:
      'V:/dev/some-project/static/locales/{{lng}}/{{ns}}.json',
     addPath:
      'V:/dev/some-project/static/locales/{{lng}}/{{ns}}.missing.json' },
  allLanguages: [ 'de', 'de' ],

loadPath is set to *\static\locales but it should be *\src\static\locales.

armenr commented 5 years ago

Question:

We have a custom server file in /projectRoot/next-web/server.js

It mounts /projectRoop/next-renderer-universal/client like so:

// in /projectRoot/next-web/server.js
const nextApp = next({
  dev: NODE_ENV !== 'production',
  dir: APP_DIR,
  quiet: false,
});

How the heck do we actually build and ship this :)?

kachkaev commented 5 years ago

@armenr This small app of mine might help. It uses a custom entry point (src/server.ts) and here is how it calls next(): https://gitlab.com/kachkaev/website-frontend/blob/e1c7106cf63811f6341c4bd47dd2354eb2546914/src/server.ts#L11-18

Keeping all source files under PROJECT_ROOT/src (or another subdirectory) is quite challenging in Next.js. Because of the added automatic TS integration in Next 9, things even become a bit more messy 😔 I wish https://github.com/zeit/next.js/issues/4315 was reopened.

armenr commented 5 years ago

:) I set up a monorepo, so the question I was asking was compounded by other complexities

We've since figured out exactly what to do, but I appreciate the sample code. Still useful! Thank you :)

anoop-gupt commented 5 years ago

@armenr What is your workaround with regards to monorepo? I set up my project with lerna and still constrained with it.

armenr commented 5 years ago

@anoop-gupt

Lerna, monorepo, yarn workspaces, and separate packages.

I put all the front-end code into a folder I call renderer-universal. I then have a package called next-web where I keep my custom next server. I also have another package where I keep nextron (next + electron...excellent project, look them up on GitHub).

In the server.js file for nextron and next-web, I use:

const nextApp = next({
  dev: NODE_ENV !== 'production',
  dir: APP_DIR,
  quiet: false,
});

And I pass in the directory location of the renderer-universal package via ENV variables to those server files.

I also have a bunch of microservices we wrote residing in other lerna packages in the monorepo as well.

No custom webpack/babel configs or symlink resolution required.

revskill10 commented 5 years ago

Normally, i prefer this project structure:

src
  - api
  - pages
  - utils

Top level src folder is normal and many projects use it. Why not ?

anoop-gupt commented 5 years ago

@revskill10 Yesh, even I preferred that structure.

armenr commented 5 years ago

We're distributing our app & services + NextJS into both desktop/cloud hybrids as well as web builds.

Package management - node_modules duplication, the need for custom serverJS files w/ Next, and shared modules and libs between the different microservices made it hard to break everything apart or follow the conventional/simpler directory structure.

To provide an easily manageable setup for my team, I had to come up with a pattern that let us work on desktop and web versions simultaneously, and to decouple all microservices and deduplicate all shared libs & modules between them. The only real "right" way to do that was via the setup I've described.

For the average project getting started, this is overkill. In our case, we had a reasonably clear understanding of our initial requirements and what we needed to build, so I was just answering the question.

For what it's worth, we're thinking of getting rid of the custom server.js file and instead moving to the /api layout that's been implemented into Next9. Unclear, as of yet, whether this will still make it easily possible for us to develop on/build web + nextron simultaneously in a simple way.

anoop-gupt commented 5 years ago

@armenr Can I have your repository location, please? It seems a good solution.

scf4 commented 5 years ago

The distDir: '../dist', method no longer works in Next 9 with typescript and customer server. The problem is it creates a tsconfig.json in the src dir.

scf4 commented 5 years ago

Spent a couple of hours trying to solve this but had to move everything into the root dir... such a mess 😞

image
armenr commented 5 years ago

Spent a couple of hours trying to solve this but had to move everything into the root dir... such a mess 😞

image

Nothing changes if you try messing with path resolutions, or modifying the entrypoint file in your tsconfig.json?

janhesters commented 5 years ago

This has been requested since 2017. How can we help to get this feature shipped?

scf4 commented 5 years ago

@timneutkens please reopen this issue and reconsider

scf4 commented 5 years ago

@janhesters https://github.com/zeit/next.js/issues/8415

timneutkens commented 5 years ago

Replied here, going to lock this issue. https://github.com/zeit/next.js/issues/4315#issuecomment-522263598