This commit is contained in:
2020-05-25 16:07:30 +03:00
parent 0753359f07
commit 13971100cf
55 changed files with 32279 additions and 6964 deletions

View File

@@ -3,8 +3,10 @@ root = true
[*]
end_of_line = lf
insert_final_newline = true
[*.js]
charset = utf-8
trim_trailing_whitespace = true
indent_style = space
charset = utf-8
indent_size = 2
[*.md]
trim_trailing_whitespace = false

2
.gitignore vendored
View File

@@ -1,4 +1,2 @@
node_modules/
.vscode/
tmp/
.env

20
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,20 @@
{
"workbench.colorCustomizations": {
"activityBar.activeBackground": "#d04649",
"activityBar.activeBorder": "#37cb34",
"activityBar.background": "#d04649",
"activityBar.foreground": "#e7e7e7",
"activityBar.inactiveForeground": "#e7e7e799",
"activityBarBadge.background": "#37cb34",
"activityBarBadge.foreground": "#15202b",
"statusBar.background": "#b52e31",
"statusBar.border": "#b52e31",
"statusBar.foreground": "#e7e7e7",
"statusBarItem.hoverBackground": "#d04649",
"titleBar.activeBackground": "#b52e31",
"titleBar.activeForeground": "#e7e7e7",
"titleBar.border": "#b52e31",
"titleBar.inactiveBackground": "#b52e3199",
"titleBar.inactiveForeground": "#e7e7e799"
}
}

4
api/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
node_modules/
.vscode/
tmp/
.env

7118
api/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

39
api/package.json Normal file
View File

@@ -0,0 +1,39 @@
{
"name": "maanteeamet-fetch",
"version": "1.0.0",
"main": "index.js",
"engines": {
"node": "14.3.0"
},
"scripts": {
"start": "babel-node src/index.js",
"dev": "nodemon -r dotenv/config --watch src --exec babel-node src/index.js"
},
"dependencies": {
"cacheman": "2.2.1",
"cacheman-file": "0.2.1",
"compression": "1.7.4",
"dotenv": "8.2.0",
"express": "4.17.1",
"form-data": "3.0.0",
"helmet": "^3.22.0",
"jsdom": "16.2.2",
"node-fetch": "2.6.0",
"puppeteer": "3.1.0"
},
"devDependencies": {
"@babel/cli": "7.8.4",
"@babel/core": "7.9.6",
"@babel/node": "7.8.7",
"@babel/plugin-proposal-class-properties": "7.8.3",
"@babel/preset-env": "7.9.6",
"babel-eslint": "10.1.0",
"eslint": "^6.8.0",
"eslint-config-airbnb": "18.1.0",
"eslint-plugin-import": "2.20.2",
"eslint-plugin-jsx-a11y": "6.2.3",
"eslint-plugin-react": "7.20.0",
"eslint-plugin-react-hooks": "2.5.0",
"nodemon": "2.0.4"
}
}

View File

