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

Add pagesDir config option #4315

Closed
1 task done
vladnicula opened this issue May 9, 2018 · 32 comments
Closed
1 task done

Add pagesDir config option #4315

vladnicula opened this issue May 9, 2018 · 32 comments

Comments

@vladnicula
Copy link
Contributor

Relating to #875, willing to try a PR if offered guidance.

We're building a ecommerce store from scratch with next and are close to finishing the initial architecture. The only thing bugging us is the number of folders we ended up with. The src folder would be a major improvement in our structure and the way we thought it could be done is by adding a property called pagesDir in the next.config.js configuration.

With this new options set to something like:

{
   "pagesDir": './src/pages'
}

we could keep all the source code in src, including the pages.

  • I have searched the issues of this repository and believe that this is not a duplicate.

Expected Behavior

Added description at the top of the page

Current Behavior

Pages cannot be placed within a sub folder.

Steps to Reproduce (for bugs)

Context

Your Environment

Tech Version
next 6.0.0
node 6.x
OS N/A
browser N/A
etc
@brad-decker
Copy link

@vladnicula if your goal is to have everything that is webpacked/babeled and part of next be in the /src folder you can just move your pages directory into src and change your path for next to /src. We actually went one step further and moved our next configuration into a specific folder and our "userland" source code into src. all that exists in our "next" folder is /pages and next.config.js.

we modified next.config.js to tell it to work its magic on the src folder.

module.exports = {
  webpack: (config, { dev, defaultLoaders }) => {
    config.module.rules.push({
      test: /\.+(js)$/,
      loader: defaultLoaders.babel,
      include: path.resolve(__dirname, '../src'),
    });
    return config;
  }
};

@joao-alberto
Copy link

@vladnicula take a look #819 (comment)

@ghost
Copy link

ghost commented May 10, 2018

@brad-decker we did something like this with next

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

but the issue here that .next folder which is built by next will stay in same folder with src
We are looking for a solution like put all code in src folder but .next folder is in the root

@joao-alberto your solution can be apply with next but not with the custom server

@vladnicula
Copy link
Contributor Author

@joao-alberto thanks for the share. I actually did try to follow the steps from the ticket. The issue with that is that with a custom server we could not get the config to properly load and find the pages folder in development mode.

So, the suggestion from #819 (comment) does not work in dev mode when using a custom server.

We could come up with an isolate example to showcase the limitation if it would help this discussion.

@vladnicula
Copy link
Contributor Author

@brad-decker thanks for sharing that configuration nugget. I gave it a try and it seems that the dev mode was not able to find any of the pages under pages/src. I tried telling our server to render either:

return app.render(req, res, '/')

or

return app.render(req, res, '/src')

But it seems it did not want to.

Attempting to bundle in production via yarn build also failed, so there might be more to it than you are sharing with us :).

I liked the idea anyway.

@brad-decker
Copy link

Our app structure:

/
|__next/
|   |__pages/
|        |__index.js //<- just imports stuff from src and exports it as default for next to pick it up as a page
|   |__next.config.js
|__src/
    |__components/
    |__pages/
        |__home.js // <- our actual code

initialize app using the next folder const app = next({ dev, dir: `${__dirname}/next` });

add the blip from my previous comment to tell webpack to compile and bundle your /src folder

@brad-decker
Copy link

also our .next folder gets added to the /next folder so our build stuff goes in next/.next which is so obviously next level

@DullReferenceException
Copy link

Any thoughts on this somewhat alternative approach?

#4406

The main purpose of that PR is to add support for multiple pages directories, but it could also be used to embed files under a different root. Sample next.config.js file:

module.exports = {
  rootPaths: ['./src']
}

@timneutkens
Copy link
Member

timneutkens commented Dec 31, 2018

We are not planning to allow changing the pages directory.

However a solution for #4406 should be explored. Let's track that in #3027

amercier added a commit to amercier/gilded-rose-visitor that referenced this issue Jan 6, 2019
amercier added a commit to amercier/gilded-rose-visitor that referenced this issue Jan 6, 2019
amercier added a commit to amercier/gilded-rose-visitor that referenced this issue Jan 6, 2019
amercier added a commit to amercier/gilded-rose-visitor that referenced this issue Jan 6, 2019
amercier added a commit to amercier/gilded-rose-visitor that referenced this issue Jan 6, 2019
amercier added a commit to amercier/gilded-rose-visitor that referenced this issue Jan 6, 2019
amercier added a commit to amercier/gilded-rose-visitor that referenced this issue Jan 6, 2019
amercier added a commit to amercier/gilded-rose-visitor that referenced this issue Jan 6, 2019
amercier added a commit to amercier/gilded-rose-visitor that referenced this issue Jan 6, 2019
amercier added a commit to amercier/gilded-rose-visitor that referenced this issue Jan 6, 2019
amercier added a commit to amercier/gilded-rose-visitor that referenced this issue Jan 6, 2019
amercier added a commit to amercier/gilded-rose-visitor that referenced this issue Jan 6, 2019
amercier added a commit to amercier/gilded-rose-visitor that referenced this issue Jan 6, 2019
@kachkaev
Copy link
Contributor

