جاسازی فایلهای استاتیک
اگر همراه ما هستید، اولین کاری که باید انجام دهید ایجاد یک فایل جدید ui/efs.go است:
$ touch 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 ارجاع داده میشود ذخیره کند.
چند نکته مهم در مورد این موضوع وجود دارد که باید توضیح دهیم:
دستورالعمل کامنت باید بلافاصله بالای متغیری که میخواهید فایلهای جاسازی شده را در آن ذخیره کنید قرار گیرد.
دستورالعمل فرمت
go:embed "<path>"دارد. مسیر نسبت به فایل.goحاوی دستورالعمل است، بنابراین — در مورد ما —go:embed "static"دایرکتوریui/staticرا از پروژه ما جاسازی میکند.شما فقط میتوانید دستورالعمل
go:embedرا روی متغیرهای سراسری در سطح package استفاده کنید، نه در داخل توابع یا متدها. اگر سعی کنید آن را در داخل یک تابع یا متد استفاده کنید، در زمان کامپایل خطای"go:embed cannot apply to var inside func"دریافت خواهید کرد.مسیرها نمیتوانند شامل عناصر
.یا..باشند، و همچنین نمیتوانند با/شروع یا پایان یابند. این اساساً شما را محدود میکند به جاسازی فقط فایلها یا دایرکتوریهایی که در همان دایرکتوری فایل.goحاوی دستورالعملgo:embedهستند.سیستم فایل جاسازی شده همیشه در دایرکتوری حاوی دستورالعمل
go:embedریشه دارد. بنابراین، در مثال بالا، متغیرFilesما شامل یک سیستم فایل جاسازی شدهembed.FSاست و ریشه آن سیستم فایل دایرکتوریuiما است.
استفاده از فایلهای استاتیک جاسازی شده
حالا بیایید برنامه خود را تغییر دهیم تا فایلهای استاتیک CSS، JavaScript و تصویر را از سیستم فایل جاسازی شده سرو کند — به جای خواندن آنها از دیسک در زمان اجرا.
فایل 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 مراجعه میکنید، فایلهای استاتیک باید از سیستم فایل جاسازی شده سرو شوند و همه چیز باید عادی به نظر برسد.
اگر میخواهید، همچنین میتوانید مستقیماً به فایلهای استاتیک بروید تا بررسی کنید که هنوز در دسترس هستند. به عنوان مثال، مراجعه به https://localhost:4000/static/css/main.css باید stylesheet CSS صفحه وب را از سیستم فایل جاسازی شده نمایش دهد.
اطلاعات اضافی
مسیرهای چندگانه
کاملاً درست است که چندین مسیر را در یک دستورالعمل 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