bridgetown-core 1.0.0 → 1.1.0.beta3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +6 -1
- data/bridgetown-core.gemspec +0 -1
- data/lib/bridgetown-core/collection.rb +39 -22
- data/lib/bridgetown-core/commands/apply.rb +3 -3
- data/lib/bridgetown-core/commands/build.rb +6 -6
- data/lib/bridgetown-core/commands/concerns/actions.rb +3 -2
- data/lib/bridgetown-core/commands/concerns/build_options.rb +2 -2
- data/lib/bridgetown-core/commands/configure.rb +1 -1
- data/lib/bridgetown-core/commands/console.rb +5 -5
- data/lib/bridgetown-core/commands/doctor.rb +7 -7
- data/lib/bridgetown-core/commands/esbuild/esbuild.defaults.js.erb +95 -12
- data/lib/bridgetown-core/commands/esbuild/migrate-from-webpack.rb +1 -6
- data/lib/bridgetown-core/commands/new.rb +20 -19
- data/lib/bridgetown-core/commands/plugins.rb +47 -9
- data/lib/bridgetown-core/commands/registrations.rb +2 -3
- data/lib/bridgetown-core/commands/serve.rb +2 -2
- data/lib/bridgetown-core/commands/start.rb +3 -0
- data/lib/bridgetown-core/commands/webpack/update.rb +3 -3
- data/lib/bridgetown-core/commands/webpack/webpack.defaults.js.erb +19 -14
- data/lib/bridgetown-core/component.rb +14 -8
- data/lib/bridgetown-core/concerns/localizable.rb +20 -0
- data/lib/bridgetown-core/concerns/prioritizable.rb +44 -0
- data/lib/bridgetown-core/concerns/publishable.rb +11 -1
- data/lib/bridgetown-core/concerns/site/configurable.rb +2 -10
- data/lib/bridgetown-core/concerns/site/localizable.rb +5 -1
- data/lib/bridgetown-core/concerns/site/ssr.rb +3 -3
- data/lib/bridgetown-core/concerns/site/writable.rb +28 -0
- data/lib/bridgetown-core/concerns/transformable.rb +2 -2
- data/lib/bridgetown-core/configuration.rb +4 -2
- data/lib/bridgetown-core/configurations/bt-postcss/postcss.config.js +5 -3
- data/lib/bridgetown-core/configurations/bt-postcss.rb +1 -1
- data/lib/bridgetown-core/configurations/lit/esbuild-plugins.js +21 -0
- data/lib/bridgetown-core/configurations/lit/happy-days.lit.js +26 -0
- data/lib/bridgetown-core/configurations/lit/lit-components-entry.js +1 -0
- data/lib/bridgetown-core/configurations/lit/lit-ssr.config.js +6 -0
- data/lib/bridgetown-core/configurations/lit.rb +95 -0
- data/lib/bridgetown-core/configurations/open-props/variables.css.erb +11 -0
- data/lib/bridgetown-core/configurations/open-props.rb +21 -0
- data/lib/bridgetown-core/configurations/ruby2js/hello_world.js.rb +9 -0
- data/lib/bridgetown-core/configurations/ruby2js.rb +67 -0
- data/lib/bridgetown-core/configurations/shoelace.rb +50 -0
- data/lib/bridgetown-core/configurations/tailwindcss.rb +16 -2
- data/lib/bridgetown-core/configurations/turbo/turbo_transitions.js +1 -1
- data/lib/bridgetown-core/converters/erb_templates.rb +7 -2
- data/lib/bridgetown-core/converters/markdown/kramdown_parser.rb +1 -1
- data/lib/bridgetown-core/converters/serbea_templates.rb +1 -4
- data/lib/bridgetown-core/drops/generated_page_drop.rb +2 -1
- data/lib/bridgetown-core/drops/resource_drop.rb +2 -1
- data/lib/bridgetown-core/errors.rb +5 -5
- data/lib/bridgetown-core/filters/translation_filters.rb +11 -0
- data/lib/bridgetown-core/filters/url_filters.rb +37 -10
- data/lib/bridgetown-core/filters.rb +3 -0
- data/lib/bridgetown-core/frontmatter_defaults.rb +14 -8
- data/lib/bridgetown-core/generated_page.rb +1 -0
- data/lib/bridgetown-core/kramdown/parser/gfm.rb +36 -0
- data/lib/bridgetown-core/model/base.rb +3 -4
- data/lib/bridgetown-core/plugin.rb +6 -37
- data/lib/bridgetown-core/plugin_manager.rb +3 -2
- data/lib/bridgetown-core/rack/boot.rb +7 -2
- data/lib/bridgetown-core/rack/logger.rb +14 -4
- data/lib/bridgetown-core/rack/roda.rb +106 -9
- data/lib/bridgetown-core/rack/routes.rb +67 -2
- data/lib/bridgetown-core/resource/base.rb +9 -6
- data/lib/bridgetown-core/resource/destination.rb +18 -0
- data/lib/bridgetown-core/resource/permalink_processor.rb +6 -4
- data/lib/bridgetown-core/resource/relations.rb +1 -1
- data/lib/bridgetown-core/ruby_template_view.rb +3 -3
- data/lib/bridgetown-core/static_file.rb +1 -1
- data/lib/bridgetown-core/tags/highlight.rb +1 -1
- data/lib/bridgetown-core/tags/post_url.rb +1 -1
- data/lib/bridgetown-core/url.rb +1 -1
- data/lib/bridgetown-core/utils/aux.rb +2 -1
- data/lib/bridgetown-core/utils/require_gems.rb +3 -6
- data/lib/bridgetown-core/utils.rb +24 -11
- data/lib/bridgetown-core/version.rb +2 -2
- data/lib/bridgetown-core/watcher.rb +21 -8
- data/lib/bridgetown-core.rb +8 -2
- data/lib/site_template/Gemfile.erb +4 -0
- data/lib/site_template/README.md +2 -2
- data/lib/site_template/bridgetown.config.yml +3 -0
- data/lib/site_template/frontend/javascript/index.js.erb +1 -0
- data/lib/site_template/frontend/styles/syntax-highlighting.css +77 -0
- data/lib/site_template/package.json.erb +18 -18
- data/lib/site_template/server/roda_app.rb +3 -6
- data/lib/site_template/src/404.html +2 -1
- data/lib/site_template/src/500.html +10 -0
- metadata +20 -19
- data/lib/bridgetown-core/publisher.rb +0 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: afc674e5aa40d66a2b9e4f24c0aad39108f47e70c8d4756cbfa86623ed2dc7e0
|
4
|
+
data.tar.gz: 4bf462c506c3fcdd09a4750bedae19cb2ee4ff429b57a6266dd56d62645d4926
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5baaa3f133d0e1cbd5e7e972645f107361088d9d11b5bebb38374573d898b67a07b318b4d19e1e5731a696dafe88a3b2ded6ba1c068b869e5bad750200905417
|
7
|
+
data.tar.gz: 4a88c972c98f54ac8b98538fec81f907797cb423f6fa89907cab21a58c29d5961b5e6bf156a3d2846a6d2fd831656696fa9a2afd76d2c2a6f3f5b62663db2c8d
|
data/.rubocop.yml
CHANGED
@@ -11,12 +11,17 @@ AllCops:
|
|
11
11
|
- vendor/**/*
|
12
12
|
- tmp/**/*
|
13
13
|
- test/source/**/*
|
14
|
-
- test/resources/src
|
14
|
+
- test/resources/src/**/*.rb
|
15
|
+
- lib/bridgetown-core/commands/base.rb
|
16
|
+
- lib/bridgetown-core/commands/plugins.rb
|
17
|
+
- lib/bridgetown-core/configurations/ruby2js/**/*
|
18
|
+
- lib/bridgetown-core/rack/roda.rb
|
15
19
|
- lib/site_template/TEMPLATES/**/*
|
16
20
|
- lib/site_template/Rakefile
|
17
21
|
- lib/site_template/config.ru
|
18
22
|
- lib/site_template/config/**/*
|
19
23
|
- lib/site_template/plugins/site_builder.rb
|
24
|
+
- lib/site_template/server/roda_app.rb
|
20
25
|
|
21
26
|
Lint/ConstantDefinitionInBlock:
|
22
27
|
Exclude:
|
data/bridgetown-core.gemspec
CHANGED
@@ -44,7 +44,6 @@ Gem::Specification.new do |s|
|
|
44
44
|
s.add_runtime_dependency("kramdown-parser-gfm", "~> 1.0")
|
45
45
|
s.add_runtime_dependency("liquid", "~> 5.0")
|
46
46
|
s.add_runtime_dependency("listen", "~> 3.0")
|
47
|
-
s.add_runtime_dependency("rack-indifferent", ">= 1.2.0")
|
48
47
|
s.add_runtime_dependency("rake", ">= 13.0")
|
49
48
|
s.add_runtime_dependency("roda", "~> 3.46")
|
50
49
|
s.add_runtime_dependency("rouge", "~> 3.0")
|
@@ -20,11 +20,11 @@ module Bridgetown
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def builtin?
|
23
|
-
label.in?
|
23
|
+
@is_builtin ||= label.in?(%w(posts pages data).freeze)
|
24
24
|
end
|
25
25
|
|
26
26
|
def data?
|
27
|
-
label == "data"
|
27
|
+
@is_data ||= label == "data"
|
28
28
|
end
|
29
29
|
|
30
30
|
# Fetch the Resources in this collection.
|
@@ -215,7 +215,7 @@ module Bridgetown
|
|
215
215
|
# Used by Resource's permalink processor
|
216
216
|
# @return [String]
|
217
217
|
def default_permalink
|
218
|
-
metadata.fetch("permalink", "/:collection/:path/")
|
218
|
+
metadata.fetch("permalink", "/:locale/:collection/:path/")
|
219
219
|
end
|
220
220
|
|
221
221
|
# Extract options for this collection from the site configuration.
|
@@ -270,32 +270,29 @@ module Bridgetown
|
|
270
270
|
|
271
271
|
# Read in resource from repo path
|
272
272
|
# @param full_path [String]
|
273
|
-
def read_resource(full_path, manifest: nil)
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
manifest ? Pathname(manifest.content) : Pathname(site.source)
|
280
|
-
).to_s
|
281
|
-
).gsub("#", "%23")
|
282
|
-
model = Bridgetown::Model::Base.find(id)
|
283
|
-
|
284
|
-
if model.attributes.key?(:locale) && model.locale.to_sym == :multi
|
273
|
+
def read_resource(full_path, manifest: nil)
|
274
|
+
model_relative_path = relative_model_path_for(full_path, manifest: manifest)
|
275
|
+
model = Bridgetown::Model::Base.find(model_id_from_relative_path(model_relative_path,
|
276
|
+
manifest: manifest))
|
277
|
+
|
278
|
+
if model_is_multi_locale?(model, model_relative_path)
|
285
279
|
site.config.available_locales.each do |locale|
|
286
280
|
model.locale = locale
|
287
|
-
|
281
|
+
add_resource_from_model model
|
288
282
|
end
|
289
283
|
return
|
290
284
|
end
|
291
285
|
|
292
|
-
|
286
|
+
add_resource_from_model model
|
293
287
|
end
|
294
288
|
|
295
|
-
|
296
|
-
|
297
|
-
|
289
|
+
# @param model [Bridgetown::Model::Base]
|
290
|
+
def add_resource_from_model(model)
|
291
|
+
model.to_resource.read!.tap do |resource|
|
292
|
+
resources << resource if resource.publishable?
|
293
|
+
end
|
298
294
|
end
|
295
|
+
alias_method :add_model_resource, :add_resource_from_model
|
299
296
|
|
300
297
|
def sort_resources!
|
301
298
|
if metadata["sort_by"].is_a?(String)
|
@@ -346,8 +343,8 @@ module Bridgetown
|
|
346
343
|
end
|
347
344
|
|
348
345
|
def order_with_warning(sort_key, resource, order)
|
349
|
-
Bridgetown.logger.warn "Sort warning:", "'#{sort_key}' not defined in" \
|
350
|
-
"
|
346
|
+
Bridgetown.logger.warn "Sort warning:", "'#{sort_key}' not defined in " \
|
347
|
+
"#{resource.relative_path}"
|
351
348
|
order
|
352
349
|
end
|
353
350
|
|
@@ -365,5 +362,25 @@ module Bridgetown
|
|
365
362
|
self
|
366
363
|
)
|
367
364
|
end
|
365
|
+
|
366
|
+
def relative_model_path_for(full_path, manifest: nil)
|
367
|
+
Pathname(full_path).relative_path_from(
|
368
|
+
manifest ? Pathname(manifest.content) : Pathname(site.source)
|
369
|
+
).to_s
|
370
|
+
end
|
371
|
+
|
372
|
+
def model_id_from_relative_path(model_relative_path, manifest: nil)
|
373
|
+
scheme = manifest ? "plugin" : "repo"
|
374
|
+
id = +"#{scheme}://#{label}.collection/"
|
375
|
+
id += "#{manifest.origin}/" if manifest
|
376
|
+
id += Addressable::URI.escape(model_relative_path).gsub("#", "%23")
|
377
|
+
id
|
378
|
+
end
|
379
|
+
|
380
|
+
def model_is_multi_locale?(model, model_relative_path)
|
381
|
+
(model.attributes.key?(:locale) && model.locale.to_sym == :multi) ||
|
382
|
+
File.extname(File.basename(model_relative_path, ".*")) == ".multi" ||
|
383
|
+
site.frontmatter_defaults.all(model_relative_path, label.to_sym)["locale"].to_s == "multi"
|
384
|
+
end
|
368
385
|
end
|
369
386
|
end
|
@@ -58,9 +58,9 @@ module Bridgetown
|
|
58
58
|
automation_command = args.empty? ? "bridgetown.automation.rb" : args[0]
|
59
59
|
|
60
60
|
if args.empty? && !File.exist?("bridgetown.automation.rb")
|
61
|
-
raise ArgumentError, "You must specify a path or a URL," \
|
62
|
-
"
|
63
|
-
"
|
61
|
+
raise ArgumentError, "You must specify a path or a URL, " \
|
62
|
+
"or add bridgetown.automation.rb to the " \
|
63
|
+
"current folder."
|
64
64
|
end
|
65
65
|
|
66
66
|
Bridgetown.with_unbundled_env do
|
@@ -22,8 +22,8 @@ module Bridgetown
|
|
22
22
|
desc: "Watch for changes and rebuild"
|
23
23
|
|
24
24
|
def self.print_startup_message
|
25
|
-
Bridgetown.logger.info "Starting:", "Bridgetown v#{Bridgetown::VERSION.magenta}" \
|
26
|
-
"
|
25
|
+
Bridgetown.logger.info "Starting:", "Bridgetown v#{Bridgetown::VERSION.magenta} " \
|
26
|
+
"(codename \"#{Bridgetown::CODE_NAME.yellow}\")"
|
27
27
|
end
|
28
28
|
|
29
29
|
# Build your bridgetown site
|
@@ -45,8 +45,8 @@ module Bridgetown
|
|
45
45
|
@site = Bridgetown::Site.new(config_options)
|
46
46
|
|
47
47
|
if config_options.fetch("skip_initial_build", false)
|
48
|
-
Bridgetown.logger.warn "Build Warning:", "Skipping the initial build." \
|
49
|
-
"
|
48
|
+
Bridgetown.logger.warn "Build Warning:", "Skipping the initial build. " \
|
49
|
+
"This may result in an out-of-date site."
|
50
50
|
else
|
51
51
|
build_site(config_options)
|
52
52
|
end
|
@@ -77,8 +77,8 @@ module Bridgetown
|
|
77
77
|
end
|
78
78
|
Bridgetown.logger.info "Generating…"
|
79
79
|
@site.process
|
80
|
-
Bridgetown.logger.info "Done! 🎉", "#{"Completed".bold.green} in less than" \
|
81
|
-
"
|
80
|
+
Bridgetown.logger.info "Done! 🎉", "#{"Completed".bold.green} in less than " \
|
81
|
+
"#{(Time.now - t).ceil(2)} seconds."
|
82
82
|
|
83
83
|
return unless config_options[:using_puma]
|
84
84
|
|
@@ -54,7 +54,8 @@ module Bridgetown
|
|
54
54
|
|
55
55
|
def add_bridgetown_plugin(gemname, version: nil)
|
56
56
|
version = " -v \"#{version}\"" if version
|
57
|
-
run "bundle add #{gemname}#{version} -g bridgetown_plugins"
|
57
|
+
run "bundle add #{gemname}#{version} -g bridgetown_plugins",
|
58
|
+
env: { "BUNDLE_GEMFILE" => File.join(destination_root, "Gemfile") }
|
58
59
|
rescue SystemExit
|
59
60
|
say_status :run, "Gem not added due to bundler error", :red
|
60
61
|
end
|
@@ -79,7 +80,7 @@ module Bridgetown
|
|
79
80
|
|
80
81
|
def determine_remote_filename(arg)
|
81
82
|
if arg.end_with?(".rb")
|
82
|
-
arg.split("/").
|
83
|
+
arg.split("/").then do |segments|
|
83
84
|
arg.sub!(%r!/#{segments.last}$!, "")
|
84
85
|
segments.last
|
85
86
|
end
|
@@ -21,8 +21,8 @@ module Bridgetown
|
|
21
21
|
desc: "Destination directory (defaults to output)"
|
22
22
|
klass.class_option :root_dir,
|
23
23
|
aliases: "-r",
|
24
|
-
desc: "The top-level root folder" \
|
25
|
-
"
|
24
|
+
desc: "The top-level root folder " \
|
25
|
+
"where config files are located"
|
26
26
|
klass.class_option :plugins_dir,
|
27
27
|
aliases: "-p",
|
28
28
|
type: :array,
|
@@ -64,9 +64,9 @@ module Bridgetown
|
|
64
64
|
require "irb/ext/save-history"
|
65
65
|
require "amazing_print" unless options[:"bypass-ap"]
|
66
66
|
|
67
|
-
Bridgetown.logger.info "Starting:", "Bridgetown v#{Bridgetown::VERSION.magenta}" \
|
68
|
-
"
|
69
|
-
"
|
67
|
+
Bridgetown.logger.info "Starting:", "Bridgetown v#{Bridgetown::VERSION.magenta} " \
|
68
|
+
"(codename \"#{Bridgetown::CODE_NAME.yellow}\") " \
|
69
|
+
"console…"
|
70
70
|
Bridgetown.logger.info "Environment:", Bridgetown.environment.cyan
|
71
71
|
site = Bridgetown::Site.new(configuration_with_overrides(options))
|
72
72
|
|
@@ -80,8 +80,8 @@ module Bridgetown
|
|
80
80
|
IRB.conf[:MAIN_CONTEXT] = irb.context
|
81
81
|
Bridgetown.logger.info "Console:", "Your site is now available as #{"site".cyan}"
|
82
82
|
Bridgetown.logger.info "",
|
83
|
-
"You can also access #{"collections".cyan} or perform a" \
|
84
|
-
"
|
83
|
+
"You can also access #{"collections".cyan} or perform a " \
|
84
|
+
"#{"reload!".cyan}"
|
85
85
|
|
86
86
|
trap("SIGINT") do
|
87
87
|
irb.signal_handle
|
@@ -62,8 +62,8 @@ module Bridgetown
|
|
62
62
|
next unless paths.size > 1
|
63
63
|
|
64
64
|
conflicting_urls = true
|
65
|
-
Bridgetown.logger.warn "Conflict:", "The URL '#{url}' is the destination" \
|
66
|
-
"
|
65
|
+
Bridgetown.logger.warn "Conflict:", "The URL '#{url}' is the destination " \
|
66
|
+
"for the following pages: #{paths.join(", ")}"
|
67
67
|
end
|
68
68
|
conflicting_urls
|
69
69
|
end
|
@@ -77,8 +77,8 @@ module Bridgetown
|
|
77
77
|
urls_only_differ_by_case = true
|
78
78
|
Bridgetown.logger.warn(
|
79
79
|
"Warning:",
|
80
|
-
"The following URLs only differ by case. On a case-insensitive file system one of
|
81
|
-
" URLs will be overwritten by the other: #{real_urls.join(", ")}"
|
80
|
+
"The following URLs only differ by case. On a case-insensitive file system one of " \
|
81
|
+
"the URLs will be overwritten by the other: #{real_urls.join(", ")}"
|
82
82
|
)
|
83
83
|
end
|
84
84
|
urls_only_differ_by_case
|
@@ -121,7 +121,7 @@ module Bridgetown
|
|
121
121
|
def url_exists?(url)
|
122
122
|
return true unless url.nil? || url.empty?
|
123
123
|
|
124
|
-
Bridgetown.logger.warn "Warning:", "You didn't set an URL in the config file, "\
|
124
|
+
Bridgetown.logger.warn "Warning:", "You didn't set an URL in the config file, " \
|
125
125
|
"you may encounter problems with some plugins."
|
126
126
|
false
|
127
127
|
end
|
@@ -132,7 +132,7 @@ module Bridgetown
|
|
132
132
|
# Addressable::URI#parse only raises a TypeError
|
133
133
|
# https://git.io/vFfbx
|
134
134
|
rescue TypeError
|
135
|
-
Bridgetown.logger.warn "Warning:", "The site URL does not seem to be valid, "\
|
135
|
+
Bridgetown.logger.warn "Warning:", "The site URL does not seem to be valid, " \
|
136
136
|
"check the value of `url` in your config file."
|
137
137
|
false
|
138
138
|
end
|
@@ -140,7 +140,7 @@ module Bridgetown
|
|
140
140
|
def url_absolute(url)
|
141
141
|
return true if url.is_a?(String) && Addressable::URI.parse(url).absolute?
|
142
142
|
|
143
|
-
Bridgetown.logger.warn "Warning:", "Your site URL does not seem to be absolute, "\
|
143
|
+
Bridgetown.logger.warn "Warning:", "Your site URL does not seem to be absolute, " \
|
144
144
|
"check the value of `url` in your config file."
|
145
145
|
false
|
146
146
|
end
|
@@ -11,11 +11,33 @@
|
|
11
11
|
const path = require("path")
|
12
12
|
const fsLib = require("fs")
|
13
13
|
const fs = fsLib.promises
|
14
|
+
const { pathToFileURL, fileURLToPath } = require("url")
|
14
15
|
const glob = require("glob")
|
15
16
|
const postcss = require("postcss")
|
16
17
|
const postCssImport = require("postcss-import")
|
17
18
|
const readCache = require("read-cache")
|
18
19
|
|
20
|
+
// Detect if an NPM package is available
|
21
|
+
const moduleAvailable = name => {
|
22
|
+
try {
|
23
|
+
require.resolve(name)
|
24
|
+
return true
|
25
|
+
} catch (e) { }
|
26
|
+
return false
|
27
|
+
}
|
28
|
+
|
29
|
+
// Generate a Source Map URL (used by the Sass plugin)
|
30
|
+
const generateSourceMappingURL = sourceMap => {
|
31
|
+
const data = Buffer.from(JSON.stringify(sourceMap), "utf-8").toString("base64")
|
32
|
+
return `/*# sourceMappingURL=data:application/json;charset=utf-8;base64,${data} */`
|
33
|
+
}
|
34
|
+
|
35
|
+
// Import Sass if available
|
36
|
+
let sass
|
37
|
+
if (moduleAvailable("sass")) {
|
38
|
+
sass = require("sass")
|
39
|
+
}
|
40
|
+
|
19
41
|
// Glob plugin derived from:
|
20
42
|
// https://github.com/thomaschaaf/esbuild-plugin-import-glob
|
21
43
|
// https://github.com/xiaohui-zhangxh/jsbundling-rails/commit/b15025dcc20f664b2b0eb238915991afdbc7cb58
|
@@ -61,24 +83,23 @@ const importGlobPlugin = () => ({
|
|
61
83
|
},
|
62
84
|
})
|
63
85
|
|
64
|
-
|
86
|
+
// Plugin for PostCSS
|
87
|
+
const postCssPlugin = (options, configuration) => ({
|
65
88
|
name: "postcss",
|
66
89
|
async setup(build) {
|
67
90
|
// Process .css files with PostCSS
|
68
|
-
build.onLoad({ filter: /\.
|
91
|
+
build.onLoad({ filter: (configuration.filter || /\.css$/) }, async (args) => {
|
69
92
|
const additionalFilePaths = []
|
70
93
|
const css = await fs.readFile(args.path, "utf8")
|
71
94
|
|
72
95
|
// Configure import plugin so PostCSS can properly resolve `@import`ed CSS files
|
73
96
|
const importPlugin = postCssImport({
|
74
|
-
filter: itemPath =>
|
75
|
-
// We'll want to track any imports later when in watch mode
|
76
|
-
additionalFilePaths.push(path.resolve(path.dirname(args.path), itemPath))
|
77
|
-
return true
|
78
|
-
},
|
97
|
+
filter: itemPath => !itemPath.startsWith("/"), // ensure it doesn't try to import source-relative paths
|
79
98
|
load: async filename => {
|
80
99
|
let contents = await readCache(filename, "utf-8")
|
81
100
|
const filedir = path.dirname(filename)
|
101
|
+
// We'll want to track any imports later when in watch mode:
|
102
|
+
additionalFilePaths.push(filename)
|
82
103
|
|
83
104
|
// We need to transform `url(...)` in imported CSS so the filepaths are properly
|
84
105
|
// relative to the entrypoint. Seems icky to have to hack this! C'est la vie...
|
@@ -106,6 +127,65 @@ const postCssPlugin = (options) => ({
|
|
106
127
|
},
|
107
128
|
})
|
108
129
|
|
130
|
+
// Plugin for Sass
|
131
|
+
const sassPlugin = (options) => ({
|
132
|
+
name: "sass",
|
133
|
+
async setup(build) {
|
134
|
+
// Process .scss and .sass files with Sass
|
135
|
+
build.onLoad({ filter: /\.(sass|scss)$/ }, async (args) => {
|
136
|
+
if (!sass) {
|
137
|
+
console.error("error: Sass is not installed. Try running `yarn add sass` and then building again.")
|
138
|
+
return
|
139
|
+
}
|
140
|
+
|
141
|
+
const modulesFolder = pathToFileURL("node_modules/")
|
142
|
+
|
143
|
+
const localOptions = {
|
144
|
+
importers: [{
|
145
|
+
// An importer that redirects relative URLs starting with "~" to
|
146
|
+
// `node_modules`.
|
147
|
+
findFileUrl(url) {
|
148
|
+
if (!url.startsWith('~')) return null
|
149
|
+
return new URL(url.substring(1), modulesFolder)
|
150
|
+
}
|
151
|
+
}],
|
152
|
+
sourceMap: true,
|
153
|
+
...options
|
154
|
+
}
|
155
|
+
const result = sass.compile(args.path, localOptions)
|
156
|
+
|
157
|
+
const watchPaths = result.loadedUrls
|
158
|
+
.filter((x) => x.protocol === "file:" && !x.pathname.startsWith(modulesFolder.pathname))
|
159
|
+
.map((x) => x.pathname)
|
160
|
+
|
161
|
+
let cssOutput = result.css.toString()
|
162
|
+
|
163
|
+
if (result.sourceMap) {
|
164
|
+
const basedir = process.cwd()
|
165
|
+
const sourceMap = result.sourceMap
|
166
|
+
|
167
|
+
const promises = sourceMap.sources.map(async source => {
|
168
|
+
const sourceFile = await fs.readFile(fileURLToPath(source), "utf8")
|
169
|
+
return sourceFile
|
170
|
+
})
|
171
|
+
sourceMap.sourcesContent = await Promise.all(promises)
|
172
|
+
|
173
|
+
sourceMap.sources = sourceMap.sources.map(source => {
|
174
|
+
return path.relative(basedir, fileURLToPath(source))
|
175
|
+
})
|
176
|
+
|
177
|
+
cssOutput += '\n' + generateSourceMappingURL(sourceMap)
|
178
|
+
}
|
179
|
+
|
180
|
+
return {
|
181
|
+
contents: cssOutput,
|
182
|
+
loader: "css",
|
183
|
+
watchFiles: [args.path, ...watchPaths],
|
184
|
+
}
|
185
|
+
})
|
186
|
+
},
|
187
|
+
})
|
188
|
+
|
109
189
|
// Set up defaults and generate frontend bundling manifest file
|
110
190
|
const bridgetownPreset = (outputFolder) => ({
|
111
191
|
name: "bridgetownPreset",
|
@@ -151,9 +231,9 @@ const bridgetownPreset = (outputFolder) => ({
|
|
151
231
|
// We have an entrypoint!
|
152
232
|
manifest[stripPrefix(value.entryPoint)] = outputPath
|
153
233
|
entrypoints.push([outputPath, fileSize(key)])
|
154
|
-
} else if (key.match(/index(\.js)?\.[^-.]*\.css/) && inputs.find(item => item.
|
234
|
+
} else if (key.match(/index(\.js)?\.[^-.]*\.css/) && inputs.find(item => item.match(/\.(s?css|sass)$/))) {
|
155
235
|
// Special treatment for index.css
|
156
|
-
manifest[stripPrefix(inputs.find(item => item.
|
236
|
+
manifest[stripPrefix(inputs.find(item => item.match(/\.(s?css|sass)$/)))] = outputPath
|
157
237
|
entrypoints.push([outputPath, fileSize(key)])
|
158
238
|
} else if (inputs.length > 0) {
|
159
239
|
// Naive implementation, we'll just grab the first input and hope it's accurate
|
@@ -182,9 +262,12 @@ const postCssConfig = postcssrc.sync()
|
|
182
262
|
module.exports = (outputFolder, esbuildOptions) => {
|
183
263
|
esbuildOptions.plugins = esbuildOptions.plugins || []
|
184
264
|
// Add the PostCSS & glob plugins to the top of the plugin stack
|
185
|
-
esbuildOptions.plugins.unshift(postCssPlugin(postCssConfig))
|
265
|
+
esbuildOptions.plugins.unshift(postCssPlugin(postCssConfig, esbuildOptions.postCssPluginConfig || {}))
|
266
|
+
if (esbuildOptions.postCssPluginConfig) delete esbuildOptions.postCssPluginConfig
|
186
267
|
esbuildOptions.plugins.unshift(importGlobPlugin())
|
187
|
-
// Add the
|
268
|
+
// Add the Sass plugin
|
269
|
+
esbuildOptions.plugins.push(sassPlugin(esbuildOptions.sassOptions || {}))
|
270
|
+
// Add the Bridgetown preset
|
188
271
|
esbuildOptions.plugins.push(bridgetownPreset(outputFolder))
|
189
272
|
|
190
273
|
// esbuild, take it away!
|
@@ -200,7 +283,7 @@ module.exports = (outputFolder, esbuildOptions) => {
|
|
200
283
|
".ttf": "file",
|
201
284
|
".eot": "file",
|
202
285
|
},
|
203
|
-
resolveExtensions: [".tsx",".ts",".jsx",".js",".css",".json",".js.rb"],
|
286
|
+
resolveExtensions: [".tsx", ".ts", ".jsx", ".js", ".css", ".scss", ".sass", ".json", ".js.rb"],
|
204
287
|
nodePaths: ["frontend/javascript", "frontend/styles"],
|
205
288
|
watch: process.argv.includes("--watch"),
|
206
289
|
minify: process.argv.includes("--minify"),
|
@@ -2,11 +2,6 @@
|
|
2
2
|
|
3
3
|
# rubocop:disable Layout/LineLength
|
4
4
|
|
5
|
-
if package_json["devDependencies"].key?("sass")
|
6
|
-
say "Unable to migrate, project uses Sass. Please migrate to PostCSS first before migrating to esbuild."
|
7
|
-
return
|
8
|
-
end
|
9
|
-
|
10
5
|
remove_file "webpack.config.js"
|
11
6
|
remove_file "config/webpack.defaults.js"
|
12
7
|
|
@@ -16,7 +11,7 @@ default_postcss_config = File.expand_path("../../../site_template/postcss.config
|
|
16
11
|
template default_postcss_config, "postcss.config.js"
|
17
12
|
|
18
13
|
unless Bridgetown.environment.test?
|
19
|
-
required_packages = %w(esbuild glob postcss postcss-flexbugs-fixes postcss-preset-env postcss-import postcss-load-config)
|
14
|
+
required_packages = %w(esbuild glob postcss postcss-flexbugs-fixes postcss-preset-env postcss-import postcss-load-config@3.1.4)
|
20
15
|
redundant_packages = %w(esbuild-loader webpack webpack-cli webpack-manifest-plugin webpack-merge css-loader file-loader mini-css-extract-plugin postcss-loader)
|
21
16
|
|
22
17
|
say "Installing required packages"
|
@@ -43,7 +43,7 @@ module Bridgetown
|
|
43
43
|
desc: "Skip 'yarn install'"
|
44
44
|
class_option :"use-sass",
|
45
45
|
type: :boolean,
|
46
|
-
desc: "
|
46
|
+
desc: "Set up a Sass configuration for your stylesheet"
|
47
47
|
|
48
48
|
DOCSURL = "https://bridgetownrb.com/docs"
|
49
49
|
|
@@ -62,19 +62,14 @@ module Bridgetown
|
|
62
62
|
def new_site
|
63
63
|
raise ArgumentError, "You must specify a path." if args.empty?
|
64
64
|
|
65
|
-
if frontend_bundling_option != "webpack" && options["use-sass"]
|
66
|
-
raise ArgumentError,
|
67
|
-
"To install Sass, you must choose Webpack (-e webpack) as your frontend bundler"
|
68
|
-
end
|
69
|
-
|
70
65
|
new_site_path = File.expand_path(args.join(" "), Dir.pwd)
|
71
66
|
@site_name = new_site_path.split(File::SEPARATOR).last
|
72
67
|
|
73
68
|
if preserve_source_location?(new_site_path, options)
|
74
69
|
say_status :conflict, "#{new_site_path} exists and is not empty.", :red
|
75
70
|
Bridgetown.logger.abort_with(
|
76
|
-
"Ensure #{new_site_path} is empty or else try again with `--force` to proceed and" \
|
77
|
-
"
|
71
|
+
"Ensure #{new_site_path} is empty or else try again with `--force` to proceed and " \
|
72
|
+
"overwrite any files."
|
78
73
|
)
|
79
74
|
end
|
80
75
|
|
@@ -98,7 +93,11 @@ module Bridgetown
|
|
98
93
|
end
|
99
94
|
|
100
95
|
def postcss_option
|
101
|
-
!
|
96
|
+
!options["use-sass"]
|
97
|
+
end
|
98
|
+
|
99
|
+
def disable_postcss?
|
100
|
+
options["use-sass"] && options["frontend-bundling"] == "webpack"
|
102
101
|
end
|
103
102
|
|
104
103
|
def create_site(new_site_path)
|
@@ -116,6 +115,7 @@ module Bridgetown
|
|
116
115
|
template("frontend/javascript/index.js.erb", "frontend/javascript/index.js")
|
117
116
|
template("src/index.md.erb", "src/index.md")
|
118
117
|
template("src/posts.md.erb", "src/posts.md")
|
118
|
+
copy_file("frontend/styles/syntax-highlighting.css")
|
119
119
|
|
120
120
|
case options["templates"]
|
121
121
|
when "erb"
|
@@ -126,11 +126,11 @@ module Bridgetown
|
|
126
126
|
setup_liquid_templates
|
127
127
|
end
|
128
128
|
|
129
|
+
postcss_option ? configure_postcss : configure_sass
|
130
|
+
|
129
131
|
if frontend_bundling_option == "esbuild"
|
130
|
-
configure_postcss
|
131
132
|
invoke(Esbuild, ["setup"], {})
|
132
133
|
else
|
133
|
-
postcss_option ? configure_postcss : configure_sass
|
134
134
|
invoke(Webpack, ["setup"], {})
|
135
135
|
end
|
136
136
|
end
|
@@ -165,6 +165,7 @@ module Bridgetown
|
|
165
165
|
end
|
166
166
|
|
167
167
|
def configure_sass
|
168
|
+
template("postcss.config.js.erb", "postcss.config.js") unless disable_postcss?
|
168
169
|
copy_file("frontend/styles/index.css", "frontend/styles/index.scss")
|
169
170
|
end
|
170
171
|
|
@@ -193,18 +194,18 @@ module Bridgetown
|
|
193
194
|
logger = Bridgetown.logger
|
194
195
|
bt_start = "bin/bridgetown start"
|
195
196
|
logger.info ""
|
196
|
-
logger.info "Success!".green, "🎉 Your new Bridgetown site was" \
|
197
|
-
"
|
197
|
+
logger.info "Success!".green, "🎉 Your new Bridgetown site was " \
|
198
|
+
"generated in #{cli_path.cyan}."
|
198
199
|
if options["skip-yarn"]
|
199
200
|
logger.info "You can now #{"cd".cyan} #{cli_path.cyan} to get started."
|
200
|
-
logger.info "You'll probably also want to #{"yarn install".cyan}" \
|
201
|
-
"
|
201
|
+
logger.info "You'll probably also want to #{"yarn install".cyan} " \
|
202
|
+
"to load in your frontend assets."
|
202
203
|
else
|
203
|
-
logger.info "You can now #{"cd".cyan} #{cli_path.cyan} and run #{bt_start.cyan}" \
|
204
|
-
"
|
204
|
+
logger.info "You can now #{"cd".cyan} #{cli_path.cyan} and run #{bt_start.cyan} " \
|
205
|
+
"to get started."
|
205
206
|
end
|
206
|
-
logger.info "Then check out our online documentation for" \
|
207
|
-
"
|
207
|
+
logger.info "Then check out our online documentation for " \
|
208
|
+
"next steps: #{DOCSURL.cyan}"
|
208
209
|
|
209
210
|
if @skipped_bundle
|
210
211
|
logger.info "Bundle install skipped.".yellow
|