e783b0a2e8
This PR re-includes ESLint with some notable changes, namely a guided setup similar to how TypeScript is instantiated in a Next.js application. To add ESLint to a project, developers will have to create an `.eslintrc` file in the root of their project or add an empty `eslintConfig` object to their `package.json` file. ```js touch .eslintrc ``` Then running `next build` will show instructions to install the required packages needed: <img width="862" alt="Screen Shot 2021-04-19 at 7 38 27 PM" src="https://user-images.githubusercontent.com/12476932/115316182-dfd51b00-a146-11eb-830c-90bad20ed151.png"> Once installed and `next build` is run again, `.eslintrc` will be automatically configured to include the default config: ```json { "extends": "next" } ``` In addition to this change: - The feature is now under the experimental flag and requires opt-in. After testing and feedback, it will be switched to the top-level namespace and turned on by default. - A new ESLint shareable configuration package is included that can be extended in any application with `{ extends: 'next' }` - This default config extends recommended rule sets from [`eslint-plugin-react`](https://www.npmjs.com/package/eslint-plugin-react), [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks), and [`eslint-plugin-next`](https://www.npmjs.com/package/@next/eslint-plugin-next) - All rules in [`eslint-plugin-next`](https://www.npmjs.com/package/@next/eslint-plugin-next) have been modified to include actionable links that show more information to help resolve each issue
96 lines
2.2 KiB
JavaScript
96 lines
2.2 KiB
JavaScript
const fs = require('fs')
|
|
const path = require('path')
|
|
|
|
/**
|
|
* Checks if the source is a directory.
|
|
* @param {string} source
|
|
*/
|
|
function isDirectory(source) {
|
|
return fs.lstatSync(source).isDirectory()
|
|
}
|
|
|
|
/**
|
|
* Checks if the source is a directory.
|
|
* @param {string} source
|
|
*/
|
|
function isSymlink(source) {
|
|
return fs.lstatSync(source).isSymbolicLink()
|
|
}
|
|
|
|
/**
|
|
* Gets the possible URLs from a directory.
|
|
* @param {string} urlprefix
|
|
* @param {string} directory
|
|
*/
|
|
function getUrlFromPagesDirectory(urlPrefix, directory) {
|
|
return parseUrlForPages(urlPrefix, directory).map(
|
|
// Since the URLs are normalized we add `^` and `$` to the RegExp to make sure they match exactly.
|
|
(url) => new RegExp(`^${normalizeURL(url)}$`)
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Recursively parse directory for page URLs.
|
|
* @param {string} urlprefix
|
|
* @param {string} directory
|
|
*/
|
|
function parseUrlForPages(urlprefix, directory) {
|
|
const files = fs.readdirSync(directory)
|
|
const res = []
|
|
files.forEach((fname) => {
|
|
if (/(\.(j|t)sx?)$/.test(fname)) {
|
|
fname = fname.replace(/\[.*\]/g, '.*')
|
|
if (/^index(\.(j|t)sx?)$/.test(fname)) {
|
|
res.push(`${urlprefix}${fname.replace(/^index(\.(j|t)sx?)$/, '')}`)
|
|
}
|
|
res.push(`${urlprefix}${fname.replace(/(\.(j|t)sx?)$/, '')}`)
|
|
} else {
|
|
const dirPath = path.join(directory, fname)
|
|
if (isDirectory(dirPath) && !isSymlink(dirPath)) {
|
|
res.push(...parseUrlForPages(urlprefix + fname + '/', dirPath))
|
|
}
|
|
}
|
|
})
|
|
return res
|
|
}
|
|
|
|
/**
|
|
* Takes a URL and does the following things.
|
|
* - Replaces `index.html` with `/`
|
|
* - Makes sure all URLs are have a trailing `/`
|
|
* - Removes query string
|
|
* @param {string} url
|
|
*/
|
|
function normalizeURL(url) {
|
|
if (!url) {
|
|
return
|
|
}
|
|
url = url.split('?')[0]
|
|
url = url.split('#')[0]
|
|
url = url = url.replace(/(\/index\.html)$/, '/')
|
|
// Empty URLs should not be trailed with `/`, e.g. `#heading`
|
|
if (url === '') {
|
|
return url
|
|
}
|
|
url = url.endsWith('/') ? url : url + '/'
|
|
return url
|
|
}
|
|
|
|
function execOnce(fn) {
|
|
let used = false
|
|
let result
|
|
|
|
return (...args) => {
|
|
if (!used) {
|
|
used = true
|
|
result = fn(...args)
|
|
}
|
|
return result
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
getUrlFromPagesDirectory,
|
|
normalizeURL,
|
|
execOnce,
|
|
}
|