bridgetown-core 1.0.0.alpha11 → 1.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -0
  3. data/bin/bridgetown +6 -1
  4. data/bridgetown-core.gemspec +3 -3
  5. data/lib/bridgetown-core/commands/base.rb +18 -18
  6. data/lib/bridgetown-core/commands/build.rb +1 -1
  7. data/lib/bridgetown-core/commands/clean.rb +2 -2
  8. data/lib/bridgetown-core/commands/esbuild/esbuild.config.js +27 -0
  9. data/lib/bridgetown-core/commands/esbuild/esbuild.defaults.js.erb +216 -0
  10. data/lib/bridgetown-core/commands/esbuild/migrate-from-webpack.rb +47 -0
  11. data/lib/bridgetown-core/commands/esbuild/setup.rb +4 -0
  12. data/lib/bridgetown-core/commands/esbuild/update.rb +4 -0
  13. data/lib/bridgetown-core/commands/esbuild.rb +83 -0
  14. data/lib/bridgetown-core/commands/new.rb +80 -10
  15. data/lib/bridgetown-core/commands/webpack/enable-postcss.rb +1 -1
  16. data/lib/bridgetown-core/commands/webpack/update.rb +3 -3
  17. data/lib/bridgetown-core/commands/webpack/webpack.defaults.js.erb +1 -1
  18. data/lib/bridgetown-core/commands/webpack.rb +3 -3
  19. data/lib/bridgetown-core/component.rb +9 -3
  20. data/lib/bridgetown-core/concerns/site/configurable.rb +4 -0
  21. data/lib/bridgetown-core/concerns/site/content.rb +4 -4
  22. data/lib/bridgetown-core/configurations/purgecss.rb +2 -1
  23. data/lib/bridgetown-core/configurations/stimulus.rb +40 -12
  24. data/lib/bridgetown-core/configurations/tailwindcss/css_imports.css +5 -0
  25. data/lib/bridgetown-core/configurations/tailwindcss.rb +31 -2
  26. data/lib/bridgetown-core/configurations/turbo/turbo_transitions.js +48 -0
  27. data/lib/bridgetown-core/configurations/turbo.rb +15 -5
  28. data/lib/bridgetown-core/converters/erb_templates.rb +1 -1
  29. data/lib/bridgetown-core/converters/ruby_templates.rb +1 -1
  30. data/lib/bridgetown-core/converters/serbea_templates.rb +1 -1
  31. data/lib/bridgetown-core/errors.rb +21 -0
  32. data/lib/bridgetown-core/helpers.rb +3 -2
  33. data/lib/bridgetown-core/model/origin.rb +4 -6
  34. data/lib/bridgetown-core/rack/boot.rb +5 -9
  35. data/lib/bridgetown-core/ruby_template_view.rb +4 -0
  36. data/lib/bridgetown-core/tags/{webpack_path.rb → asset_path.rb} +7 -9
  37. data/lib/bridgetown-core/tasks/bridgetown_tasks.rake +2 -1
  38. data/lib/bridgetown-core/utils.rb +63 -9
  39. data/lib/bridgetown-core/version.rb +1 -1
  40. data/lib/bridgetown-core/watcher.rb +34 -34
  41. data/lib/bridgetown-core.rb +1 -0
  42. data/lib/site_template/Gemfile.erb +17 -11
  43. data/lib/site_template/README.md +2 -2
  44. data/lib/site_template/{Rakefile → Rakefile.erb} +15 -0
  45. data/lib/site_template/TEMPLATES/erb/_components/shared/navbar.erb +11 -0
  46. data/lib/site_template/TEMPLATES/erb/_components/shared/navbar.rb +5 -0
  47. data/lib/site_template/TEMPLATES/erb/_layouts/default.erb +15 -0
  48. data/lib/site_template/TEMPLATES/erb/_layouts/page.erb +7 -0
  49. data/lib/site_template/TEMPLATES/erb/_layouts/post.erb +7 -0
  50. data/lib/site_template/TEMPLATES/erb/_partials/_footer.erb +3 -0
  51. data/lib/site_template/TEMPLATES/erb/_partials/_head.erb +10 -0
  52. data/lib/site_template/{src → TEMPLATES/liquid}/_components/footer.liquid +0 -0
  53. data/lib/site_template/TEMPLATES/liquid/_components/head.liquid +10 -0
  54. data/lib/site_template/TEMPLATES/liquid/_components/navbar.liquid +11 -0
  55. data/lib/site_template/{src → TEMPLATES/liquid}/_layouts/default.liquid +2 -2
  56. data/lib/site_template/{src → TEMPLATES/liquid}/_layouts/page.liquid +0 -0
  57. data/lib/site_template/{src → TEMPLATES/liquid}/_layouts/post.liquid +0 -0
  58. data/lib/site_template/TEMPLATES/serbea/_components/shared/navbar.rb +5 -0
  59. data/lib/site_template/TEMPLATES/serbea/_components/shared/navbar.serb +11 -0
  60. data/lib/site_template/TEMPLATES/serbea/_layouts/default.serb +15 -0
  61. data/lib/site_template/TEMPLATES/serbea/_layouts/page.serb +7 -0
  62. data/lib/site_template/TEMPLATES/serbea/_layouts/post.serb +7 -0
  63. data/lib/site_template/TEMPLATES/serbea/_partials/_footer.serb +3 -0
  64. data/lib/site_template/TEMPLATES/serbea/_partials/_head.serb +10 -0
  65. data/lib/site_template/frontend/javascript/index.js.erb +7 -3
  66. data/lib/site_template/frontend/styles/index.css +71 -6
  67. data/lib/site_template/package.json.erb +24 -9
  68. data/lib/site_template/ruby-version.erb +1 -0
  69. data/lib/site_template/server/roda_app.rb +5 -3
  70. data/lib/site_template/server/routes/hello.rb.sample +1 -1
  71. data/lib/site_template/src/images/logo.svg +91 -0
  72. data/lib/site_template/src/index.md.erb +22 -0
  73. data/lib/site_template/src/posts.md.erb +28 -0
  74. metadata +53 -22
  75. data/lib/bridgetown-core/configurations/swup.rb +0 -37
  76. data/lib/site_template/frontend/styles/index.scss +0 -17
  77. data/lib/site_template/src/_components/head.liquid +0 -10
  78. data/lib/site_template/src/_components/navbar.liquid +0 -5
  79. data/lib/site_template/src/_layouts/home.liquid +0 -7
  80. data/lib/site_template/src/images/.keep +0 -1
  81. data/lib/site_template/src/index.md +0 -7
  82. data/lib/site_template/src/posts.md +0 -14
