Skip to content

Instantly share code, notes, and snippets.

@lll000111
Created January 29, 2019 11:16
Show Gist options
  • Save lll000111/1b5487dc6bd07bd8b798083e4149bfa2 to your computer and use it in GitHub Desktop.
Save lll000111/1b5487dc6bd07bd8b798083e4149bfa2 to your computer and use it in GitHub Desktop.
build.js for Neo one
#!/usr/bin/env node
// @flow
'use strict';
/* eslint-disable arrow-parens, no-console, no-await-in-loop */
const {basename, dirname, join, relative} = require('path');
const {promisify} = require('util');
const crypto = require('crypto');
const exec = promisify(require('child_process').exec);
const mkdir = promisify(require('fs').mkdir);
const readDir = promisify(require('fs').readdir);
const readFile = promisify(require('fs').readFile);
const writeFile = promisify(require('fs').writeFile);
const copyFile = promisify(require('fs').copyFile);
const {flat, memoize} = require('one.core/lib/util/function.js');
// const babel = require('@babel/core');
const babel = require('babel-core');
const dependencyTree = require('dependency-tree');
const BABEL_OPTS_6 = {
presets: [
'babel-preset-es2015',
'babel-preset-stage-2'
// 'minify'
],
plugins: [
'transform-flow-strip-types'
],
comments: false
};
// const BABEL_OPTS_ES5 = {
// presets: [
// '@babel/preset-env',
// '@babel/preset-flow'
// // 'minify'
// ],
// plugins: [
// [
// '@babel/plugin-transform-runtime',
// {
// 'corejs': false,
// 'helpers': true,
// 'regenerator': true,
// 'useESModules': false
// }
// ]
// ],
// comments: false
// };
const hash = (s/*: string*/)/*: string*/ => {
return crypto.createHash('sha256').update(s, 'utf8').digest('hex');
};
/**
* Core node.js module dependencies are skipped - the package uses "precinct"
* (https://www.npmjs.com/package/precinct), function paperwork(), and sets its option
* includeCore=false.
* @param {string} file
* @returns {Array<string>}
*/
const getDepTree = memoize(
(file/*: string*/)/*: Array<string>*/ => {
// The paths of the files in the returned array of files are absolute paths from / (root)
const deps = dependencyTree.toList({
filename: file,
directory: dirname(file),
detective: {
amd: {
skipLazyLoaded: false
},
es6: {
mixedImports: true
}
}
})
.map(file => relative(__dirname, file));
return deps;
}
);
const buildOneForLowJs = async ()/*: Promise<void>*/ => {
console.log('Building ONE for low.js');
const { /* stdout, */ stderr} = await exec('./build.js low', {cwd: './node_modules/one.core'});
if (stderr !== '') {
throw new Error(stderr);
}
};
const mkdirs = async ()/*: Promise<void>*/ => {
await mkdir(join(__dirname, 'DEVICE'), {recursive: true});
await mkdir(join(__dirname, 'DEVICE', 'DATA'), {recursive: true});
};
const processJsFile = async (file/*: string*/)/*: Promise<void>*/ => {
const code/*: string*/ = await readFile(file, 'utf8');
const dest = join('DEVICE', file.startsWith('src') ? '' : dirname(file));
let oldHash/*: string*/;
try {
const oldCode = await readFile(join(dest, basename(file)), 'utf8');
oldHash = hash(oldCode);
} catch (err) {
if (err.code !== 'ENOENT') {
throw err;
}
}
// const transformedCode/*: Object*/ = await babel.transformAsync(code, BABEL_OPTS_ES5);
const transformedCode/*: Object*/ = babel.transform(code, BABEL_OPTS_6);
const newHash/*: string*/ = hash(transformedCode.code);
if (!file.startsWith('src')) {
await mkdir(dest, {recursive: true});
}
if (newHash !== oldHash) {
await writeFile(join(dest, basename(file)), transformedCode.code, {flag: 'w'});
console.log('Wrote', join(dest, basename(file)));
}
};
const findDepsInDirectory = async (dir/*: string*/)/*: Promise<Array<string>>*/ => {
const files/*: Array<string>*/ = await readDir(dir);
return Array.from(
new Set(
flat(
await Promise.all(
files
.filter(file => file.endsWith('.js'))
.map(file =>
getDepTree(join(dir, file))
)
)
)
)
);
};
const processDirectory = async (dir/*: string*/)/*: Promise<void>*/ => {
console.log(`Process directory ${dir}`);
const deps/*: Array<string>*/ = await findDepsInDirectory(join(__dirname, dir));
await Promise.all(
deps.map(file => processJsFile(file))
);
};
const findBabelHelperDeps = async ()/*: Promise<void>*/ => {
console.log('Find all Babel helper imports');
const deps/*: Array<string>*/ = await findDepsInDirectory(join(__dirname, 'DEVICE'));
await Promise.all(
// If the copy under DEVICE/ already exists the dependency-tree algorithm will find
// that file as dependency, if not it will find the version in
// <PROJECT_ROOT>/node_modules/@babel/
// We can use that to only copy the file over when it does not already exist, plus, we
// need to filter for "@babel" dependencies only in any case, so the filter condition
// actually achieves two separate things in a single condition.
deps
.filter(file => file.startsWith('node_modules/@babel/'))
.map(async file => {
await mkdir(join(__dirname, 'DEVICE', dirname(file)), {recursive: true});
await copyFile(join(__dirname, file), join(__dirname, 'DEVICE', file));
console.log(`Copied to ${join('DEVICE', file)}`);
})
);
};
console.log(`Babel version ${babel.version}`);
// buildOneForLowJs()
// .then(mkdirs)
mkdirs()
.then(() => processDirectory('src'))
.then(findBabelHelperDeps)
.catch(console.log);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment