Browse Source

Better messages for build commands (#5117)

* Better rollup messages in console

* Remove 'docs folder not found' warning

* Show production message

* fix codacy
version-14
Faris Ansari 7 years ago
committed by Rushabh Mehta
parent
commit
55e5b473d0
9 changed files with 358 additions and 213 deletions
  1. +2
    -1
      frappe/build.py
  2. +5
    -3
      package.json
  3. +0
    -204
      rollup.config.js
  4. +105
    -0
      rollup/build.js
  5. +136
    -0
      rollup/config.js
  6. +0
    -0
      rollup/frappe-html-plugin.js
  7. +29
    -1
      rollup/rollup.utils.js
  8. +57
    -0
      rollup/watch.js
  9. +24
    -4
      yarn.lock

+ 2
- 1
frappe/build.py View File

@@ -105,7 +105,8 @@ def make_asset_dirs(make_copy=False, restore=False):
shutil.rmtree(target)
os.symlink(source, target)
else:
warnings.warn('Source {source} does not exist.'.format(source = source))
# warnings.warn('Source {source} does not exist.'.format(source = source))
pass

def build(no_compress=False, verbose=False):
assets_path = os.path.join(frappe.local.sites_path, "assets")


+ 5
- 3
package.json View File

@@ -1,9 +1,9 @@
{
"name": "frappe",
"scripts": {
"build": "rollup -c --silent",
"production": "FRAPPE_ENV=production rollup -c",
"watch": "rollup -c -w"
"build": "node rollup/build.js",
"production": "FRAPPE_ENV=production node rollup/build.js",
"watch": "node rollup/watch.js"
},
"repository": {
"type": "git",
@@ -19,6 +19,7 @@
"cookie": "^0.3.1",
"express": "^4.16.2",
"frappe-datatable": "frappe/datatable",
"frappe-gantt": "^0.1.0",
"moment": "^2.20.1",
"redis": "^2.8.0",
"showdown": "^1.8.6",
@@ -28,6 +29,7 @@
},
"devDependencies": {
"babel-runtime": "^6.26.0",
"chalk": "^2.3.2",
"rollup": "^0.55.3",
"rollup-plugin-buble": "^0.19.2",
"rollup-plugin-commonjs": "^8.3.0",


+ 0
- 204
rollup.config.js View File

@@ -1,204 +0,0 @@
const path = require('path');
const fs = require('fs');
const touch = require('touch');

const {
get_build_json_path,
get_app_path,
apps_list,
assets_path,
get_public_path,
bench_path,
sites_path
} = require('./rollup.utils');

const less = require('rollup-plugin-less');
const multi_entry = require('rollup-plugin-multi-entry');
const commonjs = require('rollup-plugin-commonjs');
const node_resolve = require('rollup-plugin-node-resolve');
const buble = require('rollup-plugin-buble');
const uglify = require('rollup-plugin-uglify');
const frappe_html = require('./frappe-html-plugin');

const production = process.env.FRAPPE_ENV === 'production';

ensure_js_css_dirs();
build_libs();

function get_app_config(app) {
const build_map = get_build_json(app);
if (!build_map) return [];

const js_config = Object.keys(build_map)
.filter(output_file =>
output_file.endsWith('.js') &&
// libs is built separately (to be deprecated)
!output_file.endsWith('libs.min.js')
)
.map(output_file => {

const input_files = build_map[output_file].map(
// make paths absolute
input_path => path.resolve(get_app_path(app), input_path)
);

return get_js_config(output_file, input_files);
});

const less_config = Object.keys(build_map)
.filter(output_file =>
output_file.endsWith('.css')
)
.map(output_file => {

const input_files = build_map[output_file].map(
input_path => path.resolve(get_app_path(app), input_path)
);

return get_css_config(output_file, input_files);
});

return [].concat(js_config, less_config);
}

function get_js_config(output_file, input_files) {

const css_output_file = path.resolve(assets_path, 'css', path.basename(output_file).split('.js')[0] + '.css');

const plugins = [
// enables array of inputs
multi_entry(),
// .html -> .js
frappe_html(),
// less -> css
less({
output: css_output_file,
option: {
// so that other .less files can import variables.less from frappe directly
paths: [path.resolve(get_public_path('frappe'), 'less'), path.resolve(get_app_path('frappe'), '..')],
compress: production
},
// include: [path.resolve(bench_path, '**/*.less'), path.resolve(bench_path, '**/*.css')],
exclude: []
}),
// ES6 -> ES5
buble({
objectAssign: 'Object.assign',
transforms: {
dangerousForOf: true
},
exclude: [path.resolve(bench_path, '**/*.css'), path.resolve(bench_path, '**/*.less')]
}),
commonjs(),
node_resolve(),
production && uglify()
];

return {
input: input_files,
plugins: plugins,
output: {
file: path.resolve(assets_path, output_file),
format: 'iife',
name: 'Rollup',
globals: {
'jquery': 'window.jQuery'
},
sourcemap: true
},
context: 'window',
external: ['jquery']
};
}

function get_css_config(output_file, input_files) {
const output_path = path.resolve(assets_path, output_file);

// clear css file to avoid appending problem
delete_file(output_path);

const plugins = [
// enables array of inputs
multi_entry(),
// less -> css
less({
output: output_path,
option: {
// so that other .less files can import variables.less from frappe directly
paths: [path.resolve(get_public_path('frappe'), 'less')],
compress: production
},
include: [path.resolve(bench_path, '**/*.less'), path.resolve(bench_path, '**/*.css')]
})
];

return {
input: input_files,
plugins: plugins,
output: {
// this file is always empty, remove it later?
file: path.resolve(assets_path, `css/rollup.manifest.css`),
format: 'cjs',
}
};
}

function ensure_js_css_dirs() {
const paths = [
path.resolve(assets_path, 'js'),
path.resolve(assets_path, 'css')
];
paths.forEach(path => {
if (!fs.existsSync(path)) {
fs.mkdirSync(path);
}
});

// clear files in css folder
const css_path = path.resolve(assets_path, 'css');
const files = fs.readdirSync(css_path);

files.forEach(file => {
delete_file(path.resolve(css_path, file));
});
}

function build_libs() {
const libs_path = 'js/libs.min.js';
const input_files = get_build_json('frappe')[libs_path];

const libs_content = input_files.map(file_name => {
const full_path = path.resolve(get_app_path('frappe'), file_name);
return `/* ${file_name} */\n` + fs.readFileSync(full_path);
}).join('\n\n');

const target_path = path.resolve(assets_path, libs_path);
fs.writeFileSync(target_path, libs_content);
console.log('✨ Built libs.min.js'); // eslint-disable-line
touch(path.join(sites_path, '.build'), { force: true });
}

function get_all_apps_config() {
let configs = [];
apps_list.forEach(app => {
configs = configs.concat(get_app_config(app));
});
return configs;
}

function get_build_json(app) {
try {
return require(get_build_json_path(app));
} catch (e) {
// build.json does not exist
return null;
}
}

function delete_file(path) {
if (fs.existsSync(path)) {
fs.unlinkSync(path);
}
}

module.exports = get_all_apps_config();

+ 105
- 0
rollup/build.js View File

@@ -0,0 +1,105 @@
const fs = require('fs');
const path = require('path');
const chalk = require('chalk');
const rollup = require('rollup');
const log = console.log; // eslint-disable-line

const {
get_build_json,
get_app_path,
apps_list,
run_serially,
assets_path,
sites_path,
delete_file
} = require('./rollup.utils');

const {
get_rollup_options
} = require('./config');

show_production_message();
ensure_js_css_dirs();
build_libs();
build_assets_for_all_apps();

function build_assets_for_all_apps() {
run_serially(
apps_list.map(app => () => build_assets(app))
);
}

function build_assets(app) {
const build_json = get_build_json(app);
if (!build_json) return Promise.resolve();
log(chalk.yellow(`\nBuilding ${app} assets...\n`));

const promises = Object.keys(build_json)
.map(output_file => {
const input_files = build_json[output_file]
.map(input_file => path.resolve(get_app_path(app), input_file));
const { inputOptions, outputOptions } = get_rollup_options(output_file, input_files);

return build(inputOptions, outputOptions)
.then(() => {
log(`${chalk.green('✔')} Built ${output_file}`);
});
});

const start = Date.now();
return Promise.all(promises)
.then(() => {
const time = Date.now() - start;
log(chalk.green(`✨ Done in ${time / 1000}s`));
});
}

function build(inputOptions, outputOptions) {
return rollup.rollup(inputOptions)
.then(bundle => bundle.write(outputOptions));
}

function build_libs() {
// only concatenates lib files, not processed through rollup

const touch = require('touch');
const libs_path = 'js/libs.min.js';
const input_files = get_build_json('frappe')[libs_path];

const libs_content = input_files.map(file_name => {
const full_path = path.resolve(get_app_path('frappe'), file_name);
return `/* ${file_name} */\n` + fs.readFileSync(full_path);
}).join('\n\n');

const target_path = path.resolve(assets_path, libs_path);
fs.writeFileSync(target_path, libs_content);
log(`${chalk.green('✔')} Built ${libs_path}`);
touch(path.join(sites_path, '.build'), { force: true });
}

function ensure_js_css_dirs() {
const paths = [
path.resolve(assets_path, 'js'),
path.resolve(assets_path, 'css')
];
paths.forEach(path => {
if (!fs.existsSync(path)) {
fs.mkdirSync(path);
}
});

// clear files in css folder
const css_path = path.resolve(assets_path, 'css');
const files = fs.readdirSync(css_path);

files.forEach(file => {
delete_file(path.resolve(css_path, file));
});
}

function show_production_message() {
const production = process.env.FRAPPE_ENV === 'production';
if (production) {
log(chalk.green('Production mode'));
}
}

+ 136
- 0
rollup/config.js View File

@@ -0,0 +1,136 @@
const path = require('path');
const chalk = require('chalk');
const log = console.log; // eslint-disable-line

const multi_entry = require('rollup-plugin-multi-entry');
const commonjs = require('rollup-plugin-commonjs');
const node_resolve = require('rollup-plugin-node-resolve');
const less = require('rollup-plugin-less');
const buble = require('rollup-plugin-buble');
const uglify = require('rollup-plugin-uglify');
const frappe_html = require('./frappe-html-plugin');

const production = process.env.FRAPPE_ENV === 'production';

const {
assets_path,
bench_path,
get_public_path,
get_app_path,
delete_file,
} = require('./rollup.utils');

function get_rollup_options(output_file, input_files) {
if (output_file.endsWith('.js')) {
return get_rollup_options_for_js(output_file, input_files);
} else if(output_file.endsWith('.css')) {
return get_rollup_options_for_css(output_file, input_files);
}
}

function get_rollup_options_for_js(output_file, input_files) {
const css_output_file = path.resolve(assets_path, 'css', path.basename(output_file).split('.js')[0] + '.css');

const plugins = [
// enables array of inputs
multi_entry(),
// .html -> .js
frappe_html(),
// less -> css
less({
output: css_output_file,
option: {
// so that other .less files can import variables.less from frappe directly
paths: [path.resolve(get_public_path('frappe'), 'less'), path.resolve(get_app_path('frappe'), '..')],
compress: production
},
include: [path.resolve(bench_path, '**/*.less'), path.resolve(bench_path, '**/*.css')],
exclude: []
}),
// ES6 -> ES5
buble({
objectAssign: 'Object.assign',
transforms: {
dangerousForOf: true
},
exclude: [path.resolve(bench_path, '**/*.css'), path.resolve(bench_path, '**/*.less')]
}),
commonjs(),
node_resolve(),
production && uglify()
];

return {
inputOptions: {
input: input_files,
plugins: plugins,
context: 'window',
external: ['jquery'],
onwarn({ code, message, loc, frame }) {
// skip warnings
if (['EVAL', 'SOURCEMAP_BROKEN', 'NAMESPACE_CONFLICT'].includes(code)) return;

if (loc) {
log(`${loc.file} (${loc.line}:${loc.column}) ${message}`);
if (frame) log(frame);
} else {
log(chalk.yellow.underline(code), ':', message);
}
}
},
outputOptions: {
file: path.resolve(assets_path, output_file),
format: 'iife',
name: 'Rollup',
globals: {
'jquery': 'window.jQuery'
},
sourcemap: true
}
};
}

function get_rollup_options_for_css(output_file, input_files) {
const output_path = path.resolve(assets_path, output_file);

// clear css file to avoid appending problem
delete_file(output_path);

const plugins = [
// enables array of inputs
multi_entry(),
// less -> css
less({
output: output_path,
option: {
// so that other .less files can import variables.less from frappe directly
paths: [path.resolve(get_public_path('frappe'), 'less')],
compress: production
},
include: [path.resolve(bench_path, '**/*.less'), path.resolve(bench_path, '**/*.css')]
})
];

return {
inputOptions: {
input: input_files,
plugins: plugins,
onwarn(warning) {
// skip warnings
if (['EMPTY_BUNDLE'].includes(warning.code)) return;

// console.warn everything else
log(chalk.yellow.underline(warning.code), ':', warning.message);
}
},
outputOptions: {
// this file is always empty, remove it later?
file: path.resolve(assets_path, `css/rollup.manifest.css`),
format: 'cjs'
}
};
}

module.exports = {
get_rollup_options
};

frappe-html-plugin.js → rollup/frappe-html-plugin.js View File


rollup.utils.js → rollup/rollup.utils.js View File

@@ -42,6 +42,31 @@ const get_public_path = app => public_paths[app];

const get_build_json_path = app => path.resolve(get_public_path(app), 'build.json');

function get_build_json(app) {
try {
return require(get_build_json_path(app));
} catch (e) {
// build.json does not exist
return null;
}
}

function delete_file(path) {
if (fs.existsSync(path)) {
fs.unlinkSync(path);
}
}

function run_serially(tasks) {
let result = Promise.resolve();
tasks.forEach(task => {
if(task) {
result = result.then ? result.then(task) : Promise.resolve();
}
});
return result;
}

const get_app_path = app => app_paths[app];

module.exports = {
@@ -49,8 +74,11 @@ module.exports = {
bundle_map,
get_public_path,
get_build_json_path,
get_build_json,
get_app_path,
apps_list,
assets_path,
bench_path
bench_path,
delete_file,
run_serially
};

+ 57
- 0
rollup/watch.js View File

@@ -0,0 +1,57 @@
const path = require('path');
const chalk = require('chalk');
const rollup = require('rollup');
const log = console.log; // eslint-disable-line
const {
apps_list,
get_app_path,
get_build_json
} = require('./rollup.utils');

const {
get_rollup_options
} = require('./config');

watch_assets();

function watch_assets() {
let watchOptions = [];
apps_list.map(app => {
watchOptions.push(...get_watch_options(app));
});
log(chalk.green(`\nRollup Watcher Started`));
let watcher = rollup.watch(watchOptions);

watcher.on('event', event => {
switch(event.code) {
case 'START':
log(chalk.yellow(`\nWatching...`));
break;

case 'BUNDLE_START':
log('Rebuilding', path.basename(event.output[0]));
break;

default:
break;
}
});
}

function get_watch_options(app) {
const build_json = get_build_json(app);
if (!build_json) return [];

const watchOptions = Object.keys(build_json)
.map(output_file => {
const input_files = build_json[output_file]
.map(input_file => path.resolve(get_app_path(app), input_file));
const { inputOptions, outputOptions } = get_rollup_options(output_file, input_files);

return Object.assign({}, inputOptions, {
output: outputOptions
});
}).filter(Boolean);

return watchOptions;
}

+ 24
- 4
yarn.lock View File

@@ -54,6 +54,12 @@ ansi-styles@^3.2.0:
dependencies:
color-convert "^1.9.0"

ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
dependencies:
color-convert "^1.9.0"

arr-diff@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf"
@@ -232,6 +238,14 @@ chalk@^2.3.1:
escape-string-regexp "^1.0.5"
supports-color "^5.2.0"

chalk@^2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.2.tgz#250dc96b07491bfd601e648d66ddf5f60c7a5c65"
dependencies:
ansi-styles "^3.2.1"
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"

cliui@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.0.0.tgz#743d4650e05f36d1ed2575b59638d87322bfbbcc"
@@ -617,6 +631,10 @@ frappe-datatable@frappe/datatable:
clusterize.js "^0.18.0"
sortablejs "^1.7.0"

frappe-gantt@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/frappe-gantt/-/frappe-gantt-0.1.0.tgz#0532d7f10bc4c905ad7dd1ef8e65c7457d13355f"

fresh@0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
@@ -986,10 +1004,6 @@ locate-path@^2.0.0:
p-locate "^2.0.0"
path-exists "^3.0.0"

lodash@^4.17.5:
version "4.17.5"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511"

lru-cache@^4.0.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55"
@@ -1700,6 +1714,12 @@ supports-color@^5.2.0:
dependencies:
has-flag "^3.0.0"

supports-color@^5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.3.0.tgz#5b24ac15db80fa927cf5227a4a33fd3c4c7676c0"
dependencies:
has-flag "^3.0.0"

to-array@0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890"


Loading…
Cancel
Save