webpack打包多頁面

前言

一開始接觸webpack是由於使用Vue的關係,由於Vue的腳手架就是使用webpack構建的。剛開始的時候以爲webpack就是爲了打包單頁面而生的,後來想一想,這麼好的打包方案,只在單頁面上使用是否太浪費資源了呢?若是能在傳統多頁面上使用webpack,開始效率是否會事半功倍呢?好在衆多優秀的前端開發者已經寫了許多demo和文章供人學習。我也寫了一個小項目,但願對你們學習webpack有幫助。javascript

好吧其實上面說的都是廢話,接下來附上項目地址和乾貨,配合食用更佳。css

webpack-multi-pagehtml

項目解決的問題

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

src目錄對應dist目錄

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;
};

利用這個方法,咱們能夠得到須要打包的文件路徑(方法中獲取文件路徑的模塊也可以使用fs模塊),根據得到打包的文件路徑,咱們可使用html-webpack-plugin來實現多頁面打包。java

因爲每個html-webpack-plugin的對象實例都只針對/生成一個頁面,所以,咱們作多頁應用的話,就要配置多個html-webpack-plugin的對象實例:node

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]
      })
    );
    Entries[file.name] = file.jsPath;
  });

  return {
    plugins: [
      ...htmlPlugins,
      new ExtractTextPlugin({
        filename: getPath => {
          return getPath('css/[name].css');
        }
      })
    ],
    Entries
  };
};

因爲我使用了ExtractTextPlugin,所以這些CSS代碼最終都會生成到所屬chunk的目錄裏成爲一個CSS文件。jquery

模版引擎

每一個頁面相同的UI佈局好難維護,UI稍微改一點就要到每一個頁面去改,好麻煩還容易漏,怎麼破?

考慮到這個問題,項目引進並使用了pug模版引擎。webpack

如今,咱們能夠利用pug的特性,建立一個共用組件:git

demo.pug

p 這是一個共用組件

而後,當你須要使用這個公用組件時能夠引入進來:github

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')
    }
  });
}

經過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: [
      {
        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/
  });
}

而後將js文件改成ts便可。

後話

歡迎你們提pr,一塊兒構建。

相關文章
相關標籤/搜索