搭建一個多頁面的無依賴的工程化專案

相學長發表於2017-10-27

最近金拱門比較火,我們先戳開它的官網看看。

看完後,如果你老闆要是讓你做這麼一個網站,一定要seo,一定要相容IE,你會怎麼去做呢?

用vue/react吧,單頁應用滿足不了seo,而且IE相容性不好。上node中間層做服務端渲染又把事情搞麻煩了。只能用JQuery幹,但是又該怎麼做工程化呢?好像也不是很容易。因為目前大家的工程化方案多是一整套單頁應用全家桶,如vue-cli的webpack模板。

而前端到如今這個階段,再讓大家接手一個沒有工程化的專案,肯定內心非常牴觸了。試想這麼一個專案,手動link資源,不能寫less/sass,不能寫ES6,不能依賴管理,不能編譯打包...,哦天,想都不敢想。可是工程化這事在實際業務中卻沒有大家想象中的那麼順利。比如剛剛金拱門的官網,頁面很多,要求滿足SEO,IE相容。而且遇到這些專案,往往還會有這些問題:

  1. 由於頁面是後端渲染,需要部署後端程式(php,java之類),各種環境配置相當麻煩。
  2. 前端的html程式碼依託於服務端,導致前端做工程化時,很難對接前後端專案。

也就是說,我們需要做一個非單頁應用的工程化專案。這個專案線上上時是前後端耦合的,但是在開發時,我們又不想前後端耦合。再整理一下,我們需要解決的問題有:

  1. 前後端分離,前端開發不能依賴於後端環境。
  2. 前端工程化。諸如靜態資源的打包編譯、依賴的管理、元件化等等。

明確了要解決的問題後,我們就可以開始了。我們可以用webpack搭建一個專案,幫我們做一些打包、編譯、檔案處理這些工程化工作。webpack從零配置比較繁瑣,我們可以選擇修改一個輪子,比如把vue-cli的webpack模板改造一下,刪了沒必要的vue-loader,給它增加一下多頁面入口就好了。

修改輪子

第一步:理解 vuejs-templates/webpack

npm install -g vue-cli

vue init webpack my-project複製程式碼

既然要改人家的模板,先得理解人家都做了什麼。這裡就不帶大家讀程式碼了,根據package.json的命令一個個檔案的程式碼看過去就知道了,很直接很暴力。

第二步:刪

既然我們不需要用vue,那麼對於vue檔案處理的相關邏輯我們就不需要了。根據剛剛對這個模板的瞭解,我們知道vue-loadervue-style-loader是不需要的。所以刪除對應的程式碼跟package.json裡面的包就好了。

多提一點的是,vue-style-loader雖然不需要,style-loader還是需要的,所以需要用後者替換前者。

第三步:加

做減法容易,做加法就沒這麼輕鬆了。根據我們剛剛的需求,我們應該給它加個多頁面入口。網上有非常多的webpack多入口配置教程。然而他們不一定就能滿足我們的需求。他們普遍存在如下問題:

  1. 入口檔案需要自己配置。在一個頁面較多的專案中,入口檔案應當從約定的目錄中自動讀取,也更符合約定優於配置。
  2. 多入口是針對js的。由於業界普遍是在用單頁應用,頁面由js生成,故多頁面只要多個js入口就好,不需要直接寫html。而我的需求不是,我希望的多入口是針對html檔案而言的。

不過當我們解決了上述兩個問題後,我們還會有一個新的問題。我們不同的html檔案,其實又是有公共的部分的。比如都有 header,footer。也就是說,我們需要給這些html檔案增加一個模板。我們可以通過webpack的loader來實現,但是沒有現成的loader可以比較好的解決。那怎麼辦呢?可以參考我另外一篇文章。編寫自己的Webpack Loader

靜態資源的版本控制

上述問題解決後,我們的工作並未完成。現在這個專案的靜態資源是以檔案雜湊值來控制的。可惜有的專案的靜態資源是要後端來更新時間戳控制的。雖然這不是個好方案,但有些工程卻依舊是這樣。沒辦法,為了適應他們,我們必須得去掉雜湊值。可是這樣的話,當我們想更新css內引用的圖片時又沒轍了,因為css內鏈的圖片後端沒法控制版本。

這個該怎麼解決呢?感謝webpack,我們可以通過如下的配置來實現:

{
  test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
  oneOf: [
    {
      issuer: /\.html$/,
      loader: 'url-loader',
      options: {
        limit: 10000,
        name: utils.assetsPath('img/[name].[ext]',)
      }
    },
    {
      issuer: /\.(css|less)$/,
      loader: 'url-loader',
      options: {
        limit: 10000,
        name: utils.assetsPath('img/[name].[hash:7].[ext]')
      }
    }
  ]
}複製程式碼

意思就是如果圖片是在html中引用的則不加雜湊值,在css檔案中引入的則加上。

完工

這樣我們就完成了一個簡單的專案架構。它能幫助我們實現檔案的打包、編譯,html的模板控制等功能。最終能build出一份html+靜態資源的web頁面直接釋出cdn。當然也可以把它們直接扔給後端。

不過這個架子還不是非常的完善,應用場景也有限,比較適用於一些互動較少、頁面較多、看重seo或者傳統後端套頁面的網站。另外,作為工程化中非常重要的元件化與測試,由於沒有任何框架的引入,這點也需要使用者自己再去摸索。

另外,如果還是想用vue,react或angular,又不想搞他們的服務端渲染,可以嘗試下變相的服務端渲染系統

最後,如果這個架子對您有用,歡迎戳開github

--閱讀原文 --轉載請先經過本人授權-丁香園F2E @相學長

相關文章