@@ -1,8 +1,10 @@
import express from 'express';
import http from 'http';
import compression from 'compression';
import helmet from 'helmet';
import Hack from '../components/Hack';
const PORT = 3000;
const PORT = process.env.PORT || "8000";
class BasicApi {
app;
@@ -11,6 +13,8 @@ class BasicApi {
constructor() {
this.app = express();
this.app.use(compression());
this.app.use(helmet());
this.server = http.createServer(this.app);
this.hack = new Hack();
}

View File

Before

Width:  |  Height:  |  Size: 469 KiB

After

Width:  |  Height:  |  Size: 469 KiB

29
deploy/ftp.js Normal file
View File

@@ -0,0 +1,29 @@
const FtpDeploy = require("ftp-deploy");
const ftpDeploy = new FtpDeploy();
const config = {
user: process.env.FTP_USER,
password: process.env.FTP_PASSWORD,
host: process.env.FTP_HOST,
port: process.env.FTP_PORT,
localRoot: __dirname + "/../frontend",
remoteRoot: "/public_html/car/",
// include: ["*", "**/*"], // this would upload everything except dot files
include: ["build/**"],
// e.g. exclude sourcemaps, and ALL files in node_modules (including dot files)
exclude: ["build/**/*.map", "node_modules/**", "node_modules/**/.*", ".git/**"],
// delete ALL existing files at destination before uploading, if true
deleteRemote: false,
// Passive mode is forced (EPSV command is not sent)
forcePasv: true
};
ftpDeploy
.deploy(config)
.then(res => {
console.log("Deployment to FTP finished");
return;
})
.catch((err) => {
console.log(err);
});

61
frontend/.babelrc.js Normal file
View File

@@ -0,0 +1,61 @@
module.exports = (api) => {
api.cache(true);
return {
sourceType: 'module',
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: 3,
}
],
[
'@babel/preset-react',
{
development: process.env.NODE_ENV === 'development',
}
]
],
plugins: [
'@babel/plugin-proposal-optional-chaining',
[
'@babel/plugin-proposal-decorators',
{
legacy: true
}
],
'@babel/plugin-proposal-function-sent',
'@babel/plugin-proposal-export-namespace-from',
'@babel/plugin-proposal-numeric-separator',
'@babel/plugin-proposal-throw-expressions',
// Stage 3
'@babel/plugin-syntax-dynamic-import',
'@babel/plugin-syntax-import-meta',
[
'@babel/plugin-proposal-class-properties',
{
loose: true
}
],
'@babel/plugin-proposal-json-strings',
[
'module-resolver', {
root: [
'./src'
],
alias: {
'@slice': './src/slice',
'@util': './src/util',
'@container': './src/container',
'@style': './src/style',
'@constant': './src/constant',
'@context': './src/context',
'@components': './src/components',
'@hook': './src/hook',
'@assets': './assets',
}
}]
],
};
}

4
frontend/.browserslistrc Normal file
View File

@@ -0,0 +1,4 @@
> 1%
not dead
not ie <12
Firefox ESR

1
frontend/.eslintignore Normal file
View File

