Skip to content

Commit

Permalink
feat(build): updated tslint for package tools
Browse files Browse the repository at this point in the history
  • Loading branch information
pimenovoleg committed May 31, 2018
1 parent 50c0125 commit 16b40b1
Show file tree
Hide file tree
Showing 16 changed files with 203 additions and 190 deletions.
8 changes: 5 additions & 3 deletions tools/packages/build-package.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import * as chalk from 'chalk';
import { join } from 'path';
import chalk from 'chalk';

import { PackageBundler } from './build-bundles';
import { buildConfig } from './build-config';
import { compileEntryPoint, renamePrivateReExportsToBeUnique } from './compile-entry-point';
import { getSecondaryEntryPointsForPackage } from './secondary-entry-points';
import { ngcCompile } from './ngc-compile';
import { getSecondaryEntryPointsForPackage } from './secondary-entry-points';


const { packagesDir, outputDir } = buildConfig;
Expand Down Expand Up @@ -121,8 +121,10 @@ export class BuildPackage {
const entryPointTsconfigPath = join(entryPointPath, tsconfigName);

return ngcCompile(['-p', entryPointTsconfigPath]).catch(() => {
const error = chalk.red(`Failed to compile ${secondaryEntryPoint} using ${entryPointTsconfigPath}`);
const error = chalk.default.red(`Failed to compile ${secondaryEntryPoint} using ${entryPointTsconfigPath}`);
/* tslint:disable-next-line:no-console */
console.error(error);

return Promise.reject(error);
});
}
Expand Down
29 changes: 15 additions & 14 deletions tools/packages/build-release.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { BuildPackage } from './build-package';
import { appendFileSync } from 'fs';
import { mkdirpSync } from 'fs-extra';
import { join } from 'path';
import {buildConfig} from './build-config';
import {inlinePackageMetadataFiles} from './metadata-inlining';
import {copyFiles} from './copy-files';
import {replaceVersionPlaceholders} from './version-placeholders';
import {createTypingsReexportFile} from './typings-reexport';
import {createMetadataReexportFile} from './metadata-reexport';
import {mkdirpSync} from 'fs-extra';
import {createEntryPointPackageJson} from './entry-point-package-json';
import {appendFileSync} from "fs";

import { buildConfig } from './build-config';
import { BuildPackage } from './build-package';
import { copyFiles } from './copy-files';
import { createEntryPointPackageJson } from './entry-point-package-json';
import { inlinePackageMetadataFiles } from './metadata-inlining';
import { createMetadataReexportFile } from './metadata-reexport';
import { createTypingsReexportFile } from './typings-reexport';
import { replaceVersionPlaceholders } from './version-placeholders';


