vue cli修改默認webpack配置

vue cli修改默認webpack配置

背景

Vue CLI作爲一個Vue的腳手架,幫助我們做了很多工作,比起create-react-app腳手架,絲毫察覺不到有webpack的身影,對於簡單的開發工作,我們無需關注如何去修改他的默認配置,但是如果我們想做一些定製化的開發,比如修改一些公共變量或者添加一個插件,其實Vue CLI文檔都有介紹,但是說實話爲了理解這些東西我查了不少文檔,說實話我認爲作爲官方文檔還是不夠接地氣,下面給大家分享一下我的認知,一步一步的。

開始

​ 首先呢,初始化的項目並沒有爲我們提供一個修改配置的入口文件,需要我們在項目根目錄下新建一個vue.config.js文件,這個文件是可選的,他會被@vue/cli-service自動加載,所有配置文件的修改都在這裏了。

最簡單的配置,configureWebpack

​ 比如我們自己開發了一個插件或者網上找了個webpack插件,我們想將這個插件應用到項目中,我們可以:

// vue.config.js
module.exports = {
  configureWebpack: {
    plugins: [
      new MyWebpackPlugin()
    ]
  }
}

這個配置方式將通過webpack-merge,將結果合併到最終的webpack配置中。

開放webpack配置文件

​ 許多讀者朋友可能會比較好奇默認的配置文件到底配置了些什麼,可以通過命令行方式將配置文件開放出來,在項目路徑下運行

vue inspect > output.js

運行成功該命令行後,可以發現根目錄多了一個output.js文件,打開後就可以看到原始的配置文件了。

初識webpack-chain

Vue CLI提供了一個維護入口來維護webpack內部配置,可以通過它來維護。下面粘貼一個官網的例子,來介紹一下這個函數的使用方法。

// vue.config.js
module.exports = {
  chainWebpack: config => {
    config.module
      .rule('vue')
      .use('vue-loader')
        .loader('vue-loader')
        .tap(options => {
          // modify the options...
          return options
        })
  }
}

看到上面的代碼,大家可能會產生以下幾個疑問:

  • config 這個參數是什麼含義
  • config 修改參數時,如何做到一步一步往下鏈式修改內容

下面通過幾個小例子來解釋這個鏈式調用的使用方式:

(1) 修改html-webpack-plugin配置

​ 首先在output.js中查詢html-webpack-plugin的默認配置信息,如下所示:

/* config.plugin('html') */
new HtmlWebpackPlugin(
    {
        title: 'vue20218',
        templateParameters: function () { /* omitted long function */ },
        template: 'F:\\vue20218\\public\\index.html'
    }
),

其中的title和template是我創建項目時輸入的名稱和模板地址,這裏重點關注註釋的部分config.plugin('html')。細心的小夥伴可能會發現,在public/index.html這個模板中,title的名稱是:

<title><%= htmlWebpackPlugin.options.title %></title>

讀取的是動態的值,我現在想改變title的值,那麼我就可以在vue.config.js中這樣寫:

module.exports = {
    chainWebpack: (config) => {
      config.plugin('html')
        .tap(args => {
          args[0].title = '123'
          return args
        })
    },
}

可以發現,config.plugin('html')有tap函數,函數參數爲html-webpack-plugin的各個變量,通過變更然後返回參數來完成變量的修改。

(2) 修改alias值

首先在output.js中查詢關鍵字 alias,結果如下

resolve: {
    alias: {
      '@': 'F:\\vue20218\\src',
      vue$: 'vue/dist/vue.runtime.esm.js',
      '@mixins': 'F:\\vue20218\\src\\mixins'
    },
    ...
}

​ 可以發現默認的路徑解析,@可以作爲F:/vue20218/src路徑的替代,然後我們再添加一個。

const path = require('path')
function resolve(dir) {
  return path.join(__dirname, dir)
}
module.exports = {
    chainWebpack: (config) => { 
      config.resolve.alias
        .set('@mixins', resolve('src/mixins'))
      config.plugin('html')
        .tap(args => {
          args[0].title = '123'
          return args
        })
    },
}

​ 其中 path 和 resolve是輔助下面功能的引用和方法。從這個修改方式可以發現,這種層級引用的變量,可以通過a.b.set的方式來設置,其中set接收鍵值對,如果想繼續設置,可以在set基礎上再調用set方法,類似

config.resolve.alias
        .set('@mixins', resolve('src/mixins'))
		.set('@okk', resolve('src/okk'))
(3) 修改babel-loader的行爲

首先在output.js中查詢關鍵字 babel-loader,結果如下

/* config.module.rule('js').use('babel-loader') */
   {
     loader: 'F:\\vue20218\\node_modules\\babel-loader\\lib\\index.js'
   }

其中再次關注被註釋的部分,如果想修改,可以用下面這種方式:

const merge = require('webpack-merge')
module.exports = {
  chainWebpack: config => {
    config.module.rule('js')
      .use('babel-loader')
        .loader('F:\\vue20218\\node_modules\\babel-loader\\lib\\index.js')
        .tap(options => {
          return merge(options, {
            plugins: [
              ["import", { "libraryName": "ant-design-vue", "libraryDirectory": "es", "style": "css" }]
            ]
          })
        })
  }
}

熟悉上述代碼的可能知道,這句話的作用就是將antd按需加載,小貼士:要實現該功能,別忘了安裝babel-plugin-import
細心的大家一定發現了合併時我們用到了merge函數,而且可以發現一直到.use('url-loader')都是一致的,爲什麼又加了一個.loader('F:\\vue20218\\node_modules\\babel-loader\\lib\\index.js')呢?

因爲處理一種文件,可能存在多個loader,這句話正是唯一確定要修改的loader對象!

總結:

​ 以上總結了Vue CLI下修改webpack普通對象的值、loader的值以及plugin的值,希望有困惑的朋友們能夠解惑,有什麼問題也可以留言討論,謝謝觀看。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章