@@ -0,0 +1 @@
webpack/**

129
frontend/.eslintrc.js Normal file
View File

@@ -0,0 +1,129 @@
module.exports = {
root: true,
parser: 'babel-eslint',
parserOptions: {
ecmaVersion: 2019,
sourceType: 'module',
ecmaFeatures: {
jsx: true,
},
},
settings: {
react: {
version: 'detect',
},
'import/resolver': {
// resolves aliases from .babelrc automatically
'babel-module': {},
},
},
env: {
es6: true,
browser: true,
node: true,
},
plugins: [
'react',
'jsx-a11y',
],
extends: [
'airbnb',
'airbnb/hooks',
'plugin:react/recommended',
],
globals: {
React: true,
document: true,
window: true,
localStorage: true,
fetch: true,
},
rules: {
'babel/object-curly-spacing': 0,
'class-methods-use-this': 0,
indent: [
'error',
2,
],
'jsx-a11y/anchor-is-valid': [
'warn',
{
aspects: [
'invalidHref',
],
},
],
'jsx-a11y/href-no-hash': 'off',
'no-trailing-spaces': [
2,
{
skipBlankLines: true,
},
],
'prefer-template': 0,
'react/jsx-boolean-value': [
'warn',
'never',
],
'react/jsx-closing-bracket-location': [
'warn',
'after-props',
],
'react/jsx-curly-spacing': [
'warn',
'never',
],
'react/jsx-filename-extension': [
'warn',
{
extensions: [
'.jsx',
],
},
],
'react/jsx-first-prop-new-line': [
'warn',
'multiline',
],
'react/jsx-handler-names': [
'warn',
{
eventHandlerPrefix: 'handle',
eventHandlerPropPrefix: 'on',
},
],
'react/jsx-indent': [
2,
2,
],
'react/jsx-key': 'error',
'react/jsx-wrap-multilines': [
'warn',
],
'react/prop-types': 0,
'react/self-closing-comp': [
'warn',
{
component: true,
html: false,
},
],
'react/sort-comp': [
1,
{
groups: {
rendering: [
'/^render.+$/',
'render',
],
},
order: [
'everything-else',
'lifecycle',
'rendering',
'static-methods',
],
},
],
},
};

2
frontend/.gitattributes vendored Normal file
View File

@@ -0,0 +1,2 @@
package-lock.json -diff
yarn.lock -diff

23
frontend/.gitignore vendored Normal file
View File

@@ -0,0 +1,23 @@
# Cruft
*~
*#
.#*
.DS_Store
# Test
coverage
.eslintcache
# Logs
*.log
# npm & yarn
node_modules/
.npm
.yarn-integrity
build/*
# Editor/IDE
.idea
.vscode
packages/api/etc/

5
frontend/README.md Normal file
View File

@@ -0,0 +1,5 @@
# React Base
[![Release](https://img.shields.io/github/release/Naereen/StrapDown.js.svg)](https://github.com/k4rli/react-base/releases)
[![GitHub commits](https://img.shields.io/github/commits-since/Naereen/StrapDown.js/v1.0.0.svg)](https://github.com/k4rli/react-base/commit/)
[![GitHub contributors](https://img.shields.io/github/contributors/Naereen/StrapDown.js.svg)](https://github.com/k4rli/react-base/graphs/contributors/)

View File

10
frontend/jsconfig.json Normal file
View File

@@ -0,0 +1,10 @@
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@*":[
"src/*"
]
}
}
}

8
frontend/nodemon.json Normal file
View File

@@ -0,0 +1,8 @@
{
"watch": [
"webpack/webpack.common.js",
"webpack/webpack.dev.js",
".babelrc.js",
"package-lock.json"
]
}

14628
frontend/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

95
frontend/package.json Normal file
View File

@@ -0,0 +1,95 @@
{
"name": "react-base",
"version": "0.0.1",
"description": "Base React template",
"main": "index.js",
"scripts": {
"start": "nodemon --exec \"cross-env NODE_ENV=development webpack-dev-server\"",
"prebundle": "rimraf build/*",
"bundle": "cross-env NODE_ENV=production webpack",
"cacheclean": "rimraf node_modules/.cache/hard-source",
"precommit": "lint-staged",
"lint": "eslint --fix src --ext .jsx"
},
"author": "k4rli",
"contributors": [],
"keywords": [
"react",
"reactjs",
"react-boilerplate"
],
"license": "MIT",
"engines": {
"node": ">=11",
"npm": ">=6"
},
"lint-staged": {
"*.{js,jsx,css,md}": [
"eslint --fix",
"git add"
]
},
"dependencies": {
"@reduxjs/toolkit": "1.3.6",
"core-js": "3.6.5",
"react": "16.13.1",
"react-dom": "16.13.1",
"react-hot-loader": "4.12.21",
"react-webcam": "5.0.2",
"regenerator-runtime": "0.13.5",
"use-dark-mode": "2.3.1"
},
"devDependencies": {
"@babel/core": "7.9.6",
"@babel/plugin-proposal-class-properties": "7.8.3",
"@babel/plugin-proposal-decorators": "7.8.3",
"@babel/plugin-proposal-export-namespace-from": "7.8.3",
"@babel/plugin-proposal-function-sent": "7.8.3",
"@babel/plugin-proposal-json-strings": "7.8.3",
"@babel/plugin-proposal-numeric-separator": "7.8.3",
"@babel/plugin-proposal-optional-chaining": "7.9.0",
"@babel/plugin-proposal-throw-expressions": "7.8.3",
"@babel/plugin-syntax-dynamic-import": "7.8.3",
"@babel/plugin-syntax-import-meta": "7.8.3",
"@babel/plugin-transform-runtime": "7.9.6",
"@babel/preset-env": "7.9.6",
"@babel/preset-react": "7.9.4",
"@babel/register": "7.9.0",
"@babel/runtime-corejs3": "7.9.6",
"babel-eslint": "10.1.0",
"babel-loader": "8.1.0",
"babel-plugin-module-resolver": "4.0.0",
"browserslist": "4.12.0",
"connect-history-api-fallback": "1.6.0",
"copy-webpack-plugin": "6.0.1",
"cross-env": "7.0.2",
"css-loader": "3.5.3",
"eslint": "7.0.0",
"eslint-config-airbnb": "18.1.0",
"eslint-import-resolver-babel-module": "5.1.2",
"eslint-loader": "4.0.2",
"eslint-plugin-import": "2.20.2",
"eslint-plugin-jsx-a11y": "6.2.3",
"eslint-plugin-react": "7.20.0",
"eslint-plugin-react-hooks": "4.0.2",
"file-loader": "6.0.0",
"hard-source-webpack-plugin": "0.13.1",
"html-webpack-plugin": "4.3.0",
"koa-connect": "2.0.1",
"lint-staged": "10.2.2",
"mini-css-extract-plugin": "0.9.0",
"node-sass": "4.14.1",
"nodemon": "2.0.4",
"optimize-css-assets-webpack-plugin": "5.0.3",
"rimraf": "3.0.2",
"sass-loader": "8.0.2",
"script-ext-html-webpack-plugin": "2.1.4",
"style-loader": "1.2.1",
"terser-webpack-plugin": "3.0.1",
"webpack": "4.43.0",
"webpack-bundle-analyzer": "3.7.0",
"webpack-cli": "3.3.11",
"webpack-dev-server": "3.11.0",
"webpack-merge": "4.2.2"
}
}

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>&#x1F615;</title>
<link type="text/css" rel="stylesheet" href="./assets/css/skeleton.min.css" />
<link type="text/css" rel="stylesheet" href="https://fonts.googleapis.com/css?family=Inconsolata&display=swap">
<link rel="apple-touch-icon" sizes="180x180" href="./assets/images/icon.png">
<link rel="icon" type="image/png" sizes="64x64" href="./assets/images/icon.png">
</head>
<body>
<div id="root"></div>
</body>
</html>

View File

@@ -0,0 +1,12 @@
export default {
STORE_KEY: 'data',
DARK_MODE: {
CLASSNAME: {
Dark: 'dark',
Light: 'light',
},
STORE: {
Key: 'theme',
},
},
};

View File

@@ -0,0 +1,27 @@
import React, { useReducer, useContext } from 'react';
import { usePersistedContext, usePersistedReducer } from '@hook/usePersist';
import RootContainer from '@container/RootContainer';
import RootContext from '@context/RootContext';
import RootReducer from '@slice/RootSlice';
import Properties from '@constant/Properties';
const App = () => {
const globalStore = usePersistedContext(
useContext(RootContext),
Properties.STORE_KEY,
);
const [state, dispatch] = usePersistedReducer(
useReducer(RootReducer, globalStore),
Properties.STORE_KEY,
);
return (
<RootContext.Provider value={{ state, dispatch }}>
<RootContainer />
</RootContext.Provider>
);
};
export default App;

View File

@@ -0,0 +1,91 @@
import React, {
useState, useRef, useEffect, useCallback,
} from 'react';
import Webcam from 'react-webcam';
import '@style/RootContainer';
const RootContainer = () => {
const webcamRef = useRef(null);
const [videoInputs, setVideoInputs] = useState([]);
const [resetCameraView, setResetCameraView] = useState(false);
const [videoConstraints, setVideoConstraints] = useState({
facingMode: { exact: 'environment' },
});
const [imgSrc, setImgSrc] = useState(null);
const capture = useCallback(() => {
const imageSrc = webcamRef.current.getScreenshot();
setImgSrc(imageSrc);
}, [webcamRef, setImgSrc]);
useEffect(() => {
const gotDevices = (mediaDevices) => new Promise((resolve, reject) => {
const availableVideoInputs = [];
mediaDevices.forEach((mediaDevice) => {
if (mediaDevice.kind === 'videoinput') {
availableVideoInputs.push({
deviceId: mediaDevice.deviceId,
label: mediaDevice.label,
});
}
});
if (availableVideoInputs.length > 0) {
resolve(availableVideoInputs);
} else {
reject(new Error('ERR::NO_MEDIA_TO_STREAM'));
}
});
navigator.mediaDevices
.enumerateDevices()
.then(gotDevices)
.then((availableVideoInputs) => setVideoInputs({ availableVideoInputs }))
.catch((err) => console.error(err));
}, []);
const changeCameraView = () => {
if (videoInputs.length === 1) {
return console.error('ERR::AVAILABLE_MEDIA_STREAMS_IS_1');
}
setResetCameraView(true);
setTimeout(() => {
const { facingMode } = videoConstraints;
const newFacingMode = facingMode === 'user' ? { exact: 'environment' } : 'user';
setResetCameraView(false);
setVideoConstraints({ ...videoConstraints, facingMode: newFacingMode });
}, 100);
};
return (
<>
{resetCameraView ? (
'Loading...'
) : (
<Webcam
audio={false}
height="100%"
ref={webcamRef}
screenshotFormat="image/png"
minScreenshotWidth={1080}
minScreenshotHeight={1920}
screenshotQuality={1}
width="100%"
videoConstraints={videoConstraints} />
)}
<button type="button" onClick={changeCameraView}>
Switch camera
</button>
<button type="button" onClick={capture}>
Take image
</button>
{imgSrc && (<img src={imgSrc} />)}
</>
);
};
export default RootContainer;

View File

@@ -0,0 +1,3 @@
import { createContext } from 'react';
export default createContext({}); // include initialStates here

View File

@@ -0,0 +1,23 @@
import { useEffect, useRef } from 'react';
// https://overreacted.io/making-setinterval-declarative-with-react-hooks/
const useInterval = (callback, delay) => {
const savedCallback = useRef();
// Remember the latest callback.
useEffect(() => {
savedCallback.current = callback;
}, [callback]);
// Set up the interval.
useEffect(() => {
const tick = () => savedCallback.current();
if (delay !== null) {
const id = setInterval(tick, delay);
return () => clearInterval(id);
}
return () => {};
}, [delay]);
};
export default useInterval;

View File

@@ -0,0 +1,16 @@
import { useEffect } from 'react';
const DEFAULT_STATE_KEY = 'state';
export const usePersistedContext = (context, key = DEFAULT_STATE_KEY) => {
const persistedContext = localStorage.getItem(key);
return persistedContext ? JSON.parse(persistedContext) : context;
};
export const usePersistedReducer = ([state, dispatch], key = DEFAULT_STATE_KEY) => {
useEffect(
() => localStorage.setItem(key, JSON.stringify(state)),
[key, state],
);
return [state, dispatch];
};

6
frontend/src/index.jsx Normal file
View File

@@ -0,0 +1,6 @@
import React from 'react';
import { render } from 'react-dom';
import App from '@container/App';
render(<App />, document.getElementById('root'));

View File

@@ -0,0 +1,3 @@
import { combineReducers } from '@reduxjs/toolkit';
export default combineReducers({}); // include slices here

View File

@@ -0,0 +1,10 @@
@import 'palette.scss';
@import 'constants.scss';
body {
margin: 0;
font-family: 'Roboto';
overflow-x: hidden;
width: 100vw;
height: 100vh;
}

View File

@@ -0,0 +1,2 @@
$asset_dir: '../../assets';
$fonts_dir: '../../assets/fonts';

View File

View File

@@ -0,0 +1,14 @@
const webpackMerge = require('webpack-merge');
const common = require('./webpack/webpack.common');
const Environment = require('./webpack/webpack.common');
const envs = {
development: 'dev',
production: 'prod',
};
/* eslint-disable global-require,import/no-dynamic-require */
const env = envs[process.env.NODE_ENV || Environment.development];
const envConfig = require(`./webpack/webpack.${env}.js`);
module.exports = webpackMerge(common, envConfig);

