@stanlemon/webdev 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc.json +21 -0
- package/.eslintrc.json +5 -0
- package/README.md +45 -0
- package/jest.config.js +22 -0
- package/jest.setup.js +1 -0
- package/package.json +58 -0
- package/webpack.config.js +103 -0
package/.babelrc.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"presets": [
|
|
3
|
+
[
|
|
4
|
+
"@babel/preset-env",
|
|
5
|
+
{
|
|
6
|
+
"bugfixes": true,
|
|
7
|
+
"targets": {
|
|
8
|
+
"browsers": [
|
|
9
|
+
"last 1 year",
|
|
10
|
+
"not dead",
|
|
11
|
+
"not opera < 1000",
|
|
12
|
+
"not op_mob < 1000",
|
|
13
|
+
"not Samsung < 1000"
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"@babel/preset-typescript",
|
|
19
|
+
"@babel/preset-react"
|
|
20
|
+
]
|
|
21
|
+
}
|
package/README.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Webdev
|
|
2
|
+
|
|
3
|
+
This repository contains all of my usual environment setup for babel, webpack and jest for developing React apps. I got tired of copying and pasting the same config files everywhere, so I put this together.
|
|
4
|
+
|
|
5
|
+
To get started, either copy [apps/template](../../apps/template/) or create these files:
|
|
6
|
+
|
|
7
|
+
package.json
|
|
8
|
+
```json
|
|
9
|
+
{
|
|
10
|
+
"type": "module",
|
|
11
|
+
"scripts": {
|
|
12
|
+
"start": "webpack serve",
|
|
13
|
+
"build": "NODE_ENV=production webpack",
|
|
14
|
+
"test": "jest",
|
|
15
|
+
"lint": "eslint --ext js,jsx,ts,tsx ./src/",
|
|
16
|
+
"lint:format": "eslint --fix --ext js,jsx,ts,tsx ./src/"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@stanlemon/webdev": "*"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
webpack.config.js
|
|
25
|
+
```javascript
|
|
26
|
+
export { default } from "@stanlemon/webdev/webpack.config.js";
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
jest.config.js
|
|
30
|
+
```javascript
|
|
31
|
+
export { default } from "@stanlemon/webdev/jest.config.js";
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
.eslintrc.json
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"extends": [
|
|
38
|
+
"@stanlemon"
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Then run `npm install` and start coding!
|
|
44
|
+
|
|
45
|
+
_Eventually I'll add some CLI tooling to streamline this further._
|
package/jest.config.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { fileURLToPath } from "url";
|
|
3
|
+
import { readFileSync } from "fs";
|
|
4
|
+
|
|
5
|
+
const babelOptions = JSON.parse(
|
|
6
|
+
readFileSync(new URL("./.babelrc.json", import.meta.url))
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
|
|
11
|
+
export default {
|
|
12
|
+
verbose: true,
|
|
13
|
+
setupFilesAfterEnv: [path.resolve(__dirname, "./jest.setup.js")],
|
|
14
|
+
testEnvironment: "jsdom",
|
|
15
|
+
transform: {
|
|
16
|
+
"^.+\\.(js|jsx|ts|tsx)?$": ["babel-jest", babelOptions],
|
|
17
|
+
},
|
|
18
|
+
moduleFileExtensions: ["js", "jsx", "ts", "tsx"],
|
|
19
|
+
moduleNameMapper: {
|
|
20
|
+
"\\.(css|less|sass|scss)$": "identity-obj-proxy",
|
|
21
|
+
},
|
|
22
|
+
};
|
package/jest.setup.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "@testing-library/jest-dom";
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@stanlemon/webdev",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "My typical web development setup, but without all the copy and paste.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"webpack",
|
|
7
|
+
"babel",
|
|
8
|
+
"jest",
|
|
9
|
+
"react"
|
|
10
|
+
],
|
|
11
|
+
"author": "Stan Lemon <stanlemon@users.noreply.github.com>",
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=17.0"
|
|
15
|
+
},
|
|
16
|
+
"type": "module",
|
|
17
|
+
"scripts": {
|
|
18
|
+
"lint": "eslint --ext js,jsx,ts,tsx ./",
|
|
19
|
+
"lint:format": "eslint --fix --ext js,jsx,ts,tsx ./"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"react": "^17.0.2",
|
|
23
|
+
"react-dom": "^17.0.2"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@babel/core": "^7.16.5",
|
|
27
|
+
"@babel/preset-env": "^7.16.5",
|
|
28
|
+
"@babel/preset-react": "^7.16.5",
|
|
29
|
+
"@babel/preset-typescript": "^7.16.5",
|
|
30
|
+
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.3",
|
|
31
|
+
"@stanlemon/eslint-config": "*",
|
|
32
|
+
"@testing-library/dom": "^8.11.1",
|
|
33
|
+
"@testing-library/jest-dom": "^5.16.1",
|
|
34
|
+
"@testing-library/react": "^12.1.2",
|
|
35
|
+
"@testing-library/user-event": "^13.5.0",
|
|
36
|
+
"@types/jest": "^27.0.3",
|
|
37
|
+
"@types/node": "^17.0.0",
|
|
38
|
+
"@types/react": "^17.0.37",
|
|
39
|
+
"@types/webpack": "^5.28.0",
|
|
40
|
+
"@types/webpack-env": "^1.16.3",
|
|
41
|
+
"babel-jest": "^27.4.5",
|
|
42
|
+
"babel-loader": "^8.2.3",
|
|
43
|
+
"clean-webpack-plugin": "^4.0.0",
|
|
44
|
+
"css-loader": "^6.5.1",
|
|
45
|
+
"html-webpack-plugin": "^5.5.0",
|
|
46
|
+
"identity-obj-proxy": "^3.0.0",
|
|
47
|
+
"jest": "^27.4.5",
|
|
48
|
+
"less": "^4.1.2",
|
|
49
|
+
"less-loader": "^10.2.0",
|
|
50
|
+
"react-refresh": "^0.11.0",
|
|
51
|
+
"style-loader": "^3.3.1",
|
|
52
|
+
"typescript": "^4.5.4",
|
|
53
|
+
"webpack": "^5.65.0",
|
|
54
|
+
"webpack-bundle-analyzer": "^4.5.0",
|
|
55
|
+
"webpack-cli": "^4.9.1",
|
|
56
|
+
"webpack-dev-server": "^4.6.0"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { readFileSync } from "fs";
|
|
3
|
+
import webpack from "webpack";
|
|
4
|
+
import HtmlWebpackPlugin from "html-webpack-plugin";
|
|
5
|
+
import ReactRefreshWebpackPlugin from "@pmmmwh/react-refresh-webpack-plugin";
|
|
6
|
+
import { BundleAnalyzerPlugin } from "webpack-bundle-analyzer";
|
|
7
|
+
import { CleanWebpackPlugin } from "clean-webpack-plugin";
|
|
8
|
+
|
|
9
|
+
const babelOptions = JSON.parse(
|
|
10
|
+
readFileSync(new URL("./.babelrc.json", import.meta.url))
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
const ENV = process.env.NODE_ENV ?? "development";
|
|
14
|
+
|
|
15
|
+
const isDevelopment = ENV !== "production";
|
|
16
|
+
|
|
17
|
+
export default {
|
|
18
|
+
mode: isDevelopment ? "development" : "production",
|
|
19
|
+
entry: ["./src/index.tsx"],
|
|
20
|
+
output: {
|
|
21
|
+
filename: "[name].[contenthash].js",
|
|
22
|
+
path: path.resolve("./", "dist"),
|
|
23
|
+
},
|
|
24
|
+
devtool: isDevelopment ? "eval-source-map" : "source-map",
|
|
25
|
+
devServer: {
|
|
26
|
+
hot: true,
|
|
27
|
+
historyApiFallback: true,
|
|
28
|
+
},
|
|
29
|
+
optimization: {
|
|
30
|
+
moduleIds: "deterministic",
|
|
31
|
+
runtimeChunk: "single",
|
|
32
|
+
splitChunks: {
|
|
33
|
+
chunks: "all",
|
|
34
|
+
cacheGroups: {
|
|
35
|
+
react: {
|
|
36
|
+
test(module) {
|
|
37
|
+
// `module.resource` contains the absolute path of the file on disk.
|
|
38
|
+
return (
|
|
39
|
+
module.resource && module.resource.includes("node_modules/react")
|
|
40
|
+
);
|
|
41
|
+
},
|
|
42
|
+
chunks: "initial",
|
|
43
|
+
filename: "react.[contenthash].js",
|
|
44
|
+
priority: 1,
|
|
45
|
+
maxInitialRequests: 2,
|
|
46
|
+
minChunks: 1,
|
|
47
|
+
},
|
|
48
|
+
vendor: {
|
|
49
|
+
test: /[\\/]node_modules[\\/]/,
|
|
50
|
+
name: "vendors",
|
|
51
|
+
chunks: "all",
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
performance: {
|
|
57
|
+
hints: isDevelopment ? false : "warning",
|
|
58
|
+
},
|
|
59
|
+
module: {
|
|
60
|
+
rules: [
|
|
61
|
+
{
|
|
62
|
+
test: /\.([j|t]s)x?$/,
|
|
63
|
+
exclude: /node_modules/,
|
|
64
|
+
use: {
|
|
65
|
+
loader: "babel-loader",
|
|
66
|
+
options: {
|
|
67
|
+
...babelOptions,
|
|
68
|
+
plugins: [isDevelopment && "react-refresh/babel"].filter(Boolean),
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
test: /\.css$/i,
|
|
74
|
+
use: ["style-loader", "css-loader"],
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
test: /\.less$/,
|
|
78
|
+
use: ["style-loader", "css-loader", "less-loader"],
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
test: /\.(png|jpe?g|gif|svg|eot|ttf|woff|woff2)$/i,
|
|
82
|
+
loader: "url-loader",
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
resolve: {
|
|
87
|
+
// Enable webpack to find files without these extensions
|
|
88
|
+
extensions: [".tsx", ".ts", ".jsx", ".js"],
|
|
89
|
+
},
|
|
90
|
+
plugins: [
|
|
91
|
+
...[
|
|
92
|
+
new CleanWebpackPlugin(),
|
|
93
|
+
new HtmlWebpackPlugin({
|
|
94
|
+
template: path.resolve("./", "index.html"),
|
|
95
|
+
}),
|
|
96
|
+
new webpack.DefinePlugin({
|
|
97
|
+
"process.env.NODE_ENV": JSON.stringify(ENV),
|
|
98
|
+
}),
|
|
99
|
+
],
|
|
100
|
+
...[!isDevelopment && new BundleAnalyzerPlugin()].filter(Boolean),
|
|
101
|
+
...[isDevelopment && new ReactRefreshWebpackPlugin()].filter(Boolean),
|
|
102
|
+
],
|
|
103
|
+
};
|