2.1.10 • Published 5 years ago

generator-nextjs-typescript-antd v2.1.10

Weekly downloads
6
License
MIT
Repository
github
Last release
5 years ago

A scaffolder for ReactJS using NextJS, TypeScript & Ant Design

This yeoman generator will build different React components, creating a skeleton for the different files.

Requirements

This is a Yeoman generator. You need to install Yeoman, NodeJS and npm to install the generator and its dependencies. Make sure you have all installed globally.

First, download and install NodeJS and npm. More information about NodeJS / npm: https://nodejs.org/

Second, install Yeoman. More information about Yeoman: http://yeoman.io/

Installation

# install yo
$ npm install -g yo

# install a generator
$ npm install -g generator-nextjs-typescript-antd

Usage

$ yo nextjs-typescript-antd

Table of Contents

Questions? Feedback?

Check out Next.js FAQ & docs or let us know your feedback.

Folder Structure

After creating an app, it should look something like:

my-app/
  api/
    postsApi.js
  components/
    global/
    commentItem/
      index.tsx
      styles.scss
    commentList/       
      index.tsx
      styles.scss
    customNProgress/
      index.tsx
      styles.scss
    layout/
      index.tsx
      styles.scss
    postItem/
      index.tsx
      styles.scss
    postList/
      index.tsx
      styles.scss
  config/
    custom-environment-variables.js
    default.js
    development.js
    production.js
    testing.js
  constants/
    index.ts
  lib/
    withI18next.js
    config.shim.js
  models/
    comment.d.ts
    post.d.ts
    index.d.ts
    loadable.d.ts
    dispatchable.d.ts
  pages/
    about/
      index.tsx
      styles.scss
    index/
      index.tsx
      styles.scss
    post/
      index.tsx
      styles.scss
    posts/
      index.tsx
      styles.scss
    _app.js
    _document.js
  redux/
    posts/
      actions.ts
      constants.ts
      payloads.ts
      sagas.ts
      selectors.ts
      state.ts
    createStore.ts    
    rootReducer.ts    
    rootSaga.ts  
    storeState.ts
  static/
    favicon.ico
    locales/
        en/
    images/
  styles/
    vendors/
    _mixins.scss
    _variables.scss
    antd-custom.less
    main.scss
  tests/
    units/
        components/
        jest.config.js
        pages/
        setup/
            index.js
            assetsTransformer.js
  typings/
    react-redux.d.ts
  .babelrc
  .eslintignore
  .eslintrc
  .gitignore
  .prettierrc
  README.md
  i18n.js
  .babelrc
  next.config.js
  package.json

Available Scripts

npm run dev

Runs the app in the development mode. Open http://localhost:3000 to view it in the browser.

The page will reload if you make edits. You will also see any errors in the console.

npm run build

Builds the app for production to the .next folder. It correctly bundles React in production mode and optimizes the build for the best performance.

npm run start

Starts the application in production mode. The application should be compiled with next build first.

See the section in Next docs about deployment for more information.

npm run export

Then you have a static version of your app in the out directory.

You can also customize the output directory. For that run next export -h for the help.

Now you can deploy the out directory to any static hosting service.

Available Generators

yo nextjs-typescript-antd

It will prompt you for the details of your new project nextjs-typescript-antd project

$ yo nextjs-typescript-antd
Initializing...
? Your project name rect-next-project
? Your project display name React Next Project
? What's your full name User Name
? What's your email address username@email.com
   create package.json
   create .babelrc
   create .eslintignore
   create .eslintrc
   create .gitattributes
   create .gitignore
   create .prettierrc
   ...

yo nextjs-typescript-antd:page

It will prompt you for the name and the title of your new page.