View File

@@ -0,0 +1,4 @@
module.exports = {
development: 'development',
production: 'production',
};

20
frontend/webpack/paths.js Normal file
View File

@@ -0,0 +1,20 @@
const path = require('path');
const root = '../';
module.exports = {
root: path.resolve(__dirname, root),
outputPath: path.resolve(__dirname, root, 'build'),
entryPath: path.resolve(__dirname, root, 'src/index.jsx'),
source: path.resolve(__dirname, root, 'src/'),
templatePath: path.resolve(__dirname, root, 'public/template.html'),
cachePath: path.join(process.cwd(), 'node_modules/.cache/hard-source/', '[confighash]'),
publicPath: './',
assetPath: 'assets',
assetOriginPath: 'public/assets/',
scriptsPath: 'scripts',
imagesFolder: 'images',
fontsFolder: 'fonts',
cssFolder: 'css',
jsFolder: 'js',
};

View File

@@ -0,0 +1,88 @@
/* eslint-disable import/no-extraneous-dependencies */
const { ProgressPlugin } = require('webpack');
const convert = require('koa-connect');
const history = require('connect-history-api-fallback');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const commonPaths = require('./paths');
const Environment = require('./Environment');
module.exports = {
mode: Environment[process.env.NODE_ENV],
entry: commonPaths.entryPath,
module: {
rules: [
{
test: /\.(js|jsx)$/,
loader: 'babel-loader',
exclude: /(node_modules)/,
options: {
presets: ['@babel/preset-env'],
},
},
{
enforce: 'pre',
test: /\.(js|jsx)$/,
loader: 'eslint-loader',
exclude: /(node_modules)/,
options: {
// emitWarning: process.env.NODE_ENV !== Environment.production,
emitWarning: true,
},
},
{
test: /\.(png|jpg|gif|svg)$/,
use: [
{
loader: 'file-loader',
options: {
outputPath: commonPaths.imagesFolder,
},
},
],
},
{
test: /\.(woff2|ttf|woff|eot)$/,
use: [
{
loader: 'file-loader',
options: {
outputPath: commonPaths.fontsFolder,
},
},
],
},
],
},
serve: {
add: (app) => {
app.use(convert(history()));
},
content: commonPaths.entryPath,
dev: {
publicPath: commonPaths.outputPath,
},
open: false,
},
resolve: {
modules: ['src', 'node_modules'],
extensions: ['*', '.js', '.jsx', '.css', '.scss'],
},
plugins: [
new ProgressPlugin(),
new HtmlWebpackPlugin({
template: commonPaths.templatePath,
}),
new ScriptExtHtmlWebpackPlugin({
defaultAttribute: 'async',
}),
new CopyWebpackPlugin({
patterns: [{
from: commonPaths.assetOriginPath,
to: commonPaths.assetPath,
}],
}),
],
};

