@openveo/player
Version:
OpenVeo player to play a video with associated images and chapters
314 lines (270 loc) • 11.9 kB
JavaScript
/**
* Builds OpenVeo Player.
*
* It needs to be run from project root directory.
*
* Usage:
*
* # Build OpenVeo Player for development
* # Same as `build development`
* $ build
* $ build development
*
* # Build OpenVeo Player for production
* $ build production
*/
;
const {exec} = require('child_process');
const {writeFile} = require('fs/promises');
const path = require('path');
const util = require('util');
const openVeoApi = require('@openveo/api');
const packageInformation = require('../package.json');
const environment = process.argv[2];
/**
* Logs given message to stdout with a prefix.
*
* @param {String} message the message to log
*/
function log(message) {
console.log(`build > ${message}`);
}
/**
* Compiles and concat JavaScript files.
*
* @param {String} workingDirectory Path of the directory from where to launch the compilation
* @param {Array} filesPaths The list of files paths to compile and concat
* @param {String} outputPath The file output path
* @return {Promise} Promise resolving when JavaScript files have been compiled
*/
async function compileJavaScriptFiles(workingDirectory, filesPaths, outputPath) {
return new Promise((resolve, reject) => {
const command = `npx uglifyjs \
-c \
-m \
${environment !== 'production' ? '--source-map' : ''} \
-o ${outputPath} \
-- ${filesPaths.join(' ')}`;
log(command);
exec(command, {cwd: workingDirectory}, (error, stdout, stderr) => {
if (error) {
return reject(error);
}
return resolve();
});
});
}
/**
* Compiles SCSS files.
*
* @param {String} scssDirectoryPath The path where to find SCSS files
* @param {String} mainScssFilePath The path of the main SCSS file to compile
* @param {String} outputPath The destination directory path
* @return {Promise} Promise resolving when SCSS files have been compiled
*/
async function compileScssFiles(scssDirectoryPath, mainScssFilePath, outputPath) {
return new Promise((resolve, reject) => {
const command = `compass compile -c ./compass.rb \
--force \
--sass-dir ${scssDirectoryPath} \
--css-dir ${outputPath} \
${environment === 'production' ? '-e production -s compressed --no-sourcemap' : ''} \
-- ${mainScssFilePath}
`;
log(command);
exec(command, {cwd: process.cwd()}, (error, stdout, stderr) => {
if (error) return reject(error);
console.log(stdout);
return resolve();
});
});
}
/**
* Copies ordered sources to given directory.
*
* @param {String} baseSourcesPath The base path of all JavaScript and CSS / SCSS files
* @param {String} jsDirectoryPath The path of the directory to copy JavaScript files to
* @param {String} cssDirectoryPath The path of the directory to copy SCSS files to
* @param {Object} orderedSources The ordered JavaScript and CSS / SCSS sources
* @param {Object} orderedSources.js The ordered JavaScript sources
* @param {Object} orderedSources.css The ordered CSS / SCSS sources
* @return {Promise} Promise resolving when files have been copied
*/
async function copyOrderedSources(baseSourcesPath, jsDirectoryPath, cssDirectoryPath, orderedSources) {
const copiedOrderedSources = {js: [], css: []};
const copyFiles = async function(filesToCopy, filesCopied, outputPath) {
for (let filePath of filesToCopy) {
const relativeFilePath = filePath.replace(baseSourcesPath, '');
const destinationPath = path.join(outputPath, relativeFilePath);
await util.promisify(openVeoApi.fileSystem.copy.bind(openVeoApi.fileSystem))(
filePath,
destinationPath
);
filesCopied.push(destinationPath);
}
};
await copyFiles(orderedSources.js, copiedOrderedSources.js, jsDirectoryPath);
await copyFiles(orderedSources.css, copiedOrderedSources.css, cssDirectoryPath);
return Promise.resolve(copiedOrderedSources);
}
/**
* Gets the list of JavaScript and SCSS sources ordered by dependence.
*
* @param {String} baseSourcesPath The base directory to look for sources
* @return {Promise} Promise resolving with JavaScript and CSS / SCSS files ordered by dependence
*/
async function getOrderedSources(baseSourcesPath) {
const filesPaths = [];
const sources = await util.promisify(openVeoApi.fileSystem.readdir.bind(openVeoApi.fileSystem))(baseSourcesPath);
for (let source of sources) {
if (source.isFile() && !/(\.spec\.js|\/index\.scss|\.json|\.html)$/.test(source.path)) {
filesPaths.push(source.path);
}
}
return util.promisify(openVeoApi.angularJs.parser.orderSources.bind(openVeoApi.angularJs.parser))(filesPaths);
}
/**
* Generates HTML templates cache.
*
* @param {String} baseSourcesPath The base directory to look for HTML templates
* @param {String} outputPath The path of the template cache file
* @return {Promise} Promise resolving when template cache file has been generated
*/
async function generateTemplatesCache(baseSourcesPath, outputPath) {
const templatesPaths = [];
const sources = await util.promisify(openVeoApi.fileSystem.readdir.bind(openVeoApi.fileSystem))(baseSourcesPath);
for (let source of sources) {
if (source.isFile() && /\.html$/.test(source.path)) {
templatesPaths.push(source.path);
}
}
return util.promisify(openVeoApi.angularJs.parser.generateTemplatesCache.bind(openVeoApi.angularJs.parser))(
templatesPaths,
outputPath,
'ov.player',
'opl-'
);
}
/**
* Builds OpenVeo Player.
*/
async function main() {
const rootPath = path.join(__dirname, '../');
const baseSourcesPath = path.join(rootPath, 'src');
const indexScssPath = path.join(baseSourcesPath, 'index.scss');
const buildPath = path.join(rootPath, 'build');
const distPath = path.join(rootPath, 'dist');
const fontsPath = path.join(rootPath, 'fonts');
const fontsDistPath = path.join(distPath, 'fonts');
const scssBuildPath = path.join(buildPath, 'scss');
const scssDistPath = path.join(distPath, 'scss');
const scssComponentsBuildPath = path.join(scssBuildPath, 'scss');
const jsBuildPath = path.join(buildPath, 'js');
const jsDistPath = path.join(distPath, 'js');
const robotoRootPath = path.join(rootPath, 'node_modules/roboto-fontface');
const robotoFontsPath = path.join(robotoRootPath, 'fonts/roboto');
const robotoCssPath = path.join(robotoRootPath, 'css');
const robotoCssBuildPath = path.join(scssComponentsBuildPath, 'roboto-fontface');
const robotoMixinsPath = path.join(robotoCssBuildPath, 'mixins.scss');
const robotoFontsDistPath = path.join(fontsDistPath, 'roboto');
const indexScssBuildPath = path.join(scssBuildPath, 'openveo-player.min.scss');
const indexScssDistPath = path.join(distPath, 'openveo-player.min.scss');
const indexCssBuildPath = path.join(scssBuildPath, 'openveo-player.min.css');
const indexCssDistPath = path.join(distPath, 'openveo-player.min.css');
const indexCssSourceMapBuildPath = `${indexCssBuildPath}.map`;
const indexCssSourceMapDistPath = `${indexCssDistPath}.map`;
const mainJsDistPath = path.join(distPath, 'openveo-player.min.js');
const templateCacheBuildPath = path.join(jsBuildPath, 'openveo-player.templates.js');
const orderedSourcesBuildPath = path.join(buildPath, 'ng-components-files.json');
const orderedSources = await getOrderedSources(baseSourcesPath);
log(`Save ordered JavaScript and CSS / SCSS files to ${orderedSourcesBuildPath}`);
await util.promisify(openVeoApi.fileSystem.mkdir.bind(openVeoApi.fileSystem))(buildPath);
await writeFile(orderedSourcesBuildPath, JSON.stringify(orderedSources));
log(`Copy ordered sources to ${jsBuildPath} and ${scssBuildPath}`);
await copyOrderedSources(
baseSourcesPath,
jsBuildPath,
scssComponentsBuildPath,
orderedSources
);
log(`Generate cache for HTML templates to ${templateCacheBuildPath}`);
await generateTemplatesCache(baseSourcesPath, templateCacheBuildPath);
log(`Copy Roboto SCSS files ${robotoCssPath} to ${robotoCssBuildPath}`);
await util.promisify(openVeoApi.fileSystem.copy.bind(openVeoApi.fileSystem))(robotoCssPath, robotoCssBuildPath);
log(`Replace Roboto SCSS font paths in ${robotoMixinsPath}`);
await util.promisify(openVeoApi.fileSystem.replace.bind(openVeoApi.fileSystem))(
robotoMixinsPath,
[
{pattern: /\.\.\/\.\.\/\.\.\/fonts/g, replacement: '../../fonts'}
]
);
log(`Copy ${indexScssPath} to ${indexScssBuildPath}`);
await util.promisify(openVeoApi.fileSystem.copy.bind(openVeoApi.fileSystem))(indexScssPath, indexScssBuildPath);
log(`Inject components SCSS and Roboto SCSS to ${indexScssBuildPath}`);
await util.promisify(openVeoApi.fileSystem.replace.bind(openVeoApi.fileSystem))(
indexScssBuildPath,
[
{
pattern: /\/\/ INJECT_SCSS/,
replacement: orderedSources.css.map(function(cssSourcePath) {
return '@import "./scss' + cssSourcePath.replace(baseSourcesPath, '') + '";';
}).join('\n')
},
{
pattern: /\/\/ INJECT_EXTERNAL_FONTS_SCSS/,
replacement: [
'@import "./scss/roboto-fontface/roboto/sass/roboto-fontface-regular.scss";',
'@import "./scss/roboto-fontface/roboto/sass/roboto-fontface-medium.scss";'
].join('\n')
}
]
);
log(`Compile main SCSS file ${indexScssBuildPath} to ${scssBuildPath}`);
await compileScssFiles(scssBuildPath, indexScssBuildPath, scssBuildPath);
log(`Prepend OpenVeo Player version to ${indexCssBuildPath}`);
await util.promisify(openVeoApi.fileSystem.prepend.bind(openVeoApi.fileSystem))(
indexCssBuildPath,
`/* openveo-player v${packageInformation.version} */\n\n`
);
log(`Copy CSS file ${indexCssBuildPath} to ${indexCssDistPath}`);
await util.promisify(openVeoApi.fileSystem.copy.bind(openVeoApi.fileSystem))(indexCssBuildPath, indexCssDistPath);
if (environment !== 'production') {
log(`Copy CSS source map file ${indexCssSourceMapBuildPath} to ${indexCssSourceMapDistPath}`);
await util.promisify(openVeoApi.fileSystem.copy.bind(openVeoApi.fileSystem))(
indexCssSourceMapBuildPath,
indexCssSourceMapDistPath
);
log(`Copy JavaScript source files ${jsBuildPath} to ${jsDistPath}`);
await util.promisify(openVeoApi.fileSystem.copy.bind(openVeoApi.fileSystem))(jsBuildPath, jsDistPath);
log(`Copy main SCSS source files ${indexScssBuildPath} to ${indexScssDistPath}`);
await util.promisify(openVeoApi.fileSystem.copy.bind(openVeoApi.fileSystem))(indexScssBuildPath, indexScssDistPath);
log(`Copy SCSS source files ${scssComponentsBuildPath} to ${scssDistPath}`);
await util.promisify(openVeoApi.fileSystem.copy.bind(openVeoApi.fileSystem))(scssComponentsBuildPath, scssDistPath);
}
log(`Replace Roboto CSS font paths in ${indexCssDistPath}`);
await util.promisify(openVeoApi.fileSystem.replace.bind(openVeoApi.fileSystem))(
indexCssDistPath,
[
{pattern: /\.\.\/\.\.\/fonts/g, replacement: './fonts'}
]
);
log(`Compile JavaScript file to ${mainJsDistPath} from ${buildPath}`);
await compileJavaScriptFiles(
buildPath,
orderedSources.js.map(function(jsSourcePath) {
return jsSourcePath.replace(baseSourcesPath, 'js');
}).concat([templateCacheBuildPath.replace(jsBuildPath, 'js')]),
mainJsDistPath
);
log(`Prepend OpenVeo Player version to ${mainJsDistPath}`);
await util.promisify(openVeoApi.fileSystem.prepend.bind(openVeoApi.fileSystem))(
mainJsDistPath,
`/* openveo-player v${packageInformation.version} */\n`
);
log(`Copy ${fontsPath} to ${fontsDistPath}`);
await util.promisify(openVeoApi.fileSystem.copy.bind(openVeoApi.fileSystem))(fontsPath, fontsDistPath);
log(`Copy ${robotoFontsPath} to ${robotoFontsDistPath}`);
await util.promisify(openVeoApi.fileSystem.copy.bind(openVeoApi.fileSystem))(robotoFontsPath, robotoFontsDistPath);
}
main();