$ yo nextjs-typescript-antd:page --force
? Page name User
? Page title User Details
? Would you like to create a store for this page? Yes
? Store name User
   create pages\user\index.tsx
   create pages\user\styles.scss
   create static\locales\en\user.json
   create tests\units\pages\user.test.js
    force components\global\layout\index.tsx
    force server.js
   create redux\user\actions.ts
   create redux\user\constants.ts
   create redux\user\payloads.ts
   create redux\user\reducer.ts
   create redux\user\sagas.ts
   create redux\user\selectors.ts
   create redux\user\state.ts
    force redux\rootReducer.ts
    force redux\rootSaga.ts
    force redux\storeState.ts

Sometimes you might want to have your page nested within another page. To achieve this, all you need to do is:

$ yo nextjs-typescript-antd:page --force
? Page name forgot password
? Page title Forgot password
? Is this a nested page? Yes
? Select the parent page
  about
> account
  index
  people
  post
  posts
(Move up and down to reveal more choices)

then after selecting account as the parent page, yourforgot password will be generated within the account folder. (Please note that you would have created the account page earlier). Below is the final output:

$ yo nextjs-typescript-antd:page --force
? Page name forgot password
? Page title Forgot password
? Is this a nested page? Yes
? Select the parent page account
? Would you like to create a store for this page? No
   create pages\account\forgot-password\index.tsx
   create pages\account\forgot-password\styles.scss
   create static\locales\en\pages\account\forgot-password.json
   create tests\units\pages\account\forgot-password.test.js
    force components\global\layout\index.tsx
    force server.js

Note how the page has been named forgot-password even though you would have entered forgot password. The same would have been the case even if you had entered something like Forgot Password, forgotPassword or ForgotPassword

You can choose that a the redux store be created when you create a page. To achieve this, just answer y to the question Would you like to create a store for this page?. And the output would be something like below:

$ yo nextjs-typescript-antd:page --force
? Page name Forgot Password
? Page title Forgot password
? Is this a nested page? Yes
? Select the parent page account
? Would you like to create a store for this page? Yes
? Store name (ForgotPassword)

Notice how the default Store name is ForgotPassword. The same would have been the case even if you had entered something like forgot Password, forgotPassword or forgot-password for the name of the page . And the final output will be something like

$ yo nextjs-typescript-antd:page --force
? Page name Forgot Password
? Page title Forgot password
? Is this a nested page? Yes
? Select the parent page account
? Would you like to create a store for this page? Yes
? Store name ForgotPassword
    force pages\account\forgot-password\index.tsx
    force pages\account\forgot-password\styles.scss
    force static\locales\en\pages\account\forgot-password.json
    force tests\units\pages\account\forgot-password.test.js
    force components\global\layout\index.tsx
    force server.js
   create redux-store\forgotPassword\actions.ts
   create redux-store\forgotPassword\constants.ts
   create redux-store\forgotPassword\reducer.ts
   create redux-store\forgotPassword\sagas.ts
   create redux-store\forgotPassword\selectors.ts
   create redux-store\forgotPassword\state.ts
    force redux-store\rootReducer.ts
    force redux-store\rootSaga.ts
    force redux-store\storeState.ts

yo nextjs-typescript-antd:component

It will prompt you the name for your new component.

$ yo nextjs-typescript-antd:component --force
? Component name UserDetails
? Is this a page-specific component? Yes
? Page name User
   create components\global\pages\user\userDetails\index.tsx
   create components\global\userDetails\styles.scss
   create static\locales\en\userDetails.json
   create tests\units\components\userDetails.test.js

Just as you can nest pages, you can also choose that your components be specific to pages which are nested. Below is the code sample:

$ yo nextjs-typescript-antd:component --force
? Component name user avatar
? Is this a page-specific component? Yes
? Page name
  about
  account
> account/forgot-password
  index
  people
(Move up and down to reveal more choices)

And the final output:

$ yo nextjs-typescript-antd:component --force
? Component name user avatar
? Is this a page-specific component? Yes
? Page name account/forgot-password
   create components\pages\account\forgot-password\userAvatar\index.tsx
   create components\pages\account\forgot-password\userAvatar\styles.scss
    force static\locales\en\userAvatar.json
    force tests\units\components\userAvatar.test.js
    force components\index.ts

