vue.config.js中的webpack配置,優(yōu)化及多頁(yè)面應(yīng)用開(kāi)發(fā)

目錄

  • 一、vue.config.js中常用的配置
    • 1、導(dǎo)出模塊
    • 2、publicPath 部署應(yīng)用包的基本Url
    • 3、outputDir 輸出文件目錄
    • 4、assetsDir 打包后生成的靜態(tài)資源目錄
    • 5、lintOnSave
    • 6、productionSourceMap 生產(chǎn)環(huán)境的 source map
    • 7、devServer
    • 8、 chainWebpack webpack配置
    • 9、configureWebpack webpack配置
      • configureWebpack和chainWebpack區(qū)別
    • 10、css相關(guān)配置
    • 11、pages
    • 12、其他
  • 二、優(yōu)化
    • 1、優(yōu)化打包c(diǎn)hunk-vendors.js
    • 2、打包時(shí)去除打印信息
    • 3、開(kāi)啟gizp壓縮
    • 4、vue-cli3 圖片壓縮【image-webpack-loader】使用
    • 5、移動(dòng)端.px2rem 響應(yīng)樣式
  • 三、多頁(yè)面應(yīng)用開(kāi)發(fā)與配置
    • 搭建項(xiàng)目
        1. 創(chuàng)建項(xiàng)目
        1. 搭建文件結(jié)構(gòu)
        1. 配置路由
        1. 配置vue.config.js
    • 注意事項(xiàng)
    • 設(shè)置頁(yè)面動(dòng)態(tài)標(biāo)題
    • 路由子模塊設(shè)置
  • 四、vue.config.js完整代碼

官方文檔

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

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

在配置中絕大多數(shù)都是(可選項(xiàng))

1、導(dǎo)出模塊

常規(guī)操作還是用到了commjs語(yǔ)法

module.exports = {

}

2、publicPath 部署應(yīng)用包的基本Url

部署應(yīng)用包的基本Url,默認(rèn)/, 可以設(shè)置為相對(duì)路徑./,這樣打出來(lái)的包,可以部署到任意路徑上

let developmentPath='./';//開(kāi)發(fā)環(huán)境-npm run serve時(shí)引用文件路徑
let productionPath='./';//生產(chǎn)環(huán)境-npm run build打包后引用文件路徑
module.exports = {
    publicPath: process.env.NODE_ENV === 'production' ? productionPath: developmentPath, // 基本路徑-引用文件的路
}

3、outputDir 輸出文件目錄

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

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

4、assetsDir 打包后生成的靜態(tài)資源目錄

打包后生成的靜態(tài)資源目錄,默認(rèn)“ ” ,也就是我們打包后的css,js等存放的位置

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

5、lintOnSave

是否在保存的時(shí)候檢查

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

6、productionSourceMap 生產(chǎn)環(huán)境的 source map

生產(chǎn)環(huán)境的 source map,可以將其設(shè)置為 false 以加速生產(chǎn)環(huán)境構(gòu)建,默認(rèn)值是true

module.exports = {
    productionSourceMap: false,
}

7、devServer

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

module.exports = {
// 反向代理
  devServer: {
    index: '/login.html',   //默認(rèn)打開(kāi)文件
    open: true,             //自動(dòng)打開(kāi)瀏覽器
    host: 'localhost',      //默認(rèn)打開(kāi)域名
    port: 8080,             //默認(rèn)打開(kāi)端口號(hào)
    https: false,           //開(kāi)啟關(guān)閉https請(qǐng)求
    hotOnly: false,         //熱更

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

擴(kuò)展: hot 和 hotOnly 的區(qū)別是在某些模塊不支持熱更新的情況下,前者會(huì)自動(dòng)刷新頁(yè)面,后者不會(huì)刷新頁(yè)面,而是在控制臺(tái)輸出熱更新失敗

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')) //不對(duì)node_modules里的圖片轉(zhuǎn)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,
        },
      },
    })
  },
}

擴(kuò)展:
Preload: 用于標(biāo)記頁(yè)面加載后即將用到的資源,瀏覽器將在主體渲染前加載preload標(biāo)記文件。Vue CLI 應(yīng)用會(huì)為所有初始化渲染需要的文件自動(dòng)生成 preload 提示;

