利用 Webpack 實現小程式多專案管理

Kalengo發表於2019-04-18

故事是這樣開始的

前端開發小哥Bingo接到了產品小姐姐的需求,要上線多個小程式.

碼畜小哥開始架構

  • 小程式雜,放一個專案方便管理
  • 小程式多,程式碼要能夠複用
  • 團隊開發,程式碼風格要統一

碼畜小哥開始建專案

這是單個小程式的基本目錄結構,沒問題

圖片描述

當一個專案有多個小程式的時候,好像也沒問題

圖片描述

當多個小程式都用到同一個元件 com3 時,小哥發現程式碼沒法複用,需要複製黏貼

圖片描述

思考了一下,那麼把元件目錄移到外面,這樣不就可以複用了嗎?

圖片描述

感覺很好,小哥這時在微信開發者工具開啟 demo1,發現報錯了

圖片描述

原來小程式是以當前專案作為根目錄,components 目錄已經不在 demo1 目錄範圍內,所以是引用不到的

小哥想到了 Webpack

1. 整理目錄

  • apps/:存放全部小程式
  • build/:存放構建指令碼
  • common/:存放公共方法
  • components/:存放公共元件
  • styles/:存放公共樣式
  • templates/:存放公共模板

大概長這樣

圖片描述

2. 編寫構建指令碼

package.json

script: {
  "dev": "webpack --config build/webpack.config.js"
}
複製程式碼

build/webpack.config.js

思路就是利用 CopyWebpackPlugin 同步指定的檔案到小程式目錄下

const CopyWebpackPlugin = require('copy-webpack-plugin')
const utils = require('./utils')

// 獲取 apps 目錄下的小程式並指定公共檔案目錄命名
function copyToApps(dir) {
  let r = []

  utils
    .exec(`cd ${utils.resolve('apps')} && ls`)
    .split('\n')
    .map(app => {
      r.push({
        from: utils.resolve(dir),
        to: utils.resolve(`apps/${app}/_${dir}`)
      })
    })

  return r
}

module.exports = {
  watch: true,

  // 監聽入口檔案,儲存便會重新整理
  entry: utils.resolve('index.js'),

  output: {
    path: utils.resolve('.tmp'),
    filename: 'bundle.js'
  },

  plugins: [
    // 同步指定的公共檔案到所有小程式目錄下
    new CopyWebpackPlugin([
      ...copyToApps('styles'),
      ...copyToApps('common'),
      ...copyToApps('templates'),
      ...copyToApps('components')
    ])
  ]
}
複製程式碼

3. 啟動本地開發

npm run dev
複製程式碼

圖片描述

圖片描述

現在公用的程式碼已經自動同步到小程式目錄下,以下劃線開頭,當改動公共程式碼也會自動同步給小程式呼叫

呼叫方式長這樣

import utils from './_common/utils'
import com3 from './_components/com3'
複製程式碼
@import './_styles/index.wxss';
複製程式碼
<import src="./_templates/index.wxml" />
複製程式碼

程式碼風格校驗

package.json

script: {
  "lint": "eslint apps/"
}
複製程式碼

.eslintrc.js

module.exports = {
  extends: 'standard',

  // 將小程式特有的全域性變數排除下
  globals: {
    Page: true,
    Component: true,
    App: true,
    getApp: true,
    wx: true
  },

  rules: {
    'space-before-function-paren': ['error', 'never'],
    'no-unused-vars': [
      'error',
      {
        // 小程式還沒支援 ES7,這個是用來相容 async/await
        varsIgnorePattern: 'regeneratorRuntime'
      }
    ]
  }
}
複製程式碼

然後藉助 husky 在每次 git commit 前執行校驗

script: {
  "precommit": "npm run lint"
},

devDependencies: {
  "husky": "^0.14.3"
}

複製程式碼

清理

最後小哥還加了個清理命令,便於重新生成公共程式碼

package.json

script: {
  "clean": "node build/clean.js"
}

複製程式碼

build/clean.js

const rimraf = require('rimraf')
const utils = require('./utils')

function log(dir) {
  console.log(`cleaning ${dir}`)
}

rimraf(utils.resolve('.tmp'), () => log('.tmp'))

utils
  .exec(`cd ${utils.resolve('apps')} && ls`)
  .split('\n')
  .map(app => {
    ;[
      `${app}/_styles`,
      `${app}/_common`,
      `${app}/_templates`,
      `${app}/_components`
    ].map(m => {
      rimraf(utils.resolve(`apps/${m}`), () => log(m))
    })
  })

複製程式碼

碼畜小哥心滿意足

“可以下班追劇了”

碼畜小哥簡介

考拉前端開發小哥Bingo,鑽研小程式開發。

相關文章