Skip to content

Commit cded605

Browse files
authored
Merge pull request #2 from glook/webpack5
Version 1.0.0 * moved to webpack 5 (YAY) * added and configured copyPlugin * replaced file-loader to build in asset manager * removed unused dependencies (lodash, thread-loader,file-loader) * dependencies was updated to latest version * reorganised structure of config files
2 parents 5bcc62c + 332881b commit cded605

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+710
-491
lines changed

.babelrc.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22
* Created by: Andrey Polyakov (andrey@polyakov.im)
33
*/
44
const {argv} = require('yargs');
5-
const get = require('lodash/get');
65

76
module.exports = (api) => {
8-
const mode = argv ? get(argv, 'env.mode', 'production') : 'production';
7+
const env = argv.env || [];
8+
const mode = !!env.find((value) => value === 'mode=dev')
9+
? 'development'
10+
: 'production';
11+
912
// This caches the Babel config by environment.
1013
api.cache.using(() => mode);
1114

.eslintignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
node_modules
22
dist
33
webpack
4+
.eslintrc.js
5+
webpack.config.babel.js

.eslintrc.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ module.exports = {
2525
// e.g. "@typescript-eslint/explicit-function-return-type": "off",
2626
'@typescript-eslint/explicit-function-return-type': 'off',
2727
'@typescript-eslint/no-unused-vars': 'off',
28-
28+
'@typescript-eslint/ban-ts-comment': 'off',
2929
// These rules don't add much value, are better covered by TypeScript and good definition files
3030
'react/no-direct-mutation-state': 'off',
3131
'react/no-deprecated': 'off',

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
.idea
2+
.vscode
23
dist
34
node_modules
45
package-lock.json
6+
yarn.lock
7+
pnpm-lock.yaml

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
# Webpack 4 boilerplate
1+
# Webpack 5 boilerplate
22

33
![](https://habrastorage.org/webt/q-/lv/b0/q-lvb0d4li7cpi-hsctistlzooi.png)
44

5-
[Webpack 4](https://webpack.js.org/) boilerplate with support of most common loaders and modules:
5+
[Webpack 5](https://webpack.js.org/) boilerplate with support of most common loaders and modules:
66

77
- [babel](https://babeljs.io/)
88
- typescript (using [ForkTsCheckerWebpack](https://www.npmjs.com/package/fork-ts-checker-webpack-plugin) )

package.json

Lines changed: 89 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
11
{
22
"name": "webpack-typescript-react",
3-
"version": "0.0.9",
4-
"description": "",
5-
"license": "ISC",
6-
"author": "",
7-
"main": "index.js",
3+
"version": "1.0.0",
4+
"description": "Webpack 5 boilerplate with support of most common loaders and modules",
5+
"keywords": [
6+
"react",
7+
"typescript",
8+
"webpack",
9+
"webpack 5",
10+
"webpack boilerplate"
11+
],
12+
"repository": {
13+
"type": "git",
14+
"url": "git@github.com:glook/webpack-typescript-react.git"
15+
},
16+
"license": "MIT",
17+
"author": "Andrey Polyakov <andrey@polyakov.im>",
18+
"main": "webpack.config.babel.js",
819
"scripts": {
9-
"build": "webpack --env.mode production",
10-
"start": "webpack-dev-server --env.mode dev --env.isDevServer true"
20+
"build": "webpack --config webpack.config.babel.js",
21+
"profile": "webpack --profile --json --config webpack.config.babel.js > ./dist/profile.json && webpack-bundle-analyzer ./dist/profile.json",
22+
"start": "webpack --env mode=dev --env isDevServer --env NODE_ENV=local serve --config webpack.config.babel.js"
1123
},
1224
"husky": {
1325
"hooks": {
@@ -17,87 +29,81 @@
1729
},
1830
"dependencies": {
1931
"@types/classnames": "^2.2.10",
20-
"@types/react": "^16.9.51",
32+
"@types/react": "^16.9.53",
2133
"@types/react-dom": "^16.9.8",
2234
"classnames": "^2.2.6",
2335
"normalize.css": "^8.0.1",
24-
"react": "^16.13.1",
25-
"react-dom": "^16.13.1"
36+
"react": "^17.0.1",
37+
"react-dom": "^17.0.1"
2638
},
2739
"devDependencies": {
28-
"@babel/core": "^7.11.6",
29-
"@babel/plugin-proposal-class-properties": "^7.10.4",
30-
"@babel/plugin-proposal-export-namespace-from": "^7.10.4",
31-
"@babel/plugin-proposal-object-rest-spread": "^7.11.0",
32-
"@babel/plugin-proposal-throw-expressions": "^7.10.4",
33-
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
34-
"@babel/plugin-transform-runtime": "^7.11.5",
35-
"@babel/preset-env": "^7.11.5",
36-
"@babel/preset-react": "^7.10.4",
37-
"@babel/register": "^7.11.5",
38-
"@pmmmwh/react-refresh-webpack-plugin": "^0.4.2",
39-
"@svgr/webpack": "^5.4.0",
40-
"@teamsupercell/typings-for-css-modules-loader": "^2.3.0",
41-
"@typescript-eslint/eslint-plugin": "^4.4.0",
42-
"@typescript-eslint/parser": "^4.4.0",
43-
"autoprefixer": "^9.8.6",
44-
"babel-eslint": "^10.1.0",
45-
"babel-loader": "^8.1.0",
46-
"clean-webpack-plugin": "^3.0.0",
47-
"copy-webpack-plugin": "^6.2.0",
48-
"core-js": "^3.6.5",
49-
"css-loader": "4.3.0",
50-
"cssnano": "^4.1.10",
51-
"eslint": "^7.10.0",
52-
"eslint-config-airbnb-base": "^14.2.0",
53-
"eslint-config-airbnb-typescript": "^11.0.0",
54-
"eslint-config-prettier": "^6.12.0",
55-
"eslint-import-resolver-alias": "^1.1.2",
56-
"eslint-plugin-import": "^2.22.1",
57-
"eslint-plugin-jsx-a11y": "^6.3.1",
58-
"eslint-plugin-react": "^7.21.3",
59-
"eslint-plugin-react-hooks": "^4.1.2",
60-
"eslint-webpack-plugin": "^2.1.0",
61-
"expose-loader": "1.0.0",
62-
"extract-text-webpack-plugin": "^4.0.0-beta.0",
63-
"file-loader": "6.1.0",
64-
"fork-ts-checker-webpack-plugin": "^5.2.0",
65-
"html-loader": "^1.3.1",
66-
"html-webpack-plugin": "^4.5.0",
67-
"husky": "^4.3.0",
68-
"import-sort-style-module-and-prefix": "^0.1.3",
69-
"is-windows": "^1.0.2",
70-
"less": "^3.12.2",
71-
"less-loader": "^7.0.1",
72-
"lint-staged": "^10.4.0",
73-
"lodash": "^4.17.20",
74-
"mini-css-extract-plugin": "^0.11.3",
75-
"path": "^0.12.7",
76-
"postcss-loader": "4.0.3",
77-
"prettier": "^2.1.2",
78-
"prettier-plugin-import-sort": "0.0.6",
79-
"pretty-quick": "^3.0.2",
80-
"react-refresh": "^0.8.3",
81-
"regenerator-runtime": "^0.13.7",
82-
"resolve-url-loader": "^3.1.1",
83-
"sass": "^1.27.0",
84-
"sass-loader": "^10.0.2",
85-
"sass-resources-loader": "^2.1.1",
86-
"speed-measure-webpack-plugin": "^1.3.3",
87-
"style-loader": "1.3.0",
88-
"svg-url-loader": "^6.0.0",
89-
"terser-webpack-plugin": "^4.2.2",
90-
"thread-loader": "^3.0.0",
91-
"ts-loader": "^8.0.4",
92-
"typescript": "^4.0.3",
93-
"url-loader": "4.1.0",
94-
"webpack": "^4.44.2",
95-
"webpack-cli": "^3.3.12",
96-
"webpack-dev-server": "^3.11.0",
97-
"webpack-merge": "5.1.4",
98-
"webpack-serve": "^3.2.0",
99-
"webpack-stats-plugin": "0.3.2",
100-
"yargs": "^16.0.3"
40+
"@babel/core": "~7.12.3",
41+
"@babel/plugin-proposal-class-properties": "~7.12.1",
42+
"@babel/plugin-proposal-export-default-from": "^7.12.1",
43+
"@babel/plugin-proposal-export-namespace-from": "~7.12.1",
44+
"@babel/plugin-proposal-object-rest-spread": "~7.12.1",
45+
"@babel/plugin-proposal-throw-expressions": "~7.12.1",
46+
"@babel/plugin-syntax-dynamic-import": "~7.8.3",
47+
"@babel/plugin-transform-runtime": "~7.12.1",
48+
"@babel/preset-env": "~7.12.1",
49+
"@babel/preset-react": "~7.12.1",
50+
"@babel/register": "~7.12.1",
51+
"@pmmmwh/react-refresh-webpack-plugin": "~0.4.2",
52+
"@svgr/webpack": "~5.4.0",
53+
"@teamsupercell/typings-for-css-modules-loader": "~2.3.0",
54+
"@typescript-eslint/eslint-plugin": "~4.6.0",
55+
"@typescript-eslint/parser": "~4.6.0",
56+
"autoprefixer": "~10.0.1",
57+
"babel-eslint": "~10.1.0",
58+
"babel-loader": "~8.1.0",
59+
"clean-webpack-plugin": "~3.0.0",
60+
"copy-webpack-plugin": "~6.2.1",
61+
"core-js": "~3.6.5",
62+
"css-loader": "~5.0.0",
63+
"cssnano": "~4.1.10",
64+
"eslint": "~7.12.0",
65+
"eslint-config-airbnb-base": "~14.2.0",
66+
"eslint-config-airbnb-typescript": "~12.0.0",
67+
"eslint-config-prettier": "~6.14.0",
68+
"eslint-import-resolver-alias": "~1.1.2",
69+
"eslint-plugin-import": "~2.22.1",
70+
"eslint-plugin-jsx-a11y": "~6.4.1",
71+
"eslint-plugin-react": "~7.21.5",
72+
"eslint-plugin-react-hooks": "~4.2.0",
73+
"eslint-webpack-plugin": "~2.1.0",
74+
"fork-ts-checker-webpack-plugin": "~5.2.0",
75+
"html-loader": "~1.3.2",
76+
"html-webpack-plugin": "~5.0.0-alpha.6",
77+
"husky": "~4.3.0",
78+
"import-sort-style-module-and-prefix": "~0.1.3",
79+
"is-windows": "~1.0.2",
80+
"less": "~3.12.2",
81+
"less-loader": "~7.0.2",
82+
"lint-staged": "~10.5.0",
83+
"mini-css-extract-plugin": "~1.2.0",
84+
"path": "~0.12.7",
85+
"postcss-loader": "~4.0.4",
86+
"prettier": "~2.1.2",
87+
"prettier-plugin-import-sort": "~0.0.6",
88+
"pretty-quick": "~3.1.0",
89+
"react-refresh": "~0.9.0",
90+
"regenerator-runtime": "~0.13.7",
91+
"resolve-url-loader": "~3.1.2",
92+
"sass": "~1.27.0",
93+
"sass-loader": "~10.0.4",
94+
"sass-resources-loader": "~2.1.1",
95+
"style-loader": "~2.0.0",
96+
"svg-url-loader": "~6.0.0",
97+
"terser-webpack-plugin": "~5.0.1",
98+
"ts-loader": "~8.0.7",
99+
"typescript": "~4.0.3",
100+
"url-loader": "~4.1.1",
101+
"webpack": "~5.2.0",
102+
"webpack-bundle-analyzer": "~3.9.0",
103+
"webpack-cli": "~4.1.0",
104+
"webpack-dev-server": "~3.11.0",
105+
"webpack-merge": "~5.2.0",
106+
"yargs": "~16.1.0"
101107
},
102108
"importSort": {
103109
".ts, .tsx": {

src/@types/declarations.d.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
1-
declare module '*.scss' {
2-
const content: { [className: string]: string };
3-
export = content;
1+
declare module "*.scss" {
2+
const content: { [className: string]: string };
3+
export = content;
44
}
55

6-
declare module '*.less' {
7-
const content: { [className: string]: string };
8-
export = content;
6+
declare module "*.less" {
7+
const content: { [className: string]: string };
8+
export = content;
99
}
1010

11-
declare module '*.component.svg' {
12-
const content: any;
13-
export default content;
11+
declare module "*.svg" {
12+
import React = require("react");
13+
const ReactComponent: React.FunctionComponent<React.SVGProps<SVGSVGElement>>;
14+
export default ReactComponent;
1415
}
16+
17+
declare const IS_PROD: boolean;
18+
declare const IS_DEV: boolean;
19+
declare const IS_DEV_SERVER: boolean;

src/assets/.gitkeep

Whitespace-only changes.

src/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<html lang="en">
33
<head>
44
<meta charset="UTF-8" />
5-
<title>Webpack es6 typescript</title>
5+
<title>Webpack5 typescript react boilerplate</title>
66
<link
77
href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@600&display=swap"
88
rel="stylesheet"

src/index.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
/**
22
* Created by: Andrey Polyakov (andrey@polyakov.im)
33
*/
4-
import 'core-js/stable';
5-
import 'regenerator-runtime/runtime';
6-
74
import '@styles/styles.less';
85
import '@styles/styles.scss';
96

webpack.config.babel.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import merge from 'webpack-merge';
55

66
import baseConfig from './webpack/base';
77
import devConfig from './webpack/dev';
8-
import {isProd} from './webpack/env';
8+
import {isProd} from './webpack/utils/env';
99
import prodConfig from './webpack/prod';
1010

1111
export default () =>

webpack/base.js

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,51 @@
33
*/
44
import path from 'path';
55

6-
import {devServerUrl} from './constants/devproxy';
6+
import {aliasItems, devServerUrl, externalItems} from './config';
77
import entry from './entry';
8-
import {isDevServer, isProd} from './env';
9-
import rules from './loaders';
108
import optimization from './optimization';
11-
import plugins from './plugins';
12-
import externals from './resources/externals';
13-
import resolve from './resources/resolve';
9+
import * as plugins from './plugins';
10+
import * as rules from './rules';
11+
import {isDevServer, isProd} from './utils/env';
12+
import {arrayFilterEmpty} from './utils/helpers';
1413

1514
export default {
1615
context: __dirname,
17-
target: 'web',
16+
target: ['web', 'es5'],
1817
mode: isProd ? 'production' : 'development',
1918
entry,
2019
output: {
2120
path: path.join(__dirname, '../dist'),
2221
publicPath: isDevServer ? devServerUrl : './',
23-
filename: isDevServer ? '[name].[hash].js' : '[name].[contenthash].js',
22+
filename: isDevServer
23+
? '[name].[fullhash].js'
24+
: '[name].[contenthash].js',
2425
},
2526
module: {
26-
rules,
27+
rules: arrayFilterEmpty([
28+
rules.javascriptRule,
29+
rules.typescriptRule,
30+
rules.htmlRule,
31+
rules.imagesRule,
32+
rules.fontsRule,
33+
rules.cssRule,
34+
...rules.lessRules,
35+
...rules.sassRules,
36+
...rules.svgRules,
37+
]),
38+
},
39+
plugins: arrayFilterEmpty([
40+
plugins.htmlWebpackPlugin,
41+
plugins.providePlugin,
42+
plugins.definePlugin,
43+
plugins.forkTsCheckerWebpackPlugin,
44+
plugins.esLintPlugin,
45+
plugins.copyPlugin,
46+
]),
47+
resolve: {
48+
alias: aliasItems,
49+
extensions: ['.tsx', '.ts', '.js', '.jsx'],
2750
},
28-
plugins,
29-
resolve,
3051
optimization,
31-
externals,
52+
externals: externalItems,
3253
};

webpack/config/alias.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* Created by: Andrey Polyakov (andrey@polyakov.im)
3+
* @see https://webpack.js.org/configuration/dev-server/
4+
*/
5+
import {join} from 'path';
6+
7+
import {rootDir} from '../utils/env';
8+
9+
export const aliasItems = {
10+
'@src': join(rootDir, '/src'),
11+
'@images': join(rootDir, '/src/images'),
12+
'@styles': join(rootDir, '/src/styles'),
13+
'@components': join(rootDir, '/src/components'),
14+
};

0 commit comments

Comments
 (0)