This repository was archived by the owner on Mar 30, 2022. It is now read-only.
- Notifications
You must be signed in to change notification settings - Fork1
Example Github Page PWA with NextJs and Redux-toolkit
License
NotificationsYou must be signed in to change notification settings
Project-Setup/github_pwa
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Example Github Page PWA with NextJs, code splitting Redux-Toolkit, Typescript, Eslint, Jest and Emotion.
- Multi-pageReactProgressive Web App
- Installable foroffline use through Chrome on desktop ormobile
- Can be statically hosted onGithub Page for free (or as a regular web app hosted on a custom server)
- Dynamically loadedRedux reducers forcode splitting
- Prefetch security sensitive content at build time
- All inTypescript/Javascript withCSS-in-JS
- Easy testing withJest andEnzyme
- Eslint helps practice standard coding styles
- NextJs v9.4.2
- Redux-Toolkit v1.3.6
- Emotion v10
- Typescript v3.9.2
- [Nextjs_Ts_Eslint] NextJs, EmotionJs, Typescript
- [nextjs_redux_toolkit] NextJs, Redux-Toolkit
- [github_sql_pwa] Github page pwa setup with NextJs, code splitting Redux-Toolkit, Sql.js, Typeorm
- setup node env
nvm usenpm install
- remove unwanted files in
public/,src/ - add
.envand other .env files - preview dev progress on
http://localhost:3000/npm run dev
- export to
docs/for Github Page deploynpm runexport - readSetup for notes
- install nvm in the os
nvm install nodegit init
- add
.gitignore node -v> .nvmrcnpm init -y
npm i -S next react react-dom
- add a script to your package.json like this:
{"scripts": {"dev":"next","build":"next build","start":"next start" }}
npm i -D typescript @types/react @types/react-dom @types/node
- create
tsconfig.json{"compilerOptions": {"allowJs":true,"allowSyntheticDefaultImports":true,"alwaysStrict":true,"esModuleInterop":true,"isolatedModules":true,"jsx":"preserve","lib": ["dom","es2017" ],"module":"esnext","moduleResolution":"node","noEmit":true,"typeRoots": ["./node_modules/@types" ],"noFallthroughCasesInSwitch":true,"noUnusedLocals":true,"noUnusedParameters":true,"resolveJsonModule":true,"removeComments":false,"skipLibCheck":true,"strict":true,"target":"esnext","forceConsistentCasingInFileNames":true,"baseUrl":"./src" },"exclude": ["node_modules","next.config.js" ],"include": ["**/*.ts","**/*.tsx" ]}
- create
src/pagesfolder (orpages) - create
pages.tsxundersrc/pages/(i.e.src/pages/index.tsxfor/route)
npm i -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-react eslint-import-resolver-typescriptnpm i -D eslint-config-airbnb eslint-plugin-jsx-a11y eslint-plugin-import eslint-plugin-react-hooksnpm i -D prettier eslint-config-prettier eslint-plugin-prettier
- create
.eslintrc.jsmodule.exports={parser:'@typescript-eslint/parser',// Specifies the ESLint parserextends:['plugin:react/recommended',// Uses the recommended rules from@eslint-plugin-react'plugin:@typescript-eslint/recommended',// Uses the recommended rules from@typescript-eslint/eslint-plugin'airbnb',//Uses airbnb recommended rules'prettier/@typescript-eslint',// Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier'plugin:prettier/recommended',// Enables eslint-plugin-prettier and displays prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.],parserOptions:{ecmaVersion:2018,// Allows for the parsing of modern ECMAScript featuressourceType:'module',// Allows for the use of importsecmaFeatures:{jsx:true,// Allows for the parsing of JSX},},env:{browser:true,node:true},rules:{// Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs// e.g. '@typescript-eslint/explicit-function-return-type': 'off','no-unused-vars':'off','@typescript-eslint/no-unused-vars':['error',{'vars':'all','args':'after-used','ignoreRestSiblings':false}],'react/jsx-filename-extension':[1,{'extensions':['.js','.jsx','.ts','.tsx']}],'react/jsx-first-prop-new-line':0,'@typescript-eslint/no-explicit-any':'off','@typescript-eslint/explicit-function-return-type':0,'@typescript-eslint/no-namespace':'off','jsx-a11y/anchor-is-valid':['error',{'components':['Link'],'specialLink':['hrefLeft','hrefRight'],'aspects':['invalidHref','preferButton']}],'react/prop-types':'off','import/extensions':[1,{'extensions':['.js','.jsx','.ts','.tsx']}],'import/no-extraneous-dependencies':['error',{'devDependencies':true}],'comma-dangle':['error',{'arrays':'always-multiline','objects':'always-multiline','imports':'always-multiline','exports':'always-multiline','functions':'never'}],"react-hooks/rules-of-hooks":"error",'react-hooks/exhaustive-deps':'off','no-bitwise':'off'},plugins:['@typescript-eslint/eslint-plugin','react-hooks',],settings:{'import/resolver':{node:{extensions:['.js','.jsx','.ts','.tsx'],},typescript:{},},react:{version:'detect',// Tells eslint-plugin-react to automatically detect the version of React to use},},};
- create
.prettierrc.jsmodule.exports={semi:true,trailingComma:'es5',singleQuote:true,printWidth:80,tabWidth:2,};
npm i -D jest babel-jest
- add scripts in
package.json"scripts": {"test":"jest","test:watch":"jest --watch","test:coverage":"jest --coverage"},
npm i -D enzyme enzyme-adapter-react-16 enzyme-to-jsonnpm i -D typescript @types/enzyme @types/enzyme-adapter-react-16 @types/jest
- create
jest.config.jsmodule.exports={moduleFileExtensions:['ts','tsx','js'],testRegex:'(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|js?|tsx?|ts?)$',globals:{NODE_ENV:'test',},snapshotSerializers:['enzyme-to-json/serializer'],transform:{'^.+\\.(j|t)sx?$':'babel-jest',},coveragePathIgnorePatterns:['/node_modules/','jest.setup.js','<rootDir>/configs/','jest.config.js','.json','.snap',],setupFiles:['<rootDir>/jest/jest.setup.js'],coverageReporters:['json','lcov','text','text-summary'],moduleNameMapper:{'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':'<rootDir>/__mocks__/mocks.js','\\.(css|less|scss)$':'<rootDir>/__mocks__/mocks.js',},moduleDirectories:['node_modules','src'],};
- create
babel.config.jsmodule.exports={presets:['next/babel'],};
- create
jest/jest.setup.jsimportEnzymefrom'enzyme';importAdapterfrom'enzyme-adapter-react-16';import{join}from'path';import{loadEnvConfig}from'next/dist/lib/load-env-config';// to load '.env' files in testloadEnvConfig(join(__dirname,'.../'));Enzyme.configure({adapter:newAdapter()});
- change
envin.eslintrc.jsenv:{browser:true,node:true,jest:true},
npm i -S @emotion/corenpm i -D @emotion/babel-preset-css-prop jest-emotion eslint-plugin-emotion
- change
babel.config.jsmodule.exports={presets:[['next/babel',{'preset-env':{},'preset-react':{},},],'@emotion/babel-preset-css-prop',],};
- add rules and plugins to
.eslintrc.jsmodule.exports={// ...rules:{// ..."emotion/no-vanilla":"error","emotion/import-from-emotion":"error","emotion/styled-import":"error",},// ...plugins:['emotion',// ...],// ...}
- add
jest/jest.setupAfterEnv.jsimport{matchers}from'jest-emotion';expect.extend(matchers);
- add serializers and setup files to
jest/jest.config.js// ...snapshotSerializers:['enzyme-to-json/serializer','jest-emotion'],// ...setupFilesAfterEnv:['<rootDir>/jest.setupAfterEnv.js'],// ...
(deploy to /docs intead of using gh-pages branch; replace{folder} with the project name in github repo)
- add
.env.production
NEXT_PUBLIC_LINK_PREFIX=/{folder}- create
LINK_PREFIXinnext.config.jsconstLINK_PREFIX=process.env.NEXT_PUBLIC_LINK_PREFIX||'';module.exports=()=>({assetPrefix:LINK_PREFIX,});
- change
asprop innext/Linkto addlinkPrefix, similar tosrc/features/link/Link.tsxin the example setup - change
scriptsinpackage.json{"scripts": {"export":"NODE_ENV=production npm run build && next export -o docs && touch docs/.nojekyll" }}
npm i -D @babel/plugin-proposal-nullish-coalescing-operator @babel/plugin-proposal-optional-chaining
- add the plugins to
babel.config.jsmodule.exports={presets:[// ...],plugins:['@babel/plugin-proposal-optional-chaining','@babel/plugin-proposal-nullish-coalescing-operator',],};
npm i -S react-redux @reduxjs/toolkitnpm i -D @types/react-redux
- either use
next-redux-wrapperpackage (npm i -P next-redux-wrapper) or copy thewithRedux.tsxfrom the example setupsrc/utils/redux - create custom
makeStorefunction,_app.tsxpage and other redux setup as examples innext-redux-wrapperrepo shows
- copy
configureStore.ts,DynamicStoreWrap.tsxfrom the example setupsrc/utils/redux, andobjectAssign.tsfromsrc/utils/common - change
src/_app.tsxsimilar to the example setup
npm i -S next-pwa next-manifest
- change
next.config.jsconstisProd=process.env.NODE_ENV==='production';constFOLDER=LINK_PREFIX&&LINK_PREFIX.substring(1);// tranfrom precache url for browsers that encode dynamic routes// i.e. "[id].js" => "%5Bid%5D.js"constencodeUriTransform=async(manifestEntries)=>{constmanifest=manifestEntries.map((entry)=>{entry.url=encodeURI(entry.url);returnentry;});return{ manifest,warnings:[]};};module.exports=()=>withManifest(withPWA({// ...// service workerpwa:{disable:!isProd,subdomainPrefix:LINK_PREFIX,dest:'public',navigationPreload:true,},// manifestmanifest:{/* eslint-disable @typescript-eslint/camelcase */output:'public',short_name:FOLDER,name:FOLDER,start_url:`${LINK_PREFIX}/`,background_color:THEME_COLOR,display:'standalone',scope:`${LINK_PREFIX}/`,dir:'ltr',// text direction: left to righttheme_color:THEME_COLOR,icons:[{src:`${LINK_PREFIX}${ICON_192_PATH}`,sizes:'192x192',type:'image/png',},{src:`${LINK_PREFIX}${ICON_512_PATH}`,sizes:'512x512',type:'image/png',},],},}));
- add
public/iconsfolder and include corresponding icon files in the folder - copy
ManifestHead.tsxfrom the example setupsrc/features/head - import
ManifestHeadin pages
- NextJs, next-pwa, workbox are still growing their api, so this project setup will be modified in the future for easier setup.
- There is a known error on the workbox:GoogleChrome/workbox#2178.
- Only direct children in
next/headwill be picked up at build time, so allnext/linkwrapped elements must be inserted (useEffect) after thenext/headis loaded.
About
Example Github Page PWA with NextJs and Redux-toolkit
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Releases
No releases published
Packages0
No packages published
Uh oh!
There was an error while loading.Please reload this page.
Contributors2
Uh oh!
There was an error while loading.Please reload this page.