Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve errors blocking usage in a mountable Rails engine #1694

Merged
merged 13 commits into from
Aug 31, 2020
Merged
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/.bundle
/pkg
/test/mounted_app/test/dummy/log
/test/test_app/log
node_modules
.byebug_history
Expand Down
6 changes: 4 additions & 2 deletions lib/install/angular.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
say "Copying hello_angular app to #{Webpacker.config.source_path}"
directory "#{__dir__}/examples/angular/hello_angular", "#{Webpacker.config.source_path}/hello_angular"

say "Installing all angular dependencies"
run "yarn add core-js zone.js rxjs @angular/core @angular/common @angular/compiler @angular/platform-browser @angular/platform-browser-dynamic"
Dir.chdir(Rails.root) do
say "Installing all angular dependencies"
run "yarn add core-js zone.js rxjs @angular/core @angular/common @angular/compiler @angular/platform-browser @angular/platform-browser-dynamic"
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kevindew Do we need to do this? Is it not possible to use root package.json and yarn as a source of truth? But I see, what you mentioned in the description, in case someone wants to publish an engine package to npm.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest it's preferable to do this as it keeps the installation consistent to the Rails root (this would be a piece in a different place) and also if you have just a single package.json for both the Rails engine itself and the dummy app then they need to share dependencies when this may not makes sense (e.g. you wouldn't want to have a dependency on webpacker for your distributed engine JS files).

A nice thing though is that if you don't have a package.json in your Rails root then this will just use the global one for your application. So this dir change only prefers a package.json in your mounted app and will fallback to the root one if it doesn't exist.


if Rails::VERSION::MAJOR == 5 && Rails::VERSION::MINOR > 1
say "You need to enable unsafe-eval rule.", :yellow
Expand Down
6 changes: 4 additions & 2 deletions lib/install/coffee.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
copy_file "#{__dir__}/examples/coffee/hello_coffee.coffee",
"#{Webpacker.config.source_entry_path}/hello_coffee.coffee"

say "Installing all Coffeescript dependencies"
run "yarn add [email protected] coffee-loader"
Dir.chdir(Rails.root) do
say "Installing all Coffeescript dependencies"
run "yarn add [email protected] coffee-loader"
end

say "Webpacker now supports Coffeescript 🎉", :green
12 changes: 7 additions & 5 deletions lib/install/elm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@
copy_file "#{__dir__}/examples/elm/Main.elm",
"#{Webpacker.config.source_path}/Main.elm"

say "Installing all Elm dependencies"
run "yarn add elm elm-webpack-loader"
run "yarn add --dev elm-hot-webpack-loader"
run "yarn run elm init"
run "yarn run elm make #{Webpacker.config.source_path}/Main.elm"
Dir.chdir(Rails.root) do
say "Installing all Elm dependencies"
run "yarn add elm elm-webpack-loader"
run "yarn add --dev elm-hot-webpack-loader"
run "yarn run elm init"
run "yarn run elm make #{Webpacker.config.source_path}/Main.elm"
end

say "Updating webpack paths to include .elm file extension"
insert_into_file Webpacker.config.config_path, "- .elm\n".indent(4), after: /\s+extensions:\n/
Expand Down
6 changes: 4 additions & 2 deletions lib/install/erb.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
copy_file "#{__dir__}/examples/erb/hello_erb.js.erb",
"#{Webpacker.config.source_entry_path}/hello_erb.js.erb"

say "Installing all Erb dependencies"
run "yarn add rails-erb-loader"
Dir.chdir(Rails.root) do
say "Installing all Erb dependencies"
run "yarn add rails-erb-loader"
end

say "Webpacker now supports Erb in JS 🎉", :green
6 changes: 4 additions & 2 deletions lib/install/react.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
say "Updating webpack paths to include .jsx file extension"
insert_into_file Webpacker.config.config_path, "- .jsx\n".indent(4), after: /\s+extensions:\n/

say "Installing all react dependencies"
run "yarn add react react-dom @babel/preset-react prop-types babel-plugin-transform-react-remove-prop-types"
Dir.chdir(Rails.root) do
say "Installing all react dependencies"
run "yarn add react react-dom @babel/preset-react prop-types babel-plugin-transform-react-remove-prop-types"
end

