{"id":13428051,"url":"https://github.com/rails/spring","last_synced_at":"2025-05-12T05:32:40.214Z","repository":{"id":6134231,"uuid":"7362671","full_name":"rails/spring","owner":"rails","description":"Rails application preloader","archived":false,"fork":false,"pushed_at":"2025-04-29T19:55:59.000Z","size":1169,"stargazers_count":2812,"open_issues_count":131,"forks_count":340,"subscribers_count":78,"default_branch":"main","last_synced_at":"2025-04-30T15:12:11.068Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rails.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2012-12-29T03:53:34.000Z","updated_at":"2025-04-29T19:56:04.000Z","dependencies_parsed_at":"2023-12-07T10:31:59.219Z","dependency_job_id":"7009b377-5b68-46a9-9bb0-d1a26f221913","html_url":"https://github.com/rails/spring","commit_stats":{"total_commits":729,"total_committers":135,"mean_commits":5.4,"dds":0.4238683127572016,"last_synced_commit":"4bdb3372a33d0005f56b628e6ed9f3479dfe5db6"},"previous_names":["jonleighton/spring"],"tags_count":52,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rails%2Fspring","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rails%2Fspring/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rails%2Fspring/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rails%2Fspring/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rails","download_url":"https://codeload.github.com/rails/spring/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252288955,"owners_count":21724326,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T01:00:44.975Z","updated_at":"2025-05-08T18:02:45.770Z","avatar_url":"https://github.com/rails.png","language":"Ruby","readme":"# Spring\n\n[![Build Status](https://github.com/rails/spring/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/rails/spring/actions/workflows/ci.yml?branch=main)\n[![Gem Version](https://badge.fury.io/rb/spring.svg)](https://badge.fury.io/rb/spring)\n\nSpring is a Rails application preloader. It speeds up development by\nkeeping your application running in the background, so you don't need to\nboot it every time you run a test, rake task or migration.\n\n## Features\n\n* Totally automatic; no need to explicitly start and stop the background process\n* Reloads your application code on each run\n* Restarts your application when configs / initializers / gem\n  dependencies are changed\n\n## Compatibility\n\n* Ruby versions: MRI 2.7, MRI 3.0, MRI 3.1, MRI 3.2\n* Rails versions: 6.0, 6.1, 7.0\n* Bundler v2.1+\n\nSpring makes extensive use of `Process.fork`, so won't be able to\nprovide a speed up on platforms which don't support forking (Windows, JRuby).\n\n## Walkthrough\n\n### Setup\n\nAdd Spring to your Gemfile:\n\n``` ruby\ngem \"spring\", group: :development\n```\n\n(Note: using `gem \"spring\", git: \"...\"` *won't* work and is not a\nsupported way of using Spring.)\n\nIt's recommended to 'springify' the executables in your `bin/`\ndirectory:\n\n```\n$ bundle install\n$ bundle exec spring binstub --all\n```\n\nThis generates a `bin/spring` executable, and inserts a small snippet of\ncode into relevant existing executables. The snippet looks like this:\n\n``` ruby\nbegin\n  load File.expand_path('../spring', __FILE__)\nrescue LoadError =\u003e e\n  raise unless e.message.include?('spring')\nend\n```\n\nOn platforms where Spring is installed and supported, this snippet\nhooks Spring into the execution of commands. In other cases, the snippet\nwill just be silently ignored, and the lines after it will be executed as\nnormal.\n\nIf you don't want to prefix every command you type with `bin/`, you\ncan [use direnv](https://github.com/direnv/direnv#the-stdlib) to\nautomatically add `./bin` to your `PATH` when you `cd` into your application.\nSimply create an `.envrc` file with the command `PATH_add bin` in your\nRails directory.\n\n### Enable reloading\n\nSpring reloads application code, and therefore needs the application to have\nreloading enabled.\n\nEnsure that `config.enable_reloading` is `true` in the environments that\nSpring manages. That setting is typically configured in\n`config/environments/*.rb`. In particular, make sure it is `true` for the\n`test` environment.\n\nNote: in versions of Rails before 7.1, the setting is called `cache_classes`,\nand it needs to be `false` for Spring to work.\n\n### Usage\n\nFor this walkthrough I've generated a new Rails application, and run\n`rails generate scaffold post name:string`.\n\nLet's run a test:\n\n```\n$ time bin/rake test test/controllers/posts_controller_test.rb\nRunning via Spring preloader in process 2734\nRun options:\n\n# Running tests:\n\n.......\n\nFinished tests in 0.127245s, 55.0121 tests/s, 78.5887 assertions/s.\n\n7 tests, 10 assertions, 0 failures, 0 errors, 0 skips\n\nreal    0m2.165s\nuser    0m0.281s\nsys     0m0.066s\n```\n\nThat wasn't particularly fast because it was the first run, so Spring\nhad to boot the application. It's now running:\n\n```\n$ bin/spring status\nSpring is running:\n\n26150 spring server | spring-demo-app | started 3 secs ago\n26155 spring app    | spring-demo-app | started 3 secs ago | test mode\n```\n\nThe next run is faster:\n\n```\n$ time bin/rake test test/controllers/posts_controller_test.rb\nRunning via Spring preloader in process 8352\nRun options:\n\n# Running tests:\n\n.......\n\nFinished tests in 0.176896s, 39.5714 tests/s, 56.5305 assertions/s.\n\n7 tests, 10 assertions, 0 failures, 0 errors, 0 skips\n\nreal    0m0.610s\nuser    0m0.276s\nsys     0m0.059s\n```\n\nIf we edit any of the application files, or test files, the changes will\nbe picked up on the next run without the background process having to\nrestart. This works in exactly the same way as the code reloading\nwhich allows you to refresh your browser and instantly see changes during\ndevelopment.\n\nBut if we edit any of the files which were used to start the application\n(configs, initializers, your gemfile), the application needs to be fully\nrestarted. This happens automatically.\n\nLet's \"edit\" `config/application.rb`:\n\n```\n$ touch config/application.rb\n$ bin/spring status\nSpring is running:\n\n26150 spring server | spring-demo-app | started 36 secs ago\n26556 spring app    | spring-demo-app | started 1 sec ago | test mode\n```\n\nThe application detected that `config/application.rb` changed and\nautomatically restarted itself.\n\nIf we run a command that uses a different environment, then that\nenvironment gets booted up:\n\n```\n$ bin/rake routes\nRunning via Spring preloader in process 2363\n    posts GET    /posts(.:format)          posts#index\n          POST   /posts(.:format)          posts#create\n new_post GET    /posts/new(.:format)      posts#new\nedit_post GET    /posts/:id/edit(.:format) posts#edit\n     post GET    /posts/:id(.:format)      posts#show\n          PUT    /posts/:id(.:format)      posts#update\n          DELETE /posts/:id(.:format)      posts#destroy\n\n$ bin/spring status\nSpring is running:\n\n26150 spring server | spring-demo-app | started 1 min ago\n26556 spring app    | spring-demo-app | started 42 secs ago | test mode\n26707 spring app    | spring-demo-app | started 2 secs ago | development mode\n```\n\nThere's no need to \"shut down\" Spring. This will happen automatically\nwhen you close your terminal. However, if you do want to do a manual shut\ndown, use the `stop` command:\n\n```\n$ bin/spring stop\nSpring stopped.\n```\n\nFrom within your code, you can check whether Spring is active with `if defined?(Spring)`.\n\n### Removal\n\nTo remove Spring:\n\n* 'Unspring' your bin/ executables: `bin/spring binstub --remove --all`\n* Remove spring from your Gemfile\n\n### Deployment\n\nYou must not install Spring on your production environment. To prevent it from\nbeing installed, run the `bundle config set without 'development test'` before\n`bundle install` command which is used to install gems on your production\nmachines:\n\n```\n$ bundle config set without 'development test'\n$ bundle install\n```\n\n## Commands\n\n### `rake`\n\nRuns a rake task. Rake tasks run in the `development` environment by\ndefault. You can change this on the fly by using the `RAILS_ENV`\nenvironment variable. The environment is also configurable with the\n`Spring::Commands::Rake.environment_matchers` hash. This has sensible\ndefaults, but if you need to match a specific task to a specific\nenvironment, you'd do it like this:\n\n``` ruby\nSpring::Commands::Rake.environment_matchers[\"perf_test\"] = \"test\"\nSpring::Commands::Rake.environment_matchers[/^perf/]     = \"test\"\n\n# To change the environment when you run `rake` with no arguments\nSpring::Commands::Rake.environment_matchers[:default] = \"development\"\n```\n\n### `rails console`, `rails generate`, `rails runner`\n\nThese execute the rails command you already know and love. If you run\na different sub command (e.g. `rails server`) then Spring will automatically\npass it through to the underlying `rails` executable (without the\nspeed-up).\n\n### Additional commands\n\nYou can add these to your Gemfile for additional commands:\n\n* [spring-commands-rspec](https://github.com/jonleighton/spring-commands-rspec)\n* [spring-commands-cucumber](https://github.com/jonleighton/spring-commands-cucumber)\n* [spring-commands-spinach](https://github.com/jvanbaarsen/spring-commands-spinach)\n* [spring-commands-testunit](https://github.com/jonleighton/spring-commands-testunit) - useful for\n  running `Test::Unit` tests on Rails 3, since only Rails 4 allows you\n  to use `rake test path/to/test` to run a particular test/directory.\n* [spring-commands-parallel-tests](https://github.com/DocSpring/spring-commands-parallel-tests) - Adds the `parallel_*` commands from [`parallel_tests`](https://github.com/grosser/parallel_tests).\n* [spring-commands-teaspoon](https://github.com/alejandrobabio/spring-commands-teaspoon.git)\n* [spring-commands-m](https://github.com/gabrieljoelc/spring-commands-m.git)\n* [spring-commands-rubocop](https://github.com/p0deje/spring-commands-rubocop)\n* [spring-commands-rackup](https://github.com/wintersolutions/spring-commands-rackup)\n* [spring-commands-rack-console](https://github.com/wintersolutions/spring-commands-rack-console)\n* [spring-commands-standard](https://github.com/lakim/spring-commands-standard)\n\n## Use without adding to bundle\n\nIf you don't want Spring-related code checked into your source\nrepository, it's possible to use Spring without adding to your Gemfile.\nHowever, using Spring binstubs without adding Spring to the Gemfile is not\nsupported.\n\nTo use Spring like this, do a `gem install spring` and then prefix\ncommands with `spring`. For example, rather than running `bin/rake -T`,\nyou'd run `spring rake -T`.\n\n## Temporarily disabling Spring\n\nIf you're using Spring binstubs, but temporarily don't want commands to\nrun through Spring, set the `DISABLE_SPRING` environment variable.\n\n## Class reloading\n\nSpring uses Rails' class reloading mechanism to keep your code up to date\nbetween test runs. This is the same mechanism which allows you to see changes\nduring development when you refresh the page. However, you may never have used\nthis mechanism with your `test` environment before, and this can cause problems.\n\nIt's important to realise that code reloading means that the constants\nin your application are *different objects* after files have changed:\n\n```\n$ bin/rails runner 'puts User.object_id'\n70127987886040\n$ touch app/models/user.rb\n$ bin/rails runner 'puts User.object_id'\n70127976764620\n```\n\nSuppose you have an initializer `config/initializers/save_user_class.rb`\nlike so:\n\n``` ruby\nUSER_CLASS = User\n```\n\nThis saves off the *first* version of the `User` class, which will not\nbe the same object as `User` after the code has been reloaded:\n\n```\n$ bin/rails runner 'puts User == USER_CLASS'\ntrue\n$ touch app/models/user.rb\n$ bin/rails runner 'puts User == USER_CLASS'\nfalse\n```\n\nSo to avoid this problem, don't save off references to application\nconstants in your initialization code.\n\n## Using Spring with a containerized development environment\n\nAs of Spring 1.7, there is some support for doing this. See [this\nexample\nrepository](https://github.com/jonleighton/spring-docker-example) for\ninformation about how to do it with [Docker](https://www.docker.com/).\n\n## Configuration\n\nSpring will read `~/.spring.rb` and `config/spring.rb` for custom\nsettings. Note that `~/.spring.rb` is loaded *before* bundler, but\n`config/spring.rb` is loaded *after* bundler. So if you have any\n`spring-commands-*` gems installed that you want to be available in all\nprojects without having to be added to the project's Gemfile, require\nthem in your `~/.spring.rb`.\n\n`config/spring_client.rb` is also loaded before bundler and before a\nserver process is started, it can be used to add new top-level commands.\n\n### Application root\n\nSpring must know how to find your Rails application. If you have a\nnormal app everything works out of the box. If you are working on a\nproject with a special setup (an engine for example), you must tell\nSpring where your app is located:\n\n```ruby\nSpring.application_root = './test/dummy'\n```\n\n### Running code before forking\n\nThere is no `Spring.before_fork` callback. To run something before the\nfork, you can place it in `~/.spring.rb` or `config/spring.rb` or in any of the files\nwhich get run when your application initializes, such as\n`config/application.rb`, `config/environments/*.rb` or\n`config/initializers/*.rb`.\n\n### Running code after forking\n\nYou might want to run code after Spring forked off the process but\nbefore the actual command is run. You might want to use an\n`after_fork` callback if you have to connect to an external service,\ndo some general cleanup or set up dynamic configuration.\n\n```ruby\nSpring.after_fork do\n  # run arbitrary code\nend\n```\n\nIf you want to register multiple callbacks you can simply call\n`Spring.after_fork` multiple times with different blocks.\n\n### Watching files and directories\n\nSpring will automatically detect file changes to any file loaded when the server\nboots. Changes will cause the affected environments to be restarted.\n\nIf there are additional files or directories which should trigger an\napplication restart, you can specify them with `Spring.watch`:\n\n```ruby\nSpring.watch \"config/some_config_file.yml\"\n```\n\nBy default, Spring polls the filesystem for changes once every 0.2 seconds. This\nmethod requires zero configuration, but if you find that it's using too\nmuch CPU, then you can use event-based file system listening by\ninstalling the\n[spring-watcher-listen](https://github.com/jonleighton/spring-watcher-listen)\ngem.\n\n### Quiet output\n\nTo disable the \"Running via Spring preloader\" message which is shown each time\na command runs:\n\n``` ruby\nSpring.quiet = true\n```\n\nYou can also set the initial state of the `quiet` configuration option to true\nby setting the `SPRING_QUIET` environment variable before executing Spring.\nThis is useful if you want to set quiet mode when invoking the Spring executable\nin a subprocess, and cannot or prefer not to set it programmatically\nvia the `Spring.quiet` option in `~/.spring.rb` or the app's `config/spring.rb`.\n\n### Environment variables\n\nThe following environment variables are used by Spring:\n\n* `DISABLE_SPRING` - If set, Spring will be bypassed, and your\n  application will boot in a foreground process\n* `SPRING_LOG` - The path to a file which Spring will write log messages\n  to.\n* `SPRING_TMP_PATH` - The directory where Spring should write its temporary\n  files (a pidfile and a socket). By default, we use the\n  `XDG_RUNTIME_DIR` environment variable, or else `Dir.tmpdir`, and then\n  create a directory in that named `spring-$UID`. We don't use your\n  Rails application's `tmp/` directory because that may be on a\n  filesystem which doesn't support UNIX sockets.\n* `SPRING_APPLICATION_ID` - Used to identify distinct Rails\n  applications. By default, it is an MD5 hash of the current\n  `RUBY_VERSION`, and the path to your Rails project root.\n* `SPRING_SOCKET` - The path which should be used for the UNIX socket\n  which Spring uses to communicate with the long-running Spring server\n  process. By default, this is `SPRING_TMP_PATH/SPRING_APPLICATION_ID`.\n* `SPRING_PIDFILE` - The path which should be used to store the pid of\n  the long-running Spring server process. By default, this is related to\n  the socket path; if the socket path is `/foo/bar/spring.sock` the\n  pidfile will be `/foo/bar/spring.pid`.\n* `SPRING_QUIET` - If set, the initial state of the `Spring.quiet`\n  configuration option will default to `true`.\n* `SPRING_SERVER_COMMAND` - The command to run to start up the Spring\n  server when it is not already running. Defaults to `spring _[version]_\n  server --background`.\n\n## Troubleshooting\n\nIf you want to get more information about what Spring is doing, you can\nrun Spring explicitly in a separate terminal:\n\n```\n$ spring server\n```\n\nLogging output will be printed to stdout. You can also send log output\nto a file with the `SPRING_LOG` environment variable.\n","funding_links":[],"categories":["Debug","Web 后端","Ruby","调试","Testing","Gems"],"sub_categories":["Omniauth","Articles","Testing"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frails%2Fspring","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frails%2Fspring","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frails%2Fspring/lists"}