bridgetown-core 0.19.2 → 0.21.0.beta3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/bridgetown-core.gemspec +1 -2
  3. data/lib/bridgetown-core.rb +37 -29
  4. data/lib/bridgetown-core/cleaner.rb +9 -3
  5. data/lib/bridgetown-core/collection.rb +177 -78
  6. data/lib/bridgetown-core/commands/base.rb +9 -0
  7. data/lib/bridgetown-core/commands/build.rb +0 -11
  8. data/lib/bridgetown-core/commands/concerns/git_helpers.rb +20 -0
  9. data/lib/bridgetown-core/commands/configure.rb +8 -3
  10. data/lib/bridgetown-core/commands/console.rb +4 -0
  11. data/lib/bridgetown-core/commands/doctor.rb +1 -19
  12. data/lib/bridgetown-core/commands/new.rb +2 -2
  13. data/lib/bridgetown-core/commands/plugins.rb +14 -13
  14. data/lib/bridgetown-core/commands/serve.rb +0 -14
  15. data/lib/bridgetown-core/component.rb +178 -0
  16. data/lib/bridgetown-core/concerns/data_accessible.rb +1 -0
  17. data/lib/bridgetown-core/concerns/front_matter_importer.rb +52 -0
  18. data/lib/bridgetown-core/concerns/site/configurable.rb +10 -10
  19. data/lib/bridgetown-core/concerns/site/content.rb +56 -15
  20. data/lib/bridgetown-core/concerns/site/localizable.rb +3 -5
  21. data/lib/bridgetown-core/concerns/site/processable.rb +6 -4
  22. data/lib/bridgetown-core/concerns/site/renderable.rb +26 -0
  23. data/lib/bridgetown-core/concerns/site/writable.rb +12 -2
  24. data/lib/bridgetown-core/concerns/validatable.rb +2 -5
  25. data/lib/bridgetown-core/configuration.rb +51 -30
  26. data/lib/bridgetown-core/configurations/bt-postcss.rb +1 -3
  27. data/lib/bridgetown-core/configurations/netlify.rb +1 -0
  28. data/lib/bridgetown-core/configurations/tailwindcss.rb +1 -3
  29. data/lib/bridgetown-core/converter.rb +23 -0
  30. data/lib/bridgetown-core/converters/erb_templates.rb +51 -35
  31. data/lib/bridgetown-core/converters/identity.rb +0 -9
  32. data/lib/bridgetown-core/converters/liquid_templates.rb +1 -1
  33. data/lib/bridgetown-core/converters/markdown.rb +14 -4
  34. data/lib/bridgetown-core/converters/markdown/kramdown_parser.rb +5 -38
  35. data/lib/bridgetown-core/converters/ruby_templates.rb +17 -0
  36. data/lib/bridgetown-core/converters/smartypants.rb +3 -1
  37. data/lib/bridgetown-core/core_ext/psych.rb +19 -0
  38. data/lib/bridgetown-core/current.rb +10 -0
  39. data/lib/bridgetown-core/document.rb +9 -16
  40. data/lib/bridgetown-core/drops/collection_drop.rb +1 -1
  41. data/lib/bridgetown-core/drops/page_drop.rb +4 -0
  42. data/lib/bridgetown-core/drops/relations_drop.rb +23 -0
  43. data/lib/bridgetown-core/drops/resource_drop.rb +83 -0
  44. data/lib/bridgetown-core/drops/site_drop.rb +33 -8
  45. data/lib/bridgetown-core/drops/unified_payload_drop.rb +5 -0
  46. data/lib/bridgetown-core/entry_filter.rb +17 -28
  47. data/lib/bridgetown-core/errors.rb +0 -2
  48. data/lib/bridgetown-core/filters.rb +3 -26
  49. data/lib/bridgetown-core/filters/from_liquid.rb +23 -0
  50. data/lib/bridgetown-core/filters/url_filters.rb +12 -0
  51. data/lib/bridgetown-core/frontmatter_defaults.rb +1 -1
  52. data/lib/bridgetown-core/generators/prototype_generator.rb +37 -19
  53. data/lib/bridgetown-core/helpers.rb +48 -9
  54. data/lib/bridgetown-core/layout.rb +28 -13
  55. data/lib/bridgetown-core/liquid_renderer/file.rb +1 -0
  56. data/lib/bridgetown-core/liquid_renderer/table.rb +1 -0
  57. data/lib/bridgetown-core/model/base.rb +138 -0
  58. data/lib/bridgetown-core/model/builder_origin.rb +40 -0
  59. data/lib/bridgetown-core/model/origin.rb +38 -0
  60. data/lib/bridgetown-core/model/repo_origin.rb +126 -0
  61. data/lib/bridgetown-core/page.rb +11 -2
  62. data/lib/bridgetown-core/plugin_manager.rb +1 -3
  63. data/lib/bridgetown-core/publisher.rb +8 -2
  64. data/lib/bridgetown-core/reader.rb +37 -22
  65. data/lib/bridgetown-core/readers/data_reader.rb +5 -5
  66. data/lib/bridgetown-core/readers/defaults_reader.rb +1 -1
  67. data/lib/bridgetown-core/readers/page_reader.rb +1 -0
  68. data/lib/bridgetown-core/readers/post_reader.rb +5 -4
  69. data/lib/bridgetown-core/regenerator.rb +9 -2
  70. data/lib/bridgetown-core/related_posts.rb +9 -6
  71. data/lib/bridgetown-core/renderer.rb +6 -13
  72. data/lib/bridgetown-core/resource/base.rb +313 -0
  73. data/lib/bridgetown-core/resource/destination.rb +49 -0
  74. data/lib/bridgetown-core/resource/permalink_processor.rb +179 -0
  75. data/lib/bridgetown-core/resource/relations.rb +132 -0
  76. data/lib/bridgetown-core/resource/taxonomy_term.rb +34 -0
  77. data/lib/bridgetown-core/resource/taxonomy_type.rb +56 -0
  78. data/lib/bridgetown-core/resource/transformer.rb +177 -0
  79. data/lib/bridgetown-core/ruby_template_view.rb +11 -11
  80. data/lib/bridgetown-core/site.rb +13 -6
  81. data/lib/bridgetown-core/static_file.rb +33 -10
  82. data/lib/bridgetown-core/tags/highlight.rb +2 -15
  83. data/lib/bridgetown-core/tags/include.rb +1 -1
  84. data/lib/bridgetown-core/tags/post_url.rb +2 -2
  85. data/lib/bridgetown-core/url.rb +1 -0
  86. data/lib/bridgetown-core/utils.rb +49 -43
  87. data/lib/bridgetown-core/utils/require_gems.rb +60 -0
  88. data/lib/bridgetown-core/utils/ruby_exec.rb +6 -9
  89. data/lib/bridgetown-core/utils/ruby_front_matter.rb +39 -0
  90. data/lib/bridgetown-core/version.rb +2 -2
  91. data/lib/bridgetown-core/watcher.rb +1 -1
  92. data/lib/bridgetown-core/yaml_parser.rb +22 -0
  93. data/lib/site_template/package.json.erb +2 -2
  94. data/lib/site_template/plugins/site_builder.rb +1 -1
  95. data/lib/site_template/src/_posts/0000-00-00-welcome-to-bridgetown.md.erb +1 -1
  96. data/lib/site_template/webpack.config.js.erb +26 -6
  97. metadata +39 -40
  98. data/lib/bridgetown-core/external.rb +0 -58
  99. data/lib/bridgetown-core/page_without_a_file.rb +0 -17
  100. data/lib/bridgetown-core/path_manager.rb +0 -31
  101. data/lib/bridgetown-core/readers/collection_reader.rb +0 -23
  102. data/lib/bridgetown-core/readers/static_file_reader.rb +0 -25
  103. data/lib/bridgetown-core/utils/exec.rb +0 -26
  104. data/lib/bridgetown-core/utils/internet.rb +0 -37
  105. data/lib/bridgetown-core/utils/platforms.rb +0 -80
  106. data/lib/bridgetown-core/utils/thread_event.rb +0 -31
  107. data/lib/bridgetown-core/utils/win_tz.rb +0 -75