Prefetch: 用于標(biāo)記瀏覽器在頁(yè)面加載完成后,利用空閑時(shí)間預(yù)加載的內(nèi)容。Vue CLI 應(yīng)用默認(rèn)為所有作為 async chunk 生成的 JavaScript 文件 (通過(guò)動(dòng)態(tài) import() 按需 code splitting 的產(chǎn)物) 自動(dòng)生成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) => {
          // 為生產(chǎn)環(huán)境修改配置
        if (process.env.NODE_ENV === 'production') {
      
            config.plugins.push(
                new UglifyJsPlugin({
                    uglifyOptions: {
                        compress: {
                            drop_debugger: true,//生產(chǎn)環(huán)境自動(dòng)刪除debugger
                            drop_console: true, //生產(chǎn)環(huán)境自動(dòng)刪除console
                        },
                        warnings: false,
                    },
                    sourceMap: false,   //關(guān)掉sourcemap 會(huì)生成對(duì)于調(diào)試的完整的.map文件,但同時(shí)也會(huì)減慢打包速度
                    parallel: true, //使用多進(jìn)程并行運(yùn)行來(lái)提高構(gòu)建速度。默認(rèn)并發(fā)運(yùn)行數(shù):os.cpus().length - 1。
                }),


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

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


         // 別名配置
        Object.assign(config, {
            // 開(kāi)發(fā)生產(chǎn)共同配置
            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`
    },
 }

擴(kuò)展:

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

configureWebpack和chainWebpack區(qū)別

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

  1. chainWebpack通過(guò)鏈?zhǔn)骄幊痰男问剑瑏?lái)修改默認(rèn)的webpack配置
  2. configureWebpack通過(guò)操作對(duì)象的形式,來(lái)修改默認(rèn)的webpack配置
    如果對(duì)一個(gè)loader或plugin修改的配置如果是一項(xiàng)的話推薦 chainWebpack、如果是多項(xiàng)的話用configureWebpack直接覆寫(xiě)

10、css相關(guān)配置

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

 css: {
        loaderOptions: {
            scss: {
                additionalData: `@import "@/assets/css/reset.scss";@import "@/assets/css/globle.scss";`  //注意配置的鍵名
            },
            postcss: {
                plugins: [
                    //remUnit這個(gè)配置項(xiàng)的數(shù)值是多少呢??? 通常我們是根據(jù)設(shè)計(jì)圖來(lái)定這個(gè)值,原因很簡(jiǎn)單,便于開(kāi)發(fā)。
                    //假如設(shè)計(jì)圖給的寬度是750,我們通常就會(huì)把remUnit設(shè)置為75,這樣我們寫(xiě)樣式時(shí),可以直接按照設(shè)計(jì)圖標(biāo)注的寬高來(lái)1:1還原開(kāi)發(fā)。
                    require('postcss-px2rem')({
                        remUnit: 37.5
                    })
                ]
            }
        }
    },

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

  • sass-loader loader v8-, 這個(gè)選項(xiàng)名是 "data",
  • sass-loader loader v8中, 這個(gè)選項(xiàng)名是 "prependData",
  • sass-loader loader v10+, 這個(gè)選項(xiàng)名是 "additionalData",

11、pages

vue-cli3中的webpack與vue多頁(yè)面應(yīng)用開(kāi)發(fā)
相關(guān)參數(shù):

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

封裝

const glob = require('glob') // 引入glob模塊,用于掃描全部src/pages/**/main.js(返回的是一個(gè)數(shù)組)
// 打包多入口文件基本配置
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。該選項(xiàng)在系統(tǒng)的 CPU 有多于一個(gè)內(nèi)核時(shí)自動(dòng)啟用,僅作用于生產(chǎn)構(gòu)建。
  • pwa: {}, // PWA 插件相關(guān)配置
  • pluginOptions: {} // 第三方插件配置

很好的pwa插件相關(guān)配置
pwa介紹及使用

二、優(yōu)化

1、優(yōu)化打包c(diǎn)hunk-vendors.js

當(dāng)運(yùn)行項(xiàng)目并且打包的時(shí)候,會(huì)發(fā)現(xiàn)chunk-vendors.js這個(gè)文件非常大,那是因?yàn)閣ebpack將所有的依賴全都?jí)嚎s到了這個(gè)文件里面,這時(shí)我們可以將其拆分,將所有的依賴都打包成單獨(dú)的js;

/*
利用splitChunks將每個(gè)依賴包單獨(dú)打包,在生產(chǎn)環(huán)境下配置,代碼如下
*/

configureWebpack: (config) => {
    if (process.env.NODE_ENV === 'production') {
      // 為生產(chǎn)環(huán)境修改配置...
      config.mode = 'production'
      // 將每個(gè)依賴包打包成單獨(dú)的js文件
      let optimization = {
        runtimeChunk: 'single',
        splitChunks: {
          chunks: 'all',
          maxInitialRequests: Infinity,
          minSize: 20000, // 依賴包超過(guò)20000bit將被單獨(dú)打包
          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、打包時(shí)去除打印信息

上面已經(jīng)提到過(guò)去掉打印的操作(console、debug)這里詳細(xì)講解一下

  1. 首先下載相關(guān)插件 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') {
      // 為生產(chǎn)環(huán)境修改配置...
      config.mode = 'production'
      // 將每個(gè)依賴包打包成單獨(dú)的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需寫(xiě)成以下方式

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

3、開(kāi)啟gizp壓縮

gizp壓縮是一種http請(qǐng)求優(yōu)化方式,通過(guò)減少文件體積來(lái)提高加載速度。html、js、css文件甚至json數(shù)據(jù)都可以用它壓縮,可以減小60%以上的體積。webpack在打包時(shí)可以借助 compression webpack plugin 實(shí)現(xiàn)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') {
      // 為生產(chǎn)環(huán)境修改配置...
      config.mode = 'production';

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

    } else {
      // 為開(kāi)發(fā)環(huán)境修改配置...
      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中修改相關(guān)配置
    4M的圖片使用默認(rèn)設(shè)置壓縮成1.4M,自定義的設(shè)置可以更小

module.exports = {
  ...
  // 默認(rèn)設(shè)置
  const defaultOptions = {
      bypassOnDebug: true
  }
 //  自定義設(shè)置
  const customOptions = {
      mozjpeg: {
        progressive: true,
        quality: 50
      },
      optipng: {
        enabled: true,
      },
      pngquant: {
        quality: [0.5, 0.65],
        speed: 4
      },
      gifsicle: {
        interlaced: false,
      },
      // 不支持WEBP就不要寫(xiě)這一項(xiàng)
      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、移動(dòng)端.px2rem 響應(yīng)樣式

  1. 安裝

npm i -S lib-flexible postcss-px2rem

  1. 引入 lib-flexible

在項(xiàng)目入口中main.js 中引入lib-flexible

import 'lib-flexible' 

# 注意事項(xiàng): 由于flexible會(huì)動(dòng)態(tài)給頁(yè)面header中添加<meta name='viewport' >標(biāo)簽,所以務(wù)必請(qǐng)把目錄 public/index.html 中的這個(gè)標(biāo)簽刪除!!
  1. 配置postcss-px2rem

項(xiàng)目中vue.config.js中進(jìn)行如下的配置

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

三、多頁(yè)面應(yīng)用開(kāi)發(fā)與配置

搭建項(xiàng)目

1. 創(chuàng)建項(xiàng)目

和我們正常創(chuàng)建項(xiàng)目相同,這里通過(guò)vue-cli3腳手架進(jìn)行創(chuàng)建

vue create 項(xiàng)目name
選擇自己需要的依賴并進(jìn)行下一步

2. 搭建文件結(jié)構(gòu)

  • 新建pages存放每個(gè)頁(yè)面相關(guān)內(nèi)容
  • pages---下創(chuàng)建相關(guān)頁(yè)面存放文件
  • 頁(yè)面文件內(nèi)放入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: '這里是動(dòng)態(tài)title'
        },
        children: [

            /*  
            單頁(yè)面應(yīng)用的寫(xiě)法     
            {
                path: 'reset',
                name: 'reset',
                component: () => import('./reset.vue')
            
            },
            */
           
            //  ***多頁(yè)面的寫(xiě)法
            {
                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(返回的是一個(gè)數(shù)組)
    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',
};

注意事項(xiàng)

設(shè)置頁(yè)面動(dòng)態(tài)標(biāo)題

  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中設(shè)置
<template>
<!-- 動(dòng)態(tài)設(shè)置title -->
  <div id="app" v-wechat-title='$route.meta.title'>
    <router-view/>
  </div>
</template>

路由子模塊設(shè)置

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

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

四、vue.config.js完整代碼

// 打包多入口文件基本配置
let developmentPath = './';//開(kāi)發(fā)環(huán)境-npm run serve時(shí)引用文件路徑
let productionPath = './';//生產(chǎn)環(huán)境-npm run build打包后引用文件路徑

const UglifyJsPlugin = require('uglifyjs-webpack-plugin')//生產(chǎn)環(huán)境取消打印
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(返回的是一個(gè)數(shù)組)
    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
}
// 打包相關(guān)
module.exports = {
    pages: getPagesInfo(),//多頁(yè)面應(yīng)用配置
    publicPath: process.env.NODE_ENV === 'production' ? productionPath : developmentPath, // 基本路徑-引用文件的路 __dirname + '/server/dist', //build之后靜態(tài)文件輸出路徑
    assetsDir: 'static',//靜態(tài)資源大包位置
    outputDir: __dirname + '/server/dist', //build之后靜態(tài)文件輸出路徑
    lintOnSave: process.env.NODE_ENV !== 'production',// 打包的時(shí)候eslint-loader檢查 
    productionSourceMap: false,//source map 檢查
    // 啟動(dòng)服務(wù)器
    devServer: {
        index: '/login.html',   //默認(rèn)打開(kāi)文件
        open: true,             //自動(dòng)打開(kāi)瀏覽器
        host: 'localhost',      //默認(rèn)打開(kāi)域名
        port: 8080,             //默認(rèn)打開(kāi)端口號(hào)
        https: false,           //開(kāi)啟關(guān)閉https請(qǐng)求
        hotOnly: false,         //熱更
        // 反向代理
        proxy: {
            // 配置跨域
            '/api': {
                target: 'http://dev.aabb.cn:8082/', //代理地址,這里設(shè)置的地址會(huì)代替axios中設(shè)置的baseURL
                ws: true,   //// proxy websockets
                changeOrigin: true,// 如果接口跨域,需要進(jìn)行這個(gè)參數(shù)配置
                pathRewrite: {                //pathRewrite方法重寫(xiě)url
                    '^/api': '/',
                },
            },
        },
    },
    // webpack配置  鏈?zhǔn)?    chainWebpack: (config) => {
        // 1、取消預(yù)加載增加加載速度
        config.plugins.delete('preload')
        config.plugins.delete('prefetch')

        // 2、vue中使用SVG圖標(biāo),并且想批量導(dǎo)入,然后需要使用的時(shí)候直接添加就可以
        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')) //不對(duì)node_modules里的圖片轉(zhuǎn)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) => {
          // 為生產(chǎn)環(huán)境修改配置
        if (process.env.NODE_ENV === 'production') {
      
            config.plugins.push(
                  // 1、取消打印
                new UglifyJsPlugin({
                    uglifyOptions: {
                        compress: {
                            drop_debugger: true,//生產(chǎn)環(huán)境自動(dòng)刪除debugger
                            drop_console: true, //生產(chǎn)環(huán)境自動(dòng)刪除console
                        },
                        warnings: false,
                    },
                    sourceMap: false,   //關(guān)掉sourcemap 會(huì)生成對(duì)于調(diào)試的完整的.map文件,但同時(shí)也會(huì)減慢打包速度
                    parallel: true, //使用多進(jìn)程并行運(yùn)行來(lái)提高構(gòu)建速度。默認(rèn)并發(fā)運(yùn)行數(shù):os.cpus().length - 1。
                }),

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

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


         // 別名配置
        Object.assign(config, {
            // 開(kāi)發(fā)生產(chǎn)共同配置
            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相關(guān)
    css: {
        loaderOptions: {
            // 配置全局sass
            scss: {
                additionalData: `@import "@/assets/css/reset.scss";@import "@/assets/css/globle.scss";`  //注意配置的鍵名
            },
            // lib-flexible
            postcss: {
                plugins: [
                    //remUnit這個(gè)配置項(xiàng)的數(shù)值是多少呢??? 通常我們是根據(jù)設(shè)計(jì)圖來(lái)定這個(gè)值,原因很簡(jiǎn)單,便于開(kāi)發(fā)。
                    //假如設(shè)計(jì)圖給的寬度是750,我們通常就會(huì)把remUnit設(shè)置為75,這樣我們寫(xiě)樣式時(shí),可以直接按照設(shè)計(jì)圖標(biāo)注的寬高來(lái)1:1還原開(kāi)發(fā)。
                    require('postcss-px2rem')({
                        remUnit: 37.5
                    })
                ]
            }
        }
    },
    parallel: require('os').cpus().length > 1, // 是否為 Babel 或 TypeScript 使用 thread-loader。該選項(xiàng)在系統(tǒng)的 CPU 有多于一個(gè)內(nèi)核時(shí)自動(dòng)啟用,僅作用于生產(chǎn)構(gòu)建。
    pwa: {}, // PWA 插件相關(guān)配置 
    pluginOptions: {},  // 第三方插件配置
};
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,825評(píng)論 6 546
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,814評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 178,980評(píng)論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 64,064評(píng)論 1 319
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,779評(píng)論 6 414
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 56,109評(píng)論 1 330
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,099評(píng)論 3 450
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 43,287評(píng)論 0 291
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,799評(píng)論 1 338
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,515評(píng)論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,750評(píng)論 1 375
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,221評(píng)論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,933評(píng)論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 35,327評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,667評(píng)論 1 296
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,492評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,703評(píng)論 2 380

推薦閱讀更多精彩內(nèi)容