webpacker:compile为何在javascript_pack_tag中插入特定主机名?
我来逐个解决你遇到的这些问题,都是Webpacker部署到Heroku时常见的坑:
1. 为什么生成的script标签里出现http://0.0.0.0:8080?
这个问题几乎可以肯定是你用了开发环境的配置来编译Webpack资源。开发环境下,Webpacker默认会指向本地的Webpack Dev Server地址(0.0.0.0:8080),而不是生成生产环境的静态资源路径。
你可以检查一下编译时的环境变量,比如是否在执行rake webpacker:compile时没有指定RAILS_ENV=production。如果本地编译后推送到Heroku,或者Heroku上的编译过程意外用了development环境,都会出现这个问题。
2. 如何配置Webpacker使用相对路径适配任意服务器?
要让javascript_pack_tag生成相对路径的script标签,你需要修改config/webpacker.yml里的生产环境配置:
打开config/webpacker.yml,找到production段,做以下调整:
- 将
public_host设置为空字符串(''),这样Webpacker不会在资源路径前添加主机名 - 确保
public_output_path设置为packs(默认就是这个),这样生成的路径是/packs/application-xxxx.js这种相对根目录的路径
示例配置片段:
production: <<: *default public_host: '' # 其他配置保持不变
这样javascript_pack_tag 'application'就会生成<script src="/packs/application-xxxx.js"></script>,适配任意服务器的主机名。
3. 为什么生成的标签没有过期哈希?
这同样是开发环境编译导致的——开发环境下Webpacker为了加快编译速度,不会生成带哈希的文件名。只有在production环境下编译,才会自动在文件名后添加内容哈希(比如application-abc123.js),用于缓存 Busting。
解决方法就是确保编译时使用production环境:
RAILS_ENV=production rake webpacker:compile
4. 如何访问Webpacker的配置?
Webpacker的核心配置文件是config/webpacker.yml,里面分development、test、production三个环境块,你可以直接编辑对应环境的参数。
另外,你也可以通过环境变量来覆盖配置,比如:
WEBPACKER_PUBLIC_HOST:覆盖public_host配置WEBPACKER_OUTPUT_PATH:覆盖public_output_path配置
比如在Heroku上,你可以用命令设置环境变量:
heroku config:set WEBPACKER_PUBLIC_HOST=''
5. 在Heroku部署流程中执行webpacker:compile是否是最佳实践?
是的,而且这其实是Heroku Ruby buildpack的默认行为!
当你部署Rails应用到Heroku时,buildpack会自动执行rake assets:precompile任务,而Webpacker已经把webpacker:compile整合到了assets:precompile流程中(只要你是Rails 5.1+版本)。所以你不需要手动设置,Heroku会自动在部署时用production环境编译Webpack资源。
如果你的应用没有自动执行这个任务,可能需要检查:
- 确认你的Rails版本支持Webpacker的整合(Rails 5.1+)
- 检查Heroku的build日志,看是否有
Running rake assets:precompile的步骤 - 如果需要手动指定,可以在
package.json的scripts里添加"heroku-postbuild": "RAILS_ENV=production rake webpacker:compile",不过一般不需要这么做
内容的提问来源于stack exchange,提问作者Louise

