diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..6e87a00 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +# Editor configuration, see http://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..375b9af --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,26 @@ +module.exports = { + env: { + browser: true, + es6: true, + jquery: true + }, + globals: { + "fetch": false, + "window": true, + "document": true + }, + extends: 'eslint:recommended', + parserOptions: { + sourceType: 'module' + }, + rules: { + indent: ['error', 2], + 'no-unused-vars': [1, { vars: 'local', args: 'none' }], + 'linebreak-style': 'off', + quotes: ['error', 'single'], + semi: ['error', 'always'] + }, + env: { + node: true + } +}; diff --git a/.gitignore b/.gitignore index 40b878d..ec26407 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,5 @@ -node_modules/ \ No newline at end of file +dist +node_modules +package-lock.json +.DS_Store +.vscode/settings.json diff --git a/.stylintrc b/.stylintrc new file mode 100644 index 0000000..021eb5c --- /dev/null +++ b/.stylintrc @@ -0,0 +1,62 @@ +{ + "blocks": false, + "brackets": { + "expect": "never", + "error": true + }, + "colons": { + "expect": "never", + "error": true + }, + "colors": "always", + "commaSpace": "aways", + "commentSpace": "always", + "cssLiteral": "never", + "customProperties": [], + "depthLimit": { + "expect": 3, + "error": true + }, + "duplicates": true, + "efficient": "always", + "extendPref": false, + "globalDupe": false, + "groupOutputByFile": true, + "indentPref": { + "expect": 2, + "error": true + }, + "leadingZero": "never", + "maxErrors": false, + "maxWarnings": false, + "mixed": false, + "mixins": [], + "namingConvention": false, + "namingConventionStrict": false, + "none": "never", + "noImportant": false, + "parenSpace": false, + "placeholders": "always", + "prefixVarsWithDollar": "always", + "quotePref": false, + "reporterOptions": { + "columns": ["lineData", "severity", "description", "rule"], + "columnSplitter": " ", + "showHeaders": false, + "truncate": true + }, + "semicolons": { + "expect": "never", + "error": true + }, + "sortOrder": { + "expect": "alphabetical", + "error": true + }, + "stackedProperties": "never", + "trailingWhitespace": false, + "universal": false, + "valid": false, + "zeroUnits": "never", + "zIndexNormalize": false +} diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..9ba9abc --- /dev/null +++ b/.travis.yml @@ -0,0 +1,10 @@ +language: node_js +node_js: + - "7" +before_script: + - npm i +cache: + directories: + - "node_modules" +script: + - npm run deploy diff --git a/README.md b/README.md index c3a90dd..d3b52c4 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,73 @@ -Survey - Front-End -======= +

+ +