kachkaev commented Jul 17, 2019

Could this issue be looked at again please? 🙏

I used to keep all my Next.js app sources inside src in order to ease search and replace within the project. It was a bit painful to set up a custom server so that all directories were configured adequately, but it still felt worth it. In version 9, with tsconfig.json and next-env.d.ts created automatically in the Next.js dir instead of the repo root, things are getting even messier and I'm leaning towards coming back to keeping Next.js root dir the same as the repos's root dir 🤔

The fact that I'll have to have pages next to src rather inside src, makes me quite sad. Now, instead of limiting my search and replace scope in VSCode to [project]/src, I'll need to search the whole project, but then remember to exclude a bunch of directories like .next, build, coverage and so on in order to get adequate results. The blacklist varies from project to project, which builds up into a prettly long and ugly comma-separated string.

Unlike CRA, which is zero-config in principle, Next.js has quite a few options, including a bunch of experimental ones. It feels like swapping the hard-coded pages dir with something more dynamic would not be too harmful overall. What is a blocker?

Relevant concerns, which were recently raised: #7798, #7782


Partially the reason why I'm asking is because our company looks into moving a few apps from bespoke webpack-dev-server configs into Next.js. Not being able to configure pagesDir will essentially result in two src folders in each project, which will sometimes require reconfiguring linting tools as well as explaining the new project structure to the devs.

@gc
Copy link

gc commented Jul 24, 2019

Pretty surprised this is not possible, and its a put-off/downside as I'm investigating migrating my CRA app to next.js.

@Timer
Copy link
Member

Timer commented Jul 24, 2019

@gc CRA doesn't allow these types of settings to be adjusted, so the experience should be familiar. 😄

e.g. you cannot customize the src/ folder

@kachkaev
Copy link
Contributor

[in CRA] you cannot customize src/ folder

Which is great, because it means that the entry point src/index.js can be in the same subfolder as all the rest of the app code. In Next.js though the situation is very different: you cannot have a single project subfolder where all source is stored; the theoretical minimum is two (e.g. pages and src). This makes project-wide search pretty complicated. Seem details in my comment above 🙂

@Timer
Copy link
Member

Timer commented Jul 24, 2019

@kachkaev I'm well aware 😄. The above response was specifically directed at @gc, not this issue as a whole.

There's many benefits to have an application rooted within src, which is different than customizing the pages directory.
This effect can be seen in Create React App by not allowing you to import files outside of src.

We'll be drawing up a proposal soon that allows users to opt-into this rooting behavior.

@gc
Copy link

gc commented Jul 24, 2019

@Timer I was referring to not being able to have all the source in src/, this is the way I structure all my projects, for obvious reasons it's neater and more manageable. I'd rather not have to look through my many dotfiles, lock/log files, etc to find source code. I'm aware CRA (and next) are restricting things as you say, but if I'm understanding correctly, next.js is hardcoded to check only the root for /pages, so I cannot include it in my src.

If I've misunderstood anything I apologize, I've only just started using next in the last few hours. @kachkaev has pretty well described my feelings too.

I'm glad to hear about the proposal, I'm guessing it will let us specify a directory in our next.config? Like pagesDir: "./src/pages".

@Timer
Copy link
Member

Timer commented Jul 24, 2019

The proposal would look more like applicationRoot: './src'.

@treyhuffine
Copy link

Very excited to see this being considered. Trying to build any kind of complex application with now and next using serverless functions is painful when being forced to have pages in the root.

@timneutkens
Copy link
Member

Just to be clear I'm strongly against any config value for this, we've seen tons of misusage of config values like these (looking at distDir for example). The thing I'm willing to consider is adding src/pages support, where you choose either root level pages directory or src/pages, as apparently this covers the majority use-case of why people are asking for this feature.

@janhesters
Copy link

@timneutkens

The thing I'm willing to consider is adding src/pages support, where you choose either root level pages directory or src/pages, as apparently this covers the majority use-case of why people are asking for this feature.

This would already be a huge improvement 🙏🏻 Please make src/pages happen 😊

@kachkaev
Copy link
Contributor

kachkaev commented Aug 18, 2019

If there is no intent to make pagesDir fully customizable, how about checking both pages and src/pages on startup and picking the existing folder as pagesDir? Next can crash or warn with a meaningful message if both folders are present to avoid misuse. Problem solved, no options added.

@timneutkens
Copy link
Member

@kachkaev that's exactly what I outlined 😄

@chengsokdara

This comment has been minimized.

@timneutkens
Copy link
Member

Posted #8451

@armenr
Copy link

armenr commented Aug 22, 2019

YES YES HELL YES FINALLY YES!

Thanks folks :)

@Tenshock
Copy link

I dont understand your choice @timneutkens

You are strongly against any config value but you want to let the user have the choice between pages or src/pages. A well documented option would be perfect to avoid misusage of config value as you described. I like to think users are smart enough to read the doc and understand how the framework works. Please let the users freely pick whatever folder they want to store his pages.

