build: upgrade to webpack 5
This commit is contained in:
parent
2ad0217ee4
commit
9b52b33180
10 changed files with 1725 additions and 1165 deletions
|
@ -5,7 +5,7 @@ const presets = [
|
|||
modules: false,
|
||||
// see also zloirock/core-js https://bit.ly/2JLnrgw
|
||||
useBuiltIns: 'usage',
|
||||
corejs: 3,
|
||||
corejs: '3.6',
|
||||
// new in babel 7.9.0 https://babeljs.io/blog/2020/03/16/7.9.0
|
||||
bugfixes: true,
|
||||
},
|
||||
|
|
16
package.json
16
package.json
|
@ -5,7 +5,7 @@
|
|||
"scripts": {
|
||||
"lint": "eslint --fix --cache src",
|
||||
"start": "NODE_ENV=development node server.js",
|
||||
"build": "NODE_ENV=production webpack -p --progress",
|
||||
"build": "NODE_ENV=production webpack --progress",
|
||||
"pretty": "prettier --single-quote --write 'src/**/*.{js,scss}'"
|
||||
},
|
||||
"husky": {
|
||||
|
@ -41,7 +41,7 @@
|
|||
"date-fns": "^2.16.0",
|
||||
"fontsource-open-sans": "^3.0.9",
|
||||
"fontsource-roboto-mono": "^3.0.3",
|
||||
"framer-motion": "^2.8.0",
|
||||
"framer-motion": "^2.9.0",
|
||||
"history": "^5.0.0",
|
||||
"immer": "^7.0.9",
|
||||
"invariant": "^2.2.4",
|
||||
|
@ -76,12 +76,11 @@
|
|||
"@babel/preset-flow": "^7.7.4",
|
||||
"@babel/preset-react": "^7.7.4",
|
||||
"@babel/preset-typescript": "^7.10.1",
|
||||
"@hsjs/react-refresh-webpack-plugin": "^0.1.3",
|
||||
"@pmmmwh/react-refresh-webpack-plugin": "^0.4.2",
|
||||
"@types/invariant": "^2.2.33",
|
||||
"@types/jest": "^26.0.14",
|
||||
"@types/lodash-es": "^4.17.3",
|
||||
"@types/react": "^16.9.51",
|
||||
"@types/react": "^16.9.52",
|
||||
"@types/react-dom": "^16.9.8",
|
||||
"@typescript-eslint/eslint-plugin": "^4.4.0",
|
||||
"@typescript-eslint/parser": "^4.4.0",
|
||||
|
@ -91,6 +90,7 @@
|
|||
"clean-webpack-plugin": "^3.0.0",
|
||||
"copy-webpack-plugin": "^6.2.1",
|
||||
"css-loader": "^4.3.0",
|
||||
"css-minimizer-webpack-plugin": "^1.1.5",
|
||||
"cssnano": "^4.1.7",
|
||||
"eslint": "^7.11.0",
|
||||
"eslint-config-airbnb-base": "^14.1.0",
|
||||
|
@ -110,7 +110,7 @@
|
|||
"html-webpack-plugin": "^4.5.0",
|
||||
"husky": "^4.3.0",
|
||||
"lint-staged": "^10.4.0",
|
||||
"mini-css-extract-plugin": "^0.12.0",
|
||||
"mini-css-extract-plugin": "^1.0.0",
|
||||
"postcss": "^8.1.1",
|
||||
"postcss-custom-media": "^7.0.8",
|
||||
"postcss-extend-rule": "^3.0.0",
|
||||
|
@ -121,13 +121,13 @@
|
|||
"prettier": "^2.1.2",
|
||||
"react-refresh": "^0.8.2",
|
||||
"resize-observer-polyfill": "^1.5.1",
|
||||
"style-loader": "^1.3.0",
|
||||
"style-loader": "^2.0.0",
|
||||
"terser-webpack-plugin": "^4.2.3",
|
||||
"ts-loader": "^8.0.4",
|
||||
"typescript": "4.1.0-beta",
|
||||
"webpack": "^4.44.2",
|
||||
"webpack": "^5.0.0",
|
||||
"webpack-bundle-analyzer": "^3.9.0",
|
||||
"webpack-cli": "^3.3.12",
|
||||
"webpack-cli": "^4.0.0",
|
||||
"webpack-dev-middleware": "^3.7.2",
|
||||
"webpack-hot-middleware": "^2.22.2"
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const config = require('./webpack.config');
|
||||
const webpack = require('webpack');
|
||||
|
@ -12,7 +10,7 @@ const hotMiddleware = require('webpack-hot-middleware');
|
|||
const { PORT } = process.env;
|
||||
const port = PORT ? Number(PORT) : 3000;
|
||||
|
||||
config.entry.app.unshift('webpack-hot-middleware/client');
|
||||
config.entry.app.import.unshift('webpack-hot-middleware/client');
|
||||
config.plugins.push(
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
new webpack.NoEmitOnErrorsPlugin()
|
||||
|
@ -29,7 +27,7 @@ const stats = {
|
|||
cached: false,
|
||||
cachedAssets: false,
|
||||
chunks: false,
|
||||
chunkModules: false
|
||||
chunkModules: false,
|
||||
};
|
||||
|
||||
const options = { publicPath, stats };
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { motion } from 'framer-motion';
|
||||
import React from 'react';
|
||||
import ResizeObserver from 'resize-observer-polyfill';
|
||||
|
||||
import { framerMotionResouce } from '../misc/motion';
|
||||
|
||||
const { memo, useState, useRef, useEffect } = React;
|
||||
|
||||
function usePrevious(value) {
|
||||
|
@ -50,6 +51,8 @@ const variantsCollpapsibleChildContainer = {
|
|||
};
|
||||
|
||||
const Collapsible = memo(({ children, isOpen }) => {
|
||||
const module = framerMotionResouce.read();
|
||||
const motion = module.motion;
|
||||
const previous = usePrevious(isOpen);
|
||||
const [refToMeature, { height }] = useMeasure();
|
||||
return (
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import cx from 'clsx';
|
||||
import { motion } from 'framer-motion';
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import { Info } from 'react-feather';
|
||||
|
@ -13,6 +12,7 @@ import {
|
|||
} from 'react-icons/fc';
|
||||
import { Link, useLocation } from 'react-router-dom';
|
||||
|
||||
import { framerMotionResouce } from '../misc/motion';
|
||||
import { getTheme, switchTheme } from '../store/app';
|
||||
import s from './SideBar.module.css';
|
||||
import { connect } from './StateProvider';
|
||||
|
@ -130,6 +130,8 @@ function SideBar({ dispatch, theme }) {
|
|||
}
|
||||
|
||||
function MoonA() {
|
||||
const module = framerMotionResouce.read();
|
||||
const motion = module.motion;
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
@ -153,6 +155,9 @@ function MoonA() {
|
|||
}
|
||||
|
||||
function Sun() {
|
||||
const module = framerMotionResouce.read();
|
||||
const motion = module.motion;
|
||||
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { formatDistance } from 'date-fns';
|
||||
import { motion } from 'framer-motion';
|
||||
import * as React from 'react';
|
||||
import { RotateCw, Zap } from 'react-feather';
|
||||
|
||||
import { framerMotionResouce } from '../../misc/motion';
|
||||
import {
|
||||
getClashAPIConfig,
|
||||
getCollapsibleIsOpen,
|
||||
|
@ -117,6 +117,8 @@ const arrow = {
|
|||
hover: { rotate: 360, transition: { duration: 0.3 } },
|
||||
};
|
||||
function Refresh() {
|
||||
const module = framerMotionResouce.read();
|
||||
const motion = module.motion;
|
||||
return (
|
||||
<motion.div
|
||||
className={s.refresh}
|
||||
|
|
45
src/misc/createResource.ts
Normal file
45
src/misc/createResource.ts
Normal file
|
@ -0,0 +1,45 @@
|
|||
// from https://gist.github.com/ryanflorence/e10cc9dbc0e259759ec942ba82e5b57c
|
||||
export function createResource(getPromise: (key: string) => Promise<any>) {
|
||||
let cache = {};
|
||||
const inflight = {};
|
||||
const errors = {};
|
||||
|
||||
function load(key = 'default') {
|
||||
inflight[key] = getPromise(key)
|
||||
.then((val) => {
|
||||
delete inflight[key];
|
||||
cache[key] = val;
|
||||
})
|
||||
.catch((error) => {
|
||||
errors[key] = error;
|
||||
});
|
||||
return inflight[key];
|
||||
}
|
||||
|
||||
function preload(key = 'default') {
|
||||
if (cache[key] !== undefined || inflight[key]) return;
|
||||
load(key);
|
||||
}
|
||||
|
||||
function read(key = 'default') {
|
||||
if (cache[key] !== undefined) {
|
||||
return cache[key];
|
||||
} else if (errors[key]) {
|
||||
throw errors[key];
|
||||
} else if (inflight[key]) {
|
||||
throw inflight[key];
|
||||
} else {
|
||||
throw load(key);
|
||||
}
|
||||
}
|
||||
|
||||
function clear(key: 'default') {
|
||||
if (key) {
|
||||
delete cache[key];
|
||||
} else {
|
||||
cache = {};
|
||||
}
|
||||
}
|
||||
|
||||
return { preload, read, clear };
|
||||
}
|
5
src/misc/motion.ts
Normal file
5
src/misc/motion.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
import { createResource } from './createResource';
|
||||
|
||||
export const framerMotionResouce = createResource(
|
||||
() => import('framer-motion')
|
||||
);
|
|
@ -7,6 +7,7 @@ const CopyPlugin = require('copy-webpack-plugin');
|
|||
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
||||
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
|
||||
const ForkTsCheckerNotifierWebpackPlugin = require('fork-ts-checker-notifier-webpack-plugin');
|
||||
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
|
||||
|
||||
|
@ -47,7 +48,6 @@ const postcssPlugins = () =>
|
|||
require('postcss-nested')(),
|
||||
require('autoprefixer')(),
|
||||
require('postcss-extend-rule')(),
|
||||
isDev ? false : require('cssnano')(),
|
||||
].filter(Boolean);
|
||||
|
||||
const postcssOptions = { plugins: postcssPlugins() };
|
||||
|
@ -74,7 +74,7 @@ const plugins = [
|
|||
new CleanWebpackPlugin(),
|
||||
// chart.js requires moment
|
||||
// and we don't need locale stuff in moment
|
||||
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
|
||||
new webpack.IgnorePlugin({ resourceRegExp: /(^\.\/locale$)|(moment$)/ }),
|
||||
// https://github.com/pmmmwh/react-refresh-webpack-plugin
|
||||
isDev
|
||||
? new ReactRefreshWebpackPlugin({
|
||||
|
@ -93,8 +93,10 @@ module.exports = {
|
|||
// https://webpack.js.org/configuration/devtool/
|
||||
devtool: isDev ? 'eval-source-map' : 'source-map',
|
||||
entry: {
|
||||
// app: ['react-hot-loader/patch', './src/app.js']
|
||||
app: ['./src/app.js'],
|
||||
app: { import: ['./src/app.js'], dependOn: 'libs' },
|
||||
libs: { import: ['react-query', 'react-modal'], dependOn: 'vendor' },
|
||||
vendor: { import: ['react', 'react-dom'], dependOn: 'corejs' },
|
||||
corejs: { import: 'core-js' },
|
||||
},
|
||||
context: __dirname,
|
||||
output: {
|
||||
|
@ -111,6 +113,14 @@ module.exports = {
|
|||
},
|
||||
module: {
|
||||
rules: [
|
||||
// to work around "Module not found" issue for babel runtime imports
|
||||
// https://github.com/webpack/webpack/issues/11467
|
||||
{
|
||||
test: /\.m?js/,
|
||||
resolve: {
|
||||
fullySpecified: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.[tj]sx?$/,
|
||||
exclude: /node_modules/,
|
||||
|
@ -149,33 +159,15 @@ module.exports = {
|
|||
],
|
||||
},
|
||||
optimization: {
|
||||
moduleIds: isDev ? 'named' : 'hashed',
|
||||
runtimeChunk: 'single',
|
||||
splitChunks: {
|
||||
chunks: 'all',
|
||||
cacheGroups: {
|
||||
'core-js': {
|
||||
test(module, _chunks) {
|
||||
return (
|
||||
module.resource &&
|
||||
module.resource.indexOf('node_modules/core-js/') >= 0
|
||||
);
|
||||
},
|
||||
},
|
||||
react: {
|
||||
test(module, _chunks) {
|
||||
return (
|
||||
module.resource &&
|
||||
(module.resource.indexOf('node_modules/@hot-loader/react-dom/') >=
|
||||
0 ||
|
||||
module.resource.indexOf('node_modules/react-dom/') >= 0 ||
|
||||
module.resource.indexOf('node_modules/react/') >= 0)
|
||||
);
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
minimizer: [new TerserPlugin()],
|
||||
splitChunks: { chunks: 'all' },
|
||||
minimizer: [new TerserPlugin(), new CssMinimizerPlugin()],
|
||||
},
|
||||
plugins,
|
||||
bail: true,
|
||||
cache: {
|
||||
type: 'filesystem',
|
||||
buildDependencies: {
|
||||
config: [__filename],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue