vue.config.js中的webpack配置,優化及多頁面應用開發



官方文檔

vue-cli3以下版本中,關於webpack的一些配置都在config目錄文件中,可是vue-cli3以上版本中,沒有了config目錄,那該怎么配置webpack呢?
3.x初始化項目后沒有了build和config文件,如果你想對webpack相關內容進行配置,需要自己在根目錄下(與package.json同級)創建一個vue.config.js文件,這個文件一旦存在,那么它會被 @vue/cli-service 自動加載。(但需要我們自己手動創建哦vue.config.js,跟package.json同級)

一、vue.config.js中常用的配置

在配置中絕大多數都是(可選項)

1、導出模塊

常規操作還是用到了commjs語法

module.exports = {

}

2、publicPath 部署應用包的基本Url

部署應用包的基本Url,默認/, 可以設置為相對路徑./,這樣打出來的包,可以部署到任意路徑上

let developmentPath='./';//開發環境-npm run serve時引用文件路徑
let productionPath='./';//生產環境-npm run build打包后引用文件路徑
module.exports = {
    publicPath: process.env.NODE_ENV === 'production' ? productionPath: developmentPath, // 基本路徑-引用文件的路
}

3、outputDir 輸出文件目錄

輸出文件目錄(打包后生成的目錄,默認dist)

module.exports = {
  outputDir: __dirname + '/server/dist', //build之后靜態文件輸出路徑
  //outputDir: 'dist',
}

4、assetsDir 打包后生成的靜態資源目錄

打包后生成的靜態資源目錄,默認“ ” ,也就是我們打包后的css,js等存放的位置

module.exports = {
 assetsDir: 'static',
}

5、lintOnSave

是否在保存的時候檢查

module.exports = {
    lintOnSave: process.env.NODE_ENV !== 'production',// eslint-loader 
}

6、productionSourceMap 生產環境的 source map

生產環境的 source map,可以將其設置為 false 以加速生產環境構建,默認值是true

module.exports = {
    productionSourceMap: false,
}

7、devServer

可通過 devServer.proxy解決前后端跨域問題(反向代理)

module.exports = {
// 反向代理
  devServer: {
    index: '/login.html',   //默認打開文件
    open: true,             //自動打開瀏覽器
    host: 'localhost',      //默認打開域名
    port: 8080,             //默認打開端口號
    https: false,           //開啟關閉https請求
    hotOnly: false,         //熱更

    proxy: {
      // 配置跨域
      '/api': {
        target: 'http://dev.aabb.cn:8082/', //代理地址,這里設置的地址會代替axios中設置的baseURL
        ws: true,   //// proxy websockets
        changeOrigin: true,// 如果接口跨域,需要進行這個參數配置
        pathRewrite: {                //pathRewrite方法重寫url
          '^/api': '/',
        },
      },
    },
  },
} 

擴展: hot 和 hotOnly 的區別是在某些模塊不支持熱更新的情況下,前者會自動刷新頁面,后者不會刷新頁面,而是在控制台輸出熱更新失敗

8、 chainWebpack webpack配置

module.exports = {
  chainWebpack: (config) => {
    config.plugins.delete('preload')
    config.plugins.delete('prefetch')

    config.module
      .rule('svg')
      .exclude.add(resolve('src/assets/icons'))
      .end()

    config.module
      .rule('icons')
      .test(/\.svg$/)
      .include.add(resolve('src/assets/icons'))
      .end()
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'icon-[name]',
      })
      .end()

    const imagesRule = config.module.rule('images')
    imagesRule.uses.clear() //清除原本的images loader配置
    imagesRule
      .test(/\.(jpg|gif|png|svg)$/)
      .exclude.add(path.join(__dirname, '../node_modules')) //不對node_modules里的圖片轉base64
      .end()
      .use('url-loader')
      .loader('url-loader')
      .options({ name: 'img/[name].[hash:8].[ext]', limit: 6000000 })

    config.optimization.splitChunks({
      cacheGroups: {

        vendors: {
          name: 'chunk-vendors',
          minChunks: pageNum,
          test: /node_modules/,
          priority: -10,
          chunks: 'initial',
        },

        elementUI: {
          name: 'chunk-elementUI', // split elementUI into a single package
          priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
          test: /[\\/]node_modules[\\/]_?element-ui(.*)/, // in order to adapt to cnpm
        },

        commons: {
          name: 'chunk-commons',
          test: resolve('src/components'), // can customize your rules
          minChunks: 3, //  minimum common number
          priority: 5,
          reuseExistingChunk: true,
        },
      },
    })
  },
}

擴展:
Preload: 用於標記頁面加載后即將用到的資源,瀏覽器將在主體渲染前加載preload標記文件。Vue CLI 應用會為所有初始化渲染需要的文件自動生成 preload 提示;

Prefetch: 用於標記瀏覽器在頁面加載完成后,利用空閑時間預加載的內容。Vue CLI 應用默認為所有作為 async chunk 生成的 JavaScript 文件 (通過動態 import() 按需 code splitting 的產物) 自動生成prefetch提示。

9、configureWebpack webpack配置

webpack配置

const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const CompressionWebpackPlugin = require('compression-webpack-plugin')

const productionGzipExtensions = ['js', 'css']
const Version = 'V6.1'
const Timestamp = new Date().getTime()

module.exports = {
    webpack配置
    configureWebpack: (config) => {
          // 為生產環境修改配置
        if (process.env.NODE_ENV === 'production') {
      
            config.plugins.push(
                new UglifyJsPlugin({
                    uglifyOptions: {
                        compress: {
                            drop_debugger: true,//生產環境自動刪除debugger
                            drop_console: true, //生產環境自動刪除console
                        },
                        warnings: false,
                    },
                    sourceMap: false,   //關掉sourcemap 會生成對於調試的完整的.map文件,但同時也會減慢打包速度
                    parallel: true, //使用多進程並行運行來提高構建速度。默認並發運行數:os.cpus().length - 1。
                }),


                new CompressionWebpackPlugin({
                    filename: '[path].gz[query]',
                    algorithm: 'gzip',
                    test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
                    threshold: 10240,
                    minRatio: 0.8,
                })
            )
        }

        // 在這里配置后,減少了壓縮的包內容,需要在public/index.html通過cdn方式再引入,注意對應的版本
        config.externals = { 
            vue: 'Vue',
            'vue-router': 'VueRouter',
            vuex: 'Vuex',
            axios: 'axios',
            jquery: '$',
            moment: 'moment',
            'mint-ui': 'MINT'
        },


         // 別名配置
        Object.assign(config, {
            // 開發生產共同配置
            resolve: {
                alias: {
                '@': path.resolve(__dirname, './src'),
                '@c': path.resolve(__dirname, './src/components'),
                '@p': path.resolve(__dirname, './src/pages')
                }
            }
        }),

        config.output.filename = `[name].${Version}.${Timestamp}.js`  //打包生成的文件
        config.output.chunkFilename = `[name].${Version}.${Timestamp}.js`
    },
 }

擴展:

  1. UglifyJS Webpack:
    Plugin插件用來縮小(壓縮優化)js文件,至少需要Node v6.9.0和Webpack v4.0.0版本。
  2. compression-webpack-plugin
    Vue配置compression-webpack-plugin實現Gzip壓縮
  3. chunkFilename
    和webpack.optimize.CommonsChunkPlugin插件的作用差不多,都是用來將公共模塊提取出來,但是用法不一樣
entry:{
    main:__dirname + '/app/main.js',
    index:__dirname + '/app/index.js'      
},
output:{
    path:__dirname + '/public', //通過HtmlWebpackPlugin插件生成的html文件存放在這個目錄下面
    filename:'/js/[name].js', //編譯生成的js文件存放到根目錄下面的js目錄下面,如果js目錄不存在則自動創建
    /*
     * chunkFilename用來打包require.ensure方法中引入的模塊,如果該方法中沒有引入任何模塊則不會生成任何chunk塊文件
     * 比如在main.js文件中,require.ensure([],function(require){alert(11);}),這樣不會打包塊文件
     * 只有這樣才會打包生成塊文件require.ensure([],function(require){alert(11);require('./greeter')})
     * 或者這樣require.ensure(['./greeter'],function(require){alert(11);})
     * chunk的hash值只有在require.ensure中引入的模塊發生變化,hash值才會改變
     * 注意:對於不是在ensure方法中引入的模塊,此屬性不會生效,只能用CommonsChunkPlugin插件來提取
     * */
    chunkFilename:'js/[chunkhash:8].chunk.js'
},

configureWebpack和chainWebpack區別

在這里configureWebpack和chainWebpack的作用相同,唯一的區別就是他們修改webpack配置的方式不同:

  1. chainWebpack通過鏈式編程的形式,來修改默認的webpack配置
  2. configureWebpack通過操作對象的形式,來修改默認的webpack配置
    如果對一個loader或plugin修改的配置如果是一項的話推薦 chainWebpack、如果是多項的話用configureWebpack直接覆寫

10、css相關配置

這里配置了全局sass 需要安裝的依賴 sass-loader less-loader

 css: {
        loaderOptions: {
            scss: {
                additionalData: `@import "@/assets/css/reset.scss";@import "@/assets/css/globle.scss";`  //注意配置的鍵名
            },
            postcss: {
                plugins: [
                    //remUnit這個配置項的數值是多少呢??? 通常我們是根據設計圖來定這個值,原因很簡單,便於開發。
                    //假如設計圖給的寬度是750,我們通常就會把remUnit設置為75,這樣我們寫樣式時,可以直接按照設計圖標注的寬高來1:1還原開發。
                    require('postcss-px2rem')({
                        remUnit: 37.5
                    })
                ]
            }
        }
    },

由於 sass-loader 版本不同,loaderOptions 中的 additionalData 的鍵名也不同

  • sass-loader loader v8-, 這個選項名是 "data",
  • sass-loader loader v8中, 這個選項名是 "prependData",
  • sass-loader loader v10+, 這個選項名是 "additionalData",

11、pages

vue-cli3中的webpack與vue多頁面應用開發
相關參數:

  • entry:page 的入口
  • template:模板來源
  • filename:在 dist/index.html 的輸出
  • title:template 中的 title 標簽需要是
  • chunks:在這個頁面中包含的塊,默認情況下會包含
module.exports = {
   pages:{
       main: {
           // page 的入口
           entry: "src/pages/main/main.js",
           // 模板來源
           template: "public/index.html",
           // 在 dist/index.html 的輸出
           filename: "main.html",
           // 當使用 title 選項時,
           // template 中的 title 標簽需要是 <title><%= htmlWebpackPlugin.options.title %></title>
           title: "Index Page",
           // 在這個頁面中包含的塊,默認情況下會包含
           // 提取出來的通用 chunk 和 vendor chunk。
           chunks: ["chunk-vendors", "chunk-common", "main"]
       },
       hh: {
           // page 的入口
           entry: "src/pages/login/main.js",
           // 模板來源
           template: "public/index.html",
           // 在 dist/index.html 的輸出
           filename: "login.html",
           // 當使用 title 選項時,
           // template 中的 title 標簽需要是 <title><%= htmlWebpackPlugin.options.title %></title>
           title: "Index Page",
           // 在這個頁面中包含的塊,默認情況下會包含
           // 提取出來的通用 chunk 和 vendor chunk。
           chunks: ["chunk-vendors", "chunk-common", "hh"]
       },
       // 當使用只有入口的字符串格式時,
       // 模板會被推導為 `public/subpage.html`
       // 並且如果找不到的話,就回退到 `public/index.html`。
       // 輸出文件名會被推導為 `subpage.html`。
       subpage: "src/subpage/main.js"
   },
}

封裝

const glob = require('glob') // 引入glob模塊,用於掃描全部src/pages/**/main.js(返回的是一個數組)
// 打包多入口文件基本配置
function getPagesInfo() {
    let pages = {}

    glob.sync('src/pages/**/main.js').forEach((entry, i) => {
        let name = entry.slice(10, -8)
        pages[name] = {
            entry: entry,
            template: 'public.index.html',
            filename: name + '.html',
            title: '',
            chunks: ["chunk-vendors", "chunk-common", name]
        }
    })
    return pages
}
module.exports = {
    pages: getPagesInfo(),
    publicPath: './kk',
    assetsDir: 'static',
};

