webpacker-remote 0.2.0 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 635f4710cb86e3d78d8ae1da64807ae12f0bf97e7e3b476fb87a58098c9370f5
4
- data.tar.gz: 0aa52bce7bfcf825119c82aa1cc215274c929fe3572c8e4e54523555693504ec
3
+ metadata.gz: 475ff81ecaa533d711986b6b21c70ef0e3e26b3b9934168bacba2bc27f64025e
4
+ data.tar.gz: c0b2f5706cc157d3d082435a38887c870f07e90a8228fca224e5b4d043b4ebd2
5
5
  SHA512:
6
- metadata.gz: 823dab789035d9160449e109532bac324ee377ed8afd8caea5d4a72395d625cc1826902d2554ac5f7ee8930f3232d759f0276b79e7b703ba033bd62b439fb34e
7
- data.tar.gz: 799fc8946cdc5a09b83ebe58ec6f7a244041b3e9607a0a33436feb1755fe0a3db7e3ae32ba0c00c2c6029023568e0b960f1ec5d6b75305e108691b321539afea
6
+ metadata.gz: 96e16850f5db27b9e12bba5877b29bab23cf617d409b6da98b37431b3b137af973ee3559f1593070c62cdf130d672bafea72ac24b72034622fbb851b3a287963
7
+ data.tar.gz: 2574263c55709fb4890190f57255572be16ba4887729be0c5ee1fcbe3e905092ac935f936d8eb3ff975d8193c0d4f895506dca2f500de02fe5f69b5aef826081
@@ -8,8 +8,8 @@ jobs:
8
8
  runs-on: ubuntu-latest
9
9
  strategy:
10
10
  matrix:
11
- ruby: [ '2.7' ]
12
- webpacker: [ '4.3.0', '5.2.1' ]
11
+ ruby: [ '2.7', '3.0', '3.1' ]
12
+ webpacker: [ 'webpacker|~> 4.3', 'webpacker|~> 5.4', 'shakapacker|~> 6.2' ]
13
13
  name: Ruby ${{ matrix.ruby }}, Webpacker ${{ matrix.webpacker }}
14
14
  steps:
15
15
  - uses: actions/checkout@v2
@@ -13,8 +13,8 @@ jobs:
13
13
  runs-on: ubuntu-latest
14
14
  strategy:
15
15
  matrix:
16
- ruby: [ '2.7' ]
17
- webpacker: [ '4.3.0', '5.2.1' ]
16
+ ruby: [ '2.7', '3.0', '3.1' ]
17
+ webpacker: [ 'webpacker|~> 4.3', 'webpacker|~> 5.4', 'shakapacker|~> 6.2' ]
18
18
  name: Ruby ${{ matrix.ruby }}, Webpacker ${{ matrix.webpacker }}
19
19
  steps:
20
20
  - uses: actions/checkout@v2
data/.gitignore CHANGED
@@ -5,3 +5,4 @@ Gemfile.lock
5
5
  bin
6
6
  coverage/
7
7
  *gem
8
+ .DS_Store
data/.rubocop.yml CHANGED
@@ -16,5 +16,20 @@ Metrics/BlockLength:
16
16
  Style/Documentation:
17
17
  Enabled: false
18
18
 
19
+ Gemspec/RequireMFA:
20
+ Enabled: false
21
+
22
+ Style/OpenStructUse:
23
+ Enabled: false
24
+
25
+ Gemspec/RequiredRubyVersion:
26
+ Enabled: false
27
+
28
+ Style/MutableConstant:
29
+ Enabled: false
30
+
31
+ Style/HashSyntax:
32
+ EnforcedShorthandSyntax: never
33
+
19
34
  Style/ClassAndModuleChildren:
20
35
  EnforcedStyle: compact
data/Gemfile CHANGED
@@ -14,6 +14,10 @@ gem 'rubocop-performance', '~> 1.9.2'
14
14
  gem 'rubocop-rake', '~> 0.5.1'
15
15
  gem 'rubocop-rspec', '~> 2.1.0'
16
16
 
17
+ # webpacker-4.3.0 default webpacker yml config
18
+ # incompatible with ruby-3.1 (comes with psych-4)
19
+ gem 'psych', '< 4'
20
+
17
21
  group :development do
18
22
  gem 'benchmark-ips', require: false
19
23
  gem 'pry-byebug', '~> 3.9'
data/README.md CHANGED
@@ -6,23 +6,30 @@
6
6
 
7
7
  - support for `create-react-app` developed in a separate repo
8
8
  - support for multiple external frontend builds, right now `webpacker` is [a singleton](https://github.com/rails/webpacker/blob/6ba995aed2b609a27e4e35ec28b2a7f688cce0cf/lib/webpacker/helper.rb#L5L7)
9
+ - support [shakapacker](https://github.com/shakacode/shakapacker)
10
+ - support for both webpack-asset-manifest-3 and webpack-asset-manifest-5 (including `assets` and without this key)
9
11
 
10
12
  ## Usage
11
13
 
14
+ - ensure you're using `webpack-asset-manifest` to generate proper manifest structure
12
15
  - build `webpack` bundle & upload `build` directory (incl. `manifest.json`) before deploy
13
16
  - in `config/initializers/remote_webpacker.rb`
14
17
 
15
18
  ```rb
19
+ # given we can fetch `https://asset_host/build/manifest.json`
20
+ # and it contains paths relative to `https://asset_host/build/`
16
21
  REMOTE_WEBPACKER = Webpacker::Remote.new(root_path: 'https://asset_host/build/', config_path: 'manifest.json')
17
22
  ```
18
23
 
19
24
  - in `app/views/layouts/application.html.erb` (**not** `javascript_pack_tag`)
20
25
 
21
26
  ```rb
22
- <%= javascript_packs_with_chunks_tag 'main', webpacker: REMOTE_WEBPACKER %>
27
+ <%= javascript_pack_tag 'main', webpacker: REMOTE_WEBPACKER %>
23
28
  #=> <script src='https://asset_host/build/static/js/main.2e302672.chunk.js'>
24
29
  ```
25
30
 
31
+ **NOTE** if you're on `webpacker` (not `shakapacker`), then you should use `javascript_packs_with_chunks_tag`
32
+
26
33
  Of course, you can use as many build as you like and do blue-green deployments using gems like `rollout`
27
34
 
28
35
  ## CRA Requirements
@@ -33,8 +40,8 @@ For `create-react-app` you should use `webpack-assets-manifest` instead of built
33
40
 
34
41
  ```diff
35
42
  + "customize-cra": "^1.0.0",
36
- + "react-app-rewired": "^2.1.8"
37
- + "webpack-assets-manifest": "^3.1.1"
43
+ + "react-app-rewired": "^2.2.1"
44
+ + "webpack-assets-manifest": "^5.1.0"
38
45
  ...
39
46
  - "build": "react-scripts build"
40
47
  + "build": "react-app-rewired build"
@@ -79,26 +86,26 @@ module.exports = override(
79
86
  {
80
87
  "entrypoints": {
81
88
  "main": {
82
- "js": [
83
- "static/js/runtime-main...js",
84
- "static/js/2...chunk.js",
85
- "static/js/main...chunk.js"
86
- ],
87
- "js.map": [
88
- "static/js/runtime-main...js.map",
89
- "static/js/2...chunk.js.map",
90
- "static/js/main...chunk.js.map"
91
- ],
92
- "css": [
93
- "static/css/2...chunk.css",
94
- "static/css/main...chunk.css"
95
- ]
89
+ "assets": {
90
+ "js": [
91
+ "static/js/main.hashsum.js"
92
+ ],
93
+ "css": [
94
+ "static/css/main.hashsum.css"
95
+ ]
96
+ }
96
97
  }
97
98
  },
98
- "main.css": "static/css/main...chunk.css",
99
- "main.js": "static/js/main...chunk.js",
100
- "main.js.map": "static/js/main...chunk.js.map",
101
- "runtime-main.js": "static/js/runtime-main...js",
102
- "runtime-main.js.map": "static/js/runtime-main...js.map"
99
+ "main.css": "static/css/main.hashsum.css",
100
+ "main.js": "static/js/main.hashsum.js"
103
101
  }
102
+ ```
103
+
104
+ ## Tests
105
+
106
+ Specify webpacker gem explicitly:
107
+
108
+ ```sh
109
+ WEBPACKER_GEM_VERSION='shakapacker|6.2.1' bundle exec rspec
110
+ WEBPACKER_GEM_VERSION='webpacker|5.4.3' bundle exec rspec
104
111
  ```
@@ -3,11 +3,34 @@
3
3
  require 'webpacker/configuration'
4
4
 
5
5
  class Webpacker::Remote::Configuration < Webpacker::Configuration
6
+ # rubocop:disable Lint/MissingSuper
7
+ def initialize(root_path:, config_path:, env:, **config_content)
8
+ # deliberately not calling `super` just emulating what's done there
9
+ # because we accept overloading to DI the content of `webpacker.yml` inline
10
+ @root_path = root_path
11
+ @config_path = config_path
12
+ @env = env
13
+
14
+ # addition
15
+ @config_content = config_content
16
+ end
17
+ # rubocop:enable Lint/MissingSuper
18
+
6
19
  def load
7
20
  {
8
21
  cache_manifest: true,
9
22
  check_yarn_integrity: false,
10
23
  compile: false
11
- }
24
+ }.merge(@config_content)
25
+ end
26
+
27
+ # shakapacker error message
28
+ def manifest_path
29
+ File.join(root_path.to_s, config_path.to_s)
30
+ end
31
+
32
+ # webpacker error message
33
+ def public_manifest_path
34
+ manifest_path
12
35
  end
13
36
  end
@@ -3,6 +3,7 @@
3
3
  # better version of https://github.com/rails/webpacker/issues/2054#issuecomment-564173103
4
4
  # rewrite all methods by accept direct injection instead of calling `current_webpacker_instance`
5
5
  # because we can have same layout with script/link tags from different webpackers
6
+ require 'webpacker/helper'
6
7
  module Webpacker::Remote::Helper
7
8
  METHODS = %i[
8
9
  javascript_pack_tag
@@ -11,7 +12,7 @@ module Webpacker::Remote::Helper
11
12
  stylesheet_packs_with_chunks_tag
12
13
  ].freeze
13
14
 
14
- METHODS.each do |meth|
15
+ METHODS.select { |meth| ::Webpacker::Helper.instance_methods.include?(meth) }.each do |meth|
15
16
  define_method meth do |*names, **options|
16
17
  return super(*names, **options) unless options[:webpacker]
17
18
 
@@ -24,7 +25,4 @@ module Webpacker::Remote::Helper
24
25
  end
25
26
  end
26
27
 
27
- unless ENV['SKIP_WEBPACKER_HELPER_OVERRIDE']
28
- require 'webpacker/helper'
29
- Webpacker::Helper.prepend Webpacker::Remote::Helper
30
- end
28
+ Webpacker::Helper.prepend Webpacker::Remote::Helper unless ENV['SKIP_WEBPACKER_HELPER_OVERRIDE']
@@ -4,13 +4,49 @@ require 'webpacker/manifest'
4
4
 
5
5
  class Webpacker::Remote::Manifest < Webpacker::Manifest
6
6
  def load
7
- @webpacker.public_manifest_content
7
+ # load from network, upstream version operates pathnames:
8
+ # if config.manifest_path.exist?
9
+ # JSON.parse config.manifest_path.read
10
+ # else
11
+ # {}
12
+ # end
13
+ if public_manifest_content_uri
14
+ public_manifest_content
15
+ else
16
+ {}
17
+ end
18
+ end
19
+
20
+ def public_manifest_content
21
+ JSON.parse(Net::HTTP.get_response(public_manifest_content_uri).body)
22
+ rescue JSON::ParserError, Errno::ECONNREFUSED, Net::OpenTimeout, Net::ReadTimeout, Errno::ENOENT => e
23
+ raise Webpacker::Remote::Error, <<~MSG
24
+ having {root_path: #{config.root_path.inspect}, config_path: #{config.config_path.inspect}}
25
+ #{e.class}: #{e.message}
26
+ MSG
8
27
  end
9
28
 
10
29
  def lookup_pack_with_chunks(name, pack_type = {})
11
- return unless (paths = super)
30
+ # `super` method copy
31
+ manifest_pack_type = manifest_type(pack_type[:type])
32
+ manifest_pack_name = manifest_name(name, manifest_pack_type)
33
+ assets = find('entrypoints')[manifest_pack_name]
34
+ # patched super behavior:
35
+ # - keys in webpack-assets-manifest-3: entrypoints.main.{js/css}
36
+ # - keys in webpack-assets-manifest-5: entrypoints.main.assets.{js/css}
37
+ # `shakapacker` just has this inline:
38
+ # find("entrypoints")[manifest_pack_name]["assets"][manifest_pack_type]
39
+ assets = assets['assets'] if assets.key?('assets')
40
+ paths = assets[manifest_pack_type]
41
+ # end of `super` method copy
12
42
 
43
+ # remote-webpacker addition: full URIs
44
+ # railsy webpacker returns relative paths from its manifest
45
+ # because `action_view` resolves them using `config.action_controller.asset_host`
46
+ # but remote-webpacker tuned to have bundles from several locations
13
47
  paths.map { |p| File.join(config.root_path.to_s, p) }
48
+ rescue NoMethodError
49
+ nil
14
50
  end
15
51
 
16
52
  def lookup(name, pack_type = {})
@@ -18,4 +54,18 @@ class Webpacker::Remote::Manifest < Webpacker::Manifest
18
54
 
19
55
  File.join(config.root_path.to_s, path)
20
56
  end
57
+
58
+ # additional api to be able to put additional data into the manifest
59
+ # because `find` and `data` are private
60
+ def manifest_data
61
+ data
62
+ end
63
+
64
+ private
65
+
66
+ def public_manifest_content_uri
67
+ URI.parse(File.join(config.root_path.to_s, config.config_path.to_s))
68
+ rescue URI::InvalidURIError
69
+ nil
70
+ end
21
71
  end
@@ -14,21 +14,18 @@ class Webpacker::Remote < Webpacker::Instance
14
14
 
15
15
  class Error < StandardError; end
16
16
 
17
- attr_reader :public_manifest_content
18
-
19
- # fetch early, fail fast
20
17
  # rubocop:disable Lint/MissingSuper
21
- def initialize(root_path: nil, config_path: nil)
22
- uri = File.join(root_path.to_s, config_path.to_s)
23
- @public_manifest_content = JSON.parse(self.class.get_http_response(uri))
18
+ def initialize(root_path: nil, config_path: nil, **config_content)
24
19
  # deliberately not calling `super` just emulating what's done there
20
+ # otherwise defaults in super initialize would call `Rails`
21
+ # let's unbind the gem from rails
25
22
  @config_path = config_path
26
23
  @root_path = root_path
27
- rescue StandardError => e
28
- raise Error, <<~MSG
29
- having {root_path: #{root_path.inspect}, config_path: #{config_path.inspect}}
30
- #{e.class}: #{e.message}
31
- MSG
24
+
25
+ # additions
26
+ @config_content = config_content.symbolize_keys
27
+ # fetch manifest eagerly to fail fast in initiazer unless cache_manifest: false
28
+ manifest.manifest_data if @config_content.fetch(:cache_manifest, true)
32
29
  end
33
30
  # rubocop:enable Lint/MissingSuper
34
31
 
@@ -40,7 +37,7 @@ class Webpacker::Remote < Webpacker::Instance
40
37
  @config ||= Webpacker::Remote::Configuration.new(
41
38
  root_path: root_path,
42
39
  config_path: config_path,
43
- env: env
40
+ **config_content
44
41
  )
45
42
  end
46
43
 
@@ -49,7 +46,9 @@ class Webpacker::Remote < Webpacker::Instance
49
46
  'production'
50
47
  end
51
48
 
52
- def self.get_http_response(uri)
53
- Net::HTTP.get_response(URI.parse(uri)).body
49
+ private
50
+
51
+ def config_content
52
+ { env: env }.merge(@config_content)
54
53
  end
55
54
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = 'webpacker-remote'
5
- spec.version = '0.2.0'
5
+ spec.version = '0.3.0'
6
6
  spec.authors = ['Vlad Bokov']
7
7
  spec.email = ['vlad@lunatic.cat']
8
8
  spec.license = 'MIT'
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.summary = 'Inject external webpack builds into Rails'
11
11
  spec.description = 'Use your webpack builds independently'
12
12
  spec.homepage = 'https://github.com/lunatic-cat/webpacker-remote'
13
- spec.required_ruby_version = Gem::Requirement.new('>= 2.4.0')
13
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.7.0')
14
14
 
15
15
  spec.metadata['homepage_uri'] = spec.homepage
16
16
  spec.metadata['source_code_uri'] = 'https://github.com/lunatic-cat/webpacker-remote'
@@ -20,8 +20,11 @@ Gem::Specification.new do |spec|
20
20
  end
21
21
  spec.require_paths = ['lib']
22
22
 
23
- spec.add_dependency('webpacker', ENV.fetch('WEBPACKER_GEM_VERSION', '< 6'))
24
-
23
+ spec.post_install_message = %(
24
+ This gem is compatible with both `webpacker` and `shakapacker` but has no dependency on any.
25
+ Specify correct one by yourself
26
+ )
27
+ spec.add_development_dependency(*ENV.fetch('WEBPACKER_GEM_VERSION', 'shakapacker|~> 6.2').split('|'))
25
28
  spec.add_development_dependency('rspec', '~> 3.0')
26
29
  spec.add_development_dependency('simplecov', '~> 0.19')
27
30
  end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webpacker-remote
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vlad Bokov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-30 00:00:00.000000000 Z
11
+ date: 2022-05-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: webpacker
14
+ name: shakapacker
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "<"
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '6'
20
- type: :runtime
19
+ version: '6.2'
20
+ type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "<"
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '6'
26
+ version: '6.2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rspec
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -78,7 +78,8 @@ licenses:
78
78
  metadata:
79
79
  homepage_uri: https://github.com/lunatic-cat/webpacker-remote
80
80
  source_code_uri: https://github.com/lunatic-cat/webpacker-remote
81
- post_install_message:
81
+ post_install_message: "\n This gem is compatible with both `webpacker` and `shakapacker`
82
+ but has no dependency on any.\n Specify correct one by yourself\n "
82
83
  rdoc_options: []
83
84
  require_paths:
84
85
  - lib
@@ -86,14 +87,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
86
87
  requirements:
87
88
  - - ">="
88
89
  - !ruby/object:Gem::Version
89
- version: 2.4.0
90
+ version: 2.7.0
90
91
  required_rubygems_version: !ruby/object:Gem::Requirement
91
92
  requirements:
92
93
  - - ">="
93
94
  - !ruby/object:Gem::Version
94
95
  version: '0'
95
96
  requirements: []
96
- rubygems_version: 3.0.8
97
+ rubygems_version: 3.3.7
97
98
  signing_key:
98
99
  specification_version: 4
99
100
  summary: Inject external webpack builds into Rails