Vuejs多頁weback配置

webpack的流行給前端開發減小了許多沒必要要的工做,webpack可讓咱們更純粹的關注咱們的代碼,可是不少人認爲它更適合單頁應用,主要有如下一些痛點javascript

  • 若是模板是後臺管理的生成的怎麼辦
  • 我目前沒有使用任何模塊化的開發方式,或使用了模塊加載器(如seajsrequireJs等)

其實第二點我已經在上篇文章中講過了,若是平滑的過渡到webpack,痛點一也解釋過,只是沒有詳細的說明,這次分享一個完整的配置,來應對你的多頁項目。不論是jspphphtmlxshtml均可以經過具體的配置來使用webpack,爲何如此青睞webpack,在我看來熱更新技術lesssasses6es7的引入是最吸引個人(嘗試過使用gulp、可是感受並無webpack這種一站式服務來得順手),下面我詳細講述下下面一些配置的用途,部分代碼來自vue-cliphp

├─build                 // webpack的配置文件存放目錄
├─Public                // 咱們的前端資源存放目錄
│  ├─dev                // 源碼存放目錄(能夠更名爲src)
│  │  ├─css             // 一些共用的css文件,共用才放這裏哦
│  │  ├─font            // 字體文件
│  │  ├─images          // 圖片文件
│  │  └─js              // js文件
│  │      ├─libs        // npm裏沒有的第三方插件或庫
│  │      ├─modules     // 項目的業務組件存放目錄
│  │      └─page        // 頁面的目錄
│  │          └─Index   // 具體的頁面名稱
│  └─dist               // 編譯後的存放目錄
└─static                // 好像是拿來緩存文件用的?vue-cli存在的

固然,我目前開發的項目是半路引入webpack的,大部分都仍是jQuery那套東西、可是我仍是秉着關注點分離的原則,將htmlcssjs按頁面來放了,再也不使用老掉牙的按文件類型來放、那是由於有了webpack的打包才能夠這麼隨意。除了分離出來的模板(ThinkPHP<include file=""/>標籤來引入模板)文件,js和css都是放到同模板名的Public/dev/js/modules目錄裏了,這樣一來能夠直接像這樣css

require( './style.less' );
...

先在js文件的頭部引入這個組件的樣式文件,再來寫js代碼,至少咱們在使用組件的時候沒必要關心css了(下篇文章會講講重構後如何連html也不關注了)html

images

這裏爲何會有一個images目錄看起來不少餘呢,那是由於咱們的php模板裏的圖片標籤src前面都帶了一個php的系統變量,webpack插件的靜態分析是沒法識別這裏的路徑的,因此保留了這個目錄,在打包後用插件拷貝到打包目錄裏前端

page

而後是page這個目錄,這個目錄是拿來存放咱們頁面的三劍客的,好比有一個叫index的目錄,裏面有cssjshtml文件,這裏的index能夠看做是一個頁面目錄,也能夠看做是一個分類,若是是分類,那下面就應該是頁面了,html裏不該該引用css文件和js文件,由於webpack會幫咱們插入生成新的html到咱們指定的目錄裏vue

最重要的就是build目錄下的了java

config.js

proxyTable項我已經在上篇文章中講過了,這裏就不贅述了webpack

mapping.js

這個文件就是描述咱們entry也就是入口文件和html模板之間的關係映射的文件的git

module.exports = {
  // 微知首頁
  'Index': {
    // 對應到Public/dev/js/page的文件夾名稱
    file: 'main',
    // 視圖層的文件名稱,默認爲index
    viewFile: 'index',
    disable: false,
    templateOutput: 'Index'
  },
  'EditText': {
    chunks: [ 'editor' ],
    disable: false
  },
  // 編輯模板
  'Template': {
    chunks: [ 'editor' ],
    disable: true
  },
  // 默認模板
  'GzhArtStyle': {
    chunks: [ 'editor' ],
    disable: true
  }
};

這裏導出的每一個對象的鍵值都對應了page目錄裏的名字,下面的file字段對應的入口js文件名稱,默認爲mainviewFile對應的是html模板名稱,默認爲index,這裏頗有用,由於在ThinkPHPView目錄裏模板部分文件夾的,因此咱們配合templateOutput把html輸出過去就不存在目錄了,templateOutput的默認值爲這個對象的鍵值如Index默認爲Index。disable字段是開發模式使用的,當運行npm run dev命令時會自動掃描這個字段,若爲false纔會啓動,若是所有都爲false,那麼你頁面越多形成性能開銷就越大,因此除非你同時去開發幾個頁面,這裏建議啓動的頁面不超過5個,其餘頁面若要運行,提早npm run build一次讓它跑編譯後的代碼就行了。chunks字段是用來標記當前頁面依賴的除了共有chunks須要依賴的其餘chunks,上面的有chunks字段的三個頁面都是引用了百度編輯器,由於百度編輯器的包都太大了,因此不建議抽取到公用的chunk裏,這裏的配置在webpack.prod.cfg.js文件裏有單獨配置。es6

