Skip to content

Commit 800cef6

Browse files
authored
feat: use npm for managing js packages (#571)
We've decided that we want to use `npm` as our package manager for JavaScript dependencies, so this removes our explicit support for the other package managers, though we still remain pretty agnostic due to the use of `PackageJson` which I've retained for now given it's lightweight and secretly I'm keen to explore `pnpm` at some point so this will come in handy if that turns out to be worth switching to 😄 I've also retained the "create fake package managers" script + ci step to ensure that we really are only ever using `npm`; I plan to explore refactoring that script given we no longer need to support all the package managers as a follow-up since it too is lightweight and perfectly functional as-is.
1 parent b3edbf7 commit 800cef6

File tree

11 files changed

+51
-148
lines changed

11 files changed

+51
-148
lines changed

.github/workflows/ci.yml

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ jobs:
4949
- uses: actions/setup-node@v4
5050
with:
5151
node-version-file: '.node-version'
52-
cache: 'yarn'
53-
- run: yarn install
54-
- run: yarn run format-check
52+
cache: 'npm'
53+
- run: npm ci
54+
- run: npm run format-check
5555

5656
rubocop:
5757
permissions:
@@ -79,24 +79,6 @@ jobs:
7979
# how many fail)
8080
fail-fast: false
8181
matrix:
82-
js_package_manager:
83-
- name: npm
84-
installer: npm
85-
- name: yarn_berry
86-
installer: yarn
87-
linker: pnp
88-
- name: yarn_berry
89-
installer: yarn
90-
linker: node-modules
91-
- name: yarn_berry
92-
installer: yarn
93-
linker: pnpm
94-
- name: yarn_classic
95-
installer: yarn
96-
- name: pnpm
97-
installer: pnpm
98-
- name: bun
99-
installer: bun
10082
variant:
10183
- name: defaults
10284
config_path: 'ackama_rails_template.config.yml'
@@ -173,8 +155,8 @@ jobs:
173155
with:
174156
node-version-file: '.node-version'
175157

176-
- name: install package manager
177-
run: npm i -g ${{ matrix.js_package_manager.installer }}
158+
- name: Install latest version of npm
159+
run: npm i -g npm
178160

179161
# We don't cache gems or JS packages because we are actually testing how
180162
# installation and setup works in this project so, while caching would
@@ -192,8 +174,7 @@ jobs:
192174
git config --global user.email "[email protected]"
193175
git config --global user.name "Your Name"
194176
195-
# prettier-ignore
196-
- run: ./ci/bin/create-fake-js-package-managers ${{ matrix.js_package_manager.installer }}
177+
- run: ./ci/bin/create-fake-js-package-managers npm
197178

198179
- name: Run CI script
199180
env:
@@ -207,7 +188,4 @@ jobs:
207188
PGUSER: postgres
208189
PGPASSWORD: postgres
209190
PGHOST: localhost
210-
PACKAGE_JSON_FALLBACK_MANAGER: ${{ matrix.js_package_manager.name }}
211-
PACKAGE_JSON_YARN_BERRY_LINKER:
212-
${{ matrix.js_package_manager.linker }}
213191
run: ./ci/bin/build-and-test

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ Where possible we stick to Rails defaults.
3333

3434
- General
3535
- [puma](https://github.com/puma/puma) as application server
36-
- [Yarn](https://yarnpkg.com/) for managing JS packages
36+
- [npm](https://www.npmjs.com/) for managing JS packages
3737
- PostgreSQL as database. This template only supports PostgreSQL.
3838
- A much-improved `bin/setup` script
3939
- Install [dotenv](https://github.com/bkeepers/dotenv)
@@ -155,7 +155,7 @@ our other templates:
155155
Before running this template, you must have the following installed on your
156156
machine:
157157

158-
- Yarn v1.21.0 or later
158+
- NPM v10.0.0 or later
159159
- Rails 7.1.x
160160

161161
The following are not strictly required to run the template but you will need it

package-lock.json

Lines changed: 38 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

template.rb

Lines changed: 1 addition & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,6 @@ def apply_template! # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Met
177177
package_json.manager.run!("typecheck")
178178
end
179179

180-
ensure_yarn_files_are_not_linted
181-
182180
# apply any js linting fixes after all frontend variants have run
183181
package_json.manager.run!("js-lint-fix")
184182

@@ -266,78 +264,7 @@ def apply_prettier_all_over
266264
git commit: ". -m 'Run prettier one last time'"
267265
end
268266

269-
# Sets Yarn Berry up in the project directory by initializing it with what is probably Yarn Classic.
270-
#
271-
# This is required as the Berry binary is actually downloaded and committed to the codebase, and
272-
# the global yarn command passes through to it when detected (even if its Yarn Classic).
273-
#
274-
# This also requires us to temporarily create a package.json as otherwise Yarn Berry will
275-
# look up the file tree and initialize itself in every directory that has a yarn.lock
276-
def setup_yarn_berry
277-
# safeguard against parent directories having a yarn.lock
278-
File.write("package.json", "{}") unless File.exist?("package.json")
279-
280-
run "yarn init -2"
281-
run "yarn config set enableGlobalCache true"
282-
run "yarn config set nodeLinker #{ENV.fetch("PACKAGE_JSON_YARN_BERRY_LINKER", "node-modules")}"
283-
284-
ignores = <<~YARN
285-
.pnp.*
286-
.yarn/*
287-
!.yarn/patches
288-
!.yarn/plugins
289-
!.yarn/releases
290-
!.yarn/sdks
291-
!.yarn/versions
292-
YARN
293-
File.write(".gitignore", ignores, mode: "a")
294-
295-
# this will be properly (re)created later
296-
File.unlink("package.json")
297-
end
298-
299-
# Bun uses a binary-based lockfile which cannot be parsed by shakapacker or
300-
# osv-detector, so we want to configure bun to always write a yarn.lock
301-
# in addition so that such tools can check it
302-
def setup_bun
303-
File.write("bunfig.toml", <<~TOML)
304-
[install.lockfile]
305-
print = "yarn"
306-
TOML
307-
end
308-
309-
def add_yarn_package_extension_dependency(name, dependency)
310-
return unless File.exist?(".yarnrc.yml")
311-
312-
require "yaml"
313-
314-
yarnrc = YAML.load_file(".yarnrc.yml")
315-
316-
yarnrc["packageExtensions"] ||= {}
317-
yarnrc["packageExtensions"]["#{name}@*"] ||= {}
318-
yarnrc["packageExtensions"]["#{name}@*"]["dependencies"] ||= {}
319-
yarnrc["packageExtensions"]["#{name}@*"]["dependencies"][dependency] = "*"
320-
321-
File.write(".yarnrc.yml", yarnrc.to_yaml)
322-
end
323-
324-
# Ensures that files related to Yarn Berry are ignored by ESLint
325-
def ensure_yarn_files_are_not_linted
326-
return unless Dir.exist?(".yarn") && File.exist?("eslint.config.js")
327-
328-
gsub_file!(
329-
"eslint.config.js",
330-
" { ignores: ['tmp/*'] },",
331-
" { ignores: ['tmp/*', '.yarn/*', '.pnp.cjs', '.pnp.loader.mjs'] },"
332-
)
333-
end
334-
335267
def package_json
336-
if @package_json.nil?
337-
setup_yarn_berry if ENV.fetch("PACKAGE_JSON_FALLBACK_MANAGER", nil) == "yarn_berry"
338-
setup_bun if ENV.fetch("PACKAGE_JSON_FALLBACK_MANAGER", nil) == "bun"
339-
end
340-
341268
@package_json ||= PackageJson.new
342269
end
343270

@@ -359,8 +286,7 @@ def build_engines_field(existing)
359286
node_version = File.read("./.node-version").strip
360287

361288
existing.merge({
362-
"node" => "^#{node_version}",
363-
"yarn" => "^1.0.0"
289+
"node" => "^#{node_version}"
364290
})
365291
end
366292

@@ -374,9 +300,6 @@ def cleanup_package_json
374300
}
375301
end
376302

377-
# TODO: this doesn't work when using pnpm even though it shouldn't matter? anyway, replace with 'exec' support
378-
# run "npx -y sort-package-json"
379-
380303
# ensure the lockfile is up to date with any changes we've made to package.json
381304
package_json.manager.install!
382305
end

variants/accessibility/spec/rails_helper.rb

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,3 @@
1212
Lighthouse::Matchers.chrome_flags = %w[headless=new no-sandbox]
1313
OPTIONS
1414
end
15-
16-
if File.exist?(".yarnrc.yml")
17-
insert_into_file! "spec/rails_helper.rb", after: /# Lighthouse Matcher options\n/ do
18-
<<~OPTIONS
19-
Lighthouse::Matchers.lighthouse_cli = "yarn run lighthouse"
20-
OPTIONS
21-
end
22-
end

variants/backend-base/Dockerfile

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,6 @@ RUN apt-get update -qq &&\
3939
/usr/share/locales \
4040
/var/cache/apt/archives
4141

42-
# Use NPM to install Yarn.
43-
RUN npm install -g yarn
44-
4542
# Install gem and NPM dependencies. These are baked into the image so the image can run
4643
# standalone provided valid configuration. When running in docker-compose, these
4744
# dependencies are stored in a volume so the image does not need rebuilding when the
@@ -56,10 +53,10 @@ USER deploy
5653

5754
# Add just the dependency manifests before installing.
5855
# This reduces the chance that bundler or NPM will get a cold cache because some kind of application file changed.
59-
ADD Gemfile* package.json yarn.lock /usr/src/app/
56+
ADD Gemfile* package.json package-lock.json /usr/src/app/
6057
WORKDIR /usr/src/app
6158
RUN bundle check || bundle install &&\
62-
yarn install --frozen-lockfile
59+
npm ci
6360

6461
# Add all application code to /usr/src/app and set this as the working directory
6562
# of the container

variants/frontend-base/js-lint/template.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
# Javascript code linting and formatting
22
# ######################################
33

4-
add_yarn_package_extension_dependency("eslint-plugin-prettier", "eslint-config-prettier")
5-
64
add_js_dependencies %w[
75
@eslint-community/eslint-plugin-eslint-comments
86
@stylistic/eslint-plugin-js@3

variants/frontend-react/template.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77

88
run "rails generate react:install"
99

10-
add_yarn_package_extension_dependency("@testing-library/user-event", "@testing-library/dom")
11-
1210
# prefer importing from the more specific package for consistency
1311
gsub_file! "app/frontend/test/stimulus/controllers/add_class_controller.test.js",
1412
"'@testing-library/dom'",

variants/frontend-stimulus-typescript/template.rb

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,5 @@
11
source_paths.unshift(File.dirname(__FILE__))
22

3-
add_yarn_package_extension_dependency("@testing-library/jest-dom", "@types/aria-query")
4-
add_yarn_package_extension_dependency("ts-jest", "@jest/transform")
5-
add_yarn_package_extension_dependency("ts-jest", "@jest/types")
6-
add_yarn_package_extension_dependency("ts-jest", "jest-util")
7-
add_yarn_package_extension_dependency("@jest/test-result", "jest-haste-map")
8-
add_yarn_package_extension_dependency("@jest/test-result", "jest-resolve")
9-
add_yarn_package_extension_dependency("jest-cli", "@types/yargs")
10-
113
add_js_dependencies ["@babel/plugin-transform-typescript"]
124
add_js_dependencies [
135
"@types/jest@#{JEST_MAJOR_VERSION}",

variants/github_actions_ci/workflows/ci.yml.tt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ jobs:
4949
- uses: actions/setup-node@v4
5050
with:
5151
node-version-file: '.node-version'
52-
cache: 'yarn'
52+
cache: 'npm'
5353
- run: <%= package_json.manager.native_install_command(frozen: true).join(" ") %>
5454
<%- if TEMPLATE_CONFIG.use_typescript? -%>
5555
- run: <%= package_json.manager.native_run_command("typecheck").join(" ") %>
@@ -109,7 +109,7 @@ jobs:
109109
- uses: actions/setup-node@v4
110110
with:
111111
node-version-file: '.node-version'
112-
cache: 'yarn'
112+
cache: 'npm'
113113
- run: <%= package_json.manager.native_install_command(frozen: true).join(" ") %>
114114
- run: bundle exec rspec spec --format progress
115115
- name: Archive spec outputs

0 commit comments

Comments
 (0)