shakapacker 6.0.0.rc.6

Sign up to get free protection for your applications and to get access to all the features.
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