return new Promise((resolve, reject) => { const stream = gulp.src(outputDir + '/**/*.js'); stream.on('end', resolve); stream.on('error', reject); stream.pipe( replace(/\$internalRuntimeVersion\$/g, internalRuntimeVersion, 'runtime-version')) .pipe(shortenLicense()) .pipe(gulp.dest(outputDir)); });
return new Promise(function(resolve) { let entryModuleFilename; if (entryModuleFilenames instanceof Array) { entryModuleFilename = entryModuleFilenames[0]; } else { entryModuleFilename = entryModuleFilenames; entryModuleFilenames = [entryModuleFilename]; } const checkTypes = options.checkTypes || options.typeCheckOnly || argv.typecheck_only; const intermediateFilename = 'build/cc/' + entryModuleFilename.replace(/\//g, '_').replace(/^\./, ''); // If undefined/null or false then we're ok executing the deletions // and mkdir. if (!options.preventRemoveAndMakeDir) { cleanupBuildDir(); } const unneededFiles = [ 'build/fake-module/third_party/babel/custom-babel-helpers.js', ]; let wrapper = '(function(){%output%})();'; if (options.wrapper) { wrapper = options.wrapper.replace('<%= contents %>', '%output%'); } wrapper += '\n//# sourceMappingURL=' + outputFilename + '.map\n'; if (fs.existsSync(intermediateFilename)) { fs.unlinkSync(intermediateFilename); } let sourceMapBase = 'http://*****:*****@ampproject/animations/dist/animations.mjs', 'node_modules/@ampproject/worker-dom/dist/' + 'unminified.index.safe.mjs.patched.js', 'node_modules/document-register-element/build/' + 'document-register-element.patched.js', // 'node_modules/core-js/modules/**.js', // Not sure what these files are, but they seem to duplicate code // one level below and confuse the compiler. '!node_modules/core-js/modules/library/**.js', // Don't include rollup configs '!**/rollup.config.js', // Don't include tests. '!**_test.js', '!**/test-*.js', '!**/*.extern.js', ]; // Add needed path for extensions. // Instead of globbing all extensions, this will only add the actual // extension path for much quicker build times. entryModuleFilenames.forEach(function(filename) { if (!filename.includes('extensions/')) { return; } const path = filename.replace(/\/[^/]+\.js$/, '/**/*.js'); srcs.push(path); }); if (options.extraGlobs) { srcs.push.apply(srcs, options.extraGlobs); } if (options.include3pDirectories) { srcs.push( '3p/**/*.js', 'ads/**/*.js'); } // Many files include the polyfills, but we only want to deliver them // once. Since all files automatically wait for the main binary to load // this works fine. if (options.includeOnlyESMLevelPolyfills) { const polyfills = fs.readdirSync('src/polyfills'); const polyfillsShadowList = polyfills.filter(p => { // custom-elements polyfill must be included. return p !== 'custom-elements.js'; }); srcs.push( '!build/fake-module/src/polyfills.js', '!build/fake-module/src/polyfills/**/*.js', '!build/fake-polyfills/src/polyfills.js', 'src/polyfills/custom-elements.js', 'build/fake-polyfills/**/*.js'); polyfillsShadowList.forEach(polyfillFile => { srcs.push(`!src/polyfills/${polyfillFile}`); fs.writeFileSync('build/fake-polyfills/src/polyfills/' + polyfillFile, 'export function install() {}'); }); } else if (options.includePolyfills) { srcs.push( '!build/fake-module/src/polyfills.js', '!build/fake-module/src/polyfills/**/*.js', '!build/fake-polyfills/**/*.js', ); } else { srcs.push('!src/polyfills.js', '!build/fake-polyfills/**/*.js',); unneededFiles.push('build/fake-module/src/polyfills.js'); } unneededFiles.forEach(function(fake) { if (!fs.existsSync(fake)) { fs.writeFileSync(fake, '// Not needed in closure compiler\n' + 'export function deadCode() {}'); } }); let externs = baseExterns; if (options.externs) { externs = externs.concat(options.externs); } /* eslint "google-camelcase/google-camelcase": 0*/ const compilerOptions = { // Temporary shipping with our own compiler that has a single patch // applied compilerPath: 'build-system/runner/dist/runner.jar', fileName: intermediateFilename, continueWithWarnings: false, tieredCompilation: true, // Magic speed up. compilerFlags: { compilation_level: options.compilationLevel || 'SIMPLE_OPTIMIZATIONS', // Turns on more optimizations. assume_function_wrapper: true, // Transpile from ES6 to ES5. language_in: 'ECMASCRIPT6', language_out: 'ECMASCRIPT5', // We do not use the polyfills provided by closure compiler. // If you need a polyfill. Manually include them in the // respective top level polyfills.js files. rewrite_polyfills: false, externs, js_module_root: [ // Do _not_ include 'node_modules/' in js_module_root with 'NODE' // resolution or bad things will happen (#18600). 'build/patched-module/', 'build/fake-module/', 'build/fake-polyfills/', ], entry_point: entryModuleFilenames, module_resolution: 'NODE', process_common_js_modules: true, // This strips all files from the input set that aren't explicitly // required. only_closure_dependencies: true, output_wrapper: wrapper, create_source_map: intermediateFilename + '.map', source_map_location_mapping: '|' + sourceMapBase, warning_level: 'DEFAULT', jscomp_error: [], // moduleLoad: Demote "module not found" errors to ignore missing files // in type declarations in the swg.js bundle. jscomp_warning: ['moduleLoad'], // Turn off warning for "Unknown @define" since we use define to pass // args such as FORTESTING to our runner. jscomp_off: ['unknownDefines'], define, hide_warnings_for: hideWarningsFor, }, }; // For now do type check separately if (argv.typecheck_only || checkTypes) { // Don't modify compilation_level to a lower level since // it won't do strict type checking if its whitespace only. compilerOptions.compilerFlags.define.push('TYPECHECK_ONLY=true'); compilerOptions.compilerFlags.jscomp_error.push( 'checkTypes', 'accessControls', 'const', 'constantProperty', 'globalThis'); compilerOptions.compilerFlags.conformance_configs = 'build-system/conformance-config.textproto'; } if (compilerOptions.compilerFlags.define.length == 0) { delete compilerOptions.compilerFlags.define; } let stream = gulp.src(srcs) .pipe(closureCompiler(compilerOptions)) .on('error', function(err) { const {message} = err; console./*OK*/error(colors.red( 'Compiler issues for ' + outputFilename + ':\n') + formatClosureCompilerError(message)); process.exit(1); }); // If we're only doing type checking, no need to output the files. if (!argv.typecheck_only && !options.typeCheckOnly) { stream = stream .pipe(rename(outputFilename)) .pipe(replace(/\$internalRuntimeVersion\$/g, internalRuntimeVersion, 'runtime-version')) .pipe(shortenLicense()) .pipe(gulp.dest(outputDir)) .on('end', function() { gulp.src(intermediateFilename + '.map') .pipe(rename(outputFilename + '.map')) .pipe(gulp.dest(outputDir)) .on('end', resolve); }); } else { stream = stream.on('end', resolve); } return stream; });