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.
- checksums.yaml +7 -0
- data/.eslintignore +4 -0
- data/.eslintrc.js +14 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +20 -0
- data/.github/ISSUE_TEMPLATE/feature-request.md +18 -0
- data/.github/workflows/jest.yml +30 -0
- data/.github/workflows/js-lint.yml +31 -0
- data/.github/workflows/rubocop.yml +39 -0
- data/.github/workflows/ruby.yml +48 -0
- data/.gitignore +13 -0
- data/.node-version +1 -0
- data/.rubocop.yml +229 -0
- data/CHANGELOG.md +32 -0
- data/CONTRIBUTING.md +62 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +183 -0
- data/MIT-LICENSE +20 -0
- data/README.md +666 -0
- data/Rakefile +11 -0
- data/config/README.md +3 -0
- data/config/webpacker.yml +1 -0
- data/docs/customizing_babel_config.md +59 -0
- data/docs/deployment.md +116 -0
- data/docs/developing_webpacker.md +29 -0
- data/docs/troubleshooting.md +212 -0
- data/docs/v6_upgrade.md +158 -0
- data/gemfiles/Gemfile-rails-edge +12 -0
- data/gemfiles/Gemfile-rails.5.2.x +9 -0
- data/gemfiles/Gemfile-rails.6.0.x +9 -0
- data/gemfiles/Gemfile-rails.6.1.x +12 -0
- data/lib/install/application.js +15 -0
- data/lib/install/bin/webpacker +15 -0
- data/lib/install/bin/webpacker-dev-server +18 -0
- data/lib/install/bin/yarn +18 -0
- data/lib/install/binstubs.rb +4 -0
- data/lib/install/config/webpack/webpack.config.js +5 -0
- data/lib/install/config/webpacker.yml +64 -0
- data/lib/install/package.json +15 -0
- data/lib/install/template.rb +100 -0
- data/lib/shakapacker/utils/git_utils.rb +23 -0
- data/lib/shakapacker/utils/version_syntax_converter.rb +24 -0
- data/lib/tasks/webpacker/binstubs.rake +15 -0
- data/lib/tasks/webpacker/check_binstubs.rake +12 -0
- data/lib/tasks/webpacker/check_node.rake +31 -0
- data/lib/tasks/webpacker/check_yarn.rake +33 -0
- data/lib/tasks/webpacker/clean.rake +25 -0
- data/lib/tasks/webpacker/clobber.rake +20 -0
- data/lib/tasks/webpacker/compile.rake +45 -0
- data/lib/tasks/webpacker/info.rake +21 -0
- data/lib/tasks/webpacker/install.rake +17 -0
- data/lib/tasks/webpacker/verify_config.rake +14 -0
- data/lib/tasks/webpacker/verify_install.rake +4 -0
- data/lib/tasks/webpacker/yarn_install.rake +18 -0
- data/lib/tasks/webpacker.rake +19 -0
- data/lib/tasks/yarn.rake +38 -0
- data/lib/webpacker/commands.rb +79 -0
- data/lib/webpacker/compiler.rb +130 -0
- data/lib/webpacker/configuration.rb +111 -0
- data/lib/webpacker/dev_server.rb +72 -0
- data/lib/webpacker/dev_server_proxy.rb +33 -0
- data/lib/webpacker/dev_server_runner.rb +96 -0
- data/lib/webpacker/env.rb +43 -0
- data/lib/webpacker/helper.rb +161 -0
- data/lib/webpacker/instance.rb +41 -0
- data/lib/webpacker/manifest.rb +120 -0
- data/lib/webpacker/railtie.rb +63 -0
- data/lib/webpacker/runner.rb +23 -0
- data/lib/webpacker/version.rb +4 -0
- data/lib/webpacker/webpack_runner.rb +58 -0
- data/lib/webpacker.rb +46 -0
- data/package/__tests__/config.js +34 -0
- data/package/__tests__/dev_server.js +45 -0
- data/package/__tests__/development.js +35 -0
- data/package/__tests__/env.js +58 -0
- data/package/__tests__/index.js +9 -0
- data/package/__tests__/production.js +29 -0
- data/package/__tests__/staging.js +30 -0
- data/package/__tests__/test.js +25 -0
- data/package/babel/preset.js +41 -0
- data/package/config.js +32 -0
- data/package/configPath.js +3 -0
- data/package/dev_server.js +20 -0
- data/package/env.js +27 -0
- data/package/environments/__tests__/base.js +69 -0
- data/package/environments/base.js +116 -0
- data/package/environments/development.js +55 -0
- data/package/environments/production.js +79 -0
- data/package/environments/test.js +3 -0
- data/package/index.js +33 -0
- data/package/inliningCss.js +7 -0
- data/package/rules/babel.js +30 -0
- data/package/rules/coffee.js +6 -0
- data/package/rules/css.js +3 -0
- data/package/rules/erb.js +15 -0
- data/package/rules/file.js +23 -0
- data/package/rules/index.js +18 -0
- data/package/rules/less.js +22 -0
- data/package/rules/raw.js +5 -0
- data/package/rules/sass.js +16 -0
- data/package/rules/stylus.js +26 -0
- data/package/utils/get_style_rule.js +37 -0
- data/package/utils/helpers.js +51 -0
- data/package.json +71 -0
- data/rakelib/release.rake +57 -0
- data/test/command_test.rb +109 -0
- data/test/compiler_test.rb +68 -0
- data/test/configuration_test.rb +78 -0
- data/test/dev_server_runner_test.rb +81 -0
- data/test/dev_server_test.rb +47 -0
- data/test/engine_rake_tasks_test.rb +39 -0
- data/test/env_test.rb +23 -0
- data/test/helper_test.rb +159 -0
- data/test/manifest_test.rb +89 -0
- data/test/mounted_app/Rakefile +4 -0
- data/test/mounted_app/test/dummy/Rakefile +3 -0
- data/test/mounted_app/test/dummy/bin/rails +3 -0
- data/test/mounted_app/test/dummy/bin/rake +3 -0
- data/test/mounted_app/test/dummy/config/application.rb +10 -0
- data/test/mounted_app/test/dummy/config/environment.rb +3 -0
- data/test/mounted_app/test/dummy/config/webpacker.yml +75 -0
- data/test/mounted_app/test/dummy/config.ru +5 -0
- data/test/mounted_app/test/dummy/package.json +7 -0
- data/test/rake_tasks_test.rb +71 -0
- data/test/test_app/Rakefile +3 -0
- data/test/test_app/app/packs/entrypoints/application.js +10 -0
- data/test/test_app/app/packs/entrypoints/multi_entry.css +4 -0
- data/test/test_app/app/packs/entrypoints/multi_entry.js +4 -0
- data/test/test_app/bin/webpacker +14 -0
- data/test/test_app/bin/webpacker-dev-server +14 -0
- data/test/test_app/config/application.rb +11 -0
- data/test/test_app/config/environment.rb +4 -0
- data/test/test_app/config/initializers/inspect_autoload_paths.rb +1 -0
- data/test/test_app/config/webpack/webpack.config.js +0 -0
- data/test/test_app/config/webpacker.yml +77 -0
- data/test/test_app/config/webpacker_other_location.yml +79 -0
- data/test/test_app/config/webpacker_public_root.yml +18 -0
- data/test/test_app/config.ru +5 -0
- data/test/test_app/package.json +13 -0
- data/test/test_app/public/packs/manifest.json +50 -0
- data/test/test_app/some.config.js +0 -0
- data/test/test_app/yarn.lock +11 -0
- data/test/test_helper.rb +33 -0
- data/test/webpack_runner_test.rb +57 -0
- data/test/webpacker_test.rb +34 -0
- data/webpacker.gemspec +31 -0
- data/yarn.lock +4029 -0
- metadata +331 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
module Webpacker::Helper
|
|
2
|
+
# Returns the current Webpacker instance.
|
|
3
|
+
# Could be overridden to use multiple Webpacker
|
|
4
|
+
# configurations within the same app (e.g. with engines).
|
|
5
|
+
def current_webpacker_instance
|
|
6
|
+
Webpacker.instance
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# Computes the relative path for a given Webpacker asset.
|
|
10
|
+
# Returns the relative path using manifest.json and passes it to path_to_asset helper.
|
|
11
|
+
# This will use path_to_asset internally, so most of their behaviors will be the same.
|
|
12
|
+
#
|
|
13
|
+
# Example:
|
|
14
|
+
#
|
|
15
|
+
# <%= asset_pack_path 'calendar.css' %> # => "/packs/calendar-1016838bab065ae1e122.css"
|
|
16
|
+
def asset_pack_path(name, **options)
|
|
17
|
+
path_to_asset(current_webpacker_instance.manifest.lookup!(name), options)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Computes the absolute path for a given Webpacker asset.
|
|
21
|
+
# Returns the absolute path using manifest.json and passes it to url_to_asset helper.
|
|
22
|
+
# This will use url_to_asset internally, so most of their behaviors will be the same.
|
|
23
|
+
#
|
|
24
|
+
# Example:
|
|
25
|
+
#
|
|
26
|
+
# <%= asset_pack_url 'calendar.css' %> # => "http://example.com/packs/calendar-1016838bab065ae1e122.css"
|
|
27
|
+
def asset_pack_url(name, **options)
|
|
28
|
+
url_to_asset(current_webpacker_instance.manifest.lookup!(name), options)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Computes the relative path for a given Webpacker image with the same automated processing as image_pack_tag.
|
|
32
|
+
# Returns the relative path using manifest.json and passes it to path_to_asset helper.
|
|
33
|
+
# This will use path_to_asset internally, so most of their behaviors will be the same.
|
|
34
|
+
def image_pack_path(name, **options)
|
|
35
|
+
resolve_path_to_image(name, **options)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Computes the absolute path for a given Webpacker image with the same automated
|
|
39
|
+
# processing as image_pack_tag. Returns the relative path using manifest.json
|
|
40
|
+
# and passes it to path_to_asset helper. This will use path_to_asset internally,
|
|
41
|
+
# so most of their behaviors will be the same.
|
|
42
|
+
def image_pack_url(name, **options)
|
|
43
|
+
resolve_path_to_image(name, **options.merge(protocol: :request))
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Creates an image tag that references the named pack file.
|
|
47
|
+
#
|
|
48
|
+
# Example:
|
|
49
|
+
#
|
|
50
|
+
# <%= image_pack_tag 'application.png', size: '16x10', alt: 'Edit Entry' %>
|
|
51
|
+
# <img alt='Edit Entry' src='/packs/application-k344a6d59eef8632c9d1.png' width='16' height='10' />
|
|
52
|
+
#
|
|
53
|
+
# <%= image_pack_tag 'picture.png', srcset: { 'picture-2x.png' => '2x' } %>
|
|
54
|
+
# <img srcset= "/packs/picture-2x-7cca48e6cae66ec07b8e.png 2x" src="/packs/picture-c38deda30895059837cf.png" >
|
|
55
|
+
def image_pack_tag(name, **options)
|
|
56
|
+
if options[:srcset] && !options[:srcset].is_a?(String)
|
|
57
|
+
options[:srcset] = options[:srcset].map do |src_name, size|
|
|
58
|
+
"#{resolve_path_to_image(src_name)} #{size}"
|
|
59
|
+
end.join(", ")
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
image_tag(resolve_path_to_image(name), options)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Creates a link tag for a favicon that references the named pack file.
|
|
66
|
+
#
|
|
67
|
+
# Example:
|
|
68
|
+
#
|
|
69
|
+
# <%= favicon_pack_tag 'mb-icon.png', rel: 'apple-touch-icon', type: 'image/png' %>
|
|
70
|
+
# <link href="/packs/mb-icon-k344a6d59eef8632c9d1.png" rel="apple-touch-icon" type="image/png" />
|
|
71
|
+
def favicon_pack_tag(name, **options)
|
|
72
|
+
favicon_link_tag(resolve_path_to_image(name), options)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Creates script tags that reference the js chunks from entrypoints when using split chunks API,
|
|
76
|
+
# as compiled by webpack per the entries list in package/environments/base.js.
|
|
77
|
+
# By default, this list is auto-generated to match everything in
|
|
78
|
+
# app/packs/entrypoints/*.js and all the dependent chunks. In production mode, the digested reference is automatically looked up.
|
|
79
|
+
# See: https://webpack.js.org/plugins/split-chunks-plugin/
|
|
80
|
+
#
|
|
81
|
+
# Example:
|
|
82
|
+
#
|
|
83
|
+
# <%= javascript_pack_tag 'calendar', 'map', 'data-turbolinks-track': 'reload' %> # =>
|
|
84
|
+
# <script src="/packs/vendor-16838bab065ae1e314.chunk.js" data-turbolinks-track="reload" defer="true"></script>
|
|
85
|
+
# <script src="/packs/calendar~runtime-16838bab065ae1e314.chunk.js" data-turbolinks-track="reload" defer="true"></script>
|
|
86
|
+
# <script src="/packs/calendar-1016838bab065ae1e314.chunk.js" data-turbolinks-track="reload" defer="true"></script>
|
|
87
|
+
# <script src="/packs/map~runtime-16838bab065ae1e314.chunk.js" data-turbolinks-track="reload" defer="true"></script>
|
|
88
|
+
# <script src="/packs/map-16838bab065ae1e314.chunk.js" data-turbolinks-track="reload" defer="true"></script>
|
|
89
|
+
#
|
|
90
|
+
# DO:
|
|
91
|
+
#
|
|
92
|
+
# <%= javascript_pack_tag 'calendar', 'map' %>
|
|
93
|
+
#
|
|
94
|
+
# DON'T:
|
|
95
|
+
#
|
|
96
|
+
# <%= javascript_pack_tag 'calendar' %>
|
|
97
|
+
# <%= javascript_pack_tag 'map' %>
|
|
98
|
+
def javascript_pack_tag(*names, defer: true, **options)
|
|
99
|
+
javascript_include_tag(*sources_from_manifest_entrypoints(names, type: :javascript), **options.tap { |o| o[:defer] = defer })
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Creates a link tag, for preloading, that references a given Webpacker asset.
|
|
103
|
+
# In production mode, the digested reference is automatically looked up.
|
|
104
|
+
# See: https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content
|
|
105
|
+
#
|
|
106
|
+
# Example:
|
|
107
|
+
#
|
|
108
|
+
# <%= preload_pack_asset 'fonts/fa-regular-400.woff2' %> # =>
|
|
109
|
+
# <link rel="preload" href="/packs/fonts/fa-regular-400-944fb546bd7018b07190a32244f67dc9.woff2" as="font" type="font/woff2" crossorigin="anonymous">
|
|
110
|
+
def preload_pack_asset(name, **options)
|
|
111
|
+
if self.class.method_defined?(:preload_link_tag)
|
|
112
|
+
preload_link_tag(current_webpacker_instance.manifest.lookup!(name), options)
|
|
113
|
+
else
|
|
114
|
+
raise "You need Rails >= 5.2 to use this tag."
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Creates link tags that reference the css chunks from entrypoints when using split chunks API,
|
|
119
|
+
# as compiled by webpack per the entries list in package/environments/base.js.
|
|
120
|
+
# By default, this list is auto-generated to match everything in
|
|
121
|
+
# app/packs/entrypoints/*.js and all the dependent chunks. In production mode, the digested reference is automatically looked up.
|
|
122
|
+
# See: https://webpack.js.org/plugins/split-chunks-plugin/
|
|
123
|
+
#
|
|
124
|
+
# Examples:
|
|
125
|
+
#
|
|
126
|
+
# <%= stylesheet_pack_tag 'calendar', 'map' %> # =>
|
|
127
|
+
# <link rel="stylesheet" media="screen" href="/packs/3-8c7ce31a.chunk.css" />
|
|
128
|
+
# <link rel="stylesheet" media="screen" href="/packs/calendar-8c7ce31a.chunk.css" />
|
|
129
|
+
# <link rel="stylesheet" media="screen" href="/packs/map-8c7ce31a.chunk.css" />
|
|
130
|
+
#
|
|
131
|
+
# When using the webpack-dev-server, CSS is inlined so HMR can be turned on for CSS,
|
|
132
|
+
# including CSS modules
|
|
133
|
+
# <%= stylesheet_pack_tag 'calendar', 'map' %> # => nil
|
|
134
|
+
#
|
|
135
|
+
# DO:
|
|
136
|
+
#
|
|
137
|
+
# <%= stylesheet_pack_tag 'calendar', 'map' %>
|
|
138
|
+
#
|
|
139
|
+
# DON'T:
|
|
140
|
+
#
|
|
141
|
+
# <%= stylesheet_pack_tag 'calendar' %>
|
|
142
|
+
# <%= stylesheet_pack_tag 'map' %>
|
|
143
|
+
def stylesheet_pack_tag(*names, **options)
|
|
144
|
+
return "" if Webpacker.inlining_css?
|
|
145
|
+
|
|
146
|
+
stylesheet_link_tag(*sources_from_manifest_entrypoints(names, type: :stylesheet), **options)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
private
|
|
150
|
+
|
|
151
|
+
def sources_from_manifest_entrypoints(names, type:)
|
|
152
|
+
names.map { |name| current_webpacker_instance.manifest.lookup_pack_with_chunks!(name.to_s, type: type) }.flatten.uniq
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def resolve_path_to_image(name, **options)
|
|
156
|
+
path = name.starts_with?("static/") ? name : "static/#{name}"
|
|
157
|
+
path_to_asset(current_webpacker_instance.manifest.lookup!(path), options)
|
|
158
|
+
rescue
|
|
159
|
+
path_to_asset(current_webpacker_instance.manifest.lookup!(name), options)
|
|
160
|
+
end
|
|
161
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
class Webpacker::Instance
|
|
2
|
+
cattr_accessor(:logger) { ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new(STDOUT)) }
|
|
3
|
+
|
|
4
|
+
attr_reader :root_path, :config_path
|
|
5
|
+
|
|
6
|
+
def initialize(root_path: Rails.root, config_path: Rails.root.join("config/webpacker.yml"))
|
|
7
|
+
@root_path, @config_path = root_path, config_path
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def env
|
|
11
|
+
@env ||= Webpacker::Env.inquire self
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def config
|
|
15
|
+
@config ||= Webpacker::Configuration.new(
|
|
16
|
+
root_path: root_path,
|
|
17
|
+
config_path: config_path,
|
|
18
|
+
env: env
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def compiler
|
|
23
|
+
@compiler ||= Webpacker::Compiler.new self
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def dev_server
|
|
27
|
+
@dev_server ||= Webpacker::DevServer.new config
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def manifest
|
|
31
|
+
@manifest ||= Webpacker::Manifest.new self
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def commands
|
|
35
|
+
@commands ||= Webpacker::Commands.new self
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def inlining_css?
|
|
39
|
+
dev_server.hmr? && dev_server.running?
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Singleton registry for accessing the packs path using a generated manifest.
|
|
2
|
+
# This allows javascript_pack_tag, stylesheet_pack_tag, asset_pack_path to take a reference to,
|
|
3
|
+
# say, "calendar.js" or "calendar.css" and turn it into "/packs/calendar-1016838bab065ae1e314.js" or
|
|
4
|
+
# "/packs/calendar-1016838bab065ae1e314.css".
|
|
5
|
+
#
|
|
6
|
+
# When the configuration is set to on-demand compilation, with the `compile: true` option in
|
|
7
|
+
# the webpacker.yml file, any lookups will be preceded by a compilation if one is needed.
|
|
8
|
+
class Webpacker::Manifest
|
|
9
|
+
class MissingEntryError < StandardError; end
|
|
10
|
+
|
|
11
|
+
delegate :config, :compiler, :dev_server, to: :@webpacker
|
|
12
|
+
|
|
13
|
+
def initialize(webpacker)
|
|
14
|
+
@webpacker = webpacker
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def refresh
|
|
18
|
+
@data = load
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def lookup_pack_with_chunks(name, pack_type = {})
|
|
22
|
+
compile if compiling?
|
|
23
|
+
|
|
24
|
+
manifest_pack_type = manifest_type(pack_type[:type])
|
|
25
|
+
manifest_pack_name = manifest_name(name, manifest_pack_type)
|
|
26
|
+
find("entrypoints")[manifest_pack_name]["assets"][manifest_pack_type]
|
|
27
|
+
rescue NoMethodError
|
|
28
|
+
nil
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def lookup_pack_with_chunks!(name, pack_type = {})
|
|
32
|
+
lookup_pack_with_chunks(name, pack_type) || handle_missing_entry(name, pack_type)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Computes the relative path for a given Webpacker asset using manifest.json.
|
|
36
|
+
# If no asset is found, returns nil.
|
|
37
|
+
#
|
|
38
|
+
# Example:
|
|
39
|
+
#
|
|
40
|
+
# Webpacker.manifest.lookup('calendar.js') # => "/packs/calendar-1016838bab065ae1e122.js"
|
|
41
|
+
def lookup(name, pack_type = {})
|
|
42
|
+
compile if compiling?
|
|
43
|
+
|
|
44
|
+
find(full_pack_name(name, pack_type[:type]))
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Like lookup, except that if no asset is found, raises a Webpacker::Manifest::MissingEntryError.
|
|
48
|
+
def lookup!(name, pack_type = {})
|
|
49
|
+
lookup(name, pack_type) || handle_missing_entry(name, pack_type)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
def compiling?
|
|
54
|
+
config.compile? && !dev_server.running?
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def compile
|
|
58
|
+
Webpacker.logger.tagged("Webpacker") { compiler.compile }
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def data
|
|
62
|
+
if config.cache_manifest?
|
|
63
|
+
@data ||= load
|
|
64
|
+
else
|
|
65
|
+
refresh
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def find(name)
|
|
70
|
+
data[name.to_s].presence
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def full_pack_name(name, pack_type)
|
|
74
|
+
return name unless File.extname(name.to_s).empty?
|
|
75
|
+
"#{name}.#{manifest_type(pack_type)}"
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def handle_missing_entry(name, pack_type)
|
|
79
|
+
raise Webpacker::Manifest::MissingEntryError, missing_file_from_manifest_error(full_pack_name(name, pack_type[:type]))
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def load
|
|
83
|
+
if config.public_manifest_path.exist?
|
|
84
|
+
JSON.parse config.public_manifest_path.read
|
|
85
|
+
else
|
|
86
|
+
{}
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# The `manifest_name` method strips of the file extension of the name, because in the
|
|
91
|
+
# manifest hash the entrypoints are defined by their pack name without the extension.
|
|
92
|
+
# When the user provides a name with a file extension, we want to try to strip it off.
|
|
93
|
+
def manifest_name(name, pack_type)
|
|
94
|
+
name.chomp(".#{pack_type}")
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def manifest_type(pack_type)
|
|
98
|
+
case pack_type
|
|
99
|
+
when :javascript then "js"
|
|
100
|
+
when :stylesheet then "css"
|
|
101
|
+
else pack_type.to_s
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def missing_file_from_manifest_error(bundle_name)
|
|
106
|
+
<<-MSG
|
|
107
|
+
Webpacker can't find #{bundle_name} in #{config.public_manifest_path}. Possible causes:
|
|
108
|
+
1. You forgot to install node packages (try `yarn install`) or are running an incompatible version of Node
|
|
109
|
+
2. Your app has code with a non-standard extension (like a `.jsx` file) but the extension is not in the `extensions` config in `config/webpacker.yml`
|
|
110
|
+
3. You have set compile: false (see `config/webpacker.yml`) for this environment
|
|
111
|
+
(unless you are using the `bin/webpacker -w` or the `bin/webpacker-dev-server`, in which case maybe you aren't running the dev server in the background?)
|
|
112
|
+
4. webpack has not yet re-run to reflect updates.
|
|
113
|
+
5. You have misconfigured Webpacker's `config/webpacker.yml` file.
|
|
114
|
+
6. Your webpack configuration is not creating a manifest.
|
|
115
|
+
|
|
116
|
+
Your manifest contains:
|
|
117
|
+
#{JSON.pretty_generate(@data)}
|
|
118
|
+
MSG
|
|
119
|
+
end
|
|
120
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require "rails/railtie"
|
|
2
|
+
|
|
3
|
+
require "webpacker/helper"
|
|
4
|
+
require "webpacker/dev_server_proxy"
|
|
5
|
+
|
|
6
|
+
class Webpacker::Engine < ::Rails::Engine
|
|
7
|
+
# Allows Webpacker config values to be set via Rails env config files
|
|
8
|
+
config.webpacker = ActiveSupport::OrderedOptions.new
|
|
9
|
+
|
|
10
|
+
initializer "webpacker.proxy" do |app|
|
|
11
|
+
if (Webpacker.config.dev_server.present? rescue nil)
|
|
12
|
+
app.middleware.insert_before 0,
|
|
13
|
+
Rails::VERSION::MAJOR >= 5 ?
|
|
14
|
+
Webpacker::DevServerProxy : "Webpacker::DevServerProxy", ssl_verify_none: true
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
initializer "webpacker.helper" do
|
|
19
|
+
ActiveSupport.on_load :action_controller do
|
|
20
|
+
ActionController::Base.helper Webpacker::Helper
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
ActiveSupport.on_load :action_view do
|
|
24
|
+
include Webpacker::Helper
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
initializer "webpacker.logger" do
|
|
29
|
+
config.after_initialize do
|
|
30
|
+
if ::Rails.logger.respond_to?(:tagged)
|
|
31
|
+
Webpacker.logger = ::Rails.logger
|
|
32
|
+
else
|
|
33
|
+
Webpacker.logger = ActiveSupport::TaggedLogging.new(::Rails.logger)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
initializer "webpacker.bootstrap" do
|
|
39
|
+
if defined?(Rails::Server) || defined?(Rails::Console)
|
|
40
|
+
Webpacker.bootstrap
|
|
41
|
+
if defined?(Spring)
|
|
42
|
+
require "spring/watcher"
|
|
43
|
+
Spring.after_fork { Webpacker.bootstrap }
|
|
44
|
+
Spring.watch(Webpacker.config.config_path)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
initializer "webpacker.set_source" do |app|
|
|
50
|
+
if Webpacker.config.config_path.exist?
|
|
51
|
+
app.config.javascript_path = Webpacker.config.source_path.relative_path_from(Rails.root.join("app")).to_s
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
initializer "webpacker.remove_app_packs_from_the_autoload_paths" do
|
|
56
|
+
Rails.application.config.before_initialize do
|
|
57
|
+
if Webpacker.config.config_path.exist?
|
|
58
|
+
source_path = Webpacker.config.source_path.to_s
|
|
59
|
+
ActiveSupport::Dependencies.autoload_paths.delete(source_path)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Webpacker
|
|
2
|
+
class Runner
|
|
3
|
+
def self.run(argv)
|
|
4
|
+
$stdout.sync = true
|
|
5
|
+
|
|
6
|
+
new(argv).run
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def initialize(argv)
|
|
10
|
+
@argv = argv
|
|
11
|
+
|
|
12
|
+
@app_path = File.expand_path(".", Dir.pwd)
|
|
13
|
+
@node_modules_bin_path = ENV["WEBPACKER_NODE_MODULES_BIN_PATH"] || `yarn bin`.chomp
|
|
14
|
+
@webpack_config = File.join(@app_path, "config/webpack/webpack.config.js")
|
|
15
|
+
@webpacker_config = ENV["WEBPACKER_CONFIG"] || File.join(@app_path, "config/webpacker.yml")
|
|
16
|
+
|
|
17
|
+
unless File.exist?(@webpack_config)
|
|
18
|
+
$stderr.puts "webpack config #{@webpack_config} not found, please run 'bundle exec rails webpacker:install' to install Webpacker with default configs or add the missing config file for your custom environment."
|
|
19
|
+
exit!
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require "shellwords"
|
|
2
|
+
require "webpacker/runner"
|
|
3
|
+
|
|
4
|
+
module Webpacker
|
|
5
|
+
class WebpackRunner < Webpacker::Runner
|
|
6
|
+
WEBPACK_COMMANDS = [
|
|
7
|
+
"help",
|
|
8
|
+
"h",
|
|
9
|
+
"--help",
|
|
10
|
+
"-h",
|
|
11
|
+
"version",
|
|
12
|
+
"v",
|
|
13
|
+
"--version",
|
|
14
|
+
"-v",
|
|
15
|
+
"info",
|
|
16
|
+
"i"
|
|
17
|
+
].freeze
|
|
18
|
+
|
|
19
|
+
def run
|
|
20
|
+
env = Webpacker::Compiler.env
|
|
21
|
+
env["WEBPACKER_CONFIG"] = @webpacker_config
|
|
22
|
+
|
|
23
|
+
cmd = if node_modules_bin_exist?
|
|
24
|
+
["#{@node_modules_bin_path}/webpack"]
|
|
25
|
+
else
|
|
26
|
+
["yarn", "webpack"]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
if @argv.delete "--debug-webpacker"
|
|
30
|
+
cmd = ["node", "--inspect-brk"] + cmd
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
if @argv.delete "--trace-deprecation"
|
|
34
|
+
cmd = ["node", "--trace-deprecation"] + cmd
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
if @argv.delete "--no-deprecation"
|
|
38
|
+
cmd = ["node", "--no-deprecation"] + cmd
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Webpack commands are not compatible with --config option.
|
|
42
|
+
if (@argv & WEBPACK_COMMANDS).empty?
|
|
43
|
+
cmd += ["--config", @webpack_config]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
cmd += @argv
|
|
47
|
+
|
|
48
|
+
Dir.chdir(@app_path) do
|
|
49
|
+
Kernel.exec env, *cmd
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
def node_modules_bin_exist?
|
|
55
|
+
File.exist?("#{@node_modules_bin_path}/webpack")
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
data/lib/webpacker.rb
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require "active_support/core_ext/module/attribute_accessors"
|
|
2
|
+
require "active_support/core_ext/string/inquiry"
|
|
3
|
+
require "active_support/logger"
|
|
4
|
+
require "active_support/tagged_logging"
|
|
5
|
+
|
|
6
|
+
module Webpacker
|
|
7
|
+
extend self
|
|
8
|
+
|
|
9
|
+
def instance=(instance)
|
|
10
|
+
@instance = instance
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def instance
|
|
14
|
+
@instance ||= Webpacker::Instance.new
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def with_node_env(env)
|
|
18
|
+
original = ENV["NODE_ENV"]
|
|
19
|
+
ENV["NODE_ENV"] = env
|
|
20
|
+
yield
|
|
21
|
+
ensure
|
|
22
|
+
ENV["NODE_ENV"] = original
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def ensure_log_goes_to_stdout
|
|
26
|
+
old_logger = Webpacker.logger
|
|
27
|
+
Webpacker.logger = Logger.new(STDOUT)
|
|
28
|
+
yield
|
|
29
|
+
ensure
|
|
30
|
+
Webpacker.logger = old_logger
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
delegate :logger, :logger=, :env, :inlining_css?, to: :instance
|
|
34
|
+
delegate :config, :compiler, :manifest, :commands, :dev_server, to: :instance
|
|
35
|
+
delegate :bootstrap, :clean, :clobber, :compile, to: :commands
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
require "webpacker/instance"
|
|
39
|
+
require "webpacker/env"
|
|
40
|
+
require "webpacker/configuration"
|
|
41
|
+
require "webpacker/manifest"
|
|
42
|
+
require "webpacker/compiler"
|
|
43
|
+
require "webpacker/commands"
|
|
44
|
+
require "webpacker/dev_server"
|
|
45
|
+
|
|
46
|
+
require "webpacker/railtie" if defined?(Rails)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/* global test expect, describe */
|
|
2
|
+
|
|
3
|
+
const { chdirCwd, chdirTestApp, resetEnv } = require('../utils/helpers')
|
|
4
|
+
|
|
5
|
+
chdirTestApp()
|
|
6
|
+
|
|
7
|
+
const config = require('../config')
|
|
8
|
+
|
|
9
|
+
describe('Config', () => {
|
|
10
|
+
beforeEach(() => jest.resetModules() && resetEnv())
|
|
11
|
+
afterAll(chdirCwd)
|
|
12
|
+
|
|
13
|
+
test('public path', () => {
|
|
14
|
+
process.env.RAILS_ENV = 'development'
|
|
15
|
+
const config = require('../config')
|
|
16
|
+
expect(config.publicPath).toEqual('/packs/')
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
test('public path with asset host', () => {
|
|
20
|
+
process.env.RAILS_ENV = 'development'
|
|
21
|
+
process.env.WEBPACKER_ASSET_HOST = 'http://foo.com/'
|
|
22
|
+
const config = require('../config')
|
|
23
|
+
expect(config.publicPath).toEqual('http://foo.com/packs/')
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
test('should return additional paths as listed in app config, with resolved paths', () => {
|
|
27
|
+
expect(config.additional_paths).toEqual([
|
|
28
|
+
'app/assets',
|
|
29
|
+
'/etc/yarn',
|
|
30
|
+
'some.config.js',
|
|
31
|
+
'app/elm'
|
|
32
|
+
])
|
|
33
|
+
})
|
|
34
|
+
})
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/* global test expect, describe */
|
|
2
|
+
|
|
3
|
+
const { chdirTestApp, chdirCwd } = require('../utils/helpers')
|
|
4
|
+
|
|
5
|
+
chdirTestApp()
|
|
6
|
+
|
|
7
|
+
describe('DevServer', () => {
|
|
8
|
+
beforeEach(() => jest.resetModules())
|
|
9
|
+
afterAll(chdirCwd)
|
|
10
|
+
|
|
11
|
+
test('with NODE_ENV and RAILS_ENV set to development', () => {
|
|
12
|
+
process.env.NODE_ENV = 'development'
|
|
13
|
+
process.env.RAILS_ENV = 'development'
|
|
14
|
+
process.env.WEBPACKER_DEV_SERVER_HOST = '0.0.0.0'
|
|
15
|
+
process.env.WEBPACKER_DEV_SERVER_PORT = 5000
|
|
16
|
+
process.env.WEBPACKER_DEV_SERVER_DISABLE_HOST_CHECK = false
|
|
17
|
+
|
|
18
|
+
const devServer = require('../dev_server')
|
|
19
|
+
expect(devServer).toBeDefined()
|
|
20
|
+
expect(devServer.host).toEqual('0.0.0.0')
|
|
21
|
+
expect(devServer.port).toEqual('5000')
|
|
22
|
+
expect(devServer.disable_host_check).toBe(false)
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
test('with custom env prefix', () => {
|
|
26
|
+
const config = require('../config')
|
|
27
|
+
config.dev_server.env_prefix = 'TEST_WEBPACKER_DEV_SERVER'
|
|
28
|
+
|
|
29
|
+
process.env.NODE_ENV = 'development'
|
|
30
|
+
process.env.RAILS_ENV = 'development'
|
|
31
|
+
process.env.TEST_WEBPACKER_DEV_SERVER_HOST = '0.0.0.0'
|
|
32
|
+
process.env.TEST_WEBPACKER_DEV_SERVER_PORT = 5000
|
|
33
|
+
|
|
34
|
+
const devServer = require('../dev_server')
|
|
35
|
+
expect(devServer).toBeDefined()
|
|
36
|
+
expect(devServer.host).toEqual('0.0.0.0')
|
|
37
|
+
expect(devServer.port).toEqual('5000')
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
test('with NODE_ENV and RAILS_ENV set to production', () => {
|
|
41
|
+
process.env.RAILS_ENV = 'production'
|
|
42
|
+
process.env.NODE_ENV = 'production'
|
|
43
|
+
expect(require('../dev_server')).toEqual({})
|
|
44
|
+
})
|
|
45
|
+
})
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/* test expect, describe, afterAll, beforeEach */
|
|
2
|
+
|
|
3
|
+
const { resolve } = require('path')
|
|
4
|
+
const { chdirTestApp, chdirCwd } = require('../utils/helpers')
|
|
5
|
+
|
|
6
|
+
chdirTestApp()
|
|
7
|
+
|
|
8
|
+
describe('Development environment', () => {
|
|
9
|
+
afterAll(chdirCwd)
|
|
10
|
+
|
|
11
|
+
describe('webpackConfig', () => {
|
|
12
|
+
beforeEach(() => jest.resetModules())
|
|
13
|
+
|
|
14
|
+
test('should use development config and environment including devServer if WEBPACK_SERVE', () => {
|
|
15
|
+
process.env.RAILS_ENV = 'development'
|
|
16
|
+
process.env.NODE_ENV = 'development'
|
|
17
|
+
process.env.WEBPACK_SERVE = 'true'
|
|
18
|
+
const { webpackConfig } = require('../index')
|
|
19
|
+
|
|
20
|
+
expect(webpackConfig.output.path).toEqual(resolve('public', 'packs'))
|
|
21
|
+
expect(webpackConfig.output.publicPath).toEqual('/packs/')
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
test('should use development config and environment if WEBPACK_SERVE', () => {
|
|
25
|
+
process.env.RAILS_ENV = 'development'
|
|
26
|
+
process.env.NODE_ENV = 'development'
|
|
27
|
+
process.env.WEBPACK_SERVE = undefined
|
|
28
|
+
const { webpackConfig } = require('../index')
|
|
29
|
+
|
|
30
|
+
expect(webpackConfig.output.path).toEqual(resolve('public', 'packs'))
|
|
31
|
+
expect(webpackConfig.output.publicPath).toEqual('/packs/')
|
|
32
|
+
expect(webpackConfig.devServer).toEqual(undefined)
|
|
33
|
+
})
|
|
34
|
+
})
|
|
35
|
+
})
|