├── .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 | }; --------------------------------------------------------------------------------