Note that for the component name we entered user avatar and we got userAvatar. This is because all the component files should be camelCased and the component names should be PascalCased. Below is the generated component:

import  React, {FC} from  'react';
import  './styles.scss';

interface  IProps {};

export  const  UserAvatar:  FC<IProps> = () => (
    <div  className="user-avatar">
        UserAvatar component
    </div>
);

export  default  UserAvatar;

And the components\index.ts file looks something like

export { default  as  CommentItem } from  './global/commentItem';
export { default  as  CommentList } from  './global/commentList';
export { default  as  CustomNProgress } from  './global/customNProgress';
export { default  as  Layout } from  './global/layout';
export { default  as  PostItem } from  './global/postItem';
export { default  as  PostList } from  './global/postList';
export { default  as  CustomErrorBoundary } from  './global/customErrorBoundary';
export { default  as  UserAvatar } from  './pages/account/forgot-password/userAvatar';
/* new-component-import-goes-here */

This will allow you to import the UserAvatar component from anywhere in the project like below

...
import { UserAvatar } from 'components';
...

This is possible because of the configuration in the .babelrc file.

...
"module-resolver",
  {
    "root": ["./"],
    "alias": {
      "api": "./api",
      "components": "./components",
      "constants": "./constants",
      "redux-store": "./redux-store"
    }
  }
...

yo nextjs-typescript-antd:store

It will prompt you the name for your new store.

$ $ yo nextjs-typescript-antd:store --force
? Store name People
   create redux-store\people\actions.ts
   create redux-store\people\constants.ts
   create redux-store\people\reducer.ts
   create redux-store\people\sagas.ts
   create redux-store\people\selectors.ts
   create redux-store\people\state.ts
    force redux-store\rootReducer.ts
    force redux-store\rootSaga.ts
    force redux-store\storeState.ts

As you can see, there were 6 new files which were created. Let's have a look at each and explain what's happening in those.

state.ts

export  type  PeopleErrable  =
    |  '__errable__'  // Remove this. It's just a placeholder
    /* new-errable-goes-here */; 

export  type  PeopleBooleanable  =
    |  '__booleanable__'  // Remove this. It's just a placeholder
    /* new-booleanable-goes-here */;  

export  type  PeopleSuccessible  =
    |  '__successible__'  // Remove this. It's just a placeholder
    /* new-successible-goes-here */;  

export  interface  IPeopleState { 
    //#region Doables
    readonly errable?: { [key  in  PeopleErrable]?:  string };
    readonly booleanable?: { [key  in  PeopleBooleanable]?:  boolean };
    readonly successible?: { [key  in  PeopleSuccessible]?:  string };
    //#endregion
}

As you can see, we have 3 types, namely PeopleErrable, PeopleBooleanable & PeopleSuccessible and they are initialized with default values which the comments state that they should be removed as soon as you start creating your own.