View File

@@ -0,0 +1,92 @@
/* eslint-disable import/no-extraneous-dependencies */
const { HotModuleReplacementPlugin } = require('webpack');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
const commonPaths = require('./paths');
module.exports = {
devtool: 'cheap-eval-source-map',
output: {
filename: '[name].js',
path: commonPaths.outputPath,
chunkFilename: '[name].js',
},
module: {
rules: [
{
test: /\.(js|jsx)$/, // allows both .jsx and .js
exclude: /node_modules/,
include: commonPaths.source,
loader: 'babel-loader',
options: {
cacheDirectory: true,
plugins: ['react-hot-loader/babel'],
},
},
{
test: /\.(sa|sc|c)ss$/,
use: [{
loader: 'style-loader',
},
{
loader: 'css-loader',
options: {
modules: false,
},
},
{
loader: 'sass-loader',
},
],
},
],
},
devServer: {
contentBase: commonPaths.outputPath,
compress: true,
hot: true,
port: 3001,
},
plugins: [
new HotModuleReplacementPlugin(),
new HardSourceWebpackPlugin({
// Either an absolute path or relative to webpack's options.context.
cacheDirectory: commonPaths.cachePath,
// Either a string of object hash function given a webpack config.
// node-object-hash on npm can be used to build this.
configHash: (webpackConfig) => require('node-object-hash')({ // eslint-disable-line
sort: false,
}).hash(webpackConfig),
// Either false, a string, an object, or a project hashing function.
environmentHash: {
root: process.cwd(),
directories: [],
files: [
// Cache will get an unique hash based on those files
// if either of them changes, new cache must be generated
'package-lock.json',
'.babelrc.js',
],
},
info: {
mode: 'none',
level: 'debug',
},
// Clean up large, old caches automatically.
cachePrune: {
// Caches younger than `maxAge` are not considered for deletion.
// They must be at least this old in milliseconds.
maxAge: 3 * 60 * 60 * 1000, // 3 hours
// All caches together must be larger than `sizeThreshold` before any
// caches will be deleted.
// Together they must be at least this big in bytes.
sizeThreshold: 50 * 1024 * 1024, // 50 MB
},
}),
new BundleAnalyzerPlugin({
analyzerPort: 8888,
openAnalyzer: false,
}),
],
};