say "Webpacker now supports react.js 🎉", :green
6 changes: 4 additions & 2 deletions lib/install/stimulus.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
say "Creating controllers directory"
directory "#{__dir__}/examples/stimulus/controllers", "#{Webpacker.config.source_path}/controllers"

say "Installing all Stimulus dependencies"
run "yarn add stimulus"
Dir.chdir(Rails.root) do
say "Installing all Stimulus dependencies"
run "yarn add stimulus"
end

say "Webpacker now supports Stimulus.js 🎉", :green
25 changes: 14 additions & 11 deletions lib/install/template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@

apply "#{__dir__}/binstubs.rb"

if File.exists?(".gitignore")
append_to_file ".gitignore" do
git_ignore_path = Rails.root.join(".gitignore")
if File.exists?(git_ignore_path)
append_to_file git_ignore_path do
"\n" +
"/public/packs\n" +
"/public/packs-test\n" +
Expand All @@ -28,16 +29,18 @@
end
end

if Webpacker::VERSION =~ /^[0-9]+\.[0-9]+\.[0-9]+$/
say "Installing all JavaScript dependencies [#{Webpacker::VERSION}]"
run "yarn add @rails/webpacker@#{Webpacker::VERSION}"
else
say "Installing all JavaScript dependencies [from prerelease rails/webpacker]"
run "yarn add @rails/webpacker@next"
end
Dir.chdir(Rails.root) do
if Webpacker::VERSION =~ /^[0-9]+\.[0-9]+\.[0-9]+$/
say "Installing all JavaScript dependencies [#{Webpacker::VERSION}]"
run "yarn add @rails/webpacker@#{Webpacker::VERSION}"
else
say "Installing all JavaScript dependencies [from prerelease rails/webpacker]"
run "yarn add @rails/webpacker@next"
end

say "Installing dev server for live reloading"
run "yarn add --dev webpack-dev-server"
say "Installing dev server for live reloading"
run "yarn add --dev webpack-dev-server"
end

insert_into_file Rails.root.join("package.json").to_s, before: /\n}\n*$/ do
<<~JSON.chomp
Expand Down
6 changes: 4 additions & 2 deletions lib/install/typescript.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@
copy_file "#{__dir__}/examples/typescript/hello_typescript.ts",
"#{Webpacker.config.source_entry_path}/hello_typescript.ts"

say "Installing all typescript dependencies"
run "yarn add typescript @babel/preset-typescript #{additional_packages}"
Dir.chdir(Rails.root) do
say "Installing all typescript dependencies"
run "yarn add typescript @babel/preset-typescript #{additional_packages}"
end

say "Webpacker now supports typescript 🎉", :green
6 changes: 4 additions & 2 deletions lib/install/vue.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@
copy_file "#{__dir__}/examples/vue/app.vue",
"#{Webpacker.config.source_path}/app.vue"

say "Installing all Vue dependencies"
run "yarn add vue vue-loader vue-template-compiler"
Dir.chdir(Rails.root) do
say "Installing all Vue dependencies"
run "yarn add vue vue-loader vue-template-compiler"
end

if Rails::VERSION::MAJOR == 5 && Rails::VERSION::MINOR > 1
say "You need to enable unsafe-eval rule.", :yellow
Expand Down
10 changes: 6 additions & 4 deletions lib/tasks/installers.rake
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,21 @@ dependencies = {
"Angular": [:typescript]
}

bin_path = ENV["BUNDLE_BIN"] || "./bin"
bin_path = ENV["BUNDLE_BIN"] || Rails.root.join("bin")

