diff --git a/.gitignore b/.gitignore index 62fbfaee1..07598ddfd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ /.bundle /pkg +/test/mounted_app/test/dummy/log /test/test_app/log node_modules .byebug_history diff --git a/lib/install/angular.rb b/lib/install/angular.rb index 2f4de8db0..1535610e8 100644 --- a/lib/install/angular.rb +++ b/lib/install/angular.rb @@ -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 if Rails::VERSION::MAJOR == 5 && Rails::VERSION::MINOR > 1 say "You need to enable unsafe-eval rule.", :yellow diff --git a/lib/install/coffee.rb b/lib/install/coffee.rb index 0a402ec1c..800b743cd 100644 --- a/lib/install/coffee.rb +++ b/lib/install/coffee.rb @@ -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 coffeescript@1.12.7 coffee-loader" +Dir.chdir(Rails.root) do + say "Installing all Coffeescript dependencies" + run "yarn add coffeescript@1.12.7 coffee-loader" +end say "Webpacker now supports Coffeescript 🎉", :green diff --git a/lib/install/elm.rb b/lib/install/elm.rb index 579a97df4..71399f0b4 100644 --- a/lib/install/elm.rb +++ b/lib/install/elm.rb @@ -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/ diff --git a/lib/install/erb.rb b/lib/install/erb.rb index 6918896f1..c9333190b 100644 --- a/lib/install/erb.rb +++ b/lib/install/erb.rb @@ -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 diff --git a/lib/install/react.rb b/lib/install/react.rb index 5c0c6e9ff..6039b4478 100644 --- a/lib/install/react.rb +++ b/lib/install/react.rb @@ -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 diff --git a/lib/install/stimulus.rb b/lib/install/stimulus.rb index 94ee32a70..6ce522865 100644 --- a/lib/install/stimulus.rb +++ b/lib/install/stimulus.rb @@ -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 diff --git a/lib/install/template.rb b/lib/install/template.rb index f079f4e05..43158f3ca 100644 --- a/lib/install/template.rb +++ b/lib/install/template.rb @@ -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" + @@ -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 diff --git a/lib/install/typescript.rb b/lib/install/typescript.rb index 3273165f3..dfb9d12c9 100644 --- a/lib/install/typescript.rb +++ b/lib/install/typescript.rb @@ -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 diff --git a/lib/install/vue.rb b/lib/install/vue.rb index 8a18c531c..33800e3ed 100644 --- a/lib/install/vue.rb +++ b/lib/install/vue.rb @@ -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 diff --git a/lib/tasks/installers.rake b/lib/tasks/installers.rake index 96b658b27..e88372bfe 100644 --- a/lib/tasks/installers.rake +++ b/lib/tasks/installers.rake @@ -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] ||= [] diff --git a/lib/tasks/webpacker/binstubs.rake b/lib/tasks/webpacker/binstubs.rake index 19d71458a..645655205 100644 --- a/lib/tasks/webpacker/binstubs.rake +++ b/lib/tasks/webpacker/binstubs.rake @@ -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 diff --git a/lib/tasks/webpacker/check_binstubs.rake b/lib/tasks/webpacker/check_binstubs.rake index 81731940a..17db6b4b2 100644 --- a/lib/tasks/webpacker/check_binstubs.rake +++ b/lib/tasks/webpacker/check_binstubs.rake @@ -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"\ diff --git a/lib/tasks/webpacker/compile.rake b/lib/tasks/webpacker/compile.rake index f2b02cd46..a970f8df2 100644 --- a/lib/tasks/webpacker/compile.rake +++ b/lib/tasks/webpacker/compile.rake @@ -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 diff --git a/lib/tasks/webpacker/info.rake b/lib/tasks/webpacker/info.rake index 3a44a12d9..df9b9fb94 100644 --- a/lib/tasks/webpacker/info.rake +++ b/lib/tasks/webpacker/info.rake @@ -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 diff --git a/lib/tasks/webpacker/install.rake b/lib/tasks/webpacker/install.rake index a5a78e215..c47a867cd 100644 --- a/lib/tasks/webpacker/install.rake +++ b/lib/tasks/webpacker/install.rake @@ -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 diff --git a/lib/tasks/webpacker/verify_install.rake b/lib/tasks/webpacker/verify_install.rake index d81090c25..4f4ca6189 100644 --- a/lib/tasks/webpacker/verify_install.rake +++ b/lib/tasks/webpacker/verify_install.rake @@ -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! diff --git a/lib/tasks/webpacker/yarn_install.rake b/lib/tasks/webpacker/yarn_install.rake index af5bea542..fbd2e94d5 100644 --- a/lib/tasks/webpacker/yarn_install.rake +++ b/lib/tasks/webpacker/yarn_install.rake @@ -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 diff --git a/test/engine_rake_tasks_test.rb b/test/engine_rake_tasks_test.rb new file mode 100644 index 000000000..a1a288a52 --- /dev/null +++ b/test/engine_rake_tasks_test.rb @@ -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 diff --git a/test/mounted_app/Rakefile b/test/mounted_app/Rakefile new file mode 100644 index 000000000..fe4151add --- /dev/null +++ b/test/mounted_app/Rakefile @@ -0,0 +1,4 @@ +require "bundler/setup" + +APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__) +load "rails/tasks/engine.rake" diff --git a/test/mounted_app/test/dummy/Rakefile b/test/mounted_app/test/dummy/Rakefile new file mode 100644 index 000000000..d1baef069 --- /dev/null +++ b/test/mounted_app/test/dummy/Rakefile @@ -0,0 +1,3 @@ +require_relative "config/application" + +Rails.application.load_tasks diff --git a/test/mounted_app/test/dummy/bin/rails b/test/mounted_app/test/dummy/bin/rails new file mode 100755 index 000000000..fc42e555b --- /dev/null +++ b/test/mounted_app/test/dummy/bin/rails @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +APP_PATH = File.expand_path("../config/application", __dir__) +require "rails/commands" diff --git a/test/mounted_app/test/dummy/bin/rake b/test/mounted_app/test/dummy/bin/rake new file mode 100755 index 000000000..580915dc8 --- /dev/null +++ b/test/mounted_app/test/dummy/bin/rake @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +require "rake" +Rake.application.run diff --git a/test/mounted_app/test/dummy/config.ru b/test/mounted_app/test/dummy/config.ru new file mode 100644 index 000000000..8987d1c00 --- /dev/null +++ b/test/mounted_app/test/dummy/config.ru @@ -0,0 +1,5 @@ +# This file allows the `Rails.root` to be correctly determined. + +require_relative "config/environment" + +run Rails.application diff --git a/test/mounted_app/test/dummy/config/application.rb b/test/mounted_app/test/dummy/config/application.rb new file mode 100644 index 000000000..24f516874 --- /dev/null +++ b/test/mounted_app/test/dummy/config/application.rb @@ -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 diff --git a/test/mounted_app/test/dummy/config/environment.rb b/test/mounted_app/test/dummy/config/environment.rb new file mode 100644 index 000000000..73a3979b0 --- /dev/null +++ b/test/mounted_app/test/dummy/config/environment.rb @@ -0,0 +1,3 @@ +require_relative "application" + +Rails.application.initialize! diff --git a/test/mounted_app/test/dummy/config/webpacker.yml b/test/mounted_app/test/dummy/config/webpacker.yml new file mode 100644 index 000000000..b8ef6d6c7 --- /dev/null +++ b/test/mounted_app/test/dummy/config/webpacker.yml @@ -0,0 +1,75 @@ +# Note: You must restart bin/webpack-dev-server for changes to take effect + +default: &default + source_path: app/javascript + source_entry_path: packs + public_output_path: packs + cache_path: tmp/cache/webpacker + + # Additional paths webpack should lookup modules + # ['app/assets', 'engine/foo/app/assets'] + additional_paths: + - app/assets + - /etc/yarn + + # Reload manifest.json on all requests so we reload latest compiled packs + cache_manifest: false + + extensions: + - .js + - .sass + - .scss + - .css + - .module.sass + - .module.scss + - .module.css + - .png + - .svg + - .gif + - .jpeg + - .jpg + +development: + <<: *default + compile: true + + # Reference: https://webpack.js.org/configuration/dev-server/ + dev_server: + https: false + host: localhost + port: 3035 + public: localhost:3035 + hmr: false + # Inline should be set to true if using HMR + inline: true + overlay: true + disable_host_check: true + use_local_ip: false + +test: + <<: *default + compile: true + + # Compile test packs to a separate directory + public_output_path: packs-test + +production: + <<: *default + + # Production depends on precompilation of packs prior to booting for performance. + compile: false + + # Cache manifest.json for performance + cache_manifest: true + +staging: + <<: *default + + # Production depends on precompilation of packs prior to booting for performance. + compile: false + + # Cache manifest.json for performance + cache_manifest: true + + # Compile staging packs to a separate directory + public_output_path: packs-staging diff --git a/test/mounted_app/test/dummy/package.json b/test/mounted_app/test/dummy/package.json new file mode 100644 index 000000000..d32a2dc50 --- /dev/null +++ b/test/mounted_app/test/dummy/package.json @@ -0,0 +1,7 @@ +{ + "private": true, + "dependencies": { + "@rails/webpacker": "file:../../../../" + }, + "license": "MIT" +}