Class: Proscenium::Importer

Inherits:
ActiveSupport::CurrentAttributes
  • Object
show all
Defined in:
lib/proscenium/importer.rb

Constant Summary collapse

JS_EXTENSIONS =
%w[.tsx .ts .jsx .js].freeze
CSS_EXTENSIONS =
%w[.module.css .css].freeze

Class Method Summary collapse

Class Method Details

.css_imported?Boolean

Returns:

  • (Boolean)


156
157
158
# File 'lib/proscenium/importer.rb', line 156

def css_imported?
  imported&.keys&.any? { |x| x.end_with?(*CSS_EXTENSIONS) }
end

.each_javascript(delete: false) ⇒ Object



144
145
146
147
148
149
150
151
152
153
154
# File 'lib/proscenium/importer.rb', line 144

def each_javascript(delete: false)
  return if imported.blank?

  blk = proc do |key, options|
    if key.end_with?(*JS_EXTENSIONS)
      yield(key, options)
      true
    end
  end
  delete ? imported.delete_if(&blk) : imported.each(&blk)
end

.each_stylesheet(delete: false) ⇒ Object



131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/proscenium/importer.rb', line 131

def each_stylesheet(delete: false)
  return if imported.blank?

  blk = proc do |key, options|
    if key.end_with?(*CSS_EXTENSIONS)
      yield(key, options)
      true
    end
  end

  delete ? imported.delete_if(&blk) : imported.each(&blk)
end

.import(filepath = nil, sideloaded: false) ⇒ String|nil

Import the given ‘filepath`. This is idempotent - it will never include duplicates.

Parameters:

  • filepath (String) (defaults to: nil)

    Absolute URL path (relative to Rails root) of the file to import. Should be the actual asset file, eg. app.css, some/component.js.

Returns:

  • (String|nil)

    the digest of the imported file path if a css module (*.module.css).



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/proscenium/importer.rb', line 27

def import(filepath = nil, sideloaded: false, **)
  self.imported ||= {}

  filepath = "/node_modules/#{filepath}" if filepath.start_with?('@rubygems/')
  css_module = filepath.match?(/\.module(-\$[a-z0-9]+\$)?\.css$/i)

  unless self.imported.key?(filepath)
    if sideloaded
      ActiveSupport::Notifications.instrument 'sideload.proscenium', identifier: filepath,
                                                                     sideloaded: do
        self.imported[filepath] = { ** }
        self.imported[filepath][:digest] ||= Utils.digest(filepath) if css_module

        if self.imported[filepath][:digest].is_a?(Proc)
          self.imported[filepath][:digest] = self.imported[filepath][:digest].call
        end
      end
    else
      self.imported[filepath] = { ** }
      self.imported[filepath][:digest] ||= Utils.digest(filepath) if css_module

      if self.imported[filepath][:digest].is_a?(Proc)
        self.imported[filepath][:digest] = self.imported[filepath][:digest].call
      end
    end
  end

  css_module ? self.imported[filepath][:digest] : nil
end

.imported?(filepath = nil) ⇒ Boolean

Returns:

  • (Boolean)


164
165
166
# File 'lib/proscenium/importer.rb', line 164

def imported?(filepath = nil)
  filepath ? imported&.key?(filepath) : !imported.blank?
end

.js_imported?Boolean

Returns:

  • (Boolean)


160
161
162
# File 'lib/proscenium/importer.rb', line 160

def js_imported?
  imported&.keys&.any? { |x| x.end_with?(*JS_EXTENSIONS) }
end

.sideload(filepath, **options) ⇒ Object

Sideloads JS and CSS assets for the given Ruby filepath.

Any files with the same base name and matching a supported extension will be sideloaded. Only one JS and one CSS file will be sideloaded, with the first match used in the following order:

- JS extensions: .tsx, .ts, .jsx, and .js.
- CSS extensions: .css.module, and .css.

Example:

- `app/views/layouts/application.rb`
- `app/views/layouts/application.css`
- `app/views/layouts/application.js`
- `app/views/layouts/application.tsx`

A request to sideload ‘app/views/layouts/application.rb` will result in `application.css` and `application.tsx` being sideloaded. `application.js` will not be sideloaded because the `.tsx` extension is matched first.

Parameters:

  • filepath (Pathname)

    Absolute file system path of the Ruby file to sideload.

  • options (Hash)

    Options to pass to ‘import`.



77
78
79
80
81
82
# File 'lib/proscenium/importer.rb', line 77

def sideload(filepath, **options)
  return if !Proscenium.config.side_load || (options[:js] == false && options[:css] == false)

  sideload_js(filepath, **options) unless options[:js] == false
  sideload_css(filepath, **options) unless options[:css] == false
end

.sideload_css(filepath) ⇒ Object



88
89
90
# File 'lib/proscenium/importer.rb', line 88

def sideload_css(filepath, **)
  _sideload(filepath, ['.css'], **)
end

.sideload_css_module(filepath) ⇒ Object



92
93
94
# File 'lib/proscenium/importer.rb', line 92

def sideload_css_module(filepath, **)
  _sideload(filepath, ['.module.css'], **)
end

.sideload_js(filepath) ⇒ Object



84
85
86
# File 'lib/proscenium/importer.rb', line 84

def sideload_js(filepath, **)
  _sideload(filepath, JS_EXTENSIONS, **)
end