The reason I introduced these 3 type in a newly-created store is to allow the user to define the state for all the actions that are fullfillable and by this, I simply mean the situation where an action can be dispatched and we wait for it finish (by either succeeding or failing). If we use fetching users as an example, we would normally have three properties in the state: isFetchUsersInProgress: boolean, fetchUsersError: string and (sometimes fetchUserSuccess: string - which, for the purpose of this example, would be a string like "Successfully fetched the user!".

This approach seem to work properly, except for when you have to create a selector to read them. You would have something like selectisFetchUsersInProgress, fetchUserErrorMessage and, finally, fetchUserSuccess. This creates a problem because for every fullfilable action, that would mean you would need a new selector.

Another problem is when you need an action to set each of those. The old approach means you would need 3 actions, namely: setisFetchUsersInProgress, setFetchUserErrorMessage and fetchUserSuccess. That's not cool! So, to avoid having to do this, I just thought I could get away with these doable types and define, in them, what can be doable. This allows me to create just one selector that allows me to select anything that can be booleanable, such as isFetchUsersInProgress, isUpdateUserInProgress, isSigningOutInProgress, showDeleteModal, etc. with just one selector like the one below

export  const  selectPeopleBooleanableState  = (key:  PeopleBooleanable  |  PeopleBooleanable[]) =>

createSelector(
    peopleState(),
    ({ booleanable }) => (Array.isArray(key) ?  !!key.filter(k  =>          booleanable[k]).length  :  booleanable[key])
);

As you can see, I can simply do something like

const mapStateToProps = createStructuredSelector({
    isFetchUsersInProgress= selectPeopleBooleanableState('isFetchUsersInProgress')
    isUpdateUserInProgress= selectPeopleBooleanableState('isUpdateUserInProgress')
    isSigningOutInProgress= selectPeopleBooleanableState('isSigningOutInProgress')
    showDeleteModal= selectPeopleBooleanableState('showDeleteModal')
});

// Or the one that returns true if any of the above is true, like
const mapStateToProps = createStructuredSelector({
    showloader= selectPeopleBooleanableState(['isFetchUsersInProgress', 'isUpdateUserInProgress', 'isSigningOutInProgress'])
})

Please be sure to remove the default doables like __errable__, __booleanable__ & __successible__ once you have added your own.

Another example of creating an action that can set either of them, is in the redux-store\people\actions.ts

export  const  togglePeopleErrableState  =  createAction<IPeopleState, { [key  in  PeopleErrable]?:  string }>(
    TOGGLE_PEOPLE_ERRABLE_STATE,
    key  => ({
        errable: key,
    })
);

This allows you to what is shown below. (This assumes you have errable states such as fetcUserErrorMsg, updateUserErrorMsg, signInErrorMsg, etc.

dispatch(togglePeopleErrableState({ fetcUserErrorMsg: '' )); 
dispatch(togglePeopleErrableState({ updateUserErrorMsg: 'Could not update the user!' ));
dispatch(togglePeopleErrableState({ signInErrorMsg: '' ));

// Or even
dispatch(togglePeopleErrableState({ 
    fetcUserErrorMsg: '',
    updateUserErrorMsg: 'Could not update the user!',
    signInErrorMsg: '' 
})); 

All with just one action.

constants.ts

export  const  DEFAULT_ACTION  =  'DEFAULT_ACTION';

  

//#region Reset doable for this state
export  const  RESET_PEOPLE_DOABLES  =  'RESET_PEOPLE_DOABLES';
export  const  TOGGLE_PEOPLE_BOOLEANABLE_STATE  =  'TOGGLE_PEOPLE_BOOLEANABLE_STATE';
export  const  TOGGLE_PEOPLE_ERRABLE_STATE  =  'TOGGLE_PEOPLE_ERRABLE_STATE';
export  const  TOGGLE_PEOPLE_SUCCESSIBLE_STATE  =  'TOGGLE_PEOPLE_SUCCESSIBLE_STATE';
//#endregion

/* new-constant-export-goes-here */

This contains the constants to set the doables and reset them. Please do not remove the line that says /* new-constant-export-goes-here */ as that is where the generated code will seat.

reducer.ts

import {
    DEFAULT_ACTION,
    RESET_PEOPLE_DOABLES,
    /* new-constant-import-goes-here */
} from  './constants';
  
import { IPeopleState } from  './state';
import { reducerPayloadDoableHelper } from  'redux-store/rootReducer';
  
const  initialState:  IPeopleState  = {
    errable: {},
    booleanable: {},
    successible: {},
};
 
export  default (
state: IPeopleState  =  initialState,
{ type, payload: incomingPayload }: ReduxActions.Action<IPeopleState>
) => {
const  payload  =
    type  ===  RESET_PEOPLE_DOABLES
    ?  incomingPayload
    : (reducerPayloadDoableHelper(state, incomingPayload) as  IPeopleState);

switch (type) {
    /* new-constant-cases-go-here */
    case  DEFAULT_ACTION:
        return {
            ...state,
            ...payload,
        }
    default:
        return  state;
    }
};

Inside the reducer, the first line ensures that if the action being performed is RESET_PEOPLE_DOABLES, we make make use of ./rootReducer/reducerPayloadDoableHelper which ensures that the current errable, successible and boolean are not overridden by the incoming values. A good example of when that can be the case is if our current state has something like this:

{
    booleanable: {
        isFetchUsersInProgress: true,
        isUpdateUserInProgress: false,
    }
}

if we were to togglePeopleBooleanableState like below

dispatch(togglePeopleBooleanableState({
    isSigningOutInProgress: false, showDeleteModal: false
}));

this would have resulted in a new state being

{
    booleanable: {
        isSigningOutInProgress: false,
        showDeleteModal: false,
    }
}

but what we are looking for is

{
    booleanable: {
        isFetchUsersInProgress: true,
        isUpdateUserInProgress: false,
        isSigningOutInProgress: false,
        showDeleteModal: false,
    }
}

but the reducerPayloadDoableHelper function solves that problem.

I will skipsagas.ts file.

selectors.ts

This is initialized with 3 selectors that are used to select the errable, successible or booleanable states of a given sub-state. and they are, in the case of People state, selectPeopleBooleanableState, selectPeopleErrableState and selectPeopleSuccessibleState. All these will be generated for you when you use the :store subgenerator.

yo nextjs-typescript-antd:action

It will prompt you the name for your new action.

Below is an example of creating a action. The first question you are asked is t select the name of the state under which the action will be created. In our case, that will be a People state.

$ $ yo nextjs-typescript-antd:action --force
? Action name jump
? Select the store (Use arrow keys)
> People 
  Posts 

In case you are wondering, the list of states is contained in the .yo-rc.json file and it's updated each time you use a generator to generate a state. Currently, it looks like below

{
  "generator-nextjs-typescript-antd": {
    "pages": [
      ...
    ],
    "stores": [
      "Posts",
      "People"
    ]
  }
}

As you can see, there are two stores in our project.

After that, you are asked if your action will can be fullfillable or not. An example of such can be one that triggers an API call, such as fetchUsers because an API can return either success or error in which case you might want to react to that by dispatching a success (fetchUsersSuccess) an error (fetchUsersError) action.

$ yo nextjs-typescript-antd:action --force
? Action name fetchUsers
? Select the store People
? Is it fullfillable? (Does it have SUCCESS & ERROR?) Yes
    force redux-store\people\constants.ts
    force redux-store\people\reducer.ts
    force redux-store\people\actions.ts
    force redux-store\people\state.ts
    force redux-store\people\sagas.ts

As you can see 5 files were updated. Let's see how they were all affected.

// redux-store\people\constants.ts
  
...
//#region FETCH_USERS-related constants
export  const  FETCH_USERS  =  'FETCH_USERS';
export  const  FETCH_USERS_SUCCESS  =  'FETCH_USERS_SUCCESS';
export  const  FETCH_USERS_ERROR  =  'FETCH_USERS_ERROR';
//#endregion
...
// redux-store\people\actions.ts
  
...
//#region fetchUsers-related constants
export  const  fetchUsers  =  createAction<IPeopleState>(FETCH_USERS, () => ({
booleanable: { isFetchUsersInProgress: true },
errable: { fetchUsersErrorMsg: null },
successible: { fetchUsersSuccessMsg: null },
}));
 
export  const  fetchUsersSuccess  =  createAction<IPeopleState, IPeopleState>(FETCH_USERS_SUCCESS, state  => ({
booleanable: { isFetchUsersInProgress: false },
successible: { fetchUsersSuccessMsg: 'FETCH_USERS action fullfilled!' },
state,
}));

export  const  fetchUsersError  =  createAction<IPeopleState, string>(FETCH_USERS_ERROR, fetchUsersErrorMsg  => ({
booleanable: { isFetchUsersInProgress: false },
errable: { fetchUsersErrorMsg },
}));
//#endregion
...
// redux-store\people\reducer.ts
  
import {
    ...
    FETCH_USERS,
    FETCH_USERS_SUCCESS,
    FETCH_USERS_ERROR,
    /* new-constant-import-goes-here */
} from  './constants';

...

export  default (
state: IPeopleState  =  initialState,
{ type, payload: incomingPayload }: ReduxActions.Action<IPeopleState>
) => {
const  payload  = ...

    switch (type) {
        ...
        case  FETCH_USERS:
        case  FETCH_USERS_SUCCESS:
        case  FETCH_USERS_ERROR:
        /* new-constant-cases-go-here */
        case  DEFAULT_ACTION:
        return {
            ...state,
            ...payload,
        };
        default:
            return  state;
    }
};
// redux-store\people\sagas.ts
  
...
import {
  ...
  FETCH_USERS,
  /* new-constant-import-goes-here */
} from './constants';
import {
  ...
  fetchUsersSuccess,
  fetchUsersError,
  /* new-action-import-goes-here */
} from './actions';
...
function* fetchUsersSaga() {
  const BOOL_VALUE = Math.random() >= 0.5;

  yield delay(500); // Just sleep for half a sec just to look real. A saga requires a yield because it's a generator

  try {
    if (BOOL_VALUE) {
      yield put(fetchUsersSuccess({}));
    } else {
      yield put(fetchUsersError('Sorry, An error occured! Please try again later!'));
    }
  } catch (error) {
    yield put(fetchUsersError('Sorry, An error occured! Please try again later!'));
  }
}

export default function* peopleSaga() {
  yield all([
    ...
    takeLatest(FETCH_USERS, fetchUsersSaga),
    /* new-saga-registration-goes-here */
  ]);
}
// redux-store\people\state.ts
...
export  type  PeopleErrable  = 'fetchUsersErrorMsg'  /* new-errable-goes-here */;
export  type  PeopleBooleanable  = 'isFetchUsersInProgress'  /* new-booleanable-goes-here */;
export  type  PeopleSuccessible  = 'fetchUsersSuccessMsg'  /* new-successible-goes-here */;
...

As you can see, it's too much code... but it's too much code that you don't get to write.

In a case where you do not want to have your action that has _ERROR and _SUCCESS, you would have only three files updated such as below

$ yo nextjs-typescript-antd:action --force
? Action name jump
? Select the store People
? Is it fullfillable? (Does it have SUCCESS & ERROR?) No
    force redux-store\people\constants.ts
    force redux-store\people\reducer.ts
    force redux-store\people\actions.ts

And below is how each would have been affected

// redux-store\people\constants.ts
...
//#region JUMP-related constants
export  const  JUMP  =  'JUMP';
//#endregion
...

// redux-store\people\reducer.ts
...
switch (type) {
    ...
    case  JUMP:
    /* new-constant-cases-go-here */
    case  DEFAULT_ACTION:
        return {
            ...state,
            ...payload,
        };
    default:
        return  state;
}

...
// redux-store\people\actions.ts
...
//#region jump-related constants
export  const  jump  =  createAction<IPeopleState, IPeopleState>(JUMP,  state  =>  state); // Make sure you pass a proper payload!!!
//#endregion
...

As you can see, there was nothing updated with regards to errable, successible and booleanable states because the action is not async and can't fail.

yo nextjs-typescript-antd:enum

It will prompt you the name for your new enum.

$ yo nextjs-typescript-antd:enum --force
? Enum name UserRoles
   create enums\userRoles.ts
    force enums\index.ts

Below is how the two files will be affected

// enums\userRoles.ts
export  enum  UserRoles {
    DefaultValue =  1,
}

and

// enums\index.ts
...
export { UserRoles } from  './userRoles';
...

yo nextjs-typescript-antd:antdhoc

It will prompt you the name for your new higher-order component.

$ yo nextjs-typescript-antd:hoc --force
? HOC name withUserRoles
   create hocs\withUserRoles.tsx
    force hocs\index.ts

Below is how the two files will be affected

// hocs\withUserRoles.tsx

import  React, { FC, ComponentType } from  'react';
/**
 *
 * @param  Component - the component that is passed into the HOC can be either a function component or class component.
 *
 * @see https://medium.com/@jrwebdev/react-higher-order-component-patterns-in-typescript-42278f7590fb
*/
const  withUserRoles  = <P  extends  object>(Component:  ComponentType<P>):  FC<P> => (props:  P) => {
    // Your logic comes up in here
    return  <Component {...props} />;
};  

export  default  withUserRoles;

and

// hocs\index.ts
...
export { default  as  withUserRoles } from  './withUserRoles';
...

yo nextjs-typescript-antd:antdhook

It will prompt you the name for your new hook.

$ yo nextjs-typescript-antd:hook --force
? Hook name (Should start with use) useUserRoles
   create hooks\useUserRoles.ts
    force hooks\index.ts

Below is how the two files will be affected

// hooks\useUserRoles.ts

export  const  useUserRoles  = () => {
    // Put your logic here
    return  null;
};

and

// hooks\index.ts
...
export { useUserRoles } from  './useUserRoles';
...

yo nextjs-typescript-antd:antdcontext

It will prompt you the name for your new context.

$ yo nextjs-typescript-antd:context --force
? Context name UserContext
   create contexts\userContext.ts
    force contexts\index.ts

Below is how the two files will be affected

// contexts\userContext.ts

import { createContext } from  'react';  

interface  IUserContext {} 

export  const  defaultUserContext:  IUserContext  = {};

export  const  UserContext  =  createContext<IUserContext>(defaultUserContext);

and

// contexts\index.ts
...
export { UserContext } from  './userContext';
...

yo nextjs-typescript-antd:model

It will prompt you the name for your new interface.

$ yo nextjs-typescript-antd:model --force
? Model name User
   create models\user.d.ts
    force models\index.d.ts

Below is how the two files will be affected

// models\user.d.ts

export  interface  IUser {
    readonly id:  string;
}

and

// models\index.d.ts
...
export { IUser } from  './user';
...

All that the subgenerators :hoc, :hook, :model, :hook and :context are giving you is a boilerplate and they also help enforcing the naming convention and eliminate the issues that can arise by someone creating something, like an hoc and they forget to export it in the hocs/index.ts. That will only mean that they can only import it as import { someHoc } from 'hocs/someHoc';. But they should only be importing it as import { someHoc } from 'hocs'; and that is only possible if they don't forget to export it in the hocs/index.ts file. And, also, because the code is generated, you can not create a file in PascalCase , as in SomeHoc or even hocs/some-hoc. All file names will be in camelCase.

Changelog Generator

Generate a changelog from git commits using https://github.com/lob/generate-changelog. This is meant to be used so that for every patch, minor, or major version, you update the changelog prior to running npm version so that the git tag contains the commit that updated both the changelog and version.

Release and Publish

In order to release and publish we have created a npm script npm run release-and-publish that will create a new tag in github and will publish your pkg into npm.

What does this generator do?

This yeoman generator will build different React components, creating a skeleton for the different files.

TODO List

  • Allow The User To Choose A CSS Preprocessor (LESS OR LESS)
  • Allow The User To Specify CRUD Requirements When Generating The Page
  • Allow The User To Choose A Layout When Generating The Boilerplate

Credits

Electron Hacked Github: https://github.com/ElectronHacked/nextjs-typescript-antd

Inspired by https://github.com/AnalyticsFire/generator-create-next-app-reloaded by Damian Aruj

Licence

MIT

2.1.10

5 years ago

2.1.9

5 years ago

2.1.8

5 years ago

2.1.7

5 years ago

2.1.6

5 years ago

2.1.5

5 years ago

2.1.4

5 years ago

2.1.3

5 years ago

2.1.2

5 years ago

2.1.1

5 years ago

2.1.0

5 years ago

2.0.1

5 years ago

2.0.1-alpha

5 years ago

2.0.0-alpha

5 years ago

1.0.4

5 years ago

1.0.3

5 years ago

1.0.2

5 years ago

1.0.1

5 years ago

1.0.0

5 years ago