The majority of the people are happy with only the possibility to put the pages folder inside the src but what about different folder structures? Per example a folder structure that tends to implement common software architectures like clean architecture or another?

Your choice to support either /pages or src/pages is almost an answer, a compromise. You want to fulfil users needs but it seems like you have some fears about letting the user be free to organise his folders.

I think the framework should be agnostic of each user project and folder structures. I think the choice to freeze the project structure breaks a common software engineering principle.

The framework realise assumptions about the project structure. It breaks the Single Responsibility Principle in object oriented programming. Or, if you prefer, one of Linux principles that suggests that a software does one thing well, but only one thing. The aim of NextJS is to server-side render React. Not to suggests how the user has to organise his project.

I would be happy to deeply understand why you don't want to leave the choice to the user. I read many threads about this discussion but I still don't understand. The framework will only be more powerful as it will be more adaptable.

@timneutkens
Copy link
Member

The framework realise assumptions about the project structure. It breaks the Single Responsibility Principle in object oriented programming. Or, if you prefer, one of Linux principles that suggests that a software does one thing well, but only one thing. The aim of NextJS is to server-side render React. Not to suggests how the user has to organise his project.

The premise is convention over configuration.

Next.js is not a library, it does more than a single thing by design. It's a collection of:

  • Libraries (next/head etc)
  • CLIs (next dev, next build, next start)

The Next.js CLI is a compiler/bundler, but not a conventional one, as it compiles much more than the general compiler. A basic compiler takes input -> transforms -> output where input is one piece of code and output is one piece of code. Next.js on the other hand handles more: input multiple files -> transforms -> full renderable app with server and client bundles.

Hence why Next.js is a framework and not a library that does a single thing.

The aim of NextJS is to server-side render React.

This is a wrong assumption. As said earlier the main goal for Next.js is to have the right defaults for building websites / web applications and giving flexibility between tradeoffs (eg static, ssr, etc) while putting you / your team into the pit of success.

Your choice to support either /pages or src/pages is almost an answer, a compromise. You want to fulfil users needs but it seems like you have some fears about letting the user be free to organise his folders.

There are tradeoffs and impact in adding new features, the (negative) impact of allowing setting the pages directory does not outweigh the arguments for allowing it, we've seen this before with distDir, there's a whole category of issues that came out of allowing it and are still breaking between upgrades quite often.

So yes, we're careful in adding new features, because we want you to not get stuck on a certain version and we want to guarantee that they'll continue working in the future.

The best example of this is probably that almost all features outlined in Next.js 1 are still fully compatible with Next.js 9.

I would be happy to deeply understand why you don't want to leave the choice to the user

Besides what I've written above there is this reply: #8451 (comment)

@vladnicula
Copy link
Contributor Author

vladnicula commented Sep 1, 2019

As said earlier the main goal for Next.js is to have the right defaults for building websites / web applications and giving flexibility between tradeoffs (eg static, ssr, etc) while putting you / your team into the pit of success.

Well then, you're assumptions about this particular issue is off compared to many people who voiced their opinions.

In the end it's you and the team that needs to support this, so whatever works for you best should be the way to go forward. I wouldn't want to maintain a large codebase that does not follow my ideals.

I hope you also understand that this kind of decisions are strongly polarizing. For my case, nextjs falls down from a tool that I really like to use to a tool I just pick when I want to get something done really fast, without much certainty of customization or long term support.

@timneutkens
Copy link
Member

timneutkens commented Sep 1, 2019

Well then, you're assumptions about this particular issue is off compared to many people who voiced their opinions.

This comment captures part of why we shouldn't allow it: #8451 (comment)

It's hard to argue that anyone:

  • Never wants to upgrade without issues
  • Doesn't want things to work expectedly

Maybe you're building short term projects, but there are thousands of actively worked on projects using Next.js. This ranges from the 6th largest website of the internet (by Alexa rank) to personal websites.

I wouldn't want to maintain a large codebase that does not follow my ideals.

Note that I wouldn't use src/pages personally, yet I did write up a RFC to allow it and all the semantics required to implement.

The discussion about introducing config options has many sides. For example in a similar fashion some asked "I want to change all chunking logic", eg how Next.js decides commons etc. instead we ended up implementing #7631 and now soon all users will profit from this.
Whereas if we had introduced the option it would have been more likely to end up in userland with close to no usage.

Furthermore it increases the surface of what users have to learn to be able to start getting productive. For example nextjs.org/learn is part of many companies' onboarding process.

@Strandedpirate

This comment has been minimized.

@andormade
Copy link

If you found this, while looking for a solution, there is now a fork that allows you to set a custom pages directory, you can find a link in this discussion post: #23640

@arosemena
Copy link

Another situation where this would be desirable would be when you're targeting environments where no SSR is available, like native apps with something like capacitor, if you want to have both SSR for the browser and client side loaded content you have to do some really dirty hacks around moving the pages directory which could all be solved if we just had a build time option to select where to take the pages from, please reconsider.

@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 28, 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