Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

220 linhas
5.0 KiB

  1. let path = require("path");
  2. let fs = require("fs");
  3. let glob = require("fast-glob");
  4. let esbuild = require("esbuild");
  5. let vue = require("esbuild-vue");
  6. let cliui = require("cliui")();
  7. let chalk = require("chalk");
  8. let html_plugin = require("./esbuild-plugin-html");
  9. let postCssPlugin = require("esbuild-plugin-postcss2").default;
  10. let ignore_assets = require("./ignore-assets");
  11. let sass_options = require("./sass_options");
  12. let {
  13. app_list,
  14. assets_path,
  15. apps_path,
  16. get_app_path,
  17. get_public_path,
  18. get_cli_arg
  19. } = require("./utils");
  20. const TOTAL_BUILD_TIME = `${chalk.black.bgGreen(" DONE ")} Total Build Time`;
  21. const WATCH_MODE = get_cli_arg("watch");
  22. const NODE_PATHS = [].concat(
  23. // node_modules of apps directly importable
  24. app_list
  25. .map(app => path.resolve(get_app_path(app), "../node_modules"))
  26. .filter(fs.existsSync),
  27. // import js file of any app if you provide the full path
  28. app_list
  29. .map(app => path.resolve(get_app_path(app), ".."))
  30. .filter(fs.existsSync)
  31. );
  32. (async function() {
  33. let apps = app_list;
  34. let apps_arg = get_cli_arg("apps");
  35. if (apps_arg) {
  36. apps = apps_arg.split(",");
  37. }
  38. console.time(TOTAL_BUILD_TIME);
  39. build_assets_for_apps(apps)
  40. .then(() => {
  41. console.timeEnd(TOTAL_BUILD_TIME);
  42. console.log();
  43. if (WATCH_MODE) {
  44. console.log('Watching for changes...')
  45. }
  46. })
  47. .catch(() => {
  48. let error = chalk.white.bgRed(" ERROR ");
  49. console.error(`${error} There were some problems during build`);
  50. });
  51. })();
  52. function build_assets_for_apps(apps) {
  53. let { include_patterns, ignore_patterns } = get_files_to_build(apps);
  54. return glob(include_patterns, { ignore: ignore_patterns }).then(files => {
  55. let output_path = assets_path;
  56. let file_map = {};
  57. for (let file of files) {
  58. let relative_app_path = path.relative(apps_path, file);
  59. let app = relative_app_path.split(path.sep)[0];
  60. let extension = path.extname(file);
  61. let output_name = path.basename(file, extension);
  62. if (
  63. [".css", ".scss", ".less", ".sass", ".styl"].includes(extension)
  64. ) {
  65. output_name = path.join("css", output_name);
  66. } else if ([".js", ".ts"].includes(extension)) {
  67. output_name = path.join("js", output_name);
  68. }
  69. output_name = path.join(app, "dist", output_name);
  70. if (Object.keys(file_map).includes(output_name)) {
  71. console.warn(
  72. `Duplicate output file ${output_name} generated from ${file}`
  73. );
  74. }
  75. file_map[output_name] = file;
  76. }
  77. return build_files({
  78. files: file_map,
  79. outdir: output_path
  80. });
  81. });
  82. }
  83. function get_files_to_build(apps) {
  84. let include_patterns = [];
  85. let ignore_patterns = [];
  86. for (let app of apps) {
  87. let public_path = get_public_path(app);
  88. include_patterns.push(
  89. path.resolve(
  90. public_path,
  91. "**",
  92. "*.bundle.{js,ts,css,sass,scss,less,styl}"
  93. )
  94. );
  95. ignore_patterns.push(
  96. path.resolve(public_path, "node_modules"),
  97. path.resolve(public_path, "dist")
  98. );
  99. }
  100. return {
  101. include_patterns,
  102. ignore_patterns
  103. };
  104. }
  105. function build_files({ files, outdir }) {
  106. return esbuild
  107. .build({
  108. entryPoints: files,
  109. outdir,
  110. sourcemap: true,
  111. bundle: true,
  112. metafile: true,
  113. // minify: true,
  114. nodePaths: NODE_PATHS,
  115. define: {
  116. "process.env.NODE_ENV": "'development'"
  117. },
  118. plugins: [
  119. html_plugin,
  120. ignore_assets,
  121. vue(),
  122. postCssPlugin({
  123. plugins: [require("autoprefixer")],
  124. sassOptions: sass_options
  125. })
  126. ],
  127. watch: WATCH_MODE
  128. ? {
  129. onRebuild(error, result) {
  130. if (error)
  131. console.error("watch build failed:", error);
  132. else {
  133. console.log(`${new Date().toLocaleTimeString()}: Compiled changes...`)
  134. // log_build_meta(result.metafile);
  135. }
  136. }
  137. }
  138. : null
  139. })
  140. .then(result => {
  141. log_build_meta(result.metafile);
  142. });
  143. }
  144. function log_build_meta(metafile) {
  145. let column_widths = [40, 20];
  146. cliui.div(
  147. {
  148. text: chalk.cyan.bold("File"),
  149. width: column_widths[0]
  150. },
  151. {
  152. text: chalk.cyan.bold("Size"),
  153. width: column_widths[1]
  154. }
  155. );
  156. cliui.div("");
  157. let output_by_dist_path = {};
  158. for (let outfile in metafile.outputs) {
  159. if (outfile.endsWith(".map")) continue;
  160. let data = metafile.outputs[outfile];
  161. outfile = path.resolve(outfile);
  162. outfile = path.relative(assets_path, outfile);
  163. let filename = path.basename(outfile);
  164. let dist_path = outfile.replace(filename, "");
  165. output_by_dist_path[dist_path] = output_by_dist_path[dist_path] || [];
  166. output_by_dist_path[dist_path].push({
  167. name: filename,
  168. size: (data.bytes / 1000).toFixed(2) + " Kb"
  169. });
  170. }
  171. for (let dist_path in output_by_dist_path) {
  172. let files = output_by_dist_path[dist_path];
  173. cliui.div({
  174. text: dist_path,
  175. width: column_widths[0]
  176. });
  177. for (let i in files) {
  178. let file = files[i];
  179. let branch = "";
  180. if (i < files.length - 1) {
  181. branch = "├─ ";
  182. } else {
  183. branch = "└─ ";
  184. }
  185. let color = file.name.endsWith(".js") ? "green" : "blue";
  186. cliui.div(
  187. {
  188. text: branch + chalk[color]("" + file.name),
  189. width: column_widths[0]
  190. },
  191. {
  192. text: file.size,
  193. width: column_widths[1]
  194. }
  195. );
  196. }
  197. cliui.div("");
  198. }
  199. console.log(cliui.toString());
  200. }