As a Rails developer, you should have worked with Sprocket to deal with front-end resources. This article highlights a key difference between
require is used, Sprocket searches the file from search paths. You can find out the search paths by inspecting
Rails.application.config.assets.paths in Rails console. The search starts from the first path in the list to the last one until the required file is found. In contrast, when
require_tree is used, Sprocket gets all the files from the relative directory specified in the argument, and these files are required in alphabetical order.
As a result, we can see that Sprocket loads file in different ways between
//= require foo //= require_tree .
The gem require
foo.js first because it defines a function
bar did not meet my requirements, so I decided to overwrite it. I wrote another
foo.js with a new implementation of function
bar, and put the new
//= require foo loads
foo.js from search paths, and the path
foo.js would be loaded instead of the original one, and the new function
bar should take effect.
However, I noticed that the new function
bar did not take effect. Moreover, I found that both original and new
foo.js were loaded. I spent a lot of time to troubleshoot, and finally I realized that
//= require foo loaded the new
//= require_tree . loaded the original one from the specified directory. The new
foo.js was loaded before the original one, so the bar function in the original
foo.js took effect.
Finally, I solved it by renamed the new
foo2.js, and added a
//= require foo2 at the bottom of
application.js in the application. It is working because the
bar function in
foo2.js is loaded later than the original
bar function, though this solution is not clean. Anyway, this is a good lesson to understand the difference between
require_tree in Sprocket and be aware of it in future.