webpacker 1.2 → 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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/CHANGELOG.md +93 -9
  4. data/Gemfile.lock +2 -2
  5. data/README.md +979 -93
  6. data/lib/install/angular.rb +2 -2
  7. data/lib/install/bin/webpack-dev-server.tt +20 -10
  8. data/lib/install/bin/webpack.tt +10 -15
  9. data/lib/install/config/.babelrc +13 -1
  10. data/lib/install/config/loaders/core/sass.js +3 -2
  11. data/lib/install/config/loaders/installers/elm.js +20 -0
  12. data/lib/install/config/loaders/installers/vue.js +1 -0
  13. data/lib/install/config/webpack/configuration.js +22 -13
  14. data/lib/install/config/webpack/development.js +17 -1
  15. data/lib/install/config/webpack/production.js +16 -2
  16. data/lib/install/config/webpack/shared.js +15 -11
  17. data/lib/install/config/{webpack/paths.yml → webpacker.yml} +12 -7
  18. data/lib/install/elm.rb +29 -0
  19. data/lib/install/examples/angular/tsconfig.json +1 -0
  20. data/lib/install/examples/elm/Main.elm +54 -0
  21. data/lib/install/examples/elm/hello_elm.js +11 -0
  22. data/lib/install/examples/vue/hello_vue.js +4 -8
  23. data/lib/install/react.rb +2 -2
  24. data/lib/install/template.rb +10 -11
  25. data/lib/install/vue.rb +2 -2
  26. data/lib/tasks/installers.rake +1 -0
  27. data/lib/tasks/webpacker.rake +11 -9
  28. data/lib/tasks/webpacker/check_webpack_binstubs.rake +11 -0
  29. data/lib/tasks/webpacker/check_yarn.rake +6 -3
  30. data/lib/tasks/webpacker/clobber.rake +3 -3
  31. data/lib/tasks/webpacker/compile.rake +14 -20
  32. data/lib/tasks/webpacker/verify_install.rake +2 -2
  33. data/lib/tasks/webpacker/yarn_install.rake +2 -2
  34. data/lib/webpacker.rb +16 -1
  35. data/lib/webpacker/compiler.rb +20 -0
  36. data/lib/webpacker/configuration.rb +30 -22
  37. data/lib/webpacker/env.rb +2 -6
  38. data/lib/webpacker/helper.rb +0 -2
  39. data/lib/webpacker/manifest.rb +23 -6
  40. data/lib/webpacker/version.rb +1 -1
  41. data/package.json +1 -1
  42. data/test/configuration_test.rb +32 -0
  43. data/test/env_test.rb +3 -5
  44. data/test/helper_test.rb +23 -0
  45. data/test/manifest_test.rb +30 -0
  46. data/test/test_app/config/secrets.yml +5 -0
  47. data/test/test_app/public/packs/manifest.json +4 -0
  48. data/test/webpacker_test.rb +2 -1
  49. metadata +20 -7
  50. data/lib/install/bin/yarn.tt +0 -11
  51. data/lib/install/config/webpack/development.server.js +0 -17
  52. data/lib/install/config/webpack/development.server.yml +0 -17
@@ -0,0 +1,11 @@
1
+ // Run this example by adding <%= javascript_pack_tag "hello_elm" %> to the head of your layout
2
+ // file, like app/views/layouts/application.html.erb. It will render "Hello Elm!" within the page.
3
+
4
+ import Elm from './Main'
5
+
6
+ document.addEventListener('DOMContentLoaded', () => {
7
+ const target = document.createElement('div')
8
+
9
+ document.body.appendChild(target)
10
+ Elm.Main.embed(target)
11
+ })
@@ -1,19 +1,15 @@
1
1
  /* eslint no-console: 0 */
2
- // Run this example by adding <%= javascript_pack_tag 'hello_vue' %>
3
- // to the head of your layout file,
2
+ // Run this example by adding <%= javascript_pack_tag 'hello_vue' %> and
3
+ // <%= stylesheet_pack_tag 'hello_vue' %> to the head of your layout file,
4
4
  // like app/views/layouts/application.html.erb.
5
5
  // All it does is render <div>Hello Vue</div> at the bottom of the page.
6
6
 
7
- import Vue from 'vue/dist/vue.esm'
7
+ import Vue from 'vue'
8
8
  import App from './app.vue'
9
9
 
10
10
  document.addEventListener('DOMContentLoaded', () => {
11
11
  document.body.appendChild(document.createElement('hello'))
12
- const app = new Vue({
13
- el: 'hello',
14
- template: '<App/>',
15
- components: { App }
16
- })
12
+ const app = new Vue(App).$mount('hello')
17
13
 
18
14
  console.log(app)
19
15
  })
@@ -19,13 +19,13 @@ else
19
19
  copy_file "#{__dir__}/examples/react/.babelrc", ".babelrc"
20
20
  end
21
21
 
22
- puts "Copying react loader to #{Webpacker::Configuration.config_path}/loaders"
22
+ puts "Copying react loader to config/webpack/loaders"
23
23
  copy_file "#{__dir__}/config/loaders/installers/react.js", "config/webpack/loaders/react.js"
24
24
 
25
25
  puts "Copying react example entry file to #{Webpacker::Configuration.entry_path}"
26
26
  copy_file "#{__dir__}/examples/react/hello_react.jsx", "#{Webpacker::Configuration.entry_path}/hello_react.jsx"
27
27
 
28
28
  puts "Installing all react dependencies"
29
- run "./bin/yarn add react react-dom babel-preset-react prop-types"
29
+ run "yarn add react react-dom babel-preset-react prop-types"
30
30
 
31
31
  puts "Webpacker now supports react.js 🎉"
@@ -1,7 +1,11 @@
1
1
  # Install webpacker
2
+ copy_file "#{__dir__}/config/webpacker.yml", "config/webpacker.yml"
3
+
2
4
  puts "Copying webpack core config and loaders"
3
5
  directory "#{__dir__}/config/webpack", "config/webpack"
4
6
  directory "#{__dir__}/config/loaders/core", "config/webpack/loaders"
7
+
8
+ puts "Copying .postcssrc.yml to app root directory"
5
9
  copy_file "#{__dir__}/config/.postcssrc.yml", ".postcssrc.yml"
6
10
 
7
11
  puts "Copying .babelrc to app root directory"
@@ -11,13 +15,7 @@ puts "Creating javascript app source directory"
11
15
  directory "#{__dir__}/javascript", "#{Webpacker::Configuration.source}"
12
16
 
13
17
  puts "Copying binstubs"
14
- template "#{__dir__}/bin/webpack-dev-server", "bin/webpack-dev-server"
15
- template "#{__dir__}/bin/webpack", "bin/webpack"
16
-
17
- if !File.exist?("bin/yarn")
18
- puts "Copying yarn"
19
- template "#{__dir__}/bin/yarn", "bin/yarn"
20
- end
18
+ directory "#{__dir__}/bin", "bin"
21
19
 
22
20
  chmod "bin", 0755 & ~File.umask, verbose: false
23
21
 
@@ -29,13 +27,14 @@ EOS
29
27
  end
30
28
 
31
29
  puts "Installing all JavaScript dependencies"
32
- run "./bin/yarn add webpack webpack-merge js-yaml path-complete-extname " \
30
+ run "yarn add webpack webpack-merge js-yaml path-complete-extname " \
33
31
  "webpack-manifest-plugin babel-loader@7.x coffee-loader coffee-script " \
34
- "babel-core babel-preset-env compression-webpack-plugin rails-erb-loader glob " \
32
+ "babel-core babel-preset-env babel-polyfill compression-webpack-plugin rails-erb-loader glob " \
35
33
  "extract-text-webpack-plugin node-sass file-loader sass-loader css-loader style-loader " \
36
- "postcss-loader autoprefixer postcss-smart-import precss"
34
+ "postcss-loader autoprefixer postcss-smart-import precss resolve-url-loader " \
35
+ "babel-plugin-syntax-dynamic-import babel-plugin-transform-class-properties"
37
36
 
38
37
  puts "Installing dev server for live reloading"
39
- run "./bin/yarn add --dev webpack-dev-server"
38
+ run "yarn add --dev webpack-dev-server"
40
39
 
41
40
  puts "Webpacker successfully installed 🎉 🍰"
@@ -1,6 +1,6 @@
1
1
  require "webpacker/configuration"
2
2
 
3
- puts "Copying vue loader to #{Webpacker::Configuration.config_path}/loaders"
3
+ puts "Copying vue loader to config/webpack/loaders"
4
4
  copy_file "#{__dir__}/config/loaders/installers/vue.js", "config/webpack/loaders/vue.js"
5
5
 
6
6
  puts "Copying the example entry file to #{Webpacker::Configuration.entry_path}"
@@ -10,6 +10,6 @@ puts "Copying vue app file to #{Webpacker::Configuration.entry_path}"
10
10
  copy_file "#{__dir__}/examples/vue/app.vue", "#{Webpacker::Configuration.entry_path}/app.vue"
11
11
 
12
12
  puts "Installing all vue dependencies"
13
- run "./bin/yarn add vue vue-loader vue-template-compiler"
13
+ run "yarn add vue vue-loader vue-template-compiler"
14
14
 
15
15
  puts "Webpacker now supports vue.js 🎉"
@@ -1,5 +1,6 @@
1
1
  INSTALLERS = {
2
2
  "Angular": :angular,
3
+ "Elm": :elm,
3
4
  "React": :react,
4
5
  "Vue": :vue
5
6
  }.freeze
@@ -1,13 +1,15 @@
1
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:verify_install" => "Verifies if webpacker is installed",
7
- "webpacker:yarn_install" => "Support for older Rails versions. Install all JavaScript dependencies as specified via Yarn",
8
- "webpacker:install:react" => "Installs and setup example react component",
9
- "webpacker:install:vue" => "Installs and setup example vue component",
10
- "webpacker:install:angular" => "Installs and setup example angular2 component"
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_webpack_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"
11
13
  }.freeze
12
14
 
13
15
  desc "Lists all available tasks in webpacker"
@@ -0,0 +1,11 @@
1
+ namespace :webpacker do
2
+ desc "Verifies that bin/webpack & bin/webpack-dev-server are present."
3
+ task :check_webpack_binstubs do
4
+ unless File.exist?("bin/webpack") && File.exist?("bin/webpack-dev-server")
5
+ puts "Webpack binstubs not found.\n"\
6
+ "Make sure the bin directory or binstubs are not included in .gitignore\n"\
7
+ "Exiting!"
8
+ exit!
9
+ end
10
+ end
11
+ end
@@ -1,11 +1,14 @@
1
1
  namespace :webpacker do
2
2
  desc "Verifies if yarn is installed"
3
3
  task :check_yarn do
4
+ required_yarn_version = "0.20.1"
5
+
4
6
  begin
5
- version = `yarn --version`
6
- raise Errno::ENOENT if version.blank?
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)
7
10
  rescue Errno::ENOENT
8
- puts "Webpacker requires yarn. Please download and install Yarn https://yarnpkg.com/lang/en/docs/install/"
11
+ puts "Webpacker requires Yarn version >= #{required_yarn_version}. Please download and install the latest version from https://yarnpkg.com/lang/en/docs/install/"
9
12
  puts "Exiting!" && exit!
10
13
  end
11
14
  end
@@ -3,9 +3,9 @@ require "webpacker/configuration"
3
3
  namespace :webpacker do
4
4
  desc "Remove the webpack compiled output directory"
5
5
  task clobber: ["webpacker:verify_install", :environment] do
6
- packs_path = Webpacker::Configuration.packs_path
7
- FileUtils.rm_r(packs_path) if File.exist?(packs_path)
8
- puts "Removed webpack output path directory #{packs_path}"
6
+ output_path = Webpacker::Configuration.output_path
7
+ FileUtils.rm_r(output_path) if File.exist?(output_path)
8
+ puts "Removed webpack output path directory #{output_path}"
9
9
  end
10
10
  end
11
11
 
@@ -1,35 +1,29 @@
1
+ require "open3"
1
2
  require "webpacker/env"
2
3
  require "webpacker/configuration"
3
- REGEX_MAP = /\A.*\.map\z/
4
4
 
5
5
  namespace :webpacker do
6
6
  desc "Compile javascript packs using webpack for production with digests"
7
7
  task compile: ["webpacker:verify_install", :environment] do
8
- puts "Compiling webpacker assets 🎉"
9
- asset_host = Rails.application.config.action_controller.asset_host
10
- result = `ASSET_HOST=#{asset_host} NODE_ENV=#{Webpacker::Env.current} ./bin/webpack --json`
8
+ puts "[Webpacker] Compiling assets 🎉"
11
9
 
12
- unless $?.success?
13
- puts JSON.parse(result)["errors"]
14
- exit! $?.exitstatus
15
- end
10
+ asset_host = ActionController::Base.helpers.compute_asset_host
11
+ env = { "NODE_ENV" => Webpacker.env, "ASSET_HOST" => asset_host }.freeze
16
12
 
17
- puts "Compiled digests for all packs in #{Webpacker::Configuration.packs_path}: "
18
- puts JSON.parse(File.read(Webpacker::Configuration.manifest_path))
19
- end
13
+ stdout_str, stderr_str, status = Open3.capture3(env, "./bin/webpack")
20
14
 
21
- desc "Compile javascript packs using webpack for test with digests"
22
- task compile_before_test: ["webpacker:compile"] do
23
- Webpacker::Manifest.load(Webpacker::Manifest.file_path)
15
+ if status.success?
16
+ $stdout.puts "\e[32m[Webpacker] Compiled digests for all packs in #{Webpacker::Configuration.entry_path}:\e[0m"
17
+ $stdout.puts "\e[32m#{JSON.parse(File.read(Webpacker::Configuration.manifest_path))}\e[0m"
18
+ else
19
+ $stdout.puts "[Webpacker] Compilation Failed"
20
+ $stdout.puts "\e[31m#{stdout_str}\e[0m"
21
+ $stderr.puts "\e[31m#{stderr_str}\e[0m"
22
+ exit!
23
+ end
24
24
  end
25
25
  end
26
26
 
27
- # Compile packs prior to system and controller tests running
28
- if Rake::Task.task_defined?("test:system")
29
- Rake::Task["test:system"].enhance(["webpacker:compile_before_test"])
30
- Rake::Task["test:controllers"].enhance(["webpacker:compile_before_test"])
31
- end
32
-
33
27
  # Compile packs after we've compiled all other assets during precompilation
34
28
  if Rake::Task.task_defined?("assets:precompile")
35
29
  Rake::Task["assets:precompile"].enhance do
@@ -2,12 +2,12 @@ require "webpacker/configuration"
2
2
 
3
3
  namespace :webpacker do
4
4
  desc "Verifies if webpacker is installed"
5
- task verify_install: [:check_node, :check_yarn] do
5
+ task verify_install: [:check_node, :check_yarn, :check_webpack_binstubs] do
6
6
  if File.exist?(Webpacker::Configuration.file_path)
7
7
  puts "Webpacker is installed 🎉 🍰"
8
8
  puts "Using #{Webpacker::Configuration.file_path} file for setting up webpack paths"
9
9
  else
10
- puts "Configuration config/webpack/paths.yml file not found. \n"\
10
+ puts "Configuration config/webpacker.yml file not found. \n"\
11
11
  "Make sure webpacker:install is run successfully before " \
12
12
  "running dependent tasks"
13
13
  exit!
@@ -1,6 +1,6 @@
1
1
  namespace :webpacker do
2
2
  desc "Support for older Rails versions.Install all JavaScript dependencies as specified via Yarn"
3
- task :yarn_install do
4
- system("./bin/yarn")
3
+ task :yarn_install, [:arg1, :arg2] do |task, args|
4
+ system "yarn #{args[:arg1]} #{args[:arg2]}"
5
5
  end
6
6
  end
@@ -1,9 +1,24 @@
1
1
  module Webpacker
2
- def self.bootstrap
2
+ extend self
3
+
4
+ def bootstrap
3
5
  Webpacker::Env.load
4
6
  Webpacker::Configuration.load
5
7
  Webpacker::Manifest.load
6
8
  end
9
+
10
+ def compile
11
+ Webpacker::Compiler.compile
12
+ Webpacker::Manifest.load
13
+ end
14
+
15
+ def env
16
+ Webpacker::Env.current.inquiry
17
+ end
7
18
  end
8
19
 
20
+ require "webpacker/env"
21
+ require "webpacker/configuration"
22
+ require "webpacker/manifest"
23
+ require "webpacker/compiler"
9
24
  require "webpacker/railtie" if defined?(Rails)
@@ -0,0 +1,20 @@
1
+ require "rake"
2
+
3
+ module Webpacker::Compiler
4
+ extend self
5
+
6
+ def compile
7
+ compile_task.invoke
8
+ compile_task.reenable
9
+ end
10
+
11
+ private
12
+ def compile_task
13
+ @compile_task ||= load_rake_task("webpacker:compile")
14
+ end
15
+
16
+ def load_rake_task(name)
17
+ @load_rakefile ||= Rake.load_rakefile(Rails.root.join("Rakefile"))
18
+ Rake::Task[name]
19
+ end
20
+ end
@@ -1,51 +1,59 @@
1
- # Loads webpacker configuration from config/webpack/paths.yml
1
+ # Loads webpacker configuration from config/webpacker.yml
2
+
2
3
  require "webpacker/file_loader"
3
- require "webpacker/env"
4
4
 
5
5
  class Webpacker::Configuration < Webpacker::FileLoader
6
6
  class << self
7
- def config_path
8
- Rails.root.join(paths.fetch(:config, "config/webpack"))
9
- end
10
-
11
7
  def entry_path
12
- Rails.root.join(source_path, paths.fetch(:entry, "packs"))
8
+ source_path.join(fetch(:source_entry_path))
13
9
  end
14
10
 
15
- def file_path
16
- Rails.root.join("config", "webpack", "paths.yml")
11
+ def output_path
12
+ public_path.join(fetch(:public_output_path))
17
13
  end
18
14
 
19
15
  def manifest_path
20
- Rails.root.join(packs_path, paths.fetch(:manifest, "manifest.json"))
16
+ output_path.join("manifest.json")
21
17
  end
22
18
 
23
- def packs_path
24
- Rails.root.join(output_path, paths.fetch(:entry, "packs"))
19
+ def source_path
20
+ Rails.root.join(source)
25
21
  end
26
22
 
27
- def paths
28
- load if Webpacker::Env.development?
29
- raise Webpacker::FileLoader::FileLoaderError.new("Webpacker::Configuration.load must be called first") unless instance
30
- instance.data
23
+ def public_path
24
+ Rails.root.join("public")
31
25
  end
32
26
 
33
- def output_path
34
- Rails.root.join(paths.fetch(:output, "public"))
27
+ def file_path(root: Rails.root)
28
+ root.join("config/webpacker.yml")
29
+ end
30
+
31
+ def default_file_path
32
+ file_path(root: Pathname.new(__dir__).join("../install"))
35
33
  end
36
34
 
37
35
  def source
38
- paths.fetch(:source, "app/javascript")
36
+ fetch(:source_path)
39
37
  end
40
38
 
41
- def source_path
42
- Rails.root.join(source)
39
+ def fetch(key)
40
+ data.fetch(key, defaults[key])
41
+ end
42
+
43
+ def data
44
+ load if Webpacker.env.development?
45
+ raise Webpacker::FileLoader::FileLoaderError.new("Webpacker::Configuration.load must be called first") unless instance
46
+ instance.data
47
+ end
48
+
49
+ def defaults
50
+ @defaults ||= HashWithIndifferentAccess.new(YAML.load(default_file_path.read)["default"])
43
51
  end
44
52
  end
45
53
 
46
54
  private
47
55
  def load
48
56
  return super unless File.exist?(@path)
49
- HashWithIndifferentAccess.new(YAML.load(File.read(@path))[Webpacker::Env.current])
57
+ HashWithIndifferentAccess.new(YAML.load(File.read(@path))[Webpacker.env])
50
58
  end
51
59
  end
@@ -1,4 +1,4 @@
1
- # Singleton registry for determining NODE_ENV from config/webpack/paths.yml
1
+ # Singleton registry for determining NODE_ENV from config/webpacker.yml
2
2
  require "webpacker/file_loader"
3
3
 
4
4
  class Webpacker::Env < Webpacker::FileLoader
@@ -8,12 +8,8 @@ class Webpacker::Env < Webpacker::FileLoader
8
8
  instance.data
9
9
  end
10
10
 
11
- def development?
12
- current == "development"
13
- end
14
-
15
11
  def file_path
16
- Rails.root.join("config", "webpack", "paths.yml")
12
+ Rails.root.join("config", "webpacker.yml")
17
13
  end
18
14
  end
19
15
 
@@ -1,5 +1,3 @@
1
- require "webpacker/manifest"
2
-
3
1
  module Webpacker::Helper
4
2
  # Computes the full path for a given webpacker asset.
5
3
  # Return relative path using manifest.json and passes it to asset_url helper
@@ -6,8 +6,6 @@
6
6
  # "/packs/calendar-1016838bab065ae1e314.css" for long-term caching
7
7
 
8
8
  require "webpacker/file_loader"
9
- require "webpacker/env"
10
- require "webpacker/configuration"
11
9
 
12
10
  class Webpacker::Manifest < Webpacker::FileLoader
13
11
  class << self
@@ -16,14 +14,33 @@ class Webpacker::Manifest < Webpacker::FileLoader
16
14
  end
17
15
 
18
16
  def lookup(name)
19
- load if Webpacker::Env.development?
20
- raise Webpacker::FileLoader::FileLoaderError.new("Webpacker::Manifest.load must be called first") unless instance
21
- instance.data[name.to_s] || raise(Webpacker::FileLoader::NotFoundError.new("Can't find #{name} in #{file_path}. Is webpack still compiling?"))
17
+ load if Webpacker.env.development?
18
+
19
+ if Webpacker.env.test?
20
+ find(name) || compile_and_find!(name)
21
+ else
22
+ find!(name)
23
+ end
22
24
  end
23
25
 
24
26
  def lookup_path(name)
25
- Rails.root.join(File.join(Webpacker::Configuration.output_path, lookup(name)))
27
+ Rails.root.join(File.join(Webpacker::Configuration.public_path, lookup(name)))
26
28
  end
29
+
30
+ private
31
+ def find(name)
32
+ instance.data[name.to_s] if instance
33
+ end
34
+
35
+ def find!(name)
36
+ raise Webpacker::FileLoader::FileLoaderError.new("Webpacker::Manifest.load must be called first") unless instance
37
+ instance.data[name.to_s] || raise(Webpacker::FileLoader::NotFoundError.new("Can't find #{name} in #{file_path}. Is webpack still compiling?"))
38
+ end
39
+
40
+ def compile_and_find!(name)
41
+ Webpacker.compile
42
+ find!(name)
43
+ end
27
44
  end
28
45
 
29
46
  private