12、其他

  • parallel: require('os').cpus().length > 1, // 是否為 Babel 或 TypeScript 使用 thread-loader。該選項在系統的 CPU 有多於一個內核時自動啟用,僅作用於生產構建。
  • pwa: {}, // PWA 插件相關配置
  • pluginOptions: {} // 第三方插件配置

很好的pwa插件相關配置
pwa介紹及使用

二、優化

1、優化打包chunk-vendors.js

當運行項目並且打包的時候,會發現chunk-vendors.js這個文件非常大,那是因為webpack將所有的依賴全都壓縮到了這個文件里面,這時我們可以將其拆分,將所有的依賴都打包成單獨的js;

/*
利用splitChunks將每個依賴包單獨打包,在生產環境下配置,代碼如下
*/

configureWebpack: (config) => {
    if (process.env.NODE_ENV === 'production') {
      // 為生產環境修改配置...
      config.mode = 'production'
      // 將每個依賴包打包成單獨的js文件
      let optimization = {
        runtimeChunk: 'single',
        splitChunks: {
          chunks: 'all',
          maxInitialRequests: Infinity,
          minSize: 20000, // 依賴包超過20000bit將被單獨打包
          cacheGroups: {
            vendor: {
              test: /[\\/]node_modules[\\/]/,
              name (module) {
                // get the name. E.g. node_modules/packageName/not/this/part.js
                // or node_modules/packageName
                const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1]
                // npm package names are URL-safe, but some servers don't like @ symbols
                return `npm.${packageName.replace('@', '')}`
              }
            }
          }
        }
      }
      Object.assign(config, {
        optimization
      })
    } 
  }

2、打包時去除打印信息

上面已經提到過去掉打印的操作(console、debug)這里詳細講解一下

  1. 首先下載相關插件 uglifyjs-webpack-plugin

    npm i -D uglifyjs-webpack-plugin

  2. 在vue.config.js文件中引入,並在configureWebpack的optimization中添加如下代碼
const UglifyPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
    
 configureWebpack: (config) => {
    if (process.env.NODE_ENV === 'production') {
      // 為生產環境修改配置...
      config.mode = 'production'
      // 將每個依賴包打包成單獨的js文件
      let optimization = {

        /*以下代碼適用於uglifyjs-webpack-plugin 2.1.1及以前的版本*/
        minimizer: [new UglifyPlugin({
          uglifyOptions: {
            compress: {
              warnings: false,
              drop_console: true, // console
              drop_debugger: false,
              pure_funcs: ['console.log'] // 移除console
            }
          }
        })]
        
      }
      Object.assign(config, {
        optimization
      })
    }
   
  }
}

新版uglifyjs-webpack-plugin需寫成以下方式

minimizer: [new UglifyPlugin({
    uglifyOptions: {
        warnings: false,
        compress: {
            drop_console: false, // console
            drop_debugger: false,
            pure_funcs: ['console.log'] // 移除console
        }
    }
})]

3、開啟gizp壓縮

gizp壓縮是一種http請求優化方式,通過減少文件體積來提高加載速度。html、js、css文件甚至json數據都可以用它壓縮,可以減小60%以上的體積。webpack在打包時可以借助 compression webpack plugin 實現gzip壓縮。

  1. 下載 compression webpack plugin

    npm i -D compression-webpack-plugin

  2. vue.config.js配置
const CompressionPlugin = require("compression-webpack-plugin");
module.exports = {

  configureWebpack: (config) => {
    if (process.env.NODE_ENV === 'production') {
      // 為生產環境修改配置...
      config.mode = 'production';

      if(openGzip){
        config.plugins = [
          ...config.plugins,
          new CompressionPlugin({
            test:/\.js$|\.html$|.\css/, //匹配文件名
            threshold: 10240,//對超過10k的數據壓縮
            deleteOriginalAssets: false //不刪除源文件
          })
        ]
      }

    } else {
      // 為開發環境修改配置...
      config.mode = 'development';
    }
    
  }
}
  1. package.js 配置
{
  "name": "demo-cli3",
  "version": "1.0.0",
  "openGizp": false,
  ...
}

4、vue-cli3 圖片壓縮【image-webpack-loader】使用

  1. 下載image-webpack-loader

    npm install --save-dev image-webpack-loader

  2. 在vue.config.js中修改相關配置
    4M的圖片使用默認設置壓縮成1.4M,自定義的設置可以更小
module.exports = {
  ...
  // 默認設置
  const defaultOptions = {
      bypassOnDebug: true
  }
 //  自定義設置
  const customOptions = {
      mozjpeg: {
        progressive: true,
        quality: 50
      },
      optipng: {
        enabled: true,
      },
      pngquant: {
        quality: [0.5, 0.65],
        speed: 4
      },
      gifsicle: {
        interlaced: false,
      },
      // 不支持WEBP就不要寫這一項
      webp: {
        quality: 75
      }
  }
  chainWebpack: config => {

    config.module.rule('images') 
        .test(/\.(gif|png|jpe?g|svg)$/i)
        .use('image-webpack-loader')
        .loader('image-webpack-loader')
        .options(customOptions)
        .end() 

  }
}

5、移動端.px2rem 響應樣式

  1. 安裝

npm i -S lib-flexible postcss-px2rem

  1. 引入 lib-flexible

在項目入口中main.js 中引入lib-flexible

import 'lib-flexible' 

# 注意事項: 由於flexible會動態給頁面header中添加<meta name='viewport' >標簽,所以務必請把目錄 public/index.html 中的這個標簽刪除!!
  1. 配置postcss-px2rem

項目中vue.config.js中進行如下的配置

module.exports = { 
    css: {
        loaderOptions: { 
            css: {}, 
            postcss: { 
                plugins: [ require('postcss-px2rem')({ remUnit: 37.5 }) 
                ] 
            } 
        } 
    } 
}

三、多頁面應用開發與配置

搭建項目

1. 創建項目

和我們正常創建項目相同,這里通過vue-cli3腳手架進行創建

vue create 項目name
選擇自己需要的依賴並進行下一步

2. 搭建文件結構

  • 新建pages存放每個頁面相關內容
  • pages---下創建相關頁面存放文件
  • 頁面文件內放入main.js 與 router.js

3. 配置路由

import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)

// const originalPush = VueRouter.prototype.push
// VueRouter.prototype.push = function push(location) {
//   return originalPush.call(this, location).catch((err) => err)
// }
const routes = [
    {
        path: '/login',
        name: 'login',
        component: () => import('./views/index.vue'),
        // component:()=>import('./reset.vue'),
        meta: {
            title: '這里是動態title'
        },
        children: [

            /*  
            單頁面應用的寫法     
            {
                path: 'reset',
                name: 'reset',
                component: () => import('./reset.vue')
            
            },
            */
           
            //  ***多頁面的寫法
            {
                path: 'editJobs',
                components: {
                    'editJobs': () => import('./views/reset.vue'),
                },
            },],

    },
    // {
    //     path: '/',
    //     redirect: '/'
    // }

]
export default new VueRouter({
    mode: 'hash',
    base: process.env.BASE_URL,
    routes
})

4. 配置vue.config.js

// 打包多入口文件基本配置
function getPagesInfo() {
    let pages = {}
    const glob = require('glob') // 引入glob模塊,用於掃描全部src/pages/**/main.js(返回的是一個數組)
    glob.sync('src/pages/**/main.js').forEach((entry, i) => {
        let name = entry.slice(10, -8)
        pages[name] = {
            entry: entry,
            template: 'public.index.html',
            filename: name + '.html',
            title: '',
            chunks: ["chunk-vendors", "chunk-common", name]
        }
    })
    return pages
}
module.exports = {
    pages: getPagesInfo(),
    publicPath: './kk',
    assetsDir: 'static',
};

