【问题标题】:Asset compilation searching the wrong path for Webpacker config files资产编译搜索 Webpacker 配置文件的错误路径
【发布时间】:2020-08-05 02:48:36
【问题描述】:

我已将webpacker gem 添加到我的Rails 5.2 应用程序中,现在我正尝试将它部署到带有Capistrano 的服务器上。该过程在deploy:assets:precompile 步骤中失败,并显示以下错误消息:

DEBUG [f2c62805] Command: cd /var/www/myapp/releases/20200805023716 && ( export RAILS_ENV="production" RAILS_GROUPS="" ; /usr/local/rvm/bin/rvm 2.5.7 do bundle exec rake assets:precompile )

 DEBUG [f2c62805]       Compiling...

 DEBUG [f2c62805]       Compilation failed:

webpack config /var/www/myapp/shared/config/webpack/production.js not found, please run 'bundle exec rails webpacker:install' to install Webpacker with default configs or add the missing config file for your custom environment.

我不知道为什么它在 shared/config 文件夹中而不是新版本的文件夹中查找。大概我不希望我的配置被共享,以防我更改它并且未来的部署失败。在这种情况下,我的应用程序的当前版本可能会有不适合它的配置。

以下是一些相关的 Capistrano 配置:

set :config_files, ['config/boot.rb', 'config/database.yml', 'config/secrets.yml']
set :bin_files, ['bin/bundle', 'bin/delayed_job', 'bin/rails', 'bin/rake', 'bin/webpack']

# Tells Capistrano to store config/database.yml file inside a directory called /shared, which is meant for any files
# we want to persist between deploys
set :linked_files, fetch(:linked_files, []) + fetch(:config_files)

# Directories that are meant to persist between deploys, and they will also be stored inside /shared
set :linked_dirs, fetch(:linked_dirs, []).push('bin', 'log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system', 'public/uploads')

Sprockets 资产编译得很好。我试过在服务器上运行bundle exec rake assets:precompile,它确实在shared/config 文件夹中查找。我运行了--trace,发现它运行了webpacker:compile 步骤,这就是它失败的地方。

如何让它在当前版本的目录 (/var/www/myapp/releases/20200805023716/config/webpack/production.js) 中查找配置文件?

【问题讨论】:

    标签: ruby-on-rails capistrano webpacker


    【解决方案1】:

    我修好了!有两个问题:

    1. 共享目录中的bin 文件
    2. 在预编译资产之前不安装 yarn

    问题 #1:共享目录中的bin 文件

    我之前已将部署设置为将 bin 文件复制到 shared 目录,以便 delayed_job 可以运行。上传文件会自动将这些文件设置为可执行文件。到目前为止,这还不是问题。但是因为this line in Webpacker's compilation process,在编译webpack资产的时候就出问题了:

    stdout, stderr, status = Open3.capture3(
      webpack_env,
      "#{RbConfig.ruby} ./bin/webpack",
      chdir: File.expand_path(config.root_path)
    )
    

    由于我将所有bin 文件移动到shared 目录并且Capistrano 设置了符号链接,因此它将运行共享目录中的bin/webpack 文件。当该命令运行时,它会查找 Webpacker 配置文件的相对路径。鉴于上下文,这意味着它将在 /var/www/myapp/shared/config/webpack/production.js 而不是 /var/www/myapp/releases/20200805023716/config/webpack/production.js 中查找我的 webpack 配置文件。

    解决方法:停止将bin文件复制到shared目录下,设置为可执行

    为了解决这个问题,我从 Capistrano 部署脚本中删除了这一行:

    # config/deploy.rb
    set :bin_files, ['bin/bundle', 'bin/delayed_job', 'bin/rails', 'bin/rake', 'bin/webpack']
    

    然后我从链接目录中删除了bin

    # config/deploy.rb
    set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system', 'public/uploads')
    

    之后,Webpacker 会在预编译资产时查找正确的目录。现在,我需要解决可执行问题。我添加了一个新的 Capistrano 任务,我在 this SO answer 上找到了它:

    before "deploy:symlink:release", "deploy:ensure_bin_files_executable"
    
    namespace :deploy do
      desc 'Ensure that bin files are executable'
      task :ensure_bin_files_executable do
        on roles(:web) do
          within release_path do
            execute "cd #{release_path} && chmod +x bin/*"
          end
        end
      end
    end
    

    这使得bin/ 文件夹中的所有文件都成为当前版本的可执行文件。问题解决了!

    问题 #2:在预编译资产之前未安装 yarn

    解决第一个问题后,我在预编译资产时收到了这个错误:

    01:33 deploy:assets:precompile
      01 /usr/local/rvm/bin/rvm default do bundle exec rake assets:precompile
      01 Webpacker is installed ? ?
      01 Using /var/www/myapp/releases/20200805023716/config/webpacker.yml file for setting up webpack paths
      01 Compiling…
      01 Compilation failed:
      01 yarn run v1.13.0
      01 info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
      01
      01 warning package.json: No license field
      01 error Command "webpack" not found.
    
    解决方案:在预编译资产之前安装 yarn 包

    我意识到 Yarn 没有安装 webpack 包,所以我在 Webpacker Deployment document 上找到了这个有用的 Capistrano 任务:

    确保您在 :linked_dirs 中有 public/packs 和 node_modules

    append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/packs", ".bundle", "node_modules"
    

    如果你有 node_modules 添加到 :linked_dirs 你需要在 deploy:assets:precompile 之前运行 yarn install ,所以你可以在 deploy.rb 底部添加这段代码 sn-p

    before "deploy:assets:precompile", "deploy:yarn_install"
    
    namespace :deploy do
      desc "Run rake yarn install"
      task :yarn_install do
        on roles(:web) do
          within release_path do
            execute("cd #{release_path} && yarn install --silent --no-progress --no-audit --no-optional")
          end
        end
      end
    end
    

    添加后,我的部署很顺利!

    【讨论】:

    • @caraca 很高兴能帮上忙!我至少花了几天时间解决这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-07
    • 2014-07-06
    • 1970-01-01
    • 1970-01-01
    • 2020-02-19
    • 1970-01-01
    相关资源
    最近更新 更多