Skip to content

Commit

Permalink
Merge branch 'bigopon-master'
Browse files Browse the repository at this point in the history
  • Loading branch information
zewa666 committed Nov 13, 2018
2 parents 69e23a3 + 561c33e commit b585383
Show file tree
Hide file tree
Showing 22 changed files with 792 additions and 97 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ jspm_packages
bower_components
.idea
.DS_STORE
.rollupcache
build/reports
.vscode/
test/coverage-jest
29 changes: 29 additions & 0 deletions build/args.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import yargs from 'yargs';
import { IBuildTargetFormat } from './shared';

export interface IArguments {
target: string;
format: IBuildTargetFormat[];
dev: boolean;
}

export const args: IArguments = yargs
.options(
'target',
{
alias: 't',
// tslint:disable-next-line:max-line-length
description: 'target module dir to copy build results into (eg. "--target ../other-module" to copy build results into "../other-module/node_modules/this-module/dist/…" whenever they change)'
}
)
.options('format', {
alias: 'f',
array: true,
description: 'format to compile to (eg. "es2015", "commonjs", …). Can be set muliple times to compile to multiple formats. Default is all formats.'
})
.options('dev', {
alias: 'd',
boolean: true,
description: 'Enable dev move to watch for change and copy dist over target folder'
})
.argv as any;
177 changes: 177 additions & 0 deletions build/build.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
import rollup from 'rollup';
import { build, IBuildTargetFormat, watchAndReBuild, copy } from './shared';
import { args } from './args';
import packageJson from '../package.json';
import { IRollupWatchOptions } from './interfaces';
import * as path from 'path';
import ChildProcess from 'child_process';
import * as fs from 'fs';

const BASE_DIR = process.cwd();
const DIST_DIR = path.join(BASE_DIR, 'dist');
const NODE_MODULES = 'node_modules';
const LIB_NAME = 'aurelia-i18n';
const DIST_FILE_NAME = `${LIB_NAME}.js`;
const TYPE_DIST_FILE_NAME = `${LIB_NAME}.d.ts`;
const ENTRY_PATH = `src/${LIB_NAME}.ts`;
const EXTERNAL_LIBS = [
'aurelia-framework',
'i18next',
...Object
.keys({ ...packageJson.dependencies, ...packageJson.devDependencies })
.filter(dev => /^(?:aurelia)/.test(dev) && dev !== LIB_NAME)
];
const configs: Record<IBuildTargetFormat, { input: string; outputs: rollup.OutputOptions[]; tsConfig?: { target: string } }> = {
es2017: {
input: ENTRY_PATH,
outputs: [
{ file: `dist/es2017/${DIST_FILE_NAME}`, format: 'esm' }
]
},
es2015: {
input: ENTRY_PATH,
outputs: [
{ file: `dist/es2015/${DIST_FILE_NAME}`, format: 'esm' }
]
},
es5: {
input: ENTRY_PATH,
outputs: [
{ file: `dist/commonjs/${DIST_FILE_NAME}`, format: 'cjs' },
{ file: `dist/amd/${DIST_FILE_NAME}`, format: 'amd', amd: { id: LIB_NAME } },
{ file: `dist/native-modules/${DIST_FILE_NAME}`, format: 'esm' },
{ file: `dist/system/${DIST_FILE_NAME}`, format: 'system' }
]
},
amd: {
input: ENTRY_PATH,
outputs: [
{ file: `dist/amd/${DIST_FILE_NAME}`, format: 'amd', amd: { id: LIB_NAME } }
],
tsConfig: {
target: 'es5'
}
},
system: {
input: ENTRY_PATH,
outputs: [
{ file: `dist/system/${DIST_FILE_NAME}`, format: 'system' }
],
tsConfig: {
target: 'es5'
}
},
commonjs: {
input: ENTRY_PATH,
outputs: [
{ file: `dist/commonjs/${DIST_FILE_NAME}`, format: 'cjs' }
],
tsConfig: {
target: 'es5'
}
},
'native-modules': {
input: ENTRY_PATH,
outputs: [
{ file: `dist/native-modules/${DIST_FILE_NAME}`, format: 'esm' }
],
tsConfig: {
target: 'es5'
}
}
};