注意事項

設置頁面動態標題

  1. 下載 vue-wechat-title

npm i -S vue-wechat-title

  1. main.js中全局引入
import VueWechatTitle from 'vue-wechat-title'
Vue.use(VueWechatTitle)
  1. App.vue中設置
<template>
<!-- 動態設置title -->
  <div id="app" v-wechat-title='$route.meta.title'>
    <router-view/>
  </div>
</template>

路由子模塊設置

  1. 路由配置方法
const routes = [
    {
        path: '/login',
        name: 'login',
        component: () => import('./views/index.vue'),
        meta: {
            title: '這里是動態title'
        },
        children: [
           
            //  ***多頁面的寫法
            {
                path: 'editJobs',
                components: {
                    'editJobs': () => import('./views/reset.vue'),
                },
            },],

    },
]
  1. 頁面中渲染寫法
<template>
  <div>
    login
    <router-link :to="{ name: 'reset' }" tag="li">我的收藏</router-link>
    這里的name對應的是route配置里的名字(別忘了地址連里面的path)
    <router-view name="editJobs">待完善信息</router-view>
  </div>
</template>

四、vue.config.js完整代碼

// 打包多入口文件基本配置
let developmentPath = './';//開發環境-npm run serve時引用文件路徑
let productionPath = './';//生產環境-npm run build打包后引用文件路徑

const UglifyJsPlugin = require('uglifyjs-webpack-plugin')//生產環境取消打印
const CompressionWebpackPlugin = require('compression-webpack-plugin')//gzip壓縮

