1. 程式人生 > >將 laravel 專案內靜態檔案,css、js、images 部署到七牛雲 CDN

將 laravel 專案內靜態檔案,css、js、images 部署到七牛雲 CDN

專案升級,打算把 public 目錄下的 css、js、image等檔案,上傳到七牛雲,一直想搞來著,今天又想起來,正好 laravel 也從 5.2 升級到了 5.7,接下來把這邊一搞,專案就更加優化了。

接上篇文章:
	使用 qshell 將本地檔案同步到七牛雲
	https://blog.csdn.net/beyond__devil/article/details/83030702

1>我們通過 qshell 已經可以將本地靜態檔案,上傳到七牛雲了,七牛雲相關處理:

	1.登入七牛雲,開啟物件儲存,建立一個全新的 '儲存空間'。

	2.對新建立的空間進行配置,主要是 '繫結域名' 的配置。因為預設的是有 '測試域名',而測試域名無法用於生產環境,我們需要配置自己的域名。
		域名配置,屬於 '融合 CDN',我們需要對熟悉這裡的文件:
			https://developer.qiniu.com/fusion

		這裡卡了我很久,一直不太明白是什麼意思(因為對網路知識的不瞭解)。配置起來很簡單

		假設,我們網站使用的域名是:
			www.kissyou.com

		想要為七牛雲配置一直加速域名(我們建立的七牛雲的域名型別為:普通域名):
			qiniu.kissyou.com

		我們在 '建立域名->加速域名' 這裡,填寫的就是 'qiniu.kissyou.com',然後完成其他配置,點選 '建立',就新建了一個域名。同時會得到一個 'CNAME',下面會用到

		然後,我們登入我們的 '域名服務商',我用的 '阿里雲',登入後,給該域名下,新增一個 'qiniu.kissyou.com' 的解析。這個解析和平常我們的網站解析不一樣,使用的記錄型別是 'CNAME'。

		新增解析記錄:
			記錄型別 - CNAME
			主機記錄 - qiniu
			解析線路 - 預設
			記錄值 - 我們上面獲取到的 '七牛雲的CNAME'
			TTL - 預設

		是否配置成功,檢視相關文件介紹

	3.使用 qshell 上傳我們本地的靜態檔案,css、js、images等

	到此,七牛雲的配置基本結束。

