Make Webpacker the default JavaScript compiler for Rails 6 (#33079)
* 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. 46215b1794
* 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
This commit is contained in:
parent
6d40d2d3d1
commit
4838c1716a
2
.gitignore
vendored
2
.gitignore
vendored
@ -14,3 +14,5 @@ debug.log
|
||||
node_modules/
|
||||
package-lock.json
|
||||
pkg/
|
||||
/tmp/
|
||||
/yarn.lock
|
@ -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.
|
||||
|
2
.yarnrc
Normal file
2
.yarnrc
Normal file
@ -0,0 +1,2 @@
|
||||
workspaces-experimental true
|
||||
--add.prefer-offline true
|
2
Gemfile
2
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.
|
||||
|
12
Gemfile.lock
12
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
|
||||
|
@ -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
|
||||
|
@ -16,10 +16,11 @@ def create_channel_file
|
||||
|
||||
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
|
||||
|
@ -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 -%>
|
@ -1,4 +1,6 @@
|
||||
App.<%= class_name.underscore %> = App.cable.subscriptions.create("<%= class_name %>Channel", {
|
||||
import consumer from "./consumer"
|
||||
|
||||
consumer.subscriptions.create("<%= class_name %>Channel", {
|
||||
connected: function() {
|
||||
// Called when the subscription is ready for use on the server
|
||||
},
|
@ -1,13 +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.
|
||||
//
|
||||
//= require action_cable
|
||||
//= require_self
|
||||
//= require_tree ./channels
|
||||
|
||||
(function() {
|
||||
this.App || (this.App = {});
|
||||
import ActionCable from "actioncable"
|
||||
|
||||
App.cable = ActionCable.createConsumer();
|
||||
|
||||
}).call(this);
|
||||
export default ActionCable.createConsumer()
|
@ -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)
|
@ -1,5 +1,3 @@
|
||||
|
||||
//= link_tree ../images
|
||||
//= link_directory ../javascripts .js
|
||||
//= link_directory ../stylesheets .css
|
||||
//= link active_storage_manifest.js
|
||||
|
@ -25,8 +25,7 @@
|
||||
# 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.
|
||||
|
72
activestorage/test/dummy/config/webpacker.yml
Normal file
72
activestorage/test/dummy/config/webpacker.yml
Normal file
@ -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
|
14
package.json
Normal file
14
package.json
Normal file
@ -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"
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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(",")
|
||||
|
@ -33,8 +33,6 @@ module Generators
|
||||
rails: {
|
||||
actions: "-a",
|
||||
orm: "-o",
|
||||
javascripts: "-j",
|
||||
javascript_engine: "-je",
|
||||
resource_controller: "-c",
|
||||
scaffold_controller: "-c",
|
||||
stylesheets: "-y",
|
||||
|
@ -68,10 +68,7 @@ def self.add_shared_options_for(name)
|
||||
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 @@ def convert_database_option_for_jruby
|
||||
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 @@ def jbuilder_gemfile_entry
|
||||
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 @@ def run_bundle
|
||||
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
|
||||
|
||||
|
@ -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
|
@ -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.
|
@ -80,7 +80,6 @@ def app
|
||||
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 @@ class AppGenerator < AppBase # :nodoc:
|
||||
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 @@ def delete_public_files_if_api_option
|
||||
|
||||
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 @@ def delete_action_mailer_files_skipping_action_mailer
|
||||
|
||||
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
|
||||
|
@ -1,5 +1,2 @@
|
||||
//= link_tree ../images
|
||||
<% unless options.skip_javascript -%>
|
||||
//= link_directory ../javascripts .js
|
||||
<% end -%>
|
||||
//= link_directory ../stylesheets .css
|
||||
|
@ -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 .
|
@ -1,13 +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.
|
||||
//
|
||||
//= require action_cable
|
||||
//= require_self
|
||||
//= require_tree ./channels
|
||||
|
||||
(function() {
|
||||
this.App || (this.App = {});
|
||||
import ActionCable from "actioncable"
|
||||
|
||||
App.cable = ActionCable.createConsumer();
|
||||
|
||||
}).call(this);
|
||||
export default ActionCable.createConsumer()
|
@ -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)
|
21
railties/lib/rails/generators/rails/app/templates/app/javascript/packs/application.js.tt
Normal file
21
railties/lib/rails/generators/rails/app/templates/app/javascript/packs/application.js.tt
Normal file
@ -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 -%>
|
@ -10,10 +10,10 @@
|
||||
<%- else -%>
|
||||
<%- unless options[:skip_turbolinks] -%>
|
||||
<%%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
|
||||
<%%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
|
||||
<%%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
|
||||
<%- else -%>
|
||||
<%%= stylesheet_link_tag 'application', media: 'all' %>
|
||||
<%%= javascript_include_tag 'application' %>
|
||||
<%%= javascript_pack_tag 'application' %>
|
||||
<%- end -%>
|
||||
<%- end -%>
|
||||
</head>
|
||||
|
@ -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.
|
||||
|
@ -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"
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.
|
@ -113,7 +113,7 @@ def test_dummy_config
|
||||
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
|
||||
|
@ -67,6 +67,9 @@ def destination(path)
|
||||
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
|
||||
|
@ -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),
|
||||
|
@ -68,20 +68,6 @@ def assert_no_file_exists(filename)
|
||||
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 @@ class ::PostsController < ActionController::Base ; end
|
||||
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
|
||||
|
@ -25,6 +25,7 @@ def app
|
||||
boot!
|
||||
|
||||
assert_equal [
|
||||
"Webpacker::DevServerProxy",
|
||||
"Rack::Sendfile",
|
||||
"ActionDispatch::Static",
|
||||
"ActionDispatch::Executor",
|
||||
@ -56,6 +57,7 @@ def app
|
||||
boot!
|
||||
|
||||
assert_equal [
|
||||
"Webpacker::DevServerProxy",
|
||||
"Rack::Sendfile",
|
||||
"ActionDispatch::Static",
|
||||
"ActionDispatch::Executor",
|
||||
@ -138,7 +140,7 @@ def app
|
||||
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 @@ def app
|
||||
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
|
||||
|
@ -118,7 +118,7 @@ def test_should_not_eager_load_model_for_rake
|
||||
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 @@ def test_scaffold_with_references_columns_tests_pass_by_default
|
||||
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)
|
||||
|
@ -24,7 +24,7 @@ def test_help_command_work_inside_engine
|
||||
|
||||
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 @@ def plugin_path
|
||||
|
||||
def spawn_command(command, fd)
|
||||
Process.spawn(
|
||||
{ "SKIP_REQUIRE_WEBPACKER" => "true" },
|
||||
"#{plugin_path}/bin/rails #{command}",
|
||||
in: fd, out: fd, err: fd
|
||||
)
|
||||
|
@ -40,7 +40,6 @@ def test_api_modified_files
|
||||
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)
|
||||
|
@ -13,10 +13,9 @@
|
||||
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 @@ def test_skip_bundle
|
||||
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 @@ def test_new_application_doesnt_need_defaults
|
||||
|
||||
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 @@ def test_generator_has_assets_gems
|
||||
run_generator
|
||||
|
||||
assert_gem "sass-rails"
|
||||
assert_gem "uglifier"
|
||||
end
|
||||
|
||||
def test_action_cable_redis_gems
|
||||
@ -601,24 +600,6 @@ def test_does_not_generate_system_test_files_if_skip_system_test_is_given
|
||||
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 @@ def test_javascript_is_skipped_if_required
|
||||
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 @@ def test_spring_with_dev_option
|
||||
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 @@ def test_webpack_option_with_js_framework
|
||||
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 @@ def test_after_bundle_callback
|
||||
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 @@ def test_after_bundle_callback
|
||||
end
|
||||
end
|
||||
|
||||
assert_equal 5, @sequence_step
|
||||
assert_equal 6, @sequence_step
|
||||
end
|
||||
|
||||
def test_gitignore
|
||||
|
@ -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
|
||||
|
@ -26,8 +26,8 @@ def test_channel_is_created
|
||||
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 @@ def test_channel_with_multiple_actions_is_created
|
||||
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 @@ def test_channel_asset_is_not_created_when_skip_assets_is_passed
|
||||
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 @@ def test_channel_on_revoke
|
||||
|
||||
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 @@ def test_channel_suffix_is_not_duplicated
|
||||
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
|
||||
|
@ -39,13 +39,11 @@ def test_does_not_invoke_helper_if_required
|
||||
|
||||
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 @@ def test_controller_suffix_is_not_duplicated
|
||||
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"
|
||||
|
@ -140,10 +140,6 @@ def test_generating_adds_dummy_app_without_javascript_and_assets_deps
|
||||
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 @@ def test_generation_does_not_run_bundle_install_with_full_and_mountable
|
||||
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 @@ def test_ensure_that_migration_tasks_work_with_mountable_option
|
||||
|
||||
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 @@ def test_creating_engine_in_full_mode
|
||||
|
||||
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 @@ def test_creating_engine_with_hyphenated_name_in_full_mode
|
||||
|
||||
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 @@ def test_being_quiet_while_creating_dummy_application
|
||||
|
||||
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 @@ def test_create_mountable_application_with_mountable_option
|
||||
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 @@ def test_create_mountable_application_with_mountable_option
|
||||
|
||||
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 @@ def test_create_mountable_application_with_mountable_option_and_hypenated_name
|
||||
assert_file "hyphenated-name/app/views/layouts/hyphenated/name/application.html.erb" do |contents|
|
||||
assert_match "<title>Hyphenated name</title>", 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 @@ def test_create_mountable_application_with_mountable_option_and_hypenated_and_un
|
||||
assert_file "my_hyphenated-name/app/views/layouts/my_hyphenated/name/application.html.erb" do |contents|
|
||||
assert_match "<title>My hyphenated name</title>", 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 @@ def test_create_mountable_application_with_mountable_option_and_multiple_hypenat
|
||||
assert_file "deep-hyphenated-name/app/views/layouts/deep/hyphenated/name/application.html.erb" do |contents|
|
||||
assert_match "<title>Deep hyphenated name</title>", 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
|
||||
|
||||
|
@ -93,7 +93,6 @@ def test_scaffold_on_invoke
|
||||
|
||||
# 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 @@ def test_api_scaffold_on_invoke
|
||||
|
||||
# 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 @@ def test_scaffold_on_revoke
|
||||
|
||||
# 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 @@ def test_scaffold_with_namespace_on_invoke
|
||||
|
||||
# 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 @@ def test_scaffold_with_namespace_on_revoke
|
||||
|
||||
# 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 @@ def test_scaffold_generator_ignores_commented_routes
|
||||
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 @@ def test_scaffold_generator_no_helper_with_switch_helper_false
|
||||
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 @@ def test_scaffold_on_invoke_inside_mountable_engine
|
||||
|
||||
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 @@ def test_scaffold_on_revoke_inside_mountable_engine
|
||||
|
||||
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
|
||||
|
@ -27,7 +27,7 @@ def application_path
|
||||
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 @@ def test_generator_if_skip_active_record_is_given
|
||||
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 @@ def test_generator_for_active_storage
|
||||
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 @@ def test_generator_if_skip_active_storage_is_given
|
||||
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 @@ def test_generator_if_skip_sprockets_is_given
|
||||
|
||||
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 @@ def test_generator_if_skip_sprockets_is_given
|
||||
|
||||
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
|
||||
|
@ -30,11 +30,11 @@
|
||||
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 @@ def frozen_error_class
|
||||
|
||||
# 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"
|
||||
|
Loading…
Reference in New Issue
Block a user