@@ -24,6 +24,14 @@ module Bridgetown
24
24
  aliases: "-c",
25
25
  banner: "CONFIGURATION(S)",
26
26
  desc: "Comma separated list of bundled configurations to perform"
27
+ class_option :templates,
28
+ aliases: "-t",
29
+ banner: "liquid|erb|serbea",
30
+ desc: "Preferred template engine (defaults to Liquid)"
31
+ class_option :"frontend-bundling",
32
+ aliases: "-e",
33
+ banner: "esbuild|webpack",
34
+ desc: "Choose your frontend bundling stack (defaults to esbuild)"
27
35
  class_option :force,
28
36
  type: :boolean,
29
37
  desc: "Force creation even if PATH already exists"
@@ -33,9 +41,9 @@ module Bridgetown
33
41
  class_option :"skip-yarn",
34
42
  type: :boolean,
35
43
  desc: "Skip 'yarn install'"
36
- class_option :"use-postcss",
44
+ class_option :"use-sass",
37
45
  type: :boolean,
38
- desc: "Create an empty PostCSS configuration instead of using Sass"
46
+ desc: "(Webpack only) Create a Sass configuration instead of using PostCSS"
39
47
 
40
48
  DOCSURL = "https://bridgetownrb.com/docs"
41
49
 
@@ -54,6 +62,11 @@ module Bridgetown
54
62
  def new_site
55
63
  raise ArgumentError, "You must specify a path." if args.empty?
56
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
+
57
70
  new_site_path = File.expand_path(args.join(" "), Dir.pwd)
58
71
  @site_name = new_site_path.split(File::SEPARATOR).last
59
72
 
@@ -70,6 +83,8 @@ module Bridgetown
70
83
  say_status :create, new_site_path
71
84
  create_site new_site_path
72
85
  after_install new_site_path, args.join(" "), options
86
+ rescue ArgumentError => e
87
+ say_status :alert, e.message, :red
73
88
  end
74
89
 
75
90
  protected
@@ -78,24 +93,79 @@ module Bridgetown
78
93
  !options["force"] && Dir.exist?(path)
79
94
  end
80
95
 
96
+ def frontend_bundling_option
97
+ options["frontend-bundling"] == "webpack" ? "webpack" : "esbuild"
98
+ end
99
+
100
+ def postcss_option
101
+ !(frontend_bundling_option == "webpack" && options["use-sass"])
102
+ end
103
+
81
104
  def create_site(new_site_path)
82
- directory ".", ".", exclude_pattern: %r!\.erb|DS_Store$|\.(s[ac]|c)ss$!
105
+ directory ".", ".", exclude_pattern: %r!\.erb|TEMPLATES|DS_Store$|\.(s[ac]|c)ss$!
83
106
  FileUtils.chmod_R "u+w", new_site_path
84
107
 
85
108
  template(
86
109
  "src/_posts/0000-00-00-welcome-to-bridgetown.md.erb",
87
110
  "src/_posts/#{Time.now.strftime("%Y-%m-%d")}-welcome-to-bridgetown.md"
88
111
  )
112
+ template("ruby-version.erb", ".ruby-version")
89
113
  template("Gemfile.erb", "Gemfile")
114
+ template("Rakefile.erb", "Rakefile")
90
115
  template("package.json.erb", "package.json")
91
116
  template("frontend/javascript/index.js.erb", "frontend/javascript/index.js")
117
+ template("src/index.md.erb", "src/index.md")
118
+ template("src/posts.md.erb", "src/posts.md")
119
+
120
+ case options["templates"]
121
+ when "erb"
122
+ setup_erb_templates
123
+ when "serbea"
124
+ setup_serbea_templates
125
+ else
126
+ setup_liquid_templates
127
+ end
128
+
129
+ if frontend_bundling_option == "esbuild"
130
+ configure_postcss
131
+ invoke(Esbuild, ["setup"], {})
132
+ else
133
+ postcss_option ? configure_postcss : configure_sass
134
+ invoke(Webpack, ["setup"], {})
135
+ end
136
+ end
137
+
138
+ def setup_erb_templates
139
+ directory "TEMPLATES/erb/_layouts", "src/_layouts"
140
+ directory "TEMPLATES/erb/_components", "src/_components"
141
+ directory "TEMPLATES/erb/_partials", "src/_partials"
142
+ gsub_file "bridgetown.config.yml", %r!permalink: pretty\n!, <<~YML
143
+ permalink: pretty
144
+ template_engine: erb
145
+ YML
146
+ end
147
+
148
+ def setup_serbea_templates
149
+ directory "TEMPLATES/serbea/_layouts", "src/_layouts"
150
+ directory "TEMPLATES/serbea/_components", "src/_components"
151
+ directory "TEMPLATES/serbea/_partials", "src/_partials"
152
+ gsub_file "bridgetown.config.yml", %r!permalink: pretty\n!, <<~YML
153
+ permalink: pretty
154
+ template_engine: serbea
155
+ YML
156
+ end
92
157
 
93
- options["use-postcss"] ? configure_postcss : configure_sass
94
- invoke(Webpack, ["setup"], {})
158
+ def setup_liquid_templates
159
+ directory "TEMPLATES/liquid/_layouts", "src/_layouts"
160
+ directory "TEMPLATES/liquid/_components", "src/_components"
161
+ gsub_file "bridgetown.config.yml", %r!permalink: pretty\n!, <<~YML
162
+ permalink: pretty
163
+ template_engine: liquid
164
+ YML
95
165
  end
96
166
 
97
167
  def configure_sass
98
- copy_file("frontend/styles/index.scss")
168
+ copy_file("frontend/styles/index.css", "frontend/styles/index.scss")
99
169
  end
100
170
 
101
171
  def configure_postcss
@@ -159,9 +229,9 @@ module Bridgetown
159
229
  end
160
230
  @skipped_bundle = false
161
231
  rescue LoadError
162
- say_status :run, "Could not load Bundler. Bundle install skipped.", :red
232
+ say_status :alert, "Could not load Bundler. Bundle install skipped.", :red
163
233
  rescue SystemExit
164
- say_status :run, "Problem occured while running bundle install.", :red
234
+ say_status :alert, "Problem occured while running bundle install.", :red
165
235
  end
166
236
 
167
237
  def git_init(path)
@@ -171,7 +241,7 @@ module Bridgetown
171
241
  end
172
242
  end
173
243
  rescue SystemExit
