├── src ├── app.js ├── components │ ├── button │ │ ├── button.pug │ │ └── button.css │ └── plan │ │ ├── plan.pug │ │ └── plan.css ├── main.css └── index.pug ├── .DS_Store ├── README.md ├── .gitignore ├── package.json ├── webpack.config.js └── dist ├── index.html ├── main.css └── main.bundle.js /src/app.js: -------------------------------------------------------------------------------- 1 | import './main.css' -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krashaen/pugWithWebpack/HEAD/.DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pugWithWebpack 2 | ## перед запуском нужно выполнить 3 | 1) `npm install` 4 | 2) `npm run dev` 5 | готовые файлы появятся в папке `dist` 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | coverage/ 3 | .history/ 4 | .idea/ 5 | .vscode/ 6 | .project/ 7 | build/ 8 | npm-debug.log 9 | src/assets/index.html 10 | gemini/gemini-reports 11 | gemini/screens 12 | dist/ -------------------------------------------------------------------------------- /src/components/button/button.pug: -------------------------------------------------------------------------------- 1 | mixin btn(options) 2 | - 3 | var buttonClassName = "button" 4 | buttonClassName += options.isBlue ? " button-blue" : "" 5 | button(class = buttonClassName)= options.title || "Button" -------------------------------------------------------------------------------- /src/main.css: -------------------------------------------------------------------------------- 1 | @import "components/button/button.css"; 2 | @import "components/plan/plan.css"; 3 | 4 | body { 5 | font-family: 'Source Sans Pro', Arial, sans-serif; 6 | font-size: 18px; 7 | line-height: 1.45; 8 | color: #999; 9 | -webkit-font-smoothing: antialiased; 10 | } 11 | 12 | .wrapper { 13 | display: flex; 14 | justify-content: space-around; 15 | flex-wrap: wrap; 16 | } 17 | -------------------------------------------------------------------------------- /src/components/button/button.css: -------------------------------------------------------------------------------- 1 | .button { 2 | outline: none; 3 | border: 1px solid #e0e0e0; 4 | color: #008ed6; 5 | padding: 14px 40px; 6 | border-radius: 3px; 7 | font-size: 14px; 8 | font-weight: bold; 9 | text-transform: uppercase; 10 | cursor: pointer; 11 | } 12 | .button:hover { 13 | background: #008ed6; 14 | border: 1px solid #008ed6; 15 | color: #fff; 16 | } 17 | .button-blue { 18 | color: #fff; 19 | background-color: #008ed6; 20 | } 21 | -------------------------------------------------------------------------------- /src/index.pug: -------------------------------------------------------------------------------- 1 | include ./components/plan/plan 2 | 3 | doctype html 4 | html(lang="en") 5 | head 6 | meta(charset="UTF-8") 7 | title Пример страницы 8 | link(rel="stylesheet" type="text/css" href="main.css") 9 | 10 | body 11 | .wrapper 12 | +plan({title: "free", price: 0}) 13 | +plan({title: "personal", price: 25}) 14 | +plan({title: "business", price: 50, isBusiness: true}) 15 | +plan({title: "ultimate", price: 99}) 16 | 17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "component", 3 | "version": "0.0.1", 4 | "description": "", 5 | "main": "app.js", 6 | "scripts": { 7 | "build": "webpack --mode=production", 8 | "build:dev": "webpack --mode=development", 9 | "start:dev": "webpack-dev-server --mode=development", 10 | "dev": "webpack --watch --mode development", 11 | "prod": "webpack --mode production" 12 | }, 13 | "author": "mikhail krasheninnikov", 14 | "devDependencies": { 15 | "html-webpack-plugin": "^3.2.0", 16 | "pug": "^2.0.3", 17 | "pug-loader": "^2.4.0", 18 | "webpack": "^4.29.5", 19 | "webpack-cli": "^3.2.3", 20 | "webpack-dev-server": "^3.2.1" 21 | }, 22 | "dependencies": { 23 | "css-loader": "^2.1.0", 24 | "extract-text-webpack-plugin": "^4.0.0-beta.0", 25 | "html-loader": "^0.5.5", 26 | "pug-html-loader": "^1.1.5", 27 | "style-loader": "^0.23.1" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/components/plan/plan.pug: -------------------------------------------------------------------------------- 1 | include ../button/button 2 | 3 | mixin plan(options) 4 | - 5 | var priceClassName = "price" 6 | priceClassName += options.isBusiness ? " price-business" : "" 7 | var titleClassName = "title" 8 | titleClassName += options.isBusiness ? " title-business" : "" 9 | var countClassName = "price-count" 10 | countClassName += options.isBusiness ? " price-count-business" : "" 11 | .plan 12 | div(class = titleClassName)= options.title 13 | div(class = priceClassName) 14 | span(class = countClassName) 15 | em $ 16 | span= options.price 17 | small.period /per month 18 | .description 19 | p 20 | | Fusce fermentum placerat magna ac pharetra. 21 | | Aliquam euismod elit non ipsum 22 | a.description-link(href="#")= "lacinia " 23 | | consectetur. 24 | 25 | .buy-button 26 | +btn({title: "Order Now", isBlue: options.isBusiness}) 27 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const ExtractTextPlugin = require('extract-text-webpack-plugin'); 3 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 4 | const pug = { 5 | test: /\.pug$/, 6 | use: ['html-loader?attrs=false', 'pug-html-loader'] 7 | }; 8 | const config = { 9 | entry: './src/app.js', 10 | output: { 11 | path: path.resolve(__dirname, 'dist'), 12 | filename: '[name].bundle.js' 13 | }, 14 | module: { 15 | rules: [ 16 | pug, 17 | { 18 | test: /\.css$/, 19 | use: ExtractTextPlugin.extract( 20 | { 21 | fallback: 'style-loader', 22 | use: ['css-loader'] 23 | }) 24 | }, 25 | ], 26 | }, 27 | 28 | plugins: [ 29 | new ExtractTextPlugin( 30 | { 31 | filename: 'main.css', 32 | } 33 | ), 34 | new HtmlWebpackPlugin({ 35 | filename: 'index.html', 36 | template: 'src/index.pug', 37 | inject: false 38 | }), 39 | 40 | ] 41 | }; 42 | module.exports = config; -------------------------------------------------------------------------------- /src/components/plan/plan.css: -------------------------------------------------------------------------------- 1 | .plan { 2 | border: 1px solid #e0e0e0; 3 | flex-basis: 270px; 4 | margin: 10px; 5 | } 6 | .title { 7 | display: flex; 8 | align-items: center; 9 | justify-content: center; 10 | height: 70px; 11 | border-bottom: 1px solid #e0e0e0; 12 | font-size: 24px; 13 | text-transform: uppercase; 14 | font-weight: 700; 15 | color: #1a1a1a; 16 | } 17 | .title-business { 18 | color: #008ed6; 19 | } 20 | .price { 21 | padding: 32px 0 35px; 22 | text-align: center; 23 | border-bottom: 1px solid #e0e0e0; 24 | } 25 | .price-business { 26 | background-color: #008ed6; 27 | color: #fafafa; 28 | } 29 | .price-count { 30 | color: #1a1a1a; 31 | font-size: 60px; 32 | font-weight: 600; 33 | line-height: 1; 34 | } 35 | .price-count-business { 36 | color: #fafafa; 37 | } 38 | .price-count em { 39 | vertical-align: super; 40 | font-size: 28px; 41 | font-style: normal; 42 | } 43 | .period { 44 | line-height: 1; 45 | display: block; 46 | width: 100%; 47 | font-size: 18px; 48 | margin-top: 5px; 49 | } 50 | .description { 51 | padding: 45px 20px 29px; 52 | text-align: center; 53 | } 54 | .description-link { 55 | text-decoration: none; 56 | color: #337ab7; 57 | } -------------------------------------------------------------------------------- /dist/index.html: -------------------------------------------------------------------------------- 1 | Пример страницы
free
$ 0/per month

