bridgetown-core 0.21.0.beta3 → 0.21.2

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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/lib/bridgetown-core.rb +10 -1
  3. data/lib/bridgetown-core/collection.rb +11 -6
  4. data/lib/bridgetown-core/commands/concerns/build_options.rb +2 -2
  5. data/lib/bridgetown-core/commands/new.rb +4 -4
  6. data/lib/bridgetown-core/commands/serve.rb +1 -1
  7. data/lib/bridgetown-core/commands/webpack.rb +82 -0
  8. data/lib/bridgetown-core/commands/webpack/enable-postcss.rb +12 -0
  9. data/lib/bridgetown-core/commands/webpack/setup.rb +4 -0
  10. data/lib/bridgetown-core/commands/webpack/update.rb +24 -0
  11. data/lib/bridgetown-core/commands/webpack/webpack.config.js +31 -0
  12. data/lib/bridgetown-core/commands/webpack/webpack.defaults.js.erb +130 -0
  13. data/lib/bridgetown-core/component.rb +36 -31
  14. data/lib/bridgetown-core/concerns/layout_placeable.rb +1 -1
  15. data/lib/bridgetown-core/concerns/site/configurable.rb +16 -1
  16. data/lib/bridgetown-core/configuration.rb +11 -4
  17. data/lib/bridgetown-core/configurations/bt-postcss.rb +5 -3
  18. data/lib/bridgetown-core/configurations/tailwindcss.rb +13 -6
  19. data/lib/bridgetown-core/configurations/tailwindcss/postcss.config.js +2 -2
  20. data/lib/bridgetown-core/drops/resource_drop.rb +2 -1
  21. data/lib/bridgetown-core/drops/site_drop.rb +2 -0
  22. data/lib/bridgetown-core/filters/url_filters.rb +4 -8
  23. data/lib/bridgetown-core/generators/prototype_generator.rb +25 -4
  24. data/lib/bridgetown-core/layout.rb +27 -10
  25. data/lib/bridgetown-core/readers/layout_reader.rb +1 -1
  26. data/lib/bridgetown-core/resource/base.rb +26 -0
  27. data/lib/bridgetown-core/resource/destination.rb +3 -1
  28. data/lib/bridgetown-core/resource/permalink_processor.rb +7 -3
  29. data/lib/bridgetown-core/site.rb +1 -1
  30. data/lib/bridgetown-core/static_file.rb +3 -2
  31. data/lib/bridgetown-core/utils.rb +1 -1
  32. data/lib/bridgetown-core/version.rb +1 -1
  33. data/lib/bridgetown-core/watcher.rb +1 -0
  34. data/lib/site_template/bridgetown.config.yml +5 -1
  35. data/lib/site_template/config/.keep +0 -0
  36. data/lib/site_template/package.json.erb +8 -11
  37. data/lib/site_template/src/_data/site_metadata.yml +1 -1
  38. metadata +9 -3
  39. data/lib/site_template/webpack.config.js.erb +0 -122
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fc153d4826e8e0678bea76a9e2c251040123418ab9cfe0b1243b7f38cb8f1ec5
4
- data.tar.gz: '08d6c10878993b10963dc1a89058c8b0a9dbd57a5ed2b399963a68ea537ea5f8'
3
+ metadata.gz: d33d466ab78dad035cfbd9d255dcd53a42c307cefebb5a12ae215393ec096ee3
4
+ data.tar.gz: 7c46ed1c37f82ffd63b3ee6753029fc74a17d67c625e638ac5b088fb3d2b929a
5
5
  SHA512:
6
- metadata.gz: 7151ae352509556c2b6b7e524e56186a3c782746dc1f2090756a37e9325c9153e48a03daf720e64fd0450e472a43b96c3e9b90ec53896d409881ab33b8aabea0
7
- data.tar.gz: 42289c4f1da1116e37fa50bdb49345264e2a56a719f1e76691eb294721a1b4c834909ab7dc22691d238bec4df509c6680c479fa7b6fec8831f69d79bee8fef6b
6
+ metadata.gz: 6a61dfef1bd907e8ff64fccfb43b57f081e45c92c0824b342d13f4137f02bd30d21772c8c9e8e1083d396738ef9df22eba103bbeeb2f7858192bac662cd2b18a
7
+ data.tar.gz: 19c1ff73c5f47403c6d741935cf0aa6bb52cc8f78b41114521c36f2594d7f79ee49f6919ca07d8cd3ea188edd1eba0a5605e94c102c66ba95b1549755ddbc082
@@ -257,7 +257,16 @@ end
257
257
 
258
258
  module Bridgetown
259
259
  module Model; end
260
- module Resource; end
260
+ module Resource
261
+ def self.register_extension(mod)
262
+ if mod.const_defined?(:LiquidResource)
263
+ Bridgetown::Drops::ResourceDrop.include mod.const_get(:LiquidResource)
264
+ end
265
+ if mod.const_defined?(:RubyResource)
266
+ Bridgetown::Resource::Base.include mod.const_get(:RubyResource)
267
+ end
268
+ end
269
+ end
261
270
  end
262
271
 
263
272
  # This method is available in Ruby 3, monkey patching for older versions
@@ -242,7 +242,7 @@ module Bridgetown
242
242
  site.config.collections[label] || HashWithDotAccess::Hash.new
243
243
  end
244
244
 
245
- def merge_data_resources
245
+ def merge_data_resources # rubocop:todo Metrics/AbcSize, Metrics/MethodLength
246
246
  data_contents = {}
247
247
 
248
248
  sanitize_filename = ->(name) do
@@ -256,11 +256,16 @@ module Bridgetown
256
256
  segments.each_with_index do |segment, index|
257
257
  sanitized_segment = sanitize_filename.(File.basename(segment, ".*"))
258
258
  hsh = nested.empty? ? data_contents : data_contents.dig(*nested)
259
- hsh[sanitized_segment] = if index == segments.length - 1
260
- data_resource.data.rows || data_resource.data
261
- else
262
- {}
263
- end
259
+ if !hsh.is_a?(Hash)
260
+ Bridgetown.logger.error(
261
+ "Error:",
262
+ "#{nested.join("/")} is not a Hash structure, #{segment} cannot be read"
263
+ )
264
+ elsif index == segments.length - 1
265
+ hsh[sanitized_segment] = data_resource.data.rows || data_resource.data
266
+ elsif !hsh.key?(sanitized_segment)
267
+ hsh[sanitized_segment] = {}
268
+ end
264
269
  nested << sanitized_segment
