discourse/script/build_jsconfig.rb
David Taylor 93c67eeb4f
DEV: Consolidate and update jsconfig, and add types packages (#23824)
These updates significantly improve IDE tooling for imports across the Discourse core codebase, and also for framework packages. The `@types/ember-*` packages are a temporary solution until we get onto Ember 5, which ships its types in the main package.

The previous approach of having jsconfig files in each package directory did work, but once you start adding all the possible interlinks between them, we hit the file count limit of VSCode's tooling (because it counts every file for every jsconfig its referenced in). Having one file at the root means that a single file can apply to all core packages and plugins.

Long-term, to get the same functionality for all themes/plugins, we may need to look at building/publishing a Discourse types package which can be added to theme/plugin package.json files for development purposes.
2023-10-18 12:13:20 +01:00

65 lines
2.1 KiB
Ruby

# frozen_string_literal: true
require "pathname"
require "json"
Dir.chdir("#{__dir__}/..") # rubocop:disable Discourse/NoChdir because this is not part of the app
CORE_NAMESPACES = {
"discourse/*" => ["app/assets/javascripts/discourse/app"],
"discourse/tests/*" => ["app/assets/javascripts/discourse/tests"],
"discourse-common/*" => ["app/assets/javascripts/discourse-common/addon"],
"admin/*" => ["app/assets/javascripts/admin/addon"],
"wizard/*" => ["app/assets/javascripts/wizard/addon"],
"pretty-text/*" => ["app/assets/javascripts/pretty-text/addon"],
"select-kit/*" => ["app/assets/javascripts/select-kit/addon"],
"float-kit/*" => ["app/assets/javascripts/float-kit/addon"],
"truth-helpers/*" => ["app/assets/javascripts/truth-helpers/addon"],
"dialog-holder/*" => ["app/assets/javascripts/dialog-holder/addon"],
}
def relative(from, to)
relative_path = Pathname.new(to).relative_path_from(from).to_s
relative_path = "./#{relative_path}" if !relative_path.start_with?(".")
relative_path
end
def write_config(package_dir, extras: {})
package_dir = Pathname.new(package_dir)
namespaces = { **CORE_NAMESPACES, **extras }
config = {
"compilerOptions" => {
"target" => "es2021",
"module" => "esnext",
"moduleResolution" => "bundler",
"experimentalDecorators" => true,
"paths" => {
**namespaces
.map { |ns, paths| [ns, paths.map { |p| "#{relative(package_dir, p)}/*" }] }
.to_h,
},
},
"include" => namespaces.flat_map { |ns, paths| paths.map { |p| relative(package_dir, p) } },
}
output = <<~JSON
// This file was generated by scripts/build_jsconfig.rb
#{JSON.pretty_generate(config)}
JSON
File.write("#{package_dir}/jsconfig.json", output)
end
core_plugins = `git ls-files plugins/*/plugin.rb`.lines.map { |path| path.split("/")[1] }
plugin_configs =
core_plugins
.map do |name|
[
"discourse/plugins/#{name}/*",
["plugins/#{name}/assets/javascripts", "plugins/#{name}/test/javascripts"],
]
end
.to_h
write_config ".", extras: { **plugin_configs }