namespace :webpacker do
namespace :install do
installers.each do |name, task_name|
desc "Install everything needed for #{name}"
task task_name => ["webpacker:verify_install"] do
task task_name => ["webpacker:verify_install"] do |task|
prefix = task.name.split(/#|webpacker:install/).first

template = File.expand_path("../install/#{task_name}.rb", __dir__)
base_path =
if Rails::VERSION::MAJOR >= 5
"#{RbConfig.ruby} #{bin_path}/rails app:template"
"#{RbConfig.ruby} #{bin_path}/rails #{prefix}app:template"
else
"#{RbConfig.ruby} #{bin_path}/rake rails:template"
"#{RbConfig.ruby} #{bin_path}/rake #{prefix}rails:template"
end

dependencies[name] ||= []
Expand Down
10 changes: 6 additions & 4 deletions lib/tasks/webpacker/binstubs.rake
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
binstubs_template_path = File.expand_path("../../install/binstubs.rb", __dir__).freeze
bin_path = ENV["BUNDLE_BIN"] || "./bin"
bin_path = ENV["BUNDLE_BIN"] || Rails.root.join("bin")

namespace :webpacker do
desc "Installs Webpacker binstubs in this application"
task binstubs: [:check_node, :check_yarn] do
task binstubs: [:check_node, :check_yarn] do |task|
prefix = task.name.split(/#|webpacker:binstubs/).first

if Rails::VERSION::MAJOR >= 5
exec "#{RbConfig.ruby} #{bin_path}/rails app:template LOCATION=#{binstubs_template_path}"
exec "#{RbConfig.ruby} #{bin_path}/rails #{prefix}app:template LOCATION=#{binstubs_template_path}"
else
exec "#{RbConfig.ruby} #{bin_path}/rake rails:template LOCATION=#{binstubs_template_path}"
exec "#{RbConfig.ruby} #{bin_path}/rake #{prefix}rails:template LOCATION=#{binstubs_template_path}"
end
end
end
2 changes: 1 addition & 1 deletion lib/tasks/webpacker/check_binstubs.rake
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
namespace :webpacker do
desc "Verifies that webpack & webpack-dev-server are present."
task :check_binstubs do
unless File.exist?("bin/webpack")
unless File.exist?(Rails.root.join("bin/webpack"))
$stderr.puts "webpack binstubs not found.\n"\
"Have you run rails webpacker:install ?\n"\
"Make sure the bin directory or binstubs are not included in .gitignore\n"\
Expand Down
6 changes: 4 additions & 2 deletions lib/tasks/webpacker/compile.rake
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ end
def enhance_assets_precompile
# yarn:install was added in Rails 5.1
deps = yarn_install_available? ? [] : ["webpacker:yarn_install"]
Rake::Task["assets:precompile"].enhance(deps) do
Rake::Task["webpacker:compile"].invoke
Rake::Task["assets:precompile"].enhance(deps) do |task|
prefix = task.name.split(/#|assets:precompile/).first

Rake::Task["#{prefix}webpacker:compile"].invoke
end
end

Expand Down
22 changes: 12 additions & 10 deletions lib/tasks/webpacker/info.rake
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@ require "webpacker/version"
namespace :webpacker do
desc "Provide information on Webpacker's environment"
task :info do
$stdout.puts "Ruby: #{`ruby --version`}"
$stdout.puts "Rails: #{Rails.version}"
$stdout.puts "Webpacker: #{Webpacker::VERSION}"
$stdout.puts "Node: #{`node --version`}"
$stdout.puts "Yarn: #{`yarn --version`}"
Dir.chdir(Rails.root) do
$stdout.puts "Ruby: #{`ruby --version`}"
$stdout.puts "Rails: #{Rails.version}"
$stdout.puts "Webpacker: #{Webpacker::VERSION}"
$stdout.puts "Node: #{`node --version`}"
$stdout.puts "Yarn: #{`yarn --version`}"

$stdout.puts "\n"
$stdout.puts "@rails/webpacker: \n#{`npm list @rails/webpacker version`}"
$stdout.puts "\n"
$stdout.puts "@rails/webpacker: \n#{`npm list @rails/webpacker version`}"

$stdout.puts "Is bin/webpack present?: #{File.exist? 'bin/webpack'}"
$stdout.puts "Is bin/webpack-dev-server present?: #{File.exist? 'bin/webpack-dev-server'}"
$stdout.puts "Is bin/yarn present?: #{File.exist? 'bin/yarn'}"
$stdout.puts "Is bin/webpack present?: #{File.exist? 'bin/webpack'}"
$stdout.puts "Is bin/webpack-dev-server present?: #{File.exist? 'bin/webpack-dev-server'}"
$stdout.puts "Is bin/yarn present?: #{File.exist? 'bin/yarn'}"
end
end
end
10 changes: 6 additions & 4 deletions lib/tasks/webpacker/install.rake
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
install_template_path = File.expand_path("../../install/template.rb", __dir__).freeze
bin_path = ENV["BUNDLE_BIN"] || "./bin"
bin_path = ENV["BUNDLE_BIN"] || Rails.root.join("bin")

namespace :webpacker do
desc "Install Webpacker in this application"
task install: [:check_node, :check_yarn] do
task install: [:check_node, :check_yarn] do |task|
prefix = task.name.split(/#|webpacker:install/).first

if Rails::VERSION::MAJOR >= 5
exec "#{RbConfig.ruby} #{bin_path}/rails app:template LOCATION=#{install_template_path}"
exec "#{RbConfig.ruby} #{bin_path}/rails #{prefix}app:template LOCATION=#{install_template_path}"
else
exec "#{RbConfig.ruby} #{bin_path}/rake rails:template LOCATION=#{install_template_path}"
exec "#{RbConfig.ruby} #{bin_path}/rake #{prefix}rails:template LOCATION=#{install_template_path}"
end
end
end
3 changes: 2 additions & 1 deletion lib/tasks/webpacker/verify_install.rake
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ namespace :webpacker do
desc "Verifies if Webpacker is installed"
task verify_install: [:check_node, :check_yarn, :check_binstubs] do
unless Webpacker.config.config_path.exist?
$stderr.puts "Configuration config/webpacker.yml file not found. \n"\
path = Webpacker.config.config_path.relative_path_from(Pathname.new(pwd)).to_s
$stderr.puts "Configuration #{path} file not found. \n"\
"Make sure webpacker:install is run successfully before " \
"running dependent tasks"
exit!
Expand Down
4 changes: 3 additions & 1 deletion lib/tasks/webpacker/yarn_install.rake
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ namespace :webpacker do
node_env = ENV.fetch("NODE_ENV") do
valid_node_envs.include?(Rails.env) ? Rails.env : "production"
end
system({ "NODE_ENV" => node_env }, "yarn install --no-progress --frozen-lockfile")
Dir.chdir(Rails.root) do
system({ "NODE_ENV" => node_env }, "yarn install --no-progress --frozen-lockfile")
end
end
end
39 changes: 39 additions & 0 deletions test/engine_rake_tasks_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
require "test_helper"

class EngineRakeTasksTest < Minitest::Test
def setup
remove_webpack_binstubs
end

def teardown
remove_webpack_binstubs
end

def test_task_mounted
output = Dir.chdir(mounted_app_path) { `rake -T` }
assert_includes output, "app:webpacker"
end

def test_binstubs
Dir.chdir(mounted_app_path) { `bundle exec rake app:webpacker:binstubs` }
webpack_binstub_paths.each { |path| assert File.exist?(path) }
end

private
def mounted_app_path
File.expand_path("mounted_app", __dir__)
end

def webpack_binstub_paths
[
"#{mounted_app_path}/test/dummy/bin/webpack",
"#{mounted_app_path}/test/dummy/bin/webpack-dev-server",
]
end

def remove_webpack_binstubs
webpack_binstub_paths.each do |path|
File.delete(path) if File.exist?(path)
end
end
end
4 changes: 4 additions & 0 deletions test/mounted_app/Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
require "bundler/setup"

APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
load "rails/tasks/engine.rake"
3 changes: 3 additions & 0 deletions test/mounted_app/test/dummy/Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
require_relative "config/application"

Rails.application.load_tasks
3 changes: 3 additions & 0 deletions test/mounted_app/test/dummy/bin/rails
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env ruby
APP_PATH = File.expand_path("../config/application", __dir__)
require "rails/commands"
3 changes: 3 additions & 0 deletions test/mounted_app/test/dummy/bin/rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env ruby
require "rake"
Rake.application.run
5 changes: 5 additions & 0 deletions test/mounted_app/test/dummy/config.ru
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# This file allows the `Rails.root` to be correctly determined.

require_relative "config/environment"

run Rails.application
10 changes: 10 additions & 0 deletions test/mounted_app/test/dummy/config/application.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
require "action_controller/railtie"
require "action_view/railtie"
require "webpacker"

module TestDummyApp
class Application < Rails::Application
config.secret_key_base = "abcdef"
config.eager_load = true
end
end
3 changes: 3 additions & 0 deletions test/mounted_app/test/dummy/config/environment.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
require_relative "application"

Rails.application.initialize!
Loading