1. 程式人生 > >從 vue-cli 到 webpack多入口打包(二)

從 vue-cli 到 webpack多入口打包(二)

epo 代碼 添加 text dir 例如 arr 向上 只需要

完成多入口打包配置

上一節我說完了三個關鍵的plugin,通過三個plugin我們可以做到將代碼進行分割,並且將分割的代碼打包到我們指定的路徑下,完成打包的模塊可以被index.html文件正確引用。這裏我們需要貫穿整個流程。

1、yargs

yargs 是一個非常強大的命令行參數處理工具,這裏我們用到的功能比較簡單,只需要獲取從命令行傳入的modules數組,這個數組表示所需打包的入口chunk。在vue-cli的默認安裝包中並沒有安裝yargs這個模塊,所以我們需要首先安裝yargs模塊。

// 通過npm安裝yargs
npm install yargs -D

完成安裝後,我們就能使用yargs進行命令行參數的獲取,然後通過獲取到的數組,按需打包我們需要的入口模塊。例如:我們src下面有三個入口,分別為moduleA

moduleBmoduleC,但是本次我們發現moduleC的代碼沒有發生變動,我們只需要在打包時傳入moduleAmoduleB這兩個參數就能做到。首先我們需要將參數從命令行傳入到我們的運行腳本中。

2、命令行傳入參數

2.1 scripts 的命令行參數

我們打包時運行的命令是npm run build,實際上我們執行的是package.json中的scripts中的腳本配置,vue-cli中默認的build配置是"build": "node build/build.js",也就是說通過npm run build執行的是 build目錄下的build.js文件。我們想要將參數傳入到運行腳本中,就需要通過script腳本進行參數傳遞。

關於script腳本參數傳遞,這裏貼一篇阮一峰老師的一篇博文供參考 npm scripts 使用指南,貼上我們需要的一段:

四、傳參
向 npm 腳本傳入參數,要使用--標明。
"lint": "jshint **.js"
向上面的npm run lint命令傳入參數,必須寫成下面這樣。
$ npm run lint --  --reporter checkstyle > checkstyle.xml
也可以在package.json裏面再封裝一個命令。
"lint": "jshint **.js",
"lint:checkstyle": "npm run lint -- --reporter checkstyle > checkstyle.xml"

也就是說在npm腳本中傳入參數我們需要使用 -- --parameters進行參數傳遞,我們在此使用的方式:npm run build -- --modules=moduleA moduleB

2.2 使用yargs的命令行參數傳入

通過npm腳本我們已經可以將我們需要的modules參數傳入到我們開始運行的build.js代碼中了,接下來我們就要通過yargs來獲取到modules參數所傳入的值,這裏的值是moduleA、moduleB,直接貼上我們獲取參數的代碼:

// utils.js文件
// 引入yargs模塊
const yargs = require(‘yargs‘)
/**
 * 獲取 命令行傳入的參數
 */
const args = yargs.array(‘modules‘).argv
// 這裏如果沒有傳入modules參數則默認打包全部的模塊
const modules = args.modules || [‘moduleA‘, ‘moduleB‘, ‘moduleC‘]
// 我們將的到modules導出,以備其他模塊使用
exports.bundleModules = modules

通過以上步驟我們就完成了參數的傳遞,可以通過命令行參數完成我們想要打包的模塊。

3、入口處理

在vue-cli的默認入口中,是單入口應用的配置,所以我們需要修改為多入口的entry,根據webpack的文檔,多入口配置采用的是對象的寫法。我們在utils.js文件中通過方法生成entry,代碼如下:

// utils.js
exports.entires = function () {
  // 模塊主目錄
  const BASE_PATH = path.resolve(__dirname, ‘..\\src\\modules‘)
  // 最終的返回結果
  let entriesMap = {}
  // 得到所有模塊的主入口
  modules.forEach(item => {
    entriesMap[item] = BASE_PATH + ‘\\‘ + item + ‘\\main.js‘
  })
  // 最終橫撐的entriesMap是一個對象,key為模塊的名稱,這個名稱可以作為output中[name]占位符的值,也是很重要的
  return entriesMap
}

這樣我們就能通過modules得到我們需要打包的入口函數,接著我們將webpack.base.conf.js文件中的entry替換成我們生成的多入口形式,代碼如下

// webpack.base.conf.js
module.exports = {
  context: path.resolve(__dirname, ‘../‘),
  // 此處替換成我們自己的entry
  entry: utils.entires(),
  output: {
    path: config.build.assetsRoot,
    filename: ‘[name].js‘,
    publicPath: process.env.NODE_ENV === ‘production‘
      ? config.build.assetsPublicPath
      : config.dev.assetsPublicPath
  }
  // ...
}

這樣我們就處理好了入口處的webpack配置

4、出口處理

vue-cli生成的webpack配置中,通過npm run build命令進行的打包配置文件,出口配置在webpack.prod.conf.js文件中,在這裏的output配置我們只需要修改打包生成的文件路徑,代碼如下:

// webpack.prod.conf.js
output: {
    path: config.build.assetsRoot,
    // 默認的配置,這裏是將打包好的文件統一放在assets/js文件夾下面
    // filename: utils.assetsPath(‘js/[name].[chunkhash].js‘),
    // 修改後的配置,這裏的[name]就是入口處的占位符,放到我們這裏來說就分別是 moduleA|moduleB|moduleC,所以這裏我們這麽配置就是將不同的模塊文件打包到各自的模塊名稱的js文件夾下
    filename: path.posix.join(‘[name]/js‘, ‘[name].[chunkhash].js‘),
    // 這裏是異步模塊,就是上一篇中說的async打包模塊,這裏的[name]占位符是vue-router中配置的異步路由名稱
    chunkFilename: utils.assetsPath(‘[name]/[id].[chunkhash].js‘)
}

5、最終

完成了本篇中的所有配置之後,再將上一篇中三個插件的配置全部添加到webpack.prod.conf.js文件中,我們就能完成多入口模塊的打包。我們需要清楚一點,執行npm run buildnpm run dev的區別。這兩篇文章只是將build的代碼實現了多入口的打包,我們並沒有修改本地開發時的打包配置。下一篇文章我們會介紹一下前端多模塊分布式發布時的打包配置,這個配置包含了本地開發環境的配置和build的配置。

完整版的代碼倉庫地址 multipleModules

最後貼一張最終打包完成的目錄圖
技術分享圖片

從 vue-cli 到 webpack多入口打包(二)