- Use PostCSS instead of Less plugin - Fixes CSS append problem - Show which css file changed instead of rollup.manifest.css - Minify CSS in production - Cannot import less/css files in js files, put them in build.json - Let's avoid major changes in Frappe Framework now :)version-14
@@ -126,7 +126,8 @@ | |||||
"public/less/form.less", | "public/less/form.less", | ||||
"public/less/mobile.less", | "public/less/mobile.less", | ||||
"public/less/kanban.less", | "public/less/kanban.less", | ||||
"public/less/controls.less" | |||||
"public/less/controls.less", | |||||
"public/less/chat.less" | |||||
], | ], | ||||
"css/frappe-rtl.css": [ | "css/frappe-rtl.css": [ | ||||
"public/css/bootstrap-rtl.css", | "public/css/bootstrap-rtl.css", | ||||
@@ -350,6 +351,8 @@ | |||||
], | ], | ||||
"css/report.min.css": [ | "css/report.min.css": [ | ||||
"public/less/report.less", | "public/less/report.less", | ||||
"node_modules/frappe-datatable/dist/frappe-datatable.css", | |||||
"public/less/frappe-datatable.less", | |||||
"public/css/tree_grid.css" | "public/css/tree_grid.css" | ||||
], | ], | ||||
"js/report.min.js": [ | "js/report.min.js": [ | ||||
@@ -7,8 +7,6 @@ import hyper from '../lib/hyper.min' | |||||
import './socketio_client' | import './socketio_client' | ||||
import '../../less/chat.less' | |||||
/* eslint semi: "never" */ | /* eslint semi: "never" */ | ||||
// Fuck semicolons - https://mislav.net/2010/05/semicolons | // Fuck semicolons - https://mislav.net/2010/05/semicolons | ||||
@@ -1055,7 +1053,7 @@ frappe.components.FAB.defaultProps | |||||
icon: "octicon octicon-plus" | icon: "octicon octicon-plus" | ||||
} | } | ||||
frappe.components.FAB.SIZE | frappe.components.FAB.SIZE | ||||
= | |||||
= | |||||
{ | { | ||||
small: | small: | ||||
{ | { | ||||
@@ -1470,7 +1468,7 @@ class extends Component { | |||||
placeholder: __("Search or Create a New Chat"), | placeholder: __("Search or Create a New Chat"), | ||||
class: "level", | class: "level", | ||||
layout: props.layout, | layout: props.layout, | ||||
actions: | |||||
actions: | |||||
frappe._.compact([ | frappe._.compact([ | ||||
{ | { | ||||
label: __("New"), | label: __("New"), | ||||
@@ -2460,11 +2458,11 @@ frappe.chat.setup = () => | |||||
{ | { | ||||
if ( frappe.session.user !== 'Guest' ) { | if ( frappe.session.user !== 'Guest' ) { | ||||
frappe.log = frappe.Logger.get('frappe.chat'); | frappe.log = frappe.Logger.get('frappe.chat'); | ||||
frappe.log.info('Setting up frappe.chat'); | frappe.log.info('Setting up frappe.chat'); | ||||
frappe.log.warn('TODO: Handle realtime System Settings update.'); | frappe.log.warn('TODO: Handle realtime System Settings update.'); | ||||
frappe.log.warn('TODO: frappe.chat.<object> requires a storage.'); | frappe.log.warn('TODO: frappe.chat.<object> requires a storage.'); | ||||
// Create/Get Chat Profile for session User, retrieve enable_chat | // Create/Get Chat Profile for session User, retrieve enable_chat | ||||
frappe.log.info('Creating a Chat Profile.'); | frappe.log.info('Creating a Chat Profile.'); | ||||
frappe.chat.profile.create('enable_chat').then(({ enable_chat }) => { | frappe.chat.profile.create('enable_chat').then(({ enable_chat }) => { | ||||
@@ -2472,7 +2470,7 @@ frappe.chat.setup = () => | |||||
const should_render = frappe.sys_defaults.enable_chat && enable_chat; | const should_render = frappe.sys_defaults.enable_chat && enable_chat; | ||||
frappe.chat.render(should_render); | frappe.chat.render(should_render); | ||||
}); | }); | ||||
// Triggered when a User updates his/her Chat Profile. | // Triggered when a User updates his/her Chat Profile. | ||||
// Don't worry, enable_chat is broadcasted to this user only. No overhead. :) | // Don't worry, enable_chat is broadcasted to this user only. No overhead. :) | ||||
frappe.chat.profile.on.update((user, profile) => { | frappe.chat.profile.on.update((user, profile) => { | ||||
@@ -2,8 +2,7 @@ | |||||
* frappe.views.ReportView | * frappe.views.ReportView | ||||
*/ | */ | ||||
import DataTable from 'frappe-datatable'; | import DataTable from 'frappe-datatable'; | ||||
import 'frappe-datatable/dist/frappe-datatable.css'; | |||||
import '../../../../less/frappe-datatable.less'; | |||||
frappe.provide('frappe.views'); | frappe.provide('frappe.views'); | ||||
frappe.views.ReportView = class ReportView extends frappe.views.ListView { | frappe.views.ReportView = class ReportView extends frappe.views.ListView { | ||||
@@ -32,12 +32,13 @@ | |||||
"devDependencies": { | "devDependencies": { | ||||
"babel-runtime": "^6.26.0", | "babel-runtime": "^6.26.0", | ||||
"chalk": "^2.3.2", | "chalk": "^2.3.2", | ||||
"less": "^3.0.1", | |||||
"rollup": "^0.55.3", | "rollup": "^0.55.3", | ||||
"rollup-plugin-buble": "^0.19.2", | "rollup-plugin-buble": "^0.19.2", | ||||
"rollup-plugin-commonjs": "^8.3.0", | "rollup-plugin-commonjs": "^8.3.0", | ||||
"rollup-plugin-less": "^0.1.3", | |||||
"rollup-plugin-multi-entry": "^2.0.2", | "rollup-plugin-multi-entry": "^2.0.2", | ||||
"rollup-plugin-node-resolve": "^3.0.2", | "rollup-plugin-node-resolve": "^3.0.2", | ||||
"rollup-plugin-postcss": "^1.4.0", | |||||
"rollup-plugin-uglify": "^3.0.0" | "rollup-plugin-uglify": "^3.0.0" | ||||
} | } | ||||
} | } |
@@ -10,12 +10,11 @@ const { | |||||
apps_list, | apps_list, | ||||
run_serially, | run_serially, | ||||
assets_path, | assets_path, | ||||
sites_path, | |||||
delete_file | |||||
sites_path | |||||
} = require('./rollup.utils'); | } = require('./rollup.utils'); | ||||
const { | const { | ||||
get_rollup_options | |||||
get_options_for | |||||
} = require('./config'); | } = require('./config'); | ||||
show_production_message(); | show_production_message(); | ||||
@@ -30,23 +29,16 @@ function build_assets_for_all_apps() { | |||||
} | } | ||||
function build_assets(app) { | function build_assets(app) { | ||||
const build_json = get_build_json(app); | |||||
if (!build_json) return Promise.resolve(); | |||||
const options = get_options_for(app); | |||||
if (!options.length) return Promise.resolve(); | |||||
log(chalk.yellow(`\nBuilding ${app} assets...\n`)); | 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); | |||||
if (output_file.endsWith('libs.min.js')) return Promise.resolve(); | |||||
return build(inputOptions, outputOptions) | |||||
.then(() => { | |||||
log(`${chalk.green('✔')} Built ${output_file}`); | |||||
}); | |||||
}); | |||||
const promises = options.map(({ inputOptions, outputOptions, output_file}) => { | |||||
return build(inputOptions, outputOptions) | |||||
.then(() => { | |||||
log(`${chalk.green('✔')} Built ${output_file}`); | |||||
}); | |||||
}); | |||||
const start = Date.now(); | const start = Date.now(); | ||||
return Promise.all(promises) | return Promise.all(promises) | ||||
@@ -89,19 +81,9 @@ function ensure_js_css_dirs() { | |||||
fs.mkdirSync(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() { | function show_production_message() { | ||||
const production = process.env.FRAPPE_ENV === 'production'; | const production = process.env.FRAPPE_ENV === 'production'; | ||||
if (production) { | |||||
log(chalk.green('Production mode')); | |||||
} | |||||
} | |||||
log(chalk.yellow(`${production ? 'Production' : 'Development'} mode`)); | |||||
} |
@@ -5,7 +5,7 @@ const log = console.log; // eslint-disable-line | |||||
const multi_entry = require('rollup-plugin-multi-entry'); | const multi_entry = require('rollup-plugin-multi-entry'); | ||||
const commonjs = require('rollup-plugin-commonjs'); | const commonjs = require('rollup-plugin-commonjs'); | ||||
const node_resolve = require('rollup-plugin-node-resolve'); | const node_resolve = require('rollup-plugin-node-resolve'); | ||||
const less = require('rollup-plugin-less'); | |||||
const postcss = require('rollup-plugin-postcss'); | |||||
const buble = require('rollup-plugin-buble'); | const buble = require('rollup-plugin-buble'); | ||||
const uglify = require('rollup-plugin-uglify'); | const uglify = require('rollup-plugin-uglify'); | ||||
const frappe_html = require('./frappe-html-plugin'); | const frappe_html = require('./frappe-html-plugin'); | ||||
@@ -17,7 +17,7 @@ const { | |||||
bench_path, | bench_path, | ||||
get_public_path, | get_public_path, | ||||
get_app_path, | get_app_path, | ||||
delete_file, | |||||
get_build_json | |||||
} = require('./rollup.utils'); | } = require('./rollup.utils'); | ||||
function get_rollup_options(output_file, input_files) { | function get_rollup_options(output_file, input_files) { | ||||
@@ -36,17 +36,6 @@ function get_rollup_options_for_js(output_file, input_files) { | |||||
multi_entry(), | multi_entry(), | ||||
// .html -> .js | // .html -> .js | ||||
frappe_html(), | 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 | // ES6 -> ES5 | ||||
buble({ | buble({ | ||||
objectAssign: 'Object.assign', | objectAssign: 'Object.assign', | ||||
@@ -93,21 +82,20 @@ function get_rollup_options_for_js(output_file, input_files) { | |||||
function get_rollup_options_for_css(output_file, input_files) { | function get_rollup_options_for_css(output_file, input_files) { | ||||
const output_path = path.resolve(assets_path, output_file); | const output_path = path.resolve(assets_path, output_file); | ||||
// clear css file to avoid appending problem | |||||
delete_file(output_path); | |||||
const plugins = [ | const plugins = [ | ||||
// enables array of inputs | // enables array of inputs | ||||
multi_entry(), | multi_entry(), | ||||
// less -> css | // 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')] | |||||
postcss({ | |||||
extract: output_path, | |||||
use: [['less', { | |||||
// import other less/css files starting from these folders | |||||
paths: [ | |||||
path.resolve(get_public_path('frappe'), 'less') | |||||
] | |||||
}]], | |||||
include: [path.resolve(bench_path, '**/*.less'), path.resolve(bench_path, '**/*.css')], | |||||
minimize: production | |||||
}) | }) | ||||
]; | ]; | ||||
@@ -131,6 +119,30 @@ function get_rollup_options_for_css(output_file, input_files) { | |||||
}; | }; | ||||
} | } | ||||
function get_options_for(app) { | |||||
const build_json = get_build_json(app); | |||||
if (!build_json) return []; | |||||
return Object.keys(build_json) | |||||
.map(output_file => { | |||||
if (output_file.endsWith('libs.min.js')) return null; | |||||
const input_files = build_json[output_file] | |||||
.map(input_file => { | |||||
let prefix = get_app_path(app); | |||||
if (input_file.startsWith('node_modules/')) { | |||||
prefix = path.resolve(get_app_path(app), '..'); | |||||
} | |||||
return path.resolve(prefix, input_file); | |||||
}); | |||||
return Object.assign( | |||||
get_rollup_options(output_file, input_files), { | |||||
output_file | |||||
}); | |||||
}) | |||||
.filter(Boolean); | |||||
} | |||||
module.exports = { | module.exports = { | ||||
get_rollup_options | |||||
get_options_for | |||||
}; | }; |
@@ -23,4 +23,4 @@ module.exports = function frappe_html() { | |||||
`; | `; | ||||
} | } | ||||
}; | }; | ||||
}; | |||||
}; |
@@ -3,13 +3,11 @@ const chalk = require('chalk'); | |||||
const rollup = require('rollup'); | const rollup = require('rollup'); | ||||
const log = console.log; // eslint-disable-line | const log = console.log; // eslint-disable-line | ||||
const { | const { | ||||
apps_list, | |||||
get_app_path, | |||||
get_build_json | |||||
apps_list | |||||
} = require('./rollup.utils'); | } = require('./rollup.utils'); | ||||
const { | const { | ||||
get_rollup_options | |||||
get_options_for | |||||
} = require('./config'); | } = require('./config'); | ||||
watch_assets(); | watch_assets(); | ||||
@@ -24,36 +22,42 @@ function watch_assets() { | |||||
watcher.on('event', event => { | watcher.on('event', event => { | ||||
switch(event.code) { | switch(event.code) { | ||||
case 'START': | |||||
case 'START': { | |||||
log(chalk.yellow(`\nWatching...`)); | log(chalk.yellow(`\nWatching...`)); | ||||
break; | break; | ||||
} | |||||
case 'BUNDLE_START': | |||||
log('Rebuilding', path.basename(event.output[0])); | |||||
case 'BUNDLE_START': { | |||||
const output = event.output[0]; | |||||
if (output.endsWith('.js')) { | |||||
log('Rebuilding', path.basename(event.output[0])); | |||||
} | |||||
break; | break; | ||||
} | |||||
default: | |||||
break; | |||||
default: break; | |||||
} | } | ||||
}); | }); | ||||
} | } | ||||
function get_watch_options(app) { | 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); | |||||
if (output_file.endsWith('libs.min.js')) return; | |||||
const options = get_options_for(app); | |||||
return Object.assign({}, inputOptions, { | |||||
output: outputOptions | |||||
}); | |||||
}).filter(Boolean); | |||||
return options.map(({ inputOptions, outputOptions, output_file}) => { | |||||
return Object.assign({}, inputOptions, { | |||||
output: outputOptions, | |||||
plugins: [log_css_change({output: output_file})].concat(inputOptions.plugins) | |||||
}); | |||||
}); | |||||
} | |||||
return watchOptions; | |||||
function log_css_change({output}) { | |||||
return { | |||||
name: 'log-css-change', | |||||
ongenerate() { | |||||
if (!output.endsWith('.css')) return null; | |||||
log('Rebuilding', path.basename(output)); | |||||
return null; | |||||
} | |||||
}; | |||||
} | } |