Skip to content

Instantly share code, notes, and snippets.

@tassilogroeper
Last active May 4, 2017 15:26
Show Gist options
  • Save tassilogroeper/e9a3aa8fa4e9aadf471e57c4e305e9be to your computer and use it in GitHub Desktop.
Save tassilogroeper/e9a3aa8fa4e9aadf471e57c4e305e9be to your computer and use it in GitHub Desktop.
D8-Gulp4-setup
{
"extends": "stylelint-config-sass-guidelines",
"rules": {
"string-quotes": "double",
"order/properties-alphabetical-order": null,
"order/declaration-block-properties-alphabetical-order": null,
"max-nesting-depth": [
3,
{
"ignore": [
"blockless-at-rules"
]
}
],
"selector-no-qualifying-type": [
true,
{
"ignore": [
"attribute",
"class"
]
}
],
"selector-class-pattern": [
"^[a-z0-9\\-\\_]+$",
{
"message": "Selector should be written in lowercase with hyphens or underscores (selector-class-pattern)"
}
]
}
}
// --------------------------------------------------------
// Dependencies
// --------------------------------------------------------
const fractal = require('@frctl/fractal').create();
const pkg = require('./package.json');
const twigAdapter = require('@frctl/twig-drupal');
const webroot = 'web';
// mock twig functions, filter and tags
const twig = twigAdapter({
handlePrefix: '@components/'
});
// --------------------------------------------------------
// Configuration
// --------------------------------------------------------
const paths = {
build: `${__dirname}/${webroot}/styleguide`,
docs: `${__dirname}/${webroot}/themes/custom/wndrs/docs`,
components: `${__dirname}/${webroot}/themes/custom/wndrs/components`,
static: `${__dirname}/${webroot}/themes/custom/wndrs/static`
};
fractal.set('project.title', pkg.name);
fractal.set('project.version', pkg.version);
fractal.set('project.author', pkg.author);
fractal.components.engine(twig);
fractal.components.set('default.preview', '@preview');
fractal.components.set('ext', '.twig');
fractal.components.set('path', paths.components);
fractal.docs.set('path', paths.docs);
fractal.web.set('builder.dest', paths.build);
fractal.web.set('static.path', paths.static);
// --------------------------------------------------------
// Export config
// --------------------------------------------------------
module.exports = fractal;
'use strict';
// using env vars for gulp
// https://www.sitepoint.com/pass-parameters-gulp-tasks/
const env_prod = ((process.env.NODE_ENV || 'dev').trim().toLowerCase() === 'production');
const env_debug = !env_prod;
const themeName = 'wndrs';
const webroot = 'web';
// Fractal
const fractal = require('./fractal.js');
const logger = fractal.cli.console; // keep a reference to the fractal CLI console utility
// Requirements
const gulp = require('gulp');
const sass = require('gulp-sass');
const gulpif = require('gulp-if');
const sourcemaps = require('gulp-sourcemaps');
const path = require('path');
const postcss = require('gulp-postcss');
const autoprefixer = require('autoprefixer');
const cssnano = require('cssnano');
const rename = require('gulp-rename');
const reporter = require('postcss-reporter');
const include = require('gulp-include');
const uglify = require('gulp-uglify');
const iconfont = require('gulp-iconfont');
const iconfontCss = require('gulp-iconfont-css');
const eslint = require('gulp-eslint');
const imagemin = require('gulp-imagemin');
const gulpStylelint = require('gulp-stylelint');
const stylefmt = require('gulp-stylefmt');
// --------------------------------------------------------
// Configuration
// --------------------------------------------------------
const paths = {
webroot: `${__dirname}/${webroot}`,
build: `${__dirname}/${webroot}/themes/custom/${themeName}/build`,
theme: `${__dirname}/${webroot}/themes/custom/${themeName}`,
docs: `${__dirname}/${webroot}/themes/custom/${themeName}/docs`,
components: `${__dirname}/${webroot}/themes/custom/${themeName}/components`,
modules: `${__dirname}/node_modules`,
static: `${__dirname}/${webroot}/themes/custom/${themeName}/static`
};
const processors = [
autoprefixer({
browsers: ['last 2 version', 'safari 9', 'ie 11', 'opera 12.1', 'ios 9', 'android 4']
}),
cssnano({
options: {
safe: true
},
autoprefixer: false,
discardComments: {
removeAll: true
},
colormin: true,
}),
reporter()
];
const sass_config = {
includePaths: [
`${paths.modules}`,
`${paths.modules}/foundation-sites/scss/`,
`${paths.modules}/motion-ui/src/`,
`${paths.components}`,
],
};
const sass_custom_sources = [
`${paths.theme}/**/*.scss`,
`!${paths.theme}/sass/vendor/**/*`,
`!${paths.theme}/sass/generated/**/*`,
`!${paths.theme}/sass/templates/**/*`,
];
const js_custom_sources = [
`${paths.theme}/**/*.js`,
`!${paths.theme}/js/**/*.js`,
`!${paths.theme}/public/**/*.js`,
`!${paths.theme}/static/**/*.js`,
`!${paths.theme}/public/**/*.js`,
`!${paths.theme}/js-src/vendor/*.js`,
];
const js_config = {
includePaths: [
`${paths.components}/**/*`,
`${paths.theme}/js-src`,
`${paths.modules}`,
`${paths.modules}/jquery/**/*`,
`${paths.modules}/foundation-sites/dist/js`,
`${paths.modules}/jquery-once`,
`${paths.modules}/fastclick/**/*`,
],
};
const img_config = [
imagemin.gifsicle({interlaced: true}),
imagemin.jpegtran({progressive: true}),
imagemin.optipng({optimizationLevel: 5}),
imagemin.svgo({plugins: [{cleanupIDs: false}]})
];
// --------------------------------------------------------
// Fractal Tasks
// --------------------------------------------------------
// Build static site
function build() {
const builder = fractal.web.builder();
builder.on('progress', (completed, total) => logger.update(`Exported ${completed} of ${total} items`, 'info'));
builder.on('error', err => logger.error(err.message));
return builder.build().then(() => {
logger.success('Fractal build completed!');
});
}
// Serve dynamic site
function serve() {
const server = fractal.web.server({
sync: true,
});
server.on('error', err => logger.error(err.message));
return server.start().then(() => {
logger.success(`Fractal server is now running at ${server.url}`);
});
}
function copy_drupal_js() {
return gulp.src(`${paths.webroot}/core/misc/drupal.js`)
.pipe(gulp.dest(`${paths.static}/js`));
}
function copy_frontend_assets() {
return gulp.src(`${paths.theme}/assets/**/*`)
.pipe(gulp.dest(`${paths.static}/assets`));
}
// --------------------------------------------------------
// Styles
// --------------------------------------------------------
function theme_styles() {
return gulp.src(`${paths.theme}/sass/*.scss`)
.pipe(gulpif(env_debug, sourcemaps.init()))
.pipe(sass(sass_config).on('error', sass.logError))
.pipe(postcss(processors))
.pipe(rename({suffix: '.min'}))
.pipe(gulpif(env_debug, sourcemaps.write('./')))
.pipe(gulp.dest(`${paths.static}/css`));
}
// --------------------------------------------------------
// Javascripts
// --------------------------------------------------------
function theme_scripts() {
return gulp.src([
`${paths.theme}/js-src/*.js`,
`${paths.theme}/js-src/vendor/*.js`
])
.pipe(gulpif(env_debug, sourcemaps.init()))
.pipe(include(js_config).on('error', console.log))
.pipe(uglify().on('error', console.log))
.pipe(rename({suffix: '.min'}))
.pipe(gulpif(env_debug, sourcemaps.write('./')))
.pipe(gulp.dest(`${paths.static}/js`));
}
// --------------------------------------------------------
// Vectors
// --------------------------------------------------------
function component_assets() {
return gulp.src([
`${paths.components}/**/assets/**/*.{svg,jpg,jpeg,png}`,
])
.pipe(imagemin(img_config))
.pipe(rename(function(file) {file.dirname = path.dirname(file.dirname);}))
.pipe(gulp.dest(`${paths.static}/components`))
.pipe(rename(function(file) {file.dirname = file.dirname + '/static/';}))
.pipe(gulp.dest(`${paths.components}`));
}
function vectors() {
return gulp.src([
`${paths.theme}/svg-src/**/*.svg`,
`!${paths.theme}/svg-src/**/dist/*.svg`,
`!${paths.theme}/svg-src/icons/**/*.svg`,
])
.pipe(imagemin(img_config))
.pipe(gulp.dest(`${paths.static}/svg`));
}
function icons() {
let fontCss = iconfontCss({
fontName: 'iconfont',
path: `${paths.theme}/sass/templates/iconfont.bootstrap.scss`,
targetPath: '../../sass/generated/_iconfont.scss',
fontPath: '../iconfont/'
});
let font = iconfont({
normalize: true,
fontName: 'iconfont',
formats: ['ttf', 'eot', 'woff', 'woff2', 'svg']
});
return gulp.src([
`${paths.theme}/svg-src/icons/*.svg`,
])
.pipe(imagemin())
.pipe(fontCss)
.pipe(font)
.pipe(gulp.dest(`${paths.static}/iconfont`));
}
// --------------------------------------------------------
// Images
// --------------------------------------------------------
function images() {
return gulp.src(`${paths.theme}/images/**/*`)
.pipe(imagemin(img_config))
.pipe(gulp.dest(`${paths.static}/images`));
}
// --------------------------------------------------------
// Linter
// --------------------------------------------------------
function script_linting() {
return gulp.src(js_custom_sources)
.pipe(eslint())
.pipe(eslint.format());
}
function script_linting_fix() {
return gulp.src(js_custom_sources)
.pipe(eslint({
fix: true,
}))
.pipe(eslint.format())
.pipe(gulp.dest(paths.theme));
}
function style_linting() {
return gulp.src(sass_custom_sources)
.pipe(gulpStylelint({
failAfterError: false,
reporters: [
{formatter: 'string', console: true}
]
}));
}
function style_linting_fix() {
return gulp.src(sass_custom_sources)
.pipe(stylefmt())
.pipe(gulp.dest(paths.theme));
}
// --------------------------------------------------------
// Watch
// --------------------------------------------------------
function watch() {
serve();
gulp.watch(`${paths.theme}/images/**/*`, images);
gulp.watch(`${paths.theme}/svg-src/**/*.svg`, gulp.parallel(vectors, icons));
gulp.watch(`${paths.components}/**/assets/**/*.{svg,jpg,png}`, component_assets);
gulp.watch(js_custom_sources, theme_scripts);
gulp.watch(sass_custom_sources, theme_styles);
}
// --------------------------------------------------------
// Task sets
// --------------------------------------------------------
const compile = gulp.series(
gulp.parallel(
copy_frontend_assets,
component_assets,
vectors,
icons
),
gulp.parallel(
images,
theme_scripts,
theme_styles
)
);
// @todo: merge into watch task
gulp.task('lint', gulp.parallel(script_linting, style_linting));
gulp.task('lint-fix', gulp.parallel(script_linting_fix, style_linting_fix));
gulp.task('start', gulp.series(compile, copy_drupal_js, serve));
gulp.task('static-styleguide', gulp.series(compile, copy_drupal_js, build));
gulp.task('watch', gulp.series(compile, copy_drupal_js, watch));
gulp.task('default', gulp.series(compile));
{
"name": "wondrous-base",
"version": "1.1.0",
"description": "automated tasks for local development and deployment",
"author": "WONDROUS LLC <hello@wondrous.ch> (https://www.wearewondrous.ch)",
"scripts": {
"project-local-drush": "cd web && ../vendor/bin/drush -y",
"gulp": "./node_modules/.bin/gulp"
},
"dependencies": {
"@frctl/fractal": "^1.1.3",
"@frctl/twig-drupal": "https://github.com/WondrousLLC/twig-drupal.git",
"autoprefixer": "^6.7.7",
"cssnano": "^3.10.0",
"faker": "^4.1.0",
"fastclick": "^1.0.6",
"foundation-sites": "^6.3.1",
"gulp": "gulpjs/gulp#4.0",
"gulp-eslint": "^3.0.1",
"gulp-iconfont": "^8.0.1",
"gulp-iconfont-css": "^2.1.0",
"gulp-if": "^2.0.2",
"gulp-imagemin": "^3.2.0",
"gulp-include": "^2.3.1",
"gulp-postcss": "^6.4.0",
"gulp-rename": "^1.2.2",
"gulp-reporter": "^1.8.1",
"gulp-sass": "^3.1.0",
"gulp-sourcemaps": "^2.5.0",
"gulp-stylefmt": "^1.1.0",
"gulp-stylelint": "^3.9.0",
"gulp-uglify": "^2.1.2",
"jquery": "^3.2.1",
"jquery-once": "^2.1.2",
"motion-ui": "^1.2.2",
"node-sass": "^4.5.2",
"postcss-reporter": "^3.0.0",
"rename": "^1.0.4",
"slick-carousel": "^1.6.0",
"stylelint-config-sass-guidelines": "^2.0.0",
"yamljs": "^0.2.8"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment