Example #1
0
 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));
 });
Example #2
0
  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;
  });