if (args.dev) {
// watch mode
let generateDtsTO: any;
const targetFormats: IBuildTargetFormat[] = args.format || ['commonjs'];
const options = targetFormats.reduce((formats, targetFormat) => {
const { outputs, tsConfig } = configs[targetFormat];
formats[targetFormat] = {
input: ENTRY_PATH,
external: EXTERNAL_LIBS,
output: outputs,
tsConfig
};
return formats;
}, {} as Record<IBuildTargetFormat, IRollupWatchOptions>);
console.log('=============\nBuilding Started\n=============');
watchAndReBuild(
options,
() => {
console.log('=============\nFinished building\n=============');
clearTimeout(generateDtsTO);
generateDtsTO = setTimeout(() => {
generateDts().then(() => {
if (args.target) {
copyToTargetProject(targetFormats, args.target);
}
});
}, 1000);
}
);
} else {
// Single build
const targetFormats: IBuildTargetFormat[] = args.format || ['es5', 'es2015', 'es2017'];
Promise
.all(targetFormats.map(target => {
const { outputs, tsConfig, ...options } = configs[target];
return build(target, { ...options, external: EXTERNAL_LIBS }, outputs as rollup.OutputOptionsFile[]);
}))
.then(() => generateDts())
.then(() => {
if (args.target) {
copyToTargetProject(targetFormats, args.target);
}
})
.catch(ex => {
console.log(ex);
});
}

async function generateDts(): Promise<void> {
console.log('\n==============\nGenerating dts bundle...\n==============');
return new Promise<void>((resolve, reject) => {
ChildProcess.exec(`npm run build:dts`, (err, stdout, stderr) => {
if (err || stderr) {
console.log('Generating dts error:');
console.log(stderr);
} else {
console.log('Generated dts bundle successfully');
console.log(stdout);
}
try {
fixI18nDefaultImport(path.resolve(DIST_DIR, TYPE_DIST_FILE_NAME));
} catch (ex) {
console.log('Failure fixing default import.');
reject(ex);
}
resolve();
});
});
}

async function fixI18nDefaultImport(typeDefFileName: string) {
const importDeclaration = `import i18next from "i18next";\n`;
const data = fs.readFileSync(typeDefFileName, 'utf-8');
const fd = fs.openSync(typeDefFileName, 'w+');
fs.writeSync(fd, Buffer.from(importDeclaration, 'utf8'), 0, importDeclaration.length, 0);
fs.writeSync(fd, Buffer.from(data, 'utf8'), 0, data.length, importDeclaration.length);
}

function copyToTargetProject(targetFormats: string[], targetProject: string) {
console.log('=============\nCopying to target\n=============');
targetFormats.forEach((targetFormat) => {
copy(
path.join(DIST_DIR, targetFormat, DIST_FILE_NAME),
path.join(BASE_DIR, targetProject, NODE_MODULES, LIB_NAME, 'dist', targetFormat, DIST_FILE_NAME)
);
});
copy(
path.join(DIST_DIR, TYPE_DIST_FILE_NAME),
path.join(BASE_DIR, targetProject, NODE_MODULES, LIB_NAME, 'dist', TYPE_DIST_FILE_NAME)
);
console.log('=============\nCopied to target\n=============');
}

20 changes: 20 additions & 0 deletions build/changelog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/// <reference path="./types.d.ts" />
import fs from 'fs';
import path from 'path';
import conventionalChangelog from 'conventional-changelog';

