iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 3
0
Modern Web

Webpack with ASP.NET MVC系列 第 3

ASP.NET MVC 專案架構及入口頁面設定

專案資料夾結構

╸ ASP.NET.WEBPACK
  ┝╸ App_Data
  ┝╸ App_Start
  ┝╸ Attributes
  ┝╸ Controllers
  ┝╸ Models
  ┝╸ node_modules
  ┝╸ Resource            // 前端資源資料夾
     ┝╸ __BundleDev__    // 開發時使用的 Bundle 
     ┝╸ __VendorDev__    // 開發時使用的 Vendor
     ┝╸ Bundle           // 正式區 Bundle
     ┝╸ Containers       // 入口頁面
     ┝╸ Components
     ┝╸ Images
     ┝╸ Sass
     ┝╸ Vendor
     ┝╸ Webpack_cache
  ┕╸ Views
  Startup.cs
  ASP.NET.WEBPACK.csproj
  webpack.common.js      // Common 設定檔
  webpack.dev.js         // Dev 設定檔
  webpack.prod.js        // Prod 設定檔

入口頁面設定

以前使用 Webpack 都是處理 SPA ( 單頁應用程式 ),還沒有實際執行過多入口頁面的專案。當時參考了 NEXTJS 的架構,每個 Views 頁面都有一個根組件 ( Container ),這些 Container 會 Import 到各別資料夾的 Index.jsIndex.js 也是 Webpack 入口頁面的進入點。直接看範例比較清楚 ASP.NET MVCViews 資料夾大概長這樣:

Views 資料夾結構

╸ Views
  ┝╸ Account
     ┝╸ Profile.cshtml
     ┝╸ Login.cshtml
     ┕╸ Register.cshtml
  ┝╸ Cart
     ┝╸ Checkout.cshtml
     ┕╸ Complete.cshtml
  ┝╸ Home
     ┕╸ Home.cshtml
  ┝╸ Member
  ┝╸ Order
  ┕╸ Product

Resource/Containers 資料夾則比照 Views 資料夾

Containers 資料夾結構

╸ Containers
  ┝╸ Account
     ┝╸ Index.js
     ┝╸ Profile.js
     ┝╸ Login.js
     ┕╸ Register.js
  ┝╸ Cart
     ┝╸ Index.js
     ┝╸ Checkout.js
     ┕╸ Complete.js
  ┝╸ Home
     ┕╸ Index.js
  ┝╸ Member
  ┝╸ Order
  ┕╸ Product

每個 Container 都 export default 一個根組件

Account/Profile.js
export default class Profile extends React.Component{
    ...
}

透過各資料夾的 Index.js 去 import 該資料夾的 Container

Account/Index.js
import Profile from './Profile'
import Login from './Login'
import Register from './Register'

Webpack entry 以各資料夾名稱為 Key 值,設定 Index.js 為入口頁面進入點

Webpack Entry
entry: {
  Account: 'Containers/Account/Index.js',
  Cart: 'Containers/Cart/Index.js',
  Home: 'Containers/Home/Index.js',
  ...
}

使用 Glob 自動查找入口文件

依照上面的設定每次新增 / 刪除頁面,都必須修改 Webpack config,這樣有點麻煩。為了讓 Webpack 自動去查找 Resource/Containers 裡的 Index.js,我們使用 glob 這個套件自動查找入口文件,這樣以後新增 / 刪除頁面就不需要再修改 Webpack 設定檔了。

首先安裝 glob 套件

npm i glob --save-dev
Webpack.common.js
var glob = require('glob')
/**
 * @class getEntry
 * @description 動態查找 Containers 入口文件並打包
 */
var getEntry = function() {
  var Files = glob.sync(path.resolve(__dirname, 'Resource/Containers/**/Index.js'))
  var Entries = {}
  Files.forEach(function(file) {
    var name = /.*\/(Containers\/.*?)\.js/.exec(file)[1].split('/')[1]
    Entries[name] = file
  })
  return Entries
}
module.exports = {
  entry: getEntry(),
  output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, 'Resource/Bundle')
  }
}

執行打包指令

webpack --config webpack.dev.js

output Bundle 檔案如下

╸ Bundle
  ┝╸ Account.Bundle.js
  ┝╸ Cart.Bundle.js
  ┝╸ Home.Bundle.js
  ┝╸ Member.Bundle.js
  ┝╸ Order.Bundle.js
  ┕╸ Product.Bundle.js

Github DEMO


上一篇
比較 Webpack 與 ASP.NET MVC Bundle 工具
下一篇
使用 Html-Webpack-Plugin 引入 Bundle 檔案
系列文
Webpack with ASP.NET MVC30

尚未有邦友留言

立即登入留言