Skip to content

Instantly share code, notes, and snippets.

@panoply
Last active December 16, 2019 15:37
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save panoply/ac1db31e188014b994ea5542d6906b8b to your computer and use it in GitHub Desktop.
Save panoply/ac1db31e188014b994ea5542d6906b8b to your computer and use it in GitHub Desktop.
Gulp stream for theme building. The stream relies on a specific directory structure.

Gulp Shopify Stream

This gulp stream provides a lean environment for Shopify Theme based builds. For those who liked to work in a modulated manner, this stream allows you create create and modify content outside the theme directory and will import production ready files to their designated directories. Using this Gulp task stream will keep your Theme design and all its components under Bower version control (including Timber) and other theme build dependants.

Below is a directory structure tree similar to the working environment built for this gulp file.

│Shopify Theme Development Directory Structure
├───────────────────────────
│
├── bower_components
│   └── timber
│
├── documentation
│   └── readme.md
│
├── javascript
│   ├── components
│   ├── extensions
│   ├── liquid
│   ├── modules
│   │
│   ├── scripts.js
│   ├── components.js
│   └── liquids.js
│
├── media
│   ├── design
│   ├── flags
│   ├── icons
│   ├── images
│   ├── json
│   └── videos
│
├── node_modules
│   └── Node Requirements
│
├── sass
│   ├── components
│   ├── controls
│   ├── extensions
│   ├── frameworks
│   │    └── _timber
│   │          └── _vc
│   ├── layout
│   ├── mixins
│   ├── polyfills
│   ├── templates
│   ├── variables
│   │
│   ├── liquids.scss
│   └── imports.scss
│
├── settings_schema
│   ├── configurations
│   ├── templates
│   ├── theme
│   │
│   └── settings_schema.yml
│
└── theme
│    ├── assets
│    ├── config
│    ├── layout
│    ├── locales
│    ├── snippets
│    ├── spec
│    ├── templates
│    │
│    └── config.yml
│
├── bower.json
├── settings_schema
├── gulpfile.js
├── package.json
//=====================================================//
//## PLUGINS
//=====================================================//
// Gulp plugin setup
var gulp = require('gulp');
// Gulp Plumber for Error control
var plumber = require('gulp-plumber');
// Gulp Ruby for local build
var sass = require('gulp-sass');
// Merge Streams
var merge = require('merge-stream');
// Size – File Sizes
var size = require('gulp-filesize');
// Bower Components
var mainBowerFiles = require('main-bower-files');
// SCSS - CSS Prefixer
var autoprefixer = require('gulp-autoprefixer');
// Minify CSS
var cssnano = require('gulp-cssnano');
var rename = require('gulp-rename');
// JS Includes / pipes
var order = require("gulp-order");
var include = require("gulp-include");
var concat = require("gulp-concat");
var uglify = require("gulp-uglify");
// Yaml to Json – Shopify Settings Schema
var yaml = require('gulp-yaml');
// Minify Images - Lossless
var imagemin = require('gulp-imagemin');
// Watches single files
var watch = require('gulp-watch');
var gulpShopify = require('gulp-shopify-upload');
//=====================================================//
//## VARIABLES
//=====================================================//
// Relocation Directories
//
var themeAssets = 'theme/assets';
// AutoPrefix Support
//
var supported = [
'Android >= 2.3',
'BlackBerry >= 7',
'Chrome >= 9',
'Firefox >= 4',
'Explorer >= 9',
'iOS >= 5',
'Opera >= 11',
'Safari >= 5',
'OperaMobile >= 11',
'OperaMini >= 6',
'ChromeAndroid >= 9',
'FirefoxAndroid >= 4',
'ExplorerMobile >= 9'
];
//=====================================================//
// ## SASS
//=====================================================//
// See the 'imports.scss' file for the entire breakdown.
// Merging stylesheets from bower components in here too.
gulp.task('sass', function () {
return gulp.src(['sass/imports.scss', '!sass/liquids.js'])
.pipe(sass({outputStyle: 'uncompressed'}).on('error', sass.logError))
.pipe(cssnano({
autoprefixer: {browsers: supported, add: true}
}))
.pipe(rename('stylesheet.min.css')) // Rename
.pipe(gulp.dest(themeAssets))
.pipe(size());
});
//=====================================================//
// ## SASS LIQUID
//=====================================================//
// See the 'liquid.scss' file for merge breakdown.
// Shopify renders .scss files, so only merge and combine here..
gulp.task('sass-liquid', function () {
return gulp.src(['sass/liquids.scss', '!sass/imports.scss'])
.pipe(include())
.pipe(rename('theme.scss.liquid')) // Rename
.pipe(gulp.dest(themeAssets))
.on("error", console.log)
.pipe(size());
});
//=====================================================//
//## JAVASCRIPT / jQuery & JavaScript
//=====================================================//
// Merger and concat modulized components and vendors.
// Files merge, minify and export production ready.
gulp.task('javascript', function () {
return gulp.src(['javascript/*.js', '!javascript/liquids.js'])
.pipe(plumber())
.pipe(include())
.pipe(uglify())
.pipe(plumber.stop())
.pipe(rename({
suffix: ".min"
}))
.pipe(gulp.dest(themeAssets))
.on("error", console.log)
.pipe(size());
});
//=====================================================//
// ## LIQUID / JavaScript
//=====================================================//
// Merge all .liquid JS files that Shopify will render and use.
// This will combine all .liquid JS files that contain settings.
gulp.task('javascript-liquid', function () {
return gulp.src('javascript/liquids.js')
.pipe(include())
.pipe(rename('liquids.js.liquid'))
.pipe(gulp.dest(themeAssets))
.on("error", console.log);
});
//=====================================================//
//## BOWER COMPONENTS
//=====================================================//
//
// See the Bower.json file overrides for additions.
// Task will also move all components files for later concatenation/s.
// We Run "gulp bower" Manually, this ain't part of default task.
gulp.task('bower', function () {
return gulp.src(mainBowerFiles('**/*.js'))
.on("error", console.log)
.pipe(gulp.dest('javascript/components/'));
});
//=====================================================//
//## TIMBER COMPONENTS
//=====================================================//
// Rework all timber framework from src files found in bower dir.
// Task moves all timber JS & SCSS into development directories.
// Run "gulp timber" Manually, this is not a default task.
gulp.task('timber', function () {
// Import Respond for IE 9 > (IE 8 not supported in theme)
var RespondJS = gulp.src('bower_components/timber/assets/respond.min.js')
.pipe(gulp.dest(themeAssets));
// Timber JS (js.liquid) Files
var AjaxCart = gulp.src('bower_components/timber/assets/ajax-cart.js.liquid')
.pipe(gulp.dest('javascript/liquid'));
var TimberJS = gulp.src('bower_components/timber/assets/timber.js.liquid')
.pipe(gulp.dest('javascript/liquid'));
// Import Handlebars to Components
var Handlebars = gulp.src('bower_components/timber/assets/handlebars.min.js')
.pipe(gulp.dest('javascript/components'));
// Timber SASS (scss.liquid) Files.
//
// Import everything into "VC" (Version Control) directory folder.
// by importing to this directory we wont overwrite current DEV version.
var TimberSCSS = gulp.src('bower_components/timber/assets/timber.scss.liquid')
.pipe(gulp.dest('sass/frameworks/timber/_vc'));
// Gift Card
var GiftCard = gulp.src('bower_components/timber/assets/gift-card.scss.liquid')
.pipe(gulp.dest('sass/frameworks/timber/_vc'));
// Merge
//
return merge(RespondJS, AjaxCart, TimberJS, Handlebars, TimberSCSS, GiftCard);
});
//=====================================================//
//## YAML > JSON – SETTINGS_SCHEMA
//=====================================================//
// Convert Yaml to Json and create a settings_schema.json file.
// Task will combine all modularized files from schema.
// Task will compile automatically.
gulp.task('settings', function () {
return gulp.src('settings_schema/*.yml')
.pipe(include())
.pipe(yaml({ schema: 'DEFAULT_SAFE_SCHEMA' }))
.on("error", console.log)
.pipe(gulp.dest('theme/config/'));
});
//=====================================================//
//## IMAGEMIN
//=====================================================//
// Minify images and import to "/theme/assets" directory.
// Images import in a lossless state.
gulp.task('minify-images', function () {
gulp.src([
'media/design/*',
'media/flags/*',
'media/images/index/*'
])
.pipe(imagemin())
.pipe(gulp.dest('theme/assets/'))
});
//=====================================================//
//## DIRECTORY MOVE
//=====================================================//
// Images, Icons, Json and all other files imported into
// theme/assets directory.
gulp.task('relocate', function () {
var icons = gulp.src('media/icons/*')
.pipe(gulp.dest(themeAssets));
// Timber JS (js.liquid) Files
var json = gulp.src('media/json/*')
.pipe(gulp.dest(themeAssets));
//var videos = gulp.src('media/videos/*')
//.pipe(gulp.dest(themeAssets));
return merge(icons, json);
});
//=====================================================//
//## GULP WATCH
//=====================================================//
// ## Watch Directories -------------------------------//
//
// Watch and export files from "_build" to "assets"
// Clean folder logic and directory structre.
gulp.task('watch', function () {
// Watch SASS and LIQUID SASS Files and Directories
gulp
.watch(
['sass/**/*.scss','sass/liquids.scss'],
['sass','sass-liquid']);
// Watch JAVASCRIPT Files and Directories
gulp
.watch(
['javascript/**/*.js', '!javascript/liquids.js'],
['javascript']);
// Watch LIQUID JavaScript Files and Directories
gulp
.watch(
['javascript/liquids.js','javascript/liquid/*.liquid'],
['javascript-liquid']);
// Watch SETTINGS_SCHEMA files
gulp
.watch('settings_schema/**/*.yml', ['settings']);
// Watch IMAGEMIN media
gulp
.watch('media/images/**/*', ['minify-images']);
// Watch RELOCATE
gulp
.watch(['media/icons/*','media/json/*'], ['relocate']);
});
//=====================================================//
//## SHOPIFY API
//=====================================================//
// Deprecated in favor of "Shopify Theme" Ruby Gem.
/*
gulp.task('shopify', function () {
return watch('./+(assets|layout|config|snippets|templates|locales)/**')
.pipe(gulpShopify(
'xxx', // API Key
'xxx', // Password
'xxx.myshopify.com',
'xxx'));
});
*/
//=====================================================//
//## RUN GULP TASK
//=====================================================//
gulp.task('default', ['watch']);
//--------- MIT License ----------//
// Do what the fuck you want license.
//
// Stream via @heynicos
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment