compile_js.gni 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. # Copyright 2017 The Chromium Authors. All rights reserved.
  2. # Use of this source code is governed by a BSD-style license that can be
  3. # found in the LICENSE file.
  4. import("//third_party/closure_compiler/closure_args.gni")
  5. declare_args() {
  6. # Enable closure type-checking for Chrome's web technology-based UI. This
  7. # enables the webui_closure_compile target which does a no-op without this
  8. # flag enabled. Requires Java.
  9. enable_js_type_check = is_chromeos || is_linux || is_android
  10. }
  11. script_path = "//third_party/closure_compiler"
  12. compiler_path = "$script_path/compiler/compiler.jar"
  13. externs_path = "$script_path/externs"
  14. interfaces_path = "$script_path/interfaces"
  15. chrome_externs = "$externs_path/chrome.js"
  16. polymer_externs = "$externs_path/polymer-1.0.js"
  17. # Defines a target that creates an ordering for .js files to be used by
  18. # js_binary to compile.
  19. #
  20. # Variables:
  21. # sources:
  22. # List of Javascript files to include in the library. Uses target_name.js by
  23. # default.
  24. #
  25. # deps:
  26. # List of js_library targets to depend on
  27. #
  28. # extra_deps:
  29. # List of any other rules to depend on. E.g. a rule that generates js source
  30. # files
  31. #
  32. # extra_public_deps
  33. # List of other targets to expose as public dependencies.
  34. #
  35. # externs_list:
  36. # A list of .js files to pass to the compiler as externs
  37. #
  38. # extra_sources:
  39. # A list of .js files to pass to the compiler as interfaces
  40. #
  41. # Example:
  42. # js_library("apple_tree") {
  43. # sources = ["tree_main.js"]
  44. # deps = [
  45. # ":branch",
  46. # ":trunk",
  47. # ":root",
  48. # ]
  49. # }
  50. template("js_library") {
  51. action(target_name) {
  52. script = "$script_path/js_library.py"
  53. forward_variables_from(invoker,
  54. [
  55. "deps",
  56. "externs_list",
  57. "extra_deps",
  58. "extra_public_deps",
  59. "extra_sources",
  60. "sources",
  61. "testonly",
  62. "visibility",
  63. ])
  64. inputs = [ "$script_path/compiler.py" ]
  65. output_file = "$target_gen_dir/$target_name.js_library"
  66. outputs = [ output_file ]
  67. args = [ "--output" ] + [ rebase_path(output_file, root_build_dir) ]
  68. if (!defined(sources)) {
  69. sources = [ target_name + ".js" ]
  70. }
  71. args += [ "--sources" ] + rebase_path(sources, root_build_dir)
  72. if (defined(extra_sources)) {
  73. args += rebase_path(extra_sources, root_build_dir)
  74. sources += extra_sources
  75. }
  76. if (defined(deps)) {
  77. args += [ "--deps" ]
  78. foreach(dep, deps) {
  79. # Get the output path for each dep
  80. dep_gen_dir = get_label_info(dep, "target_gen_dir")
  81. dep_name = get_label_info(dep, "name")
  82. dep_output_path = "$dep_gen_dir/$dep_name.js_library"
  83. args += [ rebase_path(dep_output_path, root_build_dir) ]
  84. }
  85. }
  86. if (defined(externs_list)) {
  87. args += [ "--externs" ] + rebase_path(externs_list, root_build_dir)
  88. sources += externs_list
  89. }
  90. if (defined(extra_deps)) {
  91. if (!defined(deps)) {
  92. deps = []
  93. }
  94. deps += extra_deps
  95. }
  96. if (defined(extra_public_deps)) {
  97. public_deps = extra_public_deps
  98. }
  99. }
  100. }
  101. # Defines a target that compiles javascript files using the Closure compiler.
  102. # This will produce a minified javascript output file. Additional checks and
  103. # optimizations can be configured using the closure_flags attribute.
  104. #
  105. # Variables:
  106. # sources:
  107. # List of .js files to compile. Will be target_name.js by default. Use
  108. # sources = [] to specify no input files (when making a target that just
  109. # group compiles other targets, for example).
  110. #
  111. # deps:
  112. # List of js_library rules to depend on
  113. #
  114. # outputs:
  115. # If chunks is not specified, a file to write the compiled .js to.
  116. # If chunks is specified, a directory to write the compiled .js to.
  117. # Only takes in a single file or directory, but must be placed in a list.
  118. #
  119. # bootstrap_file:
  120. # A .js files to include before all others
  121. #
  122. # config_files:
  123. # A list of .js files to include after the bootstrap_file but before all
  124. # others
  125. #
  126. # closure_flags:
  127. # A list of custom flags to pass to the Closure compiler. Do not include
  128. # the leading dashes
  129. #
  130. # externs_list:
  131. # A list of .js files to pass to the compiler as externs
  132. #
  133. # chunks:
  134. # Unused in chromium/src but used downstream.
  135. # A boolean indicating that a chunk should be created for each input file
  136. # (or target_name.js), along with a common_chunk.js for shared code.
  137. # Requires outputs refer to a directory and chunk_suffix be provided.
  138. #
  139. # chunk_suffix:
  140. # Unused in chromium/src but used downstream.
  141. # The suffix appended to a source when naming a chunk, since it may not
  142. # have the same name as the source. By default, creates target_name_chunk.js.
  143. #
  144. # Example:
  145. # js_binary("tree") {
  146. # sources = ["tree_main.js"]
  147. # deps = [":apple_tree"]
  148. # outputs = [ "$target_gen_dir/tree.js" ]
  149. # bootstrap_file = "bootstrap.js"
  150. # config_files = [
  151. # "config1.js",
  152. # "config2.js",
  153. # ]
  154. # closure_flags = ["jscomp_error=undefinedVars"]
  155. # externs_list = [ "externs.js" ]
  156. # }
  157. template("js_binary") {
  158. action(target_name) {
  159. script = "$script_path/js_binary.py"
  160. forward_variables_from(invoker,
  161. [
  162. "bootstrap_file",
  163. "checks_only",
  164. "chunks",
  165. "chunk_suffix",
  166. "closure_flags",
  167. "config_files",
  168. "deps",
  169. "externs_list",
  170. "extra_deps",
  171. "is_polymer3",
  172. "outputs",
  173. "sources",
  174. "testonly",
  175. "uses_legacy_modules",
  176. ])
  177. args = [
  178. "--compiler",
  179. rebase_path(compiler_path, root_build_dir),
  180. ]
  181. if (!defined(outputs)) {
  182. if (defined(chunks) && chunks) {
  183. outputs = [ "$target_gen_dir/" ]
  184. } else {
  185. outputs = [ "$target_gen_dir/$target_name.js" ]
  186. }
  187. }
  188. args += [ "--output" ] + rebase_path(outputs, root_build_dir)
  189. if (!defined(sources)) {
  190. sources = [ "$target_name.js" ]
  191. }
  192. if (defined(deps)) {
  193. args += [ "--deps" ]
  194. foreach(dep, deps) {
  195. # Get the output path for each dep
  196. dep_gen_dir = get_label_info(dep, "target_gen_dir")
  197. dep_name = get_label_info(dep, "name")
  198. dep_output_path = "$dep_gen_dir/$dep_name.js_library"
  199. args += [ rebase_path(dep_output_path, root_build_dir) ]
  200. }
  201. }
  202. args += [ "--sources" ] + rebase_path(sources, root_build_dir)
  203. if (defined(bootstrap_file)) {
  204. args += [
  205. "--bootstrap",
  206. rebase_path(bootstrap_file, root_build_dir),
  207. ]
  208. sources += [ bootstrap_file ]
  209. }
  210. if (defined(config_files)) {
  211. args += [ "--config" ] + rebase_path(config_files, root_build_dir)
  212. sources += config_files
  213. }
  214. if (defined(chunks) && chunks) {
  215. args += [ "--chunks" ]
  216. assert(defined(chunk_suffix), "Need chunk_suffix with chunks")
  217. args += [
  218. "--chunk_suffix",
  219. chunk_suffix,
  220. ]
  221. }
  222. if (defined(checks_only) && checks_only) {
  223. args += [ "--checks-only" ]
  224. }
  225. # |minifying_closure_args| from
  226. # //third_party/closure_compiler/closure_args.gni
  227. if (!defined(closure_flags)) {
  228. closure_flags = default_closure_args
  229. }
  230. uses_legacy_modules = defined(uses_legacy_modules) && uses_legacy_modules
  231. if (!uses_legacy_modules) {
  232. closure_flags += js_modules_args
  233. } else {
  234. closure_flags += legacy_modules_args
  235. }
  236. is_polymer3 = defined(is_polymer3) && is_polymer3
  237. assert(!is_polymer3 || !uses_legacy_modules)
  238. if (is_polymer3) {
  239. closure_flags += polymer3_args
  240. }
  241. args += [ "--flags" ] + closure_flags
  242. args += [
  243. "--externs",
  244. rebase_path("$chrome_externs", root_build_dir),
  245. ]
  246. inputs = [
  247. "$script_path/closure_args.gni",
  248. chrome_externs,
  249. compiler_path,
  250. ]
  251. # |polymer_externs| should only be added for Polymer versions 1 and 2. For
  252. # Polymer3, Polymer sources are directly passed to the compiler instead.
  253. if (!is_polymer3) {
  254. args += [ rebase_path("$polymer_externs", root_build_dir) ]
  255. inputs += [ polymer_externs ]
  256. }
  257. if (defined(externs_list)) {
  258. args += rebase_path(externs_list, root_build_dir)
  259. sources += externs_list
  260. }
  261. if (defined(extra_deps)) {
  262. if (!defined(deps)) {
  263. deps = []
  264. }
  265. deps += extra_deps
  266. }
  267. }
  268. }
  269. # Defines a target that compiles a group of js_library targets.
  270. template("js_type_check") {
  271. if (enable_js_type_check) {
  272. js_binary(target_name) {
  273. sources = []
  274. checks_only = true
  275. forward_variables_from(invoker,
  276. [
  277. "closure_flags",
  278. "deps",
  279. "is_polymer3",
  280. "testonly",
  281. "uses_legacy_modules",
  282. ])
  283. }
  284. } else {
  285. not_needed(invoker, "*")
  286. group(target_name) {
  287. }
  288. }
  289. }
  290. # These externs files depend on each other (often in a cyclical way), and
  291. # therefore makes more sense to add all of them as a dependency together.
  292. chrome_extension_public_externs = [
  293. "$externs_path/events.js",
  294. "$externs_path/extension_types.js",
  295. "$externs_path/runtime.js",
  296. "$externs_path/tabs.js",
  297. "$externs_path/windows.js",
  298. ]