Skip to content

Commit

Permalink
Add CLI command to update webpack config (#270)
Browse files Browse the repository at this point in the history
  • Loading branch information
ayushn21 authored May 24, 2021
1 parent 80455a4 commit 5a95144
Show file tree
Hide file tree
Showing 15 changed files with 250 additions and 36 deletions.
2 changes: 1 addition & 1 deletion bridgetown-core/lib/bridgetown-core/commands/new.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,10 @@ def create_site(new_site_path)
)
template("Gemfile.erb", "Gemfile")
template("package.json.erb", "package.json")
template("webpack.config.js.erb", "webpack.config.js")
template("frontend/javascript/index.js.erb", "frontend/javascript/index.js")

options["use-postcss"] ? configure_postcss : configure_sass
invoke(Webpack, ["setup"], {})
end

def configure_sass
Expand Down
76 changes: 76 additions & 0 deletions bridgetown-core/lib/bridgetown-core/commands/webpack.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# frozen_string_literal: true

module Bridgetown
module Commands
class Webpack < Thor::Group
include Thor::Actions
include ConfigurationOverridable
extend Summarizable

Registrations.register do
register(Webpack, "webpack", "webpack ACTION", Webpack.summary)
end

def self.banner
"bridgetown webpack ACTION"
end
summary "Perform actions on the bridgetown webpack configuration"

def self.exit_on_failure?
true
end

def webpack
logger = Bridgetown.logger
return show_actions if args.empty?

action = args.first
if supported_actions.include?(action)
perform action
else
logger.error "Error:".red, "🚨 Please enter a valid action."
say "\n"
show_actions
end
end

def self.source_root
File.expand_path("./webpack", __dir__)
end

def self.destination_root
site.root_dir
end

def site
@site ||= Bridgetown::Site.new(configuration_with_overrides(quiet: true))
end

protected

def perform(action)
automation = find_in_source_paths("#{action}.rb")
inside(New.created_site_dir || Dir.pwd) do
apply automation, verbose: false
end
end

def show_actions
say "Available actions:\n".bold

longest_action = supported_actions.keys.max_by(&:size).size
supported_actions.each do |action, description|
say action.ljust(longest_action).to_s.bold.blue + "\t" + "# #{description}"
end
end

def supported_actions
{
setup: "Sets up a webpack integration with Bridgetown in your project",
update: "Updates the Bridgetown webpack defaults to the latest available version",
"enable-postcss": "Configures PostCSS in your project",
}.with_indifferent_access
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true

create_file "postcss.config.js"
template "webpack.defaults.js.erb", "webpack.defaults.js", force: true
4 changes: 4 additions & 0 deletions bridgetown-core/lib/bridgetown-core/commands/webpack/setup.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true

template "webpack.defaults.js.erb", "webpack.defaults.js"
copy_file "webpack.config.js", force: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# frozen_string_literal: true

template "webpack.defaults.js.erb", "webpack.defaults.js", force: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const config = require("./webpack.defaults.js")

// Add any overrides to the default webpack config here:

// Eg:
//
// ```
// const path = require("path")
// config.resolve.modules.push(path.resolve(__dirname, 'frontend', 'components'))
// config.resolve.alias.frontendComponents = path.resolve(__dirname, 'frontend', 'components')
// ```




////////////////////////////////////////////////////////

module.exports = config
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
// This file is created and managed by Bridgetown.
// Instead of editing this file, add your overrides to `webpack.config.js`
//
// To update this file to the latest version provided by Bridgetown,
// run `bridgetown webpack update`. Any changes to this file will be overwritten
// when an update is applied hence we strongly recommend adding overrides to
// `webpack.config.js` instead of editing this file.

const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const ManifestPlugin = require("webpack-manifest-plugin");
Expand Down Expand Up @@ -54,11 +62,12 @@ module.exports = {
helpers: false,
},
],
["@babel/plugin-proposal-private-methods", { "loose": true }],
],
},
},
},
<% if options["use-postcss"] %>
<% if site.uses_postcss? %>
{
test: /\.(s[ac]|c)ss$/,
use: [
Expand Down Expand Up @@ -119,4 +128,4 @@ module.exports = {
},
],
},
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,13 @@ def collections_path
@collections_path ||= dir_str.empty? ? source : in_source_dir(dir_str)
end

# Whether or not a site uses PostCSS to process stylesheets.
#
# @return [Boolean] true if `postcss.config.js` exists, false if not
def uses_postcss?
File.exist?(in_root_dir("postcss.config.js"))
end

private

# Disable Marshaling cache to disk in Safe Mode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
error_message = "#{"postcss.config.js".bold} not found. Please configure postcss in your project."

@logger.error "\nError:".red, "🚨 #{error_message}"
@logger.info "\nFor new projects, you can use #{"bridgetown new my_project --use-postcss".bold.blue}\n"
@logger.info "\nRun #{"bridgetown webpack enable-postcss".bold.blue} to set it up.\n"

return
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
# frozen_string_literal: true

# rubocop:disable all

TEMPLATE_PATH = File.expand_path("./tailwindcss", __dir__)

unless File.exist?("postcss.config.js")
error_message = "#{"postcss.config.js".bold} not found. Please configure postcss in your project."

@logger.error "\nError:".red, "🚨 #{error_message}"
@logger.info "\nFor new projects, you can use #{"bridgetown new my_project --use-postcss".bold.blue}\n"
@logger.info "\nRun #{"bridgetown webpack enable-postcss".bold.blue} to set it up.\n"

return
end
Expand All @@ -23,5 +21,3 @@
File.read("#{TEMPLATE_PATH}/css_imports.css")

run "bundle exec bridgetown configure purgecss"

# rubocop:enable all
14 changes: 14 additions & 0 deletions bridgetown-core/test/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,20 @@ def refute_exist(filename, msg = nil)
msg = message(msg) { "Expected '#{filename}' not to exist" }
refute File.exist?(filename), msg
end

def assert_file_contains(regex, filename)
assert_exist filename

file_contents = File.read(filename)
assert_match regex, file_contents
end

def refute_file_contains(regex, filename)
assert_exist filename

file_contents = File.read(filename)
refute_match regex, file_contents
end
end

module DirectoryHelpers
Expand Down
37 changes: 14 additions & 23 deletions bridgetown-core/test/test_new_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,13 @@ def site_template_source
end

def template_config_files
["/Gemfile", "/package.json", "/webpack.config.js", "/frontend/javascript/index.js"]
["/Gemfile", "/package.json", "/frontend/javascript/index.js", "/webpack.config.js", "/webpack.defaults.js"]
end

def static_template_files
dir_contents(site_template).reject do |f|
File.extname(f) =~ %r!\.erb|\.(s[ac]|c)ss!
end
end

context "when args contains a path" do
Expand Down Expand Up @@ -50,21 +56,7 @@ def template_config_files
assert_match(%r!"start": "node start.js"!, File.read(packagejson))
end

should "display a success message" do
output = capture_output do
Bridgetown::Commands::Base.start(argumentize(@args))
end
success_message = "Your new Bridgetown site was generated in" \
" #{@path.cyan}."

assert_includes output, success_message
end

should "copy the static files for postcss configuration in site template to the new directory" do
static_template_files = dir_contents(site_template).reject do |f|
File.extname(f) =~ %r!\.erb|\.(s[ac]|c)ss!
end

postcss_config_files = ["/postcss.config.js", "/frontend/styles/index.css"]
postcss_template_files = static_template_files + postcss_config_files + template_config_files

Expand All @@ -80,10 +72,6 @@ def template_config_files
end

should "copy the static files for sass configuration in site template to the new directory" do
static_template_files = dir_contents(site_template).reject do |f|
File.extname(f) =~ %r!\.erb|\.(s[ac]|c)ss!
end