265
270
  end
266
271
  end
@@ -36,9 +36,9 @@ module Bridgetown
36
36
  klass.class_option :limit_posts,
37
37
  type: :numeric,
38
38
  desc: "Limits the number of posts to parse and publish"
39
- klass.class_option :baseurl,
39
+ klass.class_option :base_path,
40
40
  aliases: "-b",
41
- desc: "Serve the website from the given base URL"
41
+ desc: "Serve the website from the given base path"
42
42
  klass.class_option :force_polling,
43
43
  type: :boolean,
44
44
  desc: "Force watch to use polling"
@@ -86,10 +86,10 @@ module Bridgetown
86
86
  )
87
87
  template("Gemfile.erb", "Gemfile")
88
88
  template("package.json.erb", "package.json")
89
- template("webpack.config.js.erb", "webpack.config.js")
90
89
  template("frontend/javascript/index.js.erb", "frontend/javascript/index.js")
91
90
 
92
91
  options["use-postcss"] ? configure_postcss : configure_sass
92
+ invoke(Webpack, ["setup"], {})
93
93
  end
94
94
 
95
95
  def configure_sass
@@ -140,7 +140,7 @@ module Bridgetown
140
140
  # rubocop:enable Metrics/PerceivedComplexity
141
141
 
142
142
  def bundle_install(path)
143
- unless Bridgetown.environment == "test"
143
+ unless Bridgetown.environment.test?
144
144
  require "bundler"
145
145
  Bridgetown.with_unbundled_env do
146
146
  inside(path) do
@@ -156,7 +156,7 @@ module Bridgetown
156
156
  end
157
157
 
158
158
  def git_init(path)
159
- unless Bridgetown.environment == "test"
159
+ unless Bridgetown.environment.test?
160
160
  inside(path) do
161
161
  initialize_new_repo
162
162
  end
@@ -166,7 +166,7 @@ module Bridgetown
166
166
  end
167
167
 
168
168
  def yarn_install(path)
169
- unless Bridgetown.environment == "test"
169
+ unless Bridgetown.environment.test?
170
170
  inside(path) do
171
171
  run "yarn install", abort_on_failure: true
172
172
  end
@@ -119,7 +119,7 @@ module Bridgetown
119
119
 
120
120
  def start_up_webrick(opts, destination)
121
121
  @server = WEBrick::HTTPServer.new(webrick_opts(opts)).tap { |o| o.unmount("") }
122
- @server.mount(opts["baseurl"].to_s, Servlet, destination, file_handler_opts)
122
+ @server.mount(opts["base_path"].to_s, Servlet, destination, file_handler_opts)
123
123
 
124
124
  Bridgetown.logger.info "Server address:", server_address(@server, opts)
125
125
  launch_browser @server, opts if opts["open_url"]
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ module Commands
5
+ class Webpack < Thor::Group
6
+ include Thor::Actions
7
+ extend Summarizable
8
+
9
+ Registrations.register do
10
+ register(Webpack, "webpack", "webpack ACTION", Webpack.summary)
11
+ end
12
+
13
+ def self.banner
14
+ "bridgetown webpack ACTION"
15
+ end
16
+ summary "Perform actions on the bridgetown webpack configuration"
17
+
18
+ def self.exit_on_failure?
19
+ true
20
+ end
21
+
22
+ def webpack
23
+ @logger = Bridgetown.logger
24
+ return show_actions if args.empty?
25
+
26
+ action = args.first
27
+ if supported_actions.include?(action)
28
+ perform action
29
+ else
30
+ @logger.error "Error:".red, "🚨 Please enter a valid action."
31
+ say "\n"
32
+ show_actions
33
+ end
34
+ end
35
+
36
+ def self.source_root
37
+ File.expand_path("./webpack", __dir__)
38
+ end
39
+
40
+ def self.destination_root
41
+ config.root_dir
42
+ end
43
+
44
+ protected
45
+
46
+ def config
47
+ @config ||= Bridgetown.configuration({ root_dir: Dir.pwd })
48
+ end
49
+
50
+ def package_json
51
+ @package_json ||= begin
52
+ package_json_file = File.read(Bridgetown.sanitized_path(config.root_dir, "package.json"))
53
+ JSON.parse(package_json_file)
54
+ end
55
+ end
56
+
57
+ def perform(action)
58
+ automation = find_in_source_paths("#{action}.rb")
59
+ inside(New.created_site_dir || Dir.pwd) do
60
+ apply automation, verbose: false
61
+ end
62
+ end
63
+
64
+ def show_actions
65
+ say "Available actions:\n".bold
66
+
67
+ longest_action = supported_actions.keys.max_by(&:size).size
68
+ supported_actions.each do |action, description|
69
+ say action.ljust(longest_action).to_s.bold.blue + "\t" + "# #{description}"
70
+ end
71
+ end
72
+
73
+ def supported_actions
74
+ {
75
+ setup: "Sets up a webpack integration with Bridgetown in your project",
76
+ update: "Updates the Bridgetown webpack defaults to the latest available version",
77
+ "enable-postcss": "Configures PostCSS in your project",
78
+ }.with_indifferent_access
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ default_postcss_config = File.expand_path("../../../site_template/postcss.config.js.erb", __dir__)
4
+
5
+ template default_postcss_config, "postcss.config.js"
6
+ template "webpack.defaults.js.erb", "config/webpack.defaults.js", force: true
7
+
8
+ unless Bridgetown.environment.test?
9
+ packages = %w(postcss@8.3.0 postcss-loader@4.3.0 postcss-flexbugs-fixes postcss-preset-env)
10
+ run "yarn add -D #{packages.join(" ")}"
11
+ run "yarn remove sass sass-loader"
12
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ template "webpack.defaults.js.erb", "config/webpack.defaults.js"
4
+ copy_file "webpack.config.js", force: true
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Layout/LineLength
4
+
5
+ required_packages = %w(esbuild esbuild-loader webpack@5.39.1 webpack-cli@4.7.2 webpack-manifest-plugin@3.1.1)
6
+ redundant_packages = %w(@babel/core @babel/plugin-proposal-class-properties @babel/plugin-proposal-decorators @babel/plugin-transform-runtime @babel/preset-env babel-loader)
7
+
8
+ template "webpack.defaults.js.erb", "config/webpack.defaults.js", force: true
9
+ say "🎉 Webpack configuration updated successfully!"
10
+
11
+ return if Bridgetown.environment.test?
12
+
13
+ say "Installing required packages"
14
+ run "yarn add -D #{required_packages.join(" ")}"
15
+
16
+ packages_to_remove = package_json["devDependencies"].slice(*redundant_packages).keys
17
+ unless packages_to_remove.empty?
18
+ confirm = ask "\nThe following packages will be removed: \n\n#{packages_to_remove.join("\n")}\n\nWould you like to continue? [Yn]"
19
+ return unless confirm.casecmp?("Y")
20
+
21
+ run "yarn remove #{packages_to_remove.join(" ")}"
22
+ end
23
+
24
+ # rubocop:enable Layout/LineLength
@@ -0,0 +1,31 @@
1
+ const { merge } = require('webpack-merge')
2
+
3
+ var config = require("./config/webpack.defaults.js")
4
+
5
+ // Add any overrides to the default webpack config here:
6
+ //
7
+ // Eg:
8
+ //
9
+ // ```
10
+ // const path = require("path")
11
+ // config.resolve.modules.push(path.resolve(__dirname, 'frontend', 'components'))
12
+ // config.resolve.alias.frontendComponents = path.resolve(__dirname, 'frontend', 'components')
13
+ // ```
14
+ //
15
+ // You can also merge in a custom config using the included `webpack-merge` package.
16
+ // Complete docs available at: https://github.com/survivejs/webpack-merge
17
+ //
18
+ // Eg:
19
+ //
20
+ // ```
21
+ // const customConfig = { ..... }
22
+ // config = merge(config, customConfig)
23
+ // ```
24
+
25
+
26
+
27
+
28
+
29
+ ////////////////////////////////////////////////////////
30
+
31
+ module.exports = config
@@ -0,0 +1,130 @@
1
+ // This file is created and managed by Bridgetown.
2
+ // Instead of editing this file, add your overrides to `webpack.config.js`
3
+ //
4
+ // To update this file to the latest version provided by Bridgetown,
5
+ // run `bridgetown webpack update`. Any changes to this file will be overwritten
6
+ // when an update is applied hence we strongly recommend adding overrides to
7
+ // `webpack.config.js` instead of editing this file.
8
+ //
9
+ // Shipped with Bridgetown v<%= Bridgetown::VERSION %>
10
+
11
+ const path = require("path");
12
+ const rootDir = path.resolve(__dirname, "..")
13
+ const MiniCssExtractPlugin = require("mini-css-extract-plugin");
14
+ const { WebpackManifestPlugin } = require("webpack-manifest-plugin");
15
+
16
+ // Input and output
17
+
18
+ const entry = { main: path.resolve(rootDir, "frontend", "javascript", "index.js") }
19
+ const output = {
20
+ path: path.resolve(rootDir, "output", "_bridgetown", "static", "js"),
21
+ filename: "[name].[contenthash].js",
22
+ publicPath: "",
23
+ }
24
+
25
+ // Rules and Loaders
26
+
27
+ const jsRule = {
28
+ test: /\.(js|jsx)/,
29
+ use: {
30
+ loader: "esbuild-loader",
31
+ options: {
32
+ target: 'es2016'
33
+ },
34
+ },
35
+ }
36
+
37
+ const cssRules = {
38
+ test: /\.(s[ac]|c)ss$/,
39
+ use: [
40
+ MiniCssExtractPlugin.loader,
41
+ {
42
+ loader: "css-loader",
43
+ options: {
44
+ url: url => !url.startsWith('/'),
45
+ importLoaders: 1
46
+ }
47
+ }
48
+ ],
49
+ mode: '<%= self.config.uses_postcss? ? "postcss" : "sass" %>',
50
+
51
+ postcss: () => {
52
+ cssRules.use.push("postcss-loader")
53
+ return { test: cssRules.test, use: cssRules.use }
54
+ },
55
+
56
+ sass: () => {
57
+ cssRules.use.push({
58
+ loader: "sass-loader",
59
+ options: {
60
+ implementation: require("sass"),
61
+ sassOptions: {
62
+ fiber: false,
63
+ includePaths: [
64
+ path.resolve(rootDir, "src/_components")
65
+ ],
66
+ },
67
+ },
68
+ })
69
+ return { test: cssRules.test, use: cssRules.use }
70
+ }
71
+ }
72
+
73
+ const fontsRule = {
74
+ test: /\.woff2?$|\.ttf$|\.eot$/,
75
+ loader: "file-loader",
76
+ options: {
77
+ name: "[name]-[contenthash].[ext]",
78
+ outputPath: "../fonts",
79
+ publicPath: "../fonts",
80
+ },
81
+ }
82
+
83
+ const imagesRule = {
84
+ test: /\.png?$|\.gif$|\.jpg$|\.svg$/,
85
+ loader: "file-loader",
86
+ options: {
87
+ name: "[path][name]-[contenthash].[ext]",
88
+ outputPath: "../",
89
+ publicPath: "../",
90
+ },
91
+ }
92
+
93
+ // Default configuration object
94
+
95
+ module.exports = {
96
+ entry: entry,
97
+ devtool: "source-map",
98
+ // Set some or all of these to true if you want more verbose logging:
99
+ stats: {
100
+ modules: false,
101
+ builtAt: false,
102
+ timings: false,
103
+ children: false,
104
+ },
105
+ output: output,
106
+ resolve: {
107
+ extensions: [".js", ".jsx"],
108
+ modules: [
109
+ path.resolve(rootDir, 'frontend', 'javascript'),
110
+ path.resolve(rootDir, 'frontend', 'styles'),
111
+ path.resolve(rootDir, 'node_modules')
112
+ ],
113
+ alias: {
114
+ bridgetownComponents: path.resolve(rootDir, "src", "_components")
115
+ }
116
+ },
117
+ plugins: [
118
+ new MiniCssExtractPlugin({
119
+ filename: "../css/[name].[contenthash].css",
120
+ }),
121
+ new WebpackManifestPlugin({
122
+ fileName: path.resolve(rootDir, ".bridgetown-webpack", "manifest.json"),
123
+ }),
124
+ ],
125
+ module: {
126
+ rules: [
127
+ jsRule, cssRules[cssRules.mode](), fontsRule, imagesRule
128
+ ]
129
+ }
130
+ }
@@ -30,24 +30,24 @@ module Bridgetown
30
30
  #
31
31
  # @param ext [String] erb, slim, etc.
32
32
  def renderer_for_ext(ext, &block)
33
- case ext
34
- when "erb"
35
- include ERBCapture
36
- Tilt::ErubiTemplate.new(component_template_path,
37
- outvar: "@_erbout",
38
- bufval: "Bridgetown::OutputBuffer.new",
39
- engine_class: Bridgetown::ERBEngine,
40
- &block)
41
- when "serb" # requires serbea
42
- include Serbea::Helpers
43
- Tilt::SerbeaTemplate.new(component_template_path, &block)
44
- when "slim" # requires bridgetown-slim
45
- Slim::Template.new(component_template_path, &block)
46
- when "haml" # requires bridgetown-haml
47
- Tilt::HamlTemplate.new(component_template_path, &block)
48
- else
49
- raise NameError
50
- end
33
+ @_tmpl ||= case ext
34
+ when "erb"
35
+ include ERBCapture
36
+ Tilt::ErubiTemplate.new(component_template_path,
37
+ outvar: "@_erbout",
38
+ bufval: "Bridgetown::OutputBuffer.new",
39
+ engine_class: Bridgetown::ERBEngine,
40
+ &block)
41
+ when "serb" # requires serbea
42
+ include Serbea::Helpers
43
+ Tilt::SerbeaTemplate.new(component_template_path, &block)
44
+ when "slim" # requires bridgetown-slim
45
+ Slim::Template.new(component_template_path, &block)
46
+ when "haml" # requires bridgetown-haml
47
+ Tilt::HamlTemplate.new(component_template_path, &block)
48
+ else
49
+ raise NameError
50
+ end
51
51
  rescue NameError, LoadError
52
52
  raise "No component rendering engine could be found for .#{ext} templates"
53
53
  end
@@ -56,26 +56,32 @@ module Bridgetown
56
56
  #
57
57
  # @return [String]
58
58
  def component_template_path
59
- stripped_path = File.join(
60
- File.dirname(source_location),
61
- File.basename(source_location, ".*")
62
- )
63
- supported_template_extensions.each do |ext|
64
- test_path = "#{stripped_path}.#{ext}"
65
- return test_path if File.exist?(test_path)
66
-
67
- test_path = "#{stripped_path}.html.#{ext}"
68
- return test_path if File.exist?(test_path)
59
+ @_tmpl_path ||= begin
60
+ stripped_path = File.join(
61
+ File.dirname(source_location),
62
+ File.basename(source_location, ".*")
63
+ )
64
+ supported_template_extensions.each do |ext|
65
+ test_path = "#{stripped_path}.#{ext}"
66
+ break test_path if File.exist?(test_path)
67
+
68
+ test_path = "#{stripped_path}.html.#{ext}"
69
+ break test_path if File.exist?(test_path)
70
+ end
71
+ end
72
+
73
+ unless @_tmpl_path.is_a?(String)
74
+ raise "#{name}: no matching template could be found in #{File.dirname(source_location)}"
69
75
  end
70
76
 
71
- raise "No matching templates could be found in #{File.dirname(source_location)}"
77
+ @_tmpl_path
72
78
  end
73
79
 
74
80
  # Read the template file.
75
81
  #
76
82
  # @return [String]
77
83
  def component_template_content
78
- File.read(component_template_path)
84
+ @_tmpl_content ||= File.read(component_template_path)
79
85
  end
80
86
 
81
87
  # A list of extensions supported by the renderer
@@ -154,7 +160,6 @@ module Bridgetown
154
160
  end
155
161
 
156
162
  def _renderer
157
- # TODO: figure out a way to compile templates for increased performance
158
163
  @_renderer ||= begin
159
164
  ext = File.extname(self.class.component_template_path).delete_prefix(".")
160
165
  self.class.renderer_for_ext(ext) { self.class.component_template_content }
@@ -11,7 +11,7 @@ module Bridgetown
11
11
  end
12
12
 
13
13
  def no_layout?
14
- data["layout"] == "none" || data["layout"] == false
14
+ data.layout.nil? || data.layout == "none" || data.layout == false
15
15
  end
16
16
  end
17
17
  end
@@ -24,7 +24,6 @@ class Bridgetown::Site
24
24
  configure_include_paths
25
25
  configure_file_read_opts
26
26
 
27
- self.baseurl = config.baseurl
28
27
  self.permalink_style = (config["permalink"] || "pretty").to_sym
29
28
 
30
29
  @config
@@ -34,6 +33,22 @@ class Bridgetown::Site
34
33
  config[:content_engine] == "resource"
35
34
  end
36
35
 
36
+ # Returns a base path from which the site is served (aka `/cool-site`) or
37
+ # `/` if served from root.
38
+ #
39
+ # @param strip_slash_only [Boolean] set to true if you wish "/" to be returned as ""
40
+ # @return [String]
41
+ def base_path(strip_slash_only: false)
42
+ (config[:base_path] || config[:baseurl]).yield_self do |path|
43
+ strip_slash_only ? path.to_s.sub(%r{^/$}, "") : path
44
+ end
45
+ end
46
+
47
+ def baseurl
48
+ Bridgetown::Deprecator.deprecation_message "Site#baseurl is now Site#base_path"
49
+ base_path(strip_slash_only: true).presence
50
+ end
51
+
37
52
  def defaults_reader
38
53
  @defaults_reader ||= Bridgetown::DefaultsReader.new(self)
39
54
  end
@@ -54,7 +54,7 @@ module Bridgetown
54
54
  "detach" => false, # default to not detaching the server
55
55
  "port" => "4000",
56
56
  "host" => "127.0.0.1",
57
- "baseurl" => nil, # this mounts at /, i.e. no subdirectory
57
+ "base_path" => "/",
58
58
  "show_dir_listing" => false,
59
59
 
60
60
  # Output Configuration
@@ -118,7 +118,7 @@ module Bridgetown
118
118
  # override - the command-line options hash
119
119
  #
120
120
  # Returns the path to the Bridgetown root directory
121
- def root_dir(override)
121
+ def root_dir(override = "")
122
122
  get_config_value_with_override("root_dir", override)
123
123
  end
124
124
 
@@ -127,7 +127,7 @@ module Bridgetown
127
127
  # override - the command-line options hash
128
128
  #
129
129
  # Returns the path to the Bridgetown source directory
130
- def source(override)
130
+ def source(override = "")
131
131
  get_config_value_with_override("source", override)
132
132
  end
133
133
 
@@ -226,7 +226,7 @@ module Bridgetown
226
226
  raise ArgumentError, "Configuration file: (INVALID) #{file}".yellow
227
227
  end
228
228
 
229
- Bridgetown.logger.info "Configuration file:", file
229
+ Bridgetown.logger.debug "Configuration file:", file
230
230
  next_config
231
231
  rescue SystemCallError
232
232
  if @default_config_file ||= nil
@@ -340,5 +340,12 @@ module Bridgetown
340
340
 
341
341
  self
342
342
  end
343
+
344
+ # Whether or not PostCSS is being used to process stylesheets.
345
+ #
346
+ # @return [Boolean] true if `postcss.config.js` exists, false if not
347
+ def uses_postcss?
348
+ File.exist?(Bridgetown.sanitized_path(root_dir, "postcss.config.js"))
349
+ end
343
350
  end
344
351
  end
@@ -8,17 +8,19 @@ unless File.exist?("postcss.config.js")
8
8
  error_message = "#{"postcss.config.js".bold} not found. Please configure postcss in your project."
9
9
 
10
10
  @logger.error "\nError:".red, "🚨 #{error_message}"
11
- @logger.info "\nFor new projects, you can use #{"bridgetown new my_project --use-postcss".bold.blue}\n"
11
+ @logger.info "\nRun #{"bridgetown webpack enable-postcss".bold.blue} to set it up.\n"
12
12
 
13
13
  return
14
14
  end
15
15
 
16
+ confirm = ask "This configuration will ovewrite your existing #{"postcss.config.js".bold.white}. Would you like to continue? [Yn]"
17
+ return unless confirm.casecmp?("Y")
18
+
16
19
  plugins = %w(postcss-easy-import postcss-mixins postcss-color-function cssnano)
17
20
 
18
21
  say "Adding the following PostCSS plugins: #{plugins.join(' | ')}", :green
19
22
  run "yarn add -D #{plugins.join(' ')}"
20
23
 
21
- remove_file "postcss.config.js"
22
- copy_file "#{TEMPLATE_PATH}/postcss.config.js", "postcss.config.js"
24
+ copy_file "#{TEMPLATE_PATH}/postcss.config.js", "postcss.config.js", force: true
23
25
 
24
26
  # rubocop:enable all
@@ -8,20 +8,27 @@ unless File.exist?("postcss.config.js")
8
8
  error_message = "#{"postcss.config.js".bold} not found. Please configure postcss in your project."
9
9
 
10
10
  @logger.error "\nError:".red, "🚨 #{error_message}"
11
- @logger.info "\nFor new projects, you can use #{"bridgetown new my_project --use-postcss".bold.blue}\n"
11
+ @logger.info "\nRun #{"bridgetown webpack enable-postcss".bold.blue} to set it up.\n"
12
12
 
13
13
  return
14
14
  end
15
15
 
16
+ confirm = ask "This configuration will ovewrite your existing #{"postcss.config.js".bold.white}. Would you like to continue? [Yn]"
17
+ return unless confirm.casecmp?("Y")
18
+
16
19
  run "yarn add -D tailwindcss"
17
20
  run "npx tailwindcss init"
18
21
 
19
- remove_file "postcss.config.js"
20
- copy_file "#{TEMPLATE_PATH}/postcss.config.js", "postcss.config.js"
21
-
22
- prepend_to_file "frontend/styles/index.css",
23
- File.read("#{TEMPLATE_PATH}/css_imports.css")
22
+ copy_file "#{TEMPLATE_PATH}/postcss.config.js", "postcss.config.js", force: true
24
23
 
25
24
  run "bundle exec bridgetown configure purgecss"
26
25
 
26
+ if File.exist?("frontend/styles/index.css")
27
+ prepend_to_file "frontend/styles/index.css",
28
+ File.read("#{TEMPLATE_PATH}/css_imports.css")
29
+ else
30
+ say "\nPlease add the following lines to your CSS index file:"
31
+ say File.read("#{TEMPLATE_PATH}/css_imports.css")
32
+ end
33
+
27
34
  # rubocop:enable all
@@ -6,7 +6,7 @@ module.exports = {
6
6
  autoprefixer: {
7
7
  flexbox: 'no-2009'
8
8
  },
9
- stage: 3
9
+ stage: 2
10
10
  }
11
11
  }
12
- }
12
+ }
@@ -17,6 +17,7 @@ module Bridgetown
17
17
  :data,
18
18
  :output,
19
19
  :content,
20
+ :summary,
20
21
  :to_s,
21
22
  :absolute_url,
22
23
  :relative_path,
@@ -48,7 +49,7 @@ module Bridgetown
48
49
  end
49
50
 
50
51
  def next
51
- @next ||= @obj.previous_resource.to_liquid
52
+ @next ||= @obj.next_resource.to_liquid
52
53
  end
53
54
 
54
55
  # Generate a Hash for use in generating JSON.
@@ -8,6 +8,8 @@ module Bridgetown
8
8
  mutable false
9
9
 
10
10
  def_delegators :@obj,
11
+ :baseurl, # deprecated
12
+ :base_path,
11
13
  :data,
12
14
  :locale,
13
15
  :time,
@@ -5,7 +5,7 @@ module Bridgetown
5
5
  module URLFilters
6
6
  extend self
7
7
 
8
- # Produces an absolute URL based on site.url and site.baseurl.
8
+ # Produces an absolute URL based on site.url and site.base_path.
9
9
  #
10
10
  # input - the URL to make absolute.
11
11
  #
@@ -15,7 +15,7 @@ module Bridgetown
15
15
  cache[input] ||= compute_absolute_url(input)
16
16
  end
17
17
 
18
- # Produces a URL relative to the domain root based on site.baseurl
18
+ # Produces a URL relative to the domain root based on site.base_path
19
19
  # unless it is already an absolute url with an authority (host).
20
20
  #
21
21
  # input - the URL to make relative to the domain root
@@ -70,17 +70,13 @@ module Bridgetown
70
70
  input = input.url if input.respond_to?(:url)