const productionGzipExtensions = ['js', 'css']
const Version = 'V6.1'
const Timestamp = new Date().getTime()
function getPagesInfo() {
    let pages = {}
    const glob = require('glob') // 引入glob模塊,用於掃描全部src/pages/**/main.js(返回的是一個數組)
    glob.sync('src/pages/**/main.js').forEach((entry, i) => {
        let name = entry.slice(10, -8)
        pages[name] = {
            entry: entry,
            template: 'public.index.html',
            filename: name + '.html',
            title: '',
            chunks: ["chunk-vendors", "chunk-common", name]
        }
    })
    return pages
}
// 打包相關
module.exports = {
    pages: getPagesInfo(),//多頁面應用配置
    publicPath: process.env.NODE_ENV === 'production' ? productionPath : developmentPath, // 基本路徑-引用文件的路 __dirname + '/server/dist', //build之后靜態文件輸出路徑
    assetsDir: 'static',//靜態資源大包位置
    outputDir: __dirname + '/server/dist', //build之后靜態文件輸出路徑
    lintOnSave: process.env.NODE_ENV !== 'production',// 打包的時候eslint-loader檢查 
    productionSourceMap: false,//source map 檢查
    // 啟動服務器
    devServer: {
        index: '/login.html',   //默認打開文件
        open: true,             //自動打開瀏覽器
        host: 'localhost',      //默認打開域名
        port: 8080,             //默認打開端口號
        https: false,           //開啟關閉https請求
        hotOnly: false,         //熱更
        // 反向代理
        proxy: {
            // 配置跨域
            '/api': {
                target: 'http://dev.aabb.cn:8082/', //代理地址,這里設置的地址會代替axios中設置的baseURL
                ws: true,   //// proxy websockets
                changeOrigin: true,// 如果接口跨域,需要進行這個參數配置
                pathRewrite: {                //pathRewrite方法重寫url
                    '^/api': '/',
                },
            },
        },
    },
    // webpack配置  鏈式
    chainWebpack: (config) => {
        // 1、取消預加載增加加載速度
        config.plugins.delete('preload')
        config.plugins.delete('prefetch')

        // 2、vue中使用SVG圖標,並且想批量導入,然后需要使用的時候直接添加就可以
        config.module
            .rule('svg')
            .exclude.add(resolve('src/assets/icons'))
            .end()
        config.module
            .rule('icons')
            .test(/\.svg$/)
            .include.add(resolve('src/assets/icons'))
            .end()
            .use('svg-sprite-loader')
            .loader('svg-sprite-loader')
            .options({
                symbolId: 'icon-[name]',
            })
            .end()

        // 3、圖片處理
        const imagesRule = config.module.rule('images')
        imagesRule.uses.clear() //清除原本的images loader配置
        imagesRule
            .test(/\.(jpg|gif|png|svg)$/)
            .exclude.add(path.join(__dirname, '../node_modules')) //不對node_modules里的圖片轉base64
            .end()
            .use('url-loader')
            .loader('url-loader')
            .options({ name: 'img/[name].[hash:8].[ext]', limit: 6000000 })

        config.optimization.splitChunks({
            cacheGroups: {

                vendors: {
                    name: 'chunk-vendors',
                    minChunks: pageNum,
                    test: /node_modules/,
                    priority: -10,
                    chunks: 'initial',
                },

                elementUI: {
                    name: 'chunk-elementUI', // split elementUI into a single package
                    priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
                    test: /[\\/]node_modules[\\/]_?element-ui(.*)/, // in order to adapt to cnpm
                },

                commons: {
                    name: 'chunk-commons',
                    test: resolve('src/components'), // can customize your rules
                    minChunks: 3, //  minimum common number
                    priority: 5,
                    reuseExistingChunk: true,
                },
            },
        })
    },
    // webpack配置
    configureWebpack: (config) => {
          // 為生產環境修改配置
        if (process.env.NODE_ENV === 'production') {
      
            config.plugins.push(
                  // 1、取消打印
                new UglifyJsPlugin({
                    uglifyOptions: {
                        compress: {
                            drop_debugger: true,//生產環境自動刪除debugger
                            drop_console: true, //生產環境自動刪除console
                        },
                        warnings: false,
                    },
                    sourceMap: false,   //關掉sourcemap 會生成對於調試的完整的.map文件,但同時也會減慢打包速度
                    parallel: true, //使用多進程並行運行來提高構建速度。默認並發運行數:os.cpus().length - 1。
                }),

                // 2、gzip壓縮
                new CompressionWebpackPlugin({
                    filename: '[path].gz[query]',
                    algorithm: 'gzip',
                    test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
                    threshold: 10240,
                    minRatio: 0.8,
                })
            )
        }

        // 在這里配置后,減少了壓縮的包內容,需要在public/index.html通過cdn方式再引入,注意對應的版本
        config.externals = { 
            vue: 'Vue',
            'vue-router': 'VueRouter',
            vuex: 'Vuex',
            axios: 'axios',
            jquery: '$',
            moment: 'moment',
            'mint-ui': 'MINT'
        },


         // 別名配置
        Object.assign(config, {
            // 開發生產共同配置
            resolve: {
                alias: {
                '@': path.resolve(__dirname, './src'),
                '@c': path.resolve(__dirname, './src/components'),
                '@p': path.resolve(__dirname, './src/pages')
                }
            }
        }),

        config.output.filename = `[name].${Version}.${Timestamp}.js`  //打包生成的文件
        config.output.chunkFilename = `[name].${Version}.${Timestamp}.js`
    },
    // css相關
    css: {
        loaderOptions: {
            // 配置全局sass
            scss: {
                additionalData: `@import "@/assets/css/reset.scss";@import "@/assets/css/globle.scss";`  //注意配置的鍵名
            },
            // lib-flexible
            postcss: {
                plugins: [
                    //remUnit這個配置項的數值是多少呢??? 通常我們是根據設計圖來定這個值,原因很簡單,便於開發。
                    //假如設計圖給的寬度是750,我們通常就會把remUnit設置為75,這樣我們寫樣式時,可以直接按照設計圖標注的寬高來1:1還原開發。
                    require('postcss-px2rem')({
                        remUnit: 37.5
                    })
                ]
            }
        }
    },
    parallel: require('os').cpus().length > 1, // 是否為 Babel 或 TypeScript 使用 thread-loader。該選項在系統的 CPU 有多於一個內核時自動啟用,僅作用於生產構建。
    pwa: {}, // PWA 插件相關配置 
    pluginOptions: {},  // 第三方插件配置
};


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM