天天看點

建構webpack多頁應用

  • 參考: https://segmentfault.com/a/1190000006843916 系列文章

為什麼要用webpack建構多頁應用

  1. 考慮到SEO的存在,我們需要開發一個多頁項目
  2. 前後端分離模式下,用後端模闆引擎處理多頁時候的前端的窘境
  3. gulp、grunt、fis3随着時代的遠去,webpack比它們更适合新的時代
  4. rollup、parcel等新時代的打包自動化工具生态圈不如webpack

談一談傳統後端模闆引擎下前端開發多頁應用時候的窘境

  1. 強依賴後端環境,很多時候可能還需要自己啟動後端項目
  2. 需要對後端模闆引擎比較熟悉,有很多甚至有自己的标簽文法(jsp的jstl,Struts2的标簽)
  3. 由于模闆文法的局限性,很多業務在這些模闆引擎裡面寫起來非常費力

然而

上面的這些窘境用gulp還是用webpack都依舊存在,依舊無解,但是新時代的前端工程師,對項目進行工程化還是很有必要的。。。

進入正題

用webpack建構一個純前端的多頁應用

建立項目multi-page-app,并初始化項目:

npm init
           

安裝對應的依賴:

npm install --save-dev webpack webpack-cli
           

在項目根目錄下建立webpack.config.js,配置如下:

module.exports = {
  mode: "development",
  entry: __dirname + "/index.js",
  output: {
    path: __dirname + "/dist",
    filename: "bundle.js"
  },
};
           

再建立index.js:

alert('This is index')
           

建立index.html:

<!DOCTYPE html>
<html >
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    
    <script src="./dist/bundle.js"></script>
</body>
</html>
           

控制台執行:

npx webpack
           

顯示:

建構webpack多頁應用

則為打包成功,在浏覽器裡面打開index.html

建構webpack多頁應用

出現上圖就是webpack搭建成功

下面我們來建立多頁項目的基本骨架

建立page和static目錄,并分别建立admin和index目錄:

建構webpack多頁應用

然後下載下傳依賴:

npm install --save-dev html-webpack-plugin
           

修改webpack.config.js的配置如下:

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  mode: "development",
  entry: {
    index: __dirname + "/static/index/entry.js",
    admin: __dirname + "/static/admin/entry.js"
  },
  output: {
    path: __dirname + "/dist",
    filename: "static/[name]/bundle.js"
  },
  plugins: [
    new HtmlWebpackPlugin({
      chunks: ["admin"],
      filename: "admin.html",
      template: __dirname + "/page/admin/content.html"
    }),
    new HtmlWebpackPlugin({
      chunks: ["index"],
      filename: "index.html",
      template: __dirname + "/page/index/content.html"
    })
  ]
};
           

上面增加了兩個入口js,以及兩個對應的html,然後讓我們分别建立對應的入口js以及html:

建構webpack多頁應用

然後執行webpack編譯指令,可以看到生成的dist檔案夾:

建構webpack多頁應用

打開index.html或者admin.html,就可以看到他們打包好的html内容以及js引用的情況,最基本的多頁應用就完成了,你可以在兩個html裡面随意寫入後端的模闆引擎的文法來進行開發,通過:

webpack --watch
           

來不斷的更新輸出到後端的模闆以及靜态資源目錄,就可以保證正常開發了,但是到了這裡我們還是應該繼續優化一下這些模闆,比如增加一些公共模闆的套用,公共元件的複用等等。

優化

繼續上面的項目,讓我們引入幾個npm依賴:

npm install --save-dev ejs-compiled-loader ejs ejs-loader
           

這裡為什麼要引入ejs呢,ejs就是一個前端的模闆引擎,可供前端以及node使用,但是若是其他語言的模闆引擎并沒有任何用處。而這裡引入的主要作用是,為了使用這些模闆引擎本身擁有的文法以及loader來實作公共模闆的套用、元件的複用等等。讓我們在page下面建立common目錄,并分别建立html.ejs、header.ejs、footer.ejs:

<!-- html.ejs -->
<!DOCTYPE html>
<html >
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <header>
        <%= header %>
    </header>
    <main>
        <%= main %>
    </main>
    <footer>
        <%= footer %>
    </footer>
</body>
</html>
           
<!-- header.ejs -->
<div class="header">This is header</div>
           
<!-- footer.ejs -->
<div class="footer">This is footer</div>
           

然後在page下面的admin以及index下面新增page.js,内容如下:

// page.js
const content = require('./content.html'),
    html = require('../common/html.ejs'),
    header = require('../common/header.ejs'),
    footer = require('../common/footer.ejs');

module.exports = html({
    header: header(),
    main: content(),
    footer: footer()
})
           

修改webpack配置如下:

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  mode: "development",
  entry: {
    index: __dirname + "/static/index/entry.js",
    admin: __dirname + "/static/admin/entry.js"
  },
  output: {
    path: __dirname + "/dist",
    filename: "static/[name]/bundle.js"
  },
  module: {
    rules: [
      {
        test: /\.ejs|html$/,
        loader: "ejs-loader"
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      chunks: ["admin"],
      filename: "admin.html",
      template: __dirname + "/page/admin/page.js"
    }),
    new HtmlWebpackPlugin({
      chunks: ["index"],
      filename: "index.html",
      template: __dirname + "/page/index/page.js"
    })
  ]
};
           

執行webpack編譯指令就可以得到最終編譯合成一樣的admin.html:

建構webpack多頁應用

這裡通過ejs模闆,通過ejs模闆引擎通過ejs-loader的編譯最終通過html-webpack-plugin輸出了整個html模闆,當然我們也可以再裡面寫入任意的後端模闆引擎的代碼。

這裡主要是直接輸出整合了後端的模闆引擎的代碼,通過編譯直接生成了最終的html,而不是像後端一般模闆引擎的做法在去采用extends以及include的形式在服務端在進行一定的io操作最終編譯代碼,可以提高一定的效率,雖然這個效率可能微乎其微,但是性能本身就是一點點的堆疊,這裡快一點那裡快一點,整個網站的整體性能就上去了。