├── .gitignore
├── CHANGELOG.md
├── Gemfile
├── LICENSE
├── README.md
├── bin
└── setup
├── config.rb
├── environments
├── development.rb
└── production.rb
├── gulpfile.js
├── config.json
├── index.js
├── lib
│ ├── __tests__
│ │ └── pathToUrl.test.js
│ ├── compileLogger.js
│ ├── getEnabledTasks.js
│ ├── handleErrors.js
│ ├── pathToUrl.js
│ ├── prettifyTime.js
│ ├── repeatString.js
│ ├── webpack-multi-config.js
│ └── webpackManifest.js
└── tasks
│ ├── browserSync.js
│ ├── clean.js
│ ├── css.js
│ ├── default.js
│ ├── deploy.js
│ ├── fonts.js
│ ├── iconFont
│ ├── generateIconSass.js
│ ├── index.js
│ └── template.sass
│ ├── images.js
│ ├── production.js
│ ├── rev
│ ├── index.js
│ ├── rev-assets.js
│ ├── rev-css.js
│ ├── rev-update-references.js
│ └── update-html.js
│ ├── server.js
│ ├── sizereport.js
│ ├── static.js
│ ├── svgSprite.js
│ ├── watch.js
│ └── webpackProduction.js
├── helpers
├── README.md
└── gulp_asset_helper.rb
├── karma.conf.js
├── lib
└── gulp.rb
├── package.json
└── source
├── images
└── middleman-logo.svg
├── index.html.erb
├── javascripts
├── _test.js
└── all.js
├── layouts
└── layout.erb
├── static
└── favicon.ico
└── stylesheets
├── _normalize.scss
└── site.scss
/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 | #
3 | # If you find yourself ignoring temporary files generated by your text editor
4 | # or operating system, you probably want to add a global ignore instead:
5 | # git config --global core.excludesfile ~/.gitignore_global
6 |
7 | # Ignore bundler config
8 | /.bundle
9 |
10 | # Ignore the build directory
11 | /build
12 |
13 | # Ignore cache
14 | /.sass-cache
15 | /.cache
16 |
17 | # Ignore .DS_store file
18 | .DS_Store
19 | node_modules
20 | .tmp
21 | Gemfile.lock
22 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # ChangeLog
2 | All notable changes to this project will be documented in this file.
3 | This project adheres to [Semantic Versioning](http://semver.org/).
4 |
5 | ## [1.4.2] - 2016-08-20
6 |
7 | ### Fixed
8 | - Add missing dependencies needed when installing
9 |
10 | ## [1.4.1] - 2016-08-20
11 |
12 | ### Changed
13 | - Update Middleman
14 | - Update Gulp Starter
15 |
16 | ## [1.4.0] - 2016-04-18
17 |
18 | ### Fixed
19 | - Add the `html` task back (it was missing for some reason)
20 |
21 | ### Added
22 | - Add coffeescript support
23 | - Add `node_modules` search for webpack requires
24 |
25 | ## [1.3.1] - 2016-04-11
26 |
27 | ### Changed
28 | - Remove unrelated comments
29 | - Correctly reference the icon sprite in Rails helper
30 |
31 | ## [1.3.0] - 2016-04-10
32 |
33 | ### Added
34 | - Utilise Middleman's environment configs
35 | - Added a setup script to install dependencies
36 | - Temp directory for external_pipeline is now a variable set from `config.json` only.
37 |
38 | ### Changed
39 | - Update the README with more information
40 |
41 | ## [1.2.0] - 2016-04-06
42 |
43 | ### Added
44 | - #4: File revving with Middleman Ruby helpers ported from Gulp Starter
45 |
46 | ## [1.1.0] - 2016-04-04
47 |
48 | ### Fixed
49 | - #1: Ignore duplicate files when running `middleman build`
50 |
51 | ### Added
52 | - Add minification of HTML
53 |
54 | ## [1.0.0] - 2016-04-04
55 |
56 | ### Added
57 | - Initial repo demo for screencast
58 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | # If you do not have OpenSSL installed, change
2 | # the following line to use 'http://'
3 | source 'https://rubygems.org'
4 |
5 | # For faster file watcher updates on Windows:
6 | gem 'wdm', '~> 0.1.0', platforms: [:mswin, :mingw]
7 |
8 | # Windows does not come with time zone data
9 | gem 'tzinfo-data', platforms: [:mswin, :mingw, :jruby]
10 |
11 | # Middleman Gems
12 | gem 'middleman', '>= 4.1.1'
13 | gem 'middleman-minify-html'
14 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Craig Dennis
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Middleman + Gulp Starter
2 | Build static sites using [Middleman](https://middlemanapp.com/) with [Gulp Starter](https://github.com/vigetlabs/gulp-starter).
3 |
4 |
5 |
6 | Watch the screencast: https://youtu.be/-io8EeB3GHI
7 |
8 | ## Installation
9 | 1. Clone the repo — `git clone git@github.com:craigmdennis/middleman-gulp-starter.git`
10 | 1. Run setup — `bin/setup`
11 |
12 | Setup installs Bundler, Gem dependencies and NPM dependencies.
13 |
14 | ## Developing using Middleman + Gulp Starter
15 | 1. Run `middleman serve` to use the `environments/development` config
16 |
17 | Middleman will launch Gulp Starter as an external pipeline, in development mode.
18 |
19 | ## Production builds
20 | 1. Run `middleman build` to use the `environments/production` config
21 |
22 | Middleman will minify HTML and Gulp starter will handle everything else
23 |
24 | ## Running Middleman without Gulp Starter
25 | There may be [instances where you want to run the standard Middleman tasks without initiating Gulp Starter](https://github.com/craigmdennis/middleman-gulp-starter/pull/17#issue-147191865). To do that you simply need to pass in another environment. It doesn't even need to exist.
26 |
27 | `middleman serve -e debug`
28 |
29 | Now you can create `environments/debug` and add your own custom config in there.
30 |
31 | ## Revving Assets
32 | You'll no longer be able to use the built in Middleman asset helpers like `javascript_include_tag` on their own. Instead, you'll have to add a set of **gulp_asset_helpers**. Filenames get hashed so you can cache them forever. [Learn more](helpers/README.md)
33 |
34 | ```ruby
35 | gulp_asset_path('image/asset.jpg') # -> /image/logo-n39o4orb81.png
36 | gulp_js_path('app.js') # -> /javascripts/app-f43e9abc11.js
37 | gulp_css_path('app.css') # -> /stylesheets/app-d29e4cdb76.css
38 | gulp_image_path('logo.png') # -> /images/logo-n39o4orb81.png
39 | ```
40 |
41 | So instead of this:
42 | ```erb
43 | <%= image_tag 'logo.png', alt: 'logo' %>
44 | ```
45 |
46 | You would do this:
47 | ```erb
48 | <%= image_tag gulp_image_path('logo.png'), alt: 'logo' %>
49 | ```
50 |
51 | Instead of this:
52 | ```erb
53 | <%= stylesheet_link_tag :site %>
54 | ```
55 |
56 | You would do this:
57 | ```erb
58 | <%= stylesheet_link_tag gulp_css_path('site.css') %>
59 | ```
60 |
61 | ### When NOT to use the `gulp_asset_path` helpers
62 | Due to the way that Middleman merges the temporary folder with the source folder in the sitemap, when you reference it you don't need to use the `gulp_image_path` helper as the files in the sitemap will already be the revved files.
63 |
64 | ```haml
65 | - sitemap.resources.select{ |r| r.path.start_with?("images/some-folder-of-images") }.each do |image|
66 | = image_tag image.path
67 | ```
68 |
69 | You can disable asset revving in production on the [`config.json`](https://github.com/craigmdennis/middleman-gulp-starter/blob/master/gulpfile.js/config.json#L78) at the bottom.
70 |
71 | ## Contributing
72 | Please make sure to submit PRs to the latest feature branch.
73 |
74 | ## Release History
75 | Please consult the [official changelog](https://github.com/craigmdennis/middleman-gulp-starter/blob/master/CHANGELOG.md)
76 |
--------------------------------------------------------------------------------
/bin/setup:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | set -e
4 |
5 | # Make sure Bundler is installed
6 | if [ "$(gem query -i -n bundler)" = "false" ]; then
7 | echo "Installing Bundler..."
8 | gem install bundler
9 | fi
10 |
11 | # Set up Ruby dependencies via Bundler
12 | echo "Installing Ruby gem dependencies..."
13 | bundle install
14 |
15 | # Install node packages
16 | echo "Installing Node package dependencies..."
17 | npm install
18 |
--------------------------------------------------------------------------------
/config.rb:
--------------------------------------------------------------------------------
1 | # Read from Gulp Starter's config.json file
2 | # and rev-manifest file (if present)
3 | require './lib/gulp'
4 |
5 | ###
6 | # Page options, layouts, aliases and proxies
7 | ###
8 |
9 | # Per-page layout changes:
10 | #
11 | # With no layout
12 | page '/*.xml', layout: false
13 | page '/*.json', layout: false
14 | page '/*.txt', layout: false
15 |
16 | # With alternative layout
17 | # page "/path/to/file.html", layout: :otherlayout
18 |
19 | # Proxy pages (http://middlemanapp.com/basics/dynamic-pages/)
20 | # proxy "/this-page-has-no-template.html", "/template-file.html", locals: {
21 | # which_fake_page: "Rendering a fake page with a local variable" }
22 |
23 | # General configuration
24 |
25 | ###
26 | # Helpers
27 | ###
28 |
29 | # Methods defined in the helpers block are available in templates
30 | # helpers do
31 | # def some_helper
32 | # "Helping"
33 | # end
34 | # end
35 |
--------------------------------------------------------------------------------
/environments/development.rb:
--------------------------------------------------------------------------------
1 | # This environment is invoked by default when running `middleman server`
2 | activate :external_pipeline,
3 | name: :gulp,
4 | command: "npm run gulp",
5 | source: GULP_CONFIG['root']['dest'],
6 | latency: 1
7 |
--------------------------------------------------------------------------------
/environments/production.rb:
--------------------------------------------------------------------------------
1 | # Initialise Gulp Starter when running `middleman build`
2 | activate :external_pipeline,
3 | name: :gulp,
4 | command: "npm run production",
5 | source: GULP_CONFIG['root']['dest'],
6 | latency: 1
7 |
8 | # Ignore the CSS file Middleman normally generates
9 | # Middleman expects `site.css.scss` → `site.css`
10 | # We strip the `.css` to prevent Gulp generating `site.css.css`
11 | ignore 'stylesheets/site'
12 |
13 | # Ignore static files
14 | ignore 'icons/*'
15 | ignore 'static/*'
16 |
17 | # Check to see if file revving is enabled
18 | rev_manifest = REV_MANIFEST if defined?(REV_MANIFEST)
19 |
20 | # If file revving is enabled we need to ignore the original files
21 | # as they will still get copied by Middleman
22 | if rev_manifest
23 | rev_manifest.each do |key, value|
24 | ignore key
25 | end
26 | end
27 |
28 | # Ignore the actual manifest file
29 | ignore 'rev-manifest.json'
30 |
31 | # HTML Optimisation
32 | activate :minify_html do |html|
33 | html.remove_quotes = false
34 | html.remove_intertag_spaces = true
35 | html.remove_http_protocol = true
36 | end
37 |
--------------------------------------------------------------------------------
/gulpfile.js/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "root": {
3 | "src": "./source",
4 | "dest": "./.tmp"
5 | },
6 |
7 | "tasks": {
8 | "browserSync": {
9 | "proxy": "http://localhost:4567",
10 | "reloadDelay" : 1000,
11 | "files": ["./source/**/*.{erb,html,haml}"]
12 | },
13 |
14 | "static": {
15 | "src": "static",
16 | "dest": "./"
17 | },
18 |
19 | "js": {
20 | "src": "javascripts",
21 | "dest": "javascripts",
22 | "entries": {
23 | "all": ["./all.js"]
24 | },
25 | "extensions": ["js", "coffee", "json"],
26 | "babel": {
27 | "presets": ["es2015", "stage-1"],
28 | "plugins": []
29 | },
30 | "extractSharedJs": false
31 | },
32 | "css": {
33 | "src": "stylesheets",
34 | "dest": "stylesheets",
35 | "autoprefixer": {
36 | "browsers": ["last 3 version"]
37 | },
38 | "sass": {
39 | "indentedSyntax": false,
40 | "includePaths": [],
41 | "precision": 10
42 | },
43 | "extensions": ["sass", "scss", "css"]
44 | },
45 |
46 | "html": {
47 | "src": "./",
48 | "dest": "./",
49 | "extensions": ["html", "erb", "haml", "md", "yml"],
50 | "excludeFolders": ["images", "javascripts", "stylesheets"]
51 | },
52 |
53 | "images": {
54 | "src": "images",
55 | "dest": "images",
56 | "extensions": ["jpg", "png", "svg", "gif"]
57 | },
58 |
59 | "fonts": {
60 | "src": "fonts",
61 | "dest": "fonts",
62 | "extensions": ["woff2", "woff", "eot", "ttf", "svg"]
63 | },
64 |
65 | "iconFont": {
66 | "src": "icons",
67 | "dest": "fonts",
68 | "sassDest": "generated",
69 | "extensions": ["woff2", "woff", "eot", "ttf", "svg"]
70 | },
71 |
72 | "svgSprite": {
73 | "src": "icons",
74 | "dest": "images",
75 | "extensions": ["svg"]
76 | },
77 |
78 | "production" : {
79 | "rev": true
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/gulpfile.js/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | gulpfile.js
3 | ===========
4 | Rather than manage one giant configuration file responsible
5 | for creating multiple tasks, each task has been broken out into
6 | its own file in gulpfile.js/tasks. Any files in that directory get
7 | automatically required below.
8 |
9 | To add a new task, simply add a new task file that directory.
10 | gulpfile.js/tasks/default.js specifies the default set of tasks to run
11 | when you run `gulp`.
12 | */
13 |
14 | var requireDir = require('require-dir')
15 |
16 | // Require all tasks in gulpfile.js/tasks, including subfolders
17 | requireDir('./tasks', { recurse: true })
18 |
--------------------------------------------------------------------------------
/gulpfile.js/lib/__tests__/pathToUrl.test.js:
--------------------------------------------------------------------------------
1 | var assert = require('chai').assert
2 | var pathToUrl = require('../pathToUrl')
3 |
4 | describe('pathToUrl', function() {
5 | it('converts Windows paths to a url path', function() {
6 | var urlPath = pathToUrl("\\Foo\\bar\\baz")
7 | assert.equal(urlPath, '/Foo/bar/baz')
8 | })
9 |
10 | it('does not affect unix paths', function() {
11 | var unixPath = pathToUrl('/Foo/bar/baz/')
12 | assert.equal(unixPath, '/Foo/bar/baz/')
13 | })
14 |
15 | it('normalizes path segments', function() {
16 | var joinedPath = pathToUrl('/','//Foo', 'bar', 'baz/')
17 | assert.equal(joinedPath, '/Foo/bar/baz/')
18 | })
19 | })
20 |
--------------------------------------------------------------------------------
/gulpfile.js/lib/compileLogger.js:
--------------------------------------------------------------------------------
1 | var gutil = require("gulp-util")
2 | var prettifyTime = require('./prettifyTime')
3 | var handleErrors = require('./handleErrors')
4 |
5 | module.exports = function(err, stats) {
6 | if(err) throw new gutil.PluginError("webpack", err)
7 |
8 | var statColor = stats.compilation.warnings.length < 1 ? 'green' : 'yellow'
9 |
10 | if(stats.compilation.errors.length > 0) {
11 | stats.compilation.errors.forEach(function(error){
12 | handleErrors(error)
13 | statColor = 'red'
14 | })
15 | } else {
16 | var compileTime = prettifyTime(stats.endTime - stats.startTime)
17 | gutil.log(gutil.colors[statColor](stats))
18 | gutil.log('Compiled with', gutil.colors.cyan('webpack'), 'in', gutil.colors.magenta(compileTime))
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/gulpfile.js/lib/getEnabledTasks.js:
--------------------------------------------------------------------------------
1 | var config = require('../config')
2 | var compact = require('lodash/compact')
3 |
4 | // Grouped by what can run in parallel
5 | var assetTasks = ['fonts', 'iconFont', 'images', 'svgSprite']
6 | var codeTasks = ['css', 'js']
7 |
8 | module.exports = function(env) {
9 |
10 | function matchFilter(task) {
11 | if(config.tasks[task]) {
12 | if(task === 'js') {
13 | task = env === 'production' ? 'webpack:production' : false
14 | }
15 | return task
16 | }
17 | }
18 |
19 | function exists(value) {
20 | return !!value
21 | }
22 |
23 | return {
24 | assetTasks: compact(assetTasks.map(matchFilter).filter(exists)),
25 | codeTasks: compact(codeTasks.map(matchFilter).filter(exists))
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/gulpfile.js/lib/handleErrors.js:
--------------------------------------------------------------------------------
1 | var notify = require("gulp-notify")
2 |
3 | module.exports = function(errorObject, callback) {
4 | notify.onError(errorObject.toString().split(': ').join(':\n')).apply(this, arguments)
5 | // Keep gulp from hanging on this task
6 | if (typeof this.emit === 'function') this.emit('end')
7 | }
8 |
--------------------------------------------------------------------------------
/gulpfile.js/lib/pathToUrl.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 |
3 | module.exports = function pathToUrl() {
4 | // Normalizes Windows file paths to valid url paths
5 | return path.join.apply(this, arguments).replace(/\\/g, '/')
6 | }
7 |
--------------------------------------------------------------------------------
/gulpfile.js/lib/prettifyTime.js:
--------------------------------------------------------------------------------
1 | module.exports = function(milliseconds) {
2 | if(milliseconds > 999) {
3 | return (milliseconds / 1000).toFixed(2) + " s"
4 | } else {
5 | return milliseconds + ' ms'
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/gulpfile.js/lib/repeatString.js:
--------------------------------------------------------------------------------
1 | module.exports = function(pattern, number) {
2 | var string = ''
3 | while (number > 0){
4 | number--
5 | string += pattern
6 | }
7 | return string
8 | }
9 |
--------------------------------------------------------------------------------
/gulpfile.js/lib/webpack-multi-config.js:
--------------------------------------------------------------------------------
1 | var config = require('../config')
2 | if(!config.tasks.js) return
3 |
4 | var path = require('path')
5 | var pathToUrl = require('./pathToUrl')
6 | var webpack = require('webpack')
7 | var webpackManifest = require('./webpackManifest')
8 |
9 | module.exports = function(env) {
10 | var jsSrc = path.resolve(config.root.src, config.tasks.js.src)
11 | var jsDest = path.resolve(config.root.dest, config.tasks.js.dest)
12 | var publicPath = pathToUrl(config.tasks.js.dest, '/')
13 |
14 | var extensions = config.tasks.js.extensions.map(function(extension) {
15 | return '.' + extension
16 | })
17 |
18 | var rev = config.tasks.production.rev && env === 'production'
19 | var filenamePattern = rev ? '[name]-[hash].js' : '[name].js'
20 |
21 | var webpackConfig = {
22 | context: jsSrc,
23 | plugins: [],
24 | resolve: {
25 | root: [
26 | jsSrc,
27 | path.join(__dirname, "..", "gulp", "node_modules")
28 | ],
29 | extensions: [''].concat(extensions)
30 | },
31 | module: {
32 | loaders: [
33 | {
34 | test: /\.js$/,
35 | loader: 'babel-loader',
36 | exclude: /node_modules/,
37 | query: config.tasks.js.babel
38 | },
39 | {
40 | test: /\.coffee$/,
41 | loader: "coffee-loader" },
42 | {
43 | test: /\.(coffee\.md|litcoffee)$/,
44 | loader: "coffee-loader?literate"
45 | }
46 | ]
47 | }
48 | }
49 |
50 | if(env === 'development') {
51 | webpackConfig.devtool = 'inline-source-map'
52 |
53 | // Create new entries object with webpack-hot-middleware added
54 | for (var key in config.tasks.js.entries) {
55 | var entry = config.tasks.js.entries[key]
56 | config.tasks.js.entries[key] = ['webpack-hot-middleware/client?&reload=true'].concat(entry)
57 | }
58 |
59 | webpackConfig.plugins.push(new webpack.HotModuleReplacementPlugin())
60 | }
61 |
62 | if(env !== 'test') {
63 | // Karma doesn't need entry points or output settings
64 | webpackConfig.entry = config.tasks.js.entries
65 |
66 | webpackConfig.output= {
67 | path: path.normalize(jsDest),
68 | filename: filenamePattern,
69 | publicPath: publicPath
70 | }
71 |
72 | if(config.tasks.js.extractSharedJs) {
73 | // Factor out common dependencies into a shared.js
74 | webpackConfig.plugins.push(
75 | new webpack.optimize.CommonsChunkPlugin({
76 | name: 'shared',
77 | filename: filenamePattern,
78 | })
79 | )
80 | }
81 | }
82 |
83 | if(env === 'production') {
84 | if(rev) {
85 | webpackConfig.plugins.push(new webpackManifest(publicPath, config.root.dest))
86 | }
87 | webpackConfig.plugins.push(
88 | new webpack.DefinePlugin({
89 | 'process.env': {
90 | 'NODE_ENV': JSON.stringify('production')
91 | }
92 | }),
93 | new webpack.optimize.DedupePlugin(),
94 | new webpack.optimize.UglifyJsPlugin({
95 | output: { comments: false },
96 | compress: { drop_console: true },
97 | }),
98 | new webpack.NoErrorsPlugin()
99 | )
100 | }
101 |
102 | return webpackConfig
103 | }
104 |
--------------------------------------------------------------------------------
/gulpfile.js/lib/webpackManifest.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var fs = require('fs')
3 |
4 | module.exports = function(publicPath, dest, filename) {
5 | filename = filename || 'rev-manifest.json'
6 |
7 | return function() {
8 | this.plugin("done", function(stats) {
9 | var stats = stats.toJson()
10 | var chunks = stats.assetsByChunkName
11 | var manifest = {}
12 |
13 | for (var key in chunks) {
14 | var originalFilename = key + '.js'
15 | manifest[path.join(publicPath, originalFilename)] = path.join(publicPath, chunks[key])
16 | }
17 |
18 | fs.writeFileSync(
19 | path.join(process.cwd(), dest, filename),
20 | JSON.stringify(manifest)
21 | )
22 | })
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/gulpfile.js/tasks/browserSync.js:
--------------------------------------------------------------------------------
1 | if(global.production) return
2 |
3 | var browserSync = require('browser-sync')
4 | var gulp = require('gulp')
5 | var webpack = require('webpack')
6 | var webpackMultiConfig = require('../lib/webpack-multi-config')
7 | var config = require('../config')
8 | var pathToUrl = require('../lib/pathToUrl')
9 |
10 | var browserSyncTask = function() {
11 |
12 | var webpackConfig = webpackMultiConfig('development')
13 | var compiler = webpack(webpackConfig)
14 | var proxyConfig = config.tasks.browserSync.proxy || null;
15 |
16 | if (typeof(proxyConfig) === 'string') {
17 | config.tasks.browserSync.proxy = {
18 | target : proxyConfig
19 | }
20 | }
21 |
22 | var server = config.tasks.browserSync.proxy || config.tasks.browserSync.server;
23 |
24 | server.middleware = [
25 | require('webpack-dev-middleware')(compiler, {
26 | stats: 'errors-only',
27 | publicPath: pathToUrl('/', webpackConfig.output.publicPath)
28 | }),
29 | require('webpack-hot-middleware')(compiler)
30 | ]
31 |
32 | browserSync.init(config.tasks.browserSync)
33 | }
34 |
35 | gulp.task('browserSync', browserSyncTask)
36 | module.exports = browserSyncTask
37 |
--------------------------------------------------------------------------------
/gulpfile.js/tasks/clean.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp')
2 | var del = require('del')
3 | var config = require('../config')
4 |
5 | var cleanTask = function (cb) {
6 | del([config.root.dest]).then(function (paths) {
7 | cb()
8 | })
9 | }
10 |
11 | gulp.task('clean', cleanTask)
12 | module.exports = cleanTask
13 |
--------------------------------------------------------------------------------
/gulpfile.js/tasks/css.js:
--------------------------------------------------------------------------------
1 | var config = require('../config')
2 | if(!config.tasks.css) return
3 |
4 | var gulp = require('gulp')
5 | var gulpif = require('gulp-if')
6 | var browserSync = require('browser-sync')
7 | var sass = require('gulp-sass')
8 | var sourcemaps = require('gulp-sourcemaps')
9 | var handleErrors = require('../lib/handleErrors')
10 | var autoprefixer = require('gulp-autoprefixer')
11 | var path = require('path')
12 | var cssnano = require('gulp-cssnano')
13 |
14 | var paths = {
15 | src: path.join(config.root.src, config.tasks.css.src, '/**/*.{' + config.tasks.css.extensions + '}'),
16 | dest: path.join(config.root.dest, config.tasks.css.dest)
17 | }
18 |
19 | var cssTask = function () {
20 | return gulp.src(paths.src)
21 | .pipe(gulpif(!global.production, sourcemaps.init()))
22 | .pipe(sass(config.tasks.css.sass))
23 | .on('error', handleErrors)
24 | .pipe(autoprefixer(config.tasks.css.autoprefixer))
25 | .pipe(gulpif(global.production, cssnano({autoprefixer: false})))
26 | .pipe(gulpif(!global.production, sourcemaps.write()))
27 | .pipe(gulp.dest(paths.dest))
28 | .pipe(browserSync.stream())
29 | }
30 |
31 | gulp.task('css', cssTask)
32 | module.exports = cssTask
33 |
--------------------------------------------------------------------------------
/gulpfile.js/tasks/default.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp')
2 | var gulpSequence = require('gulp-sequence')
3 | var getEnabledTasks = require('../lib/getEnabledTasks')
4 |
5 | var defaultTask = function(cb) {
6 | var tasks = getEnabledTasks('watch')
7 | gulpSequence('clean', tasks.assetTasks, tasks.codeTasks, 'static', 'watch', cb)
8 | }
9 |
10 | gulp.task('default', defaultTask)
11 | module.exports = defaultTask
12 |
--------------------------------------------------------------------------------
/gulpfile.js/tasks/deploy.js:
--------------------------------------------------------------------------------
1 | var config = require('../config')
2 | var ghPages = require('gulp-gh-pages')
3 | var gulp = require('gulp')
4 | var open = require('open')
5 | var os = require('os')
6 | var package = require('../../package.json')
7 | var path = require('path')
8 |
9 | var settings = {
10 | url: package.homepage,
11 | src: path.join(config.root.dest, '/**/*'),
12 | ghPages: {
13 | cacheDir: path.join(os.tmpdir(), package.name)
14 | }
15 | }
16 |
17 | var deployTask = function() {
18 | return gulp.src(settings.src)
19 | .pipe(ghPages(settings.ghPages))
20 | .on('end', function(){
21 | open(settings.url)
22 | })
23 | }
24 |
25 | gulp.task('deploy', ['production'], deployTask)
26 | module.exports = deployTask
27 |
--------------------------------------------------------------------------------
/gulpfile.js/tasks/fonts.js:
--------------------------------------------------------------------------------
1 | var config = require('../config')
2 | if(!config.tasks.fonts) return
3 |
4 | var browserSync = require('browser-sync')
5 | var changed = require('gulp-changed')
6 | var gulp = require('gulp')
7 | var path = require('path')
8 |
9 | var paths = {
10 | src: path.join(config.root.src, config.tasks.fonts.src, '/**/*.{' + config.tasks.fonts.extensions + '}'),
11 | dest: path.join(config.root.dest, config.tasks.fonts.dest)
12 | }
13 |
14 | var fontsTask = function() {
15 | return gulp.src([paths.src, '*!README.md'])
16 | .pipe(changed(paths.dest)) // Ignore unchanged files
17 | .pipe(gulp.dest(paths.dest))
18 | .pipe(browserSync.stream())
19 | }
20 |
21 | gulp.task('fonts', fontsTask)
22 | module.exports = fontsTask
23 |
--------------------------------------------------------------------------------
/gulpfile.js/tasks/iconFont/generateIconSass.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp')
2 | var render = require('gulp-nunjucks-render')
3 | var rename = require('gulp-rename')
4 | var handleErrors = require('../../lib/handleErrors')
5 | var gutil = require('gulp-util')
6 | var data = require('gulp-data')
7 |
8 | module.exports = function(config) {
9 | return function(glyphs, options) {
10 | gutil.log(gutil.colors.blue('Generating ' + config.sassDest + '/' + config.sassOutputName))
11 | render.nunjucks.configure(config.nunjucks, { watch: false })
12 |
13 | return gulp.src(config.template)
14 | .pipe(data({
15 | icons: glyphs.map(function(glyph) {
16 | gutil.log(gutil.colors.green('+ adding ' + glyph.name + ' glyph'))
17 | return {
18 | name: glyph.name,
19 | code: glyph.unicode[0].charCodeAt(0).toString(16).toUpperCase()
20 | }
21 | }),
22 |
23 | fontName: config.options.fontName,
24 | fontPath: config.fontPath,
25 | className: config.className,
26 | comment: '// DO NOT EDIT DIRECTLY!\n //Generated by gulpfile.js/tasks/iconFont.js\n //from ' + config.template
27 | }))
28 | .pipe(render({
29 | path: config.template
30 | }))
31 | .on('error', handleErrors)
32 | .pipe(rename(config.sassOutputName))
33 | .pipe(gulp.dest(config.sassDest))
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/gulpfile.js/tasks/iconFont/index.js:
--------------------------------------------------------------------------------
1 | var config = require('../../config')
2 | if(!config.tasks.iconFont) return
3 |
4 | var gulp = require('gulp')
5 | var iconfont = require('gulp-iconfont')
6 | var generateIconSass = require('./generateIconSass')
7 | var handleErrors = require('../../lib/handleErrors')
8 | var package = require('../../../package.json')
9 | var path = require('path')
10 | var url = require('url')
11 |
12 | var fontPath = path.join(config.root.dest, config.tasks.iconFont.dest)
13 | var cssPath = path.join(config.root.dest, config.tasks.css.dest)
14 |
15 | var settings = {
16 | name: package.name + ' icons',
17 | src: path.join(config.root.src, config.tasks.iconFont.src, '/*.svg'),
18 | dest: path.join(config.root.dest, config.tasks.iconFont.dest),
19 | sassDest: path.join(config.root.src, config.tasks.css.src, config.tasks.iconFont.sassDest),
20 | template: path.normalize('./gulpfile.js/tasks/iconFont/template.sass'),
21 | sassOutputName: '_icons.sass',
22 | fontPath: url.resolve('.',path.relative(cssPath, fontPath)),
23 | className: 'icon',
24 | options: {
25 | timestamp: 0, // see https://github.com/fontello/svg2ttf/issues/33
26 | fontName: 'icons',
27 | normalize: false,
28 | formats: config.tasks.iconFont.extensions
29 | }
30 | }
31 |
32 | var iconFontTask = function() {
33 | return gulp.src(settings.src)
34 | .pipe(iconfont(settings.options))
35 | .on('glyphs', generateIconSass(settings))
36 | .on('error', handleErrors)
37 | .pipe(gulp.dest(settings.dest))
38 | }
39 |
40 | gulp.task('iconFont', iconFontTask)
41 | module.exports = iconFontTask
42 |
--------------------------------------------------------------------------------
/gulpfile.js/tasks/iconFont/template.sass:
--------------------------------------------------------------------------------
1 | // {{comment}}
2 |
3 | @font-face
4 | font-family: {{fontName}}
5 | src: url("{{fontPath}}/{{fontName}}.eot")
6 | src: url("{{fontPath}}/{{fontName}}.eot?#iefix") format('embedded-opentype'), url("{{fontPath}}/{{fontName}}.woff") format('woff'), url("{{fontPath}}/{{fontName}}.ttf") format('truetype'), url("{{fontPath}}/{{fontName}}.svg#{{fontName}}") format('svg')
7 | font-weight: normal
8 | font-style: normal
9 |
10 | =icon($content: '')
11 | &:before
12 | -moz-osx-font-smoothing: grayscale
13 | -webkit-font-smoothing: antialiased
14 | content: $content
15 | font-family: '{{fontName}}'
16 | font-style: normal
17 | font-variant: normal
18 | font-weight: normal
19 | line-height: 1
20 | speak: none
21 | text-transform: none
22 | @content
23 |
24 | .icon
25 | +icon
26 |
27 | {% for icon in icons -%}
28 | // Save variable
29 | $icon-{{icon.name}}: "\{{icon.code}}"
30 | // Save mixin
31 | =icon--{{icon.name}}
32 | +icon($icon-{{icon.name}})
33 | @content
34 | // Expose as class
35 | .icon.-{{icon.name}}:before
36 | content: $icon-{{icon.name}}
37 |
38 | {% endfor %}
39 |
--------------------------------------------------------------------------------
/gulpfile.js/tasks/images.js:
--------------------------------------------------------------------------------
1 | var config = require('../config')
2 | if(!config.tasks.images) return
3 |
4 | var browserSync = require('browser-sync')
5 | var changed = require('gulp-changed')
6 | var gulp = require('gulp')
7 | var imagemin = require('gulp-imagemin')
8 | var path = require('path')
9 |
10 | var paths = {
11 | src: path.join(config.root.src, config.tasks.images.src, '/**/*.{' + config.tasks.images.extensions + '}'),
12 | dest: path.join(config.root.dest, config.tasks.images.dest)
13 | }
14 |
15 | var imagesTask = function() {
16 | return gulp.src([paths.src, , '*!README.md'])
17 | .pipe(changed(paths.dest)) // Ignore unchanged files
18 | .pipe(imagemin({progressive: true})) // Optimize
19 | .pipe(gulp.dest(paths.dest))
20 | .pipe(browserSync.stream())
21 | }
22 |
23 | gulp.task('images', imagesTask)
24 | module.exports = imagesTask
25 |
--------------------------------------------------------------------------------
/gulpfile.js/tasks/production.js:
--------------------------------------------------------------------------------
1 | var config = require('../config')
2 | var gulp = require('gulp')
3 | var gulpSequence = require('gulp-sequence')
4 | var getEnabledTasks = require('../lib/getEnabledTasks')
5 |
6 | var productionTask = function(cb) {
7 | global.production = true
8 | var tasks = getEnabledTasks('production')
9 | gulpSequence('clean', tasks.assetTasks, tasks.codeTasks, config.tasks.production.rev ? 'rev': false, 'size-report', 'static', cb)
10 | }
11 |
12 | gulp.task('production', productionTask)
13 | module.exports = productionTask
14 |
--------------------------------------------------------------------------------
/gulpfile.js/tasks/rev/index.js:
--------------------------------------------------------------------------------
1 | var config = require('../../config')
2 | if(!config.tasks.production.rev) return
3 |
4 | var gulp = require('gulp')
5 | var gutil = require('gulp-util')
6 | var gulpSequence = require('gulp-sequence')
7 |
8 | // If you are familiar with Rails, this task the equivalent of `rake assets:precompile`
9 | var revTask = function(cb) {
10 | gulpSequence(
11 | // 1) Add md5 hashes to assets referenced by CSS and JS files
12 | 'rev-assets',
13 | // 2) Update asset references (images, fonts, etc) with reved filenames in compiled css + js
14 | 'rev-update-references',
15 | // 3) Rev and compress CSS and JS files (this is done after assets, so that if a referenced asset hash changes, the parent hash will change as well
16 | 'rev-css',
17 | // 4) Update asset references in HTML
18 | 'update-html',
19 | cb)
20 | }
21 |
22 | gulp.task('rev', revTask)
23 | module.exports = revTask
24 |
--------------------------------------------------------------------------------
/gulpfile.js/tasks/rev/rev-assets.js:
--------------------------------------------------------------------------------
1 | var config = require('../../config')
2 | var gulp = require('gulp')
3 | var path = require('path')
4 | var rev = require('gulp-rev')
5 | var revNapkin = require('gulp-rev-napkin');
6 |
7 | // 1) Add md5 hashes to assets referenced by CSS and JS files
8 | gulp.task('rev-assets', function() {
9 | // Ignore files that may reference assets. We'll rev them next.
10 | var ignoreThese = '!' + path.join(config.root.dest,'/**/*+(css|js|json|html)')
11 |
12 | return gulp.src([path.join(config.root.dest,'/**/*'), ignoreThese])
13 | .pipe(rev())
14 | .pipe(gulp.dest(config.root.dest))
15 | .pipe(revNapkin({verbose: false}))
16 | .pipe(rev.manifest(path.join(config.root.dest, 'rev-manifest.json'), {merge: true}))
17 | .pipe(gulp.dest(''))
18 | })
19 |
--------------------------------------------------------------------------------
/gulpfile.js/tasks/rev/rev-css.js:
--------------------------------------------------------------------------------
1 | var config = require('../../config')
2 | var gulp = require('gulp')
3 | var path = require('path')
4 | var rev = require('gulp-rev')
5 | var revNapkin = require('gulp-rev-napkin')
6 |
7 | // 4) Rev and compress CSS and JS files (this is done after assets, so that if a
8 | // referenced asset hash changes, the parent hash will change as well
9 | gulp.task('rev-css', function(){
10 | return gulp.src(path.join(config.root.dest,'/**/*.css'))
11 | .pipe(rev())
12 | .pipe(gulp.dest(config.root.dest))
13 | .pipe(revNapkin({verbose: false}))
14 | .pipe(rev.manifest(path.join(config.root.dest, 'rev-manifest.json'), {merge: true}))
15 | .pipe(gulp.dest(''))
16 | })
17 |
--------------------------------------------------------------------------------
/gulpfile.js/tasks/rev/rev-update-references.js:
--------------------------------------------------------------------------------
1 | var config = require('../../config')
2 | var gulp = require('gulp')
3 | var path = require('path')
4 | var revReplace = require('gulp-rev-replace')
5 |
6 | // 2) Update asset references with reved filenames in compiled css + js
7 | gulp.task('rev-update-references', function(){
8 | var manifest = gulp.src(path.join(config.root.dest, "rev-manifest.json"))
9 |
10 | return gulp.src(path.join(config.root.dest,'/**/**.{css,js}'))
11 | .pipe(revReplace({manifest: manifest}))
12 | .pipe(gulp.dest(config.root.dest))
13 | })
14 |
--------------------------------------------------------------------------------
/gulpfile.js/tasks/rev/update-html.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp')
2 | var config = require('../../config')
3 | var revReplace = require('gulp-rev-replace')
4 | var path = require('path')
5 |
6 | // 5) Update asset references in HTML
7 | gulp.task('update-html', function(){
8 | var manifest = gulp.src(path.join(config.root.dest, "/rev-manifest.json"))
9 | return gulp.src(path.join(config.root.dest, config.tasks.html.dest, '/**/*.html'))
10 | .pipe(revReplace({manifest: manifest}))
11 | .pipe(gulp.dest(path.join(config.root.dest, config.tasks.html.dest)))
12 | })
13 |
--------------------------------------------------------------------------------
/gulpfile.js/tasks/server.js:
--------------------------------------------------------------------------------
1 | var compress = require('compression')
2 | var config = require('../config')
3 | var express = require('express')
4 | var gulp = require('gulp')
5 | var gutil = require('gulp-util')
6 | var logger = require('morgan')
7 | var open = require('open')
8 | var path = require('path')
9 |
10 | var settings = {
11 | root: path.resolve(process.cwd(), config.root.dest),
12 | port: process.env.PORT || 5000,
13 | logLevel: process.env.NODE_ENV ? 'combined' : 'dev',
14 | staticOptions: {
15 | extensions: ['html'],
16 | maxAge: '31556926'
17 | }
18 | }
19 |
20 | var serverTask = function() {
21 | var url = 'http://localhost:' + settings.port
22 |
23 | express()
24 | .use(compress())
25 | .use(logger(settings.logLevel))
26 | .use('/', express.static(settings.root, settings.staticOptions))
27 | .listen(settings.port)
28 |
29 | gutil.log('production server started on ' + gutil.colors.green(url))
30 | open(url)
31 | }
32 |
33 | gulp.task('server', serverTask)
34 | module.exports = serverTask
35 |
--------------------------------------------------------------------------------
/gulpfile.js/tasks/sizereport.js:
--------------------------------------------------------------------------------
1 | var config = require('../config')
2 | var gulp = require('gulp')
3 | var repeatString = require('../lib/repeatString')
4 | var sizereport = require('gulp-sizereport')
5 |
6 | gulp.task('size-report', function() {
7 | return gulp.src([config.root.dest + '/**/*', '*!rev-manifest.json'])
8 | .pipe(sizereport({
9 | gzip: true
10 | }))
11 | })
12 |
--------------------------------------------------------------------------------
/gulpfile.js/tasks/static.js:
--------------------------------------------------------------------------------
1 | var config = require('../config')
2 | var changed = require('gulp-changed')
3 | var gulp = require('gulp')
4 | var path = require('path')
5 |
6 | var paths = {
7 | src: [
8 | path.join(config.root.src, config.tasks.static.src, '/**'),
9 | path.join('!' + config.root.src, config.tasks.static.src, '/README.md')
10 | ],
11 | dest: path.join(config.root.dest, config.tasks.static.dest)
12 | }
13 |
14 | var staticTask = function() {
15 | return gulp.src(paths.src)
16 | .pipe(changed(paths.dest)) // Ignore unchanged files
17 | .pipe(gulp.dest(paths.dest))
18 | }
19 |
20 | gulp.task('static', staticTask)
21 | module.exports = staticTask
22 |
--------------------------------------------------------------------------------
/gulpfile.js/tasks/svgSprite.js:
--------------------------------------------------------------------------------
1 | var config = require('../config')
2 | if(!config.tasks.svgSprite) return
3 |
4 | var browserSync = require('browser-sync')
5 | var gulp = require('gulp')
6 | var imagemin = require('gulp-imagemin')
7 | var svgstore = require('gulp-svgstore')
8 | var path = require('path')
9 |
10 | var svgSpriteTask = function() {
11 |
12 | var settings = {
13 | src: path.join(config.root.src, config.tasks.svgSprite.src, '/*.svg'),
14 | dest: path.join(config.root.dest, config.tasks.svgSprite.dest)
15 | }
16 |
17 | return gulp.src(settings.src)
18 | .pipe(imagemin())
19 | .pipe(svgstore())
20 | .pipe(gulp.dest(settings.dest))
21 | .pipe(browserSync.stream())
22 | }
23 |
24 | gulp.task('svgSprite', svgSpriteTask)
25 | module.exports = svgSpriteTask
26 |
--------------------------------------------------------------------------------
/gulpfile.js/tasks/watch.js:
--------------------------------------------------------------------------------
1 | var config = require('../config')
2 | var gulp = require('gulp')
3 | var path = require('path')
4 | var watch = require('gulp-watch')
5 |
6 | var watchTask = function() {
7 | var watchableTasks = ['fonts', 'iconFont', 'images', 'svgSprite', 'css']
8 |
9 | watchableTasks.forEach(function(taskName) {
10 | var task = config.tasks[taskName]
11 | if(task) {
12 | var glob = path.join(config.root.src, task.src, '**/*.{' + task.extensions.join(',') + '}')
13 | watch(glob, function() {
14 | require('./' + taskName)()
15 | })
16 | }
17 | })
18 | }
19 |
20 | gulp.task('watch', ['browserSync'], watchTask)
21 | module.exports = watchTask
22 |
--------------------------------------------------------------------------------
/gulpfile.js/tasks/webpackProduction.js:
--------------------------------------------------------------------------------
1 | var config = require('../config')
2 | if(!config.tasks.js) return
3 |
4 | var config = require('../lib/webpack-multi-config')('production')
5 | var gulp = require('gulp')
6 | var logger = require('../lib/compileLogger')
7 | var webpack = require('webpack')
8 |
9 | var webpackProductionTask = function(callback) {
10 | webpack(config, function(err, stats) {
11 | logger(err, stats)
12 | callback()
13 | })
14 | }
15 |
16 | gulp.task('webpack:production', webpackProductionTask)
17 | module.exports = webpackProductionTask
18 |
--------------------------------------------------------------------------------
/helpers/README.md:
--------------------------------------------------------------------------------
1 | # Gulp Starter Middleman Asset Helpers
2 |
3 | Source files should be in a `source` directory in the root of the project, **not** in `app/assets`. You'll also no longer be using the built in Middleman asset helpers like `javascript_include_tag` and the like. Instead, you'll use a set of **gulp_asset_helpers** with regular markup.
4 |
5 | #### app/helpers/gulp_asset_helper.rb
6 | In production (`npm run production`), filenames get hashed so you can cache them forever. When the file or any of it's referenced assets changes, the hash changes. This works just like the Middleman asset pipeline, and we have similar helpers to ensure that the correct filenames are referenced in production:
7 |
8 | ```ruby
9 | gulp_asset_path('image/asset.jpg') # -> /image/logo-n39o4orb81.png
10 | gulp_js_path('app.js') # -> /javascripts/app-f43e9abc11.js
11 | gulp_css_path('app.css') # -> /stylesheets/app-d29e4cdb76.css
12 | gulp_image_path('logo.png') # -> /images/logo-n39o4orb81.png
13 | ```
14 |
15 | So instead of this:
16 | ```erb
17 | <%= image_tag 'logo.png', alt: 'logo' %>
18 | ```
19 |
20 | You would do this:
21 | ```ruby
22 |
23 | ```
24 |
25 | Instead of this:
26 | ```erb
27 | <%= stylesheet_link_tag :site %>
28 | ```
29 |
30 | You would do this:
31 | ```erb
32 | <%= stylesheet_link_tag gulp_css_path('site.css') %>
33 | ```
34 |
35 | ##### Sprite helper
36 | There's also a `<%= sprite('id') %>` helper included for use with the `svgSpriteTask` task. It looks like:
37 |
38 | ```
39 | def sprite(id, classes = "", viewBox = "0 0 24 24")
40 | "".html_safe
41 | end
42 | ```
43 |
--------------------------------------------------------------------------------
/helpers/gulp_asset_helper.rb:
--------------------------------------------------------------------------------
1 | module GulpAssetHelper
2 | def gulp_asset_path(path, type = nil)
3 | rev_manifest = nil
4 |
5 | # In development, check for the manifest every time
6 | if config[:environment].to_s != 'production'
7 | rev_manifest = JSON.parse(File.read(REV_MANIFEST_PATH)) if File.exist?(REV_MANIFEST_PATH)
8 | # In production, use the manifest cached in initializers/gulp.rb
9 | else
10 | rev_manifest = REV_MANIFEST if defined?(REV_MANIFEST)
11 | end
12 |
13 | root = GULP_CONFIG['root']['dest'].gsub(/(.*).tmp/, '/')
14 | asset_path = type ? File.join(GULP_CONFIG['tasks'][type.to_s]['dest'].to_s, path.to_s) : path.to_s
15 | asset_path = rev_manifest[asset_path] if rev_manifest
16 | asset_path = File.join(root, asset_path)
17 | File.absolute_path(asset_path, '/')
18 | end
19 |
20 | def gulp_js_path(path)
21 | gulp_asset_path(path, 'js')
22 | end
23 |
24 | def gulp_css_path(path)
25 | gulp_asset_path(path, 'css')
26 | end
27 |
28 | def gulp_image_path(path)
29 | gulp_asset_path(path, 'images')
30 | end
31 |
32 | def sprite(id, classes = "", viewBox = "0 0 24 24")
33 | "".html_safe
34 | end
35 | end
36 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | var config = require('./gulpfile.js/config')
2 | var karmaWebpack = require('karma-webpack')
3 | var webpackConfig = require('./gulpfile.js/lib/webpack-multi-config')
4 | var path = require('path')
5 |
6 | var testSrc = path.join(config.root.src, config.tasks.js.src, '/**/__tests__/*')
7 |
8 | var karmaConfig = {
9 | frameworks: ['mocha', 'sinon-chai'],
10 | files: [ testSrc ],
11 | preprocessors: {},
12 | webpack: webpackConfig('test'),
13 | singleRun: process.env.TRAVIS_CI === 'true',
14 | reporters: ['nyan'],
15 | browsers: [(process.env.TRAVIS_CI === 'true'? 'Firefox' : 'Chrome')]
16 | }
17 |
18 | karmaConfig.preprocessors[testSrc] = ['webpack']
19 |
20 | module.exports = function(config) {
21 | config.set(karmaConfig)
22 | }
23 |
--------------------------------------------------------------------------------
/lib/gulp.rb:
--------------------------------------------------------------------------------
1 | GULP_CONFIG = JSON.parse(File.read('gulpfile.js/config.json'))
2 | REV_MANIFEST_PATH = File.join(GULP_CONFIG['root']['dest'], 'rev-manifest.json')
3 |
4 | if File.exist?(REV_MANIFEST_PATH)
5 | REV_MANIFEST = JSON.parse(File.read(REV_MANIFEST_PATH))
6 | end
7 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "middleman-gulp-starter",
3 | "version": "1.4.2",
4 | "description": "Middleman v4 + Gulp Starter",
5 | "engines": {
6 | "node": ">=0.12.0 ~5.9.0",
7 | "npm": ">=2.14.12 ~3.7.3"
8 | },
9 | "homepage": "https://github.com/craigmdennis/middleman-gulp-starter",
10 | "repository": {
11 | "type": "git",
12 | "url": "git@github.com:craigmdennis/middleman-gulp-starter.git"
13 | },
14 | "scripts": {
15 | "start": "gulp",
16 | "gulp": "gulp",
17 | "development": "gulp",
18 | "production": "gulp production",
19 | "deploy": "gulp deploy",
20 | "demo": "gulp production && gulp server",
21 | "test": "gulp production && karma start --single-run",
22 | "test:watch": "karma start",
23 | "test:gulp": "mocha ./gulpfile.js/**/*.test.js"
24 | },
25 | "devDependencies": {
26 | "babel-core": "6.13.2",
27 | "babel-loader": "6.2.5",
28 | "babel-preset-es2015": "6.13.2",
29 | "babel-preset-stage-1": "6.13.0",
30 | "browser-sync": "2.14.0",
31 | "chai": "3.5.0",
32 | "coffee-loader": "^0.7.2",
33 | "coffee-script": "^1.10.0",
34 | "compression": "1.6.2",
35 | "del": "2.2.2",
36 | "express": "4.14.0",
37 | "gulp": "3.9.1",
38 | "gulp-autoprefixer": "3.1.1",
39 | "gulp-changed": "1.3.2",
40 | "gulp-cssnano": "2.1.2",
41 | "gulp-data": "^1.2.1",
42 | "gulp-gh-pages": "0.5.4",
43 | "gulp-iconfont": "8.0.1",
44 | "gulp-if": "2.0.1",
45 | "gulp-imagemin": "3.0.3",
46 | "gulp-notify": "2.2.0",
47 | "gulp-nunjucks-render": "^2.0.0",
48 | "gulp-rename": "1.2.2",
49 | "gulp-rev": "7.1.2",
50 | "gulp-rev-napkin": "0.1.0",
51 | "gulp-rev-replace": "0.4.3",
52 | "gulp-sass": "2.3.2",
53 | "gulp-sequence": "0.4.5",
54 | "gulp-sizereport": "1.1.3",
55 | "gulp-sourcemaps": "1.6.0",
56 | "gulp-svgstore": "6.0.0",
57 | "gulp-uglify": "2.0.0",
58 | "gulp-util": "3.0.7",
59 | "gulp-watch": "4.3.9",
60 | "karma": "1.2.0",
61 | "karma-chrome-launcher": "2.0.0",
62 | "karma-cli": "1.0.1",
63 | "karma-firefox-launcher": "1.0.0",
64 | "karma-mocha": "1.1.1",
65 | "karma-nyan-reporter": "0.2.4",
66 | "karma-sinon-chai": "1.2.3",
67 | "karma-webpack": "1.8.0",
68 | "lodash": "4.15.0",
69 | "lolex": "1.5.1",
70 | "mocha": "3.0.2",
71 | "morgan": "1.7.0",
72 | "object-assign": "4.1.0",
73 | "open": "0.0.5",
74 | "pretty-hrtime": "1.0.2",
75 | "require-dir": "0.3.0",
76 | "sinon": "1.17.5",
77 | "sinon-chai": "2.8.0",
78 | "webpack": "1.13.2",
79 | "webpack-dev-middleware": "1.6.1",
80 | "webpack-hot-middleware": "2.12.2"
81 | },
82 | "license": "MIT"
83 | }
84 |
--------------------------------------------------------------------------------
/source/images/middleman-logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/source/index.html.erb:
--------------------------------------------------------------------------------
1 | ---
2 | title: Welcome to Middleman
3 | ---
4 |
5 |
11 | <%= link_to "Read Documentation Online", "https://middlemanapp.com", target: "_blank" %> 12 |
13 |