Files
spring-flo/build.js
2017-11-20 15:54:13 -05:00

187 lines
6.2 KiB
JavaScript

'use strict';
const fs = require('fs');
const path = require('path');
const glob = require('glob');
const camelCase = require('camelcase');
const ngc = require('@angular/compiler-cli/src/main').main;
const rollup = require('rollup');
const uglify = require('rollup-plugin-uglify');
const sourcemaps = require('rollup-plugin-sourcemaps');
const inlineResources = require('./inline-resources');
const DIST_FOLDER_NAME = 'dist';
const libName = require('./package.json').name;
const rootFolder = path.join(__dirname);
const compilationFolder = path.join(rootFolder, 'out-tsc');
const srcFolder = path.join(rootFolder, 'src/lib');
const distFolder = path.join(rootFolder, DIST_FOLDER_NAME);
const tempLibFolder = path.join(compilationFolder, 'lib');
const es5OutputFolder = path.join(compilationFolder, 'lib-es5');
const es2015OutputFolder = path.join(compilationFolder, 'lib-es2015');
return Promise.resolve()
// Copy library to temporary folder and inline html/css.
.then(() => _relativeCopy(`**/*`, srcFolder, tempLibFolder)
.then(() => inlineResources(tempLibFolder))
.then(() => console.log('Inlining succeeded.'))
)
// Compile to ES2015.
.then(() => ngc({ project: `${tempLibFolder}/tsconfig.lib.json` })
.then(exitCode => exitCode === 0 ? Promise.resolve() : Promise.reject())
.then(() => console.log('ES2015 compilation succeeded.'))
)
// Compile to ES5.
.then(() => ngc({ project: `${tempLibFolder}/tsconfig.es5.json` })
.then(exitCode => exitCode === 0 ? Promise.resolve() : Promise.reject())
.then(() => console.log('ES5 compilation succeeded.'))
)
// Copy typings and metadata to `dist/` folder.
.then(() => Promise.resolve()
.then(() => _relativeCopy('**/*.d.ts', es2015OutputFolder, distFolder))
.then(() => _relativeCopy('**/*.metadata.json', es2015OutputFolder, distFolder))
.then(() => console.log('Typings and metadata copy succeeded.'))
)
// Bundle lib.
.then(() => {
// Base configuration.
const es5Entry = path.join(es5OutputFolder, `${libName}.js`);
const es2015Entry = path.join(es2015OutputFolder, `${libName}.js`);
const rollupBaseConfig = {
name: camelCase(libName),
sourcemap: true,
// ATTENTION:
// Add any dependency or peer dependency your library to `globals` and `external`.
// This is required for UMD bundle users.
globals: {
// The key here is library name, and the value is the the name of the global variable name
// the window object.
// See https://github.com/rollup/rollup/wiki/JavaScript-API#globals for more.
'@angular/core': 'ng.core',
'jquery': '$',
'lodash': '_'
},
external: [
// List of dependencies
// See https://github.com/rollup/rollup/wiki/JavaScript-API#external for more.
'@angular/core',
'@angular/forms',
'@angular/platform-browser',
'codemirror',
'jointjs',
'lodash',
'ts-disposables'
],
plugins: [
sourcemaps()
]
};
// UMD bundle.
const umdConfig = Object.assign({}, rollupBaseConfig, {
input: es5Entry,
file: path.join(distFolder, `bundles`, `${libName}.umd.js`),
format: 'umd',
});
// Minified UMD bundle.
const minifiedUmdConfig = Object.assign({}, rollupBaseConfig, {
input: es5Entry,
file: path.join(distFolder, `bundles`, `${libName}.umd.min.js`),
format: 'umd',
plugins: rollupBaseConfig.plugins.concat([uglify({})])
});
// ESM+ES5 flat module bundle.
const fesm5config = Object.assign({}, rollupBaseConfig, {
input: es5Entry,
file: path.join(distFolder, `${libName}.es5.js`),
format: 'es'
});
// ESM+ES2015 flat module bundle.
const fesm2015config = Object.assign({}, rollupBaseConfig, {
input: es2015Entry,
file: path.join(distFolder, `${libName}.js`),
format: 'es'
});
const allBundles = [
umdConfig,
minifiedUmdConfig,
fesm5config,
fesm2015config
].map(cfg => rollup.rollup(cfg).then(bundle => bundle.write(cfg)));
return Promise.all(allBundles)
.then(() => console.log('All bundles generated successfully.'))
})
// Copy package files
.then(() => Promise.resolve()
.then(() => _relativeCopy('LICENSE', rootFolder, distFolder))
.then(() => _relativeCopy('README.md', rootFolder, distFolder))
.then(() => _generatePackageJson(path.join(rootFolder, 'package.json'), distFolder))
.then(() => console.log('Package files copy succeeded.'))
)
.catch(e => {
console.error('\Build failed. See below for errors.\n');
console.error(e);
process.exit(1);
});
// Copy files maintaining relative paths.
function _relativeCopy(fileGlob, from, to) {
return new Promise((resolve, reject) => {
glob(fileGlob, { cwd: from, nodir: true }, (err, files) => {
if (err) reject(err);
files.forEach(file => {
const origin = path.join(from, file);
const dest = path.join(to, file);
const data = fs.readFileSync(origin, 'utf-8');
_recursiveMkDir(path.dirname(dest));
fs.writeFileSync(dest, data);
resolve();
})
})
});
}
function _generatePackageJson(basePackageJson, distFolder) {
return new Promise((resolve, reject) => {
try {
const json = JSON.parse(fs.readFileSync(basePackageJson));
if (json['scripts']) {
delete json['scripts']['postinstall'];
}
const searchValue = './' + DIST_FOLDER_NAME + '/';
const replaceValue = './';
replacePropertyValue(json, 'main', searchValue, replaceValue);
replacePropertyValue(json, 'module', searchValue, replaceValue);
replacePropertyValue(json, 'es2015', searchValue, replaceValue);
replacePropertyValue(json, 'typings', searchValue, replaceValue);
fs.writeFileSync(path.join(distFolder, 'package.json'), JSON.stringify(json, null, 2));
resolve();
} catch (error) {
reject(error);
}
});
}
function replacePropertyValue(json, property, searchValue, newValue) {
if (typeof json[property] === 'string') {
json[property] = json[property].replace(searchValue, newValue);
}
}
// Recursively create a dir.
function _recursiveMkDir(dir) {
if (!fs.existsSync(dir)) {
_recursiveMkDir(path.dirname(dir));
fs.mkdirSync(dir);
}
}