├── .gitignore ├── package-lock.json ├── package.json ├── readme.md ├── src ├── assets │ └── laughing.svg ├── generateJoke.js ├── index.js ├── styles │ └── main.scss └── template.html └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack-starter", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "build": "webpack", 8 | "dev": "webpack serve" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "devDependencies": { 14 | "@babel/core": "^7.17.8", 15 | "@babel/preset-env": "^7.16.11", 16 | "babel-loader": "^8.2.3", 17 | "css-loader": "^6.7.1", 18 | "html-webpack-plugin": "^5.5.0", 19 | "sass": "^1.49.9", 20 | "sass-loader": "^12.6.0", 21 | "style-loader": "^3.3.1", 22 | "webpack": "^5.70.0", 23 | "webpack-bundle-analyzer": "^4.5.0", 24 | "webpack-cli": "^4.9.2", 25 | "webpack-dev-server": "^4.7.4" 26 | }, 27 | "dependencies": { 28 | "axios": "^0.26.1" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Webpack App Starter 2 | 3 | Frontend environment for building JavaScript applications 4 | 5 | Includes the following features... 6 | 7 | - Babel Loader 8 | - Sass Loader With Dart Sass 9 | - HTMLWebpackPlugin 10 | - WebpackDevServer 11 | - Asset Resource Loader 12 | - Source Maps 13 | - Caching 14 | 15 | ## Usage 16 | 17 | Run Dev Server (Port 3000) 18 | 19 | ``` 20 | npm run dev 21 | ``` 22 | 23 | ## Build for production 24 | 25 | ``` 26 | npm run build 27 | ``` 28 | 29 | ## Demo App 30 | 31 | The demo app is a very simple Joke generator. Replace with your own code and install other packages as needed 32 | 33 | - index.js (main javascript) 34 | - template.html (template) 35 | - styles/main.scss (styles) 36 | -------------------------------------------------------------------------------- /src/assets/laughing.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/generateJoke.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | 3 | function generateJoke() { 4 | const config = { 5 | headers: { 6 | Accept: 'application/json', 7 | }, 8 | } 9 | 10 | axios.get('https://icanhazdadjoke.com', config).then((res) => { 11 | document.getElementById('joke').innerHTML = res.data.joke 12 | }) 13 | } 14 | 15 | export default generateJoke 16 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | // DEMO JOKE APP 2 | import generateJoke from './generateJoke' 3 | import './styles/main.scss' 4 | import laughing from './assets/laughing.svg' 5 | 6 | const laughImg = document.getElementById('laughImg') 7 | laughImg.src = laughing 8 | 9 | const jokeBtn = document.getElementById('jokeBtn') 10 | jokeBtn.addEventListener('click', generateJoke) 11 | 12 | generateJoke() 13 | -------------------------------------------------------------------------------- /src/styles/main.scss: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap'); 2 | 3 | $primary-color: #2fa8cc; 4 | $secondary-color: #f4f4f4; 5 | $box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1), 0 6px 6px rgba(0, 0, 0, 0.1); 6 | 7 | * { 8 | box-sizing: border-box; 9 | } 10 | 11 | body { 12 | background-color: $primary-color; 13 | font-family: 'Roboto', sans-serif; 14 | display: flex; 15 | flex-direction: column; 16 | align-items: center; 17 | justify-content: center; 18 | height: 100vh; 19 | overflow: hidden; 20 | margin: 0; 21 | padding: 20px; 22 | } 23 | 24 | .container { 25 | background-color: $secondary-color; 26 | border-radius: 10px; 27 | box-shadow: $box-shadow; 28 | padding: 50px 20px; 29 | text-align: center; 30 | max-width: 100%; 31 | width: 800px; 32 | } 33 | 34 | h3 { 35 | margin: 0; 36 | opacity: 0.5; 37 | letter-spacing: 2px; 38 | } 39 | 40 | img { 41 | width: 100px; 42 | margin-bottom: 20px; 43 | } 44 | 45 | .joke { 46 | font-size: 30px; 47 | letter-spacing: 1px; 48 | line-height: 40px; 49 | margin: 50px auto; 50 | max-width: 600px; 51 | } 52 | 53 | .btn { 54 | background-color: $primary-color; 55 | color: $secondary-color; 56 | border: 0; 57 | border-radius: 10px; 58 | box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1), 0 6px 6px rgba(0, 0, 0, 0.1); 59 | padding: 14px 40px; 60 | font-size: 16px; 61 | cursor: pointer; 62 | 63 | &:active { 64 | transform: scale(0.98); 65 | } 66 | 67 | &:focus { 68 | outline: 0; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <%= htmlWebpackPlugin.options.title %> 8 | 9 | 10 |
11 | 12 |

Don't Laugh Challenge

13 |
14 | 15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const HtmlWebpackPlugin = require('html-webpack-plugin') 3 | const BundleAnalyzerPlugin = 4 | require('webpack-bundle-analyzer').BundleAnalyzerPlugin 5 | 6 | module.exports = { 7 | mode: 'development', 8 | entry: { 9 | bundle: path.resolve(__dirname, 'src/index.js'), 10 | }, 11 | output: { 12 | path: path.resolve(__dirname, 'dist'), 13 | filename: '[name][contenthash].js', 14 | clean: true, 15 | assetModuleFilename: '[name][ext]', 16 | }, 17 | devtool: 'source-map', 18 | devServer: { 19 | static: { 20 | directory: path.resolve(__dirname, 'dist'), 21 | }, 22 | port: 3000, 23 | open: true, 24 | hot: true, 25 | compress: true, 26 | historyApiFallback: true, 27 | }, 28 | module: { 29 | rules: [ 30 | { 31 | test: /\.scss$/, 32 | use: ['style-loader', 'css-loader', 'sass-loader'], 33 | }, 34 | { 35 | test: /\.js$/, 36 | exclude: /node_modules/, 37 | use: { 38 | loader: 'babel-loader', 39 | options: { 40 | presets: ['@babel/preset-env'], 41 | }, 42 | }, 43 | }, 44 | { 45 | test: /\.(png|svg|jpg|jpeg|gif)$/i, 46 | type: 'asset/resource', 47 | }, 48 | ], 49 | }, 50 | plugins: [ 51 | new HtmlWebpackPlugin({ 52 | title: 'Webpack App', 53 | filename: 'index.html', 54 | template: 'src/template.html', 55 | }), 56 | new BundleAnalyzerPlugin(), 57 | ], 58 | } 59 | --------------------------------------------------------------------------------