const BASE_DIR = process.cwd();
const DOC_DIR = 'doc';
const DOC_NAME = 'CHANGELOG.md';
const DEST_PATH = path.resolve(BASE_DIR, DOC_DIR, DOC_NAME);

let changelogChunk = '';
const changelogStream = conventionalChangelog({ preset: 'angular' })
.on('data', (chunk: any) => changelogChunk += chunk.toString('utf8'))
.on('end', () => {
changelogStream.removeAllListeners();
const data = fs.readFileSync(DEST_PATH, 'utf-8');
const fd = fs.openSync(DEST_PATH, 'w+');
fs.writeSync(fd, Buffer.from(changelogChunk, 'utf8'), 0, changelogChunk.length, 0);
fs.writeSync(fd, Buffer.from(data, 'utf8'), 0, data.length, changelogChunk.length);
});
5 changes: 5 additions & 0 deletions build/interfaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import * as rollup from 'rollup';

export interface IRollupWatchOptions extends rollup.RollupWatchOptions {
tsConfig?: { target: string };
}
99 changes: 99 additions & 0 deletions build/shared.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import * as rollup from 'rollup';
import typescript from 'rollup-plugin-typescript2';
import rimraf from 'rimraf';
import { IRollupWatchOptions } from './interfaces';
import * as fs from 'fs';

const CACHE_DIR = '.rollupcache';
export type IBuildTargetFormat = 'es5' | 'es2015' | 'es2017' | 'amd' | 'system' | 'commonjs' | 'native-modules';

export async function build(
target: IBuildTargetFormat,
options: rollup.RollupFileOptions,
outputs: rollup.OutputOptionsFile[]
): Promise<void> {
return rollup
.rollup({
...options,
plugins: [
typescript({
tsconfigOverride: {
compilerOptions: {
target: target
}
},
cacheRoot: CACHE_DIR
}) as rollup.Plugin,
...(options.plugins || [])
]
})
.then(bundle => Promise.all(outputs.map(output => bundle.write(output))))
.then(() => {
console.log(`Built [${target}] successfully.`);
});
}

export async function watchAndReBuild(
options: Record<string, IRollupWatchOptions>,
onBundleChanged: (e: any) => any
) {
const watcher = rollup
.watch(Object.keys(options).map(target => {
const { plugins = [], tsConfig, ...opts } = options[target];
return {
...opts,
plugins: [
typescript({
tsconfigOverride: {
compilerOptions: {
target: tsConfig ? tsConfig.target : target
}
},
cacheRoot: CACHE_DIR
}) as rollup.Plugin,
...plugins
]
};
}));

watcher.on('event', (e) => {
if (e.code === 'ERROR') {
console.log('Error:', e);
return;
}
if (e.code === 'FATAL') {
console.log('===============');
console.error('FATAL:', e);
console.log('===============');
// rollup will exit
return;
}
if (e.code === 'END') {
onBundleChanged(e);
return;
}
});
}

export async function clean(folder: string): Promise<void> {
console.log(`\n==============\nCleaning ${folder} folder...\n==============`);
return new Promise<void>(resolve => {
rimraf(folder, (error) => {
if (error) {
throw error;
}
resolve();
});
});
}


export async function copy(basePath: string, targetPath: string) {
try {
fs.createReadStream(basePath)
.pipe(fs.createWriteStream(targetPath));
} catch (ex) {
console.log(`Error trying to copy file from "${basePath}" to "${targetPath}"`);
console.log(ex);
}
}
14 changes: 14 additions & 0 deletions build/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"allowJs": false,
"module": "commonjs",
"target": "es2017",
"noEmit": true,
"esModuleInterop": true,
"resolveJsonModule": true
},
"include": [
"./**/*.ts"
]
}
4 changes: 4 additions & 0 deletions build/types.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
declare module 'conventional-changelog' {
import { EventEmitter } from 'events';
export default function (config: { preset: string }): EventEmitter;
}
Loading

0 comments on commit b585383

Please sign in to comment.