tailwindcss-rails 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,12 @@
1
+ APPLICATION_LAYOUT_PATH = Rails.root.join("app/views/layouts/application.html.erb")
2
+
3
+ if APPLICATION_LAYOUT_PATH.exist?
4
+ say "Add Tailwindcss include tags in application layout"
5
+ insert_into_file Rails.root.join("app/views/layouts/application.html.erb").to_s, %(\n <%= stylesheet_link_tag "tailwind" %>), before: /^\s*<%= stylesheet_link_tag/
6
+ else
7
+ say "Default application.html.erb is missing!", :red
8
+ say %( Add <%= stylesheet_link_tag "tailwind" %> within the <head> tag in your custom layout.)
9
+ end
10
+
11
+ say "Turn on purging of unused css classes in production"
12
+ gsub_file Rails.root.join("config/environments/production.rb"), /^\s+#?\s+config.assets.css_compressor =.*$/, %( config.assets.css_compressor = :purger)
@@ -0,0 +1,5 @@
1
+ module Tailwindcss
2
+ end
3
+
4
+ require "tailwindcss/version"
5
+ require "tailwindcss/engine"
@@ -0,0 +1,19 @@
1
+ require "tailwindcss/purger"
2
+
3
+ class Tailwindcss::Compressor
4
+ def self.instance
5
+ @instance ||= new
6
+ end
7
+
8
+ def self.call(input)
9
+ instance.call(input)
10
+ end
11
+
12
+ def initialize(options = {})
13
+ @options = { files_with_class_names: Rails.root.glob("app/views/**/*.*") + Rails.root.glob("app/helpers/**/*.rb") }.merge(options).freeze
14
+ end
15
+
16
+ def call(input)
17
+ { data: Tailwindcss::Purger.purge(input[:data], keeping_class_names_from_files: @options[:files_with_class_names]) }
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ require "tailwindcss/compressor"
2
+
3
+ module Tailwindcss
4
+ class Engine < ::Rails::Engine
5
+ initializer "tailwindcss.compressor" do
6
+ Sprockets.register_compressor "text/css", :purger, Tailwindcss::Compressor
7
+ end
8
+
9
+ initializer "tailwindcss.assets" do
10
+ Rails.application.config.assets.precompile += %w( tailwind )
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,61 @@
1
+ class Tailwindcss::Purger
2
+ CLASS_NAME_PATTERN = /([:A-Za-z0-9_-]+[\.]*[\\\/:A-Za-z0-9_-]*)/
3
+ OPENING_SELECTOR_PATTERN = /\..*\{/
4
+ CLOSING_SELECTOR_PATTERN = /\s*\}/
5
+ NEWLINE = "\n"
6
+
7
+ attr_reader :keep_these_class_names
8
+
9
+ class << self
10
+ def purge(input, keeping_class_names_from_files:)
11
+ new(extract_class_names_from(keeping_class_names_from_files)).purge(input)
12
+ end
13
+
14
+ def extract_class_names(string)
15
+ string.scan(CLASS_NAME_PATTERN).flatten.uniq.sort
16
+ end
17
+
18
+ def extract_class_names_from(files)
19
+ Array(files).flat_map { |file| extract_class_names(file.read) }.uniq.sort
20
+ end
21
+ end
22
+
23
+ def initialize(keep_these_class_names)
24
+ @keep_these_class_names = keep_these_class_names
25
+ end
26
+
27
+ def purge(input)
28
+ inside_kept_selector = inside_ignored_selector = false
29
+ output = []
30
+
31
+ input.split(NEWLINE).each do |line|
32
+ case
33
+ when inside_kept_selector
34
+ output << line
35
+ inside_kept_selector = false if line =~ CLOSING_SELECTOR_PATTERN
36
+ when inside_ignored_selector
37
+ inside_ignored_selector = false if line =~ CLOSING_SELECTOR_PATTERN
38
+ when line =~ OPENING_SELECTOR_PATTERN
39
+ if keep_these_class_names.include? class_name_in(line)
40
+ output << line
41
+ inside_kept_selector = true
42
+ else
43
+ inside_ignored_selector = true
44
+ end
45
+ else
46
+ output << line
47
+ end
48
+ end
49
+
50
+ separated_without_empty_lines(output)
51
+ end
52
+
53
+ private
54
+ def class_name_in(line)
55
+ CLASS_NAME_PATTERN.match(line)[1].remove("\\")
56
+ end
57
+
58
+ def separated_without_empty_lines(output)
59
+ output.reject { |line| line.strip.empty? }.join(NEWLINE)
60
+ end
61
+ end
@@ -0,0 +1,3 @@
1
+ module Tailwindcss
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,18 @@
1
+ namespace :tailwindcss do
2
+ desc "Install Tailwind CSS into the app"
3
+ task :install do
4
+ system "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{File.expand_path("../install/tailwindcss.rb", __dir__)}"
5
+ end
6
+
7
+ desc "Show the list of class names being kept in Tailwind CSS"
8
+ task :keeping_class_names do
9
+ puts Tailwindcss::Purger.extract_class_names_from(Rails.root.glob("app/views/**/*.*") + Rails.root.glob("app/helpers/**/*.rb"))
10
+ end
11
+
12
+ desc "Show Tailwind CSS styles that are left after purging unused class names"
13
+ task :preview_purge do
14
+ puts Tailwindcss::Purger.purge \
15
+ Pathname.new(__FILE__).join("../../../app/assets/stylesheets/tailwind.css").read,
16
+ keeping_class_names_from_files: Rails.root.glob("app/views/**/*.*") + Rails.root.glob("app/helpers/**/*.rb")
17
+ end
18
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tailwindcss-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - David Heinemeier Hansson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-01-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 6.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 6.0.0
27
+ description:
28
+ email: david@loudthinking.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - MIT-LICENSE
34
+ - README.md
35
+ - Rakefile
36
+ - app/assets/stylesheets/tailwind.css
37
+ - lib/install/tailwindcss.rb
38
+ - lib/tailwindcss-rails.rb
39
+ - lib/tailwindcss/compressor.rb
40
+ - lib/tailwindcss/engine.rb
41
+ - lib/tailwindcss/purger.rb
42
+ - lib/tailwindcss/version.rb
43
+ - lib/tasks/tailwindcss_tasks.rake
44
+ homepage: https://github.com/rails/tailwindcss-rails
45
+ licenses:
46
+ - MIT
47
+ metadata:
48
+ homepage_uri: https://github.com/rails/tailwindcss-rails
49
+ post_install_message:
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ requirements: []
64
+ rubygems_version: 3.1.2
65
+ signing_key:
66
+ specification_version: 4
67
+ summary: Integrate Tailwind CSS with the asset pipeline in Rails.
68
+ test_files: []