Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New bundled configurations: Lit, Shoelace, Ruby2JS #553

Merged
merged 16 commits into from
Jun 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bridgetown-core/.rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ AllCops:
- test/resources/src/**/*.rb
- lib/bridgetown-core/commands/base.rb
- lib/bridgetown-core/commands/plugins.rb
- lib/bridgetown-core/configurations/ruby2js/**/*
- lib/bridgetown-core/rack/roda.rb
- lib/site_template/TEMPLATES/**/*
- lib/site_template/Rakefile
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ def javascript_import(data = nil, filename: "index.js") # rubocop:todo Metrics/P

def add_bridgetown_plugin(gemname, version: nil)
version = " -v \"#{version}\"" if version
run "bundle add #{gemname}#{version} -g bridgetown_plugins"
run "bundle add #{gemname}#{version} -g bridgetown_plugins",
env: { "BUNDLE_GEMFILE" => File.join(destination_root, "Gemfile") }
rescue SystemExit
say_status :run, "Gem not added due to bundler error", :red
end
Expand Down
2 changes: 1 addition & 1 deletion bridgetown-core/lib/bridgetown-core/commands/configure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def list_configurations

def configurations
inside self.class.source_root do
return Dir.glob("*.rb").map { |file| file.sub(".rb", "") }
return Dir.glob("*.rb").map { |file| file.sub(".rb", "") }.sort
end
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,14 @@ const cssRules = {
mode: '<%= self.config.uses_postcss? ? "postcss" : "sass" %>',

postcss: () => {
cssRules.use.push("postcss-loader")
cssRules.use.push({
loader: "postcss-loader",
options: {
postcssOptions: {
config: "postcss.config.js"
}
}
})
return { test: cssRules.test, use: cssRules.use }
},

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
confirm = ask "This configuration will ovewrite your existing #{"postcss.config.js".bold.white}. Would you like to continue? [Yn]"
return unless confirm.casecmp?("Y")

plugins = %w(postcss-mixins postcss-color-function cssnano)
plugins = %w(postcss-mixins postcss-color-mod-function cssnano)

say "Adding the following PostCSS plugins: #{plugins.join(' | ')}", :green
run "yarn add -D #{plugins.join(' ')}"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
module.exports = {
plugins: {
'postcss-mixins': {},
'postcss-color-function': {},
'postcss-color-mod-function': {
// Uncomment the following to import CSS variables for use in `color-mod`:
// importFrom: "frontend/styles/variables.css"
},
'postcss-flexbugs-fixes': {},
'postcss-preset-env': {
autoprefixer: {
Expand Down
95 changes: 95 additions & 0 deletions bridgetown-core/lib/bridgetown-core/configurations/lit.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# frozen_string_literal: true

unless Bridgetown::Utils.frontend_bundler_type == :esbuild
error_message = "#{"esbuild.config.js".bold} not found. (This configuration doesn't currently " \
"support Webpack.)"

@logger.error "\nError:".red, "🚨 #{error_message}"

return
end

say_status :lit, "Installing Lit + SSR Plugin..."

add_bridgetown_plugin "bridgetown-lit-renderer", version: "2.0.0.beta3"

run "yarn add lit esbuild-plugin-lit-css bridgetown-lit-renderer@2.0.0-beta3"

copy_file in_templates_dir("lit-ssr.config.js"), "config/lit-ssr.config.js"
copy_file in_templates_dir("lit-components-entry.js"), "config/lit-components-entry.js"
copy_file in_templates_dir("esbuild-plugins.js"), "config/esbuild-plugins.js"

insert_into_file "esbuild.config.js",
after: 'const build = require("./config/esbuild.defaults.js")' do
<<~JS

const { plugins } = require("./config/esbuild-plugins.js")
JS
end

found_match = false
gsub_file "esbuild.config.js", %r{const esbuildOptions = {}\n} do |_match|
found_match = true

<<~JS
const esbuildOptions = {
plugins: [...plugins],
// Uncomment the following to opt into `.global.css` & `.lit.css` nomenclature.
// Read https://edge.bridgetownrb.com/docs/components/lit#sidecar-css-files for documentation.
/*
postCssPluginConfig: {
filter: /(?:index|\.global)\.css$/,
},
*/
}
JS
end

unless found_match
insert_into_file "esbuild.config.js",
after: 'const { plugins } = require("./config/esbuild-plugins.js")' do
<<~JS

// TODO: You will manually need to move any plugins below you wish to share with
// Lit SSR into the `config/esbuild-plugins.js` file.
// Then add `...plugins` as an item in your plugins array.
//
// You might also want to include the following in your esbuild config to opt into
// `.global.css` & `.lit.css` nomenclature.
// Read https://edge.bridgetownrb.com/docs/components/lit#sidecar-css-files for documentation.
/*
postCssPluginConfig: {
filter: /(?:index|\.global)\.css$/,
},
*/
JS
end
end

copy_file in_templates_dir("happy-days.lit.js"), "src/_components/happy-days.lit.js"

javascript_import do
<<~JS
import "bridgetown-lit-renderer"
JS
end

insert_into_file "frontend/javascript/index.js",
before: 'import components from "bridgetownComponents/**/*.{js,jsx,js.rb,css}"' do
<<~JS
// To opt into `.global.css` & `.lit.css` nomenclature, change the `css` extension below to `global.css`.
// Read https://edge.bridgetownrb.com/docs/components/lit#sidecar-css-files for documentation.
JS
end

if found_match
say_status :lit, "Lit is now configured!"
say_status :lit,
"The `config/esbuild-plugins.js` file will let you add full-stack plugins in future."
else
say_status :lit, "Lit is just about configured!"
say_status :lit, "You will need to edit `esbuild.config.js` to finish setting up the plugin."
end

say "Check out the example `happy-days.lit.js` file in `src/_components`", :blue
say 'For further reading, check out "https://edge.bridgetownrb.com/docs/components/lit"', :blue
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// You can add "full-stack" esbuild plugins here that you wish to share between
// the frontend bundles and Lit SSR. Just import your plugins and add them and
// any additional configuration to the `plugins` array below.

// This plugin will let you import `.lit.css` files as sidecar stylesheets.
// Read https://edge.bridgetownrb.com/docs/components/lit#sidecar-css-files for documentation.
const { litCssPlugin } = require("esbuild-plugin-lit-css")
const postCssConfig = require("postcss-load-config").sync()
const postCssProcessor = require("postcss")([...postCssConfig.plugins])

module.exports = {
plugins: [
litCssPlugin({
filter: /\.lit\.css$/,
transform: async (css, { filePath }) => {
const results = await postCssProcessor.process(css, { ...postCssConfig.options, from: filePath })
return results.css
}
}),
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { LitElement, html, css } from "lit"

export class HappyDaysElement extends LitElement {
static styles = css`
:host {
display: block;
border: 2px dashed gray;
padding: 20px;
max-width: 300px;
}
`

static properties = {
hello: { type: String }
}

render() {
return html`
<p>Hello ${this.hello}! ${Date.now()}</p>
`;
}
}

// Try adding `<%= lit :happy_days, hello: "there" %>` somewhere in an ERB template
// on your site to see this example Lit component in action!
customElements.define("happy-days", HappyDaysElement)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import components from "bridgetownComponents/**/*.{lit.js,lit.js.rb}"
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const build = require("bridgetown-lit-renderer/build")
const { plugins } = require("./esbuild-plugins.js")

const esbuildOptions = { plugins }

build(esbuildOptions)
21 changes: 21 additions & 0 deletions bridgetown-core/lib/bridgetown-core/configurations/open-props.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

run "yarn add open-props"

variables_import = <<~CSS
@import "variables.css";

CSS

if File.exist?("frontend/styles/index.css")
prepend_to_file "frontend/styles/index.css", variables_import
elsif File.exist?("frontend/styles/index.scss")
prepend_to_file "frontend/styles/index.scss", variables_import
else
say "\nPlease add the following lines to your CSS index file:"
say variables_import
end

template in_templates_dir("variables.css.erb"), "frontend/styles/variables.css"

say_status :open_props, "Open Props is now configured."
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
@import "open-props/<% if Bridgetown::Utils.frontend_bundler_type == :esbuild %>open-props.min.css<% else %>style<% end %>";

/* Uncomment this if you want addiitonal "default" styles applied: */
/* @import "open-props/normalize<% if Bridgetown::Utils.frontend_bundler_type == :esbuild %>.min.css<% end %>"; */

:root {
/* Define additional variables here. */

/* You can use variables from Open Props in your own custom properties. */
--color-medium-gray: var(--gray-7);
}
67 changes: 67 additions & 0 deletions bridgetown-core/lib/bridgetown-core/configurations/ruby2js.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# frozen_string_literal: true

unless Bridgetown::Utils.frontend_bundler_type == :esbuild
error_message = "#{"esbuild.config.js".bold} not found. (This configuration doesn't currently " \
"support Webpack.)"

@logger.error "\nError:".red, "🚨 #{error_message}"

return
end

say_status :ruby2js, "Installing Ruby2JS..."

run "yarn add -D @ruby2js/esbuild-plugin"

found_match = false
gsub_file "esbuild.config.js", %r{const esbuildOptions = {}\n} do |_match|
found_match = true

<<~JS
const ruby2js = require("@ruby2js/esbuild-plugin")

const esbuildOptions = {
plugins: [
// See docs on Ruby2JS options here: https://www.ruby2js.com/docs/options
ruby2js({
eslevel: 2022,
autoexports: "default",
filters: ["camelCase", "functions", "lit", "esm", "return"]
})
]
}
JS
end

unless found_match
insert_into_file "esbuild.config.js",
after: 'const build = require("./config/esbuild.defaults.js")' do
<<~JS

const ruby2js = require("@ruby2js/esbuild-plugin")

// TODO: Uncomment and move the following into your plugins array:
//
// ruby2js({
// eslevel: 2022,
// autoexports: "default",
// filters: ["camelCase", "functions", "lit", "esm", "return"]
// })
//
// See docs on Ruby2JS options here: https://www.ruby2js.com/docs/options

JS
end
end

copy_file in_templates_dir("hello_world.js.rb"), "src/_components/hello_world.js.rb"

if found_match
say_status :ruby2js, "Ruby2JS is now configured!"
else
say_status :ruby2js, "Ruby2JS is just about configured!"
say_status :ruby2js, "You will need to edit `esbuild.config.js` to finish setting up the plugin."
end

say "Check out the example `hello_world.js.rb` file in `src/_components`", :blue
say 'For further reading, check out "https://www.ruby2js.com"', :blue
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class HelloWorld < HTMLElement
def connected_callback()
self.inner_html = "<p><strong>Hello World!</strong></p>"
end
end

# Try adding `<hello-world></hello-world>` somewhere on your site to see this
# example web component in action!
custom_elements.define "hello-world", HelloWorld
50 changes: 50 additions & 0 deletions bridgetown-core/lib/bridgetown-core/configurations/shoelace.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# frozen_string_literal: true

say_status :shoelace, "Installing Shoelace..."

run "yarn add @shoelace-style/shoelace"

say 'Adding Shoelace to "frontend/javascript/index.js"...', :magenta

javascript_import do
<<~JS
// Import the base Shoelace stylesheet:
import "@shoelace-style/shoelace/dist/themes/light.css"

// Example components, mix 'n' match however you like!
import "@shoelace-style/shoelace/dist/components/button/button.js"
import "@shoelace-style/shoelace/dist/components/icon/icon.js"
import "@shoelace-style/shoelace/dist/components/spinner/spinner.js"

// Use the public icons folder:
import { setBasePath } from "@shoelace-style/shoelace/dist/utilities/base-path.js"
setBasePath("/shoelace-assets")
JS
end

say "Updating frontend build commands...", :magenta

if Bridgetown::Utils.frontend_bundler_type == :esbuild
insert_into_file "package.json", before: ' "esbuild": "node' do
<<-JS
"shoelace:copy-assets": "mkdir -p src/shoelace-assets && cp -r node_modules/@shoelace-style/shoelace/dist/assets src/shoelace-assets",
JS
end
gsub_file "package.json", %r{"esbuild": "node}, '"esbuild": "yarn shoelace:copy-assets && node'
gsub_file "package.json", %r{"esbuild-dev": "node},
'"esbuild-dev": "yarn shoelace:copy-assets && node'
else
insert_into_file "package.json", before: ' "webpack-build": "webpack' do
<<-JS
"shoelace:copy-assets": "mkdir -p src/shoelace-assets && cp -r node_modules/@shoelace-style/shoelace/dist/assets src/shoelace-assets",
JS
end
gsub_file "package.json", %r{"webpack-build": "webpack},
'"webpack-build": "yarn shoelace:copy-assets && webpack'
gsub_file "package.json", %r{"webpack-dev": "webpack},
'"webpack-dev": "yarn shoelace:copy-assets && webpack'
end

say_status :shoelace, "Shoelace is now configured!"

say 'For further reading, check out "https://shoelace.style"', :blue
Loading