fnando/i18n-js

Missing new translation after a new locale added

elpic opened this issue ยท 23 comments

After I made a deploy with capistrano all the new translations are not available. To make it work I should clear the cache and redeploy

Version? Using a branch?
What is your app's setup with this gem?

Version = i18n-js (2.1.2)

rails (4.0.1)

On the application.js

//= require i18n
//= require i18n/translations

Can you try master?
There are many bug fixes but not released yet.
Be careful that it contains "to be 3.0.0", which might break your app.

Same problem here with rails 4.0.4 and i18n-js 2.1.2.
I'm using asset precompile mode.

@micred Please try 3.0.0.rc6

nfm commented

@PikachuEXE I've had this issue in the past too, and just ran into it again.

I'm using Rails 4.0.9 with i18n-js 3.0.0.rc5. I updated to 3.0.0.rc6 and am still not seeing new locale files taken into account when I run bundle exec rake assets:precompile on deploy.

Here's a sample app that reproduces the issue: https://github.com/nfm/i18n-precompile-issue

It's just a vanilla Rails 4.0.9 app with i18n-js 3.0.0.rc6 added to the Gemfile. To reproduce the issue, run bundle exec rake assets:precompile. This will generate the initial application.js, which correctly includes the contents of config/locales/en.yml.

Now move test.yml into config/locales and re-run bundle exec rake assets:precompile. This doesn't regenerate application.js.

If you modify config/locales/en.yml, and re-run bundle exec rake assets:precompile, the changes made to that file (and the new test.yml file) get included. But you have to touch an existing locale for new locales to be included in application.js.

I ran the same reproduction against i18n-js master (currently at 0ba4000) and saw the same result.

@nfm Thanks for the sample app!
Make it much easier to reproduce the problem.
I am working on it.

@PikachuEXE thanks for suggesting a new issue. If you need any help, just let me know the direction and I can work on PR.

The preprocessor is not even run after the asset (i.e, the i18n/filtered.erb file) is precompiled already
Here is the flow:

  1. You start precompile without test.yml
    1a. Sprocket goes through all files, including i18n/filtered.erb
    1b. Sprocket cached the fingerprint of the content of i18n/filtered.erb, and run the preprocessor
    1c. The preprocessor said this i18n/filtered.erb depend on I18n.load_path, which includes the existing locale files: ["en.yml"]
  2. You start precompile after adding test.yml
    2a. Sprocket goes through all files, including i18n/filtered.erb
    2b. Sprocket found that the i18n/filtered.erb is already cached, and the fingerprint is unchanged, and all the files it depends on (["en.yml"]) has not changed, so just use the cache version

So this "bug" is by design, to make it detect the test.yml, either:
A. They have to run preprocessor everytime before using a cached version
B. You have to make some change to any existing file

Summary: by design of Sprocket, it does not detect new files (unless cache cleared)

I haven't tried depend_on using a directory path yet

OK depend_on just does not work on directory anyway.
Not sure how to fix this

I have added the workaround in README in bfa489c
If there is a way to workaround this (not manually) please reopen

nfm commented

Thanks for looking into this @PikachuEXE. Not sure if there's a way to make Sprockets do what we want :(

I'd recommend not running rake assets:clobber in production as that will trash fingerprinted assets from previous releases, which might cause issues if for example you've served up cached pages with old asset fingerprints in them.

@nfm Good point.
Added a note in bebeb13
I don't think the design of sprockets will be changed just for this issue.

The problem happens on heroku where you can't run tmp:cache:clear before the assets compilation

@alex88 You can check https://github.com/fnando/i18n-js#known-issues
which includes a method: change something in existing locale, like adding a dummy translation entry

I ended changing the config.assets.version since it wasn't picking up any translation file change

I guess I should mention that too

@alex88 I have add your solution to README: fc1e52e
Thanks for your feedback!

Good! ;)

arion commented

Still had a problem with this. Capistrano task: (https://gist.github.com/arion/d1afafbe065d7d669ef9)

@arion
Have you tried rake tmp:cache:clear as well?
I am not sure what works for clearing sprockets cache.
It would be great if documentation links can be found.

I will reopen until you solve it

ryanb commented

This is an old issue, but thought I'd share my solution. While it isn't possible to add a directory using the //= depend_on directive in Sprockets, you can add it to the context directly which will cause it to detect new files. I'm doing this at the top of my own translations.js.erb asset file.

<%
  depend_on Rails.root.join("config", "locales").to_s
  Dir.glob(Rails.root.join("config", "locales", "**", "*.yml")) do |path|
    depend_on path
  end
%>

If you want to update this project, you could do this in the engine.rb preprocessor or in filtered.js.erb.