diff --git a/build-system/tasks/css/index.js b/build-system/tasks/css/index.js index a00415a472ce..0fe0c6cd6f17 100644 --- a/build-system/tasks/css/index.js +++ b/build-system/tasks/css/index.js @@ -15,27 +15,21 @@ */ const debounce = require('debounce'); -const file = require('gulp-file'); const fs = require('fs-extra'); -const gulp = require('gulp'); -const { - endBuildStep, - mkdirSync, - toPromise, - watchDebounceDelay, -} = require('../helpers'); +const globby = require('globby'); +const path = require('path'); const {buildExtensions} = require('../extension-helpers'); +const {endBuildStep, watchDebounceDelay} = require('../helpers'); const {jsifyCssAsync} = require('./jsify-css'); const {maybeUpdatePackages} = require('../update-packages'); -const {watch} = require('gulp'); +const {watch} = require('chokidar'); /** * Entry point for 'gulp css' - * @return {!Promise} */ async function css() { maybeUpdatePackages(); - return compileCss(); + await compileCss(); } const cssEntryPoints = [ @@ -84,80 +78,81 @@ const cssEntryPoints = [ }, ]; +/** + * Copies the css from the build folder to the dist folder + */ +async function copyCss() { + const startTime = Date.now(); + await fs.ensureDir('dist/v0'); + for (const {outCss} of cssEntryPoints) { + await fs.copy(`build/css/${outCss}`, `dist/${outCss}`); + } + const cssFiles = globby.sync('build/css/amp-*.css'); + await Promise.all( + cssFiles.map((cssFile) => { + return fs.copy(cssFile, `dist/v0/${path.basename(cssFile)}`); + }) + ); + endBuildStep('Copied', 'build/css/*.css to dist/v0/*.css', startTime); +} + +/** + * Writes CSS to build folder + * + * @param {string} css + * @param {string} jsFilename + * @param {string} cssFilename + * @param {boolean} append append CSS to existing file + */ +async function writeCss(css, jsFilename, cssFilename, append) { + await fs.ensureDir('build/css'); + const jsContent = 'export const cssText = ' + JSON.stringify(css); + await fs.writeFile(`build/${jsFilename}`, jsContent); + if (append) { + await fs.appendFile(`build/css/${cssFilename}`, css); + } else { + await fs.writeFile(`build/css/${cssFilename}`, css); + } +} + +/** + * @param {string} path + * @param {string} outJs + * @param {string} outCss + * @param {boolean} append + */ +async function writeCssEntryPoint(path, outJs, outCss, append) { + const css = await jsifyCssAsync(`css/${path}`); + await writeCss(css, outJs, outCss, append); +} + /** * Compile all the css and drop in the build folder * * @param {Object=} options * @return {!Promise} */ -function compileCss(options = {}) { +async function compileCss(options = {}) { if (options.watch) { - const watchFunc = () => { - compileCss(); - }; - watch('css/**/*.css').on('change', debounce(watchFunc, watchDebounceDelay)); - } - - /** - * Writes CSS to build folder - * - * @param {string} css - * @param {string} jsFilename - * @param {string} cssFilename - * @param {boolean} append append CSS to existing file - * @return {Promise} - */ - function writeCss(css, jsFilename, cssFilename, append) { - return toPromise( - file(jsFilename, 'export const cssText = ' + JSON.stringify(css), { - src: true, - }) - .pipe(gulp.dest('build')) - .on('end', function () { - mkdirSync('build'); - mkdirSync('build/css'); - if (append) { - fs.appendFileSync(`build/css/${cssFilename}`, css); - } else { - fs.writeFileSync(`build/css/${cssFilename}`, css); - } - }) - ); - } - - /** - * @param {string} path - * @param {string} outJs - * @param {string} outCss - * @param {boolean} append - * @return {!Promise} - */ - function writeCssEntryPoint(path, outJs, outCss, append) { - return jsifyCssAsync(`css/${path}`).then((css) => - writeCss(css, outJs, outCss, append) + watch('css/**/*.css').on( + 'change', + debounce(compileCss, watchDebounceDelay) ); } const startTime = Date.now(); - - let promise = Promise.resolve(); - - cssEntryPoints.forEach(({path, outJs, outCss, append}) => { - promise = promise.then(() => - writeCssEntryPoint(path, outJs, outCss, append) - ); - }); - - return promise - .then(() => buildExtensions({compileOnlyCss: true})) - .then(() => { - endBuildStep('Recompiled all CSS files into', 'build/', startTime); - }); + // Must be in order because some iterations write while others append. + for (const {path, outJs, outCss, append} of cssEntryPoints) { + await writeCssEntryPoint(path, outJs, outCss, append); + } + await buildExtensions({compileOnlyCss: true}); + endBuildStep('Recompiled all CSS files into', 'build/', startTime); } module.exports = { css, compileCss, + copyCss, cssEntryPoints, }; diff --git a/build-system/tasks/dist.js b/build-system/tasks/dist.js index bd100ab79e03..af67e7626358 100644 --- a/build-system/tasks/dist.js +++ b/build-system/tasks/dist.js @@ -15,9 +15,9 @@ */ const colors = require('kleur/colors'); -const file = require('gulp-file'); const fs = require('fs-extra'); -const gulp = require('gulp'); +const globby = require('globby'); +const path = require('path'); const { bootstrapThirdPartyFrames, compileAllJs, @@ -25,10 +25,8 @@ const { compileJs, endBuildStep, maybeToEsmName, - mkdirSync, printConfigHelp, printNobuildHelp, - toPromise, } = require('./helpers'); const { cleanupBuildDir, @@ -42,7 +40,7 @@ const { displayLifecycleDebugging, } = require('../compile/debug-compilation-lifecycle'); const {buildExtensions, parseExtensionFlags} = require('./extension-helpers'); -const {compileCss, cssEntryPoints} = require('./css'); +const {compileCss, copyCss} = require('./css'); const {compileJison} = require('./compile-jison'); const {formatExtractedMessages} = require('../compile/log-messages'); const {log} = require('../common/logging'); @@ -105,8 +103,8 @@ async function runPreDistSteps(options) { cleanupBuildDir(); await prebuild(); await compileCss(options); - await compileJison(); await copyCss(); + await compileJison(); await copyParsers(); await bootstrapThirdPartyFrames(options); displayLifecycleDebugging(); @@ -159,11 +157,9 @@ async function doDist(extraArgs = {}) { /** * Build AMP experiments.js. - * - * @return {!Promise} */ -function buildExperiments() { - return compileJs( +async function buildExperiments() { + await compileJs( './build/experiments/', 'experiments.max.js', './dist.tools/experiments/', @@ -183,19 +179,19 @@ function buildExperiments() { * @return {!Promise} */ function buildLoginDone(version) { - const buildDir = `build/all/amp-access-${version}/`; + const buildDir = `build/all/amp-access-${version}`; const builtName = `amp-login-done-${version}.max.js`; const minifiedName = `amp-login-done-${version}.js`; const latestName = 'amp-login-done-latest.js'; - return compileJs('./' + buildDir, builtName, './dist/v0/', { + return compileJs(`./${buildDir}`, builtName, './dist/v0/', { watch: argv.watch, includePolyfills: true, minify: true, minifiedName, latestName, extraGlobs: [ - buildDir + 'amp-login-done-0.1.max.js', - buildDir + 'amp-login-done-dialog.js', + `${buildDir}/amp-login-done-0.1.max.js`, + `${buildDir}/amp-login-done-dialog.js`, ], }); } @@ -205,23 +201,20 @@ function buildLoginDone(version) { */ async function buildWebPushPublisherFiles() { const distDir = 'dist/v0'; - const promises = []; - WEB_PUSH_PUBLISHER_VERSIONS.forEach((version) => { - WEB_PUSH_PUBLISHER_FILES.forEach((fileName) => { - const tempBuildDir = `build/all/amp-web-push-${version}/`; - const builtName = fileName + '.js'; - const minifiedName = maybeToEsmName(fileName + '.js'); - const p = compileJs('./' + tempBuildDir, builtName, './' + distDir, { + for (const version of WEB_PUSH_PUBLISHER_VERSIONS) { + for (const fileName of WEB_PUSH_PUBLISHER_FILES) { + const tempBuildDir = `build/all/amp-web-push-${version}`; + const builtName = `${fileName}.js`; + const minifiedName = maybeToEsmName(builtName); + await compileJs(`./${tempBuildDir}`, builtName, `./${distDir}`, { watch: argv.watch, includePolyfills: true, minify: true, minifiedName, - extraGlobs: [tempBuildDir + '*.js'], + extraGlobs: [`${tempBuildDir}/*.js`], }); - promises.push(p); - }); - }); - await Promise.all(promises); + } + } await postBuildWebPushPublisherFilesVersion(); } @@ -231,152 +224,116 @@ async function prebuild() { await preBuildWebPushPublisherFiles(); } -/** - * Copies the css from the build folder to the dist folder - * @return {!Promise} - */ -function copyCss() { - const startTime = Date.now(); - - cssEntryPoints.forEach(({outCss}) => { - fs.copySync(`build/css/${outCss}`, `dist/${outCss}`); - }); - - return toPromise( - gulp - .src('build/css/amp-*.css', {base: 'build/css/'}) - .pipe(gulp.dest('dist/v0')) - ).then(() => { - endBuildStep('Copied', 'build/css/*.css to dist/v0/*.css', startTime); - }); -} - /** * Copies parsers from the build folder to the dist folder - * @return {!Promise} */ -function copyParsers() { +async function copyParsers() { const startTime = Date.now(); - return fs.copy('build/parsers', 'dist/v0').then(() => { - endBuildStep('Copied', 'build/parsers/ to dist/v0', startTime); - }); + await fs.copy('build/parsers', 'dist/v0'); + endBuildStep('Copied', 'build/parsers/ to dist/v0', startTime); } /** * Build amp-web-push publisher files HTML page. - * - * @return {!Promise} */ async function preBuildWebPushPublisherFiles() { - mkdirSync('dist'); - mkdirSync('dist/v0'); - const promises = []; - - WEB_PUSH_PUBLISHER_VERSIONS.forEach((version) => { - WEB_PUSH_PUBLISHER_FILES.forEach((fileName) => { - const basePath = `extensions/amp-web-push/${version}/`; - const tempBuildDir = `build/all/amp-web-push-${version}/`; + for (const version of WEB_PUSH_PUBLISHER_VERSIONS) { + for (const fileName of WEB_PUSH_PUBLISHER_FILES) { + const srcPath = `extensions/amp-web-push/${version}`; + const destPath = `build/all/amp-web-push-${version}`; // Build Helper Frame JS - const js = fs.readFileSync(basePath + fileName + '.js', 'utf8'); - const builtName = fileName + '.js'; - const promise = toPromise( - gulp - .src(basePath + '/*.js', {base: basePath}) - .pipe(file(builtName, js)) - .pipe(gulp.dest(tempBuildDir)) + const js = await fs.readFile(`${srcPath}/${fileName}.js`, 'utf8'); + const builtName = `${fileName}.js`; + await fs.outputFile(`${destPath}/${builtName}`, js); + const jsFiles = globby.sync(`${srcPath}/*.js`); + await Promise.all( + jsFiles.map((jsFile) => { + return fs.copy(jsFile, `${destPath}/${path.basename(jsFile)}`); + }) ); - promises.push(promise); - }); - }); - return Promise.all(promises); + } + } } /** * post Build amp-web-push publisher files HTML page. */ -function postBuildWebPushPublisherFilesVersion() { +async function postBuildWebPushPublisherFilesVersion() { const distDir = 'dist/v0'; - WEB_PUSH_PUBLISHER_VERSIONS.forEach((version) => { - const basePath = `extensions/amp-web-push/${version}/`; - WEB_PUSH_PUBLISHER_FILES.forEach((fileName) => { - const minifiedName = maybeToEsmName(fileName + '.js'); - if (!fs.existsSync(distDir + '/' + minifiedName)) { - throw new Error(`Cannot find ${distDir}/${minifiedName}`); + for (const version of WEB_PUSH_PUBLISHER_VERSIONS) { + const basePath = `extensions/amp-web-push/${version}`; + for (const fileName of WEB_PUSH_PUBLISHER_FILES) { + const minifiedName = maybeToEsmName(`${fileName}.js`); + const minifiedFile = `${distDir}/${minifiedName}`; + if (!fs.existsSync(minifiedFile)) { + throw new Error(`Cannot find ${minifiedFile}`); } // Build Helper Frame HTML - let fileContents = fs.readFileSync(basePath + fileName + '.html', 'utf8'); - fileContents = fileContents.replace( - '', - '' + const html = await fs.readFile(`${basePath}/${fileName}.html`, 'utf8'); + const js = await fs.readFile(minifiedFile, 'utf8'); + const minifiedHtml = html.replace( + ``, + `` ); - - fs.writeFileSync('dist/v0/' + fileName + '.html', fileContents); - }); - }); + await fs.outputFile(`dist/v0/${fileName}.html`, minifiedHtml); + } + } } /** * Precompilation steps required to build experiment js binaries. - * @return {!Promise} */ async function preBuildExperiments() { - const path = 'tools/experiments'; - const htmlPath = path + '/experiments.html'; - const jsPath = path + '/experiments.js'; + const expDir = 'tools/experiments'; + const htmlDestDir = 'dist.tools/experiments'; + const htmlSrcPath = `${expDir}/experiments.html`; + const jsSrcPath = `${expDir}/experiments.js`; // Build HTML. - const html = fs.readFileSync(htmlPath, 'utf8'); + const html = await fs.readFile(htmlSrcPath, 'utf8'); const minHtml = html .replace( '/dist.tools/experiments/experiments.js', `https://${hostname}/v0/experiments.js` ) .replace(/\$internalRuntimeVersion\$/g, VERSION); - - await toPromise( - gulp - .src(htmlPath) - .pipe(file('experiments.cdn.html', minHtml)) - .pipe(gulp.dest('dist.tools/experiments/')) - ); + await fs.outputFile(`${htmlDestDir}/experiments.cdn.html`, minHtml); + await fs.copy(htmlSrcPath, `${htmlDestDir}/${path.basename(htmlSrcPath)}`); // Build JS. - const js = fs.readFileSync(jsPath, 'utf8'); + const jsDir = 'build/experiments/'; + const js = await fs.readFile(jsSrcPath, 'utf8'); const builtName = 'experiments.max.js'; - return toPromise( - gulp - .src(path + '/*.js') - .pipe(file(builtName, js)) - .pipe(gulp.dest('build/experiments/')) + await fs.outputFile(`${jsDir}/${builtName}`, js); + const jsFiles = globby.sync(`${expDir}/*.js`); + await Promise.all( + jsFiles.map((jsFile) => { + return fs.copy(jsFile, `${jsDir}/${path.basename(jsFile)}`); + }) ); } /** * Build "Login Done" page. - * @return {!Promise} */ -function preBuildLoginDone() { - return preBuildLoginDoneVersion('0.1'); +async function preBuildLoginDone() { + await preBuildLoginDoneVersion('0.1'); } /** * Build "Login Done" page for the specified version. - * * @param {string} version - * @return {!Promise} */ -function preBuildLoginDoneVersion(version) { - const path = `extensions/amp-access/${version}/`; - const buildDir = `build/all/amp-access-${version}/`; - const htmlPath = path + 'amp-login-done.html'; - const jsPath = path + 'amp-login-done.js'; +async function preBuildLoginDoneVersion(version) { + const srcDir = `extensions/amp-access/${version}`; + const buildDir = `build/all/amp-access-${version}`; + const htmlPath = `${srcDir}/amp-login-done.html`; + const jsPath = `${srcDir}/amp-login-done.js`; // Build HTML. - const html = fs.readFileSync(htmlPath, 'utf8'); + const html = await fs.readFile(htmlPath, 'utf8'); const minJs = `https://${hostname}/v0/amp-login-done-${version}.js`; const minHtml = html .replace(`../../../dist/v0/amp-login-done-${version}.max.js`, minJs) @@ -384,20 +341,17 @@ function preBuildLoginDoneVersion(version) { if (minHtml.indexOf(minJs) == -1) { throw new Error('Failed to correctly set JS in login-done.html'); } - - mkdirSync('dist'); - mkdirSync('dist/v0'); - - fs.writeFileSync('dist/v0/amp-login-done-' + version + '.html', minHtml); + await fs.outputFile(`dist/v0/amp-login-done-${version}.html`, minHtml); // Build JS. - const js = fs.readFileSync(jsPath, 'utf8'); - const builtName = 'amp-login-done-' + version + '.max.js'; - return toPromise( - gulp - .src(path + '/*.js', {base: path}) - .pipe(file(builtName, js)) - .pipe(gulp.dest(buildDir)) + const js = await fs.readFile(jsPath, 'utf8'); + const builtName = `amp-login-done-${version}.max.js`; + await fs.outputFile(`${buildDir}/${builtName}`, js); + const jsFiles = globby.sync(`${srcDir}/*.js`); + await Promise.all( + jsFiles.map((jsFile) => { + return fs.copy(jsFile, `${buildDir}/${path.basename(jsFile)}`); + }) ); } diff --git a/build-system/tasks/extension-helpers.js b/build-system/tasks/extension-helpers.js index 4adf08cc1526..7477404c5b37 100644 --- a/build-system/tasks/extension-helpers.js +++ b/build-system/tasks/extension-helpers.js @@ -29,7 +29,7 @@ const {isCiBuild} = require('../common/ci'); const {jsifyCssAsync} = require('./css/jsify-css'); const {log} = require('../common/logging'); const {maybeToEsmName, compileJs, mkdirSync} = require('./helpers'); -const {watch} = require('gulp'); +const {watch} = require('chokidar'); const {green, red, cyan} = colors; const argv = require('minimist')(process.argv.slice(2)); diff --git a/build-system/tasks/helpers.js b/build-system/tasks/helpers.js index b659bdc52f3c..2d26959a815d 100644 --- a/build-system/tasks/helpers.js +++ b/build-system/tasks/helpers.js @@ -21,9 +21,7 @@ const debounce = require('debounce'); const del = require('del'); const esbuild = require('esbuild'); const experimentDefines = require('../global-configs/experiments-const.json'); -const file = require('gulp-file'); const fs = require('fs-extra'); -const gulp = require('gulp'); const MagicString = require('magic-string'); const open = require('open'); const path = require('path'); @@ -119,16 +117,10 @@ function doBuildJs(jsBundles, name, extraOptions) { */ async function bootstrapThirdPartyFrames(options) { const startTime = Date.now(); - const promises = []; - thirdPartyFrames.forEach((frameObject) => { - promises.push( - thirdPartyBootstrap(frameObject.max, frameObject.min, options) - ); - }); if (options.watch) { thirdPartyFrames.forEach((frameObject) => { - const watchFunc = () => { - thirdPartyBootstrap(frameObject.max, frameObject.min, options); + const watchFunc = async () => { + await thirdPartyBootstrap(frameObject.max, frameObject.min, options); }; fileWatch(frameObject.max).on( 'change', @@ -136,7 +128,11 @@ async function bootstrapThirdPartyFrames(options) { ); }); } - await Promise.all(promises); + await Promise.all( + thirdPartyFrames.map(async (frameObject) => { + await thirdPartyBootstrap(frameObject.max, frameObject.min, options); + }) + ); endBuildStep( 'Bootstrapped 3p frames into', `dist.3p/${options.minify ? internalRuntimeVersion : 'current'}/`, @@ -644,10 +640,14 @@ async function applyAmpConfig(targetFile, localDev, fortesting) { * @param {!Object} options * @return {!Promise} */ -function thirdPartyBootstrap(input, outputName, options) { +async function thirdPartyBootstrap(input, outputName, options) { const {minify, fortesting} = options; + const destDir = `dist.3p/${minify ? internalRuntimeVersion : 'current'}`; + await fs.ensureDir(destDir); + if (!minify) { - return toPromise(gulp.src(input).pipe(gulp.dest('dist.3p/current'))); + await fs.copy(input, `${destDir}/${path.basename(input)}`); + return; } // By default we use an absolute URL, that is independent of the @@ -661,21 +661,12 @@ function thirdPartyBootstrap(input, outputName, options) { const html = fs .readFileSync(input, 'utf8') .replace(/\.\/integration\.js/g, integrationJs); - return toPromise( - file(outputName, html, {src: true}) - .pipe(gulp.dest('dist.3p/' + internalRuntimeVersion)) - .on('end', function () { - const aliasToLatestBuild = 'dist.3p/current-min'; - if (fs.existsSync(aliasToLatestBuild)) { - fs.unlinkSync(aliasToLatestBuild); - } - fs.symlinkSync( - './' + internalRuntimeVersion, - aliasToLatestBuild, - 'dir' - ); - }) - ); + await fs.writeFile(`${destDir}/${outputName}`, html); + const aliasToLatestBuild = 'dist.3p/current-min'; + if (fs.existsSync(aliasToLatestBuild)) { + fs.unlinkSync(aliasToLatestBuild); + } + fs.symlinkSync('./' + internalRuntimeVersion, aliasToLatestBuild, 'dir'); } /** @@ -693,18 +684,6 @@ function mkdirSync(path) { } } -/** - * Returns a promise for readable - * - * @param {*} readable - * @return {Promise} - */ -function toPromise(readable) { - return new Promise(function (resolve, reject) { - readable.on('error', reject).on('end', resolve); - }); -} - module.exports = { MINIFIED_TARGETS, applyAmpConfig, @@ -720,6 +699,5 @@ module.exports = { mkdirSync, printConfigHelp, printNobuildHelp, - toPromise, watchDebounceDelay, }; diff --git a/extensions/amp-web-push/0.1/amp-web-push-helper-frame.html b/extensions/amp-web-push/0.1/amp-web-push-helper-frame.html index 8964bd5f5bdf..fb425d36a4c9 100644 --- a/extensions/amp-web-push/0.1/amp-web-push-helper-frame.html +++ b/extensions/amp-web-push/0.1/amp-web-push-helper-frame.html @@ -4,7 +4,7 @@
- + diff --git a/extensions/amp-web-push/0.1/amp-web-push-permission-dialog.html b/extensions/amp-web-push/0.1/amp-web-push-permission-dialog.html index 7328a70063f7..618c2b35c094 100644 --- a/extensions/amp-web-push/0.1/amp-web-push-permission-dialog.html +++ b/extensions/amp-web-push/0.1/amp-web-push-permission-dialog.html @@ -137,6 +137,6 @@ - +