This repo intends to be a starting point for future projects
Included with be
- nextjs
- react
- scss modules
- storybook
- scss in storybook
- eslint
- pm2 to manage processes
- yeoman to easily create components
- mongodb for search and database related items
- firebase
- redux
- nextjs
- react
- eslint
- prismjs
- scss modules
- storybook
- scss in storybook
- pm2 to manage processes
- yeoman to easily create components
- Makefile or yeoman?
- rename the project (not have it called basejs)
- regenerate index file within src/components
- mongodb for search and database related items
- firebase
- redux
Unless you want the name to stay as BaseNextJS and basenextjs, you will have to rename all occurrences of the name.
basenextjs package.json
npm init next-app - NEWER
npx create-next-app
- make sure name is all lowercase
npm install -g npm-check-updates
- add line to
package.json
in scripts section
"checkModules": "ncu"
npm install eslint --save-dev
npm audit fix
- You might have some packages with low
npx eslint --init
npx eslint yourfile.js
- manually lint your file
- add line to package.json in scripts section
-
"lint": "./node_modules/.bin/eslint ./pages"
OR
- add line to package.json in scripts section
"lint": "npx eslint ./pages"
eslint FILE --fix
eslint FILE --fix-dry-run
- JSX not allowed in files with extensions '.js' https://stackoverflow.com/questions/43031126/jsx-not-allowed-in-files-with-extension-js-with-eslint-config-airbnb Option 1 -.eslintrc "rules": { "react/jsx-filename-extension": [0] , "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }], }
Option 2 - webpack.config.js resolve: { extensions: ['.js', '.jsx'] }, 2. module.css and module.scss files - unexpected token . You cannot lint css with eslint. eslint is for js
-
'React' is not defined and 'React' must be in scopt when using JSX import React from 'react';
-
'Component' is missing in props-validation AND propType "Component" is not required, but has no corresponding defaultProps declaration https://stackoverflow.com/questions/38684925/react-eslint-error-missing-in-props-validation jsx-eslint/eslint-plugin-react#1433
import PropTypes from 'prop-types'
Add to the components proptypes
ReactComponent.propTypes = {
Component: ...
};
ReactComponent.defaultProps = {
Component: null
}
- Prop spreading is forbidden https://stackoverflow.com/questions/58726028/how-to-solve-prop-spreading-is-forbidden-in-custom-route-component https://eslint.org/docs/user-guide/configuring Add to the top of the file
/* eslint-disable
react/jsx-props-no-spreading,
react/prop-types
*/
-
This line has a length of 131. Maximum allowed is 100 Break up the line
-
Prop type object is forbidden OR Prop type array is forbidden Object is too vague. jsx-eslint/eslint-plugin-react#2079 facebook/prop-types#212
// Bad PropTypes.object PropTypes.array
// Good PropTypes.objectOf(PropTypes.object) PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string]))
- Component should be written as a pure function If you are only using render and do not need items like ComponentDidMount, do that
npm install -g eslint-watch
- make sure you have eslint globally installed
npm i -g eslint eslint-watch
- add line to package.json in scripts section
"watchLint": "esw --color --watch --changed --ext-js,jsx src"
- Create a new
pages/_app.js
// This default export is required in a new `pages/_app.js` file.
export default function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
- Import any additional global styles you need
import './prism.css'
There is now built in support for scss https://nextjs.org/blog/next-9-3 https://nextjs.org/docs/basic-features/built-in-css-support
npm install --save sass
- Make sure restart your server if you have it running
- Very similar to regular CSS components
- Component File
import styles from 'Button.module.scss'
- SCSS File called
Button.module.scss
If you have a global scss file and want to access the globally defined variables, you have to import the global file in each of your scss files.
@import "../global.scss"
Ideally, we shouldn't have to do this. Another option would be to utilize the configs, but that does not look like something that Next plans on using in the future. vercel/next.js#10912
Back then you had to install packages to import .css and .scss files https://github.com/zeit/next-plugins/tree/master/packages/next-css https://github.com/zeit/next-plugins/tree/master/packages/next-sass
- Install the relevant packages
npm install --save @zeit/next-css
npm install --save @zeit/next-sass node-sass
- Add a next.config.js to project root
- If you need to import both css and scss, you will need another package.
Only CSS Modules
const withCSS = require('@zeit/next-css')
module.exports = withCSS({
/* config options here */
})
Both CSS and SCSS
const withPlugins = require('next-compose-plugins');
module.exports = withPlugins([
[sass, {cssModules: true}],
[css, {cssModules: false}],
]);
npm install prismjs
- Download the css file from https://prismjs.com
- it seems like we need this file for actual color
- https://prismjs.com/download.html#themes=prism-okaidia&languages=markup+css+clike+javascript
- Import the global css file in
pages/_app.js
Regardless of how you choose to do it, it is recommended to wrap the code in a pre tag
Add this code where necessary
const Prism = require('prismjs');
const code = `var data = 1;`;
const html = Prism.highlight(code, Prism.languages.javascript, 'javascript');
<pre>
<code dangerouslySetInnerHTML={ {__html: html} }/>
</pre>
Add this code where necessary
I have noticed that if you have Prism.highlightAll() in the same file where you have
...
// Page File
import Prism from 'prismjs';
componentDidMount() {
Prism.highlightAll();
}
// Component File
<pre><code class="language-css">p { color: red }</code></pre>
https://ian.pvdindustrial.com/blog/prismjs-npm-webpack-wordpress-theme-20180920/ https://betterstack.dev/blog/code-highlighting-in-react-using-prismjs/ https://prismjs.com/plugins/ To enable features like line numbering, you need to do a bit more
npm install --save-dev babel-plugin-prismjs
- Create a .babelrc at the root of your project
{
"plugins": [
["prismjs", {
// "languages": ["javascript", "css", "html"],
"plugins": ["line-numbers", "show-language"],
// "theme": "okaidia",
"css": true
}]
]
}
You need the css to be true to get the line numbers and to show language.
- You need to add an extra line to babel
"presets": [ "next/babel" ],
https://nextjs.org/docs/advanced-features/customizing-babel-config
For some reason we cant get these features to work on the frontend It complains that you need to put all your global css in '_app.js'. This might have to do with some of the plugins calling css files
vercel/next.js#10059 PrismJS/prism#2186 vercel/next-plugins#70
import the plugins directly into _app.js
along with any css files.
However it seems like you will run into issues when you try to build and run on production. Therefore it might make sense to do all the imports in a separate file and call that file from whatever page you are on.
Do not have Prism.highlightAll() in the component and the page calling the component. You will run into multiple issues. In short, do not call Prism.highlight multiple times.
If you have other components wrapped in div tags, they may be adversely affected.
You dont have to mention show-language and copy-to-clipboard in plugins. They automatically show up once you import the plugins(maybe true for all browsers except for firefox?)
Plugins are not working properly on Firefox
- might be due to cache(but it even shows after you do a hard refresh). if you look at the dev tools, you will notice the html is not correct. if you are good on chrome and safari, i wouldnt worry too much
Babel is responsible for compiling new code es6 and transpiling to older code. The .babelrc file will be used in storybook and in regular dev https://nextjs.org/docs/advanced-features/customizing-babel-config https://storybook.js.org/docs/configurations/custom-babel-config/
https://github.com/stylelint/stylelint/blob/HEAD/docs/user-guide/get-started.md
npm install --save-dev stylelint stylelint-config-standard
.stylelintrc.json
{
"extends": "stylelint-config-standard"
}
npx stylelint "**/*.css"
npm install --save-dev stylelint-config-sass-guidelines
.stylelintrc.json
{
"extends": "stylelint-config-sass-guidelines"
"rules": {
"indentation": "tab",
"number-leading-zero": null
}
}
By default, all pages are under the page directory. You can now have it nested under src
https://nextjs.org/blog/next-9-1
https://storybook.js.org/docs/guides/guide-react/ The process has been streamlined compared to last year in 2019. While you can still do it manually, it is easier if you follow the step below
npx -p @storybook/cli sb init
npm run storybook
- In
.storybook/main.js
, update the path such that you can pull in stories fromsrc/components
stories: [
'../stories/**/*.stories.js',
'../src/components/**/*.stories.js',
],
- React is not defined when import a component.
- in the component, add
import React from 'react';
- You cannot
import styles from "./styles.scss"
within the stories directory. You can doimport './styles.scss'
though. https://stackoverflow.com/questions/48273019/storybook-webpack-will-not-load-scss-files
By default, you can import regular css files. I could not figure out how to get CSS Modules working. It worked with previous versions of storybook. So it is likely due to new versions of some node modules.
However we can set up Scss modules. If you can have scss modules, do you need css modules? Not really.
You need to customize the webpack config. Otherwise you will get this issue if you try to use SCSS Modules. You may need an appropriate loader to handle this file type
https://storybook.js.org/docs/configurations/custom-webpack-config/#full-control-mode
npm install --save-dev css-loader sass-loader style-loader
- Provide a webpack field in main.js -.storybook/main.js
const path = require('path');
// Export a function. Accept the base config as the only param.
module.exports = {
webpackFinal: async (config, { configType }) => {
// `configType` has a value of 'DEVELOPMENT' or 'PRODUCTION'
// You can change the configuration based on that.
// 'PRODUCTION' is used when building the static version of storybook.
// Make whatever fine-grained changes you need
config.module.rules.push({
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader'],
include: path.resolve(__dirname, '../'),
});
// Return the altered config
return config;
},
};
- Restart your storybook process
https://github.com/storybookjs/presets/tree/master/packages/preset-scss
This only worked for regular css and scss files within the stories directory
npm install --save @storybook/preset-scss css-loader sass-loader style-loader
- Edit .storybook/main.js
module.exports = {
stories: ['../stories/**/*.stories.js'],
addons: [
'@storybook/addon-actions',
'@storybook/addon-links',
'@storybook/preset-scss'
/*
{
name: '@storybook/preset-scss',
options: {
cssLoaderOption: {
modules: true,
},
},
},
*/
],
npm install --save-dev css-loader sass-loader style-loader
- Create a new file - .storybook/webpack.config.js
const path = require('path');
// Export a function. Accept the base config as the only param.
module.exports = async ({ config, mode }) => {
config.module.rules.push(
{
test: /\.scss$/,
// Allows for Regular SCSS
// use: ['style-loader', 'css-loader', 'sass-loader'],
// Allows for SCSS Modules
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: {
modules: true,
}
},
{loader:"sass-loader"}
],
// include: path.resolve(__dirname, '../'),
include: /\.module\.scss$/
}
);
return config;
};
For some reason, images are not loading in storybook. Supposedly you could update your webpack config in storybook to include the following but that didnt work for me, so i updated my run target
DOESNT - .storybook/webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'file-loader',
},
],
},
],
},
};
WORKS - package.json
{
"scripts": {
"start-storybook": "start-storybook -s ./public -p 9001"
}
}
https://stackoverflow.com/questions/58267903/serving-static-files-in-storybook-js https://stephencharlesweiss.com/blog/2019-06-03/storybook-and-static-images/
https://nextjs.org/docs/routing/introduction
Nested files are supported.
https://pm2.keymetrics.io/docs/usage/quick-start/
npm install pm2@latest -g
pm2 ecosystem
- create a config file that can get you started
They updated the library a bit so you will have to read the docs. i.e. TimelineMax can accept {} but will error out if given null. https://greensock.com/forums/topic/21908-v3-webpack-importing-error-module-not-found-gsapgsap/
npm install --save gsap
OLD
import { TimelineMax, Power2 } from 'gsap/TweenMax';
NEW
import { TimelineMax, Power2 } from 'gsap';
OLD
const repeatConfigs = repeat ? { repeat: -1, repeatDelay: 1 } : null;
const GSAP = require('gsap/TweenMax');
const { TimelineMax, Power2 } = GSAP;
const tl_1 = new TimelineMax(repeatConfigs);
NEW
const repeatConfigs = repeat ? { repeat: -1, repeatDelay: 1 } : {};
const GSAP = require('gsap');
const { TimelineMax, Power2 } = GSAP;
const tl = new TimelineMax(repeatConfigs);