Let's Go جاسازی فایل › جاسازی فایل‌های استاتیک
قبلی · فهرست · بعدی
فصل ۱۲.۱.

جاسازی فایل‌های استاتیک

اگر همراه ما هستید، اولین کاری که باید انجام دهید ایجاد یک فایل جدید ui/efs.go است:

$ touch ui/efs.go

سپس کد زیر را اضافه کنید:

File: ui/efs.go
package ui

import (
    "embed"
)

//go:embed "static"
var Files embed.FS

خط مهم در اینجا //go:embed "static" است.

این شبیه یک کامنت به نظر می‌رسد، اما در واقع یک دستورالعمل کامنت خاص است. وقتی برنامه ما کامپایل می‌شود (به عنوان بخشی از go build یا go run)، این دستورالعمل کامنت به Go دستور می‌دهد که فایل‌های پوشه ui/static ما را در یک سیستم فایل جاسازی شده که توسط متغیر سراسری Files ارجاع داده می‌شود ذخیره کند.

چند نکته مهم در مورد این موضوع وجود دارد که باید توضیح دهیم:

استفاده از فایل‌های استاتیک جاسازی شده

حالا بیایید برنامه خود را تغییر دهیم تا فایل‌های استاتیک CSS، JavaScript و تصویر را از سیستم فایل جاسازی شده سرو کند — به جای خواندن آن‌ها از دیسک در زمان اجرا.

فایل cmd/web/routes.go خود را باز کنید و آن را به این صورت به‌روزرسانی کنید:

File: cmd/web/routes.go
package main

import (
    "net/http"

    "snippetbox.alexedwards.net/ui" // New import

    "github.com/justinas/alice"
)

func (app *application) routes() http.Handler {
     mux := http.NewServeMux()

    // Use the http.FileServerFS() function to create a HTTP handler which 
    // serves the embedded files in ui.Files. It's important to note that our 
    // static files are contained in the "static" folder of the ui.Files
    // embedded filesystem. So, for example, our CSS stylesheet is located at
    // "static/css/main.css". This means that we no longer need to strip the
    // prefix from the request URL -- any requests that start with /static/ can
    // just be passed directly to the file server and the corresponding static
    // file will be served (so long as it exists).
    mux.Handle("GET /static/", http.FileServerFS(ui.Files))

    dynamic := alice.New(app.sessionManager.LoadAndSave, noSurf, app.authenticate)

    mux.Handle("GET /{$}", dynamic.ThenFunc(app.home))
    mux.Handle("GET /snippet/view/{id}", dynamic.ThenFunc(app.snippetView))
    mux.Handle("GET /user/signup", dynamic.ThenFunc(app.userSignup))
    mux.Handle("POST /user/signup", dynamic.ThenFunc(app.userSignupPost))
    mux.Handle("GET /user/login", dynamic.ThenFunc(app.userLogin))
    mux.Handle("POST /user/login", dynamic.ThenFunc(app.userLoginPost))

    protected := dynamic.Append(app.requireAuthentication)

    mux.Handle("GET /snippet/create", protected.ThenFunc(app.snippetCreate))
    mux.Handle("POST /snippet/create", protected.ThenFunc(app.snippetCreatePost))
    mux.Handle("POST /user/logout", protected.ThenFunc(app.userLogoutPost))

    standard := alice.New(app.recoverPanic, app.logRequest, commonHeaders)
    return standard.Then(mux)
}

اگر این تغییرات را ذخیره کنید و سپس برنامه را دوباره راه‌اندازی کنید، باید ببینید که همه چیز به درستی کامپایل و اجرا می‌شود. وقتی در مرورگر خود به https://localhost:4000 مراجعه می‌کنید، فایل‌های استاتیک باید از سیستم فایل جاسازی شده سرو شوند و همه چیز باید عادی به نظر برسد.

12.01-01.png

اگر می‌خواهید، همچنین می‌توانید مستقیماً به فایل‌های استاتیک بروید تا بررسی کنید که هنوز در دسترس هستند. به عنوان مثال، مراجعه به https://localhost:4000/static/css/main.css باید stylesheet CSS صفحه وب را از سیستم فایل جاسازی شده نمایش دهد.

12.01-02.png

اطلاعات اضافی

مسیرهای چندگانه

کاملاً درست است که چندین مسیر را در یک دستورالعمل embed مشخص کنید. به عنوان مثال، می‌توانیم دایرکتوری‌های ui/static/css، ui/static/img و ui/static/js را به صورت جداگانه جاسازی کنیم:

//go:embed "static/css" "static/img" "static/js" 
var Files embed.FS

جاسازی فایل‌های خاص

در ابتدای فصل به این اشاره کردم، اما ممکن است یک مسیر embed به یک فایل خاص اشاره کند. جاسازی فقط به دایرکتوری‌ها محدود نیست.

به عنوان مثال، بیایید فرض کنیم که دایرکتوری ui/static/css ما شامل برخی دارایی‌های اضافی است که نمی‌خواهیم جاسازی کنیم، مانند فایل‌های Sass یا Less. در آن صورت، می‌توانیم فقط فایل ui/static/css/main.css را جاسازی کنیم:

//go:embed "static/css/main.css" "static/img" "static/js" 
var Files embed.FS

مسیرهای wildcard

کاراکتر * می‌تواند به عنوان یک ‘wildcard’ در یک مسیر embed استفاده شود. با ادامه مثال بالا، می‌توانیم دستورالعمل embed را بازنویسی کنیم تا فقط فایل‌های .css زیر ui/static/css جاسازی شوند:

//go:embed "static/css/*.css" "static/img" "static/js" 
var Files embed.FS

مربوط به آن، اگر از مسیر wildcard "*" بدون هیچ واجد شرایطی استفاده کنید، مانند این:

//go:embed "*"
var Files embed.FS

… سپس همه چیز در دایرکتوری فعلی را جاسازی می‌کند، از جمله فایل .go که خود دستورالعمل embed را شامل می‌شود! بیشتر اوقات شما این را نمی‌خواهید، بنابراین معمول‌تر است که به صراحت زیردایرکتوری‌ها یا فایل‌های خاص را جاسازی کنید.

پیشوند all

در نهایت، اگر یک مسیر به یک دایرکتوری باشد، همه فایل‌های آن دایرکتوری به صورت بازگشتی جاسازی می‌شوند — به جز فایل‌هایی با نام‌هایی که با کاراکترهای . یا _ شروع می‌شوند. اگر می‌خواهید آن فایل‌ها را نیز شامل کنید، باید از پیشوند all: در ابتدای مسیر استفاده کنید.

//go:embed "all:static"
var Files embed.FS