2>接著,開始重構 laravel 專案:
	1.剛開始也不清楚,laravel 該如何配置 CDN。我先簡述下,我的專案目前的情況:
		1)專案裡檔案上傳的地方,全部使用了 '七牛雲上傳',但是是硬編碼的,在每個上傳的地方,直接使用專案裡自定義公共的七牛雲上傳函式,並未使用 laravel 的檔案系統,這樣導致的問題就是:laravel 的檔案系統的配置基本無用,不論是本地、測試環境,都是上傳到七牛雲上了,而且給資料庫上傳檔案,直接儲存的路徑就是已經添加了七牛雲的域名:http://xxx/images/xxx.jpg。(可能也是因為重構外包專案,自己壓根沒有想這塊~,正常趁這次重構了這種寫法)
			$avatar = 'http://7xt4e8.com1.z0.glb.clouddn.com/uploads/2016-07/20160727151312505.png';
			<img src="{{ $avatar }}">

		2)專案中的靜態檔案,css、js、images,前端這套,又使用的是本地的,引用時是相對專案域名(這邊可以通過 qshell 全部上傳到七牛雲)
			<javascript src="/js/test.js"></javascript>
			<img src="/images/test.jpg">

		3)1和2的問題,都可以解決掉,現在我們專案的靜態資源和上傳檔案,都已經到了七牛雲,我們在本地該如何引入呢?
			這次重構,會使用 laravel 的檔案系統,要求本地或測試環境時,我們不一定上傳到七牛雲,線上環境得上傳到七牛雲,不同的 laravel 檔案系統,如何保證靜態檔案和上傳檔案的訪問,方便配置。

			thinkphp 提供了一個 '__CDN__' 的配置字首:
				<javascript src="__CDN__/js/test.js"></javascript>
				如何是本地檔案,define('__CND__', '') 即可。
				如果是七牛雲檔案,define('__CND__', 'http://xxx') 即可。

			而 laravel 中,發現並沒有提及到任何這種配置,唯一我們在文件中,經常看到的是推薦使用 'asset()' 函式來引用前端資源。並未有 thinkphp CDN 相關的這種配置(這裡我是相當困惑,是我自己哪裡出問題了,還是 laravel 讓我們自己來發揮)

			我想到的解決方法是:
				.env 新增配置:
					CDN=xxx

				config/custom.php 新增配置(我專案裡自己添加了 custom.php 配置檔案,用於專案裡一些自定義的配置):
					'cdn' => env('CDN', 'http://qiniu.kissyou.com'),		// 預設給的是上面定義的 '七牛雲融合 CDN' 域名

				這樣,我們引入檔案時,以 js 檔案為例:
					<script src="{{ asset(config('custom.cdn') . 'js/jquery-1.11.2.min.js') }}"></script>

				這種寫法,有點繁瑣啊,給每個靜態檔案的引入前,都得新增 config('custom.cdn') 字首,更好的方式是,需要我們自定義一個類似 'asset()' 的公共函數了:
					if ( !function_exists(custom_asset())) {
						function custom_asset($path, $secure = null){
							$path = config('custom.cdn') . $path;
							asset($path, $secure);	
						}
					}
					<script src="{{ custom_asset('js/jquery-1.11.2.min.js') }}"></script>

				laravel 的 Routing/UrlGenerator.php 裡其實也提到了一個和 asset() 類似的方法 assetFrom():
				    /**
				     * Generate the URL to an asset from a custom root domain such as CDN, etc.
				     *
				     * @param  string  $root
				     * @param  string  $path
				     * @param  bool|null  $secure
				     * @return string
				     */
				    public function assetFrom($root, $path, $secure = null)
				    {
				        // Once we get the root URL, we will check to see if it contains an index.php
				        // file in the paths. If it does, we will remove it since it is not needed
				        // for asset paths, but only for routes to endpoints in the application.
				        $root = $this->formatRoot($this->formatScheme($secure), $root);

				        return $this->removeIndex($root).'/'.trim($path, '/');
				    }

				    介紹的是:根據一個自定義的根域名,例如 CDN 等,來生成元件的URL

				    但是,一樣很麻煩,並未給我們統一的配置。還是需要我們來自定義公共的 CDN 配置(只是比 asset() 方法稍微進化了一點點):
				    	<script src="{{ URL::assetFrom(config('custom.cdn'), 'js/jquery-1.11.2.min.js') }}"></script>

				    我們也可以使用它來改造我們自定義的 custom_asset() 函式:
				    	use URL;
						if ( !function_exists(custom_asset())) {
							function custom_asset($path, $secure = null){
								URL::assetFrom(config('custom.cdn'), $path, $secure);	
							}
						}

				兩種函式,我們自己選擇,配置時,都需要注意點!!!(.env 和 config/custom.php 都需要注意,方法我們寫的不夠強健,沒有處理 '', null, '/' 幾個小問題,有時間了再寫下)

	2.總覺得非官方的不妥,laravel 不應該不考慮這個問題啊,網上搜索相關內容,有關 laravel cdn 的包,主要有 2 個:
		vinelab/cdn
		publiux/laravelcdn(這個還是 fork 的 vinelab/cdn)

		publiux/laravelcdn 相關內容:
			github 地址:
				https://github.com/publiux/laravelcdn

			github 官網:
				http://publiux.github.io/laravelcdn/

			簡單看了下文件和原始碼:
				laravel 的檔案系統是從 laravel 5 開始引入的,而 laravelcdn 是從 laravel 4 開始的。
				laravelcdn 定義了命令 push 和 empty 命令,此外其他方法就是類似 laravel 的檔案系統。
				而且,它還只支援 'aws - s3'
				最大的優點就是定義了 laravel 中未定義的 CDN 這種訪問配置,幾個訪問配置函式:
					{{Cdn::asset('assets/js/main.js')}}
					{{Cdn::path('private/something/file.txt')}}

			總結:
				對於使用 'aws-s3' 的使用者,可能還有點用。對於想切換其他 laravel 檔案系統的,基本沒用(而且,寫法和 laravel 檔案系統可能不一致,建議放棄使用!)
				如果只是為了呼叫靜態資源和上傳檔案的訪問,我們目前自定義函式即可,只是寫的再強大點就好了!

	3.對於我當前專案中的上傳,未使用 laravel 檔案系統,硬編碼七牛雲上傳的問題,進行改造:
		參考文章: 
			基於七牛雲 PHP SDK + Laravel 檔案儲存實現 Laravel 學院靜態資源雲端儲存及 CDN 加速
			https://laravelacademy.org/post/9486.html

		擴充套件 laravel 檔案系統,新增 '七牛雲' 儲存引擎,這裡直接參考上述文章即可!
		新增完成後,改造專案中上傳的程式碼。

改造的過程,放到下一篇筆記。。。