1. 程式人生 > >webpack打包多頁面的方式

webpack打包多頁面的方式

一開始接觸webpack是因為使用Vue的關係,因為Vue的腳手架就是使用webpack構建的。剛開始的時候覺得webpack就是為了打包單頁面而生的,後來想想,這麼好的打包方案,只在單頁面上使用是否太浪費資源了呢?如果能在傳統多頁面上使用webpack,開始效率是否會事半功倍呢?好在眾多優秀的前端開發者已經寫了許多demo和文章供人學習。我也寫了一個小專案,希望對大家學習webpack有幫助。

webpack-multi-page

專案解決的問題

  • SPA好複雜,我還是喜歡傳統的多頁應用怎麼破?又或是,我司專案需要後端渲染,頁面模板怎麼出?
  • 每個頁面相同的UI佈局好難維護,UI稍微改一點就要到每個頁面去改,好麻煩還容易漏,怎麼破?
  • 能不能整合進ESLint來檢查語法?
  • 能不能整合postcss來加強瀏覽器相容性?
  • 我可以使用在webpack中使用jquery嗎?
  • 我可以使用在webpack中使用typescript嗎?

src目錄對應dist目錄

當我們使用webpack打包多頁面,我們希望src目錄對應打包後dist目錄是如上圖這樣的,開發根據頁面模組的思路搭建開發架構,然後經過webpack打包,生成傳統頁面的構架。

/**
 * 建立打包路徑
 */
const createFiles = function() {
 const usePug = require('../config').usePug;
 const useTypeScript = require('../config').useTypeScript;
 const path = require('path');
 const glob = require('glob');
 const result = [];
 const type = usePug ? 'pug' : 'html';
 const scriptType = useTypeScript ? 'ts' : 'js';
 const files = glob.sync(path.join(__dirname, `../src/views/**/*.${type}`));
 for (file of files) {
  result.push({
   name: usePug ? file.match(/\w{0,}(?=\.pug)/)[0] : file.match(/\w{0,}(?=\.html)/)[0],
   templatePath: file,
   jsPath: file.replace(type, scriptType),
   stylePath: file.replace(type, 'stylus')
  });
 }
 return result;
};//歡迎加入前端全棧開發交流圈一起學習交流:864305860

利用這個方法,我們可以獲得需要打包的檔案路徑(方法中獲取檔案路徑的模組也可使用fs模組),根據獲得打包的檔案路徑,我們可以使用html-webpack-plugin來實現多頁面打包。 由於每一個html-webpack-plugin的物件例項都只針對/生成一個頁面,因此,我們做多頁應用的話,就要配置多個html-webpack-plugin的物件例項:

const plugins = function() {
 const files = createFiles();
 const HtmlWebpackPlugin = require('html-webpack-plugin');
 const path = require('path');
 const ExtractTextPlugin = require('extract-text-webpack-plugin');
 
 let htmlPlugins = [];
 let Entries = {};
 files.map(file => {
  htmlPlugins.push(
   new HtmlWebpackPlugin({
    filename: `${file.name}.html`,
    template: file.templatePath,
    chunks: [file.name]
   })//歡迎加入前端全棧開發交流圈一起學習交流:864305860
  );//面向1-3年前端人員
  Entries[file.name] = file.jsPath;
 });//幫助突破技術瓶頸,提升思維能力
 
 return {
  plugins: [
   ...htmlPlugins,
   new ExtractTextPlugin({
    filename: getPath => {
     return getPath('css/[name].css');
    }
   })
  ],
  Entries//歡迎加入前端全棧開發交流圈一起學習交流:864305860
 };//面向1-3年前端人員
};//幫助突破技術瓶頸,提升思維能力

由於我使用了ExtractTextPlugin,因此這些CSS程式碼最終都會生成到所屬chunk的目錄裡成為一個CSS檔案。 模版引擎 每個頁面相同的UI佈局好難維護,UI稍微改一點就要到每個頁面去改 考慮到這個問題,專案引進並使用了pug模版引擎。 現在,我們可以利用pug的特性,建立一個共用元件:demo.pug p 這是一個共用元件 然後,當你需要使用這個公用元件時可以引入進來:

include 'demo.pug'

除此之外,你還可以使用一切pug特供的特性。 webpack中配置pug也很簡單,先安裝:

npm i --save-dev pug pug-html-loader

然後將所有.html字尾的改為.pug字尾,並且使用pug語法。 然後在規則中再增加一條配置

{
  test: /\.pug$/,
  use: 'pug-html-loader'
}

同時把plugins物件中的用到index.html的HtmlWebpackPlugin中的template,也要改成index.pug。

webpack整合eslint

先放出配置程式碼:

if (useEslint) {
 loaders.push({
  test: /\.js$/,
  loader: 'eslint-loader',
  enforce: 'pre',
  include: [path.resolve(__dirname, 'src')],
  options: {
   formatter: require('stylish')
  }//歡迎加入前端全棧開發交流圈一起吹水聊天學習交流:864305860
 });//面向1-3年前端人員
}//幫助突破技術瓶頸,提升思維能力

通過webpack整合ESLint,我們可以保證編譯生成的程式碼都是沒有語法錯誤且符合編碼規範的;但在開發過程中,等到編譯的時候才察覺到問題可能也是太慢了點兒。 因此我建議可以把ESLint整合進編輯器或IDE裡,像我本人在用vs code,就可以使用一個名為Eslint的外掛,一寫了有問題的程式碼,就馬上會標識出來。

dev環境與prod環境

首先,閱讀webpacl專案的時候通常要先看package.json這個檔案。因為當你在命令列敲下一句命令

npm run dev

webpack就會找到package.json檔案中的script屬性並依次分析命令,可見,這句命令相應的會執行

nodemon --watch build/ --exec \"cross-env NODE_ENV=development webpack-dev-server --color --progress --config build/webpack.dev.js\"

同樣的,當寫下命令

npm run build

script就會執行

ross-env NODE_ENV=production webpack --config build/webpack.prod.js

這樣就能區分開發環境,或是生產環境了。 雖然我們會為環境做區分,但是基於不重複原則,專案為兩個環境公用的配置整合到了(build/webpack.base.js)檔案中。然後利用webpack-merge外掛將配置整合在一起

webpack中使用jquery

webpack中使用jquery也很簡單,我們可以在loaders中增加一條配置:

if (useJquery) {
 loaders.push({
  // 通過require('jquery')來引入
  test: require.resolve('jquery'),
  use: [
   {//歡迎加入前端全棧開發交流圈一起吹水聊天學習交流:864305860
    loader: 'expose-loader',
    // 暴露出去的全域性變數的名稱 隨便你自定義
    options: 'jQuery'
   },
   {
    // 同上
    loader: 'expose-loader',
    options: '$'
   }
  ]
 });
}

然後當你需要在某個js檔案使用jq時,引用暴露出來的變數名即可:

import $ from 'jQuery';

webpack中使用typescript

在webpack中使用jquery也很簡單,我們可以在loaders中增加一條配置:

if (useTs) {
 loaders.push({
  test: /\.tsx?$/,
  use: 'ts-loader',
  exclude: /node_modules/
 });
}//歡迎加入前端全棧開發交流圈一起吹水聊天學習交流:864305860

然後將js檔案改為ts即可。

結語

感謝您的觀看,如有不足之處,歡迎批評指正。