View File

@@ -0,0 +1,98 @@
/* eslint-disable import/no-extraneous-dependencies */
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const commonPaths = require('./paths');
module.exports = {
output: {
publicPath: commonPaths.publicPath,
filename: `${commonPaths.scriptsPath}/${commonPaths.jsFolder}/[name].[hash].js`,
path: commonPaths.outputPath,
chunkFilename: `${commonPaths.scriptsPath}/${commonPaths.jsFolder}/[name].[chunkHash].js`,
},
module: {
rules: [
{
test: /\.(js|jsx)$/, // allows both .jsx and .js
exclude: /node_modules/,
include: commonPaths.source,
use: [
{
loader: 'babel-loader',
},
],
},
{
test: /\.(sa|sc|c)ss$/,
enforce: 'pre',
use: [{
loader: MiniCssExtractPlugin.loader,
},
{
loader: 'css-loader',
options: {
modules: false,
},
},
{
loader: 'sass-loader',
},
],
},
],
},
optimization: {
usedExports: true, // to remove unused exports
splitChunks: {
chunks: 'all',
automaticNameDelimiter: '.',
minSize: 30000,
},
noEmitOnErrors: true,
minimize: true,
minimizer: [
new TerserPlugin({
parallel: true, // use multi-process parallel running to improve the build speed
sourceMap: false, // set to true if you want JS source maps
terserOptions: {
mangle: true, // pass false to skip mangling names
toplevel: false, // set to true if you wish to enable top level variable and function name mangling and to drop unused variables and functions
ie8: false, // set to true to support IE8.
keep_fnames: false, // pass true to prevent discarding or mangling of function names
output: {
comments: false,
},
},
}),
new OptimizeCSSAssetsPlugin({
assetNameRegExp: /\.css$/g,
cssProcessorPluginOptions: {
preset: [
'default',
{
discardComments: {
removeAll: true,
},
},
],
},
canPrint: true,
}),
],
},
plugins: [
new MiniCssExtractPlugin({
filename: `${commonPaths.assetPath}/${commonPaths.cssFolder}/[name].css`,
chunkFilename: '[id].css',
}),
new BundleAnalyzerPlugin({
generateStatsFile: true,
reportFilename: 'bundleReport.html',
analyzerMode: 'static',
}),
],
};