174
- say_status :run, "Could not load git. git init skipped.", :red
244
+ say_status :alert, "Could not load git. git init skipped.", :red
175
245
  end
176
246
 
177
247
  def yarn_install(path)
@@ -182,7 +252,7 @@ module Bridgetown
182
252
  end
183
253
  @skipped_yarn = false
184
254
  rescue SystemExit
185
- say_status :run, "Could not load yarn. yarn install skipped.", :red
255
+ say_status :alert, "Could not load yarn. yarn install skipped.", :red
186
256
  end
187
257
  end
188
258
  end
@@ -6,7 +6,7 @@ template default_postcss_config, "postcss.config.js"
6
6
  template "webpack.defaults.js.erb", "config/webpack.defaults.js", force: true
7
7
 
8
8
  unless Bridgetown.environment.test?
9
- packages = %w(postcss@8.3.0 postcss-loader@4.3.0 postcss-flexbugs-fixes postcss-preset-env)
9
+ packages = %w(postcss postcss-loader postcss-flexbugs-fixes postcss-preset-env)
10
10
  run "yarn add -D #{packages.join(" ")}"
11
11
  run "yarn remove sass sass-loader"
12
12
  end
@@ -2,14 +2,14 @@
2
2
 
3
3
  # rubocop:disable Layout/LineLength
4
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
5
  template "webpack.defaults.js.erb", "config/webpack.defaults.js", force: true
9
6
  say "🎉 Webpack configuration updated successfully!"
10
7
 
11
8
  return if Bridgetown.environment.test?
12
9
 
10
+ required_packages = %w(esbuild esbuild-loader webpack@5.39.1 webpack-cli@4.7.2 webpack-manifest-plugin@3.1.1)
11
+ redundant_packages = %w(@babel/core @babel/plugin-proposal-class-properties @babel/plugin-proposal-decorators @babel/plugin-transform-runtime @babel/preset-env babel-loader)
12
+
13
13
  say "Installing required packages"
14
14
  run "yarn add -D #{required_packages.join(" ")}"
15
15
 
@@ -119,7 +119,7 @@ module.exports = {
119
119
  filename: "../css/[name].[contenthash].css",
120
120
  }),
121
121
  new WebpackManifestPlugin({
122
- fileName: path.resolve(rootDir, ".bridgetown-webpack", "manifest.json"),
122
+ fileName: path.resolve(rootDir, ".bridgetown-cache", "frontend-bundling", "manifest.json"),
123
123
  }),
124
124
  ],
125
125
  module: {
@@ -13,7 +13,7 @@ module Bridgetown
13
13
  def self.banner
14
14
  "bridgetown webpack ACTION"
15
15
  end
16
- summary "Perform actions on the bridgetown webpack configuration"
16
+ summary "Perform actions on the Bridgetown Webpack configuration"
17
17
 
18
18
  def self.exit_on_failure?
19
19
  true
@@ -72,8 +72,8 @@ module Bridgetown
72
72
 
73
73
  def supported_actions
74
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",
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
77
  "enable-postcss": "Configures PostCSS in your project",
78
78
  }.with_indifferent_access
79
79
  end
@@ -91,6 +91,12 @@ module Bridgetown
91
91
  def supported_template_extensions
92
92
  %w(erb serb slim haml)
93
93
  end
94
+
95
+ def path_for_errors
96
+ component_template_path
97
+ rescue RuntimeError
98
+ source_location
99
+ end
94
100
  end
95
101
 
96
102
  # If a content block was originally passed into via `render`, capture its output.
@@ -133,7 +139,7 @@ module Bridgetown
133
139
  rescue StandardError => e
134
140
  Bridgetown.logger.error "Component error:",
135
141
  "#{self.class} encountered an error while "\
136
- "rendering `#{self.class.component_template_path}'"
142
+ "rendering `#{self.class.path_for_errors}'"
137
143
  raise e
138
144
  end
139
145
 
@@ -165,7 +171,7 @@ module Bridgetown
165
171
  end
166
172
 
167
173
  def method_missing(method, *args, **kwargs, &block)
168
- if helpers.respond_to?(method.to_sym)
174
+ if view_context && helpers.respond_to?(method.to_sym)
169
175
  helpers.send method.to_sym, *args, **kwargs, &block
170
176
  else
171
177
  super
@@ -173,7 +179,7 @@ module Bridgetown
173
179
  end
174
180
 
175
181
  def respond_to_missing?(method, include_private = false)
176
- helpers.respond_to?(method.to_sym, include_private) || super
182
+ (view_context && helpers.respond_to?(method.to_sym, include_private)) || super
177
183
  end
178
184
  end
179
185
  end
@@ -146,6 +146,10 @@ class Bridgetown::Site
146
146
  @collections_path ||= dir_str.empty? ? source : in_source_dir(dir_str)
147
147
  end
148
148
 
149
+ def frontend_bundling_path
150
+ in_root_dir(".bridgetown-cache", "frontend-bundling")
151
+ end
152
+
149
153
  private
150
154
 
151
155
  # Disable Marshaling cache to disk in Safe Mode
@@ -67,7 +67,7 @@ class Bridgetown::Site
67
67
 
68
68
  # @return [Array<Bridgetown::Resource::TaxonomyType>]
69
69
  def taxonomy_types
70
- @taxonomy_types ||= config.taxonomies.map do |label, key_or_metadata|
70
+ @taxonomy_types ||= config.taxonomies.to_h do |label, key_or_metadata|
71
71
  key = key_or_metadata
72
72
  tax_metadata = if key_or_metadata.is_a? Hash
73
73
  key = key_or_metadata["key"]
@@ -79,7 +79,7 @@ class Bridgetown::Site
79
79
  [label, Bridgetown::Resource::TaxonomyType.new(
80
80
  site: self, label: label, key: key, metadata: tax_metadata
81
81
  ),]
82
- end.to_h.with_dot_access
82
+ end.with_dot_access
83
83
  end
84
84
 
85
85
  # Get all loaded resources.
@@ -110,11 +110,11 @@ class Bridgetown::Site
110
110
  generated_pages << generated_page
111
111
  end
112
112
 
113
- # Loads and memoizes the parsed Webpack manifest file (if available)
113
+ # Loads and memoizes the parsed frontend bundler manifest file (if available)
114
114
  # @return [Hash]
115
115
  def frontend_manifest
116
116
  @frontend_manifest ||= begin
117
- manifest_file = in_root_dir(".bridgetown-webpack", "manifest.json")
117
+ manifest_file = File.join(frontend_bundling_path, "manifest.json")
118
118
 
119
119
  JSON.parse(File.read(manifest_file)) if File.exist?(manifest_file)
120
120
  end
@@ -22,9 +22,10 @@ create_builder "purgecss.rb" do
22
22
  PURGE
23
23
  File.write(purgecss_file, config_js.strip)
24
24
  end
25
- manifest_file = site.in_root_dir(".bridgetown-webpack", "manifest.json")
25
+ manifest_file = File.join(site.frontend_bundling_path, "manifest.json")
26
26
  if File.exist?(manifest_file)
27
27
  manifest = JSON.parse(File.read(manifest_file))
28
+ # TODO: make this work with esbuild too
28
29
  css_file = manifest["main.css"].split("/").last
29
30
  css_path = ["output", "_bridgetown", "static", "css", css_file].join("/")
30
31
  Bridgetown.logger.info "PurgeCSS", "Purging \#{css_file}"
@@ -4,25 +4,53 @@ require "fileutils"
4
4
 
5
5
  say "Installing Stimulus...", :green
6
6
 
7
- run("yarn add stimulus")
7
+ run("yarn add @hotwired/stimulus")
8
+ if Bridgetown::Utils.frontend_bundler_type == :webpack
9
+ run("yarn add @hotwired/stimulus-webpack-helpers")
10
+ end
8
11
 
9
12
  say 'Adding Stimulus to "frontend/javascript/index.js"...', :magenta
10
13
 
11
14
  javascript_import do
12
- <<~JS
13
- import { Application } from "stimulus"
14
- import { definitionsFromContext } from "stimulus/webpack-helpers"
15
- JS
15
+ if Bridgetown::Utils.frontend_bundler_type == :esbuild
16
+ <<~JS
17
+ import { Application } from "@hotwired/stimulus"
18
+ JS
19
+ else
20
+ <<~JS
21
+ import { Application } from "@hotwired/stimulus"
22
+ import { definitionsFromContext } from "@hotwired/stimulus-webpack-helpers"
23
+ JS
24
+ end
16
25
  end
17
26
 
18
27
  javascript_dir = File.join("frontend", "javascript")
19
28
 
20
29
  append_to_file(File.join(javascript_dir, "index.js")) do
21
- <<~JS
22
- const application = Application.start()
23
- const context = require.context("./controllers", true, /\.js$/)
24
- application.load(definitionsFromContext(context))
25
- JS
30
+ if Bridgetown::Utils.frontend_bundler_type == :esbuild
31
+ <<~JS
32
+
33
+ window.Stimulus = Application.start()
34
+
35
+ import controllers from "./controllers/**/*.{js,js.rb}"
36
+ Object.entries(controllers).forEach(([filename, controller]) => {
37
+ if (filename.includes("_controller.")) {
38
+ const identifier = filename.replace("./controllers/", "")
39
+ .replace(/_controller\..*$/, "")
40
+ .replace("/", "--")
41
+
42
+ Stimulus.register(identifier, controller.default)
43
+ }
44
+ })
45
+ JS
46
+ else
47
+ <<~JS
48
+
49
+ window.Stimulus = Application.start()
50
+ const context = require.context("./controllers", true, /\.js$/)
51
+ Stimulus.load(definitionsFromContext(context))
52
+ JS
53
+ end
26
54
  end
27
55
 
28
56
  controller_dir = File.join(javascript_dir, "controllers")
@@ -33,7 +61,7 @@ FileUtils.mkdir_p(controller_dir)
33
61
  say "Creating an example Stimulus Controller for you!...", :magenta
34
62
  create_file(File.join(controller_dir, "example_controller.js")) do
35
63
  <<~JS
36
- import { Controller } from "stimulus"
64
+ import { Controller } from "@hotwired/stimulus"
37
65
  export default class extends Controller {
38
66
  connect() {
39
67
  console.log("Hello, Stimulus!", this.element)
@@ -46,4 +74,4 @@ say "Stimulus successfully added", :green
46
74
 
47
75
  say "To start adding controllers, visit the `./frontend/javascript/controllers/` directory", :blue
48
76
  say "Make sure your controllers follow the `[name]_controller.js` convention", :blue
49
- say 'For further reading, check out "https://stimulus.hotwire.dev/"', :blue
77
+ say 'For further reading, check out "https://stimulus.hotwired.dev/"', :blue
@@ -1,3 +1,8 @@
1
+ /* If you need to add @import statements, do so up here */
2
+
3
+ @import "jit-refresh.css"; /* triggers frontend rebuilds */
4
+
5
+ /* Set up Tailwind imports */
1
6
  @tailwind base;
2
7
  @tailwind components;
3
8
  @tailwind utilities;
@@ -11,15 +11,22 @@ unless File.exist?("postcss.config.js")
11
11
  return
12
12
  end
13
13
 
14
+ say_status :tailwind, "Installing Tailwind CSS..."
15
+
14
16
  confirm = ask "This configuration will ovewrite your existing #{"postcss.config.js".bold.white}. Would you like to continue? [Yn]"
15
17
  return unless confirm.casecmp?("Y")
16
18
 
17
19
  run "yarn add -D tailwindcss"
18
20
  run "npx tailwindcss init"
19
21
 
20
- copy_file in_templates_dir("postcss.config.js"), "postcss.config.js", force: true
22
+ gsub_file "tailwind.config.js", "content: [],", <<~JS.strip
23
+ content: [
24
+ './src/**/*.{html,md,liquid,erb,serb}',
25
+ './frontend/javascript/**/*.js',
26
+ ],
27
+ JS
21
28
 
22
- run "bundle exec bridgetown configure purgecss"
29
+ copy_file in_templates_dir("postcss.config.js"), "postcss.config.js", force: true
23
30
 
24
31
  if File.exist?("frontend/styles/index.css")
25
32
  prepend_to_file "frontend/styles/index.css",
@@ -29,4 +36,26 @@ else
29
36
  say File.read(in_templates_dir("/css_imports.css"))
30
37
  end
31
38
 
39
+ create_file "frontend/styles/jit-refresh.css", "/* #{Time.now.to_i} */"
40
+
41
+ create_builder "tailwind_jit.rb" do
42
+ <<~RUBY
43
+ class Builders::TailwindJit < SiteBuilder
44
+ def build
45
+ hook :site, :pre_reload do |_, paths|
46
+ # Don't trigger refresh if it's a frontend-only change
47
+ next if paths.length == 1 && paths.first.ends_with?("manifest.json")
48
+
49
+ # Save out a comment file to trigger Tailwind's JIT
50
+ refresh_file = site.in_root_dir("frontend", "styles", "jit-refresh.css")
51
+ File.write refresh_file, "/* \#{Time.now.to_i} */"
52
+ throw :halt # don't continue the build, wait for watcher rebuild
53
+ end
54
+ end
55
+ end
56
+ RUBY
57
+ end
58
+
59
+ say_status :tailwind, "Tailwind CSS is now configured."
60
+
32
61
  # rubocop:enable all
@@ -0,0 +1,48 @@
1
+ document.addEventListener("turbo:visit", () => {
2
+ let main = document.querySelector("main");
3
+ if (main.dataset.turboTransition == "false") return;
4
+
5
+ let [movement, scale] = ["15px", "0.99"];
6
+
7
+ if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
8
+ [movement, scale] = ["7px", "1"]
9
+ };
10
+
11
+ main.style.transformOrigin = "50% 0%";
12
+ main.dataset.animatingOut = true;
13
+
14
+ main.animate(
15
+ [
16
+ { opacity: 1, transform: "translateY(0px) scale(1)" },
17
+ { opacity: 0, transform: `translateY(${movement}) scale(${scale})` }
18
+ ],
19
+ { duration: 300, easing: "cubic-bezier(0.45, 0, 0.55, 1)" }
20
+ );
21
+
22
+ Promise.all(main.getAnimations().map(animation => animation.finished)).then(() => {
23
+ if (main.dataset.animatingOut) main.style.visibility = "hidden"
24
+ })
25
+ });
26
+
27
+ document.addEventListener("turbo:load", () => {
28
+ let main = document.querySelector("main");
29
+ if (main.dataset.turboTransition == "false") return;
30
+
31
+ let [movement, scale] = ["-10px", "0.99"];
32
+
33
+ if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
34
+ [movement, scale] = ["-5px", "1"]
35
+ };
36
+
37
+ main.style.visibility = "visible";
38
+ main.style.transformOrigin = "50% 0%";
39
+ delete main.dataset.animatingOut;
40
+
41
+ main.animate(
42
+ [
43
+ { opacity: 0, transform: `translateY(${movement}) scale(${scale})` },
44
+ { opacity: 1, transform: "translateY(0px) scale(1)" }
45
+ ],
46
+ { duration: 150, easing: "cubic-bezier(0.45, 0, 0.55, 1)" }
47
+ )
48
+ })
@@ -1,16 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- say "Installing Turbo...", :green
3
+ say_status :turbo, "Installing Turbo..."
4
4
 
5
5
  run("yarn add @hotwired/turbo")
6
6
 
7
- say 'Adding Turbo to "frontend/javascript/index.js"...', :magenta
7
+ say_status :turbo, 'Adding Turbo to "frontend/javascript/index.js"...', :magenta
8
8
 
9
9
  javascript_import do
10
10
  <<~JS
11
- import Turbo from "@hotwired/turbo"
11
+ import * as Turbo from "@hotwired/turbo"
12
+
13
+ // Uncomment the line below to add transition animations when Turbo navigates.
14
+ // We recommend adding <meta name="turbo-cache-control" content="no-preview" />
15
+ // to your HTML head if you turn on transitions. Use data-turbo-transition="false"
16
+ // on your <main> element for pages where you don't want any transition animation.
17
+ //
18
+ // import "./turbo_transitions.js"
12
19
  JS
13
20
  end
14
21
 
15
- say "Turbo successfully added", :green
16
- say 'For further reading, check out "https://turbo.hotwired.dev/"', :blue
22
+ copy_file in_templates_dir("turbo_transitions.js"), "frontend/javascript/turbo_transitions.js"
23
+
24
+ say_status :turbo, "Turbo successfully added!", :magenta
25
+ say_status :turbo, "Take a look in your index.js file for optional animation setup.", :blue
26
+ say_status :turbo, 'For further reading, check out "https://turbo.hotwired.dev/"', :blue
@@ -115,7 +115,7 @@ module Bridgetown
115
115
  erb_view = Bridgetown::ERBView.new(convertible)
116
116
 
117
117
  erb_renderer = Tilt::ErubiTemplate.new(
118
- convertible.relative_path,
118
+ convertible.path,
119
119
  line_start(convertible),
120
120
  outvar: "@_erbout",
121
121
  bufval: "Bridgetown::OutputBuffer.new",
@@ -9,7 +9,7 @@ module Bridgetown
9
9
  def convert(content, convertible)
10
10
  erb_view = Bridgetown::ERBView.new(convertible)
11
11
  erb_view.instance_eval(
12
- content, convertible.relative_path.to_s, line_start(convertible)
12
+ content, convertible.path.to_s, line_start(convertible)
13
13
  ).to_s
14
14
  end
15
15
  end
@@ -39,7 +39,7 @@ module Bridgetown
39
39
 
40
40
  serb_view = Bridgetown::SerbeaView.new(convertible)
41
41
 
42
- serb_renderer = Tilt::SerbeaTemplate.new(convertible.relative_path) { content }
42
+ serb_renderer = Tilt::SerbeaTemplate.new(convertible.path) { content }
43
43
 
44
44
  if convertible.is_a?(Bridgetown::Layout)
45
45
  serb_renderer.render(serb_view) do
@@ -14,5 +14,26 @@ module Bridgetown
14
14
  PostURLError = Class.new(FatalException)
15
15
  InvalidURLError = Class.new(FatalException)
16
16
  InvalidConfigurationError = Class.new(FatalException)
17
+
18
+ def self.print_build_error(exc, trace: false)
19
+ Bridgetown.logger.error "Exception raised:", exc.class.to_s.bold
20
+ Bridgetown.logger.error exc.message.reset_ansi
21
+
22
+ trace_args = ["-t", "--trace"]
23
+ print_trace_msg = true
24
+ traces = if trace || ARGV.find { |arg| trace_args.include?(arg) }
25
+ print_trace_msg = false
26
+ exc.backtrace
27
+ else
28
+ exc.backtrace[0..4]
29
+ end
30
+ traces.each_with_index do |backtrace_line, index|
31
+ Bridgetown.logger.error "#{index + 1}:", backtrace_line.reset_ansi
32
+ end
33
+
34
+ return unless print_trace_msg
35
+
36
+ Bridgetown.logger.warn "Backtrace:", "Use the --trace option for complete information."
37
+ end
17
38
  end
18
39
  end
@@ -22,9 +22,10 @@ module Bridgetown
22
22
  @context = Context.new({ site: site })
23
23
  end
24
24
 
25
- def webpack_path(asset_type)
26
- Bridgetown::Utils.parse_webpack_manifest_file(site, asset_type.to_s)
25
+ def asset_path(asset_type)
26
+ Bridgetown::Utils.parse_frontend_manifest_file(site, asset_type.to_s)
27
27
  end
28
+ alias_method :webpack_path, :asset_path
28
29
 
29
30
  def live_reload_dev_js
30
31
  Bridgetown::Utils.live_reload_js(site)
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # See bottom of file for specific origin requires...
4
-
5
3
  module Bridgetown
6
4
  module Model
7
5
  # Abstract Superclass
8
6
  class Origin
9
7
  extend ActiveSupport::DescendantsTracker
10
8
 
9
+ EAGER_LOAD_DESCENDANTS = %i(BuilderOrigin RepoOrigin PluginOrigin).freeze
10
+
11
11
  # @return [String]
12
12
  attr_accessor :id
13
13
 
@@ -42,9 +42,7 @@ module Bridgetown
42
42
  raise "Implement #exists? in a subclass of Bridgetown::Model::Origin"
43
43
  end
44
44
  end
45
+
46
+ Origin::EAGER_LOAD_DESCENDANTS.each { const_get _1 }
45
47
  end
46
48
  end
47
-
48
- require "bridgetown-core/model/builder_origin"
49
- require "bridgetown-core/model/repo_origin"
50
- require "bridgetown-core/model/plugin_origin"
@@ -51,15 +51,11 @@ module Bridgetown
51
51
  loader.do_not_eager_load(File.join(server_folder, "roda_app.rb"))
52
52
 
53
53
  unless ENV["BRIDGETOWN_ENV"] == "production"
54
- begin
55
- Listen.to(server_folder) do |_modified, _added, _removed|
56
- loader.reload
57
- loader.eager_load
58
- Bridgetown::Rack::Routes.reload_subclasses
59
- end.start
60
- # interrupt isn't handled well by the listener
61
- rescue ThreadError # rubocop:disable Lint/SuppressedException
62
- end
54
+ Listen.to(server_folder) do |_modified, _added, _removed|
55
+ loader.reload
56
+ loader.eager_load
57
+ Bridgetown::Rack::Routes.reload_subclasses
58
+ end.start
63
59
  end
64
60
  end
65
61