utils.js

這個文件主要是getHtmlWebpackPlugins方法,配合註釋您就能看懂剛纔的mapping配置都怎麼用的了

exports.getHtmlWebpackPlugins = ( rename ) => {
  let HtmlWebpackPlugins = [];
  Object.keys( mapping ).forEach( function( name ) {
    // 若是不是開發環境 就所有打包
    // 若是是開發環境 就根據disable來進行打包
    ( process.env.NODE_ENV !== 'development' ||
      !mapping[ name ].disable ) &&
    HtmlWebpackPlugins.push(
      new HtmlWebpackPlugin( {
        alwaysWriteToDisk: true,
        // php端使用到的模板
        // 若是是其餘目錄在此修改路徑
        filename: `${ROOT}/Application/Home/View/${mapping[ name ].templateOutput ? mapping[ name ].templateOutput : name}/${mapping[name].viewFile || 'index'}.html`,
        // 插件用的模板文件
        template: `${ROOT}/${config.$d}/js/page/${name}/${mapping[name].viewFile || 'index'}.${mapping[name].templateType || 'html'}`,
        chunks: ( function() {
          if ( !rename ) {
            //let chunks = [ 'vendor.npm', 'vendor.TP', 'manifest', 'vendor.modules' ];
            let chunks = [ 'vendor.modules', 'vendor', 'manifest' ];
            if ( mapping[ name ].chunks ) {
              chunks = chunks.concat( mapping[ name ].chunks );
            }
            return chunks;
          }
          return [];
        }() ).concat( [ `${rename ? config.dev.entryPrefix : ''}${name}` ] ),
        // 手工排序
        chunksSortMode: 'manual',
        inject: true,
        showErrors: false
      } ) );
  } );
  return HtmlWebpackPlugins;
}

alwaysWriteToDisk這個字段是咱們能先後端結合開發的關鍵,沒有使用後端模板的項目真的作到先後分離時是不須要這個字段的,由於PHP會讀這個文件再渲染數據出來給瀏覽器

webpack.base.cfg.js、webpack.dev.cfg.js

都是些老生常談的配置,這裏就不贅述了。值得注意的是dev.client.js這個文件被我刪了,由於使用了alwaysWriteToDisk實時寫入的功能,改變css文件和js文件都會強制刷新,那熱更新徹底就無法用了,因此html文件的變化仍是須要手動刷新的

webpack.prod.cfg.js

HtmlWebpackPlugin這個插件確實是有多少頁面就要插入多少個實例進去的,因此直接

...utils.getHtmlWebpackPlugins( false ),

展開這個數組就行了,這裏傳入的布爾參數是爲了區分開發模式和build模式,傳入true只會有一個chunk被包含進來,就是當前頁面依賴的全部js和css等
而後是chunks

manifest

有的頁面由於太簡單並無依賴太多共用的js,可是依賴了共用的css,因此這個chunk僅僅是爲了抽取css文件用,形成引用了一個空的js,暫時沒有想到好的解決辦法,歡迎再issues提出改進建議

vendor.modules

這個chunk是爲了抽取咱們本身寫的業務組件、在修改業務組件後可以很好的利用緩存只更新這一個文件

commonChunk

上文mapping裏的chunks字段就是這裏配置的,若是還有其餘局部共用的大chunk能夠在這裏再配置一個

vendor

vendor就是拿來放置第三方插件的,這裏抽取了npm和lib裏面的,當項目穩定後處於一個穩定的維護期,沒有較大改動時,這個文件就能夠長期緩存在用戶的電腦裏了。

new CopyWebpackPlugin( [ {
  from: path.resolve( __dirname, `../${config.$d}/images` ),
  to: `${config.build.assetsSubDirectory}/images`,
  ignore: [ '.*' ]
} ] ),

上面的代碼就是拷貝images這個目錄到咱們打包生成的目錄裏,防止資源丟失的問題


這個腳手架極可能沒法直接運行在你的項目裏,可是能爲你的多頁入口的website提供一個很好的引入webpack的思路

嗯,留下倉庫傳送門
博客地址have fun ~~

相關文章
相關標籤/搜索