-Pesquisa de mercado realizada entre front-end developers do Brasil. +# Survey Front-end Brasil -[Visualizar o projeto](http://www.felipefialho.com/survey) +> Pesquisa salarial entre frontenders do Brasil -## Contribuição +[![license](https://img.shields.io/github/license/LFeh/survey.svg)](./license.md) +[![GitHub contributors](https://img.shields.io/github/contributors/LFeh/survey.svg)](https://github.com/LFeh/survey/graphs/contributors) -Por favor leia o [Coding Style](https://github.com/LFeh/coding-style/) para [Issues](https://github.com/LFeh/survey/issues) e as regras de código. +## Getting Started -Todas as alterações devem ser feitas na pasta `/dev`. O CSS precisa ser modificado usando o pré-processador **LESS**. +```sh +# install dependencies +$ npm i -Issues e commits devem ser enviados em pt-BR. +# Run the project +$ npm start +``` - ```bash +With the commands above, you have everything to start. + +## About CSS + +### Post CSS libs - # Getting Started - # --------------- +For grid system uses [Autoprefixer](https://github.com/postcss/autoprefixer) to make easy use browser prefixes, [Lost](https://github.com/peterramsing/lost) with some help from, [Rucksack](http://simplaio.github.io/rucksack/) for animations, reset and a lot of great mixins, [Rupture](https://github.com/jenius/rupture) for responsive utilities. And [Font Magician](https://github.com/jonathantneal/postcss-font-magician/) to get the webfonts. - # 1. Fork esse repositório e clone - git clone https://github.com//survey.git +### CSS Modules - # 2. Navegue até a nova pasta - cd survey +To make easier create your components and avoid a lot of problems, it boilerplate use [CSS Modules](https://github.com/css-modules/css-modules). - # 3. Instale as dependências - npm install +Example +```css +.host + text-align center - # Development - # ----------- +.title + font-size 4rem - # Para assistir as alterações no .less e no .js rode o comando - grunt w +.description + font-size 2rem +``` - # Build o projeto para deploy - grunt build - ``` +After the transformation it will become like this + +```css +._host_4897k_1 { + text-align: center; +} + +._title_4897k_9 { + font-size: 4rem; +} + +._description_4897k_12 { + font-size: 2rem; +} +``` + +## Tasks + +- `npm start`: run all tasks and initialize watch for changes and a server +- `npm run build`: run all production tasks create a `dist` folder to deploy +- `npm run lint`: lint javascript and css +- `npm run fix`: command to fix all eslint errors +- `npm run deploy`: run all tasks to build and deploy on gh-pages + +## License + +MIT License © Felipe Fialho diff --git a/app.config.json b/app.config.json new file mode 100644 index 0000000..20395c7 --- /dev/null +++ b/app.config.json @@ -0,0 +1,10 @@ +{ + "title": "Survey - Front-End Brasil 2018", + "description": "Pesquisa salarial entre frontenders do Brasil", + "url": "https://github.com/LFeh/survey", + "logo": "images/logo.png", + "theme_color": "#333333", + "short_name": "Survey 2018", + "ga": "UA-40410936-3", + "twitter": "@lfeh" +} diff --git a/license b/license new file mode 100644 index 0000000..6afa163 --- /dev/null +++ b/license @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Felipe Fialho + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/package.json b/package.json new file mode 100644 index 0000000..6501f06 --- /dev/null +++ b/package.json @@ -0,0 +1,75 @@ +{ + "name": "survey", + "version": "2.0.0", + "title": "Survey", + "description": "Pesquisa salarial entre frontenders do Brasil", + "homepage": "https://github.com/LFeh/survey", + "browserslist": [ + "> 1%", + "last 2 versions" + ], + "author": { + "name": "Felipe Fialho", + "email": "hi@felipefialho.com", + "url": "http://www.felipefialho.com" + }, + "scripts": { + "start": "webpack-dev-server --mode development", + "build": "webpack --mode production", + "deploy": "gh-pages-deploy", + "analyzer": "npm run build && webpack-bundle-analyzer ./dist/stats.json", + "lint": "npm run lint:js && npm run lint:styl", + "lint:styl": "stylint src/**/*.styl", + "lint:scss": "sass-lint -c sass-lint.json 'src/**/*.scss' -v -q", + "lint:js": "eslint ./src/", + "fix:js": "eslint ./src/ --fix", + "precommit": "npm run lint" + }, + "gh-pages-deploy": { + "staticpath": "dist", + "prep": [ + "build" + ], + "noprompt": true + }, + "dependencies": {}, + "devDependencies": { + "autoprefixer": "^9.0.0", + "babel-core": "^6.26.3", + "babel-loader": "^7.1.5", + "babel-preset-env": "^1.7.0", + "clean-webpack-plugin": "^0.1.19", + "copy-webpack-plugin": "^4.5.2", + "css-loader": "^1.0.0", + "cssnano": "^4.0.2", + "eslint": "^5.1.0", + "file-loader": "1.1.11", + "gh-pages-deploy": "^0.5.0", + "html-webpack-plugin": "^3.2.0", + "imagemin-webpack-plugin": "^2.1.5", + "lost": "^8.3.0", + "mini-css-extract-plugin": "^0.4.1", + "node-sass": "^4.9.2", + "offline-plugin": "^5.0.5", + "postcss-font-magician": "^2.2.1", + "postcss-loader": "^2.1.6", + "postcss-modules": "^1.1.0", + "pug": "^2.0.3", + "pug-loader": "^2.4.0", + "rucksack-css": "^1.0.2", + "rupture": "^0.7.1", + "rupture-sass": "^0.3.0", + "sass-lint": "^1.12.1", + "sass-loader": "^7.0.3", + "style-loader": "^0.21.0", + "stylint": "^1.5.9", + "stylus": "^0.54.5", + "stylus-loader": "^3.0.2", + "uglifyjs-webpack-plugin": "^1.2.7", + "webpack": "^4.16.1", + "webpack-bundle-analyzer": "^2.13.1", + "webpack-cli": "^3.0.8", + "webpack-dev-server": "^3.1.4", + "webpack-pwa-manifest": "^3.6.2" + } +} diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..e698775 --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,22 @@ +module.exports = { + plugins: { + 'autoprefixer': {}, + 'rucksack-css': {}, + 'lost': {}, + 'postcss-font-magician': {}, + 'cssnano': {}, + 'postcss-modules': { + getJSON: function(cssFileName, json, outputFileName) { + const fs = require('fs'); + const path = require('path'); + const isComponent = /components/.test(path.dirname(cssFileName)); + + if (isComponent) { + const cssName = path.basename(`${cssFileName}`); + const jsonFileName = path.resolve(`${path.dirname(cssFileName)}/${cssName.split('.')[0]}-css.json`); + fs.writeFileSync(jsonFileName, JSON.stringify(json)); + } + } + } + } +}; diff --git a/src/app.js b/src/app.js new file mode 100644 index 0000000..7525b69 --- /dev/null +++ b/src/app.js @@ -0,0 +1,12 @@ +import * as offline from 'offline-plugin/runtime'; +import './app.styl'; +import './components/welcome/welcome.js'; +import './components/introduction/introduction.js'; +import './components/footer/footer.js'; + + +offline.install({ + onUpdateReady: function() { + offline.applyUpdate(); + } +}); diff --git a/src/app.styl b/src/app.styl new file mode 100644 index 0000000..5fb1b16 --- /dev/null +++ b/src/app.styl @@ -0,0 +1,2 @@ +@import 'styles/core'; +@import 'styles/base'; diff --git a/src/favicon.ico b/src/favicon.ico new file mode 100644 index 0000000..4f131de Binary files /dev/null and b/src/favicon.ico differ diff --git a/src/images/logo.png b/src/images/logo.png new file mode 100644 index 0000000..f1a9461 Binary files /dev/null and b/src/images/logo.png differ diff --git a/src/index.pug b/src/index.pug new file mode 100644 index 0000000..bea69a7 --- /dev/null +++ b/src/index.pug @@ -0,0 +1,40 @@ +- var data = require('../app.config.json'); + +doctype html +html(lang='pt-br') + head + title #{data.title} - #{data.description} + meta(charset='utf-8') + meta(name='description' content=data.description) + meta(name='image' content=data.url + data.logo) + meta(itemprop='name' content=data.title) + meta(itemprop='description' content=data.description) + meta(itemprop='image' content=data.url + data.logo) + meta(name='twitter:card' content='summary') + meta(name='twitter:title' content=data.title) + meta(name='twitter:description' content=data.description) + meta(name='twitter:site' content=data.twitter) + meta(name='twitter:creator' content=data.twitter) + meta(name='twitter:image:src' content=data.url + data.logo) + meta(name='og:title' content=data.title) + meta(name='og:description' content=data.description) + meta(name='og:image' content=data.url + data.logo) + meta(name='og:url' content=data.url) + meta(name='og:site_name' content=data.title) + meta(name='og:locale' content='en') + meta(name='og:type' content='website') + meta(http-equiv='X-UA-Compatible' content='IE=edge') + meta(name='viewport' content='width=device-width, initial-scale=1, maximum-scale=5') + meta(name='theme-color' content=data.theme_color) + link(rel='shortcut icon' type='image/favicon' href='favicon.ico') + script(async src='https://www.googletagmanager.com/gtag/js?id=' + data.ga) + script. + window.dataLayer = window.dataLayer || []; + function gtag(){dataLayer.push(arguments);} + gtag('js', new Date()); + gtag('config', '#{data.ga}'); + body + include components/welcome/welcome.pug + .main + include components/introduction/introduction.pug + include components/footer/footer.pug diff --git a/src/js/main.js b/src/js/main.js new file mode 100644 index 0000000..e69de29 diff --git a/src/styles/base.styl b/src/styles/base.styl new file mode 100644 index 0000000..770b675 --- /dev/null +++ b/src/styles/base.styl @@ -0,0 +1,31 @@ +* + box-sizing border-box + margin 0 + padding 0 + + &:before + &:after + box-sizing border-box + + &:hover + &:focus + outline transparent + +a + cursor pointer + +html + -moz-osx-font-smoothing auto + -webkit-font-smoothing auto + font-size 10px + font-size responsive 8px 10px + +body + -webkit-overflow-scrolling touch + background-color $gray-white + color $gray-darker + font-family 'Open Sans', Arial, sans-serif + font-size 1.8rem + font-smoothing auto + overflow-x hidden + diff --git a/src/styles/core.styl b/src/styles/core.styl new file mode 100644 index 0000000..3aad32c --- /dev/null +++ b/src/styles/core.styl @@ -0,0 +1,2 @@ +@import 'core/variables' + diff --git a/src/styles/core/variables.styl b/src/styles/core/variables.styl new file mode 100644 index 0000000..d501365 --- /dev/null +++ b/src/styles/core/variables.styl @@ -0,0 +1,73 @@ +// ================================================== +// Variables +// +// 1. Colors +// 2. Spaces +// 3. Media Queries +// 4. zIndex +// ================================================== + +// -------------------------------------------------- +// 1. Colors +// -------------------------------------------------- + +// +// Colors +// -------------------------------------------------- + +$gray-darker = #282828 +$gray-dark = #333 +$gray = #666 +$gray-medium = #aaa +$gray-light = #c8c8c8 +$gray-lighter = #dedede +$gray-white = #fafafa +$white = #fff + +$yellow = #f0ad4e +$green = #5cb85c +$blue = #5891ff +$blue-light = #aceff9 + +// ------------------------------------------------- +// 2. Spaces +// -------------------------------------------------- + +$space-xxs = .4rem // Smallest space margin +$space-xs = .8rem // Extra small space margin +$space-sm = 1.6rem // Small space margin +$space = 2.4rem // Regular space margin +$space-md = 3.2rem // Medium space margin +$space-lg = 4.8rem // Large space margin +$space-xlg = 6.4rem // Extra Large space margin +$space-xxlg = 8.8rem // Extra Large space margin + +// -------------------------------------------------- +// 3. Media Queries +// -------------------------------------------------- + +$screen-xxs = 380px // xExtra small screen / phone +$screen-xs = 440px // Extra small screen / phone +$screen-sm = 768px // Small screen / tablet +$screen-md = 992px // Medium screen / desktop +$screen-lg = 1200px // Large screen / wide desktop +$screen-xlg = 1400px // Extra Large screen / wide desktop +$screen-xxlg = 1600px // Extra Large screen / wide desktop + +// Rupture Settings +// @stylint off +rupture.mobile-cutoff = $screen-sm +rupture.tablet-cutoff = $screen-md +rupture.desktop-cutoff = $screen-lg +rupture.hd-cutoff = $screen-xlg + +rupture.scale = 0 $screen-xxs $screen-sm $screen-md $screen-lg $screen-xlg $screen-xxlg +rupture.scale-names = 'xxs' 'xs' 'sm' 'md' 'lg' 'xlg' 'hd' +rupture.anti-overlap = -1px +// @stylint on + +// -------------------------------------------------- +// 4. zIndex +// -------------------------------------------------- + +$zindex-default = 1 diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..38a2062 --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,157 @@ +const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; +const CleanWebpackPlugin = require('clean-webpack-plugin'); +const config = require('./app.config.json'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const ImageminPlugin = require('imagemin-webpack-plugin').default; +const MiniCssExtractPlugin = require('mini-css-extract-plugin'); +const OfflinePlugin = require('offline-plugin'); +const path = require('path'); +const rupture = require('rupture'); +const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); +const webpack = require('webpack'); +const WebpackPwaManifest = require('webpack-pwa-manifest'); + +const webapp = { + name: config.title, + short_name: config.short_name, + description: config.description, + background_color: config.theme_color, + theme_color: config.theme_color, + orientation: 'landscape', + icons: [ + { + src: path.resolve('./src/images/logo.png'), + sizes: [96, 128, 192, 256, 384, 512] + } + ] +}; + +const copyFiles = [ + { from: './src/images/', to: './images' }, + { from: './src/favicon.ico', to: './' }, +]; + +const sw = { + safeToUseOptionalCaches: true, + caches: { + main: ['index.html'], + additional: ['*.js?*'] + }, + navigateFallbackURL: '/', + autoUpdate: true, + responseStrategy: 'cache-first', + ServiceWorker: { events: true }, + AppCache: { events: true } +}; + +const baseWebpack = { + entry: { + app: './src/app.js' + }, + output: { + path: path.resolve(__dirname, 'dist'), + filename: '[name].bundle.js' + }, + module: { + rules: [ + { + test: /\.pug/, + loader: 'pug-loader', + }, + { + test: /\.styl/, + use: [ + 'style-loader', + MiniCssExtractPlugin.loader, + { + loader: 'css-loader', + options: { importLoaders: 1 } + }, + 'postcss-loader', + { + loader: 'stylus-loader', + options: { + use: [rupture()], + } + } + ] + }, + { + test: /\.scss/, + use: [ + 'style-loader', + MiniCssExtractPlugin.loader, + { + loader: 'css-loader', + options: { importLoaders: 1 } + }, + 'postcss-loader', + { + loader: 'sass-loader' + } + ] + }, + { + test: /\.jpe?g$|\.gif$|\.png$|\.svg$/, + use: 'file-loader' + }, + { + test: /\.js$/, + exclude: /node_modules/, + use: { + loader: 'babel-loader', + options: { + presets: ['env'] + } + } + } + ] + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env.WEBPACK_MODE': JSON.stringify(process.env.WEBPACK_MODE) + }), + new CleanWebpackPlugin(['dist']), + new HtmlWebpackPlugin({ + hash: true, + template: './src/index.pug' + }), + new MiniCssExtractPlugin({ + filename: 'style.[contenthash].css', + }), + new CopyWebpackPlugin(copyFiles) + ] +}; + +const prodStart = () => { + baseWebpack.optimization = { + minimizer: [ new UglifyJsPlugin() ], + }; + baseWebpack.plugins.push(new ImageminPlugin({ test: /\.(jpe?g|png|gif|svg)$/i })); + baseWebpack.plugins.push(new BundleAnalyzerPlugin({analyzerMode: 'disabled'})); + baseWebpack.plugins.push(new WebpackPwaManifest(webapp)); + baseWebpack.plugins.push(new OfflinePlugin(sw)); +}; + +const devStart = () => { + baseWebpack.devServer = { + contentBase: path.join(__dirname, 'dist'), + compress: true, + open: true, + port: 9000 + }; +}; + +module.exports = (env, options) => { + if (options.mode === 'production') { + prodStart(); + } + + if (options.mode === 'development') { + devStart(); + } + + return baseWebpack; +}; + \ No newline at end of file