webpacker 4.0.7 → 5.0.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 (91) hide show
  1. checksums.yaml +4 -4
  2. data/.node-version +1 -1
  3. data/.rubocop.yml +2 -1
  4. data/.travis.yml +10 -20
  5. data/CHANGELOG.md +243 -137
  6. data/Gemfile +1 -0
  7. data/Gemfile.lock +84 -62
  8. data/README.md +52 -149
  9. data/docs/css.md +15 -4
  10. data/docs/deployment.md +40 -11
  11. data/docs/docker.md +33 -14
  12. data/docs/engines.md +53 -3
  13. data/docs/es6.md +19 -1
  14. data/docs/integrations.md +220 -0
  15. data/docs/troubleshooting.md +37 -9
  16. data/docs/typescript.md +10 -8
  17. data/docs/webpack-dev-server.md +1 -1
  18. data/docs/webpack.md +18 -3
  19. data/gemfiles/{Gemfile-rails.4.2.x → Gemfile-rails.6.0.x} +1 -1
  20. data/lib/install/bin/webpack +0 -1
  21. data/lib/install/bin/webpack-dev-server +0 -1
  22. data/lib/install/coffee.rb +1 -1
  23. data/lib/install/config/babel.config.js +10 -10
  24. data/lib/install/config/webpacker.yml +2 -1
  25. data/lib/install/elm.rb +1 -1
  26. data/lib/install/erb.rb +2 -2
  27. data/lib/install/examples/angular/hello_angular/polyfills.ts +2 -2
  28. data/lib/install/examples/react/babel.config.js +16 -14
  29. data/lib/install/examples/svelte/app.svelte +11 -0
  30. data/lib/install/examples/svelte/hello_svelte.js +20 -0
  31. data/lib/install/loaders/elm.js +9 -6
  32. data/lib/install/loaders/svelte.js +9 -0
  33. data/lib/install/loaders/typescript.js +1 -1
  34. data/lib/install/svelte.rb +29 -0
  35. data/lib/install/template.rb +2 -2
  36. data/lib/install/typescript.rb +1 -1
  37. data/lib/install/vue.rb +1 -1
  38. data/lib/tasks/installers.rake +1 -0
  39. data/lib/tasks/webpacker.rake +2 -0
  40. data/lib/tasks/webpacker/check_node.rake +14 -7
  41. data/lib/tasks/webpacker/check_yarn.rake +16 -9
  42. data/lib/tasks/webpacker/clean.rake +25 -0
  43. data/lib/tasks/webpacker/clobber.rake +8 -4
  44. data/lib/tasks/webpacker/compile.rake +2 -10
  45. data/lib/tasks/webpacker/yarn_install.rake +5 -1
  46. data/lib/webpacker.rb +9 -1
  47. data/lib/webpacker/commands.rb +53 -1
  48. data/lib/webpacker/compiler.rb +15 -8
  49. data/lib/webpacker/configuration.rb +9 -1
  50. data/lib/webpacker/dev_server.rb +1 -1
  51. data/lib/webpacker/dev_server_proxy.rb +2 -8
  52. data/lib/webpacker/dev_server_runner.rb +4 -4
  53. data/lib/webpacker/env.rb +1 -1
  54. data/lib/webpacker/helper.rb +39 -13
  55. data/lib/webpacker/manifest.rb +4 -4
  56. data/lib/webpacker/railtie.rb +6 -0
  57. data/lib/webpacker/version.rb +1 -1
  58. data/package.json +38 -38
  59. data/package/__tests__/config.js +0 -23
  60. data/package/config.js +2 -10
  61. data/package/config_types/config_list.js +3 -3
  62. data/package/config_types/config_object.js +1 -1
  63. data/package/environments/__tests__/base.js +10 -0
  64. data/package/environments/base.js +14 -3
  65. data/package/environments/development.js +1 -5
  66. data/package/environments/production.js +12 -0
  67. data/package/rules/babel.js +1 -1
  68. data/package/rules/node_modules.js +2 -2
  69. data/package/rules/sass.js +3 -2
  70. data/package/utils/__tests__/get_style_rule.js +9 -0
  71. data/package/utils/deep_merge.js +5 -5
  72. data/package/utils/get_style_rule.js +7 -12
  73. data/package/utils/helpers.js +9 -9
  74. data/test/command_test.rb +6 -0
  75. data/test/compiler_test.rb +5 -6
  76. data/test/configuration_test.rb +36 -27
  77. data/test/dev_server_test.rb +22 -0
  78. data/test/helper_test.rb +34 -0
  79. data/test/manifest_test.rb +37 -6
  80. data/test/rake_tasks_test.rb +17 -0
  81. data/test/test_app/app/javascript/packs/multi_entry.css +4 -0
  82. data/test/test_app/app/javascript/packs/multi_entry.js +4 -0
  83. data/test/test_app/bin/webpack +0 -1
  84. data/test/test_app/bin/webpack-dev-server +0 -1
  85. data/test/test_app/config/webpacker.yml +1 -0
  86. data/test/test_app/public/packs/manifest.json +3 -0
  87. data/webpacker.gemspec +5 -3
  88. data/yarn.lock +2684 -1846
  89. metadata +48 -12
  90. data/gemfiles/Gemfile-rails.5.0.x +0 -9
  91. data/gemfiles/Gemfile-rails.5.1.x +0 -9