@@ -4,12 +4,9 @@ module Bridgetown
4
4
  module Utils
5
5
  extend self
6
6
  autoload :Ansi, "bridgetown-core/utils/ansi"
7
- autoload :Exec, "bridgetown-core/utils/exec"
8
- autoload :Internet, "bridgetown-core/utils/internet"
7
+ autoload :RequireGems, "bridgetown-core/utils/require_gems"
9
8
  autoload :RubyExec, "bridgetown-core/utils/ruby_exec"
10
- autoload :Platforms, "bridgetown-core/utils/platforms"
11
- autoload :ThreadEvent, "bridgetown-core/utils/thread_event"
12
- autoload :WinTZ, "bridgetown-core/utils/win_tz"
9
+ autoload :RubyFrontMatterDSL, "bridgetown-core/utils/ruby_front_matter"
13
10
 
14
11
  # Constants for use in #slugify
15
12
  SLUGIFY_MODES = %w(raw default pretty simple ascii latin).freeze
@@ -74,38 +71,32 @@ module Bridgetown
74
71
  end
75
72
  end
76
73
 
77
- # Read array from the supplied hash favouring the singular key
78
- # and then the plural key, and handling any nil entries.
74
+ # Read array from the supplied hash, merging the singular key with the
75
+ # plural key as needing, and handling any nil or duplicate entries.
79
76
  #
