webpacker-react-on-rails 2.0

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 (81) hide show
  1. checksums.yaml +7 -0
  2. data/.eslintrc.js +14 -0
  3. data/.gitignore +4 -0
  4. data/.rubocop.yml +124 -0
  5. data/.travis.yml +22 -0
  6. data/CHANGELOG.md +208 -0
  7. data/Gemfile +21 -0
  8. data/Gemfile.lock +137 -0
  9. data/MIT-LICENSE +20 -0
  10. data/README.md +1244 -0
  11. data/Rakefile +12 -0
  12. data/lib/install/angular.rb +18 -0
  13. data/lib/install/bin/webpack-dev-server.tt +71 -0
  14. data/lib/install/bin/webpack.tt +32 -0
  15. data/lib/install/config/.babelrc +18 -0
  16. data/lib/install/config/.postcssrc.yml +3 -0
  17. data/lib/install/config/loaders/core/assets.js +12 -0
  18. data/lib/install/config/loaders/core/babel.js +5 -0
  19. data/lib/install/config/loaders/core/coffee.js +4 -0
  20. data/lib/install/config/loaders/core/erb.js +9 -0
  21. data/lib/install/config/loaders/core/sass.js +18 -0
  22. data/lib/install/config/loaders/installers/angular.js +4 -0
  23. data/lib/install/config/loaders/installers/elm.js +20 -0
  24. data/lib/install/config/loaders/installers/react.js +5 -0
  25. data/lib/install/config/loaders/installers/vue.js +41 -0
  26. data/lib/install/config/webpack/configuration.js +45 -0
  27. data/lib/install/config/webpack/development.js +31 -0
  28. data/lib/install/config/webpack/production.js +35 -0
  29. data/lib/install/config/webpack/shared.js +53 -0
  30. data/lib/install/config/webpack/test.js +6 -0
  31. data/lib/install/config/webpacker.yml +47 -0
  32. data/lib/install/elm.rb +29 -0
  33. data/lib/install/examples/angular/hello_angular.js +7 -0
  34. data/lib/install/examples/angular/hello_angular/app/app.component.ts +9 -0
  35. data/lib/install/examples/angular/hello_angular/app/app.module.ts +16 -0
  36. data/lib/install/examples/angular/hello_angular/index.ts +6 -0
  37. data/lib/install/examples/angular/hello_angular/polyfills.ts +19 -0
  38. data/lib/install/examples/angular/tsconfig.json +19 -0
  39. data/lib/install/examples/elm/Main.elm +54 -0
  40. data/lib/install/examples/elm/hello_elm.js +11 -0
  41. data/lib/install/examples/react/.babelrc +6 -0
  42. data/lib/install/examples/react/hello_react.jsx +26 -0
  43. data/lib/install/examples/vue/app.vue +22 -0
  44. data/lib/install/examples/vue/hello_vue.js +43 -0
  45. data/lib/install/javascript/packs/application.js +10 -0
  46. data/lib/install/react.rb +31 -0
  47. data/lib/install/template.rb +42 -0
  48. data/lib/install/vue.rb +15 -0
  49. data/lib/tasks/installers.rake +22 -0
  50. data/lib/tasks/webpacker.rake +19 -0
  51. data/lib/tasks/webpacker/check_binstubs.rake +12 -0
  52. data/lib/tasks/webpacker/check_node.rake +20 -0
  53. data/lib/tasks/webpacker/check_yarn.rake +15 -0
  54. data/lib/tasks/webpacker/clobber.rake +17 -0
  55. data/lib/tasks/webpacker/compile.rake +38 -0
  56. data/lib/tasks/webpacker/install.rake +12 -0
  57. data/lib/tasks/webpacker/verify_install.rake +16 -0
  58. data/lib/tasks/webpacker/yarn_install.rake +6 -0
  59. data/lib/webpacker.rb +26 -0
  60. data/lib/webpacker/compiler.rb +59 -0
  61. data/lib/webpacker/configuration.rb +83 -0
  62. data/lib/webpacker/dev_server.rb +78 -0
  63. data/lib/webpacker/env.rb +23 -0
  64. data/lib/webpacker/file_loader.rb +47 -0
  65. data/lib/webpacker/helper.rb +69 -0
  66. data/lib/webpacker/manifest.rb +101 -0
  67. data/lib/webpacker/railtie.rb +18 -0
  68. data/lib/webpacker/version.rb +3 -0
  69. data/package.json +31 -0
  70. data/test/compiler_test.rb +25 -0
  71. data/test/configuration_test.rb +36 -0
  72. data/test/dev_server_test.rb +56 -0
  73. data/test/env_test.rb +14 -0
  74. data/test/helper_test.rb +45 -0
  75. data/test/manifest_test.rb +77 -0
  76. data/test/test_app/config/secrets.yml +5 -0
  77. data/test/test_app/public/packs/manifest.json +6 -0
  78. data/test/webpacker_test.rb +20 -0
  79. data/webpacker.gemspec +23 -0
  80. data/yarn.lock +1014 -0
  81. metadata +192 -0