71
71
  return input if Addressable::URI.parse(input.to_s).absolute?
72
72
 
73
- parts = [sanitized_baseurl, input]
73
+ site = @context.registers[:site]
74
+ parts = [site.base_path.chomp("/"), input]
74
75
  Addressable::URI.parse(
75
76
  parts.compact.map { |part| ensure_leading_slash(part.to_s) }.join
76
77
  ).normalize.to_s
77
78
  end
78
79
 
79
- def sanitized_baseurl
80
- site = @context.registers[:site]
81
- site.config["baseurl"].to_s.chomp("/")
82
- end
83
-
84
80
  def ensure_leading_slash(input)
85
81
  return input if input.nil? || input.empty? || input.start_with?("/")
86
82
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Handles Legacy Pages
3
+ # Handles Generated Pages
4
4
  Bridgetown::Hooks.register :pages, :post_init, reloadable: false do |page|
5
5
  if page.class != Bridgetown::PrototypePage && page.data["prototype"].is_a?(Hash)
6
6
  Bridgetown::PrototypeGenerator.add_matching_template(page)
@@ -14,6 +14,11 @@ Bridgetown::Hooks.register :resources, :post_read, reloadable: false do |resourc
14
14
  end
15
15
  end
16
16
 
17
+ # Ensure sites clear out templates before rebuild
18
+ Bridgetown::Hooks.register :site, :after_reset, reloadable: false do |_site|
19
+ Bridgetown::PrototypeGenerator.matching_templates.clear
20
+ end
21
+
17
22
  module Bridgetown
18
23
  class PrototypeGenerator < Generator
19
24
  priority :low
@@ -21,9 +26,9 @@ module Bridgetown
21
26
  # @return [Bridgetown::Site]
22
27
  attr_reader :site
23
28
 
24
- # @return [Array<Bridgetown::Page, Bridgetown::Resource::Base>]
29
+ # @return [Set<Bridgetown::Page, Bridgetown::Resource::Base>]
25
30
  def self.matching_templates
26
- @matching_templates ||= []
31
+ @matching_templates ||= Set.new
27
32
  end
28
33
 
29
34
  def self.add_matching_template(template)
@@ -41,6 +46,8 @@ module Bridgetown
41
46
  end
42
47
 
43
48
  if prototype_pages.length.positive?
49
+ ensure_pagination_enabled
50
+
44
51
  page_list.reject! do |page|
45
52
  prototype_pages.include? page
46
53
  end
@@ -56,6 +63,15 @@ module Bridgetown
56
63
  end
57
64
  end
58
65
 
66
+ def ensure_pagination_enabled
67
+ unless @site.config.dig(:pagination, :enabled)
68
+ Bridgetown.logger.warn(
69
+ "Pagination:",
70
+ "Must be enabled for prototype pages to contain matches"
71
+ )
72
+ end
73
+ end
74
+
59
75
  # Check incoming prototype configuration and normalize options.
60
76
  #
61
77
  # @param prototype_page [Bridgetown::Page, Bridgetown::Resource::Base]
@@ -70,7 +86,12 @@ module Bridgetown
70
86
  @configured_collection = prototype_page.data["prototype"]["collection"]
71
87
  end
72
88
 
73
- return nil unless site.collections[@configured_collection]
89
+ unless site.collections[@configured_collection]
90
+ Bridgetown.logger.warn(
91
+ "No collection specified for prototype page #{prototype_page.relative_path}"
92
+ )
93
+ return nil
94
+ end
74
95
 
75
96
  # Categories and Tags are unique in that singular and plural front matter
76
97
  # can be present for each
@@ -39,12 +39,22 @@ module Bridgetown
39
39
  # Gets/Sets the document output (for layout-compatible converters)
40
40
  attr_accessor :current_document_output
41
41
 
42
+ # Determines the label a layout should use based on its filename
43
+ #
44
+ # @param file [String]
45
+ # @return [String]
46
+ def self.label_for_file(file)
47
+ # TODO: refactor this so multi-extension layout filenames don't leak
48
+ # middle extensions into layout label
49
+ file.split(".")[0..-2].join(".")
50
+ end
51
+
42
52
  # Initialize a new Layout.
43
53
  #
44
- # site - The Site.
45
- # base - The String path to the source.
46
- # name - The String filename of the layout file.
47
- # from_plugin - true if the layout comes from a Gem-based plugin folder.
54
+ # @param site [Bridgetown::Site]
55
+ # @param base [String] The path to the source.
56
+ # @param name [String] The filename of the layout file.
57
+ # @param from_plugin [Boolean] if the layout comes from a Gem-based plugin folder.
48
58
  def initialize(site, base, name, from_plugin: false)
49
59
  @site = site
50
60
  @base = base
@@ -83,17 +93,24 @@ module Bridgetown
83
93
  end
84
94
  end
85
95
 
86
- # The inspect string for this document.
87
- # Includes the relative path and the collection label.
96
+ # The label of the layout (should match what would used in front matter
97
+ # references).
88
98
  #
89
- # Returns the inspect string for this document.
99
+ # @return [String]
100
+ def label
101
+ @label ||= self.class.label_for_file(name)
102
+ end
103
+
104
+ # The inspect string for this layout. Includes the relative path.
105
+ #
106
+ # @return [String]
90
107
  def inspect
91
- "#<#{self.class} #{@path}>"
108
+ "#<#{self.class} #{relative_path}>"
92
109
  end
93
110
 
94
- # Provide this Layout's data to a Hash suitable for use by Liquid.
111
+ # Provide this Layout's data for use by Liquid.
95
112
  #
96
- # Returns the Hash representation of this Layout.
113
+ # @return [HashWithDotAccess::Hash]
97
114
  def to_liquid
98
115
  data
99
116
  end
@@ -44,7 +44,7 @@ module Bridgetown
44
44
  end
45
45
 
46
46
  def layout_name(file)
47
- file.split(".")[0..-2].join(".")
47
+ Layout.label_for_file(file)
48
48
  end
49
49
 
50
50
  def within(directory)
@@ -42,6 +42,22 @@ module Bridgetown
42
42
  model.collection
43
43
  end
44
44
 
