Skip to content

Instantly share code, notes, and snippets.

@jozefcipa
Last active August 29, 2018 13:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save jozefcipa/698fdbb6c207d3e5a41433186526ffac to your computer and use it in GitHub Desktop.
Save jozefcipa/698fdbb6c207d3e5a41433186526ffac to your computer and use it in GitHub Desktop.
Compiling Sass with autoprefixer, ReactJS, JSX, ES6, gzip compression, eslint, sourcemaps, livereload, html minifying, link hashes, vendor dependencies in separate bundle file
// NOTE: .js extension used here only for syntax highlighting, DO NOT use in development !!!
{
"env": {
"browser": true,
"es6": true,
"node": true
},
"parser": "babel-eslint",
"rules": {
"quotes": [2, "single"],
"strict": [2, "never"],
"generator-star-spacing": 1,
"babel/new-cap": 1,
"object-shorthand": 1,
"arrow-parens": 1,
"no-await-in-loop": 1,
"react/jsx-uses-react": 2,
"react/jsx-uses-vars": 2,
"react/react-in-jsx-scope": 2
},
"plugins": [
"babel",
"react"
]
}
// gulp
const gulp = require('gulp');
const util = require('gulp-util');
const source = require('vinyl-source-stream');
const buffer = require('vinyl-buffer');
const fs = require('fs');
const rename = require('gulp-rename');
const gulpif = require('gulp-if');
const replace = require('gulp-replace');
const clean = require('gulp-clean');
// sass
const sass = require('gulp-ruby-sass');
const cleanCSS = require('gulp-clean-css');
const autoprefixer = require('gulp-autoprefixer');
// js
const browserify = require('browserify');
const babelify = require('babelify');
const uglify = require('gulp-uglify');
// optimalization
const sourcemaps = require('gulp-sourcemaps');
const gzip = require('gulp-gzip');
const htmlmin = require('gulp-htmlmin');
const hash_src = require('gulp-hash-src');
// other
const livereload = require('gulp-livereload');
const eslint = require('gulp-eslint');
// load dependencies names
const packageJson = JSON.parse(fs.readFileSync('./package.json'));
const vendors = packageJson.vendor;
const paths = {
sass: {
entryFile: './sass/styles.sass',
srcDir: './sass',
distDir: './public/css',
watch: './sass/**/*.sass',
output: 'styles.css',
min: 'styles.min.css'
},
js: {
entryFile: './app/index.js',
srcDir: './app',
distDir: './public/js',
watch: './app/**/*.js',
bundle: {
output: 'main.js',
min: 'main.min.js'
},
vendor: {
output: 'vendor.js',
min: 'vendor.min.js'
}
},
html: {
entryFile: './html/index.html',
distFile: './public/index.html',
distDir: './public',
srcDir: './app'
}
};
gulp.task('default', ['clean', 'sass', 'vendor', 'js'], () => {
return gulp.start('html');
});
gulp.task('watch', () => {
livereload.listen();
gulp.watch(paths.sass.watch, ['sass']);
gulp.watch(paths.js.watch, ['js']);
});
// sass processing
gulp.task('sass', () => {
return sass(paths.sass.entryFile)
.on('error', sass.logError)
.pipe(gulpif(util.env.production, cleanCSS()))
.pipe(autoprefixer({
// browsers are defined in package.json
cascade: false
}))
.pipe(rename(util.env.production ? paths.sass.min : paths.sass.output))
.pipe(gulpif(util.env.production, gzip()))
.pipe(gulp.dest(paths.sass.distDir))
.pipe(livereload());
});
// react, jsx, es6 processing
gulp.task('js', ['lint'], () => {
return browserify({
entries: paths.js.entryFile,
extensions: ['.js'],
debug: true
})
.external(vendors) // Specify all vendors as external resource
.transform('babelify', {
presets: ['es2015', 'react'],
plugins: ['transform-es2015-destructuring', 'transform-object-rest-spread']
})
.bundle()
.pipe(source(util.env.production ? paths.js.bundle.min : paths.js.bundle.output))
.pipe(buffer())
.pipe(gulpif(!util.env.production, sourcemaps.init()))
.pipe(gulpif(util.env.production, uglify()))
.pipe(gulpif(util.env.production, gzip()))
.pipe(gulpif(!util.env.production, sourcemaps.write('./')))
.pipe(gulp.dest(paths.js.distDir))
.pipe(livereload());
});
// js vendor processing
gulp.task('vendor', () => {
const b = browserify({
debug: true
});
// require all libs specified in vendors array
vendors.forEach(lib => b.require(lib));
return b.bundle()
.pipe(source(util.env.production ? paths.js.vendor.min : paths.js.vendor.output))
.pipe(buffer())
.pipe(gulpif(util.env.production, uglify()))
.pipe(gulpif(util.env.production, gzip()))
.pipe(gulp.dest(paths.js.distDir));
});
// js linting
gulp.task('lint', () => {
return gulp.src([paths.js.watch, '!node_modules/**'])
.pipe(eslint())
.pipe(eslint.format())
.pipe(eslint.failAfterError());
});
// minify html and append hash to URLs
gulp.task('html', () => {
return gulp.src(paths.html.entryFile)
// file name
.pipe(replace('{STYLES}', () => {
return util.env.production ? `${paths.sass.min}.gz` : paths.sass.output;
}))
.pipe(replace('{BUNDLE}', () => {
return util.env.production ? `${paths.js.bundle.min}.gz` : paths.js.bundle.output;
}))
.pipe(replace('{VENDOR}', () => {
return util.env.production ? `${paths.js.vendor.min}.gz` : paths.js.vendor.output;
}))
.pipe(htmlmin({collapseWhitespace: true}))
.pipe(hash_src({
build_dir: paths.html.distDir,
src_path: paths.html.srcDir,
query_name: 'v',
// verbose: true // DEBUG
}))
.pipe(gulp.dest(paths.html.distDir))
});
gulp.task('clean', () => {
return gulp.src([paths.sass.distDir, paths.js.distDir, paths.html.distFile], {read: false})
.pipe(clean());
});
{
"name": "bsc-ideas_notes",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"test": "protractor tests/conf.js",
"start": "node server.js",
"production": "gulp --production"
},
"keywords": [
"reactjs",
"notes",
"rest",
"api",
"bsc ideas"
],
"author": "Jozef Cipa",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.0",
"babel-eslint": "^8.2.2",
"babel-plugin-transform-es2015-destructuring": "^6.23.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babelify": "^8.0.0",
"browserify": "^16.1.0",
"eslint-plugin-babel": "^4.1.2",
"eslint-plugin-react": "^7.7.0",
"gulp": "^3.9.1",
"gulp-autoprefixer": "^4.1.0",
"gulp-clean": "^0.4.0",
"gulp-clean-css": "^3.9.2",
"gulp-envify": "^1.0.0",
"gulp-eslint": "^4.0.2",
"gulp-gzip": "^1.4.2",
"gulp-hash-src": "^0.1.6",
"gulp-htmlmin": "^4.0.0",
"gulp-if": "^2.0.2",
"gulp-livereload": "^3.8.1",
"gulp-rename": "^1.2.2",
"gulp-replace": "^0.6.1",
"gulp-ruby-sass": "^3.0.0",
"gulp-sass": "^3.1.0",
"gulp-sourcemaps": "^2.6.4",
"gulp-uglify": "^3.0.0",
"gulp-util": "^3.0.8",
"vinyl-buffer": "^1.0.1",
"vinyl-source-stream": "^2.0.0"
},
"dependencies": {
"express": "^4.16.2",
"lodash.isempty": "^4.4.0",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-redux": "^5.0.7",
"react-router-dom": "^4.2.2",
"react-router-redux": "^4.0.8",
"redux": "^3.7.2"
},
"vendor": [
"lodash.isempty",
"react",
"react-dom",
"react-redux",
"react-router-dom",
"react-router-redux",
"redux"
],
"browsers": [
"last 2 versions"
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment