Skip to content

Commit c4cf2e9

Browse files
authoredJan 17, 2019
Add new javascript_packs_with_chunks_tag helper (#1898)
1 parent c73dd7a commit c4cf2e9

File tree

8 files changed

+133
-44
lines changed

8 files changed

+133
-44
lines changed
 

‎CHANGELOG.md

+32
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,37 @@
11
**Please note that Webpacker 3.1.0 and 3.1.1 have some serious bugs so please consider using either 3.0.2 or 3.2.0**
22

3+
## [4.0.0] - Unreleased
4+
5+
### Fixed
6+
- Issue with javascript_pack_tag asset duplication [#1898](https://github.com/rails/webpacker/pull/1898)
7+
8+
9+
### Added
10+
- `javascript_packs_with_chunks_tag` helper, which creates html tags
11+
for a pack and all the dependent chunks, when using splitchunks.
12+
13+
```erb
14+
<%= javascript_packs_with_chunks_tag 'calendar', 'map', 'data-turbolinks-track': 'reload' %>
15+
16+
<script src="/packs/vendor-16838bab065ae1e314.js" data-turbolinks-track="reload"></script>
17+
<script src="/packs/calendar~runtime-16838bab065ae1e314.js" data-turbolinks-track="reload"></script>
18+
<script src="/packs/calendar-1016838bab065ae1e314.js" data-turbolinks-track="reload"></script>
19+
<script src="/packs/map~runtime-16838bab065ae1e314.js" data-turbolinks-track="reload"></script>
20+
<script src="/packs/map-16838bab065ae1e314.js" data-turbolinks-track="reload"></script>
21+
```
22+
23+
**Important:** Pass all your pack names when using `javascript_packs_with_chunks_tag`
24+
helper otherwise you will get duplicated chunks on the page.
25+
26+
```erb
27+
<%# DO %>
28+
<%= javascript_packs_with_chunks_tag 'calendar', 'map' %>
29+
30+
<%# DON'T %>
31+
<%= javascript_packs_with_chunks_tag 'calendar' %>
32+
<%= javascript_packs_with_chunks_tag 'map' %>
33+
```
34+
335
## [4.0.0.rc.2] - 2018-12-15
436

537
### Fixed

‎README.md

+25
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,31 @@ can use the `asset_pack_path` helper:
142142
<img src="<%= asset_pack_path 'images/logo.svg' %>" />
143143
```
144144

145+
If you are using new webpack 4 split chunks API, then consider using `javascript_packs_with_chunks_tag` helper, which creates html
146+
tags for a pack and all the dependent chunks.
147+
148+
```erb
149+
<%= javascript_packs_with_chunks_tag 'calendar', 'map', 'data-turbolinks-track': 'reload' %>
150+
151+
<script src="/packs/vendor-16838bab065ae1e314.js" data-turbolinks-track="reload"></script>
152+
<script src="/packs/calendar~runtime-16838bab065ae1e314.js" data-turbolinks-track="reload"></script>
153+
<script src="/packs/calendar-1016838bab065ae1e314.js" data-turbolinks-track="reload"></script>
154+
<script src="/packs/map~runtime-16838bab065ae1e314.js" data-turbolinks-track="reload"></script>
155+
<script src="/packs/map-16838bab065ae1e314.js" data-turbolinks-track="reload"></script>
156+
```
157+
158+
**Important:** Pass all your pack names when using `javascript_packs_with_chunks_tag`
159+
helper otherwise you will get duplicated chunks on the page.
160+
161+
```erb
162+
<%# DO %>
163+
<%= javascript_packs_with_chunks_tag 'calendar', 'map' %>
164+
165+
<%# DON'T %>
166+
<%= javascript_packs_with_chunks_tag 'calendar' %>
167+
<%= javascript_packs_with_chunks_tag 'map' %>
168+
```
169+
145170
**Note:** In order for your styles or static assets files to be available in your view,
146171
you would need to link them in your "pack" or entry file.
147172

‎docs/webpack.md

+26-22
Original file line numberDiff line numberDiff line change
@@ -267,32 +267,36 @@ For the full configuration options of SplitChunks, see the [Webpack documentatio
267267
// config/webpack/environment.js
268268
const WebpackAssetsManifest = require('webpack-assets-manifest');
269269

270-
const splitChunks = {
271-
optimization: {
272-
splitChunks: {
273-
chunks: 'all'
274-
},
275-
},
276-
};
277-
278-
environment.config.merge(splitChunks);
279-
280-
// Should override the existing manifest plugin
281-
environment.plugins.insert(
282-
'Manifest',
283-
new WebpackAssetsManifest({
284-
entrypoints: true, // default in rails is false
285-
writeToDisk: true, // rails defaults copied from webpacker
286-
publicPath: true // rails defaults copied from webpacker
287-
})
288-
)
270+
// Enable the default config
271+
environment.splitChunks()
272+
273+
// or using custom config
274+
environment.splitChunks((config) => Object.assign({}, config, { optimization: { splitChunks: false }}))
289275
```
290276

291-
To use the `javascript_pack_tag` or the `stylesheet_pack_tag` with `SplitChunks` or `RuntimeChunks` you can refer to the packs as usual.
277+
Then use, `javascript_packs_with_chunks_tag` helper to include all the transpiled
278+
packs with the chunks in your view, which creates html tags for all the chunks.
292279

293280
```erb
294-
javascript_pack_tag "your-entrypoint-javascript-file"
295-
stylesheet_pack_tag "your-entrypoint-stylesheet-file"
281+
<%= javascript_packs_with_chunks_tag 'calendar', 'map', 'data-turbolinks-track': 'reload' %>
282+
283+
<script src="/packs/vendor-16838bab065ae1e314.js" data-turbolinks-track="reload"></script>
284+
<script src="/packs/calendar~runtime-16838bab065ae1e314.js" data-turbolinks-track="reload"></script>
285+
<script src="/packs/calendar-1016838bab065ae1e314.js" data-turbolinks-track="reload"></script>
286+
<script src="/packs/map~runtime-16838bab065ae1e314.js" data-turbolinks-track="reload"></script>
287+
<script src="/packs/map-16838bab065ae1e314.js" data-turbolinks-track="reload"></script>
288+
```
289+
290+
**Important:** Pass all your pack names when using this helper otherwise you will
291+
get duplicated chunks on the page.
292+
293+
```erb
294+
<%# DO %>
295+
<%= javascript_packs_with_chunks_tag 'calendar', 'map' %>
296+
297+
<%# DON'T %>
298+
<%= javascript_packs_with_chunks_tag 'calendar' %>
299+
<%= javascript_packs_with_chunks_tag 'map' %>
296300
```
297301

298302
For the old configuration with the CommonsChunkPlugin see below. **Note** that this functionality is deprecated in Webpack V4.

‎lib/webpacker/helper.rb

+29-3
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,29 @@ def image_pack_tag(name, **options)
5959
# <%= javascript_pack_tag 'calendar', 'data-turbolinks-track': 'reload' %> # =>
6060
# <script src="/packs/calendar-1016838bab065ae1e314.js" data-turbolinks-track="reload"></script>
6161
def javascript_pack_tag(*names, **options)
62-
javascript_include_tag(*sources_from_pack_manifest(names, type: :javascript), **options)
62+
javascript_include_tag(*sources_from_manifest_entries(names, type: :javascript), **options)
63+
end
64+
65+
# Creates script tags that references the chunks from entrypoints when using split chunks API,
66+
# as compiled by webpack per the entries list in config/webpack/shared.js.
67+
# By default, this list is auto-generated to match everything in
68+
# app/javascript/packs/*.js and all the dependent chunks. In production mode, the digested reference is automatically looked up.
69+
# See: https://webpack.js.org/plugins/split-chunks-plugin/
70+
# Example:
71+
#
72+
# <%= javascript_packs_with_chunks_tag 'calendar', 'map', 'data-turbolinks-track': 'reload' %> # =>
73+
# <script src="/packs/vendor-16838bab065ae1e314.js" data-turbolinks-track="reload"></script>
74+
# <script src="/packs/calendar~runtime-16838bab065ae1e314.js" data-turbolinks-track="reload"></script>
75+
# <script src="/packs/calendar-1016838bab065ae1e314.js" data-turbolinks-track="reload"></script>
76+
# <script src="/packs/map~runtime-16838bab065ae1e314.js" data-turbolinks-track="reload"></script>
77+
# <script src="/packs/map-16838bab065ae1e314.js" data-turbolinks-track="reload"></script>
78+
# DO:
79+
# <%= javascript_packs_with_chunks_tag 'calendar', 'map' %>
80+
# DON'T:
81+
# <%= javascript_packs_with_chunks_tag 'calendar' %>
82+
# <%= javascript_packs_with_chunks_tag 'map' %>
83+
def javascript_packs_with_chunks_tag(*names, **options)
84+
javascript_include_tag(*sources_from_manifest_entrypoints(names, type: :javascript), **options)
6385
end
6486

6587
# Creates a link tag that references the named pack file, as compiled by webpack per the entries list
@@ -80,7 +102,7 @@ def javascript_pack_tag(*names, **options)
80102
# <link rel="stylesheet" media="screen" href="/packs/calendar-1016838bab065ae1e122.css" data-turbolinks-track="reload" />
81103
def stylesheet_pack_tag(*names, **options)
82104
if current_webpacker_instance.config.extract_css?
83-
stylesheet_link_tag(*sources_from_pack_manifest(names, type: :stylesheet), **options)
105+
stylesheet_link_tag(*sources_from_manifest_entries(names, type: :stylesheet), **options)
84106
end
85107
end
86108

@@ -89,7 +111,11 @@ def stylesheet?(name)
89111
File.extname(name) == ".css"
90112
end
91113

92-
def sources_from_pack_manifest(names, type:)
114+
def sources_from_manifest_entries(names, type:)
93115
names.map { |name| current_webpacker_instance.manifest.lookup!(name, type: type) }.flatten
94116
end
117+
118+
def sources_from_manifest_entrypoints(names, type:)
119+
names.map { |name| current_webpacker_instance.manifest.lookup_pack_with_chunks!(name, type: type) }.flatten.uniq
120+
end
95121
end

‎lib/webpacker/manifest.rb

+15-16
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,20 @@ def refresh
1818
@data = load
1919
end
2020

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][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)
33+
end
34+
2135
# Computes the relative path for a given Webpacker asset using manifest.json.
2236
# If no asset is found, returns nil.
2337
#
@@ -27,22 +41,7 @@ def refresh
2741
def lookup(name, pack_type = {})
2842
compile if compiling?
2943

30-
# When using SplitChunks or RuntimeChunks the manifest hash will contain
31-
# an extra object called "entrypoints". When the entrypoints key is not
32-
# present in the manifest, or the name is not found in the entrypoints hash,
33-
# it will raise a NoMethodError. If this happens, we should try to lookup
34-
# a single instance of the pack based on the given name.
35-
begin
36-
manifest_pack_type = manifest_type(pack_type[:type])
37-
manifest_pack_name = manifest_name(name, manifest_pack_type)
38-
39-
# Lookup the pack in the entrypoints of the manifest
40-
find("entrypoints")[manifest_pack_name][manifest_pack_type]
41-
rescue NoMethodError
42-
43-
# Lookup a single instance of the pack
44-
find(full_pack_name(name, pack_type[:type]))
45-
end
44+
find(full_pack_name(name, pack_type[:type]))
4645
end
4746

4847
# Like lookup, except that if no asset is found, raises a Webpacker::Manifest::MissingEntryError.

‎package/environments/development.js

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ module.exports = class extends Base {
99

1010
if (devServer.hmr) {
1111
this.plugins.append('HotModuleReplacement', new webpack.HotModuleReplacementPlugin())
12-
this.plugins.append('NamedModules', new webpack.NamedModulesPlugin())
1312
this.config.output.filename = '[name]-[hash].js'
1413
}
1514

‎test/helper_test.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def test_javascript_pack_tag_split_chunks
6464
%(<script src="/packs/vendors~application~bootstrap-c20632e7baf2c81200d3.chunk.js"></script>\n) +
6565
%(<script src="/packs/vendors~application-e55f2aae30c07fb6d82a.chunk.js"></script>\n) +
6666
%(<script src="/packs/application-k344a6d59eef8632c9d1.js"></script>),
67-
javascript_pack_tag("application")
67+
javascript_packs_with_chunks_tag("application")
6868
end
6969

7070
def test_stylesheet_pack_tag

‎test/manifest_test.rb

+5-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ def test_lookup_nil
2222
assert_nil Webpacker.manifest.lookup("foo.js")
2323
end
2424

25+
def test_lookup_chunks_nil
26+
assert_nil Webpacker.manifest.lookup_pack_with_chunks("foo.js")
27+
end
28+
2529
def test_lookup_success
2630
assert_equal Webpacker.manifest.lookup("bootstrap.js"), "/packs/bootstrap-300631c4f0e0f9c865bc.js"
2731
end
@@ -33,6 +37,6 @@ def test_lookup_entrypoint
3337
"/packs/application-k344a6d59eef8632c9d1.js"
3438
]
3539

36-
assert_equal Webpacker.manifest.lookup!("application", type: :javascript), application_entrypoints
40+
assert_equal Webpacker.manifest.lookup_pack_with_chunks!("application", type: :javascript), application_entrypoints
3741
end
3842
end

0 commit comments

Comments
 (0)
Please sign in to comment.