45
+ # Layout associated with this resource
46
+ # This will output a warning if the layout can't be found.
47
+ #
48
+ # @return [Bridgetown::Layout]
49
+ def layout
50
+ return @layout if @layout
51
+ return if no_layout?
52
+
53
+ @layout = site.layouts[data.layout].tap do |layout|
54
+ unless layout
55
+ Bridgetown.logger.warn "Resource:", "Layout '#{data.layout}' " \
56
+ "requested via #{relative_path} does not exist."
57
+ end
58
+ end
59
+ end
60
+
45
61
  # The relative path of source file or file-like origin
46
62
  #
47
63
  # @return [Pathname]
@@ -165,6 +181,16 @@ module Bridgetown
165
181
  data["date"] ||= site.time
166
182
  end
167
183
 
184
+ # Ask the configured summary extension to output a summary of the content,
185
+ # otherwise return the first line.
186
+ #
187
+ # @return [String]
188
+ def summary
189
+ return summary_extension_output if respond_to?(:summary_extension_output)
190
+
191
+ content.to_s.strip.lines.first.to_s.strip
192
+ end
193
+
168
194
  # @return [Hash<String, Hash<String => Bridgetown::Resource::TaxonomyType,
169
195
  # Array<Bridgetown::Resource::TaxonomyTerm>>>]
170
196
  def taxonomies
@@ -32,7 +32,9 @@ module Bridgetown
32
32
 
33
33
  def output_path
34
34
  path = URL.unescape_path(relative_url)
35
- path = path.delete_prefix(resource.site.baseurl) if resource.site.baseurl.present?
35
+ if resource.site.base_path.present?
36
+ path = path.delete_prefix resource.site.base_path(strip_slash_only: true)
37
+ end
36
38
  path = resource.site.in_dest_dir(path)
37
39
  path = File.join(path, "index.html") if relative_url.end_with? "/"
38
40
  path
@@ -40,7 +40,7 @@ module Bridgetown
40
40
  # No relative URLs should ever end in /index.html
41
41
  new_url.sub!(%r{/index$}, "") if final_ext == ".html"
42
42
 
43
- add_baseurl finalize_permalink(new_url, permalink)
43
+ add_base_path finalize_permalink(new_url, permalink)
44
44
  end
45
45
 
46
46
  def process_segment(segment)
@@ -96,8 +96,12 @@ module Bridgetown
96
96
  end
97
97
  end
98
98
 
99
- def add_baseurl(permalink)
100
- resource.site.baseurl.present? ? "#{resource.site.baseurl}#{permalink}" : permalink
99
+ def add_base_path(permalink)
100
+ if resource.site.base_path.present?
101
+ return "#{resource.site.base_path(strip_slash_only: true)}#{permalink}"
102
+ end
103
+
104
+ permalink
101
105
  end
102
106
 
103
107
  ### Default Placeholders Processors
@@ -30,7 +30,7 @@ module Bridgetown
30
30
  # is default
31
31
  alias_method :generated_pages, :pages
32
32
 
33
- attr_accessor :permalink_style, :time, :baseurl, :data,
33
+ attr_accessor :permalink_style, :time, :data,
34
34
  :file_read_opts, :plugin_manager, :converters,
35
35
  :generators, :reader
36
36
 
@@ -58,8 +58,9 @@ module Bridgetown
58
58
  def destination(dest)
59
59
  dest = site.in_dest_dir(dest)
60
60
  dest_url = url
61
- dest_url = dest_url.delete_prefix(site.baseurl) if site.uses_resource? &&
62
- site.baseurl.present? && collection
61
+ if site.uses_resource? && site.base_path.present? && collection
62
+ dest_url = dest_url.delete_prefix site.base_path(strip_slash_only: true)
63
+ end
63
64
  site.in_dest_dir(dest, Bridgetown::URL.unescape_path(dest_url))
64
65
  end
65
66
 
@@ -380,7 +380,7 @@ module Bridgetown
380
380
 
381
381
  def static_frontend_path(site, additional_parts = [])
382
382
  path_parts = [
383
- site.config["baseurl"].to_s.gsub(%r(^/|/$), ""),
383
+ site.base_path.gsub(%r(^/|/$), ""),
384
384
  "_bridgetown/static",
385
385
  *additional_parts,
386
386
  ]
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bridgetown
4
- VERSION = "0.21.0.beta3"
4
+ VERSION = "0.21.2"
5
5
  CODE_NAME = "Broughton Beach"
6
6
  end
@@ -127,6 +127,7 @@ module Bridgetown
127
127
 
128
128
  def process(site, time, options)
129
129
  begin
130
+ I18n.reload! # make sure any locale files get read again
130
131
  Bridgetown::Hooks.trigger :site, :pre_reload, site
131
132
  Bridgetown::Hooks.clear_reloadable_hooks
132
133
  site.plugin_manager.reload_plugin_files
@@ -15,9 +15,13 @@
15
15
  # https://learnxinyminutes.com/docs/yaml/
16
16
  #
17
17
 
18
- baseurl: "" # OPTIONAL: the subpath of your site, e.g. /blog
19
18
  url: "" # the base hostname & protocol for your site, e.g. https://example.com
20
19
 
21
20
  permalink: pretty
22
21
 
22
+ # Other options you might want to investigate:
23
+ #
24
+ # base_path: "/" # the subpath of your site, e.g. /blog
23
25
  # timezone: America/Los_Angeles
26
+ # pagination:
27
+ # enabled: true
File without changes
@@ -13,28 +13,25 @@
13
13
  "start": "node start.js"
14
14
  },
15
15
  "devDependencies": {
16
- "@babel/core": "^7.9.0",
17
- "@babel/plugin-proposal-class-properties": "^7.8.3",
18
- "@babel/plugin-proposal-decorators": "^7.10.1",
19
- "@babel/plugin-transform-runtime": "^7.9.0",
20
- "@babel/preset-env": "^7.9.0",
21
- "babel-loader": "^8.1.0",
22
16
  "browser-sync": "^2.26.7",
23
17
  "concurrently": "^5.2.0",
24
18
  "css-loader": "^4.3.0",
19
+ "esbuild": "^0.12.7",
20
+ "esbuild-loader": "^2.13.1",
25
21
  "file-loader": "^6.2.0",
26
22
  "mini-css-extract-plugin": "^1.3.1",
27
23
  <% if options["use-postcss"] %>
28
- "postcss": "^8.1.9",
24
+ "postcss": "^8.3.0",
29
25
  "postcss-flexbugs-fixes": "^4.1.0",
30
- "postcss-loader": "^4.1.0",
26
+ "postcss-loader": "^4.3.0",
31
27
  "postcss-preset-env": "^6.7.0",
32
28
  <% else %>
33
29
  "sass": "^1.32.8",
34
30
  "sass-loader": "^8.0.2",
35
31
  <% end %>
36
- "webpack": "^4.44.2",
37
- "webpack-cli": "^3.3.11",
38
- "webpack-manifest-plugin": "^2.1.0"
32
+ "webpack": "^5.39.1",
33
+ "webpack-cli": "^4.7.2",
34
+ "webpack-manifest-plugin": "^3.1.1",
35
+ "webpack-merge": "^5.8.0"
39
36
  }
40
37
  }
@@ -7,5 +7,5 @@
7
7
  title: Your awesome title
8
8
  tagline: This site is totally awesome
9
9
  email: your-email@example.com
10
- description: >- # this means to ignore newlines until "baseurl:"
10
+ description: >-
11
11
  Write an awesome description for your new site here. It will appear in your document head meta (for Google search results) and in your feed.xml site description.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bridgetown-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.21.0.beta3
4
+ version: 0.21.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bridgetown Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-15 00:00:00.000000000 Z
11
+ date: 2021-07-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -323,6 +323,12 @@ files:
323
323
  - lib/bridgetown-core/commands/registrations.rb
324
324
  - lib/bridgetown-core/commands/serve.rb
325
325
  - lib/bridgetown-core/commands/serve/servlet.rb
326
+ - lib/bridgetown-core/commands/webpack.rb
327
+ - lib/bridgetown-core/commands/webpack/enable-postcss.rb
328
+ - lib/bridgetown-core/commands/webpack/setup.rb
329
+ - lib/bridgetown-core/commands/webpack/update.rb
330
+ - lib/bridgetown-core/commands/webpack/webpack.config.js
331
+ - lib/bridgetown-core/commands/webpack/webpack.defaults.js.erb
326
332
  - lib/bridgetown-core/component.rb
327
333
  - lib/bridgetown-core/concerns/data_accessible.rb
328
334
  - lib/bridgetown-core/concerns/front_matter_importer.rb
@@ -450,6 +456,7 @@ files:
450
456
  - lib/site_template/Gemfile.erb
451
457
  - lib/site_template/README.md
452
458
  - lib/site_template/bridgetown.config.yml
459
+ - lib/site_template/config/.keep
453
460
  - lib/site_template/frontend/javascript/index.js.erb
454
461
  - lib/site_template/frontend/styles/index.css
455
462
  - lib/site_template/frontend/styles/index.scss
@@ -474,7 +481,6 @@ files:
474
481
  - lib/site_template/src/posts.md
475
482
  - lib/site_template/start.js
476
483
  - lib/site_template/sync.js
477
- - lib/site_template/webpack.config.js.erb
478
484
  homepage: https://www.bridgetownrb.com
479
485
  licenses:
480
486
  - MIT
@@ -1,122 +0,0 @@
1
- const path = require("path");
2
- const MiniCssExtractPlugin = require("mini-css-extract-plugin");
3
- const ManifestPlugin = require("webpack-manifest-plugin");
4
-
5
- module.exports = {
6
- entry: {
7
- main: "./frontend/javascript/index.js"
8
- },
9
- devtool: "source-map",
10
- // Set some or all of these to true if you want more verbose logging:
11
- stats: {
12
- modules: false,
13
- builtAt: false,
14
- timings: false,
15
- children: false,
16
- },
17
- output: {
18
- path: path.resolve(__dirname, "output", "_bridgetown", "static", "js"),
19
- filename: "[name].[contenthash].js",
20
- },
21
- resolve: {
22
- extensions: [".js", ".jsx"],
23
- modules: [
24
- path.resolve(__dirname, 'frontend', 'javascript'),
25
- path.resolve(__dirname, 'frontend', 'styles'),
26
- path.resolve('./node_modules')
27
- ],
28
- alias: {
29
- bridgetownComponents: path.resolve(__dirname, "src", "_components")
30
- }
31
- },
32
- plugins: [
33
- new MiniCssExtractPlugin({
34
- filename: "../css/[name].[contenthash].css",
35
- }),
36
- new ManifestPlugin({
37
- fileName: path.resolve(__dirname, ".bridgetown-webpack", "manifest.json"),
38
- }),
39
- ],
40
- module: {
41
- rules: [
42
- {
43
- test: /\.(js|jsx)/,
44
- use: {
45
- loader: "babel-loader",
46
- options: {
47
- presets: ["@babel/preset-env"],
48
- plugins: [
49
- ["@babel/plugin-proposal-decorators", { "legacy": true }],
50
- ["@babel/plugin-proposal-class-properties", { "loose" : true }],
51
- [
52
- "@babel/plugin-transform-runtime",
53
- {
54
- helpers: false,
55
- },
56
- ],
57
- ],
58
- },
59
- },
60
- },
61
- <% if options["use-postcss"] %>
62
- {
63
- test: /\.(s[ac]|c)ss$/,
64
- use: [
65
- MiniCssExtractPlugin.loader,
66
- {
67
- loader: "css-loader",
68
- options: {
69
- url: url => !url.startsWith('/'),
70
- importLoaders: 1
71
- }
72
- },
73
- "postcss-loader"
74
- ],
75
- },
76
- <% else %>
77
- {
78
- test: /\.(s[ac]|c)ss$/,
79
- use: [
80
- MiniCssExtractPlugin.loader,
81
- {
82
- loader: "css-loader",
83
- options: {
84
- url: url => !url.startsWith('/')
85
- }
86
- },
87
- {
88
- loader: "sass-loader",
89
- options: {
90
- implementation: require("sass"),
91
- sassOptions: {
92
- fiber: false,
93
- includePaths: [
94
- path.resolve(__dirname, "src/_components")
95
- ],
96
- },
97
- },
98
- },
99
- ],
100
- },
101
- <% end %>
102
- {
103
- test: /\.woff2?$|\.ttf$|\.eot$/,
104
- loader: "file-loader",
105
- options: {
106
- name: "[name]-[contenthash].[ext]",
107
- outputPath: "../fonts",
108
- publicPath: "../fonts",
109
- },
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
- },
120
- ],
121
- },
122
- };