80
- # hash - the hash to read from
81
- # singular_key - the singular key
82
- # plural_key - the plural key
83
- #
84
- # Returns an array
85
- def pluralized_array_from_hash(hash, singular_key, plural_key)
86
- array = []
87
- value = value_from_singular_key(hash, singular_key)
88
- value ||= value_from_plural_key(hash, plural_key)
77
+ # @param hsh [Hash] the hash to read from
78
+ # @param singular_key [Symbol] the singular key
79
+ # @param plural_key [Symbol] the plural key
80
+ # @return [Array]
81
+ def pluralized_array_from_hash(hsh, singular_key, plural_key)
82
+ array = [
83
+ hsh[singular_key],
84
+ value_from_plural_key(hsh, plural_key),
85
+ ]
89
86
 
90
- array << value
91
87
  array.flatten!
92
88
  array.compact!
89
+ array.uniq!
93
90
  array
94
91
  end
95
92
 
96
- def value_from_singular_key(hash, key)
97
- hash[key] if hash.key?(key) || (hash.default_proc && hash[key])
98
- end
99
-
100
- def value_from_plural_key(hash, key)
101
- if hash.key?(key) || (hash.default_proc && hash[key])
102
- val = hash[key]
103
- case val
104
- when String
105
- val.split
106
- when Array
107
- val.compact
108
- end
93
+ def value_from_plural_key(hsh, key)
94
+ val = hsh[key]
95
+ case val
96
+ when String
97
+ val.split
98
+ when Array
99
+ val.compact
109
100
  end
110
101
  end
111
102
 
@@ -124,17 +115,23 @@ module Bridgetown
124
115
 
125
116
  # Determines whether a given file has
126
117
  #
127
- # Returns true if the YAML front matter is present.
118
+ # @return [Boolean] if the YAML front matter is present.
128
119
  # rubocop: disable Naming/PredicateName
129
120
  def has_yaml_header?(file)
130
- File.open(file, "rb", &:readline).match? %r!\A---\s*\r?\n!
121
+ File.open(file, "rb", &:readline).match? Bridgetown::FrontMatterImporter::YAML_HEADER
122
+ rescue EOFError
123
+ false
124
+ end
125
+
126
+ def has_rbfm_header?(file)
127
+ File.open(file, "rb", &:readline).match? Bridgetown::FrontMatterImporter::RUBY_HEADER
131
128
  rescue EOFError
132
129
  false
133
130
  end
134
131
 
135
132
  # Determine whether the given content string contains Liquid Tags or Vaiables
136
133
  #
137
- # Returns true is the string contains sequences of `{%` or `{{`
134
+ # @return [Boolean] if the string contains sequences of `{%` or `{{`
138
135
  def has_liquid_construct?(content)
139
136
  return false if content.nil? || content.empty?
140
137
 
@@ -207,7 +204,7 @@ module Bridgetown
207
204
  slug.gsub!(%r!^\-|\-$!i, "")
208
205
 
209
206
  slug.downcase! unless cased
210
- Bridgetown.logger.warn("Warning:", "Empty `slug` generated for '#{string}'.") if slug.empty?
207
+
211
208
  slug
212
209
  end
213
210
 
@@ -347,7 +344,7 @@ module Bridgetown
347
344
 
