├── .gitignore
├── .swcrc
├── README.md
├── package.json
├── public
└── index.html
├── src
├── App.tsx
├── Lazy.tsx
└── index.tsx
├── webpack.config.js
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | node_modules
3 |
--------------------------------------------------------------------------------
/.swcrc:
--------------------------------------------------------------------------------
1 | {
2 |
3 | "jsc": {
4 | "parser": {
5 | "syntax": "typescript",
6 | "tsx": true,
7 | "dynamicImport": true
8 | },
9 | "target": "es5"
10 | }
11 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Webpack + SWC
2 |
3 | ReactJS webpack configuration example using SWC (faster alternative to babel).
4 |
5 | SWC: https://github.com/swc-project/swc
6 |
7 | ## Todo
8 |
9 | - [ ] Add Hot Loading (Fast Refresh);
10 | - [ ] Add style loaders;
11 | - [ ] Add file loaders;
12 | - [ ] Production configuration;
13 | - [ ] Sourcemaps;
14 | - [ ] TypeScript paths;
15 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-swc",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "license": "MIT",
6 | "scripts": {
7 | "start": "webpack-dev-server --env.NODE_ENV=development --open",
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "dependencies": {
11 | "react": "^16.13.1",
12 | "react-dom": "^16.13.1"
13 | },
14 | "devDependencies": {
15 | "@babel/core": "^7.9.6",
16 | "@pmmmwh/react-refresh-webpack-plugin": "^0.2.0",
17 | "@swc/core": "^1.1.41",
18 | "@types/react": "^16.9.34",
19 | "@types/react-dom": "^16.9.7",
20 | "babel-loader": "^8.1.0",
21 | "html-webpack-plugin": "^4.3.0",
22 | "react-refresh": "^0.8.2",
23 | "swc-loader": "^0.1.9",
24 | "terser-webpack-plugin": "^3.0.1",
25 | "webpack": "^4.43.0",
26 | "webpack-cli": "^3.3.11",
27 | "webpack-dev-server": "^3.11.0"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | React SWC
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/App.tsx:
--------------------------------------------------------------------------------
1 | import React, { Suspense, lazy, useState, useEffect } from 'react';
2 |
3 | const Lazy = lazy(() => import('./Lazy'));
4 |
5 | const App: React.FC = () => {
6 | const [shouldShowLazy, setShouldShowLazy] = useState(false);
7 |
8 | useEffect(() => {
9 | setTimeout(() => {
10 | setShouldShowLazy(true);
11 | }, 2000);
12 | }, []);
13 |
14 | return
15 | Loading}>
16 | { shouldShowLazy && }
17 |
18 |
;
19 | }
20 |
21 | export default App;
--------------------------------------------------------------------------------
/src/Lazy.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | // import { Container } from './styles';
4 |
5 | const LazyLoaded: React.FC = () => {
6 | return Lazyss
7 | }
8 |
9 | export default LazyLoaded;
--------------------------------------------------------------------------------
/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from 'react-dom';
3 |
4 | import App from './App';
5 |
6 | render(, document.getElementById('app'));
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require("path");
2 | const HtmlWebpackPlugin = require('html-webpack-plugin');
3 | const TerserPlugin = require('terser-webpack-plugin');
4 |
5 | module.exports = webpackEnv => {
6 | const isDevelopment = webpackEnv.NODE_ENV !== 'production';
7 | const shouldUseSourceMap = webpackEnv.GENERATE_SOURCEMAP !== 'false';
8 |
9 | const isEnvProductionProfile =
10 | !isDevelopment && process.argv.includes('--profile');
11 |
12 | return {
13 | mode: isDevelopment ? 'development' : 'production',
14 | entry: path.join(__dirname, "src", "index.tsx"),
15 | output: {
16 | path: path.join(__dirname, "build"),
17 | pathinfo: isDevelopment,
18 | chunkFilename: !isDevelopment
19 | ? 'static/js/[name].[contenthash:8].chunk.js'
20 | : isDevelopment && 'static/js/[name].chunk.js',
21 | filename: "bundle.js"
22 | },
23 | devServer: {
24 | contentBase: path.join(__dirname, 'build'),
25 | compress: true,
26 | },
27 | optimization: {
28 | minimize: !isDevelopment,
29 | minimizer: [
30 | new TerserPlugin({
31 | terserOptions: {
32 | parse: {
33 | ecma: 8,
34 | },
35 | compress: {
36 | ecma: 5,
37 | warnings: false,
38 | comparisons: false,
39 | inline: 2,
40 | },
41 | mangle: {
42 | safari10: true,
43 | },
44 | keep_classnames: isEnvProductionProfile,
45 | keep_fnames: isEnvProductionProfile,
46 | output: {
47 | ecma: 5,
48 | comments: false,
49 | ascii_only: true,
50 | },
51 | },
52 | sourceMap: shouldUseSourceMap,
53 | }),
54 | ],
55 | splitChunks: {
56 | chunks: 'all',
57 | name: false,
58 | },
59 | runtimeChunk: {
60 | name: entrypoint => `runtime-${entrypoint.name}`,
61 | }
62 | },
63 | module: {
64 | rules: [
65 | {
66 | test: /\.ts(x?)$/,
67 | exclude: /node_modules/,
68 | use: {
69 | loader: 'swc-loader',
70 | options: {
71 | sync: true
72 | }
73 | },
74 | }
75 | ]
76 | },
77 | resolve: {
78 | extensions: ['.ts', '.tsx', '.js']
79 | },
80 | plugins: [
81 | new HtmlWebpackPlugin({
82 | filename: 'index.html',
83 | template: path.join(__dirname, 'public/index.html')
84 | }),
85 | ].filter(Boolean)
86 | }
87 | };
--------------------------------------------------------------------------------