Skip to content

Commit

Permalink
[PFX-637] Support create App Router (#777)
Browse files Browse the repository at this point in the history
* feat: added app router prompt to next plugin

* tests: next plugin

* chore: fix linting errors in next plugin

* chore: reuse index page

* chore: update readme

* chore: removed lang attr on html tag

* chore: added default nextServer outside of approuter prompt
  • Loading branch information
jpina1-godaddy authored Jun 10, 2024
1 parent ddcc16a commit 9b056be
Show file tree
Hide file tree
Showing 18 changed files with 110 additions and 31 deletions.
8 changes: 0 additions & 8 deletions packages/gasket-plugin-cypress/generator/test/e2e/index.cy.js

This file was deleted.

2 changes: 2 additions & 0 deletions packages/gasket-plugin-nextjs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# `@gasket/plugin-nextjs`

- Added useAppRouter optional flag ([#777])
- Fix logic for `server.js` generation to include `customServer` ([#778])
- Update generated `_document.js` ([#778])
- Added redux optional flag ([#762])
Expand Down Expand Up @@ -285,4 +286,5 @@
[#736]: https://github.com/godaddy/gasket/pull/736
[#750]: https://github.com/godaddy/gasket/pull/750
[#762]: https://github.com/godaddy/gasket/pull/762
[#777]: https://github.com/godaddy/gasket/pull/777
[#778]: https://github.com/godaddy/gasket/pull/778
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react';
import PropTypes from 'prop-types';

export default function RootLayout({ children }) {
return (
<html lang='en'>
<body>{children}</body>
</html>
);
}

RootLayout.propTypes = {
children: PropTypes.node
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import IndexPage from '../components/index-page';

export const metadata = {
title: 'Home',
description: 'A basic gasket app',
charset: 'UTF-8'
};

export default IndexPage
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import IndexPage from '../components/index-page';

export default IndexPage;
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
/* eslint-disable no-unused-vars */
import React from 'react';
{{#unless useAppRouter}}
import Head from '../components/head';
{{/unless}}
import GasketEmblem from '@gasket/assets/react/gasket-emblem';

const pageStyle = { textAlign: 'center' };
const logoStyle = { width: '250px', height: '250px' };

export const IndexPage = () => (
<div style={ pageStyle }>
{{#unless useAppRouter}}
<Head title='Home'/>
{{/unless}}
<GasketEmblem style={ logoStyle }/>
<h1>Welcome to Gasket!</h1>
<p>To get started, edit <code>pages/index.js</code> and save to reload.</p>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { IndexPage } from '../pages/index';
import { IndexPage } from '../components/index-page';
import { expect } from '@jest/globals';

describe('IndexPage', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { describe, it } from 'mocha';
import { expect } from 'chai';
import React from 'react';

import { IndexPage } from '../../pages/index';
import { IndexPage } from '../../components/index-page';
import messages from '../../public/locales/en-US.json';

//
Expand Down
17 changes: 11 additions & 6 deletions packages/gasket-plugin-nextjs/lib/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@ const { name, version, devDependencies } = require('../package.json');
* @property {Files} files - The Gasket Files API.
* @property {generatorDir} - The directory of the generator.
*/
function createAppFiles({ files, generatorDir }) {
function createAppFiles({ files, generatorDir, useAppRouter }) {
files.add(
`${generatorDir}/app/.*`,
`${generatorDir}/app/*`,
`${generatorDir}/app/**/*`
`${generatorDir}/app/shared/**/*`
);

const appStructure = useAppRouter ? 'app-router' : 'pages-router';

files.add(
`${generatorDir}/app/${appStructure}/**/*`
);
}

Expand Down Expand Up @@ -169,11 +173,12 @@ module.exports = {
nextServerType,
nextDevProxy,
typescript,
useRedux
useRedux,
useAppRouter
} = context;
const generatorDir = `${__dirname}/../generator`;

createAppFiles({ files, generatorDir });
createAppFiles({ files, generatorDir, useAppRouter });
createTestFiles({ files, generatorDir, testPlugins });
createNextFiles({ files, generatorDir, nextDevProxy, typescript, nextServerType });
addDependencies({ pkg });
Expand Down
1 change: 1 addition & 0 deletions packages/gasket-plugin-nextjs/lib/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ declare module 'create-gasket-app' {
nextDevProxy: boolean;
typescript: boolean;
useRedux: boolean;
useAppRouter: boolean;
}
}

Expand Down
20 changes: 19 additions & 1 deletion packages/gasket-plugin-nextjs/lib/prompt.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,26 @@
/** @type {import('@gasket/core').HookHandler<'prompt'>} */
module.exports = async function promptHook(gasket, context, { prompt }) {
const newContext = { ...context };

if (!('useAppRouter' in context)) {
const { useAppRouter } = await prompt([
{
name: 'useAppRouter',
message: 'Do you want to use the App Router? (experimental)',
type: 'confirm',
default: false
}
]);

newContext.useAppRouter = useAppRouter;
}

if (newContext.useAppRouter) {
newContext.nextServerType = 'defaultServer';
}

// TODO - evaluate if these prompts should be moved to the preset
if (!('nextServerType' in context)) {
if (!('nextServerType' in context) && !newContext.useAppRouter) {
const { nextServerType } = await prompt([
{
name: 'nextServerType',
Expand Down
3 changes: 2 additions & 1 deletion packages/gasket-plugin-nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@
},
"eslintIgnore": [
"generator/redux/redux/store.js",
"generator/app/pages/_app.js",
"generator/app/pages-router/pages/_app.js",
"generator/app/shared/components/index-page.js",
"*.d.ts"
],
"babel": {
Expand Down
31 changes: 25 additions & 6 deletions packages/gasket-plugin-nextjs/test/create.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,33 @@ describe('create hook', () => {
expect(plugin.hooks.create.timing.after).toEqual(['@gasket/plugin-redux']);
});

it('adds the appropriate globs', async function () {
it('adds the appropriate globs for pages router', async function () {
await plugin.hooks.create.handler({}, mockContext);

expect(mockContext.files.add).toHaveBeenCalledWith(
`${root}/../generator/app/.*`,
`${root}/../generator/app/*`,
`${root}/../generator/app/**/*`
);
const first = mockContext.files.add.mock.calls[0];
const second = mockContext.files.add.mock.calls[1];

expect(first).toEqual([
`${root}/../generator/app/shared/**/*`
]);
expect(second).toEqual([
`${root}/../generator/app/pages-router/**/*`
]);
});

it('adds the appropriate globs for app router', async function () {
mockContext.useAppRouter = true;
await plugin.hooks.create.handler({}, mockContext);

const first = mockContext.files.add.mock.calls[0];
const second = mockContext.files.add.mock.calls[1];

expect(first).toEqual([
`${root}/../generator/app/shared/**/*`
]);
expect(second).toEqual([
`${root}/../generator/app/app-router/**/*`
]);
});

it('adds the appropriate globs for mocha', async function () {
Expand Down
25 changes: 18 additions & 7 deletions packages/gasket-plugin-nextjs/test/prompt.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ describe('prompt hook', () => {
beforeEach(() => {
gasket = {};
context = {};
mockAnswers = { addSitemap: true, nextServerType: 'next-cli' };
mockAnswers = { useAppRouter: false, addSitemap: true, nextServerType: 'next-cli' };
prompt = jest.fn().mockImplementation(() => mockAnswers);
});

Expand All @@ -19,12 +19,16 @@ describe('prompt hook', () => {
await promptHook(gasket, context, { prompt });
const first = prompt.mock.calls[0][0][0];
const second = prompt.mock.calls[1][0][0];
expect(first.name).toEqual('nextServerType');
expect(first.message).toEqual('Which server type would you like to use?');
expect(first.type).toEqual('list');
expect(second.name).toEqual('addSitemap');
expect(second.message).toEqual('Do you want to add a sitemap?');
expect(second.type).toEqual('confirm');
const third = prompt.mock.calls[2][0][0];
expect(first.name).toEqual('useAppRouter');
expect(first.message).toEqual('Do you want to use the App Router? (experimental)');
expect(first.type).toEqual('confirm');
expect(second.name).toEqual('nextServerType');
expect(second.message).toEqual('Which server type would you like to use?');
expect(second.type).toEqual('list');
expect(third.name).toEqual('addSitemap');
expect(third.message).toEqual('Do you want to add a sitemap?');
expect(third.type).toEqual('confirm');
});

it('sets nextServerType to next-cli', async () => {
Expand All @@ -49,9 +53,16 @@ describe('prompt hook', () => {
expect(result.addSitemap).toEqual(false);
});

it('sets useAppRouter to true', async () => {
mockAnswers = { useAppRouter: true };
const result = await promptHook(gasket, context, { prompt });
expect(result.useAppRouter).toEqual(true);
});

it('does not run prompt if prompts are in context', async () => {
context.addSitemap = false;
context.nextServerType = false;
context.useAppRouter = false;
const result = await promptHook(gasket, context, { prompt });
expect(result).toHaveProperty('addSitemap', false);
expect(prompt).not.toHaveBeenCalled();
Expand Down

0 comments on commit 9b056be

Please sign in to comment.