9399
frontend/yarn.lock Normal file

File diff suppressed because it is too large Load Diff

6895
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,33 +1,13 @@
{
"name": "maanteeamet-fetch",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "nodemon -r dotenv/config --watch src --exec babel-node src/index.js"
},
"dependencies": {
"cacheman": "2.2.1",
"cacheman-file": "0.2.1",
"dotenv": "8.2.0",
"express": "4.17.1",
"form-data": "3.0.0",
"jsdom": "16.2.2",
"node-fetch": "2.6.0",
"puppeteer": "3.1.0"
"deploy": "node -r dotenv/config deploy/ftp.js"
},
"devDependencies": {
"@babel/cli": "7.8.4",
"@babel/core": "7.9.6",
"@babel/node": "7.8.7",
"@babel/plugin-proposal-class-properties": "7.8.3",
"@babel/preset-env": "7.9.6",
"babel-eslint": "10.1.0",
"eslint": "^6.8.0",
"eslint-config-airbnb": "18.1.0",
"eslint-plugin-import": "2.20.2",
"eslint-plugin-jsx-a11y": "6.2.3",
"eslint-plugin-react": "7.20.0",
"eslint-plugin-react-hooks": "2.5.0",
"nodemon": "2.0.4"
"dotenv": "8.2.0",
"ftp-deploy": "2.3.7"
}
}