From e711c282bfd1fd96d072cd00d0b282e55d993caa Mon Sep 17 00:00:00 2001 From: Brandon Date: Wed, 9 May 2018 23:40:47 -0500 Subject: [PATCH] build: Remove custom build scripts in favor of Bazel builds (#1046) --- .circleci/config.yml | 8 +- .prettierignore | 1 + build/builder.ts | 21 --- build/config.ts | 47 +++---- build/index.ts | 10 -- build/tasks.ts | 320 +------------------------------------------ build/util.ts | 38 ----- package.json | 2 +- 8 files changed, 25 insertions(+), 422 deletions(-) delete mode 100644 build/builder.ts delete mode 100644 build/index.ts diff --git a/.circleci/config.yml b/.circleci/config.yml index e9a5d8e56c..d08af66ef3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -64,13 +64,13 @@ jobs: - run: bazel query --output=label //... | xargs bazel test test: - docker: - - image: circleci/node:latest-browsers + <<: *run_in_ngcontainer steps: - checkout - restore_cache: key: *cache_key - run: yarn + - run: yarn copy:schematics - run: yarn run ci - run: yarn run example:build:prod - run: yarn run example:test --watch=false @@ -80,8 +80,7 @@ jobs: - ~/.cache/yarn - node_modules deploy: - docker: - - image: circleci/node:latest-browsers + <<: *run_in_ngcontainer steps: - add_ssh_keys: fingerprints: @@ -90,6 +89,7 @@ jobs: - restore_cache: key: *cache_key - run: yarn + - run: yarn copy:schematics - run: yarn run build - run: yarn run deploy:builds diff --git a/.prettierignore b/.prettierignore index 3d0170d1b7..afeeff0261 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,5 +1,6 @@ /dist /modules/schematics/src/*/files/* +/tmp package-lock.json package.json yarn.lock diff --git a/build/builder.ts b/build/builder.ts deleted file mode 100644 index 2c10c4953a..0000000000 --- a/build/builder.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as tasks from './tasks'; -import { createBuilder } from './util'; - -export default createBuilder([ - ['Removing "./dist" Folder', tasks.removeDistFolder], - ['Compiling packages with NGC', tasks.compilePackagesWithNgc], - ['Bundling FESMs', tasks.bundleFesms], - ['Down-leveling FESMs to ES5', tasks.downLevelFesmsToES5], - ['Creating UMD Bundles', tasks.createUmdBundles], - ['Renaming package entry files', tasks.renamePackageEntryFiles], - ['Cleaning TypeScript files', tasks.cleanTypeScriptFiles], - ['Cleaning JavaScript files', tasks.cleanJavaScriptFiles], - ['Removing remaining sourcemap files', tasks.removeRemainingSourceMapFiles], - ['Copying type definition files', tasks.copyTypeDefinitionFiles], - ['Copying schematic files', tasks.copySchematicFiles], - ['Minifying UMD bundles', tasks.minifyUmdBundles], - ['Copying documents', tasks.copyDocs], - ['Copying package.json files', tasks.copyPackageJsonFiles], - ['Removing "./dist/packages" Folder', tasks.removePackagesFolder], - ['Removing summary files', tasks.removeSummaryFiles], -]); diff --git a/build/config.ts b/build/config.ts index 1b652b6333..dca749aa95 100644 --- a/build/config.ts +++ b/build/config.ts @@ -1,7 +1,7 @@ +import * as fs from 'fs'; + export interface PackageDescription { name: string; - hasTestingModule: boolean; - bundle: boolean; } export interface Config { @@ -9,30 +9,19 @@ export interface Config { scope: string; } -export const packages: PackageDescription[] = [ - { - name: 'store', - hasTestingModule: false, - bundle: true, - }, - { - name: 'effects', - hasTestingModule: true, - bundle: true, - }, - { - name: 'router-store', - hasTestingModule: false, - bundle: true, - }, - { - name: 'store-devtools', - hasTestingModule: false, - bundle: true, - }, - { - name: 'entity', - hasTestingModule: false, - bundle: true, - }, -]; +const modulesDir = './modules/'; +export const packages: PackageDescription[] = fs + .readdirSync(modulesDir) + .filter(path => { + const stat = fs.statSync(`${modulesDir}${path}`); + const isDir = stat.isDirectory(); + + if (!isDir) { + return false; + } + + const hasBuild = fs.existsSync(`${modulesDir}${path}/BUILD`); + + return hasBuild; + }) + .map(pkg => ({ name: pkg })); diff --git a/build/index.ts b/build/index.ts deleted file mode 100644 index 3c7342dc31..0000000000 --- a/build/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -import build from './builder'; -import { packages } from './config'; - -build({ - scope: '@ngrx', - packages, -}).catch(err => { - console.error(err); - process.exit(1); -}); diff --git a/build/tasks.ts b/build/tasks.ts index b24749e645..57ef68fb11 100644 --- a/build/tasks.ts +++ b/build/tasks.ts @@ -1,298 +1,12 @@ import { Config } from './config'; import * as util from './util'; -/** - * Cleans the top level dist folder. All npm-ready packages are created - * in the dist folder. - */ -export function removeDistFolder(config: Config) { - return util.exec('rimraf', ['./dist']); -} - -/** - * Uses the 'tsconfig-build.json' file in each package directory to produce - * AOT and Closure compatible JavaScript - */ -export async function compilePackagesWithNgc(config: Config) { - const pkgs = util.getTopLevelPackages(config); - const storePkg = 'store'; - const restPkgs = pkgs.filter(name => name !== storePkg); - const testPkgs = util.getTestingPackages(config); - - await _compilePackagesWithNgc(storePkg); - await mapAsync(restPkgs, _compilePackagesWithNgc); - await mapAsync(testPkgs, _compilePackagesWithNgc); -} - -async function _compilePackagesWithNgc(pkg: string) { - await util.exec('ngc', [`-p ./modules/${pkg}/tsconfig-build.json`]); - - /** - * Test modules are treated differently because nested inside top-level. - * This step removes the top-level package from testing modules from the - * export statement. - * Also changes the module name from 'index' to 'testing' - * i.e. export * from './effects/testing/index' becomes './testing/testing'; - * - * See https://github.com/ngrx/platform/issues/94 - */ - let [exportPath, moduleName] = /\/testing$/.test(pkg) - ? [pkg.replace(/(.*\/)testing/i, 'testing'), 'testing'] - : [pkg, 'index']; - - const entryTypeDefinition = `export * from './${exportPath}/${moduleName}';`; - const entryMetadata = `{"__symbolic":"module","version":3,"metadata":{},"exports":[{"from":"./${pkg}/index"}]}`; - - await Promise.all([ - util.writeFile(`./dist/packages/${pkg}.d.ts`, entryTypeDefinition), - util.writeFile(`./dist/packages/${pkg}.metadata.json`, entryMetadata), - ]); -} - -/** - * Uses Rollup to bundle the JavaScript into a single flat file called - * a FESM (Flat Ecma Script Module) - */ -export async function bundleFesms(config: Config) { - const pkgs = util.getAllPackages(config); - - await mapAsync(pkgs, async pkg => { - const topLevelName = util.getTopLevelName(pkg); - - if (!util.shouldBundle(config, topLevelName)) { - return; - } - - await util.exec('rollup', [ - `-i ./dist/packages/${pkg}/index.js`, - `-o ./dist/${topLevelName}/${config.scope}/${pkg}.js`, - `-f es`, - `--sourcemap`, - ]); - - await util.mapSources(`./dist/${topLevelName}/${config.scope}/${pkg}.js`); - }); -} - -/** - * Copies each FESM into a TS file then uses TypeScript to downlevel - * the FESM into ES5 with ESM modules - */ -export async function downLevelFesmsToES5(config: Config) { - const packages = util.getAllPackages(config); - const tscArgs = ['--target es5', '--module es2015', '--noLib', '--sourceMap']; - - await mapAsync(packages, async pkg => { - const topLevelName = util.getTopLevelName(pkg); - - if (!util.shouldBundle(config, topLevelName)) { - return; - } - - const file = `./dist/${topLevelName}/${config.scope}/${pkg}.js`; - const target = `./dist/${topLevelName}/${config.scope}/${pkg}.es5.ts`; - - await util.copy(file, target); - await util.ignoreErrors(util.exec('tsc', [target, ...tscArgs])); - await util.mapSources(target.replace('.ts', '.js')); - await util.remove(target); - }); - - await util.removeRecursively(`./dist/**/*/${config.scope}/*.ts`); -} - -/** - * Re-runs Rollup on the downleveled ES5 to produce a UMD bundle - */ -export async function createUmdBundles(config: Config) { - await mapAsync(util.getAllPackages(config), async pkg => { - const topLevelName = util.getTopLevelName(pkg); - - if (!util.shouldBundle(config, topLevelName)) { - return; - } - - const destinationName = util.getDestinationName(pkg); - - const rollupArgs = [ - `-c ./modules/${pkg}/rollup.config.js`, - `--sourcemap`, - `--amd.id ${config.scope}/${pkg}`, - ]; - - await util.exec('rollup', rollupArgs); - await util.mapSources( - `./dist/${topLevelName}/bundles/${destinationName}.umd.js` - ); - }); -} - -/** - * Removes any leftover TypeScript files from previous compilation steps, - * leaving any type definition files in place - */ -export async function cleanTypeScriptFiles(config: Config) { - const tsFilesGlob = './dist/packages/**/*.ts'; - const dtsFilesFlob = './dist/packages/**/*.d.ts'; - const filesToRemove = await util.getListOfFiles(tsFilesGlob, dtsFilesFlob); - - await mapAsync(filesToRemove, util.remove); -} - -/** - * Removes any leftover Javascript files from previous compilation steps, - * leaving the bundles and FESM in place - */ -export async function cleanJavaScriptFiles(config: Config) { - const packages = util - .getTopLevelPackages(config) - .filter(pkg => !util.shouldBundle(config, pkg)); - const jsFilesGlob = './dist/packages/**/*.js'; - const jsExcludeFilesFlob = [ - './dist/packages/(bundles|@ngrx)/**/*.js', - './dist/**/((?-)testing)/**/*.js', - ]; - const filesToRemove = await util.getListOfFiles( - jsFilesGlob, - jsExcludeFilesFlob - ); - - const filteredFilesToRemove = filesToRemove.filter((file: string) => - packages.some(pkg => file.indexOf(pkg) === -1) - ); - - await mapAsync(filteredFilesToRemove, util.remove); -} - -/** - * Renames the index files in each package to the name - * of the package. - */ -export async function renamePackageEntryFiles(config: Config) { - await mapAsync(util.getAllPackages(config), async pkg => { - const topLevelName = util.getTopLevelName(pkg); - - if (!util.shouldBundle(config, topLevelName)) { - return; - } - - const bottomLevelName = util.getBottomLevelName(pkg); - - const files = await util.getListOfFiles(`./dist/packages/${pkg}/index.**`); - - await mapAsync(files, async file => { - const target = file.replace('index', bottomLevelName); - - await util.copy(file, target); - await util.remove(file); - }); - }); -} - -/** - * Removes any remaining source map files from running NGC - */ -export async function removeRemainingSourceMapFiles(config: Config) { - const packages = util.getTopLevelPackages(config); - - await util.removeRecursively( - `./dist/packages/?(${packages.join('|')})/**/*.map` - ); -} - -/** - * Copies the type definition files and NGC metadata files to - * the root of the distribution - */ -export async function copyTypeDefinitionFiles(config: Config) { - const packages = util.getTopLevelPackages(config); - const files = await util.getListOfFiles( - `./dist/packages/?(${packages.join('|')})/**/*.*` - ); - - await mapAsync(files, async file => { - const target = file.replace('packages/', ''); - await util.copy(file, target); - }); - - await util.removeRecursively(`./dist/packages/?(${packages.join('|')})`); -} - -/** - * Creates minified copies of each UMD bundle - */ -export async function minifyUmdBundles(config: Config) { - const uglifyArgs = ['-c', '-m', '--comments']; - - await mapAsync(util.getAllPackages(config), async pkg => { - const topLevelName = util.getTopLevelName(pkg); - - if (!util.shouldBundle(config, topLevelName)) { - return; - } - - const destinationName = util.getDestinationName(pkg); - const file = `./dist/${topLevelName}/bundles/${destinationName}.umd.js`; - const out = `./dist/${topLevelName}/bundles/${destinationName}.umd.min.js`; - - return util.exec('uglifyjs', [ - file, - ...uglifyArgs, - `-o ${out}`, - `--source-map "filename='${out}.map' includeSources='${file}', content='${file}.map'"`, - ]); - }); -} - -/** - * Copies the README.md, LICENSE, and package.json files into - * each package - */ -export async function copyDocs(config: Config) { - const packages = util.getTopLevelPackages(config); - - await mapAsync(packages, async pkg => { - const source = `./modules/${pkg}`; - const target = `./dist/${pkg}`; - - await Promise.all([ - util.copy(`${source}/README.md`, `${target}/README.md`), - util.copy('./LICENSE', `${target}/LICENSE`), - ]); - }); -} - -export async function copyPackageJsonFiles(config: Config) { - const packages = util.getAllPackages(config); - - await mapAsync(packages, async pkg => { - const source = `./modules/${pkg}`; - const target = `./dist/${pkg}`; - - await util.copy(`${source}/package.json`, `${target}/package.json`); - }); -} - -/** - * Removes the packages folder - */ -export async function removePackagesFolder(config: Config) { - await util.removeRecursively('./dist/packages'); -} - -/** - * Removes the ngsummary files - */ -export function removeSummaryFiles() { - return util.exec('rimraf', ['**/dist/**/*.ngsummary.json']); -} - /** * Deploy build artifacts to repos */ export async function publishToRepo(config: Config) { for (let pkg of util.getTopLevelPackages(config)) { - const SOURCE_DIR = `./dist/${pkg}`; + const SOURCE_DIR = `./dist/bin/modules/${pkg}/npm_package`; const REPO_URL = `git@github.com:ngrx/${pkg}-builds.git`; const REPO_DIR = `./tmp/${pkg}`; const SHA = await util.git([`rev-parse HEAD`]); @@ -326,35 +40,3 @@ export async function publishToRepo(config: Config) { await process.chdir('../../'); } } - -export function mapAsync( - list: T[], - mapFn: (v: T, i: number) => Promise -) { - return Promise.all(list.map(mapFn)); -} - -/** - * Copy schematics files - */ -export async function copySchematicFiles(config: Config) { - const packages = util - .getTopLevelPackages(config) - .filter(pkg => !util.shouldBundle(config, pkg)); - - const collectionFiles = await util.getListOfFiles( - `./modules/?(${packages.join('|')})/collection.json` - ); - const schemaFiles = await util.getListOfFiles( - `./modules/?(${packages.join('|')})/src/*/schema.*` - ); - const templateFiles = await util.getListOfFiles( - `./modules/?(${packages.join('|')})/src/*/files/*` - ); - const files = [...collectionFiles, ...schemaFiles, ...templateFiles]; - - await mapAsync(files, async file => { - const target = file.replace('modules/', 'dist/'); - await util.copy(file, target); - }); -} diff --git a/build/util.ts b/build/util.ts index 4ec8f49ac0..6588b3f2cc 100644 --- a/build/util.ts +++ b/build/util.ts @@ -146,44 +146,6 @@ export function getTopLevelPackages(config: Config) { return config.packages.map(packageDescription => packageDescription.name); } -export function getTestingPackages(config: Config) { - return flatMap(config.packages, ({ name, hasTestingModule }) => { - if (hasTestingModule) { - return [`${name}/testing`]; - } - - return []; - }); -} - -export function getAllPackages(config: Config) { - return flatMap(config.packages, ({ name, hasTestingModule }) => { - if (hasTestingModule) { - return [name, `${name}/testing`]; - } - - return [name]; - }); -} - -export function getDestinationName(packageName: string) { - return packageName.replace('/testing', '-testing'); -} - -export function getTopLevelName(packageName: string) { - return packageName.replace('/testing', ''); -} - -export function getBottomLevelName(packageName: string) { - return packageName.includes('/testing') ? 'testing' : packageName; -} - export function baseDir(...dirs: string[]): string { return `"${path.resolve(__dirname, '../', ...dirs)}"`; } - -export function shouldBundle(config: Config, packageName: string) { - const pkg = config.packages.find(pkg => pkg.name === packageName); - - return pkg ? pkg.bundle : false; -} diff --git a/package.json b/package.json index 86d904bf99..0db640dcab 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "scripts": { "precommit": "lint-staged", "bootstrap": "lerna bootstrap", - "build": "ts-node ./build/index.ts", + "build": "bazel build ...", "deploy:builds": "ts-node ./build/deploy-build.ts", "test:unit": "node ./tests.js", "test": "yarn copy:schematics && nyc yarn run test:unit",