You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

194 line
4.7 KiB

  1. const path = require('path');
  2. const fs = require('fs');
  3. const touch = require('touch');
  4. const {
  5. get_build_json_path,
  6. get_app_path,
  7. apps_list,
  8. assets_path,
  9. get_public_path,
  10. bench_path,
  11. sites_path
  12. } = require('./rollup.utils');
  13. const less = require('rollup-plugin-less');
  14. const multi_entry = require('rollup-plugin-multi-entry');
  15. const commonjs = require('rollup-plugin-commonjs');
  16. const node_resolve = require('rollup-plugin-node-resolve');
  17. const buble = require('rollup-plugin-buble');
  18. const uglify = require('rollup-plugin-uglify');
  19. const frappe_html = require('./frappe-html-plugin');
  20. const production = process.env.FRAPPE_ENV === 'production';
  21. ensure_js_css_dirs();
  22. build_libs();
  23. function get_app_config(app) {
  24. const build_map = get_build_json(app);
  25. if (!build_map) return [];
  26. const js_config = Object.keys(build_map)
  27. .filter(output_file =>
  28. output_file.endsWith('.js') &&
  29. // libs is built separately (to be deprecated)
  30. !output_file.endsWith('libs.min.js')
  31. )
  32. .map(output_file => {
  33. const input_files = build_map[output_file].map(
  34. // make paths absolute
  35. input_path => path.resolve(get_app_path(app), input_path)
  36. );
  37. return get_js_config(output_file, input_files);
  38. });
  39. const less_config = Object.keys(build_map)
  40. .filter(output_file =>
  41. output_file.endsWith('.css')
  42. )
  43. .map(output_file => {
  44. const input_files = build_map[output_file].map(
  45. input_path => path.resolve(get_app_path(app), input_path)
  46. );
  47. return get_css_config(output_file, input_files);
  48. });
  49. return [].concat(js_config, less_config);
  50. }
  51. function get_js_config(output_file, input_files) {
  52. const css_output_file = path.resolve(assets_path, 'css', path.basename(output_file).split('.js')[0] + '.css');
  53. const plugins = [
  54. // enables array of inputs
  55. multi_entry(),
  56. // .html -> .js
  57. frappe_html(),
  58. // less -> css
  59. less({
  60. output: css_output_file,
  61. option: {
  62. // so that other .less files can import variables.less from frappe directly
  63. paths: [path.resolve(get_public_path('frappe'), 'less'), path.resolve(get_app_path('frappe'), '..')],
  64. compress: production
  65. },
  66. // include: [path.resolve(bench_path, '**/*.less'), path.resolve(bench_path, '**/*.css')],
  67. exclude: []
  68. }),
  69. // ES6 -> ES5
  70. buble({
  71. objectAssign: 'Object.assign',
  72. transforms: {
  73. dangerousForOf: true
  74. },
  75. exclude: [path.resolve(bench_path, '**/*.css'), path.resolve(bench_path, '**/*.less')]
  76. }),
  77. commonjs(),
  78. node_resolve(),
  79. production && uglify()
  80. ];
  81. return {
  82. input: input_files,
  83. plugins: plugins,
  84. output: {
  85. file: path.resolve(assets_path, output_file),
  86. format: 'iife',
  87. name: 'Rollup',
  88. globals: {
  89. 'jquery': 'window.jQuery'
  90. },
  91. sourcemap: true
  92. },
  93. context: 'window',
  94. external: ['jquery']
  95. };
  96. }
  97. function get_css_config(output_file, input_files) {
  98. const plugins = [
  99. // enables array of inputs
  100. multi_entry(),
  101. // less -> css
  102. less({
  103. output: path.resolve(assets_path, output_file),
  104. option: {
  105. // so that other .less files can import variables.less from frappe directly
  106. paths: [path.resolve(get_public_path('frappe'), 'less')],
  107. compress: production
  108. },
  109. include: [path.resolve(bench_path, '**/*.less'), path.resolve(bench_path, '**/*.css')]
  110. })
  111. ];
  112. return {
  113. input: input_files,
  114. plugins: plugins,
  115. output: {
  116. // this file is always empty, remove it later?
  117. file: path.resolve(assets_path, `css/rollup.manifest.css`),
  118. format: 'cjs',
  119. }
  120. };
  121. }
  122. function ensure_js_css_dirs() {
  123. const paths = [
  124. path.resolve(assets_path, 'js'),
  125. path.resolve(assets_path, 'css')
  126. ];
  127. paths.forEach(path => {
  128. if (!fs.existsSync(path)) {
  129. fs.mkdirSync(path);
  130. }
  131. });
  132. // clear files in css folder
  133. const css_path = path.resolve(assets_path, 'css');
  134. const files = fs.readdirSync(css_path);
  135. files.forEach(file => {
  136. fs.unlinkSync(path.resolve(css_path, file));
  137. });
  138. }
  139. function build_libs() {
  140. const libs_path = 'js/libs.min.js';
  141. const input_files = get_build_json('frappe')[libs_path];
  142. const libs_content = input_files.map(file_name => {
  143. const full_path = path.resolve(get_app_path('frappe'), file_name);
  144. return `/* ${file_name} */\n` + fs.readFileSync(full_path);
  145. }).join('\n\n');
  146. const target_path = path.resolve(assets_path, libs_path);
  147. fs.writeFileSync(target_path, libs_content);
  148. console.log('✨ Built libs.min.js'); // eslint-disable-line
  149. touch(path.join(sites_path, '.build'), { force: true });
  150. }
  151. function get_all_apps_config() {
  152. let configs = [];
  153. apps_list.forEach(app => {
  154. configs = configs.concat(get_app_config(app));
  155. });
  156. return configs;
  157. }
  158. function get_build_json(app) {
  159. try {
  160. return require(get_build_json_path(app));
  161. } catch (e) {
  162. // build.json does not exist
  163. return null;
  164. }
  165. }
  166. module.exports = get_all_apps_config();