Skip to content

Commit

Permalink
Run a single, top-level tsc --build (#2923)
Browse files Browse the repository at this point in the history
* WIP

* Only clean before publish

* Refactor the JSON schema gen

* Linting
  • Loading branch information
jeffposnick committed Aug 25, 2021
1 parent 2b4e88b commit 9e79454
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 116 deletions.
19 changes: 8 additions & 11 deletions gulp-tasks/build-node-packages.js
Expand Up @@ -42,6 +42,12 @@ async function buildNodePackage(packagePath) {
}

async function generateWorkboxBuildJSONSchema(packagePath) {
// We only want to do this for workbox-build, but this function might be
// run for any package, so exit early.
if (!packagePath.endsWith('workbox-build')) {
return;
}

const program = TJS.programFromConfig(
upath.join(packagePath, 'tsconfig.json'),
);
Expand Down Expand Up @@ -101,21 +107,12 @@ async function generateWorkboxBuildJSONSchema(packagePath) {
}
}

async function buildNodeTSPackage(packagePath) {
// Hardcode special logic for workbox-build, as it's the only package
// that requires JSON schema generation.
if (packagePath.endsWith('workbox-build')) {
await generateWorkboxBuildJSONSchema(packagePath);
}

await execa('tsc', ['-b', packagePath], {preferLocal: true});
}

module.exports = {
build_node_packages: parallel(
packageRunner('build_node_packages', 'node', buildNodePackage),
),
build_node_ts_packages: parallel(
packageRunner('build_node_ts_packages', 'node_ts', buildNodeTSPackage),
packageRunner('build_node_ts_packages', 'node_ts',
generateWorkboxBuildJSONSchema),
),
};
5 changes: 3 additions & 2 deletions gulp-tasks/build-packages.js
Expand Up @@ -12,9 +12,10 @@ const fse = require('fs-extra');
const upath = require('upath');

const {build_node_packages, build_node_ts_packages} =
require('./build-node-packages');
require('./build-node-packages');
const {build_sw_packages} = require('./build-sw-packages');
const {build_window_packages} = require('./build-window-packages');
const {transpile_typescript} = require('./transpile-typescript');
const constants = require('./utils/constants');
const packageRunner = require('./utils/package-runner');

Expand Down Expand Up @@ -58,9 +59,9 @@ function cleanSequence() {
module.exports = {
build_packages_clean: cleanSequence(),
build_packages: series(
cleanSequence(),
// This needs to be a series, not in parallel, so that there isn't a
// race condition with the terser nameCache.
transpile_typescript,
series(build_sw_packages, build_window_packages),
parallel(
build_node_packages,
Expand Down
12 changes: 1 addition & 11 deletions gulp-tasks/build-sw-packages.js
Expand Up @@ -12,7 +12,6 @@ const fse = require('fs-extra');
const ol = require('common-tags').oneLine;
const upath = require('upath');

const {transpilePackageOrSkip} = require('./transpile-typescript').functions;
const constants = require('./utils/constants');
const logHelper = require('../infra/utils/log-helper');
const packageRunner = require('./utils/package-runner');
Expand Down Expand Up @@ -151,23 +150,14 @@ async function buildSWBundle(packagePath, buildType) {

// This reads a little cleaner with a function to generate the sub-sequences.
function swBundleSequence() {
const transpilations = packageRunner(
'build_sw_packages_transpile_typescript', 'sw', transpilePackageOrSkip);
const builds = Object.keys(constants.BUILD_TYPES).map((type) => packageRunner(
'build_sw_packages_bundle', 'sw', buildSWBundle,
constants.BUILD_TYPES[type]));

return series(
parallel(transpilations),
// This needs to be a series, not in parallel, so that there isn't a
// race condition with the terser nameCache.
series(builds),
);
return series(builds);
}

module.exports = {
build_sw_packages_transpile_typescript: parallel(packageRunner(
'build_sw_packages_transpile_typescript', 'sw', transpilePackageOrSkip)),
build_sw_packages: series(
parallel(packageRunner('build_sw_packages_version_module', 'sw',
versionModule)),
Expand Down
11 changes: 1 addition & 10 deletions gulp-tasks/build-window-packages.js
Expand Up @@ -12,7 +12,6 @@ const fse = require('fs-extra');
const ol = require('common-tags').oneLine;
const upath = require('upath');

const {transpilePackageOrSkip} = require('./transpile-typescript').functions;
const constants = require('./utils/constants');
const logHelper = require('../infra/utils/log-helper');
const packageRunner = require('./utils/package-runner');
Expand Down Expand Up @@ -93,19 +92,11 @@ async function buildWindowBundle(packagePath, buildType) {

// This reads a little cleaner with a function to generate the sub-sequences.
function windowBundleSequence() {
const transpilations = packageRunner(
'build_window_packages_transpile_typescript', 'window',
transpilePackageOrSkip);
const builds = Object.keys(constants.BUILD_TYPES).map((type) => packageRunner(
'build_window_packages_bundle', 'window', buildWindowBundle,
constants.BUILD_TYPES[type]));

return series(
parallel(transpilations),
// This needs to be a series, not in parallel, so that there isn't a
// race condition with the terser nameCache.
series(builds),
);
return series(builds);
}

module.exports = {
Expand Down
5 changes: 3 additions & 2 deletions gulp-tasks/publish.js
Expand Up @@ -11,6 +11,7 @@ const execa = require('execa');
const fse = require('fs-extra');
const ol = require('common-tags').oneLine;

const {build_packages_clean} = require('./build-packages');
const {publish_cdn} = require('./publish-cdn');
const {publish_github} = require('./publish-github');
const {publish_lerna} = require('./publish-lerna');
Expand All @@ -33,6 +34,6 @@ async function dist_tag_check() {
}

module.exports = {
publish: series(dist_tag_check, publish_sign_in_check, publish_clean, test,
publish_lerna, publish_github, publish_cdn),
publish: series(dist_tag_check, publish_sign_in_check, build_packages_clean,
publish_clean, test, publish_lerna, publish_github, publish_cdn),
};
106 changes: 26 additions & 80 deletions gulp-tasks/transpile-typescript.js
Expand Up @@ -6,21 +6,12 @@
https://opensource.org/licenses/MIT.
*/

const {parallel, watch} = require('gulp');
const execa = require('execa');
const fse = require('fs-extra');
const globby = require('globby');
const ol = require('common-tags').oneLine;
const upath = require('upath');

const {AsyncDebounce} = require('../infra/utils/AsyncDebounce');
const logHelper = require('../infra/utils/log-helper');
const packageRunner = require('./utils/package-runner');

/**
* @type {string}
*/
const packagesDir = upath.join(__dirname, '..', 'packages');

/**
* A mapping between each package name and its corresponding `AsyncDebounce`
Expand All @@ -42,7 +33,7 @@ const debouncedTranspilerMap = {};
async function queueTranspile(packageName, options) {
if (!debouncedTranspilerMap[packageName]) {
debouncedTranspilerMap[packageName] = new AsyncDebounce(async () => {
await transpilePackage(packageName, options);
await transpile_typescript();
});
}
await debouncedTranspilerMap[packageName].call();
Expand All @@ -68,79 +59,36 @@ function needsTranspile(packageName) {
}

/**
* Transpiles a package iff it has TypeScript source files.
*
* @param {string} packagePath
* @param {Object} [options]
*/
async function transpilePackageOrSkip(packagePath, options) {
// `packagePath` will be posix style because it comes from `glob()`.
const packageName = packagePath.split('/').slice(-1)[0];

if (await fse.pathExists(upath.join(packagePath, 'tsconfig.json'))) {
await queueTranspile(packageName, options);
} else {
logHelper.log(ol`Skipping package '${packageName}', which has
not yet been converted to typescript.`);
}
}

/**
* Transpiles a package's source TypeScript files to `.js` and `.mjs` files
* in the root package directory, along with the corresponding `.d.ts` files.
* Transpiles all packages listed in the root tsconfig.json's references section
* into .js and .d.ts files. Creates stub .mjs files that re-export the contents
* of the .js files.
*
* @param {string} packageName
* @param {Object} [options]
* @param {boolean} [options.failOnError=true]
* Unlike other scripts, this does not take the --package= command line param
* into account. Each project in packages/ theoretically could depend on any
* other project, so kicking off a single, top-level compilation makes the
* most sense (and is faster when all the packages need to be compiled).
*/
async function transpilePackage(packageName, {failOnError = true} = {}) {
try {
// Compile TypeScript for the given project.
// Reference the local `node_modules` version of `tsc` since on Windows
// it will call the version in `Microsoft SDKs/TypeScript`.
await execa('tsc', ['-b', `packages/${packageName}`], {preferLocal: true});

const packagePath = upath.join('packages', packageName);

// Don't create `.mjs` files for the node_ts packages.
const pkgJson = require(`../${packagePath}/package.json`);
if (pkgJson.workbox.packageType === 'node_ts') {
return;
}

// Mirror all `.ts` files with `.mjs` files.
const tsFiles = await globby(`**/*.ts`, {
cwd: upath.join(packagePath, 'src'),
});

for (const tsFile of tsFiles) {
const assetBasename = upath.basename(tsFile, '.ts');
const mjsFile = upath.join('packages',
packageName, upath.dirname(tsFile), `${assetBasename}.mjs`);

if (!(await fse.pathExists(mjsFile))) {
const mjsSource = `export * from './${assetBasename}.js';`;

await fse.outputFile(mjsFile, mjsSource);
}
}
} catch (error) {
if (failOnError) {
throw error;
}
async function transpile_typescript() {
await execa('tsc', ['--build', 'tsconfig.json'], {preferLocal: true});

const jsFiles = await globby(`packages/*/**/*.js`, {
ignore: [
'**/build/**',
'**/src/**',
],
});

logHelper.error(error.stdout);
for (const jsFile of jsFiles) {
const {dir, name} = upath.parse(jsFile);
const mjsFile = upath.join(dir, `${name}.mjs`);
const mjsSource = `export * from './${name}.js';`;
await fse.outputFile(mjsFile, mjsSource);
}
}

function transpile_typescript_watch() {
const watcher = watch(`./${global.packageOrStar}/workbox-*/src/**/*.ts`);
watcher.on('all', async (event, file) => {
const changedPkg = upath.relative(packagesDir, file).split(upath.sep)[0];

pendingChangesMap[changedPkg] = true;
await queueTranspile(changedPkg, {failOnError: false});
pendingChangesMap[changedPkg] = false;
async function transpile_typescript_watch() {
await execa('tsc', ['--build', '--watch', 'tsconfig.json'], {
preferLocal: true,
});
}

Expand All @@ -149,9 +97,7 @@ module.exports = {
functions: {
needsTranspile,
queueTranspile,
transpilePackageOrSkip,
},
transpile_typescript_watch,
transpile_typescript: parallel(packageRunner('transpile_typescript', 'all',
transpilePackageOrSkip)),
transpile_typescript,
};

0 comments on commit 9e79454

Please sign in to comment.