summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke "Jared" Bennett <lbennett@gitlab.com>2017-05-09 18:59:53 +0100
committerLuke "Jared" Bennett <lbennett@gitlab.com>2017-05-09 18:59:53 +0100
commit213c7dfc848631a32b1b38981375b07ca51925c2 (patch)
tree497e6e2e2dd0c5f4dc1439ef40322ad164eb29d5
parent95920a9f9868a8e89541fd9bc346ffb505a42272 (diff)
downloadgitlab-ce-add-bundle-linter-to-check-for-vue-in-main.tar.gz
Improved bundles check to traverse all parent bundles and pretty print the tree path that involves main.js and vue.esm.jsadd-bundle-linter-to-check-for-vue-in-main
-rw-r--r--.gitlab-ci.yml3
-rw-r--r--lib/tasks/js_bundles_check.rake84
-rw-r--r--lib/tasks/lint.rake4
3 files changed, 81 insertions, 10 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index b4c7ec06399..e483f8d448e 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -409,8 +409,7 @@ rake gitlab:assets:compile:
SKIP_STORAGE_VALIDATION: "true"
WEBPACK_REPORT: "true"
script:
- - bundle exec rake yarn:install gitlab:assets:compile
- - bundle exec rake lint:js_bundles
+ - bundle exec rake yarn:install gitlab:assets:compile lint:js_bundles
artifacts:
name: webpack-report
expire_in: 31d
diff --git a/lib/tasks/js_bundles_check.rake b/lib/tasks/js_bundles_check.rake
index c90b1dab114..4cb82e076fd 100644
--- a/lib/tasks/js_bundles_check.rake
+++ b/lib/tasks/js_bundles_check.rake
@@ -2,11 +2,85 @@ require 'json'
desc 'GitLab | Check JavaScript bundle files for suboptimal bundling'
task :js_bundles_check do
- bundle_stats_file = File.read('./webpack-report/stats.json')
- bundle_stats = JSON.parse(bundle_stats_file)
+ js_bundle_checker = JsBundleChecker.new('./webpack-report/stats.json')
- vue_module = bundle_stats['modules'].find { |bundle_module| bundle_module['identifier'].end_with?('vue.esm.js') }
- main_bundle = bundle_stats['chunks'].find { |chunk| chunk['names'].include?('main') }
+ causal_factor_tree, target_node = js_bundle_checker.check_chunk_for('main', './app/assets/javascripts/main.js', './~/vue/dist/vue.esm.js')
- abort('vue.esm.js found within main.js') if vue_module['chunks'].include?(main_bundle['id'])
+ next if causal_factor_tree.nil?
+
+ abort("\n\nvue.esm.js module found within main.js bundle.\n\n#{target_node[:dependency_text]}\n\n")
+end
+
+class JsBundleChecker
+ def initialize(stats_file)
+ @stats_file = stats_file
+ end
+
+ def check_chunk_for(chunk_name, bundle_name, module_name)
+ parse_bundle_stats
+
+ chunk = find_chunk(chunk_name)
+ the_module = find_module(module_name)
+
+ return [nil, nil] unless is_module_in_chunk?(chunk, the_module)
+
+ build_causal_factor_tree(the_module, bundle_name)
+ end
+
+ def is_module_in_chunk?(chunk, the_module)
+ the_module['chunks'].include?(chunk['id'])
+ end
+
+ private
+
+ def parse_bundle_stats
+ bundle_stats_file = File.read(@stats_file)
+
+ @bundle_stats = JSON.parse(bundle_stats_file)
+ end
+
+ def find_module(module_name)
+ @bundle_stats['modules'].find { |bundle_module| bundle_module['name'] == module_name }
+ end
+
+ def find_chunk(chunk_name)
+ @bundle_stats['chunks'].find { |chunk| chunk['names'].include?(chunk_name) }
+ end
+
+ def build_causal_factor_tree(root_module, target_bundle_name)
+ root = create_node(root_module)
+
+ build_parent_nodes(root, target_bundle_name)
+ end
+
+ def build_parent_nodes(current_node, target_bundle_name, target_node = nil)
+ current_node[:module]['reasons'].each do |parent|
+ parent_module = find_module(parent['moduleName'])
+
+ parent_node = create_node(parent_module, current_node)
+
+ target_node = parent_node if parent_node[:name] == target_bundle_name
+
+ parent_node, target_node = build_parent_nodes(parent_node, target_bundle_name, target_node)
+
+ current_node[:parents] = current_node[:parents].push(parent_node)
+ end
+
+ [current_node, target_node]
+ end
+
+ def create_node(the_module, child_module = nil)
+ {
+ name: the_module['name'],
+ module: the_module,
+ parents: [],
+ dependency_text: get_dependency_text(the_module, child_module)
+ }
+ end
+
+ def get_dependency_text(parent_module, child_module)
+ return parent_module['name'] if child_module.nil?
+
+ "#{parent_module['name']}\n ↑\n#{child_module[:dependency_text]}"
+ end
end
diff --git a/lib/tasks/lint.rake b/lib/tasks/lint.rake
index a6f2602a88f..cb170f2684e 100644
--- a/lib/tasks/lint.rake
+++ b/lib/tasks/lint.rake
@@ -6,8 +6,6 @@ unless Rails.env.production?
end
desc 'GitLab | lint | Check JavaScript bundle files for suboptimal bundling'
- task :js_bundles do
- Rake::Task['js_bundles_check'].invoke
- end
+ task js_bundles: ['rake:js_bundles_check']
end
end