@@ -0,0 +1,22 @@
1
+ INSTALLERS = {
2
+ "Angular": :angular,
3
+ "Elm": :elm,
4
+ "React": :react,
5
+ "Vue": :vue
6
+ }.freeze
7
+
8
+ namespace :webpacker do
9
+ namespace :install do
10
+ INSTALLERS.each do |name, task_name|
11
+ desc "Install everything needed for #{name}"
12
+ task task_name => ["webpacker:verify_install"] do
13
+ template = File.expand_path("../install/#{task_name}.rb", __dir__)
14
+ if Rails::VERSION::MAJOR >= 5
15
+ exec "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{template}"
16
+ else
17
+ exec "#{RbConfig.ruby} ./bin/rake rails:template LOCATION=#{template}"
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,19 @@
1
+ tasks = {
2
+ "webpacker:install" => "Installs and setup webpack with yarn",
3
+ "webpacker:compile" => "Compiles webpack bundles based on environment",
4
+ "webpacker:check_node" => "Verifies if Node.js is installed",
5
+ "webpacker:check_yarn" => "Verifies if yarn is installed",
6
+ "webpacker:check_binstubs" => "Verifies that bin/webpack & bin/webpack-dev-server are present",
7
+ "webpacker:verify_install" => "Verifies if webpacker is installed",
8
+ "webpacker:yarn_install" => "Support for older Rails versions. Install all JavaScript dependencies as specified via Yarn",
9
+ "webpacker:install:react" => "Installs and setup example React component",
10
+ "webpacker:install:vue" => "Installs and setup example Vue component",
11
+ "webpacker:install:angular" => "Installs and setup example Angular component",
12
+ "webpacker:install:elm" => "Installs and setup example Elm component"
13
+ }.freeze
14
+
15
+ desc "Lists all available tasks in webpacker"
16
+ task :webpacker do
17
+ puts "Available webpacker tasks are:"
18
+ tasks.each { |task, message| puts task.ljust(30) + message }
19
+ end
@@ -0,0 +1,12 @@
1
+ namespace :webpacker do
2
+ desc "Verifies that bin/webpack & bin/webpack-dev-server are present."
3
+ task :check_binstubs do
4
+ unless File.exist?("bin/webpack") && File.exist?("bin/webpack-dev-server")
5
+ $stderr.puts "Webpack binstubs not found.\n"\
6
+ "Have you run rails webpacker:install ?\n"\
7
+ "Make sure the bin directory or binstubs are not included in .gitignore\n"\
8
+ "Exiting!"
9
+ exit!
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,20 @@
1
+ namespace :webpacker do
2
+ desc "Verifies if Node.js is installed"
3
+ task :check_node do
4
+ begin
5
+ node_version = `node -v`
6
+ node_version = `nodejs -v` if node_version.blank?
7
+ required_node_version = "6.4"
8
+
9
+ raise Errno::ENOENT if node_version.blank?
10
+ if Gem::Version.new(node_version.strip.tr("v", "")) < Gem::Version.new(required_node_version)
11
+ $stderr.puts "Webpacker requires Node.js >= v#{required_node_version} and you are using #{node_version}"
12
+ $stderr.puts "Please upgrade Node.js https://nodejs.org/en/download/"
13
+ $stderr.puts "Exiting!" && exit!
14
+ end
15
+ rescue Errno::ENOENT
16
+ $stderr.puts "Node.js not installed. Please download and install Node.js https://nodejs.org/en/download/"
17
+ $stderr.puts "Exiting!" && exit!
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,15 @@
1
+ namespace :webpacker do
2
+ desc "Verifies if yarn is installed"
3
+ task :check_yarn do
4
+ required_yarn_version = "0.20.1"
5
+
6
+ begin
7
+ yarn_version = `yarn --version`
8
+
9
+ raise Errno::ENOENT if yarn_version.blank? || Gem::Version.new(yarn_version) < Gem::Version.new(required_yarn_version)
10
+ rescue Errno::ENOENT
11
+ $stderr.puts "Webpacker requires Yarn version >= #{required_yarn_version}. Please download and install the latest version from https://yarnpkg.com/lang/en/docs/install/"
12
+ $stderr.puts "Exiting!" && exit!
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ require "webpacker/configuration"
2
+
3
+ namespace :webpacker do
4
+ desc "Remove the webpack compiled output directory"
5
+ task clobber: ["webpacker:verify_install", :environment] do
6
+ output_path = Webpacker::Configuration.output_path
7
+ FileUtils.rm_r(output_path) if File.exist?(output_path)
8
+ $stdout.puts "Removed webpack output path directory #{output_path}"
9
+ end
10
+ end
11
+
12
+ # Run clobber if the assets:clobber is run
13
+ if Rake::Task.task_defined?("assets:clobber")
14
+ Rake::Task["assets:clobber"].enhance do
15
+ Rake::Task["webpacker:clobber"].invoke
16
+ end
17
+ end
@@ -0,0 +1,38 @@
1
+ $stdout.sync = true
2
+
3
+ require "open3"
4
+ require "webpacker/env"
5
+ require "webpacker/configuration"
6
+
7
+ namespace :webpacker do
8
+ desc "Compile javascript packs using webpack for production with digests"
9
+ task compile: ["webpacker:verify_install", :environment] do
10
+ $stdout.puts "[Webpacker] Compiling assets 🎉"
11
+
12
+ asset_host = ActionController::Base.helpers.compute_asset_host
13
+ env = { "NODE_ENV" => Webpacker.env, "ASSET_HOST" => asset_host }.freeze
14
+
15
+ stdout_str, stderr_str, status = Open3.capture3(env, "./bin/webpack")
16
+
17
+ if status.success?
18
+ $stdout.puts "\e[32m[Webpacker] Compiled digests for all packs in #{Webpacker::Configuration.entry_path}:\e[0m"
19
+ $stdout.puts "\e[32m#{JSON.parse(File.read(Webpacker::Configuration.manifest_path))}\e[0m"
20
+ else
21
+ $stdout.puts "[Webpacker] Compilation Failed"
22
+ $stdout.puts "\e[31m#{stdout_str}\e[0m"
23
+ $stderr.puts "\e[31m#{stderr_str}\e[0m"
24
+ exit!
25
+ end
26
+ end
27
+ end
28
+
29
+ # Compile packs after we've compiled all other assets during precompilation
30
+ if Rake::Task.task_defined?("assets:precompile")
31
+ Rake::Task["assets:precompile"].enhance do
32
+ unless Rake::Task.task_defined?("yarn:install")
33
+ # For Rails < 5.1
34
+ Rake::Task["webpacker:yarn_install"].invoke
35
+ end
36
+ Rake::Task["webpacker:compile"].invoke
37
+ end
38
+ end
@@ -0,0 +1,12 @@
1
+ WEBPACKER_APP_TEMPLATE_PATH = File.expand_path("../../install/template.rb", __dir__)
2
+
3
+ namespace :webpacker do
4
+ desc "Install webpacker in this application"
5
+ task install: [:check_node, :check_yarn] do
6
+ if Rails::VERSION::MAJOR >= 5
7
+ exec "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{WEBPACKER_APP_TEMPLATE_PATH}"
8
+ else
9
+ exec "#{RbConfig.ruby} ./bin/rake rails:template LOCATION=#{WEBPACKER_APP_TEMPLATE_PATH}"
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ require "webpacker/configuration"
2
+
3
+ namespace :webpacker do
4
+ desc "Verifies if webpacker is installed"
5
+ task verify_install: [:check_node, :check_yarn, :check_binstubs] do
6
+ if File.exist?(Webpacker::Configuration.file_path)
7
+ $stdout.puts "Webpacker is installed 🎉 🍰"
8
+ $stdout.puts "Using #{Webpacker::Configuration.file_path} file for setting up webpack paths"
9
+ else
10
+ $stderr.puts "Configuration config/webpacker.yml file not found. \n"\
11
+ "Make sure webpacker:install is run successfully before " \
12
+ "running dependent tasks"
13
+ exit!
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,6 @@
1
+ namespace :webpacker do
2
+ desc "Support for older Rails versions.Install all JavaScript dependencies as specified via Yarn"
3
+ task :yarn_install, [:arg1, :arg2] do |task, args|
4
+ system "yarn #{args[:arg1]} #{args[:arg2]}"
5
+ end
6
+ end
@@ -0,0 +1,26 @@
1
+ module Webpacker
2
+ extend self
3
+
4
+ def bootstrap
5
+ Webpacker::Env.load_instance
6
+ Webpacker::Configuration.load_instance
7
+ Webpacker::DevServer.load_instance
8
+ Webpacker::Manifest.load_instance
9
+ end
10
+
11
+ def compile
12
+ Webpacker::Compiler.compile
13
+ Webpacker::Manifest.load_instance
14
+ end
15
+
16
+ def env
17
+ Webpacker::Env.current.inquiry
18
+ end
19
+ end
20
+
21
+ require "webpacker/env"
22
+ require "webpacker/configuration"
23
+ require "webpacker/dev_server"
24
+ require "webpacker/manifest"
25
+ require "webpacker/compiler"
26
+ require "webpacker/railtie" if defined?(Rails)
@@ -0,0 +1,59 @@
1
+ require "rake"
2
+
3
+ module Webpacker::Compiler
4
+ extend self
5
+
6
+ # Additional paths that test compiler needs to watch
7
+ # Webpacker::Compiler.watched_paths << 'bower_components'
8
+ mattr_accessor(:watched_paths) { [] }
9
+
10
+ # Compiler cache directory
11
+ # Webpacker::Compiler.cache_dir = 'tmp/cache'
12
+ mattr_accessor(:cache_dir) { "tmp/webpacker" }
13
+
14
+ def compile
15
+ return unless compile?
16
+ cache_source_timestamp
17
+ compile_task.invoke
18
+ compile_task.reenable
19
+ end
20
+
21
+ def compile?
22
+ return true unless File.exist?(cached_timestamp_path)
23
+ return true unless File.exist?(Webpacker::Configuration.output_path)
24
+
25
+ File.read(cached_timestamp_path) != current_source_timestamp
26
+ end
27
+
28
+ def default_watched_paths
29
+ ["#{Webpacker::Configuration.source}/**/*", "yarn.lock", "package.json", "config/webpack/**/*"].freeze
30
+ end
31
+
32
+ private
33
+ def current_source_timestamp
34
+ files = Dir[*default_watched_paths, *watched_paths].reject { |f| File.directory?(f) }
35
+ files.map { |f| File.mtime(f).utc.to_i }.max.to_s
36
+ end
37
+
38
+ def cache_source_timestamp
39
+ File.write(cached_timestamp_path, current_source_timestamp)
40
+ end
41
+
42
+ def cached_timestamp_path
43
+ FileUtils.mkdir_p(cache_dir) unless File.directory?(cache_dir)
44
+ Rails.root.join(cache_dir, ".compiler-timestamp")
45
+ end
46
+
47
+ def compile_task
48
+ @compile_task ||= load_rake_task("webpacker:compile")
49
+ end
50
+
51
+ def load_rake_task(name)
52
+ load_rakefile unless Rake::Task.task_defined?(name)
53
+ Rake::Task[name]
54
+ end
55
+
56
+ def load_rakefile
57
+ @load_rakefile ||= Rake.load_rakefile(Rails.root.join("Rakefile"))
58
+ end
59
+ end
@@ -0,0 +1,83 @@
1
+ # Loads webpacker configuration from config/webpacker.yml
2
+
3
+ require "webpacker/file_loader"
4
+
5
+ class Webpacker::Configuration < Webpacker::FileLoader
6
+ class << self
7
+ def reset
8
+ @defaults = nil
9
+ super
10
+ end
11
+
12
+ def entry_path
13
+ source_path.join(fetch(:source_entry_path))
14
+ end
15
+
16
+ def public_output_path
17
+ fetch(:public_output_path)
18
+ end
19
+
20
+ def output_path
21
+ public_path.join(public_output_path)
22
+ end
23
+
24
+ def manifest_path
25
+ output_path.join("manifest.json")
26
+ end
27
+
28
+ def source_path
29
+ Rails.root.join(source)
30
+ end
31
+
32
+ def public_path
33
+ Rails.root.join("public")
34
+ end
35
+
36
+ def file_path(root: Rails.root)
37
+ root.join("config/webpacker.yml")
38
+ end
39
+
40
+ def default_file_path
41
+ file_path(root: Pathname.new(__dir__).join("../install"))
42
+ end
43
+
44
+ def source
45
+ fetch(:source_path)
46
+ end
47
+
48
+ def compile?
49
+ fetch(:compile)
50
+ end
51
+
52
+ def fetch(key)
53
+ data.fetch(key, defaults[key])
54
+ end
55
+
56
+ def data
57
+ load_instance if Webpacker.env.development?
58
+ raise Webpacker::FileLoader::FileLoaderError.new("Webpacker::Configuration.load_data must be called first") unless instance
59
+ instance.data
60
+ end
61
+
62
+ def defaults
63
+ @defaults ||= HashWithIndifferentAccess.new(YAML.load(default_file_path.read)[Webpacker.env])
64
+ end
65
+
66
+ # Uses the webpack dev server host if appropriate
67
+ def output_path_or_url
68
+ if Webpacker::DevServer.dev_server?
69
+ Webpacker::DevServer.base_url
70
+ else
71
+ # Ensure we start with a slash so that the asset helpers don't prepend the default asset
72
+ # pipeline locations.
73
+ public_output_path.starts_with?("/") ? public_output_path : "/#{public_output_path}"
74
+ end
75
+ end
76
+ end
77
+
78
+ private
79
+ def load_data
80
+ return Webpacker::Configuration.defaults unless File.exist?(@path)
81
+ HashWithIndifferentAccess.new(YAML.load(File.read(@path))[Webpacker.env])
82
+ end
83
+ end
@@ -0,0 +1,78 @@
1
+ # Same convention as manifest/configuration.rb
2
+
3
+ # Loads webpacker configuration from config/webpacker.yml
4
+
5
+ require "webpacker/configuration"
6
+
7
+ class Webpacker::DevServer < Webpacker::FileLoader
8
+ class << self
9
+ def dev_server?
10
+ !dev_server_values.nil?
11
+ end
12
+
13
+ # read settings for dev_server
14
+ def hot?
15
+ return false unless dev_server?
16
+ if ENV["WEBPACKER_HMR"].present?
17
+ val = ENV["WEBPACKER_HMR"].downcase
18
+ return true if val == "true"
19
+ return false if val == "false"
20
+ raise new ArgumentError("WEBPACKER_HMR value is #{ENV['WEBPACKER_HMR']}. Set to TRUE|FALSE")
21
+ end
22
+ fetch(:hot)
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
+ fetch(:https)
35
+ end
36
+
37
+ def protocol
38
+ https? ? "https" : "http"
39
+ end
40
+
41
+ def file_path
42
+ Webpacker::Configuration.file_path
43
+ end
44
+
45
+ # Uses the hot_reloading_host if appropriate
46
+ def base_url
47
+ "#{protocol}://#{host}:#{port}"
48
+ end
49
+
50
+ private
51
+
52
+ def dev_server_values
53
+ data.fetch(:dev_server, nil)
54
+ end
55
+
56
+ def fetch(key)
57
+ return nil unless dev_server?
58
+ dev_server_values.fetch(key, dev_server_defaults[key])
59
+ end
60
+
61
+ def data
62
+ load_instance if Webpacker.env.development?
63
+ unless instance
64
+ raise Webpacker::FileLoader::FileLoaderError.new("Webpacker::DevServer.load_data must be called first")
65
+ end
66
+ instance.data
67
+ end
68
+
69
+ def dev_server_defaults
70
+ @defaults ||= Webpacker::Configuration.defaults[:dev_server]
71
+ end
72
+ end
73
+
74
+ private
75
+ def load_data
76
+ Webpacker::Configuration.instance.data
77
+ end
78
+ end
@@ -0,0 +1,23 @@
1
+ # Singleton registry for determining NODE_ENV from config/webpacker.yml
2
+ require "webpacker/file_loader"
3
+
4
+ class Webpacker::Env < Webpacker::FileLoader
5
+ class << self
6
+ def current
7
+ raise Webpacker::FileLoader::FileLoaderError.new("Webpacker::Env.load must be called first") unless instance
8
+ instance.data
9
+ end
10
+
11
+ def file_path
12
+ Rails.root.join("config", "webpacker.yml")
13
+ end
14
+ end
15
+
16
+ private
17
+ def load_data
18
+ environments = File.exist?(@path) ? YAML.load(File.read(@path)).keys : [].freeze
19
+ return ENV["NODE_ENV"] if environments.include?(ENV["NODE_ENV"])
20
+ return Rails.env if environments.include?(Rails.env)
21
+ "production"
22
+ end
23
+ end