348
345
  # Return an asset path based on the Webpack manifest file
349
346
  # @param site [Bridgetown::Site] The current site object
350
- # @param asset_type [String] js or css
347
+ # @param asset_type [String] js or css, or filename in manifest
351
348
  #
352
349
  # @return [String] Returns "MISSING_WEBPACK_MANIFEST" if the manifest
353
350
  # file isnt found
@@ -363,21 +360,30 @@ module Bridgetown
363
360
  manifest = JSON.parse(File.read(manifest_file))
364
361
 
365
362
  known_assets = %w(js css)
363
+ asset_path = nil
366
364
  if known_assets.include?(asset_type)
367
365
  asset_path = manifest["main.#{asset_type}"]
368
-
369
366
  log_webpack_asset_error(asset_type) && return if asset_path.nil?
370
-
371
- asset_path = asset_path.split("/").last
372
- return [static_frontend_path(site), asset_type, asset_path].join("/")
367
+ else
368
+ asset_path = manifest.find do |item, _|
369
+ item.sub(%r{^../(frontend/|src/)?}, "") == asset_type
370
+ end&.last
373
371
  end
374
372
 
375
- Bridgetown.logger.error("Unknown Webpack asset type", asset_type)
376
- nil
373
+ if asset_path
374
+ static_frontend_path(site, ["js", asset_path])
375
+ else
376
+ Bridgetown.logger.error("Unknown Webpack asset type", asset_type)
377
+ nil
378
+ end
377
379
  end
378
380
 
379
- def static_frontend_path(site)
380
- path_parts = [site.config["baseurl"].to_s.chomp("/"), "_bridgetown/static"]
381
+ def static_frontend_path(site, additional_parts = [])
382
+ path_parts = [
383
+ site.config["baseurl"].to_s.gsub(%r(^/|/$), ""),
384
+ "_bridgetown/static",
385
+ *additional_parts,
386
+ ]
381
387
  path_parts[0] = "/#{path_parts[0]}" unless path_parts[0].empty?
382
388
  Addressable::URI.parse(path_parts.join("/")).normalize.to_s
383
389
  end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ module Utils
5
+ module RequireGems
6
+ class << self
7
+ #
8
+ # Require a gem or file if it's present, otherwise silently fail.
9
+ #
10
+ # names - a string gem name or array of gem names
11
+ #
12
+ def require_if_present(names)
13
+ Array(names).each do |name|
14
+ require name
15
+ rescue LoadError
16
+ Bridgetown.logger.debug "Couldn't load #{name}. Skipping."
17
+ yield(name, version_constraint(name)) if block_given?
18
+ false
19
+ end
20
+ end
21
+
22
+ #
23
+ # The version constraint required to activate a given gem.
24
+ #
25
+ # Returns a String version constraint in a parseable form for
26
+ # RubyGems.
27
+ def version_constraint
28
+ "> 0"
29
+ end
30
+
31
+ #
32
+ # Require a gem or gems. If it's not present, show a very nice error
33
+ # message that explains everything and is much more helpful than the
34
+ # normal LoadError.
35
+ #
36
+ # names - a string gem name or array of gem names
37
+ #
38
+ def require_with_graceful_fail(names)
39
+ Array(names).each do |name|
40
+ Bridgetown.logger.debug "Requiring:", name.to_s
41
+ require name
42
+ rescue LoadError => e
43
+ Bridgetown.logger.error "Dependency Error:", <<~MSG
44
+ Yikes! It looks like you don't have #{name} or one of its dependencies installed.
45
+ In order to use Bridgetown as currently configured, you'll need to install this gem.
46
+
47
+ If you've run Bridgetown with `bundle exec`, ensure that you have included the #{name}
48
+ gem in your Gemfile as well.
49
+
50
+ The full error message from Ruby is: '#{e.message}'
51
+
52
+ If you run into trouble, you can find helpful resources at https://www.bridgetownrb.com/docs/community/
53
+ MSG
54
+ raise Bridgetown::Errors::MissingDependencyException, name
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -5,8 +5,8 @@ module Bridgetown
5
5
  module RubyExec
6
6
  extend self
7
7
 