Fusce fermentum placerat magna ac pharetra. 2 | Aliquam euismod elit non ipsum lacinia consectetur.

personal
$ 25/per month

Fusce fermentum placerat magna ac pharetra. 3 | Aliquam euismod elit non ipsum lacinia consectetur.

business
$ 50/per month

Fusce fermentum placerat magna ac pharetra. 4 | Aliquam euismod elit non ipsum lacinia consectetur.

ultimate
$ 99/per month

Fusce fermentum placerat magna ac pharetra. 5 | Aliquam euismod elit non ipsum lacinia consectetur.

-------------------------------------------------------------------------------- /dist/main.css: -------------------------------------------------------------------------------- 1 | .button { 2 | outline: none; 3 | border: 1px solid #e0e0e0; 4 | color: #008ed6; 5 | padding: 14px 40px; 6 | border-radius: 3px; 7 | font-size: 14px; 8 | font-weight: bold; 9 | text-transform: uppercase; 10 | cursor: pointer; 11 | } 12 | .button:hover { 13 | background: #008ed6; 14 | border: 1px solid #008ed6; 15 | color: #fff; 16 | } 17 | .button-blue { 18 | color: #fff; 19 | background-color: #008ed6; 20 | } 21 | .plan { 22 | border: 1px solid #e0e0e0; 23 | flex-basis: 270px; 24 | margin: 10px; 25 | } 26 | .title { 27 | display: flex; 28 | align-items: center; 29 | justify-content: center; 30 | height: 70px; 31 | border-bottom: 1px solid #e0e0e0; 32 | font-size: 24px; 33 | text-transform: uppercase; 34 | font-weight: 700; 35 | color: #1a1a1a; 36 | } 37 | .title-business { 38 | color: #008ed6; 39 | } 40 | .price { 41 | padding: 32px 0 35px; 42 | text-align: center; 43 | border-bottom: 1px solid #e0e0e0; 44 | } 45 | .price-business { 46 | background-color: #008ed6; 47 | color: #fafafa; 48 | } 49 | .price-count { 50 | color: #1a1a1a; 51 | font-size: 60px; 52 | font-weight: 600; 53 | line-height: 1; 54 | } 55 | .price-count-business { 56 | color: #fafafa; 57 | } 58 | .price-count em { 59 | vertical-align: super; 60 | font-size: 28px; 61 | font-style: normal; 62 | } 63 | .period { 64 | line-height: 1; 65 | display: block; 66 | width: 100%; 67 | font-size: 18px; 68 | margin-top: 5px; 69 | } 70 | .description { 71 | padding: 45px 20px 29px; 72 | text-align: center; 73 | } 74 | .description-link { 75 | text-decoration: none; 76 | color: #337ab7; 77 | }body { 78 | font-family: 'Source Sans Pro', Arial, sans-serif; 79 | font-size: 18px; 80 | line-height: 1.45; 81 | color: #999; 82 | -webkit-font-smoothing: antialiased; 83 | } 84 | 85 | .wrapper { 86 | display: flex; 87 | justify-content: space-around; 88 | flex-wrap: wrap; 89 | } 90 | -------------------------------------------------------------------------------- /dist/main.bundle.js: -------------------------------------------------------------------------------- 1 | /******/ (function(modules) { // webpackBootstrap 2 | /******/ // The module cache 3 | /******/ var installedModules = {}; 4 | /******/ 5 | /******/ // The require function 6 | /******/ function __webpack_require__(moduleId) { 7 | /******/ 8 | /******/ // Check if module is in cache 9 | /******/ if(installedModules[moduleId]) { 10 | /******/ return installedModules[moduleId].exports; 11 | /******/ } 12 | /******/ // Create a new module (and put it into the cache) 13 | /******/ var module = installedModules[moduleId] = { 14 | /******/ i: moduleId, 15 | /******/ l: false, 16 | /******/ exports: {} 17 | /******/ }; 18 | /******/ 19 | /******/ // Execute the module function 20 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21 | /******/ 22 | /******/ // Flag the module as loaded 23 | /******/ module.l = true; 24 | /******/ 25 | /******/ // Return the exports of the module 26 | /******/ return module.exports; 27 | /******/ } 28 | /******/ 29 | /******/ 30 | /******/ // expose the modules object (__webpack_modules__) 31 | /******/ __webpack_require__.m = modules; 32 | /******/ 33 | /******/ // expose the module cache 34 | /******/ __webpack_require__.c = installedModules; 35 | /******/ 36 | /******/ // define getter function for harmony exports 37 | /******/ __webpack_require__.d = function(exports, name, getter) { 38 | /******/ if(!__webpack_require__.o(exports, name)) { 39 | /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 40 | /******/ } 41 | /******/ }; 42 | /******/ 43 | /******/ // define __esModule on exports 44 | /******/ __webpack_require__.r = function(exports) { 45 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 46 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 47 | /******/ } 48 | /******/ Object.defineProperty(exports, '__esModule', { value: true }); 49 | /******/ }; 50 | /******/ 51 | /******/ // create a fake namespace object 52 | /******/ // mode & 1: value is a module id, require it 53 | /******/ // mode & 2: merge all properties of value into the ns 54 | /******/ // mode & 4: return value when already ns object 55 | /******/ // mode & 8|1: behave like require 56 | /******/ __webpack_require__.t = function(value, mode) { 57 | /******/ if(mode & 1) value = __webpack_require__(value); 58 | /******/ if(mode & 8) return value; 59 | /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 60 | /******/ var ns = Object.create(null); 61 | /******/ __webpack_require__.r(ns); 62 | /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 63 | /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 64 | /******/ return ns; 65 | /******/ }; 66 | /******/ 67 | /******/ // getDefaultExport function for compatibility with non-harmony modules 68 | /******/ __webpack_require__.n = function(module) { 69 | /******/ var getter = module && module.__esModule ? 70 | /******/ function getDefault() { return module['default']; } : 71 | /******/ function getModuleExports() { return module; }; 72 | /******/ __webpack_require__.d(getter, 'a', getter); 73 | /******/ return getter; 74 | /******/ }; 75 | /******/ 76 | /******/ // Object.prototype.hasOwnProperty.call 77 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 78 | /******/ 79 | /******/ // __webpack_public_path__ 80 | /******/ __webpack_require__.p = ""; 81 | /******/ 82 | /******/ 83 | /******/ // Load entry module and return exports 84 | /******/ return __webpack_require__(__webpack_require__.s = "./src/app.js"); 85 | /******/ }) 86 | /************************************************************************/ 87 | /******/ ({ 88 | 89 | /***/ "./src/app.js": 90 | /*!********************!*\ 91 | !*** ./src/app.js ***! 92 | \********************/ 93 | /*! no exports provided */ 94 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 95 | 96 | "use strict"; 97 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _main_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./main.css */ \"./src/main.css\");\n/* harmony import */ var _main_css__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_main_css__WEBPACK_IMPORTED_MODULE_0__);\n\n\n//# sourceURL=webpack:///./src/app.js?"); 98 | 99 | /***/ }), 100 | 101 | /***/ "./src/main.css": 102 | /*!**********************!*\ 103 | !*** ./src/main.css ***! 104 | \**********************/ 105 | /*! no static exports found */ 106 | /***/ (function(module, exports) { 107 | 108 | eval("// removed by extract-text-webpack-plugin\n\n//# sourceURL=webpack:///./src/main.css?"); 109 | 110 | /***/ }) 111 | 112 | /******/ }); --------------------------------------------------------------------------------