├── src ├── js │ └── main.js ├── components │ └── welcome │ │ ├── index.js │ │ ├── welcome-css.json │ │ ├── welcome.pug │ │ └── welcome.scss ├── styles │ ├── core.scss │ ├── palettes.scss │ ├── variables.scss │ └── reset.scss ├── favicon.ico ├── images │ └── logo.png ├── app.js ├── app.scss └── index.pug ├── .gitattributes ├── .gitignore ├── .travis.yml ├── .editorconfig ├── app.config.json ├── .github └── dependabot.yml ├── .eslintrc.js ├── postcss.config.js ├── license ├── sass-lint.json ├── package.json ├── readme.md └── webpack.config.js /src/js/main.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.js text eol=lf 2 | -------------------------------------------------------------------------------- /src/components/welcome/index.js: -------------------------------------------------------------------------------- 1 | import './welcome.scss'; 2 | -------------------------------------------------------------------------------- /src/styles/core.scss: -------------------------------------------------------------------------------- 1 | @import 'variables'; 2 | @import 'palettes'; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | package-lock.json 4 | .DS_Store 5 | .vscode/settings.json 6 | -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipefialho/kratos-boilerplate/HEAD/src/favicon.ico -------------------------------------------------------------------------------- /src/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipefialho/kratos-boilerplate/HEAD/src/images/logo.png -------------------------------------------------------------------------------- /src/components/welcome/welcome-css.json: -------------------------------------------------------------------------------- 1 | {"host":"_host_7ja4p_1","title":"_title_7ja4p_1","description":"_description_7ja4p_1"} -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "7" 4 | before_script: 5 | - npm i 6 | cache: 7 | directories: 8 | - "node_modules" 9 | script: 10 | - npm run deploy 11 | -------------------------------------------------------------------------------- /src/app.js: -------------------------------------------------------------------------------- 1 | import * as offline from 'offline-plugin/runtime'; 2 | import './app.scss'; 3 | import './components/welcome'; 4 | 5 | offline.install({ onUpdateReady: () => offline.applyUpdate() }); 6 | -------------------------------------------------------------------------------- /src/components/welcome/welcome.pug: -------------------------------------------------------------------------------- 1 | - var css = require('./welcome-css.json'); 2 | 3 | section(class=css.host) 4 | h1(class=css.title) Kratos Boilerplate 5 | article(class=css.description) A simple boilerplate for creating a static PWA using Webpack, Pug, PostCSS and CSS Modules 6 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /app.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Kratos Boilerplate", 3 | "description": "A simple boilerplate for creating a static PWA using Webpack, Pug, Stylus and PostCSS", 4 | "url": "https://github.com/felipefialho/kratos-boilerplate", 5 | "logo": "images/logo.png", 6 | "theme_color": "#333333", 7 | "short_name": "Kratos", 8 | "ga": "x", 9 | "twitter": "@felipefialho_" 10 | } 11 | -------------------------------------------------------------------------------- /src/app.scss: -------------------------------------------------------------------------------- 1 | // ================================================== 2 | // Scaffolding 3 | // ================================================== 4 | 5 | @import 'styles/core'; 6 | @import 'styles/reset'; 7 | 8 | html { 9 | -moz-osx-font-smoothing: auto; 10 | -webkit-font-smoothing: auto; 11 | font-size: 10px; 12 | overflow-x: hidden; 13 | } 14 | 15 | body { 16 | -webkit-overflow-scrolling: touch; 17 | overflow-x: hidden; 18 | } -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: "/" 5 | schedule: 6 | interval: monthly 7 | time: "08:00" 8 | open-pull-requests-limit: 99 9 | ignore: 10 | - dependency-name: node-sass 11 | versions: 12 | - ">= 5.0.a, < 5.1" 13 | - dependency-name: pug-code-gen 14 | versions: 15 | - 2.0.3 16 | - dependency-name: webpack-cli 17 | versions: 18 | - 4.5.0 19 | -------------------------------------------------------------------------------- /src/components/welcome/welcome.scss: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------- 2 | // Welcome 3 | // ------------------------------------------------- 4 | 5 | @import '../../styles/core'; 6 | 7 | .host { 8 | font-family: 'Open Sans'; 9 | margin-left: auto; 10 | margin-right: auto; 11 | max-width: $screen-md; 12 | padding: $space; 13 | text-align: center; 14 | } 15 | 16 | .title { 17 | font-size: 4rem; 18 | margin-bottom: $space; 19 | } 20 | 21 | .description { 22 | font-size: 2rem; 23 | } 24 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es6: true, 5 | jquery: true 6 | }, 7 | globals: { 8 | "fetch": false, 9 | "window": true, 10 | "document": true 11 | }, 12 | extends: 'eslint:recommended', 13 | parserOptions: { 14 | ecmaVersion: 2015, 15 | sourceType: 'module' 16 | }, 17 | rules: { 18 | indent: ['error', 2], 19 | 'no-unused-vars': [1, { vars: 'local', args: 'none' }], 20 | 'linebreak-style': 'off', 21 | quotes: ['error', 'single'], 22 | semi: ['error', 'always'] 23 | }, 24 | env: { 25 | node: true 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /src/styles/palettes.scss: -------------------------------------------------------------------------------- 1 | // ================================================== 2 | // Palette 3 | // ================================================== 4 | 5 | $white: #ffffff; 6 | $black: #000000; 7 | 8 | $pallet-gray: ( 9 | 50: #f9f9f9, 10 | 100: #d4d4d5, 11 | 200: #b1aeb3, 12 | 300: #928e94, 13 | 400: #868288, 14 | 500: #777777, 15 | 600: #69666c, 16 | 700: #5b575e, 17 | 800: #3f3c42, 18 | 900: #232323, 19 | contrast: ( 20 | 50: #232323, 21 | 100: #ffffff, 22 | 200: #ffffff, 23 | 300: #ffffff, 24 | 400: #ffffff, 25 | 500: #ffffff, 26 | 600: #ffffff, 27 | 700: #ffffff, 28 | 800: #ffffff, 29 | 900: #ffffff 30 | ) 31 | ); 32 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | 'autoprefixer': {}, 4 | 'rucksack-css': {}, 5 | 'lost': {}, 6 | 'postcss-font-magician': {}, 7 | 'cssnano': {}, 8 | 'postcss-modules': { 9 | getJSON: function(cssFileName, json, outputFileName) { 10 | const fs = require('fs'); 11 | const path = require('path'); 12 | const isComponent = /components/.test(path.dirname(cssFileName)); 13 | 14 | if (isComponent) { 15 | const cssName = path.basename(`${cssFileName}`); 16 | const jsonFileName = path.resolve(`${path.dirname(cssFileName)}/${cssName.split('.')[0]}-css.json`); 17 | fs.writeFileSync(jsonFileName, JSON.stringify(json)); 18 | } 19 | } 20 | } 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Felipe Fialho 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /sass-lint.json: -------------------------------------------------------------------------------- 1 | { 2 | "options": { 3 | "merge-default-rules": false 4 | }, 5 | "files": { 6 | "ignore": ["node_modules/**/*.s+(a|c)ss"] 7 | }, 8 | "rules": { 9 | "no-trailing-zero": 2, 10 | "bem-depth": 3, 11 | "brace-style": 2, 12 | "declarations-before-nesting": 2, 13 | "empty-line-between-blocks": 2, 14 | "leading-zero": 0, 15 | "one-declaration-per-line": 2, 16 | "space-after-colon": 2, 17 | "space-between-parens": 2, 18 | "trailing-semicolon": 1, 19 | "zero-unit": 1, 20 | "no-color-keywords": 2, 21 | "no-duplicate-properties": 0, 22 | "space-before-brace": 1, 23 | "extends-before-mixins": 2, 24 | "extends-before-declarations": 2, 25 | "placeholder-in-extend": 2, 26 | "mixins-before-declarations": [ 27 | 2, 28 | { 29 | "exclude": [ 30 | "breakpoint", 31 | "above", 32 | "below", 33 | "between", 34 | "mq" 35 | ] 36 | } 37 | ], 38 | "no-warn": 1, 39 | "no-debug": 1, 40 | "no-ids": 2, 41 | "no-important": 1, 42 | "hex-notation": [ 43 | 2, 44 | { 45 | "style": "lowercase" 46 | } 47 | ], 48 | "indentation": [ 49 | 2, 50 | { 51 | "size": 2 52 | } 53 | ], 54 | "property-sort-order": 2 55 | } 56 | } -------------------------------------------------------------------------------- /src/styles/variables.scss: -------------------------------------------------------------------------------- 1 | // ================================================== 2 | // Variables 3 | // 4 | // 1. Spaces 5 | // 2. Media Queries 6 | // 3. zIndex 7 | // ================================================== 8 | 9 | @import '~rupture-sass/rupture'; 10 | @import 'palettes'; 11 | 12 | // -------------------------------------------------- 13 | // 1. Spaces 14 | // -------------------------------------------------- 15 | 16 | $space-xxs : .4rem; 17 | $space-xs : .8rem; 18 | $space-sm : 1.6rem; 19 | $space : 2.4rem; 20 | $space-md : 3.2rem; 21 | $space-lg : 4.8rem; 22 | $space-xlg : 6.4rem; 23 | $space-xxlg : 9.6rem; 24 | 25 | // -------------------------------------------------- 26 | // 2. Media Queries 27 | // -------------------------------------------------- 28 | 29 | $screen-xs : 360px; // xExtra small screen / phone 30 | $screen-sm : 768px; // Extra small screen / phone 31 | $screen-md : 960px; // Small screen / tablet 32 | $screen-lg : 1280px; // Medium screen / desktop 33 | $screen-xlg : 1920px; // Extra Large screen / wide desktop 34 | 35 | $rupture: map-merge($rupture, 36 | ( 37 | anti-overlap: -1px, 38 | scale: 0 $screen-xs $screen-sm $screen-md $screen-lg, 39 | scale-names: '0' 'xs' 'sm' 'md' 'lg' 'xlg' 40 | ) 41 | ); 42 | 43 | // -------------------------------------------------- 44 | // 3. zIndex 45 | // -------------------------------------------------- 46 | 47 | $zindex-bg : -1; 48 | $zindex-default : 1; 49 | -------------------------------------------------------------------------------- /src/index.pug: -------------------------------------------------------------------------------- 1 | - var data = require('../app.config.json'); 2 | 3 | doctype html 4 | html(lang='en') 5 | head 6 | title #{data.title} - #{data.description} 7 | meta(charset='utf-8') 8 | meta(name='description' content=data.description) 9 | meta(name='image' content=data.url + data.logo) 10 | meta(itemprop='name' content=data.title) 11 | meta(itemprop='description' content=data.description) 12 | meta(itemprop='image' content=data.url + data.logo) 13 | meta(name='twitter:card' content='summary') 14 | meta(name='twitter:title' content=data.title) 15 | meta(name='twitter:description' content=data.description) 16 | meta(name='twitter:site' content=data.twitter) 17 | meta(name='twitter:creator' content=data.twitter) 18 | meta(name='twitter:image:src' content=data.url + data.logo) 19 | meta(name='og:title' content=data.title) 20 | meta(name='og:description' content=data.description) 21 | meta(name='og:image' content=data.url + data.logo) 22 | meta(name='og:url' content=data.url) 23 | meta(name='og:site_name' content=data.title) 24 | meta(name='og:locale' content='en') 25 | meta(name='og:type' content='website') 26 | meta(http-equiv='X-UA-Compatible' content='IE=edge') 27 | meta(name='viewport' content='width=device-width, initial-scale=1, maximum-scale=5') 28 | meta(name='theme-color' content=data.theme_color) 29 | link(rel='shortcut icon' type='image/favicon' href='favicon.ico') 30 | script(async src='https://www.googletagmanager.com/gtag/js?id=' + data.ga) 31 | script. 32 | window.dataLayer = window.dataLayer || []; 33 | function gtag(){dataLayer.push(arguments);} 34 | gtag('js', new Date()); 35 | gtag('config', '#{data.ga}'); 36 | body 37 | include components/welcome/welcome 38 | -------------------------------------------------------------------------------- /src/styles/reset.scss: -------------------------------------------------------------------------------- 1 | /* http://meyerweb.com/eric/tools/css/reset/ 2 | v2.0 | 20110126 3 | License: none (public domain) 4 | */ 5 | 6 | * { 7 | box-sizing: border-box; 8 | 9 | &:after, &:before { 10 | box-sizing: border-box; 11 | } 12 | } 13 | 14 | html, body, div, span, applet, object, iframe, 15 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 16 | a, abbr, acronym, address, big, cite, code, 17 | del, dfn, em, img, ins, kbd, q, s, samp, 18 | small, strike, strong, sub, sup, tt, var, 19 | b, u, i, center, 20 | dl, dt, dd, ol, ul, li, 21 | fieldset, form, label, legend, 22 | table, caption, tbody, tfoot, thead, tr, th, td, 23 | article, aside, canvas, details, embed, 24 | figure, figcaption, footer, header, hgroup, 25 | menu, nav, output, ruby, section, summary, 26 | time, mark, audio, video { 27 | border: 0; 28 | font: inherit; 29 | font-size: 100%; 30 | margin: 0; 31 | padding: 0; 32 | vertical-align: baseline; 33 | } 34 | 35 | /* HTML5 display-role reset for older browsers */ 36 | article, aside, details, figcaption, figure, 37 | footer, header, hgroup, menu, nav, section { 38 | display: block; 39 | } 40 | 41 | body { 42 | line-height: 1; 43 | } 44 | 45 | ol, ul { 46 | list-style: none; 47 | } 48 | 49 | blockquote, q { 50 | quotes: none; 51 | } 52 | 53 | blockquote:before, blockquote:after, 54 | q:before, q:after { 55 | content: ''; 56 | content: none; 57 | } 58 | 59 | table { 60 | border-collapse: collapse; 61 | border-spacing: 0; 62 | } 63 | 64 | img, 65 | svg { 66 | max-width: 100%; 67 | vertical-align: top; 68 | } 69 | 70 | button { 71 | background-color: transparent; 72 | border: 0; 73 | padding: 0; 74 | 75 | &:focus { 76 | outline: 0; 77 | } 78 | } 79 | 80 | textarea { 81 | -ms-overflow-style: none; 82 | } 83 | 84 | fieldset { 85 | border: 0; 86 | padding: 0; 87 | } 88 | 89 | input[type="search"]::-webkit-search-decoration, 90 | input[type="search"]::-webkit-search-cancel-button, 91 | input[type="search"]::-webkit-search-results-button, 92 | input[type="search"]::-webkit-search-results-decoration { 93 | -webkit-appearance: none; 94 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kratos-boilerplate", 3 | "version": "3.1.0", 4 | "title": "Kratos Boilerplate", 5 | "description": "A simple boilerplate for creating a static PWA using Webpack, Pug, PostCSS and CSS Modules", 6 | "homepage": "https://github.com/felipefialho/kratos-boilerplate", 7 | "author": { 8 | "name": "Felipe Fialho", 9 | "email": "hi@felipefialho.com", 10 | "url": "https://www.felipefialho.com" 11 | }, 12 | "browserslist": [ 13 | "> 1%", 14 | "last 2 versions" 15 | ], 16 | "engines": { 17 | "npm": "please-use-yarn", 18 | "yarn": ">= 1.20", 19 | "node": ">= 16.0.0" 20 | }, 21 | "scripts": { 22 | "start": "webpack serve --mode development", 23 | "build": "webpack --mode production", 24 | "deploy": "gh-pages-deploy", 25 | "analyzer": "npm run build && webpack-bundle-analyzer ./dist/stats.json", 26 | "lint": "npm run lint:js && npm run lint:scss", 27 | "lint:scss": "sass-lint -c sass-lint.json 'src/**/*.scss' -v -q", 28 | "lint:js": "eslint ./src/", 29 | "fix:js": "eslint ./src/ --fix" 30 | }, 31 | "gh-pages-deploy": { 32 | "staticpath": "dist", 33 | "prep": [ 34 | "build" 35 | ], 36 | "noprompt": true 37 | }, 38 | "devDependencies": { 39 | "@babel/core": "^7.22.5", 40 | "@babel/preset-env": "^7.22.14", 41 | "autoprefixer": "^10.4.15", 42 | "babel-core": "^6.26.3", 43 | "babel-loader": "^8.3.0", 44 | "babel-preset-env": "^1.7.0", 45 | "clean-webpack-plugin": "^4.0.0", 46 | "copy-webpack-plugin": "^6.4.1", 47 | "css-loader": "^5.2.7", 48 | "cssnano": "^6.0.1", 49 | "eslint": "^8.48.0", 50 | "file-loader": "6.2.0", 51 | "gh-pages-deploy": "^0.5.1", 52 | "html-webpack-plugin": "^4.5.2", 53 | "husky": "^8.0.3", 54 | "imagemin-webpack-plugin": "^2.4.2", 55 | "lost": "^9.0.2", 56 | "mini-css-extract-plugin": "^1.6.2", 57 | "node-sass": "^9.0.0", 58 | "offline-plugin": "^5.0.7", 59 | "postcss": "^8.4.29", 60 | "postcss-font-magician": "^3.0.0", 61 | "postcss-loader": "^4.3.0", 62 | "postcss-modules": "^6.0.0", 63 | "pug": "^3.0.2", 64 | "pug-loader": "^2.4.0", 65 | "rucksack-css": "^1.0.2", 66 | "rupture-sass": "^0.3.0", 67 | "sass": "^1.66.1", 68 | "sass-lint": "^1.13.1", 69 | "sass-loader": "^10.1.1", 70 | "style-loader": "^2.0.0", 71 | "uglifyjs-webpack-plugin": "^2.2.0", 72 | "webpack": "^4.46.0", 73 | "webpack-bundle-analyzer": "^4.9.1", 74 | "webpack-cli": "^4.9.2", 75 | "webpack-dev-server": "^4.15.1", 76 | "webpack-pwa-manifest": "^4.3.0" 77 | }, 78 | "husky": { 79 | "hooks": { 80 | "pre-commit": "npm run lint" 81 | } 82 | }, 83 | "dependencies": {} 84 | } 85 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 |
2 |
3 |