shopify_theme_builder 0.3.0 → 0.4.0
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.
- checksums.yaml +4 -4
- data/README.md +43 -3
- data/lib/shopify_theme_builder/command_line.rb +4 -1
- data/lib/shopify_theme_builder/filewatcher.rb +26 -0
- data/lib/shopify_theme_builder/liquid_processor.rb +2 -0
- data/lib/shopify_theme_builder/version.rb +1 -1
- data/lib/shopify_theme_builder/watcher.rb +112 -14
- data/lib/shopify_theme_builder.rb +4 -59
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 96de2b7ebf1688b16c967eb0a10fc193b0ba49064f0612a2a8ae7b73d8ff5ca4
|
|
4
|
+
data.tar.gz: e8db2e1b3643c1f2b479a4e87c03c00e1c2c8e3354ec7914dca566eabab82746
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1bbc6a322bd5a4bb4156e5692c49fa7358b962da211453289a9e9ad7bb419d76b0e28508b4fa41ec6f6eb662436d3b79c16d4e5a6a2ae46d130cb79b9faae1b4
|
|
7
|
+
data.tar.gz: ce8c3198cc5d190ca41d7e1e46f69a3c59fa3649735d74c11bcc42c37eefb950723484453e6fd909785273323c257cab39711eafbb4a5bec9da3e19d47be3ec1
|
data/README.md
CHANGED
|
@@ -33,6 +33,11 @@ _components/
|
|
|
33
33
|
schema.json
|
|
34
34
|
style.css
|
|
35
35
|
index.js
|
|
36
|
+
controllers.js
|
|
37
|
+
assets/
|
|
38
|
+
tailwind-output.css
|
|
39
|
+
tailwind.css
|
|
40
|
+
controllers.js
|
|
36
41
|
blocks/
|
|
37
42
|
button.liquid
|
|
38
43
|
```
|
|
@@ -43,6 +48,34 @@ All files inside the `button` folder will be compiled into a single `button.liqu
|
|
|
43
48
|
|
|
44
49
|
ShopifyThemeBuilder also supports Tailwind CSS integration. You can specify an input CSS file that includes Tailwind directives and an output CSS file where the compiled styles will be saved. The watcher will automatically run the Tailwind build process whenever changes are detected in the components folder.
|
|
45
50
|
|
|
51
|
+
## Stimulus JS Support
|
|
52
|
+
|
|
53
|
+
ShopifyThemeBuilder supports Stimulus JS integration. You can specify an output JavaScript file where the compiled Stimulus controllers will be saved. The watcher will automatically compile the Stimulus controllers whenever changes are detected in the components folder.
|
|
54
|
+
|
|
55
|
+
### How to create Stimulus controllers
|
|
56
|
+
|
|
57
|
+
To create Stimulus controllers, create a `controller.js` file inside your component folder. For example:
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
_components/
|
|
61
|
+
my_component/
|
|
62
|
+
controller.js
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The content of the `controller.js` file should follow the Stimulus controller structure. For example:
|
|
66
|
+
|
|
67
|
+
```javascript
|
|
68
|
+
class HelloController extends Controller {
|
|
69
|
+
connect() {
|
|
70
|
+
console.log("My component controller connected")
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
Stimulus.register("hello", HelloController)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
When the watcher runs, it will compile all `controller.js` files from your components into a single JavaScript file that can be included in your Shopify theme.
|
|
78
|
+
|
|
46
79
|
## Installation
|
|
47
80
|
|
|
48
81
|
Install the gem and add to the application's Gemfile by executing:
|
|
@@ -61,9 +94,10 @@ bundle exec theme-builder watch
|
|
|
61
94
|
|
|
62
95
|
You can customize multiple options when running the watcher:
|
|
63
96
|
- `--folders`: Specify one or more folders to watch (default is `_components`).
|
|
64
|
-
- `--tailwind-input-file`: Specify the Tailwind CSS input file (default is
|
|
65
|
-
- `--tailwind-output-file`: Specify the Tailwind CSS output file (default is
|
|
97
|
+
- `--tailwind-input-file`: Specify the Tailwind CSS input file (default is `./assets/tailwind.css`).
|
|
98
|
+
- `--tailwind-output-file`: Specify the Tailwind CSS output file (default is `./assets/tailwind-output.css`).
|
|
66
99
|
- `--skip-tailwind`: Skip the Tailwind CSS build process (default is `false`).
|
|
100
|
+
- `--stimulus-output-file`: Specify the Stimulus JS output file (default is `./assets/controllers.js`).
|
|
67
101
|
|
|
68
102
|
If you need help with all available options, or how to set them, run:
|
|
69
103
|
|
|
@@ -79,6 +113,12 @@ The watcher will create a CSS file that can be included in your Shopify theme la
|
|
|
79
113
|
{{ 'tailwind-output.css' | asset_url | stylesheet_tag }}
|
|
80
114
|
```
|
|
81
115
|
|
|
116
|
+
And a JavaScript file that can be included in your Shopify theme layout in this way:
|
|
117
|
+
|
|
118
|
+
```liquid
|
|
119
|
+
<script type="module" src="{{ 'controllers.js' | asset_url }}"></script>
|
|
120
|
+
```
|
|
121
|
+
|
|
82
122
|
## Development
|
|
83
123
|
|
|
84
124
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
@@ -88,7 +128,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
|
88
128
|
## Next Steps
|
|
89
129
|
|
|
90
130
|
- [x] Run the tailwind build process automatically.
|
|
91
|
-
- [
|
|
131
|
+
- [x] Add Stimulus JS support.
|
|
92
132
|
- [ ] Create a command to build an example component with all the files.
|
|
93
133
|
- [ ] Decompile existing Shopify files into components structure (?).
|
|
94
134
|
|
|
@@ -11,12 +11,15 @@ module ShopifyThemeBuilder
|
|
|
11
11
|
method_option :tailwind_output_file, type: :string, default: "./assets/tailwind-output.css",
|
|
12
12
|
desc: "Tailwind CSS output file"
|
|
13
13
|
method_option :skip_tailwind, type: :boolean, default: false, desc: "Skip Tailwind CSS processing"
|
|
14
|
+
method_option :stimulus_output_file, type: :string, default: "./assets/controllers.js",
|
|
15
|
+
desc: "Stimulus controllers output file"
|
|
14
16
|
def watch
|
|
15
17
|
ShopifyThemeBuilder.watch(
|
|
16
18
|
folders_to_watch: options[:folders],
|
|
17
19
|
tailwind_input_file: options[:tailwind_input_file],
|
|
18
20
|
tailwind_output_file: options[:tailwind_output_file],
|
|
19
|
-
skip_tailwind: options[:skip_tailwind]
|
|
21
|
+
skip_tailwind: options[:skip_tailwind],
|
|
22
|
+
stimulus_output_file: options[:stimulus_output_file]
|
|
20
23
|
)
|
|
21
24
|
end
|
|
22
25
|
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "filewatcher"
|
|
4
|
+
|
|
5
|
+
module ShopifyThemeBuilder
|
|
6
|
+
# It wraps the Filewatcher functionality to monitor file changes.
|
|
7
|
+
# It delegates method calls to the underlying Filewatcher instance.
|
|
8
|
+
# Check: https://github.com/filewatcher/filewatcher
|
|
9
|
+
class Filewatcher
|
|
10
|
+
def initialize(...)
|
|
11
|
+
@filewatcher = ::Filewatcher.new(...)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def method_missing(name, ...)
|
|
15
|
+
if @filewatcher.respond_to?(name)
|
|
16
|
+
@filewatcher.send(name, ...)
|
|
17
|
+
else
|
|
18
|
+
super
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def respond_to_missing?(name, include_private)
|
|
23
|
+
@filewatcher.respond_to?(name) || super
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -1,27 +1,125 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "
|
|
3
|
+
require "fileutils"
|
|
4
|
+
require "tailwindcss/ruby"
|
|
4
5
|
|
|
5
6
|
module ShopifyThemeBuilder
|
|
6
|
-
# Watcher
|
|
7
|
-
#
|
|
8
|
-
# It delegates method calls to the underlying Filewatcher instance.
|
|
9
|
-
# Check: https://github.com/filewatcher/filewatcher
|
|
7
|
+
# Watcher is responsible for monitoring specified folders for changes
|
|
8
|
+
# and triggering the build process for Shopify theme components.
|
|
10
9
|
class Watcher
|
|
11
|
-
def initialize(
|
|
12
|
-
|
|
10
|
+
def initialize(
|
|
11
|
+
folders_to_watch: ["_components"],
|
|
12
|
+
tailwind_input_file: "./assets/tailwind.css",
|
|
13
|
+
tailwind_output_file: "./assets/tailwind-output.css",
|
|
14
|
+
skip_tailwind: false,
|
|
15
|
+
stimulus_output_file: "./assets/controllers.js"
|
|
16
|
+
)
|
|
17
|
+
@folders_to_watch = folders_to_watch
|
|
18
|
+
@tailwind_input_file = tailwind_input_file
|
|
19
|
+
@tailwind_output_file = tailwind_output_file
|
|
20
|
+
@skip_tailwind = skip_tailwind
|
|
21
|
+
@stimulus_output_file = stimulus_output_file
|
|
13
22
|
end
|
|
14
23
|
|
|
15
|
-
def
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
24
|
+
def watch
|
|
25
|
+
create_folders
|
|
26
|
+
|
|
27
|
+
initial_build
|
|
28
|
+
|
|
29
|
+
create_tailwind_file
|
|
30
|
+
|
|
31
|
+
run_tailwind
|
|
32
|
+
|
|
33
|
+
run_stimulus
|
|
34
|
+
|
|
35
|
+
watch_folders
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def create_folders
|
|
41
|
+
puts "Creating necessary folders..."
|
|
42
|
+
|
|
43
|
+
FileUtils.mkdir_p(@folders_to_watch)
|
|
44
|
+
FileUtils.mkdir_p("sections")
|
|
45
|
+
FileUtils.mkdir_p("blocks")
|
|
46
|
+
FileUtils.mkdir_p("snippets")
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def initial_build
|
|
50
|
+
puts "Doing an initial build..."
|
|
51
|
+
|
|
52
|
+
@folders_to_watch.each do |folder|
|
|
53
|
+
Builder.new(files_to_process: Dir.glob("#{folder}/**/*.*")).build
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def watch_folders
|
|
58
|
+
puts "Watching for changes in '#{@folders_to_watch.join(", ")}' folders..."
|
|
59
|
+
|
|
60
|
+
Filewatcher.new(@folders_to_watch).watch do |changes|
|
|
61
|
+
changes.each_key do |filename|
|
|
62
|
+
relative_filename = filename.gsub("#{Dir.pwd}/", "")
|
|
63
|
+
|
|
64
|
+
Builder.new(files_to_process: [relative_filename]).build if relative_filename.start_with?(*@folders_to_watch)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
run_tailwind
|
|
68
|
+
|
|
69
|
+
run_stimulus if changes.keys.any? { |f| f.end_with?("controller.js") }
|
|
20
70
|
end
|
|
21
71
|
end
|
|
22
72
|
|
|
23
|
-
def
|
|
24
|
-
|
|
73
|
+
def run_tailwind
|
|
74
|
+
return if @skip_tailwind
|
|
75
|
+
|
|
76
|
+
puts "Running Tailwind CSS build..."
|
|
77
|
+
|
|
78
|
+
system("tailwindcss", "-i", @tailwind_input_file, "-o", @tailwind_output_file)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def create_tailwind_file
|
|
82
|
+
return if @skip_tailwind || File.exist?(@tailwind_input_file)
|
|
83
|
+
|
|
84
|
+
puts "Creating default Tailwind CSS input file at '#{@tailwind_input_file}'..."
|
|
85
|
+
|
|
86
|
+
FileUtils.mkdir_p(File.dirname(@tailwind_input_file))
|
|
87
|
+
File.write @tailwind_input_file, tailwind_base_config
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def tailwind_base_config
|
|
91
|
+
return '@import "tailwindcss";' if Gem::Version.new(Tailwindcss::Ruby::VERSION) >= Gem::Version.new("4.0.0")
|
|
92
|
+
|
|
93
|
+
system("tailwindcss", "init") unless File.exist?("tailwind.config.js")
|
|
94
|
+
|
|
95
|
+
<<~TAILWIND.strip
|
|
96
|
+
@tailwind base;
|
|
97
|
+
@tailwind components;
|
|
98
|
+
@tailwind utilities;
|
|
99
|
+
TAILWIND
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def run_stimulus
|
|
103
|
+
controllers_files = @folders_to_watch.map { Dir.glob("#{_1}/**/controller.js") }.flatten
|
|
104
|
+
|
|
105
|
+
return if controllers_files.empty?
|
|
106
|
+
|
|
107
|
+
puts "Building Stimulus controllers..."
|
|
108
|
+
|
|
109
|
+
content = +base_stimulus_content
|
|
110
|
+
|
|
111
|
+
controllers_files.each do |file|
|
|
112
|
+
content << File.read(file)
|
|
113
|
+
content << "\n"
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
FileUtils.mkdir_p(File.dirname(@stimulus_output_file))
|
|
117
|
+
File.write(@stimulus_output_file, content.strip)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def base_stimulus_content
|
|
121
|
+
"import { Application, Controller } from \"https://unpkg.com/@hotwired/stimulus/dist/stimulus.js\"\n\
|
|
122
|
+
window.Stimulus = Application.start()\n\n"
|
|
25
123
|
end
|
|
26
124
|
end
|
|
27
125
|
end
|
|
@@ -1,70 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "fileutils"
|
|
4
|
-
require "logger"
|
|
5
3
|
require_relative "shopify_theme_builder/version"
|
|
6
|
-
require_relative "shopify_theme_builder/
|
|
4
|
+
require_relative "shopify_theme_builder/filewatcher"
|
|
7
5
|
require_relative "shopify_theme_builder/liquid_processor"
|
|
8
6
|
require_relative "shopify_theme_builder/builder"
|
|
9
7
|
require_relative "shopify_theme_builder/command_line"
|
|
8
|
+
require_relative "shopify_theme_builder/watcher"
|
|
10
9
|
|
|
11
10
|
# The main module for ShopifyThemeBuilder.
|
|
12
11
|
module ShopifyThemeBuilder
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
folders_to_watch: ["_components"],
|
|
16
|
-
tailwind_input_file: "./assets/tailwind.css",
|
|
17
|
-
tailwind_output_file: "./assets/tailwind-output.css",
|
|
18
|
-
skip_tailwind: false
|
|
19
|
-
)
|
|
20
|
-
create_folders(folders_to_watch)
|
|
21
|
-
|
|
22
|
-
initial_build(folders_to_watch)
|
|
23
|
-
|
|
24
|
-
run_tailwind(tailwind_input_file, tailwind_output_file) unless skip_tailwind
|
|
25
|
-
|
|
26
|
-
watch_folders(folders_to_watch) do
|
|
27
|
-
run_tailwind(tailwind_input_file, tailwind_output_file) unless skip_tailwind
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
private
|
|
32
|
-
|
|
33
|
-
def create_folders(folders_to_watch)
|
|
34
|
-
puts "Creating necessary folders..."
|
|
35
|
-
|
|
36
|
-
FileUtils.mkdir_p(folders_to_watch)
|
|
37
|
-
FileUtils.mkdir_p("sections")
|
|
38
|
-
FileUtils.mkdir_p("blocks")
|
|
39
|
-
FileUtils.mkdir_p("snippets")
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def initial_build(folders_to_watch)
|
|
43
|
-
puts "Doing an initial build..."
|
|
44
|
-
|
|
45
|
-
folders_to_watch.each do |folder|
|
|
46
|
-
Builder.new(files_to_process: Dir.glob("#{folder}/**/*.*")).build
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def watch_folders(folders_to_watch)
|
|
51
|
-
puts "Watching for changes in '#{folders_to_watch.join(", ")}' folders..."
|
|
52
|
-
|
|
53
|
-
Watcher.new(folders_to_watch).watch do |changes|
|
|
54
|
-
changes.each_key do |filename|
|
|
55
|
-
relative_filename = filename.gsub("#{Dir.pwd}/", "")
|
|
56
|
-
|
|
57
|
-
Builder.new(files_to_process: [relative_filename]).build if relative_filename.start_with?(*folders_to_watch)
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
yield if block_given?
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def run_tailwind(tailwind_input_file, tailwind_output_file)
|
|
65
|
-
puts "Running Tailwind CSS build..."
|
|
66
|
-
|
|
67
|
-
system("tailwindcss", "-i", tailwind_input_file, "-o", tailwind_output_file)
|
|
68
|
-
end
|
|
12
|
+
def self.watch(...)
|
|
13
|
+
Watcher.new(...).watch
|
|
69
14
|
end
|
|
70
15
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: shopify_theme_builder
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Massimiliano Lattanzio
|
|
@@ -87,6 +87,7 @@ files:
|
|
|
87
87
|
- lib/shopify_theme_builder.rb
|
|
88
88
|
- lib/shopify_theme_builder/builder.rb
|
|
89
89
|
- lib/shopify_theme_builder/command_line.rb
|
|
90
|
+
- lib/shopify_theme_builder/filewatcher.rb
|
|
90
91
|
- lib/shopify_theme_builder/liquid_processor.rb
|
|
91
92
|
- lib/shopify_theme_builder/version.rb
|
|
92
93
|
- lib/shopify_theme_builder/watcher.rb
|