Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
reveal.js/gulpfile.js /
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
319 lines (274 sloc)
9.23 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const pkg = require('./package.json') | |
| const path = require('path') | |
| const glob = require('glob') | |
| const yargs = require('yargs') | |
| const colors = require('colors') | |
| const through = require('through2'); | |
| const qunit = require('node-qunit-puppeteer') | |
| const {rollup} = require('rollup') | |
| const {terser} = require('rollup-plugin-terser') | |
| const babel = require('@rollup/plugin-babel').default | |
| const commonjs = require('@rollup/plugin-commonjs') | |
| const resolve = require('@rollup/plugin-node-resolve').default | |
| const sass = require('sass') | |
| const gulp = require('gulp') | |
| const tap = require('gulp-tap') | |
| const zip = require('gulp-zip') | |
| const header = require('gulp-header') | |
| const eslint = require('gulp-eslint') | |
| const minify = require('gulp-clean-css') | |
| const connect = require('gulp-connect') | |
| const autoprefixer = require('gulp-autoprefixer') | |
| const root = yargs.argv.root || '.' | |
| const port = yargs.argv.port || 8000 | |
| const host = yargs.argv.host || 'localhost' | |
| const banner = `/*! | |
| * reveal.js ${pkg.version} | |
| * ${pkg.homepage} | |
| * MIT licensed | |
| * | |
| * Copyright (C) 2011-2023 Hakim El Hattab, https://hakim.se | |
| */\n` | |
| // Prevents warnings from opening too many test pages | |
| process.setMaxListeners(20); | |
| const babelConfig = { | |
| babelHelpers: 'bundled', | |
| ignore: ['node_modules'], | |
| compact: false, | |
| extensions: ['.js', '.html'], | |
| plugins: [ | |
| 'transform-html-import-to-string' | |
| ], | |
| presets: [[ | |
| '@babel/preset-env', | |
| { | |
| corejs: 3, | |
| useBuiltIns: 'usage', | |
| modules: false | |
| } | |
| ]] | |
| }; | |
| // Our ES module bundle only targets newer browsers with | |
| // module support. Browsers are targeted explicitly instead | |
| // of using the "esmodule: true" target since that leads to | |
| // polyfilling older browsers and a larger bundle. | |
| const babelConfigESM = JSON.parse( JSON.stringify( babelConfig ) ); | |
| babelConfigESM.presets[0][1].targets = { browsers: [ | |
| 'last 2 Chrome versions', | |
| 'last 2 Safari versions', | |
| 'last 2 iOS versions', | |
| 'last 2 Firefox versions', | |
| 'last 2 Edge versions', | |
| ] }; | |
| let cache = {}; | |
| // Creates a bundle with broad browser support, exposed | |
| // as UMD | |
| gulp.task('js-es5', () => { | |
| return rollup({ | |
| cache: cache.umd, | |
| input: 'js/index.js', | |
| plugins: [ | |
| resolve(), | |
| commonjs(), | |
| babel( babelConfig ), | |
| terser() | |
| ] | |
| }).then( bundle => { | |
| cache.umd = bundle.cache; | |
| return bundle.write({ | |
| name: 'Reveal', | |
| file: './dist/reveal.js', | |
| format: 'umd', | |
| banner: banner, | |
| sourcemap: true | |
| }); | |
| }); | |
| }) | |
| // Creates an ES module bundle | |
| gulp.task('js-es6', () => { | |
| return rollup({ | |
| cache: cache.esm, | |
| input: 'js/index.js', | |
| plugins: [ | |
| resolve(), | |
| commonjs(), | |
| babel( babelConfigESM ), | |
| terser() | |
| ] | |
| }).then( bundle => { | |
| cache.esm = bundle.cache; | |
| return bundle.write({ | |
| file: './dist/reveal.esm.js', | |
| format: 'es', | |
| banner: banner, | |
| sourcemap: true | |
| }); | |
| }); | |
| }) | |
| gulp.task('js', gulp.parallel('js-es5', 'js-es6')); | |
| // Creates a UMD and ES module bundle for each of our | |
| // built-in plugins | |
| gulp.task('plugins', () => { | |
| return Promise.all([ | |
| { name: 'RevealHighlight', input: './plugin/highlight/plugin.js', output: './plugin/highlight/highlight' }, | |
| { name: 'RevealMarkdown', input: './plugin/markdown/plugin.js', output: './plugin/markdown/markdown' }, | |
| { name: 'RevealSearch', input: './plugin/search/plugin.js', output: './plugin/search/search' }, | |
| { name: 'RevealNotes', input: './plugin/notes/plugin.js', output: './plugin/notes/notes' }, | |
| { name: 'RevealZoom', input: './plugin/zoom/plugin.js', output: './plugin/zoom/zoom' }, | |
| { name: 'RevealMath', input: './plugin/math/plugin.js', output: './plugin/math/math' }, | |
| ].map( plugin => { | |
| return rollup({ | |
| cache: cache[plugin.input], | |
| input: plugin.input, | |
| plugins: [ | |
| resolve(), | |
| commonjs(), | |
| babel({ | |
| ...babelConfig, | |
| ignore: [/node_modules\/(?!(highlight\.js|marked)\/).*/], | |
| }), | |
| terser() | |
| ] | |
| }).then( bundle => { | |
| cache[plugin.input] = bundle.cache; | |
| bundle.write({ | |
| file: plugin.output + '.esm.js', | |
| name: plugin.name, | |
| format: 'es' | |
| }) | |
| bundle.write({ | |
| file: plugin.output + '.js', | |
| name: plugin.name, | |
| format: 'umd' | |
| }) | |
| }); | |
| } )); | |
| }) | |
| // a custom pipeable step to transform Sass to CSS | |
| function compileSass() { | |
| return through.obj( ( vinylFile, encoding, callback ) => { | |
| const transformedFile = vinylFile.clone(); | |
| sass.render({ | |
| data: transformedFile.contents.toString(), | |
| includePaths: ['css/', 'css/theme/template'] | |
| }, ( err, result ) => { | |
| if( err ) { | |
| console.log( vinylFile.path ); | |
| console.log( err.formatted ); | |
| } | |
| else { | |
| transformedFile.extname = '.css'; | |
| transformedFile.contents = result.css; | |
| callback( null, transformedFile ); | |
| } | |
| }); | |
| }); | |
| } | |
| gulp.task('css-themes', () => gulp.src(['./css/theme/source/*.{sass,scss}']) | |
| .pipe(compileSass()) | |
| .pipe(gulp.dest('./dist/theme'))) | |
| gulp.task('css-core', () => gulp.src(['css/reveal.scss']) | |
| .pipe(compileSass()) | |
| .pipe(autoprefixer()) | |
| .pipe(minify({compatibility: 'ie9'})) | |
| .pipe(header(banner)) | |
| .pipe(gulp.dest('./dist'))) | |
| gulp.task('css', gulp.parallel('css-themes', 'css-core')) | |
| gulp.task('qunit', () => { | |
| let serverConfig = { | |
| root, | |
| port: 8009, | |
| host: 'localhost', | |
| name: 'test-server' | |
| } | |
| let server = connect.server( serverConfig ) | |
| let testFiles = glob.sync('test/*.html' ) | |
| let totalTests = 0; | |
| let failingTests = 0; | |
| let tests = Promise.all( testFiles.map( filename => { | |
| return new Promise( ( resolve, reject ) => { | |
| qunit.runQunitPuppeteer({ | |
| targetUrl: `http://${serverConfig.host}:${serverConfig.port}/${filename}`, | |
| timeout: 20000, | |
| redirectConsole: false, | |
| puppeteerArgs: ['--allow-file-access-from-files'] | |
| }) | |
| .then(result => { | |
| if( result.stats.failed > 0 ) { | |
| console.log(`${'!'} ${filename} [${result.stats.passed}/${result.stats.total}] in ${result.stats.runtime}ms`.red); | |
| // qunit.printResultSummary(result, console); | |
| qunit.printFailedTests(result, console); | |
| } | |
| else { | |
| console.log(`${'✔'} ${filename} [${result.stats.passed}/${result.stats.total}] in ${result.stats.runtime}ms`.green); | |
| } | |
| totalTests += result.stats.total; | |
| failingTests += result.stats.failed; | |
| resolve(); | |
| }) | |
| .catch(error => { | |
| console.error(error); | |
| reject(); | |
| }); | |
| } ) | |
| } ) ); | |
| return new Promise( ( resolve, reject ) => { | |
| tests.then( () => { | |
| if( failingTests > 0 ) { | |
| reject( new Error(`${failingTests}/${totalTests} tests failed`.red) ); | |
| } | |
| else { | |
| console.log(`${'✔'} Passed ${totalTests} tests`.green.bold); | |
| resolve(); | |
| } | |
| } ) | |
| .catch( () => { | |
| reject(); | |
| } ) | |
| .finally( () => { | |
| server.close(); | |
| } ); | |
| } ); | |
| } ) | |
| gulp.task('eslint', () => gulp.src(['./js/**', 'gulpfile.js']) | |
| .pipe(eslint()) | |
| .pipe(eslint.format())) | |
| gulp.task('test', gulp.series( 'eslint', 'qunit' )) | |
| gulp.task('default', gulp.series(gulp.parallel('js', 'css', 'plugins'), 'test')) | |
| gulp.task('build', gulp.parallel('js', 'css', 'plugins')) | |
| gulp.task('package', gulp.series(() => | |
| gulp.src( | |
| [ | |
| './index.html', | |
| './dist/**', | |
| './lib/**', | |
| './images/**', | |
| './plugin/**', | |
| './**/*.md' | |
| ], | |
| { base: './' } | |
| ) | |
| .pipe(zip('reveal-js-presentation.zip')).pipe(gulp.dest('./')) | |
| )) | |
| gulp.task('reload', () => gulp.src(['**/*.html', '**/*.md']) | |
| .pipe(connect.reload())); | |
| gulp.task('serve', () => { | |
| connect.server({ | |
| root: root, | |
| port: port, | |
| host: host, | |
| livereload: true | |
| }) | |
| gulp.watch(['**/*.html', '**/*.md'], gulp.series('reload')) | |
| gulp.watch(['js/**'], gulp.series('js', 'reload', 'eslint')) | |
| gulp.watch(['plugin/**/plugin.js', 'plugin/**/*.html'], gulp.series('plugins', 'reload')) | |
| gulp.watch([ | |
| 'css/theme/source/*.{sass,scss}', | |
| 'css/theme/template/*.{sass,scss}', | |
| ], gulp.series('css-themes', 'reload')) | |
| gulp.watch([ | |
| 'css/*.scss', | |
| 'css/print/*.{sass,scss,css}' | |
| ], gulp.series('css-core', 'reload')) | |
| gulp.watch(['test/*.html'], gulp.series('test')) | |
| }) |