8
- # rubocop:disable Metrics/AbcSize
9
- def search_data_for_ruby_code(convertible, renderer)
8
+ # TODO: Deprecate storing Ruby code in YAML, Rb, etc. and just use native Ruby Front Matter
9
+ def search_data_for_ruby_code(convertible, renderer) # rubocop:todo Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
10
10
  return if convertible.data.empty?
11
11
 
12
12
  # Iterate using `keys` here so inline Ruby script can add new data keys
@@ -14,24 +14,21 @@ module Bridgetown
14
14
  data_keys = convertible.data.keys
15
15
  data_keys.each do |k|
16
16
  v = convertible.data[k]
17
- next unless v.is_a?(Rb) || v.is_a?(Hash)
17
+ next unless v.is_a?(Rb) || v.is_a?(Hash) || v.is_a?(Proc)
18
18
 
19
- if v.is_a?(Hash)
19
+ if v.is_a?(Proc)
20
+ convertible.data[k] = convertible.instance_exec(&v)
21
+ elsif v.is_a?(Hash)
20
22
  v.each do |nested_k, nested_v|
21
23
  next unless nested_v.is_a?(Rb)
22
24
 
23
- Bridgetown.logger.debug("Executing inline Ruby…", convertible.relative_path)
24
25
  convertible.data[k][nested_k] = run(nested_v, convertible, renderer)
25
- Bridgetown.logger.debug("Inline Ruby completed!", convertible.relative_path)
26
26
  end
27
27
  else
28
- Bridgetown.logger.debug("Executing inline Ruby…", convertible.relative_path)
29
28
  convertible.data[k] = run(v, convertible, renderer)
30
- Bridgetown.logger.debug("Inline Ruby completed!", convertible.relative_path)
31
29
  end
32
30
  end
33
31
  end
34
- # rubocop:enable Metrics/AbcSize
35
32
 
36
33
  # Sets up a new context in which to eval Ruby coming from front matter.
37
34
  #
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ module Utils
5
+ module RubyFrontMatterDSL
6
+ def front_matter(&block)
7
+ RubyFrontMatter.new.tap { |fm| fm.instance_exec(&block) }
8
+ end
9
+ end
10
+
11
+ class RubyFrontMatter
12
+ def initialize
13
+ @data = {}
14
+ end
15
+
16
+ def method_missing(key, value) # rubocop:disable Style/MissingRespondToMissing
17
+ return super if respond_to?(key)
18
+
19
+ set(key, value)
20
+ end
21
+
22
+ def each(&block)
23
+ @data.each(&block)
24
+ end
25
+
26
+ def get(key)
27
+ @data[key]
28
+ end
29
+
30
+ def set(key, value)
31
+ @data[key] = value
32
+ end
33
+
34
+ def to_h
35
+ @data
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bridgetown
4
- VERSION = "0.19.2"
5
- CODE_NAME = "Arbor Lodge"
4
+ VERSION = "0.21.0.beta3"
5
+ CODE_NAME = "Broughton Beach"
6
6
  end
@@ -140,7 +140,7 @@ module Bridgetown
140
140
  if options[:trace]
141
141
  Bridgetown.logger.info e.backtrace.join("\n")
142
142
  else
143
- Bridgetown.logger.warn "Error:", "Use the --trace option for more information."
143
+ Bridgetown.logger.warn "Backtrace:", "Use the --trace option for more information."
144
144
  end
145
145
  end
146
146
  Bridgetown.logger.info ""
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ class YAMLParser
5
+ PERMITTED_CLASSES = [Date, Time, Rb].freeze
6
+
7
+ class << self
8
+ def load_file(filename, **kwargs)
9
+ kwargs = { permitted_classes: PERMITTED_CLASSES }.merge(kwargs)
10
+ YAML.safe_load_file(filename, **kwargs)
11
+ end
12
+
13
+ def load(yaml)
14
+ if RUBY_VERSION.start_with?("2.5")
15
+ YAML.safe_load yaml, PERMITTED_CLASSES
16
+ else
17
+ YAML.safe_load yaml, permitted_classes: PERMITTED_CLASSES
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -30,8 +30,8 @@
30
30
  "postcss-loader": "^4.1.0",
31
31
  "postcss-preset-env": "^6.7.0",
32
32
  <% else %>
33
- "node-sass": "^4.13.1",
34
- "sass-loader": "^8.0.2",
33
+ "sass": "^1.32.8",
34
+ "sass-loader": "^8.0.2",
35
35
  <% end %>
