├── .gitignore ├── package-lock.json ├── package.json ├── postcss.config.js ├── readme.md ├── src ├── styles │ ├── global │ │ ├── _global.scss │ │ └── _typography.scss │ ├── sections │ │ ├── _footer.scss │ │ └── _header.scss │ ├── setup │ │ ├── _border-box.scss │ │ ├── _clearfix.scss │ │ └── _normalize.scss │ └── utils │ │ ├── _mixins.scss │ │ └── _variables.scss ├── theme.js └── theme.scss └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | # git ignore pulled from Shopify's Slate repository 2 | 3 | # This file contains a list of files and folders to be ignored when 4 | # committing to a git repository. Ignored files are both Slate project 5 | # specific files as well as commonly ignored files on any project. 6 | 7 | # For more information on this .gitignore files, see GitHub's 8 | # documentation: https://help.github.com/articles/ignoring-files/ 9 | 10 | # Project # 11 | ################### 12 | node_modules 13 | dist 14 | upload 15 | deploy.log 16 | config/shopify.yml 17 | npm-debug.log 18 | .env 19 | .env.* 20 | 21 | 22 | # Compiled source # 23 | ################### 24 | *.com 25 | *.class 26 | *.dll 27 | *.exe 28 | *.o 29 | *.so 30 | 31 | # Packages # 32 | ############ 33 | # it's better to unpack these files and commit the raw source 34 | # git has its own built in compression methods 35 | *.7z 36 | *.dmg 37 | *.gz 38 | *.iso 39 | *.jar 40 | *.rar 41 | *.tar 42 | *.zip 43 | 44 | # Logs and databases # 45 | ###################### 46 | *.log 47 | *.sql 48 | *.sqlite 49 | 50 | # OS generated files # 51 | ###################### 52 | .DS_Store 53 | .DS_Store? 54 | ._* 55 | .Spotlight-V100 56 | .Trashes 57 | ehthumbs.db 58 | Thumbs.db 59 | 60 | # Custom # 61 | ###################### 62 | *.sass-cache* 63 | .cache/* 64 | _site 65 | /.idea 66 | /.vscode 67 | secrets.json 68 | .jekyll-metadata 69 | .ruby-version 70 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tris-shopify-webpack-boilerplate", 3 | "version": "1.0.0", 4 | "description": "A webpack boilerplate for Shopify development", 5 | "main": "theme.js", 6 | "scripts": { 7 | "watch": "webpack --watch --mode development", 8 | "watchall": "concurrently \"theme watch\" \"webpack --watch --mode development\"", 9 | "build": "webpack --mode production" 10 | }, 11 | "keywords": [], 12 | "author": "tr1s", 13 | "license": "ISC", 14 | "dependencies": { 15 | "bulma": "^0.7.4" 16 | }, 17 | "devDependencies": { 18 | "@babel/core": "^7.4.0", 19 | "@babel/preset-env": "^7.4.2", 20 | "@fullhuman/postcss-purgecss": "^1.1.0", 21 | "autoprefixer": "^9.5.0", 22 | "babel-loader": "^8.0.5", 23 | "concurrently": "^4.1.0", 24 | "css-loader": "^2.1.1", 25 | "cssnano": "^4.1.10", 26 | "mini-css-extract-plugin": "^0.5.0", 27 | "node-sass": "^4.11.0", 28 | "postcss-loader": "^3.0.0", 29 | "sass-loader": "^7.1.0", 30 | "style-loader": "^0.23.1", 31 | "terser-webpack-plugin": "^1.2.3", 32 | "webpack": "^4.29.6", 33 | "webpack-cli": "^3.3.0" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | const purgecss = require('@fullhuman/postcss-purgecss'); 2 | 3 | module.exports = { 4 | plugins: [ 5 | require("autoprefixer"), 6 | require('cssnano')({ 7 | preset: 'default', 8 | }), 9 | purgecss({ 10 | content: ['./**/*.html', './**/*.liquid'], 11 | keyframes: true 12 | }) 13 | ], 14 | }; -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # tris-shopify-webpack-boilerplate 2 | 3 | [![](https://img.shields.io/david/tr1s/tris-shopify-webpack-boilerplate.svg)](https://github.com/tr1s/tris-shopify-webpack-boilerplate) 4 | [![](https://img.shields.io/david/dev/tr1s/tris-shopify-webpack-boilerplate.svg)](https://github.com/tr1s/tris-shopify-webpack-boilerplate) 5 | 6 | This boilerplate is great for working with Shopify from scratch as well as migrating existing Shopify themes and building overtop of them. It uses Webpack 4 to bundle all your js and compile your styles into Shopify's assets folder. 7 | 8 | The idea of this boilerplate is to get you started doing custom development on Shopify's platform with minimal effort while reducing the amount of http requests your store sends off. We'll achieve this by bundling all of our scripts/styles into 1 file each. 9 | 10 | # Usage 11 | 12 | You need [git](https://git-scm.com/), [node.js](https://nodejs.org/), and [ThemeKit](https://shopify.github.io/themekit/) on your computer before running. 13 | 14 | First you need to... 15 | 16 | * `git clone https://github.com/tr1s/tris-shopify-webpack-boilerplate.git` 17 | * `cd` into the project and then `rm -rf .git` to disconnect from this repo 18 | 19 | Then use [Themekit](https://shopify.github.io/themekit/) to pull down a theme from Shopify. This will bring all of your Shopify files into the project. Then... 20 | 21 | * `npm install` 22 | * `theme watch` ThemeKit watches the `assets/` folder for changes and uploads changes to the server / your store 23 | * `npm run watch` will watch for changes in the `src/` and then bundle both the scripts and styles into Shopify's `assets/` folder 24 | * `npm run watchall` will do the above two tasks combined in one terminal window 25 | * `npm run build` will bundle and uglify your scripts into the `assets/` for production ** `theme-webpack.scss.liquid` will stay un-minified because Shopify's servers will handle that. 26 | 27 | # Caveats 28 | 29 | * **Live Reloading** — `webpack-dev-server` will not work because the files are hosted on Shopify's servers. I personally have been using [LivePage](https://livepage.mikerogers.io/) chrome extension. It simply watches the web page for any server changes, and refreshes the page right after the server updates. 30 | 31 | Sometimes you'll hit too many requests and Shopify will temporarily block you out. To fix this, go into LivePage settings and change the `Polling Settings:` to `2000ms` instead of `200ms`. 32 | 33 | * **Liquid Syntaxing** — You cannot use liquid syntax inside of your src/ `.scss`/`.js` files nor will Webpack compile `.scss.liquid`/`.js.liquid` files, so do not rename them to that. You can however get away with some liquid syntax, for example use `background-image: url( "{{ '../path/to/assets/img.jpg' | asset_url }}" )` for retrieving and using assets. The quotes around the liquid tags allow this to work. The quotes around the path and liquid tags can't be the same, use double quotes for one and single quotes for the other. 34 | 35 | * **Liquid Syntaxing (Sass Interpolation)** — Another way to use liquid in your scss and js is to use _Sass Interpolation_. Interpolating is the process of evaluating an expression or a string containing one or more variables, producing a result in which the variables are replaced with their corresponding values in memory, [according to this article all about Sass interpolation](https://webdesign.tutsplus.com/tutorials/all-you-ever-need-to-know-about-sass-interpolation--cms-21375). What that means is when Sass processes an expression or string containing one or more variables using interpolation, it replaces the `#{$variable}` with the variable value in memory, rather than trying to execute the expression or string using those variables as values in the original process. You can think of Sass interpolation as a way of escaping certain values, variables, or syntax that might otherwise be misinterpreted by Sass. 36 | 37 | Here are some examples: 38 | 39 | ``` 40 | a { 41 | color: #{'{{ settings.color-link }}'}; 42 | } 43 | ``` 44 | 45 | Will compile to `a { color: #2980b9; }` 46 | 47 | You can find other examples of how to escape Liquid code in Sass files [in this awesome Gist](https://gist.github.com/shopifypartners/d66e0725687a195a2d49974b535f8025) made by Shopify Expert [Stewart Knapman](https://twitter.com/stewartknapman)! 48 | 49 | Here are some extra resources on Sass interpolation: 50 | 51 | 1. [A beginners guide to Sass Interpolation](https://www.shopify.ca/partners/blog/a-beginners-guide-to-sass-with-shopify-part-3) 52 | 2. [All You Ever Need to Know About Sass Interpolation](https://webdesign.tutsplus.com/tutorials/all-you-ever-need-to-know-about-sass-interpolation--cms-21375) 53 | 54 | If you need more complicated liquid syntaxing in your project then insert it via scss `{% stylesheets %}` and js `{% scripts %}` at the end of your sections. 55 | 56 | # CSS optimizations 57 | 58 | [Postcss]() will handle all of our CSS optimizations before it gets sent to the assets folder. We use [autoprefixer](https://github.com/postcss/autoprefixer) (for vendor prefixing), [cssnano](https://github.com/cssnano/cssnano) (for minification), and [purgecss](https://www.purgecss.com/) (for removing unused css). Read their documentation if you'd like to customize further. 59 | 60 | ```js 61 | /* postcss.config.js */ 62 | 63 | const purgecss = require('@fullhuman/postcss-purgecss'); 64 | 65 | module.exports = { 66 | plugins: [ 67 | require("autoprefixer"), 68 | require('cssnano')({ 69 | preset: 'default', 70 | }), 71 | purgecss({ 72 | content: ['./**/*.html', './**/*.liquid'], 73 | keyframes: true 74 | }) 75 | ], 76 | }; 77 | ``` 78 | 79 | # Dealing with a Shopify Theme's core JS/SCSS files 80 | 81 | When you pull down a Theme to use, it will most likely have a few core js files in the assets folder, along with the main theme styles. We can help reduce the amount of requests your store makes by letting Webpack bundle these scripts and styles in to one file. 82 | 83 | Firstly, move the default theme styles from your `assets/` into your `src/styles/` and import them into your `theme.scss` right above where you plan to input your own custom styles. E.g `@import "./styles/global/_shopify-theme.scss";`. 84 | 85 | Secondly, move all of your core js files from `assets/` into `src/scripts/core/` and then import those core files into the `src/theme.js` file. E.g `import 'src/scripts/core/core-file-1.js`. 86 | 87 | --------------------------- 88 | 89 | If you check back in the console you *might* come across some undefined variable errors ⚠️, don’t panic. This will be because the theme contained some libraries that export themselves as modules instead of global variables if the libraries detect you’re now using an environment that supports exports. There are a few ways you can deal with this... 90 | 91 | * The “correct” but time consuming way: **Split the libraries out and import them individually, maybe moving some dependencies like JQuery to be managed with NPM.** 92 | 93 | * The quick but risky way: **Remove the exports code condition from the libraries source code so it forces the lib to be included as a global.** 94 | 95 | * The quick and safe but less optimized way: **Leave the file with the imported libraries as a separate script included in `layout/theme.liquid`** 96 | 97 | For example in the [Debut Theme](https://themes.shopify.com/themes/debut/styles/default), the file called `vendor.js` contains all these types of libraries, so you can just move this file back into the `assets` folder for now and you'll be fine, I promise. 98 | 99 | # CSS Frameworks 100 | 101 | My favourite CSS framwork [Bulma](https://bulma.io/) is included in this setup. Uncomment the `@import "../node_modules/bulma/bulma";` if you would like to use it, otherwise feel free to `npm uninstall bulma` and remove `@import "../node_modules/bulma/bulma";` from the `theme.scss` altogether. 102 | 103 | # A note on Pull Requests 104 | 105 | If you can make this better, or notice any issues, please feel free to submit a pull request. 106 | 107 | Thanks!! 108 | 109 | ___ 110 | 111 | Follow me on twitter [@triscodes](https://twitter.com/triscodes) 💎. -------------------------------------------------------------------------------- /src/styles/global/_global.scss: -------------------------------------------------------------------------------- 1 | html, body { 2 | height: 100%; 3 | // border: 8px solid orangered; // uncomment to test if setup is working. 4 | } 5 | body { 6 | min-height: 100%; 7 | } -------------------------------------------------------------------------------- /src/styles/global/_typography.scss: -------------------------------------------------------------------------------- 1 | //! import google fonts 2 | // @import url('https://fonts.googleapis.com/css?family=Libre+Baskerville:400,400i,700'); 3 | // @import url('https://fonts.googleapis.com/css?family=Roboto:100,100i,300,300i,400,400i,500,500i,700,700i,900,900i'); 4 | 5 | //! import a custom font below 6 | // @font-face { 7 | // font-family: 'font-name'; 8 | // font-display: fallback; 9 | // src: url('{{ '../path/to/font' | asset_url }}') format(''); 10 | // font-weight: normal; 11 | // font-style: normal; 12 | // } 13 | 14 | //! set font variables 15 | $font-heading: serif; 16 | $font-body: sans-serif; 17 | 18 | html { 19 | font-size: 62.5%; // 1rem = 10px, 3.5rem = 35px; 20 | } 21 | 22 | body { 23 | font-family: $font-body; 24 | -webkit-font-smoothing: antialiased; 25 | -moz-osx-font-smoothing: grayscale; 26 | text-rendering: optimizeLegibility; 27 | } 28 | 29 | h1 { 30 | font-family: $font-heading; 31 | } -------------------------------------------------------------------------------- /src/styles/sections/_footer.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tr1s/tris-shopify-webpack-boilerplate/89ca347d77acd0aa4cf9aa7f6a0ce34aacd909e8/src/styles/sections/_footer.scss -------------------------------------------------------------------------------- /src/styles/sections/_header.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tr1s/tris-shopify-webpack-boilerplate/89ca347d77acd0aa4cf9aa7f6a0ce34aacd909e8/src/styles/sections/_header.scss -------------------------------------------------------------------------------- /src/styles/setup/_border-box.scss: -------------------------------------------------------------------------------- 1 | html { 2 | box-sizing: border-box; 3 | } 4 | 5 | *, *:before, *:after { 6 | box-sizing: inherit; 7 | } -------------------------------------------------------------------------------- /src/styles/setup/_clearfix.scss: -------------------------------------------------------------------------------- 1 | .clearfix:after { 2 | visibility: hidden; 3 | display: block; 4 | content: ""; 5 | clear: both; 6 | height: 0; 7 | } -------------------------------------------------------------------------------- /src/styles/setup/_normalize.scss: -------------------------------------------------------------------------------- 1 | /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ 2 | 3 | /* Document 4 | ========================================================================== */ 5 | 6 | /** 7 | * 1. Correct the line height in all browsers. 8 | * 2. Prevent adjustments of font size after orientation changes in iOS. 9 | */ 10 | 11 | html { 12 | line-height: 1.15; 13 | /* 1 */ 14 | -webkit-text-size-adjust: 100%; 15 | /* 2 */ 16 | } 17 | 18 | /* Sections 19 | ========================================================================== */ 20 | 21 | /** 22 | * Remove the margin in all browsers. 23 | */ 24 | 25 | body { 26 | margin: 0; 27 | } 28 | 29 | /** 30 | * Render the `main` element consistently in IE. 31 | */ 32 | 33 | main { 34 | display: block; 35 | } 36 | 37 | /** 38 | * Correct the font size and margin on `h1` elements within `section` and 39 | * `article` contexts in Chrome, Firefox, and Safari. 40 | */ 41 | 42 | h1 { 43 | font-size: 2em; 44 | margin: 0.67em 0; 45 | } 46 | 47 | /* Grouping content 48 | ========================================================================== */ 49 | 50 | /** 51 | * 1. Add the correct box sizing in Firefox. 52 | * 2. Show the overflow in Edge and IE. 53 | */ 54 | 55 | hr { 56 | box-sizing: content-box; 57 | /* 1 */ 58 | height: 0; 59 | /* 1 */ 60 | overflow: visible; 61 | /* 2 */ 62 | } 63 | 64 | /** 65 | * 1. Correct the inheritance and scaling of font size in all browsers. 66 | * 2. Correct the odd `em` font sizing in all browsers. 67 | */ 68 | 69 | pre { 70 | font-family: monospace, monospace; 71 | /* 1 */ 72 | font-size: 1em; 73 | /* 2 */ 74 | } 75 | 76 | /* Text-level semantics 77 | ========================================================================== */ 78 | 79 | /** 80 | * Remove the gray background on active links in IE 10. 81 | */ 82 | 83 | a { 84 | background-color: transparent; 85 | } 86 | 87 | /** 88 | * 1. Remove the bottom border in Chrome 57- 89 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. 90 | */ 91 | 92 | abbr[title] { 93 | border-bottom: none; 94 | /* 1 */ 95 | text-decoration: underline; 96 | /* 2 */ 97 | text-decoration: underline dotted; 98 | /* 2 */ 99 | } 100 | 101 | /** 102 | * Add the correct font weight in Chrome, Edge, and Safari. 103 | */ 104 | 105 | b, 106 | strong { 107 | font-weight: bolder; 108 | } 109 | 110 | /** 111 | * 1. Correct the inheritance and scaling of font size in all browsers. 112 | * 2. Correct the odd `em` font sizing in all browsers. 113 | */ 114 | 115 | code, 116 | kbd, 117 | samp { 118 | font-family: monospace, monospace; 119 | /* 1 */ 120 | font-size: 1em; 121 | /* 2 */ 122 | } 123 | 124 | /** 125 | * Add the correct font size in all browsers. 126 | */ 127 | 128 | small { 129 | font-size: 80%; 130 | } 131 | 132 | /** 133 | * Prevent `sub` and `sup` elements from affecting the line height in 134 | * all browsers. 135 | */ 136 | 137 | sub, 138 | sup { 139 | font-size: 75%; 140 | line-height: 0; 141 | position: relative; 142 | vertical-align: baseline; 143 | } 144 | 145 | sub { 146 | bottom: -0.25em; 147 | } 148 | 149 | sup { 150 | top: -0.5em; 151 | } 152 | 153 | /* Embedded content 154 | ========================================================================== */ 155 | 156 | /** 157 | * Remove the border on images inside links in IE 10. 158 | */ 159 | 160 | img { 161 | border-style: none; 162 | } 163 | 164 | /* Forms 165 | ========================================================================== */ 166 | 167 | /** 168 | * 1. Change the font styles in all browsers. 169 | * 2. Remove the margin in Firefox and Safari. 170 | */ 171 | 172 | button, 173 | input, 174 | optgroup, 175 | select, 176 | textarea { 177 | font-family: inherit; 178 | /* 1 */ 179 | font-size: 100%; 180 | /* 1 */ 181 | line-height: 1.15; 182 | /* 1 */ 183 | margin: 0; 184 | /* 2 */ 185 | } 186 | 187 | /** 188 | * Show the overflow in IE. 189 | * 1. Show the overflow in Edge. 190 | */ 191 | 192 | button, 193 | input { 194 | /* 1 */ 195 | overflow: visible; 196 | } 197 | 198 | /** 199 | * Remove the inheritance of text transform in Edge, Firefox, and IE. 200 | * 1. Remove the inheritance of text transform in Firefox. 201 | */ 202 | 203 | button, 204 | select { 205 | /* 1 */ 206 | text-transform: none; 207 | } 208 | 209 | /** 210 | * Correct the inability to style clickable types in iOS and Safari. 211 | */ 212 | 213 | button, 214 | [type="button"], 215 | [type="reset"], 216 | [type="submit"] { 217 | -webkit-appearance: button; 218 | } 219 | 220 | /** 221 | * Remove the inner border and padding in Firefox. 222 | */ 223 | 224 | button::-moz-focus-inner, 225 | [type="button"]::-moz-focus-inner, 226 | [type="reset"]::-moz-focus-inner, 227 | [type="submit"]::-moz-focus-inner { 228 | border-style: none; 229 | padding: 0; 230 | } 231 | 232 | /** 233 | * Restore the focus styles unset by the previous rule. 234 | */ 235 | 236 | button:-moz-focusring, 237 | [type="button"]:-moz-focusring, 238 | [type="reset"]:-moz-focusring, 239 | [type="submit"]:-moz-focusring { 240 | outline: 1px dotted ButtonText; 241 | } 242 | 243 | /** 244 | * Correct the padding in Firefox. 245 | */ 246 | 247 | fieldset { 248 | padding: 0.35em 0.75em 0.625em; 249 | } 250 | 251 | /** 252 | * 1. Correct the text wrapping in Edge and IE. 253 | * 2. Correct the color inheritance from `fieldset` elements in IE. 254 | * 3. Remove the padding so developers are not caught out when they zero out 255 | * `fieldset` elements in all browsers. 256 | */ 257 | 258 | legend { 259 | box-sizing: border-box; 260 | /* 1 */ 261 | color: inherit; 262 | /* 2 */ 263 | display: table; 264 | /* 1 */ 265 | max-width: 100%; 266 | /* 1 */ 267 | padding: 0; 268 | /* 3 */ 269 | white-space: normal; 270 | /* 1 */ 271 | } 272 | 273 | /** 274 | * Add the correct vertical alignment in Chrome, Firefox, and Opera. 275 | */ 276 | 277 | progress { 278 | vertical-align: baseline; 279 | } 280 | 281 | /** 282 | * Remove the default vertical scrollbar in IE 10+. 283 | */ 284 | 285 | textarea { 286 | overflow: auto; 287 | } 288 | 289 | /** 290 | * 1. Add the correct box sizing in IE 10. 291 | * 2. Remove the padding in IE 10. 292 | */ 293 | 294 | [type="checkbox"], 295 | [type="radio"] { 296 | box-sizing: border-box; 297 | /* 1 */ 298 | padding: 0; 299 | /* 2 */ 300 | } 301 | 302 | /** 303 | * Correct the cursor style of increment and decrement buttons in Chrome. 304 | */ 305 | 306 | [type="number"]::-webkit-inner-spin-button, 307 | [type="number"]::-webkit-outer-spin-button { 308 | height: auto; 309 | } 310 | 311 | /** 312 | * 1. Correct the odd appearance in Chrome and Safari. 313 | * 2. Correct the outline style in Safari. 314 | */ 315 | 316 | [type="search"] { 317 | -webkit-appearance: textfield; 318 | /* 1 */ 319 | outline-offset: -2px; 320 | /* 2 */ 321 | } 322 | 323 | /** 324 | * Remove the inner padding in Chrome and Safari on macOS. 325 | */ 326 | 327 | [type="search"]::-webkit-search-decoration { 328 | -webkit-appearance: none; 329 | } 330 | 331 | /** 332 | * 1. Correct the inability to style clickable types in iOS and Safari. 333 | * 2. Change font properties to `inherit` in Safari. 334 | */ 335 | 336 | ::-webkit-file-upload-button { 337 | -webkit-appearance: button; 338 | /* 1 */ 339 | font: inherit; 340 | /* 2 */ 341 | } 342 | 343 | /* Interactive 344 | ========================================================================== */ 345 | 346 | /* 347 | * Add the correct display in Edge, IE 10+, and Firefox. 348 | */ 349 | 350 | details { 351 | display: block; 352 | } 353 | 354 | /* 355 | * Add the correct display in all browsers. 356 | */ 357 | 358 | summary { 359 | display: list-item; 360 | } 361 | 362 | /* Misc 363 | ========================================================================== */ 364 | 365 | /** 366 | * Add the correct display in IE 10+. 367 | */ 368 | 369 | template { 370 | display: none; 371 | } 372 | 373 | /** 374 | * Add the correct display in IE 10. 375 | */ 376 | 377 | [hidden] { 378 | display: none; 379 | } -------------------------------------------------------------------------------- /src/styles/utils/_mixins.scss: -------------------------------------------------------------------------------- 1 | @mixin respond-to($breakpoint) { 2 | @if $breakpoint=="mobile" { 3 | @media (max-width: 480px) { 4 | @content; 5 | } 6 | } 7 | 8 | @else if $breakpoint=="tablet" { 9 | @media (max-width: 769px) { 10 | @content; 11 | } 12 | } 13 | 14 | @else if $breakpoint=="desktop" { 15 | @media (max-width: 969px) { 16 | @content; 17 | } 18 | } 19 | 20 | @else if $breakpoint=="wrapper" { 21 | @media (max-width: 1170px) { 22 | @content; 23 | } 24 | } 25 | 26 | @else { 27 | @media ($breakpoint) { 28 | @content; 29 | } 30 | } 31 | } 32 | 33 | //! Example usage 34 | /* @include respond-to('mobile') {} */ 35 | 36 | //________________________________________________________________________________________ 37 | 38 | @mixin centered { 39 | position: absolute; 40 | top: 50%; 41 | left: 50%; 42 | transform: translate(-50%, -50%); 43 | } 44 | 45 | //! Example usage 46 | /* 47 | .parent { 48 | position: relative; 49 | } 50 | .child { 51 | @include centered; 52 | } 53 | */ -------------------------------------------------------------------------------- /src/styles/utils/_variables.scss: -------------------------------------------------------------------------------- 1 | //? set your brand colors 2 | 3 | $red: #AD2532; 4 | $red-darker: #690608; 5 | $blue: #3B4B98; 6 | $blue-darker: #3A3A59; 7 | 8 | $white: #fff; 9 | $white-ish: #F7F7F7; 10 | $grey: #D3D3D3; 11 | $black: #09090E; 12 | $black-ish: #444; 13 | 14 | 15 | //? override for project clarity 16 | 17 | $color-primary: $red; 18 | $color-secondary: $blue; 19 | $color-tertiary: #BADA55; -------------------------------------------------------------------------------- /src/theme.js: -------------------------------------------------------------------------------- 1 | console.log('Hello from src/theme.js 👋'); 2 | 3 | import './theme.scss'; -------------------------------------------------------------------------------- /src/theme.scss: -------------------------------------------------------------------------------- 1 | //! css framework 2 | // @import "../node_modules/bulma/bulma"; 3 | 4 | //! utilities 5 | @import "./styles/utils/mixins"; // global mixins 6 | @import "./styles/utils/variables"; // global variables 7 | 8 | //! setup 9 | @import "./styles/setup/normalize"; // normalize browsers to make more consistent 10 | @import "./styles/setup/clearfix"; // clearfix for floats 11 | @import "./styles/setup/border-box"; // global border-box setting 12 | 13 | //! global styles 14 | @import "./styles/global/typography"; // global typography 15 | @import "./styles/global/global"; // global styles 16 | 17 | //! sections 18 | @import "./styles/sections/header"; 19 | @import "./styles/sections/footer"; -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const TerserPlugin = require('terser-webpack-plugin'); 3 | const MiniCssExtractPlugin = require("mini-css-extract-plugin"); 4 | 5 | module.exports = { 6 | entry: './src/theme.js', 7 | output: { 8 | path: path.resolve(__dirname, 'assets'), // outputs bundled .js and .scss.liquid into shopify's assets folder 9 | filename: 'theme-webpack.js' 10 | }, 11 | optimization: { 12 | minimizer: [ 13 | new TerserPlugin({ 14 | test: /\.js(\?.*)?$/i, 15 | parallel: true, 16 | sourceMap: true 17 | }) 18 | ] 19 | }, 20 | module: { 21 | rules: [{ 22 | test: /\.js$/, 23 | exclude: /(node_modules)/, 24 | use: { 25 | loader: 'babel-loader', 26 | options: { 27 | presets: ['@babel/preset-env'] 28 | } 29 | } 30 | }, 31 | { 32 | test: /\.(sa|sc|c)ss$/, 33 | use: [ 34 | MiniCssExtractPlugin.loader, 35 | 'css-loader', 36 | 'postcss-loader', 37 | 'sass-loader' 38 | ] 39 | } 40 | ] 41 | }, 42 | plugins: [ 43 | new MiniCssExtractPlugin({ 44 | filename: "theme-webpack.scss.liquid" 45 | }) 46 | ], 47 | resolve: { 48 | extensions: ['.css', '.scss', '.sass', '.js', '.liquid'] 49 | } 50 | }; --------------------------------------------------------------------------------