diff --git a/lib/webpacker/dev_server_runner.rb b/lib/webpacker/dev_server_runner.rb index 4ad313a11..747ea6b76 100644 --- a/lib/webpacker/dev_server_runner.rb +++ b/lib/webpacker/dev_server_runner.rb @@ -45,15 +45,22 @@ def detect_port! def execute_cmd env = Webpacker::Compiler.env - cmd = [ - "#{@node_modules_bin_path}/webpack-dev-server", - "--config", @webpack_config - ] + + cmd = if node_modules_bin_exist? + ["#{@node_modules_bin_path}/webpack-dev-server"] + else + ["yarn", "webpack-dev-server"] + end + cmd += ["--config", @webpack_config] cmd += ["--progress", "--color"] if @pretty Dir.chdir(@app_path) do - exec env, *cmd + Kernel.exec env, *cmd end end + + def node_modules_bin_exist? + File.exist?("#{@node_modules_bin_path}/webpack-dev-server") + end end end diff --git a/lib/webpacker/webpack_runner.rb b/lib/webpacker/webpack_runner.rb index 40ca1d882..1dd834cd3 100644 --- a/lib/webpacker/webpack_runner.rb +++ b/lib/webpacker/webpack_runner.rb @@ -5,11 +5,22 @@ module Webpacker class WebpackRunner < Webpacker::Runner def run env = Webpacker::Compiler.env - cmd = [ "#{@node_modules_bin_path}/webpack", "--config", @webpack_config ] + @argv + + cmd = if node_modules_bin_exist? + ["#{@node_modules_bin_path}/webpack"] + else + ["yarn", "webpack"] + end + cmd += ["--config", @webpack_config] + @argv Dir.chdir(@app_path) do - exec env, *cmd + Kernel.exec env, *cmd end end + + private + def node_modules_bin_exist? + File.exist?("#{@node_modules_bin_path}/webpack") + end end end diff --git a/test/compiler_test.rb b/test/compiler_test.rb index d4262b666..d7c1a0bd9 100644 --- a/test/compiler_test.rb +++ b/test/compiler_test.rb @@ -19,6 +19,8 @@ def test_custom_environment_variables assert Webpacker.compiler.send(:webpack_env)["FOO"] == nil Webpacker.compiler.env["FOO"] = "BAR" assert Webpacker.compiler.send(:webpack_env)["FOO"] == "BAR" + ensure + Webpacker.compiler.env = {} end def test_default_watched_paths diff --git a/test/dev_server_runner_test.rb b/test/dev_server_runner_test.rb new file mode 100644 index 000000000..8dece7c36 --- /dev/null +++ b/test/dev_server_runner_test.rb @@ -0,0 +1,51 @@ +require "test_helper" +require "webpacker/dev_server_runner" + +class DevServerRunnerTest < Webpacker::Test + def setup + @original_node_env, ENV["NODE_ENV"] = ENV["NODE_ENV"], "development" + @original_rails_env, ENV["RAILS_ENV"] = ENV["RAILS_ENV"], "development" + end + + def teardown + ENV["NODE_ENV"] = @original_node_env + ENV["RAILS_ENV"] = @original_rails_env + end + + def test_run_cmd_via_node_modules + cmd = ["#{test_app_path}/node_modules/.bin/webpack-dev-server", "--config", "#{test_app_path}/config/webpack/development.js"] + + verify_command(cmd, use_node_modules: true) + end + + def test_run_cmd_via_yarn + cmd = ["yarn", "webpack-dev-server", "--config", "#{test_app_path}/config/webpack/development.js"] + + verify_command(cmd, use_node_modules: false) + end + + private + def test_app_path + File.expand_path("test_app", __dir__) + end + + def verify_command(cmd, use_node_modules: true) + cwd = Dir.pwd + Dir.chdir(test_app_path) + + klass = Webpacker::DevServerRunner + instance = klass.new([]) + mock = Minitest::Mock.new + mock.expect(:call, nil, [{}, *cmd]) + + klass.stub(:new, instance) do + instance.stub(:node_modules_bin_exist?, use_node_modules) do + Kernel.stub(:exec, mock) { klass.run([]) } + end + end + + mock.verify + ensure + Dir.chdir(cwd) + end +end diff --git a/test/test_app/config/webpack/development.js b/test/test_app/config/webpack/development.js new file mode 100644 index 000000000..e69de29bb diff --git a/test/webpack_runner_test.rb b/test/webpack_runner_test.rb new file mode 100644 index 000000000..5e41c07a2 --- /dev/null +++ b/test/webpack_runner_test.rb @@ -0,0 +1,51 @@ +require "test_helper" +require "webpacker/webpack_runner" + +class WebpackRunnerTest < Webpacker::Test + def setup + @original_node_env, ENV["NODE_ENV"] = ENV["NODE_ENV"], "development" + @original_rails_env, ENV["RAILS_ENV"] = ENV["RAILS_ENV"], "development" + end + + def teardown + ENV["NODE_ENV"] = @original_node_env + ENV["RAILS_ENV"] = @original_rails_env + end + + def test_run_cmd_via_node_modules + cmd = ["#{test_app_path}/node_modules/.bin/webpack", "--config", "#{test_app_path}/config/webpack/development.js"] + + verify_command(cmd, use_node_modules: true) + end + + def test_run_cmd_via_yarn + cmd = ["yarn", "webpack", "--config", "#{test_app_path}/config/webpack/development.js"] + + verify_command(cmd, use_node_modules: false) + end + + private + def test_app_path + File.expand_path("test_app", __dir__) + end + + def verify_command(cmd, use_node_modules: true) + cwd = Dir.pwd + Dir.chdir(test_app_path) + + klass = Webpacker::WebpackRunner + instance = klass.new([]) + mock = Minitest::Mock.new + mock.expect(:call, nil, [{}, *cmd]) + + klass.stub(:new, instance) do + instance.stub(:node_modules_bin_exist?, use_node_modules) do + Kernel.stub(:exec, mock) { klass.run([]) } + end + end + + mock.verify + ensure + Dir.chdir(cwd) + end +end