36
36
  "webpack": "^4.44.2",
37
37
  "webpack-cli": "^3.3.11",
@@ -1,4 +1,4 @@
1
1
  class SiteBuilder < Bridgetown::Builder
2
- # write builders which subclass SiteBuilder in plugins/builder
2
+ # write builders which subclass SiteBuilder in plugins/builders
3
3
  end
4
4
 
@@ -21,6 +21,6 @@ def print_hi(name)
21
21
  end
22
22
  print_hi('Tom')
23
23
  #=> prints 'Hi, Tom' to STDOUT.
24
- ````
24
+ ```
25
25
 
26
26
  Check out the [Bridgetown docs](https://bridgetownrb.com/docs/) for more info on how to get the most out of Bridgetown. File all bugs/feature requests at [Bridgetown’s GitHub repo](https://github.com/bridgetownrb/bridgetown). If you have questions, you can ask them on [Bridgetown Discussions on GitHub](https://github.com/bridgetownrb/bridgetown/discussions).
@@ -3,7 +3,9 @@ const MiniCssExtractPlugin = require("mini-css-extract-plugin");
3
3
  const ManifestPlugin = require("webpack-manifest-plugin");
4
4
 
5
5
  module.exports = {
6
- entry: "./frontend/javascript/index.js",
6
+ entry: {
7
+ main: "./frontend/javascript/index.js"
8
+ },
7
9
  devtool: "source-map",
8
10
  // Set some or all of these to true if you want more verbose logging:
9
11
  stats: {
@@ -14,7 +16,7 @@ module.exports = {
14
16
  },
15
17
  output: {
16
18
  path: path.resolve(__dirname, "output", "_bridgetown", "static", "js"),
17
- filename: "all.[contenthash].js",
19
+ filename: "[name].[contenthash].js",
18
20
  },
19
21
  resolve: {
20
22
  extensions: [".js", ".jsx"],
@@ -29,7 +31,7 @@ module.exports = {
29
31
  },
30
32
  plugins: [
31
33
  new MiniCssExtractPlugin({
32
- filename: "../css/all.[contenthash].css",
34
+ filename: "../css/[name].[contenthash].css",
33
35
  }),
34
36
  new ManifestPlugin({
35
37
  fileName: path.resolve(__dirname, ".bridgetown-webpack", "manifest.json"),
@@ -64,22 +66,30 @@ module.exports = {
64
66
  {
65
67
  loader: "css-loader",
66
68
  options: {
69
+ url: url => !url.startsWith('/'),
67
70
  importLoaders: 1
68
71
  }
69
72
  },
70
73
  "postcss-loader"
71
74
  ],
72
- },
75
+ },
73
76
  <% else %>
74
77
  {
75
78
  test: /\.(s[ac]|c)ss$/,
76
79
  use: [
77
80
  MiniCssExtractPlugin.loader,
78
- "css-loader",
81
+ {
82
+ loader: "css-loader",
83
+ options: {
84
+ url: url => !url.startsWith('/')
85
+ }
86
+ },
79
87
  {
80
88
  loader: "sass-loader",
81
89
  options: {
90
+ implementation: require("sass"),
82
91
  sassOptions: {
92
+ fiber: false,
83
93
  includePaths: [
84
94
  path.resolve(__dirname, "src/_components")
85
95
  ],
@@ -90,13 +100,23 @@ module.exports = {
90
100
  },
91
101
  <% end %>
92
102
  {
93
- test: /\.woff2?$|\.ttf$|\.eot$|\.svg$/,
103
+ test: /\.woff2?$|\.ttf$|\.eot$/,
94
104
  loader: "file-loader",
95
105
  options: {
106
+ name: "[name]-[contenthash].[ext]",
96
107
  outputPath: "../fonts",
97
108
  publicPath: "../fonts",
98
109
  },
99
110
  },
111
+ {
112
+ test: /\.png?$|\.gif$|\.jpg$|\.svg$/,
113
+ loader: "file-loader",
114
+ options: {
115
+ name: "[path][name]-[contenthash].[ext]",
116
+ outputPath: "../",
117
+ publicPath: "../",
118
+ },
119
+ },
100
120
  ],
101
121
  },
102
122
  };