From fe09f2247259e292185e23c89b558aaede8e0058 Mon Sep 17 00:00:00 2001 From: IronTony Date: Tue, 19 Oct 2021 23:08:49 +0200 Subject: [PATCH 1/3] Chore deps + some fixes and refactor --- .husky/pre-commit | 2 +- config/env.js | 16 ++-- config/modules.js | 6 +- config/paths.js | 10 ++- config/webpack.config.js | 118 +++++++++++++++++++-------- config/webpackDevServer.config.js | 3 +- package.json | 18 ++-- public/index.html | 5 +- scripts/build.js | 57 ++++++++----- scripts/start.js | 60 ++++++++++---- src/components/WBContainer/index.tsx | 17 ++-- src/components/WBHeader/index.tsx | 33 +++----- src/components/WBLoader/index.tsx | 8 +- src/components/WBMenu/index.tsx | 16 ++-- src/index.tsx | 32 ++++---- src/logo.svg | 8 +- src/pages/AnotherPage/index.tsx | 1 - src/pages/Homepage/index.tsx | 35 ++++---- src/redux/ghibli/sagas.ts | 12 ++- src/redux/store.ts | 23 ++---- tsconfig.json | 2 +- 21 files changed, 278 insertions(+), 204 deletions(-) diff --git a/.husky/pre-commit b/.husky/pre-commit index 9ed4084..d1ee147 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1,4 @@ #!/bin/sh . "$(dirname "$0")/_/husky.sh" -yarn lint:staged && yarn dependencies:checkCircular && yarn dependencies:graph \ No newline at end of file +yarn run pre-commit \ No newline at end of file diff --git a/config/env.js b/config/env.js index b758778..3d1411b 100644 --- a/config/env.js +++ b/config/env.js @@ -9,7 +9,9 @@ delete require.cache[require.resolve('./paths')]; const NODE_ENV = process.env.NODE_ENV; if (!NODE_ENV) { - throw new Error('The NODE_ENV environment variable is required but was not specified.'); + throw new Error( + 'The NODE_ENV environment variable is required but was not specified.' + ); } // https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use @@ -28,12 +30,12 @@ const dotenvFiles = [ // that have already been set. Variable expansion is supported in .env files. // https://github.com/motdotla/dotenv // https://github.com/motdotla/dotenv-expand -dotenvFiles.forEach((dotenvFile) => { +dotenvFiles.forEach(dotenvFile => { if (fs.existsSync(dotenvFile)) { require('dotenv-expand')( require('dotenv').config({ path: dotenvFile, - }), + }) ); } }); @@ -50,8 +52,8 @@ dotenvFiles.forEach((dotenvFile) => { const appDirectory = fs.realpathSync(process.cwd()); process.env.NODE_PATH = (process.env.NODE_PATH || '') .split(path.delimiter) - .filter((folder) => folder && !path.isAbsolute(folder)) - .map((folder) => path.resolve(appDirectory, folder)) + .filter(folder => folder && !path.isAbsolute(folder)) + .map(folder => path.resolve(appDirectory, folder)) .join(path.delimiter); // Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be @@ -60,7 +62,7 @@ const REACT_APP = /^REACT_APP_/i; function getClientEnvironment(publicUrl) { const raw = Object.keys(process.env) - .filter((key) => REACT_APP.test(key)) + .filter(key => REACT_APP.test(key)) .reduce( (env, key) => { env[key] = process.env[key]; @@ -88,7 +90,7 @@ function getClientEnvironment(publicUrl) { // which is why it's disabled by default. // It is defined here so it is available in the webpackHotDevClient. FAST_REFRESH: process.env.FAST_REFRESH !== 'false', - }, + } ); // Stringify all values so we can feed into webpack DefinePlugin const stringified = { diff --git a/config/modules.js b/config/modules.js index 261dd4a..d63e41d 100644 --- a/config/modules.js +++ b/config/modules.js @@ -44,8 +44,8 @@ function getAdditionalModulePaths(options = {}) { throw new Error( chalk.red.bold( "Your project's `baseUrl` can only be set to `src` or `node_modules`." + - ' Create React App does not support other values at this time.', - ), + ' Create React App does not support other values at this time.' + ) ); } @@ -98,7 +98,7 @@ function getModules() { if (hasTsConfig && hasJsConfig) { throw new Error( - 'You have both a tsconfig.json and a jsconfig.json. If you are using TypeScript please remove your jsconfig.json file.', + 'You have both a tsconfig.json and a jsconfig.json. If you are using TypeScript please remove your jsconfig.json file.' ); } diff --git a/config/paths.js b/config/paths.js index 4a483e3..4e3d30e 100644 --- a/config/paths.js +++ b/config/paths.js @@ -7,7 +7,7 @@ const getPublicUrlOrPath = require('react-dev-utils/getPublicUrlOrPath'); // Make sure any symlinks in the project folder are resolved: // https://github.com/facebook/create-react-app/issues/637 const appDirectory = fs.realpathSync(process.cwd()); -const resolveApp = (relativePath) => path.resolve(appDirectory, relativePath); +const resolveApp = relativePath => path.resolve(appDirectory, relativePath); // We use `PUBLIC_URL` environment variable or "homepage" field to infer // "public path" at which the app is served. @@ -18,7 +18,7 @@ const resolveApp = (relativePath) => path.resolve(appDirectory, relativePath); const publicUrlOrPath = getPublicUrlOrPath( process.env.NODE_ENV === 'development', require(resolveApp('package.json')).homepage, - process.env.PUBLIC_URL, + process.env.PUBLIC_URL ); const buildPath = process.env.BUILD_PATH || 'build'; @@ -39,7 +39,9 @@ const moduleFileExtensions = [ // Resolve file paths in the same order as webpack const resolveModule = (resolveFn, filePath) => { - const extension = moduleFileExtensions.find((extension) => fs.existsSync(resolveFn(`${filePath}.${extension}`))); + const extension = moduleFileExtensions.find(extension => + fs.existsSync(resolveFn(`${filePath}.${extension}`)) + ); if (extension) { return resolveFn(`${filePath}.${extension}`); @@ -68,4 +70,6 @@ module.exports = { publicUrlOrPath, }; + + module.exports.moduleFileExtensions = moduleFileExtensions; diff --git a/config/webpack.config.js b/config/webpack.config.js index 3082319..d7f95dd 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -34,8 +34,12 @@ const appPackageJson = require(paths.appPackageJson); // Source maps are resource heavy and can cause out of memory issue for large source files. const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false'; -const webpackDevClientEntry = require.resolve('react-dev-utils/webpackHotDevClient'); -const reactRefreshOverlayEntry = require.resolve('react-dev-utils/refreshOverlayInterop'); +const webpackDevClientEntry = require.resolve( + 'react-dev-utils/webpackHotDevClient' +); +const reactRefreshOverlayEntry = require.resolve( + 'react-dev-utils/refreshOverlayInterop' +); // Some apps do not need the benefits of saving a web request, so not inlining the chunk // makes for a smoother build process. @@ -44,7 +48,9 @@ const shouldInlineRuntimeChunk = process.env.INLINE_RUNTIME_CHUNK !== 'false'; const emitErrorsAsWarnings = process.env.ESLINT_NO_DEV_ERRORS === 'true'; const disableESLintPlugin = process.env.DISABLE_ESLINT_PLUGIN === 'true'; -const imageInlineSizeLimit = parseInt(process.env.IMAGE_INLINE_SIZE_LIMIT || '10000'); +const imageInlineSizeLimit = parseInt( + process.env.IMAGE_INLINE_SIZE_LIMIT || '10000' +); // Check if TypeScript is setup const useTypeScript = fs.existsSync(paths.appTsConfig); @@ -79,7 +85,8 @@ module.exports = function (webpackEnv) { // Variable used for enabling profiling in Production // passed into alias object. Uses a flag if passed into the build command - const isEnvProductionProfile = isEnvProduction && process.argv.includes('--profile'); + const isEnvProductionProfile = + isEnvProduction && process.argv.includes('--profile'); // We will provide `paths.publicUrlOrPath` to our app // as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript. @@ -97,7 +104,9 @@ module.exports = function (webpackEnv) { loader: MiniCssExtractPlugin.loader, // css is located in `static/css`, use '../../' to locate index.html folder // in production `paths.publicUrlOrPath` can be a relative path - options: paths.publicUrlOrPath.startsWith('.') ? { publicPath: '../../' } : {}, + options: paths.publicUrlOrPath.startsWith('.') + ? { publicPath: '../../' } + : {}, }, { loader: require.resolve('css-loader'), @@ -143,7 +152,7 @@ module.exports = function (webpackEnv) { options: { sourceMap: true, }, - }, + } ); } return loaders; @@ -192,7 +201,9 @@ module.exports = function (webpackEnv) { pathinfo: isEnvDevelopment, // There will be one main bundle, and one file per asynchronous chunk. // In development, it does not produce real files. - filename: isEnvProduction ? 'static/js/[name].[contenthash:8].js' : isEnvDevelopment && 'static/js/bundle.js', + filename: isEnvProduction + ? 'static/js/[name].[contenthash:8].js' + : isEnvDevelopment && 'static/js/bundle.js', // TODO: remove this when upgrading to webpack 5 futureEmitAssets: true, // There are also additional JS chunk files if you use code splitting. @@ -205,8 +216,12 @@ module.exports = function (webpackEnv) { publicPath: paths.publicUrlOrPath, // Point sourcemap entries to original disk location (format as URL on Windows) devtoolModuleFilenameTemplate: isEnvProduction - ? (info) => path.relative(paths.appSrc, info.absoluteResourcePath).replace(/\\/g, '/') - : isEnvDevelopment && ((info) => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')), + ? info => + path + .relative(paths.appSrc, info.absoluteResourcePath) + .replace(/\\/g, '/') + : isEnvDevelopment && + (info => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')), // Prevents conflicts when multiple webpack runtimes (from different apps) // are used on the same page. jsonpFunction: `webpackJsonp${appPackageJson.name}`, @@ -289,7 +304,7 @@ module.exports = function (webpackEnv) { // https://twitter.com/wSokra/status/969679223278505985 // https://github.com/facebook/create-react-app/issues/5358 runtimeChunk: { - name: (entrypoint) => `runtime-${entrypoint.name}`, + name: entrypoint => `runtime-${entrypoint.name}`, }, }, resolve: { @@ -297,7 +312,9 @@ module.exports = function (webpackEnv) { // We placed these paths second because we want `node_modules` to "win" // if there are any conflicts. This matches Node resolution mechanism. // https://github.com/facebook/create-react-app/issues/253 - modules: ['node_modules', paths.appNodeModules].concat(modules.additionalModulePaths || []), + modules: ['node_modules', paths.appNodeModules].concat( + modules.additionalModulePaths || [] + ), // These are the reasonable defaults supported by the Node ecosystem. // We also include JSX as a common component filename extension to support // some tools, although we do not recommend using it, see: @@ -305,8 +322,8 @@ module.exports = function (webpackEnv) { // `web` extension prefixes have been added for better support // for React Native Web. extensions: paths.moduleFileExtensions - .map((ext) => `.${ext}`) - .filter((ext) => useTypeScript || !ext.includes('ts')), + .map(ext => `.${ext}`) + .filter(ext => useTypeScript || !ext.includes('ts')), alias: { // Support React Native Web // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/ @@ -327,7 +344,10 @@ module.exports = function (webpackEnv) { // To fix this, we prevent you from importing files out of src/ -- if you'd like to, // please link the files into your node_modules/ and let module-resolution kick in. // Make sure your source files are compiled, as they will not be processed in any way. - new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson, reactRefreshOverlayEntry]), + new ModuleScopePlugin(paths.appSrc, [ + paths.appPackageJson, + reactRefreshOverlayEntry, + ]), ], }, resolveLoader: { @@ -376,7 +396,9 @@ module.exports = function (webpackEnv) { include: paths.appSrc, loader: require.resolve('babel-loader'), options: { - customize: require.resolve('babel-preset-react-app/webpack-overrides'), + customize: require.resolve( + 'babel-preset-react-app/webpack-overrides' + ), presets: [ [ require.resolve('babel-preset-react-app'), @@ -385,19 +407,22 @@ module.exports = function (webpackEnv) { }, ], ], - + plugins: [ [ require.resolve('babel-plugin-named-asset-import'), { loaderMap: { svg: { - ReactComponent: '@svgr/webpack?-svgo,+titleProp,+ref![path]', + ReactComponent: + '@svgr/webpack?-svgo,+titleProp,+ref![path]', }, }, }, ], - isEnvDevelopment && shouldUseReactRefresh && require.resolve('react-refresh/babel'), + isEnvDevelopment && + shouldUseReactRefresh && + require.resolve('react-refresh/babel'), ].filter(Boolean), // This is a feature of `babel-loader` for webpack (not Babel itself). // It enables caching results in ./node_modules/.cache/babel-loader/ @@ -418,11 +443,16 @@ module.exports = function (webpackEnv) { babelrc: false, configFile: false, compact: false, - presets: [[require.resolve('babel-preset-react-app/dependencies'), { helpers: true }]], + presets: [ + [ + require.resolve('babel-preset-react-app/dependencies'), + { helpers: true }, + ], + ], cacheDirectory: true, // See #6846 for context on why cacheCompression is disabled cacheCompression: false, - + // Babel sourcemaps are needed for debugging into node_modules // code. Without the options below, debuggers like VSCode // show incorrect code and set breakpoints on the wrong lines. @@ -442,7 +472,9 @@ module.exports = function (webpackEnv) { exclude: cssModuleRegex, use: getStyleLoaders({ importLoaders: 1, - sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment, + sourceMap: isEnvProduction + ? shouldUseSourceMap + : isEnvDevelopment, }), // Don't consider CSS imports dead code even if the // containing package claims to have no side effects. @@ -456,7 +488,9 @@ module.exports = function (webpackEnv) { test: cssModuleRegex, use: getStyleLoaders({ importLoaders: 1, - sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment, + sourceMap: isEnvProduction + ? shouldUseSourceMap + : isEnvDevelopment, modules: { getLocalIdent: getCSSModuleLocalIdent, }, @@ -471,9 +505,11 @@ module.exports = function (webpackEnv) { use: getStyleLoaders( { importLoaders: 3, - sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment, + sourceMap: isEnvProduction + ? shouldUseSourceMap + : isEnvDevelopment, }, - 'sass-loader', + 'sass-loader' ), // Don't consider CSS imports dead code even if the // containing package claims to have no side effects. @@ -488,12 +524,14 @@ module.exports = function (webpackEnv) { use: getStyleLoaders( { importLoaders: 3, - sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment, + sourceMap: isEnvProduction + ? shouldUseSourceMap + : isEnvDevelopment, modules: { getLocalIdent: getCSSModuleLocalIdent, }, }, - 'sass-loader', + 'sass-loader' ), }, // "file" loader makes sure those assets get served by WebpackDevServer. @@ -542,13 +580,15 @@ module.exports = function (webpackEnv) { minifyURLs: true, }, } - : undefined, - ), + : undefined + ) ), // Inlines the webpack runtime script. This script is too small to warrant // a network request. // https://github.com/facebook/create-react-app/issues/5358 - isEnvProduction && shouldInlineRuntimeChunk && new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime-.+[.]js/]), + isEnvProduction && + shouldInlineRuntimeChunk && + new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime-.+[.]js/]), // Makes some environment variables available in index.html. // The public URL is available as %PUBLIC_URL% in index.html, e.g.: // @@ -589,7 +629,8 @@ module.exports = function (webpackEnv) { // to restart the development server for webpack to discover it. This plugin // makes the discovery automatic so you don't have to restart. // See https://github.com/facebook/create-react-app/issues/186 - isEnvDevelopment && new WatchMissingNodeModulesPlugin(paths.appNodeModules), + isEnvDevelopment && + new WatchMissingNodeModulesPlugin(paths.appNodeModules), isEnvProduction && new MiniCssExtractPlugin({ // Options similar to the same options in webpackOptions.output @@ -611,7 +652,9 @@ module.exports = function (webpackEnv) { manifest[file.name] = file.path; return manifest; }, seed); - const entrypointFiles = entrypoints.main.filter((fileName) => !fileName.endsWith('.map')); + const entrypointFiles = entrypoints.main.filter( + fileName => !fileName.endsWith('.map') + ); return { files: manifestFiles, @@ -646,8 +689,12 @@ module.exports = function (webpackEnv) { }), async: isEnvDevelopment, checkSyntacticErrors: true, - resolveModuleNameModule: process.versions.pnp ? `${__dirname}/pnpTs.js` : undefined, - resolveTypeReferenceDirectiveModule: process.versions.pnp ? `${__dirname}/pnpTs.js` : undefined, + resolveModuleNameModule: process.versions.pnp + ? `${__dirname}/pnpTs.js` + : undefined, + resolveTypeReferenceDirectiveModule: process.versions.pnp + ? `${__dirname}/pnpTs.js` + : undefined, tsconfig: paths.appTsConfig, reportFiles: [ // This one is specifically to match during CI tests, @@ -674,7 +721,10 @@ module.exports = function (webpackEnv) { failOnError: !(isEnvDevelopment && emitErrorsAsWarnings), context: paths.appSrc, cache: true, - cacheLocation: path.resolve(paths.appNodeModules, '.cache/.eslintcache'), + cacheLocation: path.resolve( + paths.appNodeModules, + '.cache/.eslintcache' + ), // ESLint class options cwd: paths.appPath, resolvePluginsRelativeTo: __dirname, diff --git a/config/webpackDevServer.config.js b/config/webpackDevServer.config.js index 8d76f10..6c43a8a 100644 --- a/config/webpackDevServer.config.js +++ b/config/webpackDevServer.config.js @@ -32,7 +32,8 @@ module.exports = function (proxy, allowedHost) { // So we will disable the host check normally, but enable it if you have // specified the `proxy` setting. Finally, we let you override it if you // really know what you're doing with a special environment variable. - disableHostCheck: !proxy || process.env.DANGEROUSLY_DISABLE_HOST_CHECK === 'true', + disableHostCheck: + !proxy || process.env.DANGEROUSLY_DISABLE_HOST_CHECK === 'true', // Enable gzip compression of generated files. compress: true, // Silence WebpackDevServer's own logs since they're generally not useful. diff --git a/package.json b/package.json index 87d5d90..8bcc9ba 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,15 @@ { "name": "react-web-boilerplate", - "version": "1.1.0", + "version": "1.2.0", "private": true, "scripts": { "start": "node scripts/start.js", "build": "node scripts/build.js", "test": "node scripts/test.js", - "lint": "eslint ./src", - "lint:staged": "pretty-quick --staged && lint-staged", + "lint": "eslint --fix --max-warnings=0 './src/**/*.{js,jsx,ts,tsx}'", + "pre-commit": "yarn lint && lint-staged && yarn dependencies:checkCircular && yarn dependencies:graph", + "prettier:fix": "prettier --write ./src", + "prettier:check": "prettier --check ./src", "dependencies:checkCircular": "madge src/ --circular", "dependencies:graph": "madge src/ --circular --image deps-graph.svg", "start:development": "env-cmd -f src/env/.env.development yarn start", @@ -110,12 +112,10 @@ "workbox-webpack-plugin": "5.1.4" }, "lint-staged": { - "*.{ts,tsx}": "eslint --cache --fix" - }, - "husky": { - "hooks": { - "pre-commit": "yarn lint:staged && yarn dependencies:checkCircular && yarn dependencies:graph" - } + "src/**/*.{js,jsx,ts,tsx}": [ + "yarn prettier:fix", + "yarn prettier:check" + ] }, "madge": { "tsConfig": "./tsconfig.json", diff --git a/public/index.html b/public/index.html index 6a9f8c2..aa069f2 100644 --- a/public/index.html +++ b/public/index.html @@ -5,7 +5,10 @@ - +