@@ -14,11 +14,7 @@ module.exports = class extends Base {
14
14
 
15
15
  this.config.merge({
16
16
  mode: 'development',
17
- cache: true,
18
17
  devtool: 'cheap-module-source-map',
19
- output: {
20
- pathinfo: true
21
- },
22
18
  devServer: {
23
19
  clientLogLevel: 'none',
24
20
  compress: devServer.compress,
@@ -40,7 +36,7 @@ module.exports = class extends Base {
40
36
  overlay: devServer.overlay,
41
37
  stats: {
42
38
  entrypoints: false,
43
- errorDetails: false,
39
+ errorDetails: true,
44
40
  modules: false,
45
41
  moduleTrace: false
46
42
  },
@@ -18,6 +18,18 @@ module.exports = class extends Base {
18
18
  })
19
19
  )
20
20
 
21
+ if ('brotli' in process.versions) {
22
+ this.plugins.append(
23
+ 'Compression Brotli',
24
+ new CompressionPlugin({
25
+ filename: '[path].br[query]',
26
+ algorithm: 'brotliCompress',
27
+ cache: true,
28
+ test: /\.(js|css|html|json|ico|svg|eot|otf|ttf|map)$/
29
+ })
30
+ )
31
+ }
32
+
21
33
  this.plugins.append(
22
34
  'OptimizeCSSAssets',
23
35
  new OptimizeCSSAssetsPlugin({
@@ -6,7 +6,7 @@ const { nodeEnv } = require('../env')
6
6
  // Uses application .babelrc to apply any transformations
7
7
  module.exports = {
8
8
  test: /\.(js|jsx|mjs)?(\.erb)?$/,
9
- include: [sourcePath, ...resolvedPaths].map(p => resolve(p)),
9
+ include: [sourcePath, ...resolvedPaths].map((p) => resolve(p)),
10
10
  exclude: /node_modules/,
11
11
  use: [
12
12
  {
@@ -3,11 +3,11 @@ const { cache_path: cachePath } = require('../config')
3
3
  const { nodeEnv } = require('../env')
4
4
 
5
5
  // Compile standard ES features for JS in node_modules with Babel.
6
- // Regex details for exclude: https://regex101.com/r/CglKdg/5/
6
+ // Regex details for exclude: https://regex101.com/r/SKPnnv/1
7
7
  module.exports = {
8
8
  test: /\.(js|mjs)$/,
9
9
  include: /node_modules/,
10
- exclude: /(?:@?babel(?:\/|\\{1,2}|-).+)|regenerator-runtime|core-js|webpack/,
10
+ exclude: /(?:@?babel(?:\/|\\{1,2}|-).+)|regenerator-runtime|core-js|^webpack$|^webpack-assets-manifest$|^webpack-cli$|^webpack-sources$|^@rails\/webpacker$/,
11
11
  use: [
12
12
  {
13
13
  loader: 'babel-loader',
@@ -1,8 +1,9 @@
1
1
  const getStyleRule = require('../utils/get_style_rule')
2
+ const { resolved_paths: includePaths } = require('../config')
2
3
 
3
- module.exports = getStyleRule(/\.(scss|sass)$/i, false, [
4
+ module.exports = getStyleRule(/\.(scss|sass)(\.erb)?$/i, false, [
4
5
  {
5
6
  loader: 'sass-loader',
6
- options: { sourceMap: true }
7
+ options: { sourceMap: true, includePaths }
7
8
  }
8
9
  ])
@@ -44,6 +44,15 @@ describe('getStyleRule', () => {
44
44
  expect(cssRule.use).toMatchObject(expect.arrayContaining(expectation))
45
45
  })
46
46
 
47
+ test('adds style-loader when extract_css is true', () => {
48
+ const expectation = [{loader: 'style-loader'}]
49
+
50
+ require('../../config').extract_css = false
51
+ const cssRule = getStyleRule(/\.(css)$/i)
52
+
53
+ expect(cssRule.use).toMatchObject(expect.objectContaining(expectation))
54
+ })
55
+
47
56
  test(`doesn't add mini-css-extract-plugin when extract_css is false`, () => {
48
57
  const MiniCssExtractPlugin = require('mini-css-extract-plugin')
49
58
  const expectation = [MiniCssExtractPlugin.loader]
@@ -10,11 +10,11 @@ const deepMerge = (target, source) => {
10
10
  if (!(isObject(target) && isObject(source))) return source
11
11
 
12
12
  return [...Object.keys(target), ...Object.keys(source)].reduce(
13
- (result, key) => (Object.assign(
14
- {},
15
- result,
16
- { [key]: deepMerge(target[key], source[key]) }
17
- )),
13
+ (result, key) => ({
14
+
15
+ ...result,
16
+ [key]: deepMerge(target[key], source[key])
17
+ }),
18
18
  {}
19
19
  )
20
20
  }
@@ -1,17 +1,9 @@
1
1
  const MiniCssExtractPlugin = require('mini-css-extract-plugin')
2
2
  const { resolve } = require('path')
3
- const devServer = require('../dev_server')
4
3
  const config = require('../config')
5
4
 
6
- const inDevServer = process.argv.find(v => v.includes('webpack-dev-server'))
7
- const isHMR = inDevServer && (devServer && devServer.hmr)
8
-
9
5
  const styleLoader = {
10
- loader: 'style-loader',
11
- options: {
12
- hmr: isHMR,
13
- sourceMap: true
14
- }
6
+ loader: 'style-loader'
15
7
  }
16
8
 
17
9
  const getStyleRule = (test, modules = false, preprocessors = []) => {
@@ -21,8 +13,9 @@ const getStyleRule = (test, modules = false, preprocessors = []) => {
21
13
  options: {
22
14
  sourceMap: true,
23
15
  importLoaders: 2,
24
- localIdentName: '[name]__[local]___[hash:base64:5]',
25
- modules
16
+ modules: modules ? {
17
+ localIdentName: '[name]__[local]___[hash:base64:5]'
18
+ } : false
26
19
  }
27
20
  },
28
21
  {
@@ -44,7 +37,9 @@ const getStyleRule = (test, modules = false, preprocessors = []) => {
44
37
  }
45
38
 
46
39
  // sideEffects - See https://github.com/webpack/webpack/issues/6571
47
- return Object.assign({}, { test, use, sideEffects: !modules }, options)
40
+ return {
41
+ test, use, sideEffects: !modules, ...options
42
+ }
48
43
  }
49
44
 
50
45
  module.exports = getStyleRule
@@ -1,29 +1,29 @@
1
1
  const { stringify } = require('flatted/cjs')
2
2
 
3
- const isObject = value => typeof value === 'object'
3
+ const isObject = (value) => typeof value === 'object'
4
4
  && value !== null
5
5
  && (value.length === undefined || value.length === null)
6
6
 
7
- const isNotObject = value => !isObject(value)
7
+ const isNotObject = (value) => !isObject(value)
8
8
 
9
- const isBoolean = str => /^true/.test(str) || /^false/.test(str)
9
+ const isBoolean = (str) => /^true/.test(str) || /^false/.test(str)
10
10
 
11
- const isEmpty = value => value === null || value === undefined
11
+ const isEmpty = (value) => value === null || value === undefined
12
12
 
13
- const isString = key => key && typeof key === 'string'
13
+ const isString = (key) => key && typeof key === 'string'
14
14
 
15
15
  const isStrPath = (key) => {
16
16
  if (!isString(key)) throw new Error(`Key ${key} should be string`)
17
17
  return isString(key) && key.includes('.')
18
18
  }
19
19
 
20
- const isArray = value => Array.isArray(value)
20
+ const isArray = (value) => Array.isArray(value)
21
21
 
22
22
  const isEqual = (target, source) => stringify(target) === stringify(source)
23
23
 
24
- const canMerge = value => isObject(value) || isArray(value)
24
+ const canMerge = (value) => isObject(value) || isArray(value)
25
25
 
26
- const prettyPrint = obj => JSON.stringify(obj, null, 2)
26
+ const prettyPrint = (obj) => JSON.stringify(obj, null, 2)
27
27
 
28
28
  const chdirTestApp = () => {
29
29
  try {
@@ -39,7 +39,7 @@ const resetEnv = () => {
39
39
  process.env = {}
40
40
  }
41
41
 
42
- const ensureTrailingSlash = path => (path.endsWith('/') ? path : `${path}/`)
42
+ const ensureTrailingSlash = (path) => (path.endsWith('/') ? path : `${path}/`)
43
43
 
44
44
  module.exports = {
45
45
  chdirTestApp,
@@ -24,4 +24,10 @@ class CommandTest < Minitest::Test
24
24
  end
25
25
  end
26
26
  end
27
+
28
+ def test_clean_command_works_with_nested_hashes_and_without_any_compiled_files
29
+ File.stub :delete, true do
30
+ assert Webpacker.commands.clean
31
+ end
32
+ end
27
33
  end
@@ -25,9 +25,9 @@ class CompilerTest < Minitest::Test
25
25
 
26
26
  def test_default_watched_paths
27
27
  assert_equal Webpacker.compiler.send(:default_watched_paths), [
28
- "app/assets/**/*",
29
- "/etc/yarn/**/*",
30
- "app/javascript/**/*",
28
+ "app/assets/**/*{.mjs,.js,.sass,.scss,.css,.module.sass,.module.scss,.module.css,.png,.svg,.gif,.jpeg,.jpg}",
29
+ "/etc/yarn/**/*{.mjs,.js,.sass,.scss,.css,.module.sass,.module.scss,.module.css,.png,.svg,.gif,.jpeg,.jpg}",
30
+ "app/javascript/**/*{.mjs,.js,.sass,.scss,.css,.module.sass,.module.scss,.module.css,.png,.svg,.gif,.jpeg,.jpg}",
31
31
  "yarn.lock",
32
32
  "package.json",
33
33
  "config/webpack/**/*"
@@ -49,14 +49,13 @@ class CompilerTest < Minitest::Test
49
49
  end
50
50
  end
51
51
 
52
- def test_staleness_on_compile_fail
52
+ def test_freshness_on_compile_fail
53
53
  status = OpenStruct.new(success?: false)
54
54
 
55
55
  assert Webpacker.compiler.stale?
56
56
  Open3.stub :capture3, [:sterr, :stdout, status] do
57
-
58
57
  Webpacker.compiler.compile
59
- assert Webpacker.compiler.stale?
58
+ assert Webpacker.compiler.fresh?
60
59
  end
61
60
  end
62
61
 
@@ -14,11 +14,21 @@ class ConfigurationTest < Webpacker::Test
14
14
  assert_equal source_path, @config.source_path.to_s
15
15
  end
16
16
 
17
+ def test_source_path_globbed
18
+ assert_equal @config.source_path_globbed,
19
+ "app/javascript/**/*{.mjs,.js,.sass,.scss,.css,.module.sass,.module.scss,.module.css,.png,.svg,.gif,.jpeg,.jpg}"
20
+ end
21
+
17
22
  def test_source_entry_path
18
23
  source_entry_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/app/javascript", "packs").to_s
19
24
  assert_equal @config.source_entry_path.to_s, source_entry_path
20
25
  end
21
26
 
27
+ def test_public_root_path
28
+ public_root_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/public").to_s
29
+ assert_equal @config.public_path.to_s, public_root_path
30
+ end
31
+
22
32
  def test_public_output_path
23
33
  public_output_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/public/packs").to_s
24
34
  assert_equal @config.public_output_path.to_s, public_output_path
@@ -48,7 +58,10 @@ class ConfigurationTest < Webpacker::Test
48
58
  end
49
59
 
50
60
  def test_resolved_paths_globbed
51
- assert_equal @config.resolved_paths_globbed, ["app/assets/**/*", "/etc/yarn/**/*"]
61
+ assert_equal @config.resolved_paths_globbed, [
62
+ "app/assets/**/*{.mjs,.js,.sass,.scss,.css,.module.sass,.module.scss,.module.css,.png,.svg,.gif,.jpeg,.jpg}",
63
+ "/etc/yarn/**/*{.mjs,.js,.sass,.scss,.css,.module.sass,.module.scss,.module.css,.png,.svg,.gif,.jpeg,.jpg}"
64
+ ]
52
65
  end
53
66
 
54
67
  def test_extensions
@@ -60,40 +73,36 @@ class ConfigurationTest < Webpacker::Test
60
73
  def test_cache_manifest?
61
74
  assert @config.cache_manifest?
62
75
 
63
- @config = Webpacker::Configuration.new(
64
- root_path: @config.root_path,
65
- config_path: @config.config_path,
66
- env: "development"
67
- )
68
-
69
- refute @config.cache_manifest?
70
-
71
- @config = Webpacker::Configuration.new(
72
- root_path: @config.root_path,
73
- config_path: @config.config_path,
74
- env: "test"
75
- )
76
+ with_rails_env("development") do
77
+ refute Webpacker.config.cache_manifest?
78
+ end
76
79
 
77
- refute @config.cache_manifest?
80
+ with_rails_env("test") do
81
+ refute Webpacker.config.cache_manifest?
82
+ end
78
83
  end
79
84
 
80
85
  def test_compile?
81
86
  refute @config.compile?
82
87
 
83
- @config = Webpacker::Configuration.new(
84
- root_path: @config.root_path,
85
- config_path: @config.config_path,
86
- env: "development"
87
- )
88
+ with_rails_env("development") do
89
+ assert Webpacker.config.compile?
90
+ end
88
91
 
89
- assert @config.compile?
92
+ with_rails_env("test") do
93
+ assert Webpacker.config.compile?
94
+ end
95
+ end
90
96
 
91
- @config = Webpacker::Configuration.new(
92
- root_path: @config.root_path,
93
- config_path: @config.config_path,
94
- env: "test"
95
- )
97
+ def test_extract_css?
98
+ assert @config.extract_css?
99
+
100
+ with_rails_env("development") do
101
+ refute Webpacker.config.extract_css?
102
+ end
96
103
 
97
- assert @config.compile?
104
+ with_rails_env("test") do
105
+ refute Webpacker.config.extract_css?
106
+ end
98
107
  end
99
108
  end
@@ -22,4 +22,26 @@ class DevServerTest < Webpacker::Test
22
22
  assert_equal Webpacker.dev_server.https?, false
23
23
  end
24
24
  end
25
+
26
+ def test_protocol
27
+ with_rails_env("development") do
28
+ assert_equal Webpacker.dev_server.protocol, "http"
29
+ end
30
+ end
31
+
32
+ def test_host_with_port
33
+ with_rails_env("development") do
34
+ assert_equal Webpacker.dev_server.host_with_port, "localhost:3035"
35
+ end
36
+ end
37
+
38
+ def test_pretty?
39
+ with_rails_env("development") do
40
+ refute Webpacker.dev_server.pretty?
41
+ end
42
+ end
43
+
44
+ def test_default_env_prefix
45
+ assert_equal Webpacker::DevServer::DEFAULT_ENV_PREFIX, "WEBPACKER_DEV_SERVER"
46
+ end
25
47
  end
@@ -52,6 +52,24 @@ class HelperTest < ActionView::TestCase
52
52
  image_pack_tag("media/images/nested/image.jpg", size: "16x10", alt: "Edit Entry")
53
53
  end
54
54
 
55
+ def test_favicon_pack_tag
56
+ assert_equal \
57
+ "<link rel=\"apple-touch-icon\" type=\"image/png\" href=\"/packs/application-k344a6d59eef8632c9d1.png\" />",
58
+ favicon_pack_tag("application.png", rel: "apple-touch-icon", type: "image/png")
59
+ assert_equal \
60
+ "<link rel=\"apple-touch-icon\" type=\"image/png\" href=\"/packs/media/images/mb-icon-c38deda30895059837cf.png\" />",
61
+ favicon_pack_tag("mb-icon.png", rel: "apple-touch-icon", type: "image/png")
62
+ assert_equal \
63
+ "<link rel=\"apple-touch-icon\" type=\"image/png\" href=\"/packs/media/images/mb-icon-c38deda30895059837cf.png\" />",
64
+ favicon_pack_tag("media/images/mb-icon.png", rel: "apple-touch-icon", type: "image/png")
65
+ assert_equal \
66
+ "<link rel=\"apple-touch-icon\" type=\"image/png\" href=\"/packs/media/images/nested/mb-icon-c38deda30895059837cf.png\" />",
67
+ favicon_pack_tag("nested/mb-icon.png", rel: "apple-touch-icon", type: "image/png")
68
+ assert_equal \
69
+ "<link rel=\"apple-touch-icon\" type=\"image/png\" href=\"/packs/media/images/nested/mb-icon-c38deda30895059837cf.png\" />",
70
+ favicon_pack_tag("media/images/nested/mb-icon.png", rel: "apple-touch-icon", type: "image/png")
71
+ end
72
+
55
73
  def test_javascript_pack_tag
56
74
  assert_equal \
57
75
  %(<script src="/packs/bootstrap-300631c4f0e0f9c865bc.js"></script>),
@@ -79,6 +97,22 @@ class HelperTest < ActionView::TestCase
79
97
  javascript_packs_with_chunks_tag("application")
80
98
  end
81
99
 
100
+ def test_preload_pack_asset
101
+ if self.class.method_defined?(:preload_link_tag)
102
+ assert_equal \
103
+ %(<link rel="preload" href="/packs/fonts/fa-regular-400-944fb546bd7018b07190a32244f67dc9.woff2" as="font" type="font/woff2" crossorigin="anonymous">),
104
+ preload_pack_asset("fonts/fa-regular-400.woff2")
105
+ else
106
+ error = assert_raises do
107
+ preload_pack_asset("fonts/fa-regular-400.woff2")
108
+ end
109
+
110
+ assert_equal \
111
+ "You need Rails >= 5.2 to use this tag.",
112
+ error.message
113
+ end
114
+ end
115
+
82
116
  def test_stylesheet_pack_tag_split_chunks
83
117
  assert_equal \
84
118
  %(<link rel="stylesheet" media="screen" href="/packs/1-c20632e7baf2c81200d3.chunk.css" />\n) +
@@ -2,16 +2,23 @@ require "test_helper"
2
2
 
3
3
  class ManifestTest < Minitest::Test
4
4
  def test_lookup_exception!
5
- manifest_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/public/packs", "manifest.json").to_s
6
5
  asset_file = "calendar.js"
7
6
 
8
- Webpacker.config.stub :compile?, false do
9
- error = assert_raises Webpacker::Manifest::MissingEntryError do
10
- Webpacker.manifest.lookup!(asset_file)
11
- end
7
+ error = assert_raises_manifest_missing_entry_error do
8
+ Webpacker.manifest.lookup!(asset_file)
9
+ end
10
+
11
+ assert_match "Webpacker can't find #{asset_file} in #{manifest_path}", error.message
12
+ end
13
+
14
+ def test_lookup_with_type_exception!
15
+ asset_file = "calendar"
12
16
 
13
- assert_match "Webpacker can't find #{asset_file} in #{manifest_path}", error.message
17
+ error = assert_raises_manifest_missing_entry_error do
18
+ Webpacker.manifest.lookup!(asset_file, type: :javascript)
14
19
  end
20
+
21
+ assert_match "Webpacker can't find #{asset_file}.js in #{manifest_path}", error.message
15
22
  end
16
23
 
17
24
  def test_lookup_success!
@@ -30,6 +37,16 @@ class ManifestTest < Minitest::Test
30
37
  assert_equal Webpacker.manifest.lookup("bootstrap.js"), "/packs/bootstrap-300631c4f0e0f9c865bc.js"
31
38
  end
32
39
 
40
+ def test_lookup_entrypoint_exception!
41
+ asset_file = "calendar"
42
+
43
+ error = assert_raises_manifest_missing_entry_error do
44
+ Webpacker.manifest.lookup_pack_with_chunks!(asset_file, type: :javascript)
45
+ end
46
+
47
+ assert_match "Webpacker can't find #{asset_file}.js in #{manifest_path}", error.message
48
+ end
49
+
33
50
  def test_lookup_entrypoint
34
51
  application_entrypoints = [
35
52
  "/packs/vendors~application~bootstrap-c20632e7baf2c81200d3.chunk.js",
@@ -39,4 +56,18 @@ class ManifestTest < Minitest::Test
39
56
 
40
57
  assert_equal Webpacker.manifest.lookup_pack_with_chunks!("application", type: :javascript), application_entrypoints
41
58
  end
59
+
60
+ private
61
+
62
+ def assert_raises_manifest_missing_entry_error(&block)
63
+ error = nil
64
+ Webpacker.config.stub :compile?, false do
65
+ error = assert_raises Webpacker::Manifest::MissingEntryError, &block
66
+ end
67
+ error
68
+ end
69
+
70
+ def manifest_path
71
+ File.expand_path File.join(File.dirname(__FILE__), "test_app/public/packs", "manifest.json").to_s
72
+ end
42
73
  end