Ruby의 코드 로더 - Zeitwerk 이해
Zeitwerk를 사용하면 모든 곳에서 클래스와 모듈을 사용할 수 있다는 사실을 알고 프로그래밍을 간소화할 수 있습니다.
코드 로더란 무엇입니까?
코드 로더를 사용하면 개발자가 classes
를 정의할 수 있습니다. 및 modules
다른 파일과 폴더에 걸쳐 있고 명시적으로 요구하지 않고 코드베이스 전체에서 사용합니다. Rails는 코드 로더를 사용하는 소프트웨어의 좋은 예입니다. Rails 프로그래밍에는 명시적인 require
가 필요하지 않습니다. 컨트롤러에서 모델을 사용하기 전에 로드 모델을 호출합니다. 사실, Rails 6에서는 app
의 모든 것이 디렉토리는 몇 가지 예외를 제외하고 앱 부팅 시 자동으로 로드됩니다.
코드 로딩이 require
를 호출하는 것이라고 생각하기 쉽지만 , 그렇게 간단하지 않습니다. 코드 로딩은 다음과 같이 세 부분으로 더 나눌 수 있습니다.
- 자동 로드: 이는 코드가 필요에 따라 즉석에서 로드됨을 의미합니다. 예를 들어, Rails에서
rails s
실행 모든 모델, 컨트롤러 등을 로드하지는 않습니다. 그러나User
모델의 첫 번째 히트에서 , 자동 로딩 메커니즘을 실행하여 모델을 찾고 사용합니다. 이것은 작동 중인 자동 로드입니다. 이것은 더 빠른 앱과rails console
이 있기 때문에 개발 환경에 몇 가지 이점이 있습니다. 시작 시간.Rails.config.autoload_path
자동 로드할 경로를 제어합니다. - 빠른 로딩: 즉, 앱 시작 시 코드가 메모리에 로드되고 상수를 요구하기 전에 호출될 때까지 기다리지 않습니다. Rails에서 코드는 프로덕션 환경에서 즉시 로드됩니다. 위의 설명에 따르면 프로덕션에서 코드를 자동 로드하면 각 상수가 즉석에서 필요하기 때문에 응답 시간이 느려집니다.
Rails.config.eager_load_paths
즉시 로드할 경로를 제어합니다. - 다시 로드: 코드 로더는
autoload_path
의 파일 변경 사항을 지속적으로 감시합니다. 변경 사항이 감지되면 파일을 다시 로드합니다. Rails에서는rails s
를 실행할 수 있으므로 개발에 매우 유용할 수 있습니다. Rails 서버를 다시 시작할 필요 없이 동시에 변경할 수 있습니다. 다시 로드 중입니다.
우리는 이러한 개념의 대부분이 Rails에서 개발되고 실행되고 있음을 쉽게 알 수 있습니다. Zeitwerk는 이것을 변경합니다! Zeitwerk를 사용하면 모든 코드 로드 작업을 모든 Ruby 프로젝트에 가져올 수 있습니다.
자이트베르크란 무엇입니까?
Zeitwerk는 효율적이고 스레드로부터 안전한 Ruby용 코드 로더이며 웹 프레임워크(Rails, Hanami, Sinatra), Cli 도구 및 gem을 포함한 모든 Ruby 프로젝트에서 사용할 수 있습니다. 이를 통해 모든 곳에서 클래스와 모듈을 사용할 수 있다는 사실을 알고 프로그래밍을 간소화할 수 있습니다. 전통적으로 Rails와 일부 다른 gem에는 이 기능을 활성화하는 코드 로더가 내장되어 있습니다. 그러나 Zeitwerk는 이러한 개념을 보석으로 추출하고 Rubyists가 이러한 개념을 프로젝트에 적용할 수 있도록 합니다.
자이트베르크 설치
먼저 gem을 설치해야 합니다.
gem install zeitwerk
# OR in your Gemfile
gem 'zeitwerk', '~> 2.4.0'
자이트베르크 구성
이제 기본 사항부터 시작하겠습니다.
require 'zeitwerk'
loader = Zeitwerk::Loader.new
...
loader.setup
위의 코드는 로더 인스턴스를 인스턴스화하고 setup
을 호출합니다. . setup
호출 후 , 로더가 코드를 로드할 준비가 되었습니다. 그러나 그 전에 loader
에 필요한 모든 구성이 이미 덮여 있어야합니다. 이 기사에서는 loader
의 몇 가지 구성을 다룰 것입니다. 및 코드 구조화 규칙.
- 파일 구조:Zeitwerk가 작동하려면 파일 및 디렉토리 이름이 정의한 모듈 및 클래스 이름과 일치해야 합니다. 예를 들어,
lib/my_gem.rb -> MyGem
lib/my_gem/foo.rb -> MyGem::Foo
lib/my_gem/bar_baz.rb -> MyGem::BarBaz
lib/my_gem/woo/zoo.rb -> MyGem::Woo::Zoo
- 루트 네임스페이스:루트 네임스페이스는
Zeitwerk
당신의 코드를 찾을 수 있습니다.modules
일 때 및classes
참조되는 경우 Zeitwerk는 일치하는 파일 이름으로 루트 네임스페이스를 검색하는 것을 알고 있습니다. 예를 들어,
require 'zeitwerk'
loader = Zeitwerk::Loader.new
loader.push_dir("app/models")
loader.push_dir("app/controllers")
// matches as follows
app/models/user.rb -> User
app/controllers/admin/users_controller.rb -> Admin::UsersController
두 가지 사용 사례에 대해 루트 네임스페이스를 정의하는 두 가지 기본 방법이 있습니다. 기본 방법은 다음과 같습니다.
// init.rb
require 'zeitwerk'
loader = Zeitwerk::Loader.new
loader.push_dir("#{__dir__}/bar")
...
loader.setup
// bar/foo.rb
class Foo; end
이것은 Foo
클래스를 의미합니다. 명시적인 Bar::Foo
없이 참조할 수 있습니다. , bar 디렉토리가 루트 네임스페이스 역할을 하기 때문입니다. 네임스페이스를 정의하는 두 번째 방법은 push_dir
호출에서 네임스페이스를 명시적으로 지정하는 것입니다. :
// init.rb
require 'zeitwerk'
module Bar
end
loader = Zeitwerk::Loader.new
loader.push_dir("#{__dir__}/src", namespace: Bar)
loader.setup
// src/foo.rb
class Bar::Foo; end
이 코드에서 주의해야 할 몇 가지 사항이 있습니다.
- 모듈
Bar
push_dir
에서 사용하기 전에 이미 정의되었습니다. . 사용하려는 모듈이 타사에 의해 정의된 경우push_dir
호출에서 사용하기 전에 간단한 require가 모듈을 정의합니다. . push_dir
명시적으로 네임스페이스Bar
를 지정합니다. .- 파일
src/foo.rb
정의된Bar::Foo
Foo
가 아닌 , 그리고src/bar/foo.rb
와 같은 디렉토리를 생성할 필요가 없었습니다. .
-
독립 코드 로더:설계상 Zeitwerk를 사용하면 각 프로젝트 또는 앱 종속성이 개별 프로젝트 트리를 관리할 수 있습니다. 이는 각 종속성의 코드 로딩 메커니즘이 해당 종속성에 의해 관리됨을 의미합니다. 예를 들어, Rails 6에서 Zeitwerk는 Rails 앱에 대한 코드 로드를 처리하고 각 gem 종속성이 자체 프로젝트 트리를 개별적으로 관리할 수 있도록 합니다. 여러 코드 로더 간에 파일이 겹치는 것은 오류 조건입니다.
-
자동 로드:위의 설정으로
setup
을 호출하면 모든 클래스와 모듈은 주문형으로 제공될 것입니다. -
다시 로드:다시 로드를 활성화하려면
loader
명시적으로 구성해야 합니다. 예를 들어,
loader = Zeitwerk::Loader.new
...
loader.enable_reloading # you need to opt-in before setup
loader.setup
...
loader.reload
loader.reload
호출은 프로젝트 트리를 즉석에서 다시 로드하고 모든 새로운 변경 사항을 즉시 볼 수 있습니다. 그러나 파일 시스템의 변경 사항을 감지하고 loader.reload
를 호출하기 위한 주변 메커니즘이 여전히 필요합니다. . 간단한 버전은 다음과 같습니다.
require 'filewatcher'
loader = Zeitwerk::Loader.new
...
loader.enable_reloading
loader.setup
...
my_filewatcher = Filewatcher.new('lib/')
Thread.new(my_filewatcher) {|fw| fw.watch {|filename| loader.reload } }
Rails에서 Zeitwerk 사용
Zeitwerk는 Rails 6.0에서 기본적으로 활성화되어 있습니다. 그러나 선택 해제하고 Rails classic
을 사용할 수 있습니다. 코드 로더.
# config/application.rb
config.load_defaults "6.0"
config.autoloader = :classic
보석에서 Zeitwerk 사용
Zeitwerk는 표준 gem 구조(lib/special_gem
). 이 편리한 방법은 다음과 같이 사용할 수 있습니다.
# lib/special_gem.rb
require 'zeitwerk'
module SpecialGem
end
loader = Zeitwerk::Loader.for_gem
loader.setup
표준 gem 구조를 사용하면 for_gem
호출은 lib
를 추가합니다. 디렉토리를 루트 네임스페이스로 사용하여 lib
의 모든 코드 활성화 디렉토리를 자동으로 찾습니다.
더 많은 영감을 얻으려면 Zeitwerk를 사용하여 보석을 확인하십시오.
- 카라프카
- 제트기
참조
Rails 자동 로딩 — 작동 방식 및 작동하지 않는 경우
자이트베르크