From 4838c1716a0340137d858fab49bf460e23be5a4b Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sun, 30 Sep 2018 22:31:21 -0700 Subject: Make Webpacker the default JavaScript compiler for Rails 6 (#33079) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Use Webpacker by default on new apps * Stop including coffee-rails by default * Drop using a js_compressor by default * Drop extra test for coffeescript inclusion by default * Stick with skip_javascript to signify skipping webpack * Don't install a JS runtime by default any more * app/javascript will be the new default directory for JS * Make it clear that this is just for configuring the default Webpack framework setup now * Start using the Webpack tag in the default layout * Irrelevant test * jQuery is long gone * Stop having asset pipeline compile default application.js * Add rails-ujs by default to the Webpack setup * Add Active Storage JavaScript to application.js pack by default * Consistent quoting * Add Turbolinks to default pack * Add Action Cable to default pack Need some work on how to set the global consumer that channels will work with. @javan? * Require all channels by default and use a separate consumer stub * Channel generator now targets Webpack style * Update task docs to match new generator style * Use uniform import style * Drop the JS assets generator It was barely helpful as it was. It’s no longer helpful in a Webpacked world. Sayonara! * Add app/javascript to the stats directories * Simpler import style Which match the other imports. * Address test failures from dropping JS compilation (and compression) * webpacker-default: Modify `AssetsGeneratorTest` Before: ``` $ bin/test test/generators/assets_generator_test.rb Run options: --seed 46201 F Failure: AssetsGeneratorTest#test_assets [/Users/ttanimichi/ghq/github.com/ttanimichi/rails/railties/test/generators/assets_generator_test.rb:12]: Expected file "app/assets/javascripts/posts.js" to exist, but does not bin/test /Users/ttanimichi/ghq/github.com/ttanimichi/rails/railties/test/generators/assets_generator_test.rb:10 . Finished in 0.031343s, 63.8101 runs/s, 95.7152 assertions/s. 2 runs, 3 assertions, 1 failures, 0 errors, 0 skips ``` After: ``` $ bin/test test/generators/assets_generator_test.rb Run options: --seed 43571 .. Finished in 0.030370s, 65.8545 runs/s, 65.8545 assertions/s. 2 runs, 2 assertions, 0 failures, 0 errors, 0 skips ``` * webpacker-default: Modify `ChannelGeneratorTest` Before: ``` $ bin/test test/generators/channel_generator_test.rb Run options: --seed 8986 .F Failure: ChannelGeneratorTest#test_channel_with_multiple_actions_is_created [/Users/ttanimichi/ghq/github.com/ttanimichi/rails/railties/test/generators/channel_generator_test.rb:43]: Expected file "app/assets/javascripts/channels/chat.js" to exist, but does not bin/test /Users/ttanimichi/ghq/github.com/ttanimichi/rails/railties/test/generators/channel_generator_test.rb:34 .F Failure: ChannelGeneratorTest#test_channel_is_created [/Users/ttanimichi/ghq/github.com/ttanimichi/rails/railties/test/generators/channel_generator_test.rb:29]: Expected file "app/assets/javascripts/channels/chat.js" to exist, but does not bin/test /Users/ttanimichi/ghq/github.com/ttanimichi/rails/railties/test/generators/channel_generator_test.rb:22 E Error: ChannelGeneratorTest#test_cable_js_is_created_if_not_present_already: Errno::ENOENT: No such file or directory @ apply2files - /Users/ttanimichi/ghq/github.com/ttanimichi/rails/railties/test/fixtures/tmp/app/assets/javascripts/cable.js bin/test /Users/ttanimichi/ghq/github.com/ttanimichi/rails/railties/test/generators/channel_generator_test.rb:60 F Failure: ChannelGeneratorTest#test_channel_suffix_is_not_duplicated [/Users/ttanimichi/ghq/github.com/ttanimichi/rails/railties/test/generators/channel_generator_test.rb:87]: Expected file "app/assets/javascripts/channels/chat.js" to exist, but does not bin/test /Users/ttanimichi/ghq/github.com/ttanimichi/rails/railties/test/generators/channel_generator_test.rb:80 F Failure: ChannelGeneratorTest#test_channel_on_revoke [/Users/ttanimichi/ghq/github.com/ttanimichi/rails/railties/test/generators/channel_generator_test.rb:77]: Expected file "app/assets/javascripts/cable.js" to exist, but does not bin/test /Users/ttanimichi/ghq/github.com/ttanimichi/rails/railties/test/generators/channel_generator_test.rb:68 Finished in 0.064384s, 108.7227 runs/s, 481.4861 assertions/s. 7 runs, 31 assertions, 4 failures, 1 errors, 0 skips ``` After: ``` $ bin/test test/generators/channel_generator_test.rb Run options: --seed 44857 ....... Finished in 0.060243s, 116.1961 runs/s, 697.1764 assertions/s. 7 runs, 42 assertions, 0 failures, 0 errors, 0 skips ``` * Fix shared generator tests. * webpacker-default: Modify `ControllerGeneratorTest` The JS assets generator was dropped. ref. https://github.com/rails/rails/commit/46215b179483d3e4d264555f5a4952f43eb8142a * Revert "Simpler import style". It's currently failing with an error of "TypeError: undefined is not an object (evaluating '__WEBPACK_IMPORTED_MODULE_2_activestorage___default.a.start')". Waiting for @javan to have a look. This reverts commit 5d3ebb71059f635d3756cbda4ab9752027e09256. * require webpacker in test app * Add webpacker without making the build hang/timeout. (#33640) * use yarn workspaces to allow for installing unreleased packages and only generate js/bootsnap when required * no longer need to have webpacker in env templates as webpacker moved this config to yml file * Fix rubocop violation * Got the test passing for the running scaffold * update expected lines of code * update middleware tests to account for webpacker * disable js in plugins be default to get the tests passing (#34009) * clear codeclimate report issues * Anything newer than currently released is good * Use Webpacker development version during development of Rails * Edge should get development webpacker as well * Add changelog entry for Webpacker change --- .gitignore | 2 + .travis.yml | 5 ++ .yarnrc | 2 + Gemfile | 2 +- Gemfile.lock | 12 ++++ actioncable/lib/rails/generators/channel/USAGE | 8 +-- .../rails/generators/channel/channel_generator.rb | 5 +- .../channel/templates/assets/cable.js.tt | 13 ---- .../channel/templates/assets/channel.coffee.tt | 14 ----- .../channel/templates/assets/channel.js.tt | 18 ------ .../channel/templates/javascript/channel.js.tt | 20 ++++++ .../channel/templates/javascript/consumer.js.tt | 6 ++ .../channel/templates/javascript/index.js.tt | 5 ++ .../test/dummy/app/assets/config/manifest.js | 2 - .../test/dummy/config/environments/production.rb | 3 +- activestorage/test/dummy/config/webpacker.yml | 72 ++++++++++++++++++++++ package.json | 14 +++++ railties/CHANGELOG.md | 8 +++ railties/Rakefile | 3 + railties/lib/rails/generators.rb | 2 - railties/lib/rails/generators/app_base.rb | 58 ++++------------- .../rails/generators/js/assets/assets_generator.rb | 15 ----- .../generators/js/assets/templates/javascript.js | 2 - .../rails/generators/rails/app/app_generator.rb | 8 +-- .../app/templates/app/assets/config/manifest.js.tt | 3 - .../app/assets/javascripts/application.js.tt | 22 ------- .../templates/app/assets/javascripts/cable.js.tt | 13 ---- .../templates/app/javascript/channels/consumer.js | 6 ++ .../app/templates/app/javascript/channels/index.js | 5 ++ .../app/javascript/packs/application.js.tt | 21 +++++++ .../app/views/layouts/application.html.erb.tt | 8 +-- .../templates/config/environments/production.rb.tt | 7 +-- .../generators/rails/app/templates/package.json.tt | 8 ++- railties/lib/rails/generators/rails/assets/USAGE | 5 +- .../generators/rails/assets/assets_generator.rb | 8 --- .../rails/assets/templates/javascript.js | 2 - .../generators/rails/plugin/plugin_generator.rb | 2 +- railties/lib/rails/generators/testing/behaviour.rb | 3 + railties/lib/rails/tasks/statistics.rake | 1 + railties/test/application/assets_test.rb | 20 +----- railties/test/application/middleware_test.rb | 15 +++-- railties/test/application/rake_test.rb | 3 +- railties/test/engine/commands_test.rb | 3 +- railties/test/generators/api_app_generator_test.rb | 1 - railties/test/generators/app_generator_test.rb | 71 ++++++--------------- railties/test/generators/assets_generator_test.rb | 4 +- railties/test/generators/channel_generator_test.rb | 21 ++++--- .../test/generators/controller_generator_test.rb | 3 - railties/test/generators/plugin_generator_test.rb | 47 ++++---------- .../test/generators/scaffold_generator_test.rb | 19 ------ railties/test/generators/shared_generator_tests.rb | 23 ++++--- railties/test/isolation/abstract_unit.rb | 19 ++++-- 52 files changed, 310 insertions(+), 352 deletions(-) create mode 100644 .yarnrc delete mode 100644 actioncable/lib/rails/generators/channel/templates/assets/cable.js.tt delete mode 100644 actioncable/lib/rails/generators/channel/templates/assets/channel.coffee.tt delete mode 100644 actioncable/lib/rails/generators/channel/templates/assets/channel.js.tt create mode 100644 actioncable/lib/rails/generators/channel/templates/javascript/channel.js.tt create mode 100644 actioncable/lib/rails/generators/channel/templates/javascript/consumer.js.tt create mode 100644 actioncable/lib/rails/generators/channel/templates/javascript/index.js.tt create mode 100644 activestorage/test/dummy/config/webpacker.yml create mode 100644 package.json delete mode 100644 railties/lib/rails/generators/js/assets/assets_generator.rb delete mode 100644 railties/lib/rails/generators/js/assets/templates/javascript.js delete mode 100644 railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt delete mode 100644 railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/cable.js.tt create mode 100644 railties/lib/rails/generators/rails/app/templates/app/javascript/channels/consumer.js create mode 100644 railties/lib/rails/generators/rails/app/templates/app/javascript/channels/index.js create mode 100644 railties/lib/rails/generators/rails/app/templates/app/javascript/packs/application.js.tt delete mode 100644 railties/lib/rails/generators/rails/assets/templates/javascript.js diff --git a/.gitignore b/.gitignore index ab9ca8a6ac..d44875ed9a 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,5 @@ debug.log node_modules/ package-lock.json pkg/ +/tmp/ +/yarn.lock \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 109005b407..7dc6360e73 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,6 +42,11 @@ before_install: - "[[ $GEM != 'av:ujs' ]] || nvm install node" - "[[ $GEM != 'av:ujs' ]] || node --version" - "[[ $GEM != 'av:ujs' ]] || (cd actionview && npm install)" + - "[[ $GEM != 'ar:mysql2' ]] || [[ $MYSQL == 'mariadb' ]] || sudo mysql -e \"use mysql; update user set authentication_string='' where User='root'; update user set plugin='mysql_native_password';FLUSH PRIVILEGES;\"" + - "[[ $GEM != 'ar:mysql2' ]] || [[ $MYSQL == 'mariadb' ]] || sudo mysql_upgrade" + - "[[ $GEM != 'ar:mysql2' ]] || [[ $MYSQL == 'mariadb' ]] || sudo service mysql restart" + - "[[ $GEM != 'railties' ]] || (curl -o- -L https://yarnpkg.com/install.sh | bash)" + - "[[ $GEM != 'railties' ]] || export PATH=$HOME/.yarn/bin:$PATH" before_script: # Set Sauce Labs username and access key. Obfuscated, purposefully not encrypted. diff --git a/.yarnrc b/.yarnrc new file mode 100644 index 0000000000..6be74e145d --- /dev/null +++ b/.yarnrc @@ -0,0 +1,2 @@ +workspaces-experimental true +--add.prefer-offline true \ No newline at end of file diff --git a/Gemfile b/Gemfile index 5bf443b7c8..c35254eb43 100644 --- a/Gemfile +++ b/Gemfile @@ -15,7 +15,7 @@ gem "rack-cache", "~> 1.2" gem "coffee-rails" gem "sass-rails" gem "turbolinks", "~> 5" - +gem "webpacker", github: "rails/webpacker", require: ENV["SKIP_REQUIRE_WEBPACKER"] != "true" # require: false so bcrypt is loaded only when has_secure_password is used. # This is to avoid Active Model (and by extension the entire framework) # being dependent on a binary library. diff --git a/Gemfile.lock b/Gemfile.lock index e6fc04b5ca..dfa38ed102 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -30,6 +30,15 @@ GIT queue_classic (3.2.0.RC1) pg (>= 0.17, < 2.0) +GIT + remote: https://github.com/rails/webpacker.git + revision: 48d9fd52c3e9637dbb21e551b48c84c0f2dbb2ed + specs: + webpacker (4.0.0.pre.pre.2) + activesupport (>= 4.2) + rack-proxy (>= 0.6.1) + railties (>= 4.2) + PATH remote: . specs: @@ -364,6 +373,8 @@ GEM rack (>= 0.4) rack-protection (2.0.3) rack + rack-proxy (0.6.5) + rack rack-test (1.1.0) rack (>= 1.0, < 3) rails-dom-testing (2.0.3) @@ -565,6 +576,7 @@ DEPENDENCIES uglifier (>= 1.3.0) w3c_validators wdm (>= 0.1.0) + webpacker! websocket-client-simple! BUNDLED WITH diff --git a/actioncable/lib/rails/generators/channel/USAGE b/actioncable/lib/rails/generators/channel/USAGE index dd109fda80..ea9662436c 100644 --- a/actioncable/lib/rails/generators/channel/USAGE +++ b/actioncable/lib/rails/generators/channel/USAGE @@ -1,14 +1,12 @@ Description: ============ - Stubs out a new cable channel for the server (in Ruby) and client (in CoffeeScript). + Stubs out a new cable channel for the server (in Ruby) and client (in JavaScript). Pass the channel name, either CamelCased or under_scored, and an optional list of channel actions as arguments. - Note: Turn on the cable connection in app/assets/javascripts/cable.js after generating any channels. - Example: ======== rails generate channel Chat speak - creates a Chat channel class and CoffeeScript asset: + creates a Chat channel class and JavaScript asset: Channel: app/channels/chat_channel.rb - Assets: app/assets/javascripts/channels/chat.coffee + Assets: app/javascript/channels/chat_channel.js diff --git a/actioncable/lib/rails/generators/channel/channel_generator.rb b/actioncable/lib/rails/generators/channel/channel_generator.rb index 427eef1f55..ef51981e89 100644 --- a/actioncable/lib/rails/generators/channel/channel_generator.rb +++ b/actioncable/lib/rails/generators/channel/channel_generator.rb @@ -16,10 +16,11 @@ module Rails if options[:assets] if behavior == :invoke - template "assets/cable.js", "app/assets/javascripts/cable.js" + template "javascript/index.js", "app/javascript/channels/index.js" + template "javascript/consumer.js", "app/javascript/channels/consumer.js" end - js_template "assets/channel", File.join("app/assets/javascripts/channels", class_path, "#{file_name}") + js_template "javascript/channel", File.join("app/javascript/channels", class_path, "#{file_name}_channel") end generate_application_cable_files diff --git a/actioncable/lib/rails/generators/channel/templates/assets/cable.js.tt b/actioncable/lib/rails/generators/channel/templates/assets/cable.js.tt deleted file mode 100644 index 739aa5f022..0000000000 --- a/actioncable/lib/rails/generators/channel/templates/assets/cable.js.tt +++ /dev/null @@ -1,13 +0,0 @@ -// Action Cable provides the framework to deal with WebSockets in Rails. -// You can generate new channels where WebSocket features live using the `rails generate channel` command. -// -//= require action_cable -//= require_self -//= require_tree ./channels - -(function() { - this.App || (this.App = {}); - - App.cable = ActionCable.createConsumer(); - -}).call(this); diff --git a/actioncable/lib/rails/generators/channel/templates/assets/channel.coffee.tt b/actioncable/lib/rails/generators/channel/templates/assets/channel.coffee.tt deleted file mode 100644 index 5467811aba..0000000000 --- a/actioncable/lib/rails/generators/channel/templates/assets/channel.coffee.tt +++ /dev/null @@ -1,14 +0,0 @@ -App.<%= class_name.underscore %> = App.cable.subscriptions.create "<%= class_name %>Channel", - connected: -> - # Called when the subscription is ready for use on the server - - disconnected: -> - # Called when the subscription has been terminated by the server - - received: (data) -> - # Called when there's incoming data on the websocket for this channel -<% actions.each do |action| -%> - - <%= action %>: -> - @perform '<%= action %>' -<% end -%> diff --git a/actioncable/lib/rails/generators/channel/templates/assets/channel.js.tt b/actioncable/lib/rails/generators/channel/templates/assets/channel.js.tt deleted file mode 100644 index ab0e68b11a..0000000000 --- a/actioncable/lib/rails/generators/channel/templates/assets/channel.js.tt +++ /dev/null @@ -1,18 +0,0 @@ -App.<%= class_name.underscore %> = App.cable.subscriptions.create("<%= class_name %>Channel", { - connected: function() { - // Called when the subscription is ready for use on the server - }, - - disconnected: function() { - // Called when the subscription has been terminated by the server - }, - - received: function(data) { - // Called when there's incoming data on the websocket for this channel - }<%= actions.any? ? ",\n" : '' %> -<% actions.each do |action| -%> - <%=action %>: function() { - return this.perform('<%= action %>'); - }<%= action == actions[-1] ? '' : ",\n" %> -<% end -%> -}); diff --git a/actioncable/lib/rails/generators/channel/templates/javascript/channel.js.tt b/actioncable/lib/rails/generators/channel/templates/javascript/channel.js.tt new file mode 100644 index 0000000000..33baaa5a22 --- /dev/null +++ b/actioncable/lib/rails/generators/channel/templates/javascript/channel.js.tt @@ -0,0 +1,20 @@ +import consumer from "./consumer" + +consumer.subscriptions.create("<%= class_name %>Channel", { + connected: function() { + // Called when the subscription is ready for use on the server + }, + + disconnected: function() { + // Called when the subscription has been terminated by the server + }, + + received: function(data) { + // Called when there's incoming data on the websocket for this channel + }<%= actions.any? ? ",\n" : '' %> +<% actions.each do |action| -%> + <%=action %>: function() { + return this.perform('<%= action %>'); + }<%= action == actions[-1] ? '' : ",\n" %> +<% end -%> +}); diff --git a/actioncable/lib/rails/generators/channel/templates/javascript/consumer.js.tt b/actioncable/lib/rails/generators/channel/templates/javascript/consumer.js.tt new file mode 100644 index 0000000000..76ca3d0f2f --- /dev/null +++ b/actioncable/lib/rails/generators/channel/templates/javascript/consumer.js.tt @@ -0,0 +1,6 @@ +// Action Cable provides the framework to deal with WebSockets in Rails. +// You can generate new channels where WebSocket features live using the `rails generate channel` command. + +import ActionCable from "actioncable" + +export default ActionCable.createConsumer() diff --git a/actioncable/lib/rails/generators/channel/templates/javascript/index.js.tt b/actioncable/lib/rails/generators/channel/templates/javascript/index.js.tt new file mode 100644 index 0000000000..5da1ce2dce --- /dev/null +++ b/actioncable/lib/rails/generators/channel/templates/javascript/index.js.tt @@ -0,0 +1,5 @@ +// Load all the channels within this directory and all subdirectories. +// Channel files must be named *_channel.js. + +const channels = require.context('.', true, /\_channel\.js$/) +channels.keys().forEach(channels) diff --git a/activestorage/test/dummy/app/assets/config/manifest.js b/activestorage/test/dummy/app/assets/config/manifest.js index a8adebe722..bb109908b2 100644 --- a/activestorage/test/dummy/app/assets/config/manifest.js +++ b/activestorage/test/dummy/app/assets/config/manifest.js @@ -1,5 +1,3 @@ //= link_tree ../images -//= link_directory ../javascripts .js //= link_directory ../stylesheets .css -//= link active_storage_manifest.js diff --git a/activestorage/test/dummy/config/environments/production.rb b/activestorage/test/dummy/config/environments/production.rb index 34ac3bc561..be7f5b80d4 100644 --- a/activestorage/test/dummy/config/environments/production.rb +++ b/activestorage/test/dummy/config/environments/production.rb @@ -25,8 +25,7 @@ Rails.application.configure do # Apache or NGINX already handles this. config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? - # Compress JavaScripts and CSS. - config.assets.js_compressor = :uglifier + # Compress CSS using a preprocessor. # config.assets.css_compressor = :sass # Do not fallback to assets pipeline if a precompiled asset is missed. diff --git a/activestorage/test/dummy/config/webpacker.yml b/activestorage/test/dummy/config/webpacker.yml new file mode 100644 index 0000000000..c1515a2e95 --- /dev/null +++ b/activestorage/test/dummy/config/webpacker.yml @@ -0,0 +1,72 @@ +# 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 + check_yarn_integrity: false + + # Additional paths webpack should lookup modules + # ['app/assets', 'engine/foo/app/assets'] + resolved_paths: [] + + # 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 + + # Verifies that versions and hashed value of the package contents in the project's package.json + check_yarn_integrity: 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 + compress: true + disable_host_check: true + use_local_ip: false + quiet: false + headers: + 'Access-Control-Allow-Origin': '*' + watch_options: + ignored: /node_modules/ + + +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 diff --git a/package.json b/package.json new file mode 100644 index 0000000000..88029de141 --- /dev/null +++ b/package.json @@ -0,0 +1,14 @@ +{ + "private": true, + "workspaces": [ + "actioncable", + "activestorage", + "actionview", + "tmp/templates/app_template", + "railties/test/fixtures/tmp/bukkits/**/test/dummy", + "railties/test/fixtures/tmp/bukkits/**/spec/dummy" + ], + "dependencies": { + "webpack": "^4.17.1" + } +} diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md index 37444c4cf6..925dac7b3c 100644 --- a/railties/CHANGELOG.md +++ b/railties/CHANGELOG.md @@ -1,3 +1,11 @@ +* Use Webpacker by default to manage app-level JavaScript through the new app/javascript directory. + Sprockets is now solely in charge, by default, of compiling CSS and other static assets. + Action Cable channel generators will create ES6 stubs rather than use CoffeeScript. + Active Storage, Action Cable, Turbolinks, and Rails-UJS are loaded by a new application.js pack. + Generators no longer generate JavaScript stubs. + + *DHH*, *Lachlan Sylvester* + * Refactors `migrations_paths` command option in generators to `database` (aliased as `db`). Now, the migrations paths will be read from the specified database configuration in the diff --git a/railties/Rakefile b/railties/Rakefile index e1be0ceb40..445f6217b3 100644 --- a/railties/Rakefile +++ b/railties/Rakefile @@ -28,6 +28,9 @@ namespace :test do require "bundler/setup" unless defined?(Bundler) require "active_support" + # Only generate the template app once. + require_relative "test/isolation/abstract_unit" + failing_files = [] dirs = (ENV["TEST_DIR"] || ENV["TEST_DIRS"] || "**").split(",") diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb index ed672ae48e..cd8f16e247 100644 --- a/railties/lib/rails/generators.rb +++ b/railties/lib/rails/generators.rb @@ -33,8 +33,6 @@ module Rails rails: { actions: "-a", orm: "-o", - javascripts: "-j", - javascript_engine: "-je", resource_controller: "-c", scaffold_controller: "-c", stylesheets: "-y", diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb index 8991c547ca..410e53b4c0 100644 --- a/railties/lib/rails/generators/app_base.rb +++ b/railties/lib/rails/generators/app_base.rb @@ -68,10 +68,7 @@ module Rails class_option :skip_listen, type: :boolean, default: false, desc: "Don't generate configuration that depends on the listen gem" - class_option :skip_coffee, type: :boolean, default: false, - desc: "Don't use CoffeeScript" - - class_option :skip_javascript, type: :boolean, aliases: "-J", default: false, + class_option :skip_javascript, type: :boolean, aliases: "-J", default: name == "plugin", desc: "Skip JavaScript files" class_option :skip_turbolinks, type: :boolean, default: false, @@ -327,24 +324,17 @@ module Rails def assets_gemfile_entry return [] if options[:skip_sprockets] - gems = [] - gems << GemfileEntry.version("sass-rails", "~> 5.0", - "Use SCSS for stylesheets") - - if !options[:skip_javascript] - gems << GemfileEntry.version("uglifier", - ">= 1.3.0", - "Use Uglifier as compressor for JavaScript assets") - end - - gems + GemfileEntry.version("sass-rails", "~> 5.0", "Use SCSS for stylesheets") end def webpacker_gemfile_entry - return [] unless options[:webpack] + return [] if options[:skip_javascript] - comment = "Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker" - GemfileEntry.new "webpacker", nil, comment + if options.dev? || options.edge? + GemfileEntry.github "webpacker", "rails/webpacker", nil, "Use development version of Webpacker" + else + GemfileEntry.new "webpacker", nil, "Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker" + end end def jbuilder_gemfile_entry @@ -352,34 +342,12 @@ module Rails GemfileEntry.new "jbuilder", "~> 2.5", comment, {}, options[:api] end - def coffee_gemfile_entry - GemfileEntry.version "coffee-rails", "~> 4.2", "Use CoffeeScript for .coffee assets and views" - end - def javascript_gemfile_entry - if options[:skip_javascript] || options[:skip_sprockets] + if options[:skip_javascript] || options[:skip_turbolinks] [] else - gems = [javascript_runtime_gemfile_entry] - gems << coffee_gemfile_entry unless options[:skip_coffee] - - unless options[:skip_turbolinks] - gems << GemfileEntry.version("turbolinks", "~> 5", - "Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks") - end - - gems - end - end - - def javascript_runtime_gemfile_entry - comment = "See https://github.com/rails/execjs#readme for more supported runtimes" - if defined?(JRUBY_VERSION) - GemfileEntry.version "therubyrhino", nil, comment - elsif RUBY_PLATFORM.match?(/mingw|mswin/) - GemfileEntry.version "duktape", nil, comment - else - GemfileEntry.new "mini_racer", nil, comment, { platforms: :ruby }, true + [ GemfileEntry.version("turbolinks", "~> 5", + "Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks") ] end end @@ -452,9 +420,9 @@ module Rails end def run_webpack - if !(webpack = options[:webpack]).nil? + unless options[:skip_javascript] rails_command "webpacker:install" - rails_command "webpacker:install:#{webpack}" unless webpack == "webpack" + rails_command "webpacker:install:#{options[:webpack]}" if options[:webpack] && options[:webpack] != "webpack" end end diff --git a/railties/lib/rails/generators/js/assets/assets_generator.rb b/railties/lib/rails/generators/js/assets/assets_generator.rb deleted file mode 100644 index 9d32c666dc..0000000000 --- a/railties/lib/rails/generators/js/assets/assets_generator.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -require "rails/generators/named_base" - -module Js # :nodoc: - module Generators # :nodoc: - class AssetsGenerator < Rails::Generators::NamedBase # :nodoc: - source_root File.expand_path("templates", __dir__) - - def copy_javascript - copy_file "javascript.js", File.join("app/assets/javascripts", class_path, "#{file_name}.js") - end - end - end -end diff --git a/railties/lib/rails/generators/js/assets/templates/javascript.js b/railties/lib/rails/generators/js/assets/templates/javascript.js deleted file mode 100644 index dee720facd..0000000000 --- a/railties/lib/rails/generators/js/assets/templates/javascript.js +++ /dev/null @@ -1,2 +0,0 @@ -// Place all the behaviors and hooks related to the matching controller here. -// All this logic will automatically be available in application.js. diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb index a6d160f1eb..cefaffcb20 100644 --- a/railties/lib/rails/generators/rails/app/app_generator.rb +++ b/railties/lib/rails/generators/rails/app/app_generator.rb @@ -80,7 +80,6 @@ module Rails directory "app" keep_file "app/assets/images" - empty_directory_with_keep_file "app/assets/javascripts/channels" unless options[:skip_action_cable] keep_file "app/controllers/concerns" keep_file "app/models/concerns" @@ -260,7 +259,7 @@ module Rails desc: "Don't run bundle install" class_option :webpack, type: :string, default: nil, - desc: "Preconfigure for app-like JavaScript with Webpack (options: #{WEBPACKS.join('/')})" + desc: "Preconfigure Webpack with a particular framework (options: #{WEBPACKS.join('/')})" def initialize(*args) super @@ -409,7 +408,7 @@ module Rails def delete_js_folder_skipping_javascript if options[:skip_javascript] - remove_dir "app/assets/javascripts" + remove_dir "app/javascript" end end @@ -436,7 +435,8 @@ module Rails def delete_action_cable_files_skipping_action_cable if options[:skip_action_cable] - remove_file "app/assets/javascripts/cable.js" + remove_file "app/javascript/channels/consumer.js" + remove_dir "app/javascript/channels" remove_dir "app/channels" end end diff --git a/railties/lib/rails/generators/rails/app/templates/app/assets/config/manifest.js.tt b/railties/lib/rails/generators/rails/app/templates/app/assets/config/manifest.js.tt index 70b579d10e..591819335f 100644 --- a/railties/lib/rails/generators/rails/app/templates/app/assets/config/manifest.js.tt +++ b/railties/lib/rails/generators/rails/app/templates/app/assets/config/manifest.js.tt @@ -1,5 +1,2 @@ //= link_tree ../images -<% unless options.skip_javascript -%> -//= link_directory ../javascripts .js -<% end -%> //= link_directory ../stylesheets .css diff --git a/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt b/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt deleted file mode 100644 index 5183bcd256..0000000000 --- a/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt +++ /dev/null @@ -1,22 +0,0 @@ -// This is a manifest file that'll be compiled into application.js, which will include all the files -// listed below. -// -// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's -// vendor/assets/javascripts directory can be referenced here using a relative path. -// -// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the -// compiled file. JavaScript code in this file should be added after the last require_* statement. -// -// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details -// about supported directives. -// -<% unless options[:skip_javascript] -%> -//= require rails-ujs -<% unless skip_active_storage? -%> -//= require activestorage -<% end -%> -<% unless options[:skip_turbolinks] -%> -//= require turbolinks -<% end -%> -<% end -%> -//= require_tree . diff --git a/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/cable.js.tt b/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/cable.js.tt deleted file mode 100644 index 739aa5f022..0000000000 --- a/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/cable.js.tt +++ /dev/null @@ -1,13 +0,0 @@ -// Action Cable provides the framework to deal with WebSockets in Rails. -// You can generate new channels where WebSocket features live using the `rails generate channel` command. -// -//= require action_cable -//= require_self -//= require_tree ./channels - -(function() { - this.App || (this.App = {}); - - App.cable = ActionCable.createConsumer(); - -}).call(this); diff --git a/railties/lib/rails/generators/rails/app/templates/app/javascript/channels/consumer.js b/railties/lib/rails/generators/rails/app/templates/app/javascript/channels/consumer.js new file mode 100644 index 0000000000..76ca3d0f2f --- /dev/null +++ b/railties/lib/rails/generators/rails/app/templates/app/javascript/channels/consumer.js @@ -0,0 +1,6 @@ +// Action Cable provides the framework to deal with WebSockets in Rails. +// You can generate new channels where WebSocket features live using the `rails generate channel` command. + +import ActionCable from "actioncable" + +export default ActionCable.createConsumer() diff --git a/railties/lib/rails/generators/rails/app/templates/app/javascript/channels/index.js b/railties/lib/rails/generators/rails/app/templates/app/javascript/channels/index.js new file mode 100644 index 0000000000..5da1ce2dce --- /dev/null +++ b/railties/lib/rails/generators/rails/app/templates/app/javascript/channels/index.js @@ -0,0 +1,5 @@ +// Load all the channels within this directory and all subdirectories. +// Channel files must be named *_channel.js. + +const channels = require.context('.', true, /\_channel\.js$/) +channels.keys().forEach(channels) diff --git a/railties/lib/rails/generators/rails/app/templates/app/javascript/packs/application.js.tt b/railties/lib/rails/generators/rails/app/templates/app/javascript/packs/application.js.tt new file mode 100644 index 0000000000..4d7a145cd6 --- /dev/null +++ b/railties/lib/rails/generators/rails/app/templates/app/javascript/packs/application.js.tt @@ -0,0 +1,21 @@ +// This file is automatically compiled by Webpack, along with any other files +// present in this directory. You're encouraged to place your actual application logic in +// a relevant structure within app/javascript and only use these pack files to reference +// that code so it'll be compiled. + +import Rails from "rails-ujs" +Rails.start() +<%- unless options[:skip_turbolinks] -%> + +import Turbolinks from "turbolinks" +Turbolinks.start() +<%- end -%> +<%- unless skip_active_storage? -%> + +import * as ActiveStorage from "activestorage" +ActiveStorage.start() +<%- end -%> +<%- unless options[:skip_action_cable] -%> + +import "channels" +<%- end -%> diff --git a/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt b/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt index ef715f1368..9a7267c783 100644 --- a/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +++ b/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt @@ -9,11 +9,11 @@ <%%= stylesheet_link_tag 'application', media: 'all' %> <%- else -%> <%- unless options[:skip_turbolinks] -%> - <%%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> - <%%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> + <%%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> + <%%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %> <%- else -%> - <%%= stylesheet_link_tag 'application', media: 'all' %> - <%%= javascript_include_tag 'application' %> + <%%= stylesheet_link_tag 'application', media: 'all' %> + <%%= javascript_pack_tag 'application' %> <%- end -%> <%- end -%> diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt index 888336af92..08befd9196 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt @@ -23,12 +23,7 @@ Rails.application.configure do config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? <%- unless options.skip_sprockets? -%> - <%- if options.skip_javascript? -%> - # Compress CSS. - <%- else -%> - # Compress JavaScripts and CSS. - config.assets.js_compressor = :uglifier - <%- end -%> + # Compress CSS using a preprocessor. # config.assets.css_compressor = :sass # Do not fallback to assets pipeline if a precompiled asset is missed. diff --git a/railties/lib/rails/generators/rails/app/templates/package.json.tt b/railties/lib/rails/generators/rails/app/templates/package.json.tt index 46db57dcbe..a654cba39c 100644 --- a/railties/lib/rails/generators/rails/app/templates/package.json.tt +++ b/railties/lib/rails/generators/rails/app/templates/package.json.tt @@ -1,5 +1,11 @@ { "name": "<%= app_name %>", "private": true, - "dependencies": {} + "dependencies": { + "rails-ujs": ">=5.2.1"<% unless options[:skip_turbolinks] %>, + "turbolinks": "5.1.1"<% end -%><% unless skip_active_storage? %>, + "activestorage": ">=5.2.1"<% end -%><% unless options[:skip_action_cable] %>, + "actioncable": ">=5.2.1"<% end -%> + }, + "version": "0.1.0" } diff --git a/railties/lib/rails/generators/rails/assets/USAGE b/railties/lib/rails/generators/rails/assets/USAGE index d2e5ed4482..ee73d05808 100644 --- a/railties/lib/rails/generators/rails/assets/USAGE +++ b/railties/lib/rails/generators/rails/assets/USAGE @@ -5,16 +5,13 @@ Description: To create an asset within a folder, specify the asset's name as a path like 'parent/name'. - This generates a JavaScript stub in app/assets/javascripts and a stylesheet - stub in app/assets/stylesheets. + This generates a stylesheet stub in app/assets/stylesheets. - If CoffeeScript is available, JavaScripts will be generated with the .coffee extension. If Sass 3 is available, stylesheets will be generated with the .scss extension. Example: `rails generate assets posts` Posts assets. - JavaScript: app/assets/javascripts/posts.js Stylesheet: app/assets/stylesheets/posts.css diff --git a/railties/lib/rails/generators/rails/assets/assets_generator.rb b/railties/lib/rails/generators/rails/assets/assets_generator.rb index ffb695a1f3..9ce8570172 100644 --- a/railties/lib/rails/generators/rails/assets/assets_generator.rb +++ b/railties/lib/rails/generators/rails/assets/assets_generator.rb @@ -3,22 +3,14 @@ module Rails module Generators class AssetsGenerator < NamedBase # :nodoc: - class_option :javascripts, type: :boolean, desc: "Generate JavaScripts" class_option :stylesheets, type: :boolean, desc: "Generate Stylesheets" - - class_option :javascript_engine, desc: "Engine for JavaScripts" class_option :stylesheet_engine, desc: "Engine for Stylesheets" private - def asset_name file_name end - hook_for :javascript_engine do |javascript_engine| - invoke javascript_engine, [name] if options[:javascripts] - end - hook_for :stylesheet_engine do |stylesheet_engine| invoke stylesheet_engine, [name] if options[:stylesheets] end diff --git a/railties/lib/rails/generators/rails/assets/templates/javascript.js b/railties/lib/rails/generators/rails/assets/templates/javascript.js deleted file mode 100644 index dee720facd..0000000000 --- a/railties/lib/rails/generators/rails/assets/templates/javascript.js +++ /dev/null @@ -1,2 +0,0 @@ -// Place all the behaviors and hooks related to the matching controller here. -// All this logic will automatically be available in application.js. diff --git a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb index 8cc42325bb..9ec0ccbe7a 100644 --- a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb +++ b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb @@ -113,7 +113,7 @@ task default: :test end def test_dummy_assets - template "rails/javascripts.js", "#{dummy_path}/app/assets/javascripts/application.js", force: true + template "rails/javascripts.js", "#{dummy_path}/app/javascript/packs/application.js", force: true template "rails/stylesheets.css", "#{dummy_path}/app/assets/stylesheets/application.css", force: true template "rails/dummy_manifest.js", "#{dummy_path}/app/assets/config/manifest.js", force: true end diff --git a/railties/lib/rails/generators/testing/behaviour.rb b/railties/lib/rails/generators/testing/behaviour.rb index 6ab88bd59f..238ffdd677 100644 --- a/railties/lib/rails/generators/testing/behaviour.rb +++ b/railties/lib/rails/generators/testing/behaviour.rb @@ -67,6 +67,9 @@ module Rails def run_generator(args = default_arguments, config = {}) capture(:stdout) do args += ["--skip-bundle"] unless args.include? "--dev" + args |= ["--skip-bootsnap"] unless args.include? "--no-skip-bootsnap" + args |= ["--skip-javascript"] unless args.include? "--no-skip-javascript" + generator_class.start(args, config.reverse_merge(destination_root: destination_root)) end end diff --git a/railties/lib/rails/tasks/statistics.rake b/railties/lib/rails/tasks/statistics.rake index 594db91eec..8cacf4a49f 100644 --- a/railties/lib/rails/tasks/statistics.rake +++ b/railties/lib/rails/tasks/statistics.rake @@ -11,6 +11,7 @@ STATS_DIRECTORIES = [ %w(Mailers app/mailers), %w(Channels app/channels), %w(JavaScripts app/assets/javascripts), + %w(JavaScript app/javascript), %w(Libraries lib/), %w(APIs app/apis), %w(Controller\ tests test/controllers), diff --git a/railties/test/application/assets_test.rb b/railties/test/application/assets_test.rb index 4ca6d02b85..46ee0d670e 100644 --- a/railties/test/application/assets_test.rb +++ b/railties/test/application/assets_test.rb @@ -68,20 +68,6 @@ module ApplicationTests assert_equal 'a = "/assets/rails.png";', last_response.body.strip end - test "assets do not require compressors until it is used" do - app_file "app/assets/javascripts/demo.js.erb", "<%= :alert %>();" - add_to_env_config "production", "config.assets.compile = true" - add_to_env_config "production", "config.assets.precompile = []" - - # Load app env - app "production" - - assert_not defined?(Uglifier) - get "/assets/demo.js" - assert_match "alert()", last_response.body - assert defined?(Uglifier) - end - test "precompile creates the file, gives it the original asset's content and run in production as default" do app_file "app/assets/config/manifest.js", "//= link_tree ../javascripts" app_file "app/assets/javascripts/application.js", "alert();" @@ -443,13 +429,13 @@ module ApplicationTests end test "digested assets are not mistakenly removed" do - app_file "app/assets/application.js", "alert();" + app_file "app/assets/application.css", "div { font-weight: bold }" add_to_config "config.assets.compile = true" precompile! - files = Dir["#{app_path}/public/assets/application-*.js"] - assert_equal 1, files.length, "Expected digested application.js asset to be generated, but none found" + files = Dir["#{app_path}/public/assets/application-*.css"] + assert_equal 1, files.length, "Expected digested application.css asset to be generated, but none found" end test "digested assets are removed from configured path" do diff --git a/railties/test/application/middleware_test.rb b/railties/test/application/middleware_test.rb index 5efaf841d4..631f5bac7f 100644 --- a/railties/test/application/middleware_test.rb +++ b/railties/test/application/middleware_test.rb @@ -25,6 +25,7 @@ module ApplicationTests boot! assert_equal [ + "Webpacker::DevServerProxy", "Rack::Sendfile", "ActionDispatch::Static", "ActionDispatch::Executor", @@ -56,6 +57,7 @@ module ApplicationTests boot! assert_equal [ + "Webpacker::DevServerProxy", "Rack::Sendfile", "ActionDispatch::Static", "ActionDispatch::Executor", @@ -138,7 +140,7 @@ module ApplicationTests add_to_config "config.ssl_options = { redirect: { host: 'example.com' } }" boot! - assert_equal [{ redirect: { host: "example.com" } }], Rails.application.middleware.first.args + assert_equal [{ redirect: { host: "example.com" } }], Rails.application.middleware[1].args end test "removing Active Record omits its middleware" do @@ -222,30 +224,31 @@ module ApplicationTests test "insert middleware after" do add_to_config "config.middleware.insert_after Rack::Sendfile, Rack::Config" boot! - assert_equal "Rack::Config", middleware.second + assert_equal "Rack::Config", middleware.third end test "unshift middleware" do add_to_config "config.middleware.unshift Rack::Config" boot! - assert_equal "Rack::Config", middleware.first + assert_equal "Rack::Config", middleware.second end test "Rails.cache does not respond to middleware" do add_to_config "config.cache_store = :memory_store" boot! - assert_equal "Rack::Runtime", middleware.fourth + assert_equal "Rack::Runtime", middleware.fifth end test "Rails.cache does respond to middleware" do boot! - assert_equal "Rack::Runtime", middleware.fifth + assert_equal "ActiveSupport::Cache::Strategy::LocalCache", middleware.fifth + assert_equal "Rack::Runtime", middleware[5] end test "insert middleware before" do add_to_config "config.middleware.insert_before Rack::Sendfile, Rack::Config" boot! - assert_equal "Rack::Config", middleware.first + assert_equal "Rack::Config", middleware.second end test "can't change middleware after it's built" do diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb index 1522a2bbc5..a0cdae898b 100644 --- a/railties/test/application/rake_test.rb +++ b/railties/test/application/rake_test.rb @@ -118,7 +118,7 @@ module ApplicationTests end def test_code_statistics_sanity - assert_match "Code LOC: 25 Test LOC: 0 Code to Test Ratio: 1:0.0", + assert_match "Code LOC: 32 Test LOC: 0 Code to Test Ratio: 1:0.0", rails("stats") end @@ -190,6 +190,7 @@ module ApplicationTests rails "generate", "model", "Cart" rails "generate", "scaffold", "LineItems", "product:references", "cart:belongs_to" with_rails_env("test") { rails("db:migrate") } + rails("webpacker:compile") output = rails("test") assert_match(/7 runs, 9 assertions, 0 failures, 0 errors/, output) diff --git a/railties/test/engine/commands_test.rb b/railties/test/engine/commands_test.rb index 48c93af80c..0e5167578d 100644 --- a/railties/test/engine/commands_test.rb +++ b/railties/test/engine/commands_test.rb @@ -24,7 +24,7 @@ class Rails::Engine::CommandsTest < ActiveSupport::TestCase def test_runner_command_work_inside_engine output = capture(:stdout) do - Dir.chdir(plugin_path) { system("bin/rails runner 'puts Rails.env'") } + Dir.chdir(plugin_path) { system({ "SKIP_REQUIRE_WEBPACKER" => "true" }, "bin/rails runner 'puts Rails.env'") } end assert_equal "test", output.strip @@ -67,6 +67,7 @@ class Rails::Engine::CommandsTest < ActiveSupport::TestCase def spawn_command(command, fd) Process.spawn( + { "SKIP_REQUIRE_WEBPACKER" => "true" }, "#{plugin_path}/bin/rails #{command}", in: fd, out: fd, err: fd ) diff --git a/railties/test/generators/api_app_generator_test.rb b/railties/test/generators/api_app_generator_test.rb index c2540f4091..4f2894e71e 100644 --- a/railties/test/generators/api_app_generator_test.rb +++ b/railties/test/generators/api_app_generator_test.rb @@ -40,7 +40,6 @@ class ApiAppGeneratorTest < Rails::Generators::TestCase end assert_file "Gemfile" do |content| - assert_no_match(/gem 'coffee-rails'/, content) assert_no_match(/gem 'sass-rails'/, content) assert_no_match(/gem 'web-console'/, content) assert_no_match(/gem 'capybara'/, content) diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index 1169633244..48e8b7123f 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -13,10 +13,9 @@ DEFAULT_APP_FILES = %w( config.ru app/assets/config/manifest.js app/assets/images - app/assets/javascripts - app/assets/javascripts/application.js - app/assets/javascripts/cable.js - app/assets/javascripts/channels + app/javascript + app/javascript/channels + app/javascript/packs/application.js app/assets/stylesheets app/assets/stylesheets/application.css app/channels/application_cable/channel.rb @@ -114,12 +113,12 @@ class AppGeneratorTest < Rails::Generators::TestCase end def test_assets - run_generator + run_generator [destination_root, "--no-skip-javascript"] assert_file("app/views/layouts/application.html.erb", /stylesheet_link_tag\s+'application', media: 'all', 'data-turbolinks-track': 'reload'/) - assert_file("app/views/layouts/application.html.erb", /javascript_include_tag\s+'application', 'data-turbolinks-track': 'reload'/) + assert_file("app/views/layouts/application.html.erb", /javascript_pack_tag\s+'application', 'data-turbolinks-track': 'reload'/) assert_file("app/assets/stylesheets/application.css") - assert_file("app/assets/javascripts/application.js") + assert_file("app/javascript/packs/application.js") end def test_application_job_file_present @@ -215,7 +214,8 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_new_application_load_defaults app_root = File.join(destination_root, "myfirstapp") - run_generator [app_root] + run_generator [app_root, "--no-skip-javascript"] + output = nil assert_file "#{app_root}/config/application.rb", /\s+config\.load_defaults #{Rails::VERSION::STRING.to_f}/ @@ -559,7 +559,6 @@ class AppGeneratorTest < Rails::Generators::TestCase run_generator assert_gem "sass-rails" - assert_gem "uglifier" end def test_action_cable_redis_gems @@ -601,24 +600,6 @@ class AppGeneratorTest < Rails::Generators::TestCase end end - def test_inclusion_of_javascript_runtime - run_generator - if defined?(JRUBY_VERSION) - assert_gem "therubyrhino" - elsif RUBY_PLATFORM =~ /mingw|mswin/ - assert_gem "duktape" - else - assert_file "Gemfile", /# gem 'mini_racer', platforms: :ruby/ - end - end - - def test_rails_ujs_is_the_default_ujs_library - run_generator - assert_file "app/assets/javascripts/application.js" do |contents| - assert_match %r{^//= require rails-ujs}, contents - end - end - def test_javascript_is_skipped_if_required run_generator [destination_root, "--skip-javascript"] @@ -628,22 +609,6 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_match(/stylesheet_link_tag\s+'application', media: 'all' %>/, contents) assert_no_match(/javascript_include_tag\s+'application' \%>/, contents) end - - assert_no_gem "coffee-rails" - assert_no_gem "uglifier" - - assert_file "config/environments/production.rb" do |content| - assert_no_match(/config\.assets\.js_compressor = :uglifier/, content) - end - end - - def test_coffeescript_is_skipped_if_required - run_generator [destination_root, "--skip-coffee"] - - assert_file "Gemfile" do |content| - assert_no_match(/coffee-rails/, content) - assert_match(/uglifier/, content) - end end def test_inclusion_of_jbuilder @@ -819,22 +784,22 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_no_gem "spring" end - def test_webpack_option + def test_skip_javascript_option command_check = -> command, *_ do @called ||= 0 if command == "webpacker:install" @called += 1 - assert_equal 1, @called, "webpacker:install expected to be called once, but was called #{@called} times." + assert_equal 0, @called, "webpacker:install expected not to be called once, but was called #{@called} times." end end - generator([destination_root], webpack: "webpack").stub(:rails_command, command_check) do + generator([destination_root], skip_javascript: true).stub(:rails_command, command_check) do generator.stub :bundle_command, nil do quietly { generator.invoke_all } end end - assert_gem "webpacker" + assert_no_gem "webpacker" end def test_webpack_option_with_js_framework @@ -856,22 +821,24 @@ class AppGeneratorTest < Rails::Generators::TestCase quietly { generator.invoke_all } end end + + assert_gem "webpacker" end def test_generator_if_skip_turbolinks_is_given - run_generator [destination_root, "--skip-turbolinks"] + run_generator [destination_root, "--skip-turbolinks", "--no-skip-javascript"] assert_no_gem "turbolinks" assert_file "app/views/layouts/application.html.erb" do |content| assert_no_match(/data-turbolinks-track/, content) end - assert_file "app/assets/javascripts/application.js" do |content| + assert_file "app/javascript/packs/application.js" do |content| assert_no_match(/turbolinks/, content) end end def test_bootsnap - run_generator + run_generator [destination_root, "--no-skip-bootsnap"] unless defined?(JRUBY_VERSION) assert_gem "bootsnap" @@ -972,7 +939,7 @@ class AppGeneratorTest < Rails::Generators::TestCase template end - sequence = ["git init", "install", "binstubs bundler", "exec spring binstub --all", "echo ran after_bundle"] + sequence = ["git init", "install", "binstubs bundler", "exec spring binstub --all", "webpacker:install", "echo ran after_bundle"] @sequence_step ||= 0 ensure_bundler_first = -> command, options = nil do assert_equal sequence[@sequence_step], command, "commands should be called in sequence #{sequence}" @@ -989,7 +956,7 @@ class AppGeneratorTest < Rails::Generators::TestCase end end - assert_equal 5, @sequence_step + assert_equal 6, @sequence_step end def test_gitignore diff --git a/railties/test/generators/assets_generator_test.rb b/railties/test/generators/assets_generator_test.rb index 3cec41dbf8..83d2429acf 100644 --- a/railties/test/generators/assets_generator_test.rb +++ b/railties/test/generators/assets_generator_test.rb @@ -9,13 +9,11 @@ class AssetsGeneratorTest < Rails::Generators::TestCase def test_assets run_generator - assert_file "app/assets/javascripts/posts.js" assert_file "app/assets/stylesheets/posts.css" end def test_skipping_assets - run_generator ["posts", "--no-stylesheets", "--no-javascripts"] - assert_no_file "app/assets/javascripts/posts.js" + run_generator ["posts", "--no-stylesheets"] assert_no_file "app/assets/stylesheets/posts.css" end end diff --git a/railties/test/generators/channel_generator_test.rb b/railties/test/generators/channel_generator_test.rb index e543cc11b8..265d7c9618 100644 --- a/railties/test/generators/channel_generator_test.rb +++ b/railties/test/generators/channel_generator_test.rb @@ -26,8 +26,8 @@ class ChannelGeneratorTest < Rails::Generators::TestCase assert_match(/class ChatChannel < ApplicationCable::Channel/, channel) end - assert_file "app/assets/javascripts/channels/chat.js" do |channel| - assert_match(/App\.chat = App\.cable\.subscriptions\.create\("ChatChannel/, channel) + assert_file "app/javascript/channels/chat_channel.js" do |channel| + assert_match(/import consumer from "\.\/consumer"\s+consumer\.subscriptions\.create\("ChatChannel/, channel) end end @@ -40,8 +40,8 @@ class ChannelGeneratorTest < Rails::Generators::TestCase assert_match(/def mute/, channel) end - assert_file "app/assets/javascripts/channels/chat.js" do |channel| - assert_match(/App\.chat = App\.cable\.subscriptions\.create\("ChatChannel/, channel) + assert_file "app/javascript/channels/chat_channel.js" do |channel| + assert_match(/import consumer from "\.\/consumer"\s+consumer\.subscriptions\.create\("ChatChannel/, channel) assert_match(/,\n\n speak/, channel) assert_match(/,\n\n mute: function\(\) \{\n return this\.perform\('mute'\);\n \}\n\}\);/, channel) end @@ -54,15 +54,17 @@ class ChannelGeneratorTest < Rails::Generators::TestCase assert_match(/class ChatChannel < ApplicationCable::Channel/, channel) end - assert_no_file "app/assets/javascripts/channels/chat.js" + assert_no_file "app/javascript/channels/chat_channel.js" end def test_cable_js_is_created_if_not_present_already run_generator ["chat"] - FileUtils.rm("#{destination_root}/app/assets/javascripts/cable.js") + FileUtils.rm("#{destination_root}/app/javascript/channels/index.js") + FileUtils.rm("#{destination_root}/app/javascript/channels/consumer.js") run_generator ["camp"] - assert_file "app/assets/javascripts/cable.js" + assert_file "app/javascript/channels/index.js" + assert_file "app/javascript/channels/consumer.js" end def test_channel_on_revoke @@ -74,7 +76,8 @@ class ChannelGeneratorTest < Rails::Generators::TestCase assert_file "app/channels/application_cable/channel.rb" assert_file "app/channels/application_cable/connection.rb" - assert_file "app/assets/javascripts/cable.js" + assert_file "app/javascript/channels/index.js" + assert_file "app/javascript/channels/consumer.js" end def test_channel_suffix_is_not_duplicated @@ -84,6 +87,6 @@ class ChannelGeneratorTest < Rails::Generators::TestCase assert_file "app/channels/chat_channel.rb" assert_no_file "app/assets/javascripts/channels/chat_channel.js" - assert_file "app/assets/javascripts/channels/chat.js" + assert_file "app/javascript/channels/chat_channel.js" end end diff --git a/railties/test/generators/controller_generator_test.rb b/railties/test/generators/controller_generator_test.rb index 021004c9b8..adef56255a 100644 --- a/railties/test/generators/controller_generator_test.rb +++ b/railties/test/generators/controller_generator_test.rb @@ -39,13 +39,11 @@ class ControllerGeneratorTest < Rails::Generators::TestCase def test_invokes_assets run_generator - assert_file "app/assets/javascripts/account.js" assert_file "app/assets/stylesheets/account.css" end def test_does_not_invoke_assets_if_required run_generator ["account", "--skip-assets"] - assert_no_file "app/assets/javascripts/account.js" assert_no_file "app/assets/stylesheets/account.css" end @@ -133,7 +131,6 @@ class ControllerGeneratorTest < Rails::Generators::TestCase assert_file "app/helpers/account_helper.rb" assert_no_file "app/assets/javascripts/account_controller.js" - assert_file "app/assets/javascripts/account.js" assert_no_file "app/assets/stylesheets/account_controller.css" assert_file "app/assets/stylesheets/account.css" diff --git a/railties/test/generators/plugin_generator_test.rb b/railties/test/generators/plugin_generator_test.rb index 468a9c9e89..66286fc554 100644 --- a/railties/test/generators/plugin_generator_test.rb +++ b/railties/test/generators/plugin_generator_test.rb @@ -140,10 +140,6 @@ class PluginGeneratorTest < Rails::Generators::TestCase run_generator assert_file "test/dummy/app/assets/stylesheets/application.css" - - assert_file "test/dummy/app/assets/javascripts/application.js" do |contents| - assert_no_match(/jquery/, contents) - end end def test_ensure_that_plugin_options_are_not_passed_to_app_generator @@ -210,28 +206,10 @@ class PluginGeneratorTest < Rails::Generators::TestCase assert_no_file "#{destination_root}/Gemfile.lock" end - def test_skipping_javascripts_without_mountable_option - run_generator - assert_no_file "app/assets/javascripts/bukkits/application.js" - end - - def test_javascripts_generation - run_generator [destination_root, "--mountable"] - assert_file "app/assets/javascripts/bukkits/application.js" do |content| - assert_match "//= require rails-ujs", content - assert_match "//= require activestorage", content - assert_match "//= require_tree .", content - end - assert_file "app/views/layouts/bukkits/application.html.erb" do |content| - assert_match "javascript_include_tag", content - end - end - - def test_skip_javascripts + def test_skip_javascript run_generator [destination_root, "--skip-javascript", "--mountable"] - assert_no_file "app/assets/javascripts/bukkits/application.js" assert_file "app/views/layouts/bukkits/application.html.erb" do |content| - assert_no_match "javascript_include_tag", content + assert_no_match "javascript_pack_tag", content end end @@ -264,7 +242,6 @@ class PluginGeneratorTest < Rails::Generators::TestCase def test_creating_engine_in_full_mode run_generator [destination_root, "--full"] - assert_file "app/assets/javascripts/bukkits" assert_file "app/assets/stylesheets/bukkits" assert_file "app/assets/images/bukkits" assert_file "app/models" @@ -280,7 +257,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase def test_creating_engine_with_hyphenated_name_in_full_mode run_generator [File.join(destination_root, "hyphenated-name"), "--full"] - assert_file "hyphenated-name/app/assets/javascripts/hyphenated/name" + assert_no_file "hyphenated-name/app/assets/javascripts/hyphenated/name" assert_file "hyphenated-name/app/assets/stylesheets/hyphenated/name" assert_file "hyphenated-name/app/assets/images/hyphenated/name" assert_file "hyphenated-name/app/models" @@ -297,7 +274,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase def test_creating_engine_with_hyphenated_and_underscored_name_in_full_mode run_generator [File.join(destination_root, "my_hyphenated-name"), "--full"] - assert_file "my_hyphenated-name/app/assets/javascripts/my_hyphenated/name" + assert_no_file "my_hyphenated-name/app/assets/javascripts/my_hyphenated/name" assert_file "my_hyphenated-name/app/assets/stylesheets/my_hyphenated/name" assert_file "my_hyphenated-name/app/assets/images/my_hyphenated/name" assert_file "my_hyphenated-name/app/models" @@ -318,7 +295,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase def test_create_mountable_application_with_mountable_option run_generator [destination_root, "--mountable"] - assert_file "app/assets/javascripts/bukkits" + assert_no_file "app/assets/javascripts/bukkits" assert_file "app/assets/stylesheets/bukkits" assert_file "app/assets/images/bukkits" assert_file "config/routes.rb", /Bukkits::Engine\.routes\.draw do/ @@ -334,7 +311,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase assert_match "<%= csrf_meta_tags %>", contents assert_match "<%= csp_meta_tag %>", contents assert_match(/stylesheet_link_tag\s+['"]bukkits\/application['"]/, contents) - assert_match(/javascript_include_tag\s+['"]bukkits\/application['"]/, contents) + assert_no_match(/javascript_include_tag\s+['"]bukkits\/application['"]/, contents) assert_match "<%= yield %>", contents end assert_file "test/test_helper.rb" do |content| @@ -348,7 +325,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase def test_create_mountable_application_with_mountable_option_and_hypenated_name run_generator [File.join(destination_root, "hyphenated-name"), "--mountable"] - assert_file "hyphenated-name/app/assets/javascripts/hyphenated/name" + assert_no_file "hyphenated-name/app/assets/javascripts/hyphenated/name" assert_file "hyphenated-name/app/assets/stylesheets/hyphenated/name" assert_file "hyphenated-name/app/assets/images/hyphenated/name" assert_file "hyphenated-name/config/routes.rb", /Hyphenated::Name::Engine\.routes\.draw do/ @@ -364,13 +341,13 @@ class PluginGeneratorTest < Rails::Generators::TestCase assert_file "hyphenated-name/app/views/layouts/hyphenated/name/application.html.erb" do |contents| assert_match "Hyphenated name", contents assert_match(/stylesheet_link_tag\s+['"]hyphenated\/name\/application['"]/, contents) - assert_match(/javascript_include_tag\s+['"]hyphenated\/name\/application['"]/, contents) + assert_no_match(/javascript_include_tag\s+['"]hyphenated\/name\/application['"]/, contents) end end def test_create_mountable_application_with_mountable_option_and_hypenated_and_underscored_name run_generator [File.join(destination_root, "my_hyphenated-name"), "--mountable"] - assert_file "my_hyphenated-name/app/assets/javascripts/my_hyphenated/name" + assert_no_file "my_hyphenated-name/app/assets/javascripts/my_hyphenated/name" assert_file "my_hyphenated-name/app/assets/stylesheets/my_hyphenated/name" assert_file "my_hyphenated-name/app/assets/images/my_hyphenated/name" assert_file "my_hyphenated-name/config/routes.rb", /MyHyphenated::Name::Engine\.routes\.draw do/ @@ -386,13 +363,13 @@ class PluginGeneratorTest < Rails::Generators::TestCase assert_file "my_hyphenated-name/app/views/layouts/my_hyphenated/name/application.html.erb" do |contents| assert_match "My hyphenated name", contents assert_match(/stylesheet_link_tag\s+['"]my_hyphenated\/name\/application['"]/, contents) - assert_match(/javascript_include_tag\s+['"]my_hyphenated\/name\/application['"]/, contents) + assert_no_match(/javascript_include_tag\s+['"]my_hyphenated\/name\/application['"]/, contents) end end def test_create_mountable_application_with_mountable_option_and_multiple_hypenates_in_name run_generator [File.join(destination_root, "deep-hyphenated-name"), "--mountable"] - assert_file "deep-hyphenated-name/app/assets/javascripts/deep/hyphenated/name" + assert_no_file "deep-hyphenated-name/app/assets/javascripts/deep/hyphenated/name" assert_file "deep-hyphenated-name/app/assets/stylesheets/deep/hyphenated/name" assert_file "deep-hyphenated-name/app/assets/images/deep/hyphenated/name" assert_file "deep-hyphenated-name/config/routes.rb", /Deep::Hyphenated::Name::Engine\.routes\.draw do/ @@ -408,7 +385,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase assert_file "deep-hyphenated-name/app/views/layouts/deep/hyphenated/name/application.html.erb" do |contents| assert_match "Deep hyphenated name", contents assert_match(/stylesheet_link_tag\s+['"]deep\/hyphenated\/name\/application['"]/, contents) - assert_match(/javascript_include_tag\s+['"]deep\/hyphenated\/name\/application['"]/, contents) + assert_no_match(/javascript_include_tag\s+['"]deep\/hyphenated\/name\/application['"]/, contents) end end diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb index 94aab15aa9..21b5013484 100644 --- a/railties/test/generators/scaffold_generator_test.rb +++ b/railties/test/generators/scaffold_generator_test.rb @@ -93,7 +93,6 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Assets assert_file "app/assets/stylesheets/scaffold.css" - assert_file "app/assets/javascripts/product_lines.js" assert_file "app/assets/stylesheets/product_lines.css" end @@ -166,7 +165,6 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Assets assert_no_file "app/assets/stylesheets/scaffold.css" - assert_no_file "app/assets/javascripts/product_lines.js" assert_no_file "app/assets/stylesheets/product_lines.css" end @@ -222,7 +220,6 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Assets assert_file "app/assets/stylesheets/scaffold.css", /:visited/ - assert_no_file "app/assets/javascripts/product_lines.js" assert_no_file "app/assets/stylesheets/product_lines.css" end @@ -299,7 +296,6 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Assets assert_file "app/assets/stylesheets/scaffold.css", /:visited/ - assert_file "app/assets/javascripts/admin/roles.js" assert_file "app/assets/stylesheets/admin/roles.css" end @@ -335,7 +331,6 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Assets assert_file "app/assets/stylesheets/scaffold.css" - assert_no_file "app/assets/javascripts/admin/roles.js" assert_no_file "app/assets/stylesheets/admin/roles.css" end @@ -380,28 +375,24 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase def test_scaffold_generator_no_assets_with_switch_no_assets run_generator [ "posts", "--no-assets" ] assert_no_file "app/assets/stylesheets/scaffold.css" - assert_no_file "app/assets/javascripts/posts.js" assert_no_file "app/assets/stylesheets/posts.css" end def test_scaffold_generator_no_assets_with_switch_assets_false run_generator [ "posts", "--assets=false" ] assert_no_file "app/assets/stylesheets/scaffold.css" - assert_no_file "app/assets/javascripts/posts.js" assert_no_file "app/assets/stylesheets/posts.css" end def test_scaffold_generator_no_scaffold_stylesheet_with_switch_no_scaffold_stylesheet run_generator [ "posts", "--no-scaffold-stylesheet" ] assert_no_file "app/assets/stylesheets/scaffold.css" - assert_file "app/assets/javascripts/posts.js" assert_file "app/assets/stylesheets/posts.css" end def test_scaffold_generator_no_scaffold_stylesheet_with_switch_scaffold_stylesheet_false run_generator [ "posts", "--scaffold-stylesheet=false" ] assert_no_file "app/assets/stylesheets/scaffold.css" - assert_file "app/assets/javascripts/posts.js" assert_file "app/assets/stylesheets/posts.css" end @@ -429,17 +420,9 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase def test_scaffold_generator_no_stylesheets run_generator [ "posts", "--no-stylesheets" ] assert_no_file "app/assets/stylesheets/scaffold.css" - assert_file "app/assets/javascripts/posts.js" assert_no_file "app/assets/stylesheets/posts.css" end - def test_scaffold_generator_no_javascripts - run_generator [ "posts", "--no-javascripts" ] - assert_file "app/assets/stylesheets/scaffold.css" - assert_no_file "app/assets/javascripts/posts.js" - assert_file "app/assets/stylesheets/posts.css" - end - def test_scaffold_generator_outputs_error_message_on_missing_attribute_type run_generator ["post", "title", "body:text", "author"] @@ -630,7 +613,6 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase assert File.exist?("app/helpers/bukkits/users_helper.rb") - assert File.exist?("app/assets/javascripts/bukkits/users.js") assert File.exist?("app/assets/stylesheets/bukkits/users.css") end end @@ -660,7 +642,6 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase assert_not File.exist?("app/helpers/bukkits/users_helper.rb") - assert_not File.exist?("app/assets/javascripts/bukkits/users.js") assert_not File.exist?("app/assets/stylesheets/bukkits/users.css") end end diff --git a/railties/test/generators/shared_generator_tests.rb b/railties/test/generators/shared_generator_tests.rb index 5a1257e5c1..521f775553 100644 --- a/railties/test/generators/shared_generator_tests.rb +++ b/railties/test/generators/shared_generator_tests.rb @@ -27,7 +27,7 @@ module SharedGeneratorTests end def test_skeleton_is_created - run_generator + run_generator [destination_root, "--no-skip-javascript"] default_files.each { |path| assert_file path } end @@ -196,10 +196,12 @@ module SharedGeneratorTests end def test_generator_for_active_storage - run_generator + run_generator [destination_root, "--no-skip-javascript"] - assert_file "#{application_path}/app/assets/javascripts/application.js" do |content| - assert_match(/^\/\/= require activestorage/, content) + unless generator_class.name == "Rails::Generators::PluginGenerator" + assert_file "#{application_path}/app/javascript/packs/application.js" do |content| + assert_match(/^import \* as ActiveStorage from "activestorage"\nActiveStorage.start\(\)/, content) + end end assert_file "#{application_path}/config/environments/development.rb" do |content| @@ -224,11 +226,11 @@ module SharedGeneratorTests end def test_generator_if_skip_active_storage_is_given - run_generator [destination_root, "--skip-active-storage"] + run_generator [destination_root, "--skip-active-storage", "--no-skip-javascript"] assert_file "#{application_path}/config/application.rb", /#\s+require\s+["']active_storage\/engine["']/ - assert_file "#{application_path}/app/assets/javascripts/application.js" do |content| + assert_file "#{application_path}/app/javascript/packs/application.js" do |content| assert_no_match(/^\/\/= require activestorage/, content) end @@ -254,12 +256,12 @@ module SharedGeneratorTests end def test_generator_does_not_generate_active_storage_contents_if_skip_active_record_is_given - run_generator [destination_root, "--skip-active-record"] + run_generator [destination_root, "--skip-active-record", "--no-skip-javascript"] assert_file "#{application_path}/config/application.rb", /#\s+require\s+["']active_storage\/engine["']/ - assert_file "#{application_path}/app/assets/javascripts/application.js" do |content| - assert_no_match(/^\/\/= require activestorage/, content) + assert_file "#{application_path}/app/javascript/packs/application.js" do |content| + assert_no_match(/^import * as ActiveStorage from "activestorage"\nActiveStorage.start()/, content) end assert_file "#{application_path}/config/environments/development.rb" do |content| @@ -320,8 +322,6 @@ module SharedGeneratorTests assert_file "Gemfile" do |content| assert_no_match(/sass-rails/, content) - assert_no_match(/uglifier/, content) - assert_no_match(/coffee-rails/, content) end assert_file "#{application_path}/config/environments/development.rb" do |content| @@ -330,7 +330,6 @@ module SharedGeneratorTests assert_file "#{application_path}/config/environments/production.rb" do |content| assert_no_match(/config\.assets\.digest/, content) - assert_no_match(/config\.assets\.js_compressor/, content) assert_no_match(/config\.assets\.css_compressor/, content) assert_no_match(/config\.assets\.compile/, content) end diff --git a/railties/test/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb index 2a8c6d8f97..e44f21380e 100644 --- a/railties/test/isolation/abstract_unit.rb +++ b/railties/test/isolation/abstract_unit.rb @@ -30,11 +30,11 @@ require "rails/secrets" module TestHelpers module Paths def app_template_path - File.join Dir.tmpdir, "app_template" + File.join RAILS_FRAMEWORK_ROOT, "tmp/templates/app_template" end def tmp_path(*args) - @tmp_path ||= File.realpath(Dir.mktmpdir) + @tmp_path ||= File.realpath(Dir.mktmpdir(nil, File.join(RAILS_FRAMEWORK_ROOT, "tmp"))) File.join(@tmp_path, *args) end @@ -469,17 +469,28 @@ Module.new do # Build a rails app FileUtils.rm_rf(app_template_path) - FileUtils.mkdir(app_template_path) + FileUtils.mkdir_p(app_template_path) + + Dir.chdir "#{RAILS_FRAMEWORK_ROOT}/actionview" do + `yarn build` + end `#{Gem.ruby} #{RAILS_FRAMEWORK_ROOT}/railties/exe/rails new #{app_template_path} --skip-gemfile --skip-listen --no-rc` File.open("#{app_template_path}/config/boot.rb", "w") do |f| f.puts "require 'rails/all'" end + Dir.chdir(app_template_path) { `yarn add https://github.com/rails/webpacker.git` } # Use the latest version. + + # Manually install `webpack` as bin symlinks are not created for subdependencies + # in workspaces. See https://github.com/yarnpkg/yarn/issues/4964 + Dir.chdir(app_template_path) { `yarn add webpack@4.17.1 --tilde` } + Dir.chdir(app_template_path) { `yarn add webpack-cli` } + # Fake 'Bundler.require' -- we run using the repo's Gemfile, not an # app-specific one: we don't want to require every gem that lists. contents = File.read("#{app_template_path}/config/application.rb") - contents.sub!(/^Bundler\.require.*/, "%w(turbolinks).each { |r| require r }") + contents.sub!(/^Bundler\.require.*/, "%w(turbolinks webpacker).each { |r| require r }") File.write("#{app_template_path}/config/application.rb", contents) require "rails" -- cgit v1.2.3