Skip to content

Commit

Permalink
Merge pull request #17 from kreuzerk/feature/multiFileGeneration
Browse files Browse the repository at this point in the history
Feature/multi file generation
  • Loading branch information
nivekcode authored Mar 4, 2020
2 parents 391d955 + 1e3e238 commit abc22c7
Show file tree
Hide file tree
Showing 13 changed files with 238 additions and 69 deletions.
27 changes: 18 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@
"format:write": "prettier --write 'src/**/*.ts'",
"prebuild": "npm run copy:readme",
"start": "ts-node ./src/bin/svg-to-ts.ts -s './inputfiles/*.svg'",
"start:help": "ts-node ./src/bin/svg-to-ts.ts -h",
"start:regex": "ts-node ./src/bin/svg-to-ts.ts -s './inputfilesRegex/**/*.svg'",
"start:kebap": "ts-node ./src/bin/svg-to-ts.ts -s './inputfiles/*.svg -d KEBAB'",
"start:kebap": "ts-node ./src/bin/svg-to-ts.ts -s './inputfiles/*.svg' -d KEBAB",
"start:multiple-source": "ts-node ./src/bin/svg-to-ts.ts -s './inputfiles/*.svg' -s './inputfilesBis/*.svg'",
"start:custom": "ts-node ./src/bin/svg-to-ts.ts -s './inputfiles/*.svg' -o ./dist -t sampleIcon -i SampleIcon -p sampleIcon -f icons",
"start:help": "ts-node ./src/bin/svg-to-ts.ts -h",
"start:ofl:regex": "ts-node ./src/bin/svg-to-ts.ts --optimizeForLazyLoading true -s './inputfilesRegex/**/*.svg'",
"start:ofl:kebap": "ts-node ./src/bin/svg-to-ts.ts --optimizeForLazyLoading true -s './inputfiles/*.svg' -d KEBAB",
"start:ofl:multiple-source": "ts-node ./src/bin/svg-to-ts.ts --optimizeForLazyLoading true -s './inputfiles/*.svg' -s './inputfilesBis/*.svg'",
"start:ofl:custom": "ts-node ./src/bin/svg-to-ts.ts --optimizeForLazyLoading true -s './inputfiles/*.svg' -o ./dist -t sampleIcon -i SampleIcon -p sampleIcon -f icons",
"semantic-release": "semantic-release"
},
"repository": {
Expand Down
21 changes: 16 additions & 5 deletions src/bin/svg-to-ts.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
#!/usr/bin/env node
import * as packgeJSON from '../../package.json';
import commander from 'commander';
import { convert } from '../lib/convert';
import { Delimiter } from '../lib/generators/generators';

import { Delimiter } from '../lib/generators/code-snippet-generators';
import { convertToSingleFile } from '../lib/converters/single-file.converter';
import { convertToMultipleFiles } from '../lib/converters/multiple-files.converter';

import * as packgeJSON from '../../package.json';

export interface ConvertionOptions {
delimiter: Delimiter;
Expand All @@ -21,7 +24,8 @@ const DEFAULTS = {
outputDirectory: './dist',
prefix: 'myIcon',
sourceFilesRegex: ['*.svg'],
typeName: 'myIcons'
typeName: 'myIcons',
optimizeForLazyLoading: false
};

function collect(value, previous) {
Expand All @@ -41,6 +45,7 @@ commander
.option('-i --interfaceName <string>', 'name for the generated interface', DEFAULTS.interfaceName)
.option('-s --srcFiles <value>', 'name of the source directory', collect, [])
.option('-o --outputDirectory <string>', 'name of the output directory', DEFAULTS.outputDirectory)
.option('--optimizeForLazyLoading <boolean>', 'optimize the output for lazyloading', DEFAULTS.optimizeForLazyLoading)
.parse(process.argv);

const { delimiter, fileName, interfaceName, outputDirectory, prefix, typeName } = commander;
Expand All @@ -51,6 +56,7 @@ let srcFiles = commander.srcFiles;
if (srcFiles.length === 0) {
srcFiles = DEFAULTS.sourceFilesRegex;
}
const optimizeForLazyLoading = commander.optimizeForLazyLoading;

const convertionOptions = {
delimiter,
Expand All @@ -61,4 +67,9 @@ const convertionOptions = {
srcFiles,
outputDirectory
};
convert(convertionOptions);

if (optimizeForLazyLoading) {
convertToMultipleFiles(convertionOptions);
} else {
convertToSingleFile(convertionOptions);
}
37 changes: 37 additions & 0 deletions src/lib/compiler/typescript-compiler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import * as ts from 'typescript';
import { error, info } from '../helpers/log-helper';

const compile = (filePaths: string[], compilerOptions: ts.CompilerOptions): void => {
let program = ts.createProgram(filePaths, compilerOptions);
let emitResult = program.emit();
if (emitResult.emitSkipped) {
error('Error during compilation of Typesript files');
reportDiagnostics(ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics));
} else {
info('Typescript files successfully compiled');
}
};

const reportDiagnostics = (diagnostics: ts.Diagnostic[]): void => {
diagnostics.forEach(diagnostic => {
let message = 'Error';
if (diagnostic.file) {
let { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
message += ` ${diagnostic.file.fileName} (${line + 1},${character + 1})`;
}
message += ': ' + ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
info(message);
});
};

export const compileSources = (filePaths: string[]): void => {
const tsOptions = {
noEmitOnError: true,
noImplicitAny: true,
declaration: true,
moduleResolution: ts.ModuleResolutionKind.NodeJs,
target: ts.ScriptTarget.ESNext,
module: ts.ModuleKind.ESNext
};
compile(filePaths, tsOptions);
};
63 changes: 63 additions & 0 deletions src/lib/converters/multiple-files.converter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import * as path from 'path';

import { ConvertionOptions } from '../../bin/svg-to-ts';

import {
generateExportStatement,
generateTypeName,
generateUntypedSvgConstant,
generateVariableName
} from '../generators/code-snippet-generators';
import { getFilePathsFromRegex } from '../helpers/regex-helpers';
import { deleteFiles, deleteFolder, extractSvgContent, writeFile } from '../helpers/file-helpers';
import { compileSources } from '../compiler/typescript-compiler';
import { info, success } from '../helpers/log-helper';
import { svgOptimizer } from '../helpers/svg-optimization';

export const convertToMultipleFiles = async (convertionOptions: ConvertionOptions): Promise<void> => {
const { prefix, delimiter, outputDirectory, srcFiles } = convertionOptions;
let indexFileContent = '';

try {
const filePaths = await getFilePathsFromRegex(srcFiles);
await deleteFolder(`${outputDirectory}/icons`);
info(`deleting output directory: ${outputDirectory}`);

for (let i = 0; i < filePaths.length; i++) {
const fileNameWithEnding = path.basename(filePaths[i]);
const [filenameWithoutEnding, extension] = fileNameWithEnding.split('.');

if (extension === 'svg') {
const rawSvg = await extractSvgContent(filePaths[i]);
info(`optimize svg: ${fileNameWithEnding}`);
const optimizedSvg = await svgOptimizer.optimize(rawSvg);
const variableName = generateVariableName(prefix, filenameWithoutEnding);
const typeName = generateTypeName(filenameWithoutEnding, delimiter);
const svgConstant = generateUntypedSvgConstant(variableName, typeName, optimizedSvg.data);
const generatedFileName = `${prefix}-${filenameWithoutEnding}.icon`;
indexFileContent += generateExportStatement(generatedFileName);
await writeFile(`${outputDirectory}/icons`, generatedFileName, svgConstant);
info(`write file svg: ${outputDirectory}/icons/${generatedFileName}.ts`);
}
}
await writeFile(outputDirectory, 'index', indexFileContent);
info(`write index.ts`);
const generatedTypeScriptFilePaths = await getFilePathsFromRegex([
`${outputDirectory}/icons/*.ts`,
`${outputDirectory}/index.ts`
]);
compileSources(generatedTypeScriptFilePaths);
info(`compile Typescript - generate JS and d.ts`);
deleteFiles(generatedTypeScriptFilePaths);
info(`delete Typescript files`);

success('========================================================');
success(`your files were successfully created under: ${outputDirectory}`);
success(
`don't forget to copy this folder to your dist in a post build script - enjoy your tree-shakable icon library 😎`
);
success('========================================================');
} catch (error) {
error('Something went wrong', error);
}
};
29 changes: 13 additions & 16 deletions src/lib/convert.ts → src/lib/converters/single-file.converter.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
import chalk from 'chalk';
import * as path from 'path';
import { svgo } from './svgo';

import { ConvertionOptions } from '../../bin/svg-to-ts';

import {
generateInterfaceDefinition,
generateSvgConstant,
generateTypeDefinition,
generateTypeName,
generateVariableName
} from './generators/generators';
import { getFilePathsFromRegex } from './regex-helpers';
import { extractSvgContent, writeIconsFile } from './file-helpers';
import { ConvertionOptions } from '../bin/svg-to-ts';
} from '../generators/code-snippet-generators';
import { getFilePathsFromRegex } from '../helpers/regex-helpers';
import { extractSvgContent, writeFile } from '../helpers/file-helpers';
import { success, underlineSuccess } from '../helpers/log-helper';
import { svgOptimizer } from '../helpers/svg-optimization';

const typesDelimitor = ' | ';

export const convert = async (convertionOptions: ConvertionOptions): Promise<void> => {
const { typeName, prefix, delimiter, interfaceName, outputDirectory, srcFiles } = convertionOptions;
export const convertToSingleFile = async (convertionOptions: ConvertionOptions): Promise<void> => {
const { typeName, prefix, delimiter, interfaceName, outputDirectory, srcFiles, fileName } = convertionOptions;
let svgConstants = '';
let types = generateTypeDefinition(typeName);

Expand All @@ -28,7 +29,7 @@ export const convert = async (convertionOptions: ConvertionOptions): Promise<voi

if (extension === 'svg') {
const rawSvg = await extractSvgContent(filePaths[i]);
const optimizedSvg = await svgo.optimize(rawSvg);
const optimizedSvg = await svgOptimizer.optimize(rawSvg);
const variableName = generateVariableName(prefix, filenameWithoutEnding);
const typeName = generateTypeName(filenameWithoutEnding, delimiter);
const svgConstant = generateSvgConstant(variableName, interfaceName, typeName, optimizedSvg.data);
Expand All @@ -40,14 +41,10 @@ export const convert = async (convertionOptions: ConvertionOptions): Promise<voi

if (svgConstants !== '') {
const fileContent = (svgConstants += types += generateInterfaceDefinition(interfaceName, typeName));
await writeIconsFile(convertionOptions, fileContent);
console.log(
chalk.blue.bold('svg-to-ts:'),
chalk.green('Icons file successfully generated under'),
chalk.green.underline(outputDirectory)
);
await writeFile(outputDirectory, fileName, fileContent);
success(`Icons file successfully generated under ${underlineSuccess(outputDirectory)}`);
}
} catch (error) {
console.log(chalk.blue.bold('svg-to-ts:'), chalk.red('Something went wrong', error));
error('Something went wrong', error);
}
};
33 changes: 0 additions & 33 deletions src/lib/file-helpers.ts

This file was deleted.

File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,31 @@ export const generateSvgConstant = (
};`;
};

export const generateUntypedSvgConstant = (
variableName: string,
filenameWithoutEnding: string,
data: string
): string => {
return `export const ${variableName} = {
name: '${filenameWithoutEnding}',
data: '${data}'
};`;
};

export const generateSvgStandaloneFile = (
variableName: string,
interfaceName: string,
filenameWithoutEnding: string,
data: string
): string => {
return `export const ${variableName}: ${interfaceName} = {
name: '${filenameWithoutEnding}',
data: '${data}'
};`;
};

export const generateExportStatement = (fileName: string) => `export * from './icons/${fileName}';`;

export const generateTypeName = (filenameWithoutEnding, delimiter: Delimiter): string => {
if (delimiter === Delimiter.CAMEL) {
return `${camelCase(filenameWithoutEnding)}`;
Expand Down
Loading

0 comments on commit abc22c7

Please sign in to comment.