const {packagesDir, outputDir, projectDir} = buildConfig;
Expand Down Expand Up @@ -57,14 +58,14 @@ export function composeRelease(buildPackage: BuildPackage) {

if (buildPackage.exportsSecondaryEntryPointsAtRoot) {
const es2015Exports = buildPackage.secondaryEntryPoints
.map(p => `export * from './${p}';`).join('\n');
.map((p) => `export * from './${p}';`).join('\n');
appendFileSync(join(releasePath, `${name}.d.ts`), es2015Exports, 'utf-8');

// When re-exporting secondary entry-points, we need to manually create a metadata file that
// re-exports everything.
createMetadataReexportFile(
releasePath,
buildPackage.secondaryEntryPoints.concat(['typings/index']).map(p => `./${p}`),
buildPackage.secondaryEntryPoints.concat(['typings/index']).map((p) => `./${p}`),
name,
importAsName);
}
Expand All @@ -74,7 +75,7 @@ function createFilesForSecondaryEntryPoint(buildPackage: BuildPackage, releasePa
const {name} = buildPackage;
const packageOut = buildPackage.outputDir;

buildPackage.secondaryEntryPoints.forEach(entryPointName => {
buildPackage.secondaryEntryPoints.forEach((entryPointName) => {
// Create a directory in the root of the package for this entry point that contains
// * A package.json that lists the different bundle locations
// * An index.d.ts file that re-exports the index.d.ts from the typings/ directory
Expand Down Expand Up @@ -105,7 +106,7 @@ function createFilesForSecondaryEntryPoint(buildPackage: BuildPackage, releasePa
}

function copySecondaryEntryPointStylesheets(buildPackage: BuildPackage, releasePath: string) {
buildPackage.secondaryEntryPoints.forEach(entryPointName => {
buildPackage.secondaryEntryPoints.forEach((entryPointName) => {
const entryPointDir = join(buildPackage.outputDir, entryPointName);

copyFiles(entryPointDir, `_${entryPointName}.scss`, releasePath);
Expand Down
9 changes: 4 additions & 5 deletions tools/packages/compile-entry-point.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { red } from 'chalk';
import * as chalk from 'chalk';

import { readFileSync, writeFileSync } from 'fs';
import { sync as glob } from 'glob';
import { join } from 'path';


import { BuildPackage } from './build-package';
import { ngcCompile } from './ngc-compile';

Expand All @@ -25,10 +25,9 @@ export async function compileEntryPoint(buildPackage: BuildPackage, tsConfigName
}

return ngcCompile(ngcFlags).catch(() => {
const error = red(`Failed to compile ${secondaryEntryPoint} using ${entryPointTSConfigPath}`);
/* tslint:disable:no-console */
const error = chalk.default.red(`Failed to compile ${secondaryEntryPoint} using ${entryPointTSConfigPath}`);
/* tslint:disable-next-line:no-console */
console.error(error);
/* tslint:enable:no-console */

return Promise.reject(error);
});
Expand Down
4 changes: 2 additions & 2 deletions tools/packages/entry-point-package-json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ export function createEntryPointPackageJson(destDir: string, packageName: string
main: `../bundles/${packageName}-${entryPointName}.umd.js`,
module: `../esm5/${entryPointName}.es5.js`,
es2015: `../esm2015/${entryPointName}.js`,
sideEffects: false,
sideEffects: false
};

/* tslint:disable-next-line:no-magic-numbers */
writeFileSync(join(destDir, 'package.json'), JSON.stringify(content, null, 2), 'utf-8');
}
12 changes: 6 additions & 6 deletions tools/packages/gulp/build-scss-task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ const gulpCleanCss = require('gulp-clean-css');
/* tslint:enable:no-var-requires */

export function buildScssTask(outputDir: string, sourceDir: string, minifyOutput = false) {
return () => {
return src(join(sourceDir, '**/*.scss'))
.pipe(gulpSass().on('error', gulpSass.logError))
.pipe(gulpIf(minifyOutput, gulpCleanCss()))
.pipe(dest(outputDir));
};
return () => {
return src(join(sourceDir, '**/*.scss'))
.pipe(gulpSass().on('error', gulpSass.logError))
.pipe(gulpIf(minifyOutput, gulpCleanCss()))
.pipe(dest(outputDir));
};
}
6 changes: 3 additions & 3 deletions tools/packages/gulp/build-tasks-gulp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import { join } from 'path';
import { BuildPackage } from '../build-package';
import { inlineResourcesForDirectory } from '../inline-resources';

import { composeRelease } from '../build-release';

import { buildScssTask } from './build-scss-task';
import { sequenceTask } from './sequence-task';
import {composeRelease} from '../build-release';


/* tslint:disable:no-var-requires */
/* tslint:disable-next-line:no-var-requires */
const htmlmin = require('gulp-htmlmin');
/* tslint:enable:no-var-requires */

const htmlMinifierOptions = {
collapseWhitespace: true,
Expand Down
15 changes: 7 additions & 8 deletions tools/packages/gulp/sequence-task.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
/* tslint:disable:no-var-requires */
/* tslint:disable-next-line:no-var-requires */
const gulpRunSequence = require('run-sequence');
/* tslint:enable:no-var-requires */


export function sequenceTask(...args: any[]) {
return (done: any) => {
gulpRunSequence(
...args,
done
);
};
return (done: any) => {
gulpRunSequence(
...args,
done
);
};
}
62 changes: 33 additions & 29 deletions tools/packages/inline-resources.ts
Original file line number Diff line number Diff line change
@@ -1,58 +1,62 @@
// tslint:disable:no-eval

import {dirname, join} from 'path';
import {readFileSync, writeFileSync} from 'fs';
import {sync as glob} from 'glob';
import { readFileSync, writeFileSync } from 'fs';
import { sync as glob } from 'glob';
import { dirname, join } from 'path';


/** Finds all JavaScript files in a directory and inlines all resources of Angular components. */
export function inlineResourcesForDirectory(folderPath: string) {
glob(join(folderPath, '**/*.js')).forEach(filePath => inlineResources(filePath));
/* tslint:disable-next-line:no-unnecessary-callback-wrapper */
glob(join(folderPath, '**/*.js')).forEach((filePath) => inlineResources(filePath));
}


/** Inlines the external resources of Angular components of a file. */
export function inlineResources(filePath: string) {
let fileContent = readFileSync(filePath, 'utf-8');
let fileContent = readFileSync(filePath, 'utf-8');

fileContent = inlineTemplate(fileContent, filePath);
fileContent = inlineStyles(fileContent, filePath);
fileContent = removeModuleId(fileContent);
fileContent = inlineTemplate(fileContent, filePath);
fileContent = inlineStyles(fileContent, filePath);
fileContent = removeModuleId(fileContent);

writeFileSync(filePath, fileContent, 'utf-8');
writeFileSync(filePath, fileContent, 'utf-8');
}

/** Inlines the templates of Angular components for a specified source file. */
function inlineTemplate(fileContent: string, filePath: string) {
return fileContent.replace(/templateUrl:\s*'([^']+?\.html)'/g, (_match, templateUrl) => {
const templatePath = join(dirname(filePath), templateUrl);
const templateContent = loadResourceFile(templatePath);
return `template: "${templateContent}"`;
});
return fileContent.replace(/templateUrl:\s*'([^']+?\.html)'/g, (_match, templateUrl) => {
const templatePath = join(dirname(filePath), templateUrl);
const templateContent = loadResourceFile(templatePath);

return `template: "${templateContent}"`;
});
}

/** Inlines the external styles of Angular components for a specified source file. */
function inlineStyles(fileContent: string, filePath: string) {
return fileContent.replace(/styleUrls:\s*(\[[\s\S]*?])/gm, (_match, styleUrlsValue) => {
// The RegExp matches the array of external style files. This is a string right now and
// can to be parsed using the `eval` method. The value looks like "['AAA.css', 'BBB.css']"
const styleUrls = eval(styleUrlsValue) as string[];

const styleContents = styleUrls
.map(url => join(dirname(filePath), url))
.map(path => loadResourceFile(path));

return `styles: ["${styleContents.join(' ')}"]`;
});
return fileContent.replace(/styleUrls:\s*(\[[\s\S]*?])/gm, (_match, styleUrlsValue) => {
// The RegExp matches the array of external style files. This is a string right now and
// can to be parsed using the `eval` method. The value looks like "['AAA.css', 'BBB.css']"
const styleUrls = eval(styleUrlsValue) as string[];

const styleContents = styleUrls
.map((url) => join(dirname(filePath), url))
/* tslint:disable-next-line:no-unnecessary-callback-wrapper */
.map((path) => loadResourceFile(path));

return `styles: ["${styleContents.join(' ')}"]`;
});
}

/** Remove every mention of `moduleId: module.id` */
function removeModuleId(fileContent: string) {
return fileContent.replace(/\s*moduleId:\s*module\.id\s*,?\s*/gm, '');
return fileContent.replace(/\s*moduleId:\s*module\.id\s*,?\s*/gm, '');
}

/** Loads the specified resource file and drops line-breaks of the content. */
function loadResourceFile(filePath: string): string {
return readFileSync(filePath, 'utf-8')
.replace(/([\n\r]\s*)+/gm, ' ')
.replace(/"/g, '\\"');
return readFileSync(filePath, 'utf-8')
.replace(/([\n\r]\s*)+/gm, ' ')
.replace(/"/g, '\\"');
}
84 changes: 43 additions & 41 deletions tools/packages/metadata-inlining.ts
Original file line number Diff line number Diff line change
@@ -1,58 +1,60 @@
import { readFileSync, writeFileSync } from 'fs';
import { basename } from 'path';
import { sync as glob } from 'glob';
import { join } from 'path';
import { join, basename} from 'path';


/**
* Recurse through a parsed metadata.json file and inline all html and css.
* Note: this assumes that all html and css files have a unique name.
*/
export function inlineMetadataResources(metadata: any, componentResources: Map<string, string>) {
// Convert `templateUrl` to `template`
if (metadata.templateUrl) {
const fullResourcePath = componentResources.get(basename(metadata.templateUrl));
metadata.template = readFileSync(fullResourcePath!, 'utf-8');
delete metadata.templateUrl;
}

// Convert `styleUrls` to `styles`
if (metadata.styleUrls && metadata.styleUrls.length) {
metadata.styles = [];
for (const styleUrl of metadata.styleUrls) {
const fullResourcePath = componentResources.get(basename(styleUrl));
metadata.styles.push(readFileSync(fullResourcePath!, 'utf-8'));
// Convert `templateUrl` to `template`
if (metadata.templateUrl) {
const fullResourcePath = componentResources.get(basename(metadata.templateUrl));
/* tslint:disable-next-line:no-non-null-assertion */
metadata.template = readFileSync(fullResourcePath!, 'utf-8');
delete metadata.templateUrl;
}
delete metadata.styleUrls;
}

// We we did nothing at this node, go deeper.
if (!metadata.template && !metadata.styles) {
for (const property in metadata) {
if (typeof metadata[property] == 'object' && metadata[property]) {
inlineMetadataResources(metadata[property], componentResources);
}

// Convert `styleUrls` to `styles`
if (metadata.styleUrls && metadata.styleUrls.length) {
metadata.styles = [];
for (const styleUrl of metadata.styleUrls) {
const fullResourcePath = componentResources.get(basename(styleUrl));
/* tslint:disable-next-line:no-non-null-assertion */
metadata.styles.push(readFileSync(fullResourcePath!, 'utf-8'));
}
delete metadata.styleUrls;
}

// We we did nothing at this node, go deeper.
if (!metadata.template && !metadata.styles) {
/* tslint:disable-next-line:no-for-in */
for (const property in metadata) {
if (typeof metadata[property] === 'object' && metadata[property]) {
inlineMetadataResources(metadata[property], componentResources);
}
}
}
}
}


/** Inlines HTML and CSS resources into `metadata.json` files. */
export function inlinePackageMetadataFiles(packagePath: string) {
// Create a map of fileName -> fullFilePath. This is needed because the templateUrl and
// styleUrls for each component use just the filename because, in the source, the component
// and the resources live in the same directory.
const componentResources = new Map<string, string>();

glob(join(packagePath, '**/*.+(html|css)')).forEach(resourcePath => {
componentResources.set(basename(resourcePath), resourcePath);
});

// Find all metadata files. For each one, parse the JSON content, inline the resources, and
// reserialize and rewrite back to the original location.
glob(join(packagePath, '**/*.metadata.json')).forEach(path => {
const metadata = JSON.parse(readFileSync(path, 'utf-8'));
inlineMetadataResources(metadata, componentResources);
writeFileSync(path , JSON.stringify(metadata), 'utf-8');
});
// Create a map of fileName -> fullFilePath. This is needed because the templateUrl and
// styleUrls for each component use just the filename because, in the source, the component
// and the resources live in the same directory.
const componentResources = new Map<string, string>();

glob(join(packagePath, '**/*.+(html|css)')).forEach((resourcePath) => {
componentResources.set(basename(resourcePath), resourcePath);
});

// Find all metadata files. For each one, parse the JSON content, inline the resources, and
// reserialize and rewrite back to the original location.
glob(join(packagePath, '**/*.metadata.json')).forEach((path) => {
const metadata = JSON.parse(readFileSync(path, 'utf-8'));
inlineMetadataResources(metadata, componentResources);
writeFileSync(path, JSON.stringify(metadata), 'utf-8');
});
}
Loading

0 comments on commit 16b40b1

Please sign in to comment.