├── .gitignore
├── README.md
├── package-lock.json
├── package.json
├── src
├── app.js
├── index.handlebars
├── partials
│ ├── header.handlebars
│ └── newsletter.handlebars
├── static
│ └── logo.png
└── styles
│ └── main.scss
└── webpack
├── webpack.common.js
├── webpack.dev.js
└── webpack.prod.js
/.gitignore:
--------------------------------------------------------------------------------
1 | dist/
2 | node_modules/
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Webpack Workflow
2 |
3 | This is a webpack configuration for development Websites with HTML, Handlebars, Javacript, CSS and Sass, using a live server and other features that webpack provides to other libraries and frameworks like React, Vue or Angular.
4 |
5 | A tipical website needs:
6 | - CSS or Sass styles
7 | - A template engine (like Handlebars)
8 | - Import and install Javascript files (like npm modules)
9 | - Custom Fonts
10 |
11 | ## Installation
12 |
13 | Install dependencies
14 | ```
15 | npm install
16 | ```
17 |
18 | To start the development server
19 | ```
20 | npm run dev
21 | ```
22 |
23 | To build your project for production use:
24 | ```
25 | npm run build
26 | ```
27 |
28 | ## Considerations
29 | - the entry of our files is inside the folder: `src`
30 | - the webpack folder is to setting webpack files for development and production
31 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "webpack-workflow",
3 | "version": "1.0.0",
4 | "description": "A tipical website needs: - CSS styles - A template engine - Javascript files - Custom Fonts",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "rimraf dist && webpack --config ./webpack/webpack.prod.js",
8 | "start": "webpack serve --config ./webpack/webpack.dev.js"
9 | },
10 | "keywords": [],
11 | "author": "",
12 | "license": "ISC",
13 | "devDependencies": {
14 | "autoprefixer": "^10.3.1",
15 | "css-loader": "^6.2.0",
16 | "file-loader": "^6.2.0",
17 | "handlebars": "^4.7.7",
18 | "handlebars-loader": "^1.7.1",
19 | "html-webpack-plugin": "^5.3.2",
20 | "image-webpack-loader": "^7.0.1",
21 | "mini-css-extract-plugin": "^2.2.0",
22 | "postcss-loader": "^6.1.1",
23 | "sass-loader": "^12.1.0",
24 | "webpack": "^5.48.0",
25 | "webpack-cli": "^4.7.2",
26 | "webpack-dev-server": "^3.11.2",
27 | "webpack-merge": "^5.8.0"
28 | },
29 | "dependencies": {
30 | "rimraf": "^3.0.2",
31 | "sass": "^1.37.5",
32 | "toastify-js": "^1.11.1"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/app.js:
--------------------------------------------------------------------------------
1 | import Toastify from "toastify-js";
2 | import "toastify-js/src/toastify.css";
3 |
4 | import "./styles/main.scss";
5 | import "./static/logo.png";
6 |
7 | const newsletterForm = document.querySelector("#newsletter");
8 | const newsletterInput = document.querySelector("#newsletter-input");
9 |
10 | newsletterForm.addEventListener("submit", (event) => {
11 | event.preventDefault();
12 |
13 | console.log(newsletterInput.value);
14 |
15 | Toastify({
16 | text: `Gracias ${newsletterInput.value} por registrarte!`,
17 | className: "info",
18 | }).showToast();
19 | });
20 |
--------------------------------------------------------------------------------
/src/index.handlebars:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{htmlWebpackPlugin.options.title}}
8 |
9 |
10 |
11 |
12 | Webpack, Sass & A Template Engine
13 |
14 |
15 | {{> partials/header title=htmlWebpackPlugin.options.title}}
16 | {{> partials/newsletter}}
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/partials/header.handlebars:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/src/partials/newsletter.handlebars:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/static/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FaztWeb/webpack-simple-workflow/eab582b6ca478a8f4bc0fd55d860a3ffcc4c1b22/src/static/logo.png
--------------------------------------------------------------------------------
/src/styles/main.scss:
--------------------------------------------------------------------------------
1 | $bg-dark: #0f0f0f;
2 | $bg-light: #f5f6fa;
3 |
4 | $text-color: $bg-dark;
5 |
6 | body {
7 | padding: 10rem;
8 | text-align: center;
9 | background: $bg-light;
10 | color: $text-color;
11 | font-family: "Roboto", sans-serif;
12 | }
13 |
14 | .bg-white {
15 | background: #ffffff;
16 | color: #0f0f0f;
17 | padding: 40px;
18 | }
19 |
20 | .newsletter-input {
21 | padding: 0.5rem;
22 | font-size: 1.2rem;
23 | }
24 |
25 | .newsletter-btn {
26 | padding: 0.5rem;
27 | font-size: 1.2rem;
28 | background: beige;
29 | border: 1px solid #ccc;
30 | }
31 |
--------------------------------------------------------------------------------
/webpack/webpack.common.js:
--------------------------------------------------------------------------------
1 | const path = require("path");
2 | const HtmlWebpackPlugin = require("html-webpack-plugin");
3 | const MiniCssExtractPlugin = require("mini-css-extract-plugin");
4 | const autoprefixer = require("autoprefixer");
5 |
6 | module.exports = {
7 | entry: "./src/app.js",
8 | output: {
9 | path: path.resolve(__dirname, "../dist"),
10 | filename: "js/bundle.js",
11 | },
12 | devtool: "source-map",
13 | devServer: {
14 | port: 4000,
15 | open: true,
16 | },
17 | module: {
18 | rules: [
19 | {
20 | test: /\.handlebars$/,
21 | loader: "handlebars-loader",
22 | },
23 | {
24 | test: /\.(sa|sc|c)ss$/,
25 | use: [
26 | MiniCssExtractPlugin.loader,
27 | "css-loader",
28 | {
29 | loader: "postcss-loader",
30 | options: {
31 | postcssOptions: {
32 | plugins: [
33 | [
34 | autoprefixer,
35 | {
36 | browsers: "last 2 versions",
37 | },
38 | ],
39 | ],
40 | },
41 | },
42 | },
43 | "sass-loader",
44 | ],
45 | },
46 | {
47 | test: /\.(jpg|png|gif)$/,
48 | use: [
49 | {
50 | loader: "file-loader",
51 | options: {
52 | name: "[name].[ext]",
53 | outputPath: "static/",
54 | useRelativePath: true,
55 | },
56 | },
57 | {
58 | loader: "image-webpack-loader",
59 | options: {
60 | mozjpeg: {
61 | progressive: true,
62 | quality: 65,
63 | },
64 | // optipng.enabled: false will disable optipng
65 | optipng: {
66 | enabled: false,
67 | },
68 | pngquant: {
69 | quality: [0.65, 0.9],
70 | speed: 4,
71 | },
72 | gifsicle: {
73 | interlaced: false,
74 | },
75 | // the webp option will enable WEBP
76 | webp: {
77 | quality: 75,
78 | },
79 | },
80 | },
81 | ],
82 | },
83 | ],
84 | },
85 | plugins: [
86 | new HtmlWebpackPlugin({
87 | title: "My Cool Website",
88 | template: "./src/index.handlebars",
89 | minify: {
90 | html5: true,
91 | collapseWhitespace: true,
92 | caseSensitive: true,
93 | removeComments: true,
94 | removeEmptyElements: true,
95 | },
96 | }),
97 | new MiniCssExtractPlugin({
98 | filename: "css/[name]-styles.css",
99 | chunkFilename: "[id].css",
100 | }),
101 | ],
102 | };
103 |
--------------------------------------------------------------------------------
/webpack/webpack.dev.js:
--------------------------------------------------------------------------------
1 | const { merge } = require("webpack-merge");
2 | const common = require("./webpack.common");
3 |
4 | module.exports = merge(common, {
5 | mode: "development",
6 | });
7 |
--------------------------------------------------------------------------------
/webpack/webpack.prod.js:
--------------------------------------------------------------------------------
1 | const { merge } = require("webpack-merge");
2 | const common = require("./webpack.common");
3 |
4 | module.exports = merge(common, {
5 | mode: "production",
6 | });
7 |
--------------------------------------------------------------------------------