Skip to content

Instantly share code, notes, and snippets.

@atannus
Last active June 21, 2020 13:57
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 atannus/4dc9c4ec5036499d0b49681283a24174 to your computer and use it in GitHub Desktop.
Save atannus/4dc9c4ec5036499d0b49681283a24174 to your computer and use it in GitHub Desktop.
Basic Gulp Setup for Closure Family: Library + Compiler + Stylesheets + Templates
/**
* This is a minimal working setup for using Google Closure Tools.
*
* One thing I've used extensivelly that is not covered here is support for
* i18n, which would require generating a messages file, translating it and
* passing it into the js compilation step.
*
* Also not covered is CSS minification, but you can (probably) just enable
* that by passing the appropriate flag in the compile-css step.
*
* I hope this is helpful to you.
*
*/
/**
* The MIT License
*
* Copyright (c) 2019 André Tannús
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
const gulp = require('gulp');
const concat = require('gulp-concat');
const soynode = require('gulp-soynode');
const execSync = require('child_process').execSync;
const file = require('gulp-file');
const closureCompiler = require('google-closure-compiler').gulp();
const cssBase64 = require('gulp-css-base64');
const sourcemaps = require('gulp-sourcemaps');
// Compiles soy templates.
// Not meant to be run directly, but via task 'js'.
// The task 'compile-js' requires the output from this task.
gulp.task('compile-soy', function () {
return gulp.src('./src/views/*.soy')
.pipe(soynode({
useClosureStyle: true,
shouldProvideRequireSoyNamespaces: true,
shouldProvideRequireJsFunctions: true,
loadCompiledTemplates: false // otherwise gulp.watch breaks.
}))
.pipe(gulp.dest('./dist/views'));
});
// Compiles javascript.
// Requires output from task 'compile-soy'.
// Not meant to be run directly, but via task 'js'.
// Uses gulp.src() and takes advantage of gulp's sourcemaps plugin.
// @see https://github.com/google/closure-compiler-npm/blob/master/packages/google-closure-compiler/docs/gulp.md
gulp.task('compile-js', function () {
return gulp.src([
'./src/js/**/*.js',
'./dist/views/**/*.js',
'./node_modules/google-closure-library/closure/goog/**/*.js',
'./node_modules/google-closure-library/third_party/**/*.js'
], {base: './'})
.pipe(sourcemaps.init())
.pipe(closureCompiler({
entry_point: './src/js/index.js',
compilation_level: 'ADVANCED',
warning_level: 'QUIET',
language_in: 'ECMASCRIPT6_STRICT',
language_out: 'ECMASCRIPT5',
js_output_file: 'output.min.js'
}))
.pipe(sourcemaps.write('/')) // gulp-sourcemaps automatically adds the sourcemap url comment
.pipe(gulp.dest('./dist/js'));
});
// Concatenates all CSS into a single file, otherwise stylesheets.jar
// will process them individually producing clashing CSS class names.
// Not meant to be run directly, but via task 'css'.
gulp.task('concat-css', function() {
return gulp.src('./src/css/*.css')
.pipe(cssBase64({baseDir: "./"}))
.pipe(concat('styles.css'))
.pipe(gulp.dest('./dist/css'));
});
// Compiles CSS.
// Requires output from task 'concat-css'.
// Not meant to be run directly, but via task 'css'.
// This is the cleanest way I found to run a command and store its stdout to a file.
const compileCssCommand = [
'java -jar node_modules/google-closure-stylesheets/stylesheets.jar',
'dist/css/styles.css',
'--rename CLOSURE',
'--output-renaming-map-format CLOSURE_COMPILED',
'--output-renaming-map dist/css/styles-name-map.js'
].join(' ');
gulp.task('compile-css', function () {
var stdout = execSync(compileCssCommand).toString();
return file('styles.min.css', stdout, {src:true})
.pipe(gulp.dest('dist/css'));
});
// You should run these tasks.
gulp.task('css', gulp.series('concat-css', 'compile-css'));
gulp.task('js', gulp.series('compile-soy', 'compile-js'));
gulp.task('default', gulp.series('css', 'js'));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment