jspm-rails 0.1.0 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d28f515c7c82e31da220cc7dca25540b499ad2f3ca9f98f0b9e9092dc31940a6
4
- data.tar.gz: 2fa31fa61006a069f3d8876ce5c68e60e0e766852749ff062656a1436e67f7e6
3
+ metadata.gz: 2066a105c29bf4cebd19a25c1afa9ac3bfb7530b080cd5f347ed1c69e3cd56b2
4
+ data.tar.gz: 1e89f49cd667a1b7771b90b2df5a8d36918d0cdb78334fe6cdee6d831d470fcc
5
5
  SHA512:
6
- metadata.gz: 1dc7843f5631aa615fb7797120c6d047c74808ff08d6ec429db85b3ef1efff1a61419a35f5dd10c644df650cfd9484ea20a455ecd8ef25151714eb959678e2fa
7
- data.tar.gz: 2074d972cf1e2a2fb11a8753df72228a5cb1984b43455c906e23c176d3bb8d5a110e846c43ebffe4c267544e5faedc16fab871050e9bc9fe70197bb1eee16a3b
6
+ metadata.gz: 4253a93277d3368d3e2e34fe023aeee5ac6d74090417941e36056ea65ccffb3f9465909e036ae52a00caa3bb403ef0b3d9ee7e6de26299b0f741487baf11fa30
7
+ data.tar.gz: 330b9d72f4d2b528aa4701d655cc066adf83da4fbfef4f718eb472c624d0398f52542e05ee84b97bfc3b25d4219f227e25ba2f02bc7aab9bd524cefc8ddae6ef
data/CHANGELOG.md CHANGED
@@ -1,9 +1,20 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.0 (unreleased)
3
+ ## 0.3.0 (unreleased)
4
4
 
5
- - `bin/rails jspm:install` traces `app/javascript/application.js` with jspm and vendors every module it reaches. It copies npm dependencies' stylesheets, fonts and images. `config/importmap.json` locks versions, and `package-lock.json` overrides it for packages installed with npm.
5
+ - Names every module in `app/javascript` in the import map, so stimulus-rails's `eagerLoadControllersFrom` finds controllers.
6
+
7
+ ## 0.2.0 (unreleased)
8
+
9
+ - Reads Yarn 1's `yarn.lock` as well as `package-lock.json`.
10
+ - No longer copies npm packages' stylesheets, fonts and images. Put the directories you use on Propshaft's load path instead.
11
+ - A package in the lockfile wins over a gem's file with the same name.
12
+
13
+ ## 0.1.0 (2026-11-13)
14
+
15
+ - `bin/rails jspm:install` traces `app/javascript/application.js` with jspm and vendors every module it reaches. `config/importmap.json` locks versions, and `package-lock.json` overrides it for packages installed with npm.
6
16
  - `javascript_jspm_tags` renders the import map with Propshaft's digested paths, preloads, and the entry module.
7
17
  - Modules on Propshaft's load path, including engines', are importable by asset name, the way importmap-rails pins work.
18
+ - Modules on Propshaft's load path, including engines', are importable by asset name, the way importmap-rails pins work.
8
19
  - `bin/rails jspm:check` fails when `config/importmap.json` or `vendor/jspm` is out of date.
9
20
  - Warns when the import map can't match `package-lock.json`.
data/README.md CHANGED
@@ -1,10 +1,4 @@
1
- ```
2
- _ _ _
3
- (_) ___ _ __ _ __ _ _ __ _ (_)| | ___
4
- | |(_-<| '_ \| ' \ ___ | '_|/ _` || || |(_-<
5
- _/ |/__/| .__/|_|_|_||___||_| \__,_||_||_|/__/
6
- |__/ |_|
7
- ```
1
+ <p align="center"><img src="docs/banner.svg" alt="jspm-rails" width="576"></p>
8
2
 
9
3
  [![CI](https://github.com/ClayShentrup/jspm-rails/actions/workflows/ci.yml/badge.svg)](https://github.com/ClayShentrup/jspm-rails/actions/workflows/ci.yml)
10
4
 
@@ -19,7 +13,6 @@ bin/rails jspm:install
19
13
  ```
20
14
  traced ./app/javascript/application.js
21
15
  vendored 31 modules from ga.jspm.io
22
- copied 73 assets from node_modules
23
16
  wrote config/importmap.json
24
17
  ```
25
18
 
@@ -96,6 +89,8 @@ import 'controllers' // app/javascript/controllers/index.js
96
89
  import { helper } from './helpers.js'
97
90
  ```
98
91
 
92
+ **Every module in `app/javascript` is in the import map by name,** even ones nothing imports directly, as importmap-rails's `pin_all_from` names them. So stimulus-rails's `eagerLoadControllersFrom("controllers", application)` and `lazyLoadControllersFrom` work unchanged.
93
+
99
94
  **Import modules that gems ship the same way.** Every engine's `app/assets` directories are on Propshaft's load path, so a gem's modules are importable by asset name with no setup:
100
95
 
101
96
  ```js
@@ -112,7 +107,7 @@ const { default: katex } = await import('katex')
112
107
 
113
108
  **Plain jspm works on its own.** The install resolves each package you import from jspm.io. That's the latest version, or the newest within a range you give in `package.json`'s `dependencies`, as jspm does. `config/importmap.json` is jspm's lockfile: every install keeps the versions it already holds.
114
109
 
115
- **Install a package with npm when you want more.** Its version in `package-lock.json` then overrides the import map, and you get:
110
+ **Install a package with npm or Yarn 1 when you want more.** Its version in `package-lock.json` or `yarn.lock` then overrides the import map, and you get:
116
111
 
117
112
  - Dependabot pull requests for it.
118
113
  - Its stylesheets, fonts and images in `node_modules`, at the same version as its JavaScript.
@@ -121,17 +116,19 @@ Mix the two freely. A package's JavaScript always comes from jspm.io either way.
121
116
 
122
117
  ## Stylesheets, fonts and images
123
118
 
124
- jspm.io serves JavaScript. For a package's other files, install it with npm as a dependency. The install copies the stylesheets, fonts and images of every package in `dependencies`, and their dependencies, into `vendor/jspm/<package>/`:
119
+ jspm.io serves JavaScript. For a package's other files, install it with npm and put the directory that holds them on Propshaft's load path, as Rails's generated `config/initializers/assets.rb` suggests:
125
120
 
126
- ```erb
127
- <%= stylesheet_link_tag 'katex/dist/katex' %>
121
+ ```ruby
122
+ Rails.application.config.assets.paths << Rails.root.join('node_modules/katex/dist')
128
123
  ```
129
124
 
130
- Propshaft rewrites the `url()`s in the stylesheet to digested paths, so the fonts load too. The CSS comes from npm and the JavaScript from jspm.io, both at the version in `package-lock.json`.
125
+ ```erb
126
+ <%= stylesheet_link_tag 'katex' %>
127
+ ```
131
128
 
132
- Each name starts with its package, so two packages' `style.css` never collide. `devDependencies` are build tools, so the install leaves them out.
129
+ Propshaft rewrites the `url()`s in the stylesheet to digested paths, so the fonts load too. The CSS comes from npm and the JavaScript from jspm.io, both at the version in your lockfile.
133
130
 
134
- Why copy, instead of putting `node_modules` on the load path? Propshaft checks every file on its load path for changes before each request in development. With one real app's `node_modules` (8,900 files), that took a page request from 1.4 ms to 98 ms. Production would also precompile all of `node_modules` into `public/assets`.
131
+ Add the directory you use, not the whole package or all of `node_modules`. Propshaft checks every file on its load path before each development request and precompiles every one, so `bootstrap-icons/font` (7 files) costs far less than the package (2,089).
135
132
 
136
133
  ## Keeping up to date
137
134
 
@@ -145,7 +142,7 @@ Why copy, instead of putting `node_modules` on the load path? Propshaft checks e
145
142
  bin/rails jspm:check
146
143
  ```
147
144
 
148
- It traces again without writing anything. It fails when an install would change `config/importmap.json`, for example after Dependabot bumps `package-lock.json`. It also fails when a module is missing from `vendor/jspm`, or a copied stylesheet, font or image no longer matches `node_modules`:
145
+ It traces again without writing anything. It fails when an install would change `config/importmap.json`, for example after Dependabot bumps `package-lock.json`. It also fails when a module is missing from `vendor/jspm`:
149
146
 
150
147
  ```
151
148
  stale config/importmap.json
@@ -165,7 +162,7 @@ npm installs two versions of a package when its dependents' ranges don't overlap
165
162
  ## Deploying
166
163
 
167
164
  - **Commit `config/importmap.json` and `vendor/jspm`.** `assets:precompile` digests the vendored modules like any other asset.
168
- - **Production needs no Node, no npm and no jspm.io.**
165
+ - **Production needs no jspm.io,** and no Node unless you serve stylesheets from `node_modules`, which needs your packages installed before precompiling.
169
166
  - **An `asset_host` on another origin must send `Access-Control-Allow-Origin`.** Browsers load modules and fonts across origins only with CORS.
170
167
  - **Content Security Policy works.** Every tag carries the request's nonce.
171
168
  - **Turbo reloads the page when the import map changes,** because the map's tag has `data-turbo-track="reload"`.
@@ -176,8 +173,7 @@ npm installs two versions of a package when its dependents' ranges don't overlap
176
173
 
177
174
  1. Boots the app, then traces `app/javascript/application.js` with [`@jspm/generator`](https://github.com/jspm/generator). Every module on Propshaft's load path is importable by asset name. The previous `config/importmap.json` locks versions, and `package-lock.json` pins every package npm installed. Only packages your code reaches end up in the map, so KaTeX's command-line dependency stays out.
178
175
  2. Downloads each traced module from jspm.io, with its source map, into `vendor/jspm/ga.jspm.io`.
179
- 3. Copies each npm dependency's stylesheets, fonts and images into `vendor/jspm/<package>/`.
180
- 4. Writes jspm's import map to `config/importmap.json`, with the list of modules to preload. Local modules appear as `asset:` plus their logical path, such as `asset:astrology/math_controller.js`, so the map is the same on every machine.
176
+ 3. Writes jspm's import map to `config/importmap.json`, with the list of modules to preload. Local modules appear as `asset:` plus their logical path, such as `asset:astrology/math_controller.js`, so the map is the same on every machine.
181
177
 
182
178
  `javascript_jspm_tags` renders that map for Propshaft. Propshaft serves each file under a digested name, so the helper rewrites the map's URLs:
183
179
 
@@ -239,15 +235,15 @@ Node printed the reason just above. Usually Node isn't on your `PATH`, or `@jspm
239
235
  **Modules or fonts fail to load with an asset host**
240
236
  The asset host must send `Access-Control-Allow-Origin`. See [Deploying](#deploying).
241
237
 
242
- **A package's stylesheet 404s**
243
- Install the package with npm as a dependency, not a devDependency, and run the install. See [Stylesheets, fonts and images](#stylesheets-fonts-and-images).
238
+ **A package's stylesheet raises `Propshaft::MissingAssetError`**
239
+ Add its directory to `config.assets.paths`. See [Stylesheets, fonts and images](#stylesheets-fonts-and-images).
244
240
 
245
241
  ## Development
246
242
 
247
243
  ```sh
248
244
  bundle install
249
245
  npm ci && npx playwright install chromium
250
- (cd spec/dummy && npm ci) && (cd spec/fixtures/conflicted && npm ci)
246
+ (cd spec/dummy && npm ci) && (cd spec/fixtures/conflicted && npm ci) && (cd spec/fixtures/yarn && yarn install --frozen-lockfile)
251
247
  bundle exec rake
252
248
  ```
253
249
 
data/lib/jspm/check.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fileutils'
4
3
  require 'json'
5
4
 
6
5
  module Jspm
@@ -10,11 +9,10 @@ module Jspm
10
9
  def self.call(asset_paths:, output:, root:)
11
10
  lockfile = Lockfile.read(root)
12
11
  trace = Trace.call(asset_paths:, lockfile:, root:)
13
- new(lockfile:, output:, root:, trace:).call
12
+ new(output:, root:, trace:).call
14
13
  end
15
14
 
16
- def initialize(lockfile:, output:, root:, trace:)
17
- @lockfile = lockfile
15
+ def initialize(output:, root:, trace:)
18
16
  @output = output
19
17
  @root = root
20
18
  @trace = trace
@@ -23,12 +21,10 @@ module Jspm
23
21
  def call
24
22
  written = written?
25
23
  missing = missing_modules
26
- stale_assets = stale_asset_paths
27
24
  report('stale', Paths::IMPORT_MAP) unless written
28
25
  missing.each { |path| report('missing', path) }
29
- stale_assets.each { |path| report('stale', path) }
30
26
 
31
- up_to_date = written && missing.empty? && stale_assets.empty?
27
+ up_to_date = written && missing.empty?
32
28
  if up_to_date
33
29
  report('ok', 'nothing to install')
34
30
  else
@@ -39,22 +35,13 @@ module Jspm
39
35
 
40
36
  private
41
37
 
42
- attr_reader :lockfile, :output, :root, :trace
38
+ attr_reader :output, :root, :trace
43
39
 
44
40
  def written?
45
41
  import_map_file = root.join(Paths::IMPORT_MAP)
46
42
  import_map_file.exist? && JSON.parse(import_map_file.read) == trace.import_map
47
43
  end
48
44
 
49
- def stale_asset_paths
50
- copies = Assets.copies(lockfile:, root:)
51
- stale =
52
- copies.reject do |source, target|
53
- target.file? && FileUtils.compare_file(source, target)
54
- end
55
- stale.map { |_source, target| target.relative_path_from(root).to_s }
56
- end
57
-
58
45
  def missing_modules
59
46
  vendored = trace.cdn_urls.map { |url| File.join(Paths::VENDOR, Paths.logical(url)) }
60
47
  vendored.reject { |path| root.join(path).file? }
data/lib/jspm/install.rb CHANGED
@@ -5,8 +5,7 @@ require 'json'
5
5
  require 'net/http'
6
6
 
7
7
  module Jspm
8
- # Vendors every module the trace reaches from jspm.io, copies npm
9
- # dependencies' stylesheets, fonts and images, and writes
8
+ # Vendors every module the trace reaches from jspm.io, and writes
10
9
  # config/importmap.json.
11
10
  class Install
12
11
  SOURCE_MAP = %r{//# sourceMappingURL=(?<path>\S+\.map)\s*\z}
@@ -32,16 +31,10 @@ module Jspm
32
31
  cdn = URI(Paths::CDN)
33
32
  cdn_urls = trace.cdn_urls
34
33
  Net::HTTP.start(cdn.host, cdn.port, use_ssl: true) { |http| download_all(http, cdn_urls, vendor_dir) }
35
- copies = Assets.copies(lockfile:, root:)
36
- copies.each do |source, target|
37
- target.dirname.mkpath
38
- FileUtils.cp(source, target)
39
- end
40
34
  root.join(Paths::IMPORT_MAP).write("#{JSON.pretty_generate(trace.import_map)}\n")
41
35
 
42
36
  report('traced', Paths::ENTRY_PATH)
43
37
  report('vendored', "#{cdn_urls.size} modules from ga.jspm.io")
44
- report('copied', "#{copies.size} assets from node_modules")
45
38
  report('wrote', Paths::IMPORT_MAP)
46
39
  warn_about_versions
47
40
  end
data/lib/jspm/lockfile.rb CHANGED
@@ -3,14 +3,11 @@
3
3
  require 'json'
4
4
 
5
5
  module Jspm
6
- # The packages npm installed, as package-lock.json records them.
6
+ # The packages npm or Yarn installed, as package-lock.json or yarn.lock
7
+ # records them.
7
8
  class Lockfile
8
9
  Package =
9
- Data.define(:dev, :name, :path, :top_level, :version) do
10
- def browser?
11
- top_level && !dev
12
- end
13
-
10
+ Data.define(:name, :top_level, :version) do
14
11
  def resolution
15
12
  [name, version]
16
13
  end
@@ -21,18 +18,24 @@ module Jspm
21
18
  end
22
19
  private_constant :Package
23
20
 
24
- def self.read(root)
25
- json = JSON.parse(root.join('package-lock.json').read)
26
- installed = json.fetch('packages').reject { |path, _package| path.empty? }
27
- packages =
21
+ class << self
22
+ def read(root)
23
+ packages = root.join('yarn.lock').exist? ? YarnLock.packages(root) : npm_packages(root)
24
+ new(packages: packages.map { |package| Package.new(**package) })
25
+ end
26
+
27
+ private
28
+
29
+ def npm_packages(root)
30
+ json = JSON.parse(root.join('package-lock.json').read)
31
+ installed = json.fetch('packages').reject { |path, _package| path.empty? }
28
32
  installed.map do |path, package|
29
33
  name = path.split('node_modules/').last
30
34
  top_level = path.scan('node_modules/').one?
31
35
  version = package.fetch('version')
32
- dev = package.fetch('dev', false)
33
- Package.new(dev:, name:, path:, top_level:, version:)
36
+ { name:, top_level:, version: }
34
37
  end
35
- new(packages:)
38
+ end
36
39
  end
37
40
 
38
41
  def initialize(packages:)
@@ -43,10 +46,6 @@ module Jspm
43
46
  packages.select(&:top_level).to_h(&:resolution)
44
47
  end
45
48
 
46
- def browser_packages
47
- packages.select(&:browser?)
48
- end
49
-
50
49
  def nested_versions(name)
51
50
  nested = packages.select { |package| package.nested?(name) }
52
51
  nested.map(&:version)
data/lib/jspm/paths.rb CHANGED
@@ -12,7 +12,8 @@ module Jspm
12
12
  ENTRY_PATH = "#{LOCAL}#{ENTRY}".freeze
13
13
  IMPORT_MAP = 'config/importmap.json'
14
14
  VENDOR = 'vendor/jspm'
15
- public_constant :CDN, :ENTRY, :ENTRY_PATH, :IMPORT_MAP, :LOCAL, :VENDOR
15
+ public_constant :CDN, :ENTRY, :ENTRY_PATH, :IMPORT_MAP, :VENDOR
16
+ private_constant :LOCAL
16
17
 
17
18
  def self.logical(url)
18
19
  return url.delete_prefix('https://').sub('/npm:', '/npm/') if url.start_with?(CDN)
data/lib/jspm/tags.rb CHANGED
@@ -9,7 +9,7 @@ module Jspm
9
9
  # imports name its siblings undigested. So the rendered map also sends each
10
10
  # undigested module URL to its digested one.
11
11
  class Tags
12
- MODULE_EXTENSIONS = %w[.css .js .mjs].freeze
12
+ MODULE_EXTENSIONS = %w[.js .mjs].freeze
13
13
  private_constant :MODULE_EXTENSIONS
14
14
 
15
15
  def self.call(view:)
data/lib/jspm/trace.mjs CHANGED
@@ -8,7 +8,7 @@ import { readFileSync } from 'node:fs';
8
8
  import { createRequire } from 'node:module';
9
9
  import { fileURLToPath, pathToFileURL } from 'node:url';
10
10
 
11
- const { entry, inputMap, resolutions, root } = JSON.parse(readFileSync(0, 'utf8'));
11
+ const { entries, inputMap, resolutions, root } = JSON.parse(readFileSync(0, 'utf8'));
12
12
  const rootUrl = pathToFileURL(`${root}/`);
13
13
  const generatorPath = createRequire(rootUrl).resolve('@jspm/generator');
14
14
  const { Generator } = await import(pathToFileURL(generatorPath));
@@ -37,7 +37,7 @@ const generator = new Generator({
37
37
  resolutions,
38
38
  });
39
39
 
40
- const { dynamicDeps, staticDeps } = await generator.link(entry);
40
+ const { dynamicDeps, staticDeps } = await generator.link(entries);
41
41
  const map = generator.getMap();
42
42
 
43
43
  process.stdout.write(
data/lib/jspm/trace.rb CHANGED
@@ -17,10 +17,20 @@ module Jspm
17
17
  pathnames = asset_paths.map { |path| Pathname(path) }
18
18
  module_paths = pathnames.reject { |path| path == vendor_dir }
19
19
  local_modules = LocalModules.find(asset_paths: module_paths)
20
+ resolutions = lockfile.resolutions
21
+ # A package the app installed beats a gem's file of the same name, such
22
+ # as actiontext's trix.js, so the app and its packages share one copy.
23
+ pins = local_modules.pins.reject { |name, _path| resolutions.key?(name) }
24
+ # Every app module is traced and named in the map, as importmap-rails
25
+ # pins them, so code can import one by a name it computes, the way
26
+ # stimulus-rails's eagerLoadControllersFrom does.
27
+ app_dir = root.join('app/javascript').to_s
28
+ app_modules = pins.select { |_name, path| path.start_with?(app_dir) }
29
+ .keys
20
30
  input = JSON.generate(
21
- entry: Paths::ENTRY_PATH,
22
- inputMap: { imports: locked_versions(root).merge(local_modules.pins), scopes: {} },
23
- resolutions: lockfile.resolutions,
31
+ entries: [Paths::ENTRY_PATH, *app_modules],
32
+ inputMap: { imports: locked_versions(root).merge(pins), scopes: {} },
33
+ resolutions:,
24
34
  root: root.to_s
25
35
  )
26
36
  script = File.expand_path('trace.mjs', __dir__)
data/lib/jspm/version.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Jspm
4
- VERSION = '0.1.0'
4
+ VERSION = '0.3.0'
5
5
  public_constant :VERSION
6
6
  end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module Jspm
6
+ # Reads Yarn 1's yarn.lock. Unlike package-lock.json, it doesn't record
7
+ # where each package sits in node_modules. A package locked at one version
8
+ # is the top-level one. When Yarn locked several versions, the one
9
+ # node_modules holds at its top level is.
10
+ module YarnLock
11
+ Entry = Data.define(:name, :version)
12
+ private_constant :Entry
13
+
14
+ class << self
15
+ def packages(root)
16
+ entries = parse(root.join('yarn.lock').read)
17
+ counts = entries.map(&:name).tally
18
+ entries.map do |entry|
19
+ name = entry.name
20
+ version = entry.version
21
+ locked_once = counts.fetch(name) == 1
22
+ installed = installed_version(root.join('node_modules', name)) == version
23
+ { name:, top_level: locked_once || installed, version: }
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def installed_version(package_dir)
30
+ manifest = package_dir.join('package.json')
31
+ JSON.parse(manifest.read).fetch('version') if manifest.exist?
32
+ end
33
+
34
+ def parse(text)
35
+ blocks =
36
+ text.split(/\n{2,}/).reject do |block|
37
+ block.start_with?('#') || block.strip.empty?
38
+ end
39
+ blocks.map { |block| parse_entry(block) }
40
+ end
41
+
42
+ def parse_entry(block)
43
+ header, *body = block.lines(chomp: true)
44
+ spec = header.delete_suffix(':').split(', ').first.delete('"')
45
+ version = body.find { |line| line.start_with?(' version ') }[/"(.*)"/, 1]
46
+ Entry.new(name: spec.rpartition('@').first, version:)
47
+ end
48
+ end
49
+ end
50
+ end
data/lib/jspm-rails.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'jspm/assets'
4
3
  require 'jspm/check'
5
4
  require 'jspm/helper'
6
5
  require 'jspm/install'
@@ -11,3 +10,4 @@ require 'jspm/railtie'
11
10
  require 'jspm/tags'
12
11
  require 'jspm/trace'
13
12
  require 'jspm/version'
13
+ require 'jspm/yarn_lock'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jspm-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Clay Shentrup
@@ -49,7 +49,6 @@ files:
49
49
  - LICENSE
50
50
  - README.md
51
51
  - lib/jspm-rails.rb
52
- - lib/jspm/assets.rb
53
52
  - lib/jspm/check.rb
54
53
  - lib/jspm/helper.rb
55
54
  - lib/jspm/install.rb
@@ -61,6 +60,7 @@ files:
61
60
  - lib/jspm/trace.mjs
62
61
  - lib/jspm/trace.rb
63
62
  - lib/jspm/version.rb
63
+ - lib/jspm/yarn_lock.rb
64
64
  - lib/tasks/jspm.rake
65
65
  homepage: https://github.com/ClayShentrup/jspm-rails
66
66
  licenses:
data/lib/jspm/assets.rb DELETED
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Jspm
4
- # The stylesheets, fonts and images of each npm dependency, and where each
5
- # one is vendored. devDependencies are build tools, so they stay out.
6
- module Assets
7
- EXTENSIONS = %w[
8
- .avif
9
- .css
10
- .eot
11
- .gif
12
- .jpeg
13
- .jpg
14
- .otf
15
- .png
16
- .svg
17
- .ttf
18
- .webp
19
- .woff
20
- .woff2
21
- ].freeze
22
- private_constant :EXTENSIONS
23
-
24
- class << self
25
- # Each copy is a pair: the file in node_modules, and its vendored path.
26
- def copies(lockfile:, root:)
27
- lockfile.browser_packages.flat_map { |package| package_copies(package, root) }
28
- end
29
-
30
- private
31
-
32
- def package_copies(package, root)
33
- package_dir = root.join(package.path)
34
- vendor_dir = root.join(Paths::VENDOR, package.name)
35
- files =
36
- package_dir.glob('**/*').select do |file|
37
- EXTENSIONS.include?(file.extname.downcase)
38
- end
39
- files.map do |file|
40
- relative_path = file.relative_path_from(package_dir)
41
- [file, vendor_dir.join(relative_path)]
42
- end
43
- end
44
- end
45
- end
46
- end