shakapacker 6.0.0.rc.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. checksums.yaml +7 -0
  2. data/.eslintignore +4 -0
  3. data/.eslintrc.js +14 -0
  4. data/.github/ISSUE_TEMPLATE/bug_report.md +20 -0
  5. data/.github/ISSUE_TEMPLATE/feature-request.md +18 -0
  6. data/.github/workflows/jest.yml +30 -0
  7. data/.github/workflows/js-lint.yml +31 -0
  8. data/.github/workflows/rubocop.yml +39 -0
  9. data/.github/workflows/ruby.yml +48 -0
  10. data/.gitignore +13 -0
  11. data/.node-version +1 -0
  12. data/.rubocop.yml +229 -0
  13. data/CHANGELOG.md +32 -0
  14. data/CONTRIBUTING.md +62 -0
  15. data/Gemfile +13 -0
  16. data/Gemfile.lock +183 -0
  17. data/MIT-LICENSE +20 -0
  18. data/README.md +666 -0
  19. data/Rakefile +11 -0
  20. data/config/README.md +3 -0
  21. data/config/webpacker.yml +1 -0
  22. data/docs/customizing_babel_config.md +59 -0
  23. data/docs/deployment.md +116 -0
  24. data/docs/developing_webpacker.md +29 -0
  25. data/docs/troubleshooting.md +212 -0
  26. data/docs/v6_upgrade.md +158 -0
  27. data/gemfiles/Gemfile-rails-edge +12 -0
  28. data/gemfiles/Gemfile-rails.5.2.x +9 -0
  29. data/gemfiles/Gemfile-rails.6.0.x +9 -0
  30. data/gemfiles/Gemfile-rails.6.1.x +12 -0
  31. data/lib/install/application.js +15 -0
  32. data/lib/install/bin/webpacker +15 -0
  33. data/lib/install/bin/webpacker-dev-server +18 -0
  34. data/lib/install/bin/yarn +18 -0
  35. data/lib/install/binstubs.rb +4 -0
  36. data/lib/install/config/webpack/webpack.config.js +5 -0
  37. data/lib/install/config/webpacker.yml +64 -0
  38. data/lib/install/package.json +15 -0
  39. data/lib/install/template.rb +100 -0
  40. data/lib/shakapacker/utils/git_utils.rb +23 -0
  41. data/lib/shakapacker/utils/version_syntax_converter.rb +24 -0
  42. data/lib/tasks/webpacker/binstubs.rake +15 -0
  43. data/lib/tasks/webpacker/check_binstubs.rake +12 -0
  44. data/lib/tasks/webpacker/check_node.rake +31 -0
  45. data/lib/tasks/webpacker/check_yarn.rake +33 -0
  46. data/lib/tasks/webpacker/clean.rake +25 -0
  47. data/lib/tasks/webpacker/clobber.rake +20 -0
  48. data/lib/tasks/webpacker/compile.rake +45 -0
  49. data/lib/tasks/webpacker/info.rake +21 -0
  50. data/lib/tasks/webpacker/install.rake +17 -0
  51. data/lib/tasks/webpacker/verify_config.rake +14 -0
  52. data/lib/tasks/webpacker/verify_install.rake +4 -0
  53. data/lib/tasks/webpacker/yarn_install.rake +18 -0
  54. data/lib/tasks/webpacker.rake +19 -0
  55. data/lib/tasks/yarn.rake +38 -0
  56. data/lib/webpacker/commands.rb +79 -0
  57. data/lib/webpacker/compiler.rb +130 -0
  58. data/lib/webpacker/configuration.rb +111 -0
  59. data/lib/webpacker/dev_server.rb +72 -0
  60. data/lib/webpacker/dev_server_proxy.rb +33 -0
  61. data/lib/webpacker/dev_server_runner.rb +96 -0
  62. data/lib/webpacker/env.rb +43 -0
  63. data/lib/webpacker/helper.rb +161 -0
  64. data/lib/webpacker/instance.rb +41 -0
  65. data/lib/webpacker/manifest.rb +120 -0
  66. data/lib/webpacker/railtie.rb +63 -0
  67. data/lib/webpacker/runner.rb +23 -0
  68. data/lib/webpacker/version.rb +4 -0
  69. data/lib/webpacker/webpack_runner.rb +58 -0
  70. data/lib/webpacker.rb +46 -0
  71. data/package/__tests__/config.js +34 -0
  72. data/package/__tests__/dev_server.js +45 -0
  73. data/package/__tests__/development.js +35 -0
  74. data/package/__tests__/env.js +58 -0
  75. data/package/__tests__/index.js +9 -0
  76. data/package/__tests__/production.js +29 -0
  77. data/package/__tests__/staging.js +30 -0
  78. data/package/__tests__/test.js +25 -0
  79. data/package/babel/preset.js +41 -0
  80. data/package/config.js +32 -0
  81. data/package/configPath.js +3 -0
  82. data/package/dev_server.js +20 -0
  83. data/package/env.js +27 -0
  84. data/package/environments/__tests__/base.js +69 -0
  85. data/package/environments/base.js +116 -0
  86. data/package/environments/development.js +55 -0
  87. data/package/environments/production.js +79 -0
  88. data/package/environments/test.js +3 -0
  89. data/package/index.js +33 -0
  90. data/package/inliningCss.js +7 -0
  91. data/package/rules/babel.js +30 -0
  92. data/package/rules/coffee.js +6 -0
  93. data/package/rules/css.js +3 -0
  94. data/package/rules/erb.js +15 -0
  95. data/package/rules/file.js +23 -0
  96. data/package/rules/index.js +18 -0
  97. data/package/rules/less.js +22 -0
  98. data/package/rules/raw.js +5 -0
  99. data/package/rules/sass.js +16 -0
  100. data/package/rules/stylus.js +26 -0
  101. data/package/utils/get_style_rule.js +37 -0
  102. data/package/utils/helpers.js +51 -0
  103. data/package.json +71 -0
  104. data/rakelib/release.rake +57 -0
  105. data/test/command_test.rb +109 -0
  106. data/test/compiler_test.rb +68 -0
  107. data/test/configuration_test.rb +78 -0
  108. data/test/dev_server_runner_test.rb +81 -0
  109. data/test/dev_server_test.rb +47 -0
  110. data/test/engine_rake_tasks_test.rb +39 -0
  111. data/test/env_test.rb +23 -0
  112. data/test/helper_test.rb +159 -0
  113. data/test/manifest_test.rb +89 -0
  114. data/test/mounted_app/Rakefile +4 -0
  115. data/test/mounted_app/test/dummy/Rakefile +3 -0
  116. data/test/mounted_app/test/dummy/bin/rails +3 -0
  117. data/test/mounted_app/test/dummy/bin/rake +3 -0
  118. data/test/mounted_app/test/dummy/config/application.rb +10 -0
  119. data/test/mounted_app/test/dummy/config/environment.rb +3 -0
  120. data/test/mounted_app/test/dummy/config/webpacker.yml +75 -0
  121. data/test/mounted_app/test/dummy/config.ru +5 -0
  122. data/test/mounted_app/test/dummy/package.json +7 -0
  123. data/test/rake_tasks_test.rb +71 -0
  124. data/test/test_app/Rakefile +3 -0
  125. data/test/test_app/app/packs/entrypoints/application.js +10 -0
  126. data/test/test_app/app/packs/entrypoints/multi_entry.css +4 -0
  127. data/test/test_app/app/packs/entrypoints/multi_entry.js +4 -0
  128. data/test/test_app/bin/webpacker +14 -0
  129. data/test/test_app/bin/webpacker-dev-server +14 -0
  130. data/test/test_app/config/application.rb +11 -0
  131. data/test/test_app/config/environment.rb +4 -0
  132. data/test/test_app/config/initializers/inspect_autoload_paths.rb +1 -0
  133. data/test/test_app/config/webpack/webpack.config.js +0 -0
  134. data/test/test_app/config/webpacker.yml +77 -0
  135. data/test/test_app/config/webpacker_other_location.yml +79 -0
  136. data/test/test_app/config/webpacker_public_root.yml +18 -0
  137. data/test/test_app/config.ru +5 -0
  138. data/test/test_app/package.json +13 -0
  139. data/test/test_app/public/packs/manifest.json +50 -0
  140. data/test/test_app/some.config.js +0 -0
  141. data/test/test_app/yarn.lock +11 -0
  142. data/test/test_helper.rb +33 -0
  143. data/test/webpack_runner_test.rb +57 -0
  144. data/test/webpacker_test.rb +34 -0
  145. data/webpacker.gemspec +31 -0
  146. data/yarn.lock +4029 -0
  147. metadata +331 -0
@@ -0,0 +1,79 @@
1
+ class Webpacker::Commands
2
+ delegate :config, :compiler, :manifest, :logger, to: :@webpacker
3
+
4
+ def initialize(webpacker)
5
+ @webpacker = webpacker
6
+ end
7
+
8
+ # Cleanup old assets in the compile directory. By default it will
9
+ # keep the latest version, 2 backups created within the past hour.
10
+ #
11
+ # Examples
12
+ #
13
+ # To force only 1 backup to be kept, set count=1 and age=0.
14
+ #
15
+ # To only keep files created within the last 10 minutes, set count=0 and
16
+ # age=600.
17
+ #
18
+ def clean(count = 2, age = 3600)
19
+ if config.public_output_path.exist? && config.public_manifest_path.exist?
20
+ packs
21
+ .map do |paths|
22
+ paths.map { |path| [Time.now - File.mtime(path), path] }
23
+ .sort
24
+ .reject.with_index do |(file_age, _), index|
25
+ file_age < age || index < count
26
+ end
27
+ .map { |_, path| path }
28
+ end
29
+ .flatten
30
+ .compact
31
+ .each do |file|
32
+ if File.file?(file)
33
+ File.delete(file)
34
+ logger.info "Removed #{file}"
35
+ end
36
+ end
37
+ end
38
+
39
+ true
40
+ end
41
+
42
+ def clobber
43
+ config.public_output_path.rmtree if config.public_output_path.exist?
44
+ config.cache_path.rmtree if config.cache_path.exist?
45
+ end
46
+
47
+ def bootstrap
48
+ manifest.refresh
49
+ end
50
+
51
+ def compile
52
+ compiler.compile.tap do |success|
53
+ manifest.refresh if success
54
+ end
55
+ end
56
+
57
+ private
58
+ def packs
59
+ all_files = Dir.glob("#{config.public_output_path}/**/*")
60
+ manifest_config = Dir.glob("#{config.public_manifest_path}*")
61
+
62
+ packs = all_files - manifest_config - current_version
63
+ packs.reject { |file| File.directory?(file) }.group_by do |path|
64
+ base, _, ext = File.basename(path).scan(/(.*)(-[\da-f]+)(\.\w+)/).flatten
65
+ "#{File.dirname(path)}/#{base}#{ext}"
66
+ end.values
67
+ end
68
+
69
+ def current_version
70
+ packs = manifest.refresh.values.map do |value|
71
+ value = value["src"] if value.is_a?(Hash)
72
+ next unless value.is_a?(String)
73
+
74
+ File.join(config.root_path, "public", "#{value}*")
75
+ end.compact
76
+
77
+ Dir.glob(packs).uniq
78
+ end
79
+ end
@@ -0,0 +1,130 @@
1
+ require "open3"
2
+ require "digest/sha1"
3
+
4
+ class Webpacker::Compiler
5
+ # Additional paths that test compiler needs to watch
6
+ # Webpacker::Compiler.watched_paths << 'bower_components'
7
+ #
8
+ # Deprecated. Use additional_paths in the YAML configuration instead.
9
+ cattr_accessor(:watched_paths) { [] }
10
+
11
+ # Additional environment variables that the compiler is being run with
12
+ # Webpacker::Compiler.env['FRONTEND_API_KEY'] = 'your_secret_key'
13
+ cattr_accessor(:env) { {} }
14
+
15
+ delegate :config, :logger, to: :webpacker
16
+
17
+ def initialize(webpacker)
18
+ @webpacker = webpacker
19
+ end
20
+
21
+ def compile
22
+ if stale?
23
+ run_webpack.tap do |success|
24
+ # We used to only record the digest on success
25
+ # However, the output file is still written on error, meaning that the digest should still be updated.
26
+ # If it's not, you can end up in a situation where a recompile doesn't take place when it should.
27
+ # See https://github.com/rails/webpacker/issues/2113
28
+ record_compilation_digest
29
+ end
30
+ else
31
+ logger.debug "Everything's up-to-date. Nothing to do"
32
+ true
33
+ end
34
+ end
35
+
36
+ # Returns true if all the compiled packs are up to date with the underlying asset files.
37
+ def fresh?
38
+ last_compilation_digest&.== watched_files_digest
39
+ end
40
+
41
+ # Returns true if the compiled packs are out of date with the underlying asset files.
42
+ def stale?
43
+ !fresh?
44
+ end
45
+
46
+ private
47
+ attr_reader :webpacker
48
+
49
+ def last_compilation_digest
50
+ compilation_digest_path.read if compilation_digest_path.exist? && config.public_manifest_path.exist?
51
+ rescue Errno::ENOENT, Errno::ENOTDIR
52
+ end
53
+
54
+ def watched_files_digest
55
+ if Rails.env.development?
56
+ warn <<~MSG.strip
57
+ Webpacker::Compiler - Slow setup for development
58
+
59
+ Prepare JS assets with either:
60
+ 1. Running `bin/webpack-dev-server`
61
+ 2. Set `compile` to false in webpacker.yml and run `bin/webpack -w`
62
+ MSG
63
+ end
64
+
65
+ warn "Webpacker::Compiler.watched_paths has been deprecated. Set additional_paths in webpacker.yml instead." unless watched_paths.empty?
66
+ root_path = Pathname.new(File.expand_path(config.root_path))
67
+ expanded_paths = [*default_watched_paths, *watched_paths].map do |path|
68
+ root_path.join(path)
69
+ end
70
+ files = Dir[*expanded_paths].reject { |f| File.directory?(f) }
71
+ file_ids = files.sort.map { |f| "#{File.basename(f)}/#{Digest::SHA1.file(f).hexdigest}" }
72
+ Digest::SHA1.hexdigest(file_ids.join("/"))
73
+ end
74
+
75
+ def record_compilation_digest
76
+ config.cache_path.mkpath
77
+ compilation_digest_path.write(watched_files_digest)
78
+ end
79
+
80
+ def optionalRubyRunner
81
+ bin_webpack_path = config.root_path.join("bin/webpacker")
82
+ first_line = File.readlines(bin_webpack_path).first.chomp
83
+ /ruby/.match?(first_line) ? RbConfig.ruby : ""
84
+ end
85
+
86
+ def run_webpack
87
+ logger.info "Compiling..."
88
+
89
+ stdout, stderr, status = Open3.capture3(
90
+ webpack_env,
91
+ "#{optionalRubyRunner} ./bin/webpacker",
92
+ chdir: File.expand_path(config.root_path)
93
+ )
94
+
95
+ if status.success?
96
+ logger.info "Compiled all packs in #{config.public_output_path}"
97
+ logger.error "#{stderr}" unless stderr.empty?
98
+
99
+ if config.webpack_compile_output?
100
+ logger.info stdout
101
+ end
102
+ else
103
+ non_empty_streams = [stdout, stderr].delete_if(&:empty?)
104
+ logger.error "\nCOMPILATION FAILED:\nEXIT STATUS: #{status}\nOUTPUTS:\n#{non_empty_streams.join("\n\n")}"
105
+ end
106
+
107
+ status.success?
108
+ end
109
+
110
+ def default_watched_paths
111
+ [
112
+ *config.additional_paths,
113
+ "#{config.source_path}/**/*",
114
+ "yarn.lock", "package.json",
115
+ "config/webpack/**/*"
116
+ ].freeze
117
+ end
118
+
119
+ def compilation_digest_path
120
+ config.cache_path.join("last-compilation-digest-#{webpacker.env}")
121
+ end
122
+
123
+ def webpack_env
124
+ return env unless defined?(ActionController::Base)
125
+
126
+ env.merge("WEBPACKER_ASSET_HOST" => ENV.fetch("WEBPACKER_ASSET_HOST", ActionController::Base.helpers.compute_asset_host),
127
+ "WEBPACKER_RELATIVE_URL_ROOT" => ENV.fetch("WEBPACKER_RELATIVE_URL_ROOT", ActionController::Base.relative_url_root),
128
+ "WEBPACKER_CONFIG" => webpacker.config_path.to_s)
129
+ end
130
+ end
@@ -0,0 +1,111 @@
1
+ require "yaml"
2
+ require "active_support/core_ext/hash/keys"
3
+ require "active_support/core_ext/hash/indifferent_access"
4
+
5
+ class Webpacker::Configuration
6
+ class << self
7
+ attr_accessor :installing
8
+ end
9
+
10
+ attr_reader :root_path, :config_path, :env
11
+
12
+ def initialize(root_path:, config_path:, env:)
13
+ @root_path = root_path
14
+ @config_path = config_path
15
+ @env = env
16
+ end
17
+
18
+ def dev_server
19
+ fetch(:dev_server)
20
+ end
21
+
22
+ def compile?
23
+ fetch(:compile)
24
+ end
25
+
26
+ def source_path
27
+ root_path.join(fetch(:source_path))
28
+ end
29
+
30
+ def additional_paths
31
+ fetch(:additional_paths)
32
+ end
33
+
34
+ def source_entry_path
35
+ source_path.join(fetch(:source_entry_path))
36
+ end
37
+
38
+ def public_path
39
+ root_path.join(fetch(:public_root_path))
40
+ end
41
+
42
+ def public_output_path
43
+ public_path.join(fetch(:public_output_path))
44
+ end
45
+
46
+ def public_manifest_path
47
+ public_output_path.join("manifest.json")
48
+ end
49
+
50
+ def cache_manifest?
51
+ fetch(:cache_manifest)
52
+ end
53
+
54
+ def cache_path
55
+ root_path.join(fetch(:cache_path))
56
+ end
57
+
58
+ def check_yarn_integrity=(value)
59
+ warn <<~EOS
60
+ Webpacker::Configuration#check_yarn_integrity=(value) is obsolete. The integrity
61
+ check has been removed from Webpacker (https://github.com/rails/webpacker/pull/2518)
62
+ so changing this setting will have no effect.
63
+ EOS
64
+ end
65
+
66
+ def webpack_compile_output?
67
+ fetch(:webpack_compile_output)
68
+ end
69
+
70
+ def fetch(key)
71
+ data.fetch(key, defaults[key])
72
+ end
73
+
74
+ private
75
+ def data
76
+ @data ||= load
77
+ end
78
+
79
+ def load
80
+ config = begin
81
+ YAML.load_file(config_path.to_s, aliases: true)
82
+ rescue ArgumentError
83
+ YAML.load_file(config_path.to_s)
84
+ end
85
+ config[env].deep_symbolize_keys
86
+ rescue Errno::ENOENT => e
87
+ if self.class.installing
88
+ {}
89
+ else
90
+ raise "Webpacker configuration file not found #{config_path}. " \
91
+ "Please run rails webpacker:install " \
92
+ "Error: #{e.message}"
93
+ end
94
+ rescue Psych::SyntaxError => e
95
+ raise "YAML syntax error occurred while parsing #{config_path}. " \
96
+ "Please note that YAML must be consistently indented using spaces. Tabs are not allowed. " \
97
+ "Error: #{e.message}"
98
+ end
99
+
100
+ def defaults
101
+ @defaults ||= begin
102
+ path = File.expand_path("../../install/config/webpacker.yml", __FILE__)
103
+ config = begin
104
+ YAML.load_file(path, aliases: true)
105
+ rescue ArgumentError
106
+ YAML.load_file(path)
107
+ end
108
+ HashWithIndifferentAccess.new(config[env])
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,72 @@
1
+ class Webpacker::DevServer
2
+ DEFAULT_ENV_PREFIX = "WEBPACKER_DEV_SERVER".freeze
3
+
4
+ # Configure dev server connection timeout (in seconds), default: 0.01
5
+ # Webpacker.dev_server.connect_timeout = 1
6
+ cattr_accessor(:connect_timeout) { 0.01 }
7
+
8
+ attr_reader :config
9
+
10
+ def initialize(config)
11
+ @config = config
12
+ end
13
+
14
+ def running?
15
+ if config.dev_server.present?
16
+ Socket.tcp(host, port, connect_timeout: connect_timeout).close
17
+ true
18
+ else
19
+ false
20
+ end
21
+ rescue
22
+ false
23
+ end
24
+
25
+ def host
26
+ fetch(:host)
27
+ end
28
+
29
+ def port
30
+ fetch(:port)
31
+ end
32
+
33
+ def https?
34
+ case fetch(:https)
35
+ when true, "true", Hash
36
+ true
37
+ else
38
+ false
39
+ end
40
+ end
41
+
42
+ def protocol
43
+ https? ? "https" : "http"
44
+ end
45
+
46
+ def host_with_port
47
+ "#{host}:#{port}"
48
+ end
49
+
50
+ def pretty?
51
+ fetch(:pretty)
52
+ end
53
+
54
+ def hmr?
55
+ fetch(:hmr)
56
+ end
57
+
58
+ def env_prefix
59
+ config.dev_server.fetch(:env_prefix, DEFAULT_ENV_PREFIX)
60
+ end
61
+
62
+ private
63
+ def fetch(key)
64
+ return nil unless config.dev_server.present?
65
+
66
+ ENV["#{env_prefix}_#{key.upcase}"] || config.dev_server.fetch(key, defaults[key])
67
+ end
68
+
69
+ def defaults
70
+ config.send(:defaults)[:dev_server] || {}
71
+ end
72
+ end
@@ -0,0 +1,33 @@
1
+ require "rack/proxy"
2
+
3
+ class Webpacker::DevServerProxy < Rack::Proxy
4
+ delegate :config, :dev_server, to: :@webpacker
5
+
6
+ def initialize(app = nil, opts = {})
7
+ @webpacker = opts.delete(:webpacker) || Webpacker.instance
8
+ opts[:streaming] = false if Rails.env.test? && !opts.key?(:streaming)
9
+ super
10
+ end
11
+
12
+ def perform_request(env)
13
+ if env["PATH_INFO"].start_with?("/#{public_output_uri_path}") && dev_server.running?
14
+ env["HTTP_HOST"] = env["HTTP_X_FORWARDED_HOST"] = dev_server.host
15
+ env["HTTP_X_FORWARDED_SERVER"] = dev_server.host_with_port
16
+ env["HTTP_PORT"] = env["HTTP_X_FORWARDED_PORT"] = dev_server.port.to_s
17
+ env["HTTP_X_FORWARDED_PROTO"] = env["HTTP_X_FORWARDED_SCHEME"] = dev_server.protocol
18
+ unless dev_server.https?
19
+ env["HTTPS"] = env["HTTP_X_FORWARDED_SSL"] = "off"
20
+ end
21
+ env["SCRIPT_NAME"] = ""
22
+
23
+ super(env)
24
+ else
25
+ @app.call(env)
26
+ end
27
+ end
28
+
29
+ private
30
+ def public_output_uri_path
31
+ config.public_output_path.relative_path_from(config.public_path).to_s + "/"
32
+ end
33
+ end
@@ -0,0 +1,96 @@
1
+ require "shellwords"
2
+ require "socket"
3
+ require "webpacker/configuration"
4
+ require "webpacker/dev_server"
5
+ require "webpacker/runner"
6
+
7
+ module Webpacker
8
+ class DevServerRunner < Webpacker::Runner
9
+ def run
10
+ load_config
11
+ detect_unsupported_switches!
12
+ detect_port!
13
+ execute_cmd
14
+ end
15
+
16
+ private
17
+
18
+ def load_config
19
+ app_root = Pathname.new(@app_path)
20
+
21
+ @config = Configuration.new(
22
+ root_path: app_root,
23
+ config_path: Pathname.new(@webpacker_config),
24
+ env: ENV["RAILS_ENV"]
25
+ )
26
+
27
+ dev_server = DevServer.new(@config)
28
+
29
+ @hostname = dev_server.host
30
+ @port = dev_server.port
31
+ @pretty = dev_server.pretty?
32
+ @https = dev_server.https?
33
+ @hot = dev_server.hmr?
34
+
35
+ rescue Errno::ENOENT, NoMethodError
36
+ $stdout.puts "webpack dev_server configuration not found in #{@config.config_path}[#{ENV["RAILS_ENV"]}]."
37
+ $stdout.puts "Please run bundle exec rails webpacker:install to install Webpacker"
38
+ exit!
39
+ end
40
+
41
+ UNSUPPORTED_SWITCHES = %w[--host --port]
42
+ private_constant :UNSUPPORTED_SWITCHES
43
+ def detect_unsupported_switches!
44
+ unsupported_switches = UNSUPPORTED_SWITCHES & @argv
45
+ if unsupported_switches.any?
46
+ $stdout.puts "The following CLI switches are not supported by Webpacker: #{unsupported_switches.join(' ')}. Please edit your command and try again."
47
+ exit!
48
+ end
49
+
50
+ if @argv.include?("--https") && !@https
51
+ $stdout.puts "Please set https: true in webpacker.yml to use the --https command line flag."
52
+ exit!
53
+ end
54
+ end
55
+
56
+ def detect_port!
57
+ server = TCPServer.new(@hostname, @port)
58
+ server.close
59
+
60
+ rescue Errno::EADDRINUSE
61
+ $stdout.puts "Another program is running on port #{@port}. Set a new port in #{@config.config_path} for dev_server"
62
+ exit!
63
+ end
64
+
65
+ def execute_cmd
66
+ env = Webpacker::Compiler.env
67
+ env["WEBPACKER_CONFIG"] = @webpacker_config
68
+ env["WEBPACK_SERVE"] = "true"
69
+
70
+ cmd = if node_modules_bin_exist?
71
+ ["#{@node_modules_bin_path}/webpack", "serve"]
72
+ else
73
+ ["yarn", "webpack", "serve"]
74
+ end
75
+
76
+ if @argv.include?("--debug-webpacker")
77
+ cmd = [ "node", "--inspect-brk", "--trace-warnings" ] + cmd
78
+ @argv.delete "--debug-webpacker"
79
+ end
80
+
81
+ cmd += ["--config", @webpack_config]
82
+ cmd += ["--progress", "--color"] if @pretty
83
+
84
+ cmd += ["--hot"] if @hot
85
+ cmd += @argv
86
+
87
+ Dir.chdir(@app_path) do
88
+ Kernel.exec env, *cmd
89
+ end
90
+ end
91
+
92
+ def node_modules_bin_exist?
93
+ File.exist?("#{@node_modules_bin_path}/webpack-dev-server")
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,43 @@
1
+ class Webpacker::Env
2
+ DEFAULT = "production".freeze
3
+
4
+ delegate :config_path, :logger, to: :@webpacker
5
+
6
+ def self.inquire(webpacker)
7
+ new(webpacker).inquire
8
+ end
9
+
10
+ def initialize(webpacker)
11
+ @webpacker = webpacker
12
+ end
13
+
14
+ def inquire
15
+ fallback_env_warning if config_path.exist? && !current
16
+ current || DEFAULT.inquiry
17
+ end
18
+
19
+ private
20
+ def current
21
+ Rails.env.presence_in(available_environments)
22
+ end
23
+
24
+ def fallback_env_warning
25
+ logger.info "RAILS_ENV=#{Rails.env} environment is not defined in config/webpacker.yml, falling back to #{DEFAULT} environment"
26
+ end
27
+
28
+ def available_environments
29
+ if config_path.exist?
30
+ begin
31
+ YAML.load_file(config_path.to_s, aliases: true)
32
+ rescue ArgumentError
33
+ YAML.load_file(config_path.to_s)
34
+ end
35
+ else
36
+ [].freeze
37
+ end
38
+ rescue Psych::SyntaxError => e
39
+ raise "YAML syntax error occurred while parsing #{config_path}. " \
40
+ "Please note that YAML must be consistently indented using spaces. Tabs are not allowed. " \
41
+ "Error: #{e.message}"
42
+ end
43
+ end