sass_config_files = ["/frontend/styles/index.scss"]
sass_template_files = static_template_files + sass_config_files + template_config_files

Expand Down Expand Up @@ -124,18 +112,21 @@ def template_config_files

should "force created folder" do
capture_output { Bridgetown::Commands::Base.start(argumentize(@args)) }

output = capture_output do
Bridgetown::Commands::Base.start(argumentize("#{@args} --force"))
end
assert_match %r!new Bridgetown site was generated in!, output

refute_match %r!try again with `--force` to proceed and overwrite any files.!, output
assert_match %r!identical!, output
end

should "skip bundle install when opted to" do
output = capture_output do
capture_output do
Bridgetown::Commands::Base.start(argumentize("#{@args} --skip-bundle"))
end
bundle_message = "Bundle install skipped."
assert_includes output, bundle_message

refute_exist File.join(@full_path, "Gemfile.lock")
end
end

Expand Down
81 changes: 81 additions & 0 deletions bridgetown-core/test/test_webpack_command.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# frozen_string_literal: true

require "helper"

class TestWebpackCommand < BridgetownUnitTest
def webpack_defaults
File.join(@full_path, "webpack.defaults.js")
end

def webpack_config
File.join(@full_path, "webpack.config.js")
end

context "the webpack command" do
setup do
@path = "new-site"
@full_path = File.expand_path(@path, Dir.pwd)

capture_stdout { Bridgetown::Commands::Base.start(["new", @path]) }
@cmd = Bridgetown::Commands::Webpack.new
end

teardown do
FileUtils.rm_r @full_path if File.directory?(@full_path)
end

should "list all available actions when invoked without args" do
output = capture_stdout do
@cmd.webpack
end
assert_match %r!setup!, output
assert_match %r!update!, output
assert_match %r!enable-postcss!, output
end

should "show error when action doesn't exist" do
output = capture_stdout do
@cmd.invoke(:webpack, ["qwerty"])
end

assert_match %r!Please enter a valid action!, output
end

should "setup webpack defaults and config" do
File.delete webpack_defaults # Delete the file created during setup

@cmd.inside(@full_path) do
capture_stdout { @cmd.invoke(:webpack, ["setup"]) }
end

assert_exist webpack_defaults
assert_exist webpack_config
end

should "update webpack config" do
webpack_defaults = File.join(@full_path, "webpack.defaults.js")
File.write(webpack_defaults, "OLD_VERSION")

@cmd.inside(@full_path) do
capture_stdout { @cmd.invoke(:webpack, ["update"]) }
end

assert_file_contains %r!module.exports!, webpack_defaults
refute_file_contains %r!OLD_VERSION!, webpack_defaults
end

# TODO: Figure out how to make this test pass
# Info: https://github.com/bridgetownrb/bridgetown/pull/270#issuecomment-841709898

# should "enable postcss in webpack config" do
# webpack_defaults = File.join(@full_path, "webpack.defaults.js")
# refute_file_contains %r!postcss-loader!, webpack_defaults

# @cmd.inside(@full_path) do
# capture_stdout { @cmd.invoke(:webpack, ["enable-postcss"]) }
# end

# assert_file_contains %r!postcss-loader!, webpack_defaults
# end
end
end
1 change: 1 addition & 0 deletions bridgetown-website/src/_docs/command-line-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ You can use this command in a number of ways:
* `bridgetown help` - Shows help, optionally for a given subcommand, e.g. `bridgetown help build`.
* `bridgetown doctor` - Outputs any deprecation or configuration issues.
* `bridgetown clean` - Removes all generated files: destination folder, metadata file, and Bridgetown caches.
* `bridgetown webpack ACTION` - Allows you to perform actions such as `update` on your project's Webpack configuration. Invoke without arguments to see all available actions.

Typically you'll use `bridgetown serve` while developing locally and
`bridgetown build` when you need to generate the site for production*.
Expand Down
Loading

0 comments on commit 5a95144

Please sign in to comment.