* Better rollup messages in console * Remove 'docs folder not found' warning * Show production message * fix codacyversion-14
@@ -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") | |||
@@ -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", | |||
@@ -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(); |
@@ -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')); | |||
} | |||
} |
@@ -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 | |||
}; |
@@ -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 | |||
}; |
@@ -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; | |||
} |
@@ -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" | |||