官方文档

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、导出模块

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

3、outputDir 输出文件目录

4、assetsDir 打包后生成的静态资源目录

5、lintOnSave

6、productionSourceMap 生产环境的 source map

7、devServer相关配置

8、 chainWebpack webpack配置

9、configureWebpack webpack配置

chainWebpack与configureWebpack异同

10、css相关配置

11、pages多页面应用

12、其他(parallel,pwa,pluginOptions)

二、优化打包chunk-vendors.js

三、打包时去除打印信息

四、开启gizp压缩

五、vue-cli3 图片压缩【image-webpack-loader】使用

六、.px2rem 响应样式

七、多页面应用开发与配置

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

在配置中绝大多数都是(可选项)

1、导出模块

常规操作还是用到了commjs语法

  1. module.exports = {
  2. }

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

部署应用包的基本Url,默认/, 可以设置为相对路径./,这样打出来的包,可以部署到任意路径上

  1. let developmentPath='./';//开发环境-npm run serve时引用文件路径
  2. let productionPath='./';//生产环境-npm run build打包后引用文件路径
  3. module.exports = {
  4. publicPath: process.env.NODE_ENV === 'production' ? productionPath: developmentPath, // 基本路径-引用文件的路
  5. }

3、outputDir 输出文件目录

输出文件目录(打包后生成的目录,默认dist)

  1. module.exports = {
  2. outputDir: __dirname + '/server/dist', //build之后静态文件输出路径
  3. //outputDir: 'dist',
  4. }

4、assetsDir 打包后生成的静态资源目录

打包后生成的静态资源目录,默认“ ” ,也就是我们打包后的css,js等存放的位置

  1. module.exports = {
  2. assetsDir: 'static',
  3. }

5、lintOnSave

是否在保存的时候检查

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

6、productionSourceMap 生产环境的 source map

生产环境的 source map,可以将其设置为 false 以加速生产环境构建,默认值是true

  1. module.exports = {
  2. productionSourceMap: false,
  3. }

7、devServer

可通过 devServer.proxy解决前后端跨域问题(反向代理)

  1. module.exports = {
  2. // 反向代理
  3. devServer: {
  4. index: '/login.html', //默认打开文件
  5. open: true, //自动打开浏览器
  6. host: 'localhost', //默认打开域名
  7. port: 8080, //默认打开端口号
  8. https: false, //开启关闭https请求
  9. hotOnly: false, //热更
  10. proxy: {
  11. // 配置跨域
  12. '/api': {
  13. target: 'http://dev.aabb.cn:8082/', //代理地址,这里设置的地址会代替axios中设置的baseURL
  14. ws: true, //// proxy websockets
  15. changeOrigin: true,// 如果接口跨域,需要进行这个参数配置
  16. pathRewrite: { //pathRewrite方法重写url
  17. '^/api': '/',
  18. },
  19. },
  20. },
  21. },
  22. }

扩展: hot 和 hotOnly 的区别是在某些模块不支持热更新的情况下,前者会自动刷新页面,后者不会刷新页面,而是在控制台输出热更新失败

8、 chainWebpack webpack配置

  1. module.exports = {
  2. chainWebpack: (config) => {
  3. config.plugins.delete('preload')
  4. config.plugins.delete('prefetch')
  5. config.module
  6. .rule('svg')
  7. .exclude.add(resolve('src/assets/icons'))
  8. .end()
  9. config.module
  10. .rule('icons')
  11. .test(/\.svg$/)
  12. .include.add(resolve('src/assets/icons'))
  13. .end()
  14. .use('svg-sprite-loader')
  15. .loader('svg-sprite-loader')
  16. .options({
  17. symbolId: 'icon-[name]',
  18. })
  19. .end()
  20. const imagesRule = config.module.rule('images')
  21. imagesRule.uses.clear() //清除原本的images loader配置
  22. imagesRule
  23. .test(/\.(jpg|gif|png|svg)$/)
  24. .exclude.add(path.join(__dirname, '../node_modules')) //不对node_modules里的图片转base64
  25. .end()
  26. .use('url-loader')
  27. .loader('url-loader')
  28. .options({ name: 'img/[name].[hash:8].[ext]', limit: 6000000 })
  29. config.optimization.splitChunks({
  30. cacheGroups: {
  31. vendors: {
  32. name: 'chunk-vendors',
  33. minChunks: pageNum,
  34. test: /node_modules/,
  35. priority: -10,
  36. chunks: 'initial',
  37. },
  38. elementUI: {
  39. name: 'chunk-elementUI', // split elementUI into a single package
  40. priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
  41. test: /[\\/]node_modules[\\/]_?element-ui(.*)/, // in order to adapt to cnpm
  42. },
  43. commons: {
  44. name: 'chunk-commons',
  45. test: resolve('src/components'), // can customize your rules
  46. minChunks: 3, // minimum common number
  47. priority: 5,
  48. reuseExistingChunk: true,
  49. },
  50. },
  51. })
  52. },
  53. }

扩展:

Preload: 用于标记页面加载后即将用到的资源,浏览器将在主体渲染前加载preload标记文件。Vue CLI 应用会为所有初始化渲染需要的文件自动生成 preload 提示;

Prefetch: 用于标记浏览器在页面加载完成后,利用空闲时间预加载的内容。Vue CLI 应用默认为所有作为 async chunk 生成的 JavaScript 文件 (通过动态 import() 按需 code splitting 的产物) 自动生成prefetch提示。

9、configureWebpack webpack配置

webpack配置

  1. const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
  2. const CompressionWebpackPlugin = require('compression-webpack-plugin')
  3. const productionGzipExtensions = ['js', 'css']
  4. const Version = 'V6.1'
  5. const Timestamp = new Date().getTime()
  6. module.exports = {
  7. webpack配置
  8. configureWebpack: (config) => {
  9. // 为生产环境修改配置
  10. if (process.env.NODE_ENV === 'production') {
  11. config.plugins.push(
  12. new UglifyJsPlugin({
  13. uglifyOptions: {
  14. compress: {
  15. drop_debugger: true,//生产环境自动删除debugger
  16. drop_console: true, //生产环境自动删除console
  17. },
  18. warnings: false,
  19. },
  20. sourceMap: false, //关掉sourcemap 会生成对于调试的完整的.map文件,但同时也会减慢打包速度
  21. parallel: true, //使用多进程并行运行来提高构建速度。默认并发运行数:os.cpus().length - 1。
  22. }),
  23. new CompressionWebpackPlugin({
  24. filename: '[path].gz[query]',
  25. algorithm: 'gzip',
  26. test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
  27. threshold: 10240,
  28. minRatio: 0.8,
  29. })
  30. )
  31. }
  32. // 在这里配置后,减少了压缩的包内容,需要在public/index.html通过cdn方式再引入,注意对应的版本
  33. config.externals = {
  34. vue: 'Vue',
  35. 'vue-router': 'VueRouter',
  36. vuex: 'Vuex',
  37. axios: 'axios',
  38. jquery: '$',
  39. moment: 'moment',
  40. 'mint-ui': 'MINT'
  41. },
  42. // 别名配置
  43. Object.assign(config, {
  44. // 开发生产共同配置
  45. resolve: {
  46. alias: {
  47. '@': path.resolve(__dirname, './src'),
  48. '@c': path.resolve(__dirname, './src/components'),
  49. '@p': path.resolve(__dirname, './src/pages')
  50. }
  51. }
  52. }),
  53. config.output.filename = `[name].${Version}.${Timestamp}.js` //打包生成的文件
  54. config.output.chunkFilename = `[name].${Version}.${Timestamp}.js`
  55. },
  56. }

扩展:

  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插件的作用差不多,都是用来将公共模块提取出来,但是用法不一样
  1. entry:{
  2. main:__dirname + '/app/main.js',
  3. index:__dirname + '/app/index.js'
  4. },
  5. output:{
  6. path:__dirname + '/public', //通过HtmlWebpackPlugin插件生成的html文件存放在这个目录下面
  7. filename:'/js/[name].js', //编译生成的js文件存放到根目录下面的js目录下面,如果js目录不存在则自动创建
  8. /*
  9. * chunkFilename用来打包require.ensure方法中引入的模块,如果该方法中没有引入任何模块则不会生成任何chunk块文件
  10. * 比如在main.js文件中,require.ensure([],function(require){alert(11);}),这样不会打包块文件
  11. * 只有这样才会打包生成块文件require.ensure([],function(require){alert(11);require('./greeter')})
  12. * 或者这样require.ensure(['./greeter'],function(require){alert(11);})
  13. * chunk的hash值只有在require.ensure中引入的模块发生变化,hash值才会改变
  14. * 注意:对于不是在ensure方法中引入的模块,此属性不会生效,只能用CommonsChunkPlugin插件来提取
  15. * */
  16. chunkFilename:'js/[chunkhash:8].chunk.js'
  17. },

configureWebpack和chainWebpack

在这里configureWebpack和chainWebpack的作用相同,唯一的区别就是他们修改webpack配置的方式不同:

  1. chainWebpack通过链式编程的形式,来修改默认的webpack配置
  2. configureWebpack通过操作对象的形式,来修改默认的webpack配置
如果对一个loader或plugin修改的配置如果是一项的话推荐 chainWebpack、如果是多项的话用configureWebpack直接覆写

10、css相关配置

这里配置了全局sass 需要安装的依赖 sass-loader less-loader

  1. css: {
  2. loaderOptions: {
  3. scss: {
  4. additionalData: `@import "@/assets/css/reset.scss";@import "@/assets/css/globle.scss";` //注意配置的键名
  5. },
  6. postcss: {
  7. plugins: [
  8. //remUnit这个配置项的数值是多少呢??? 通常我们是根据设计图来定这个值,原因很简单,便于开发。
  9. //假如设计图给的宽度是750,我们通常就会把remUnit设置为75,这样我们写样式时,可以直接按照设计图标注的宽高来1:1还原开发。
  10. require('postcss-px2rem')({
  11. remUnit: 37.5
  12. })
  13. ]
  14. }
  15. }
  16. },

由于 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:在这个页面中包含的块,默认情况下会包含
  1. module.exports = {
  2. pages:{
  3. main: {
  4. // page 的入口
  5. entry: "src/pages/main/main.js",
  6. // 模板来源
  7. template: "public/index.html",
  8. // 在 dist/index.html 的输出
  9. filename: "main.html",
  10. // 当使用 title 选项时,
  11. // template 中的 title 标签需要是 <title><%= htmlWebpackPlugin.options.title %></title>
  12. title: "Index Page",
  13. // 在这个页面中包含的块,默认情况下会包含
  14. // 提取出来的通用 chunk 和 vendor chunk。
  15. chunks: ["chunk-vendors", "chunk-common", "main"]
  16. },
  17. hh: {
  18. // page 的入口
  19. entry: "src/pages/login/main.js",
  20. // 模板来源
  21. template: "public/index.html",
  22. // 在 dist/index.html 的输出
  23. filename: "login.html",
  24. // 当使用 title 选项时,
  25. // template 中的 title 标签需要是 <title><%= htmlWebpackPlugin.options.title %></title>
  26. title: "Index Page",
  27. // 在这个页面中包含的块,默认情况下会包含
  28. // 提取出来的通用 chunk 和 vendor chunk。
  29. chunks: ["chunk-vendors", "chunk-common", "hh"]
  30. },
  31. // 当使用只有入口的字符串格式时,
  32. // 模板会被推导为 `public/subpage.html`
  33. // 并且如果找不到的话,就回退到 `public/index.html`。
  34. // 输出文件名会被推导为 `subpage.html`。
  35. subpage: "src/subpage/main.js"
  36. },
  37. }

封装

  1. const glob = require('glob') // 引入glob模块,用于扫描全部src/pages/**/main.js(返回的是一个数组)
  2. // 打包多入口文件基本配置
  3. function getPagesInfo() {
  4. let pages = {}
  5. glob.sync('src/pages/**/main.js').forEach((entry, i) => {
  6. let name = entry.slice(10, -8)
  7. pages[name] = {
  8. entry: entry,
  9. template: 'public.index.html',
  10. filename: name + '.html',
  11. title: '',
  12. chunks: ["chunk-vendors", "chunk-common", name]
  13. }
  14. })
  15. return pages
  16. }
  17. module.exports = {
  18. pages: getPagesInfo(),
  19. publicPath: './kk',
  20. assetsDir: 'static',
  21. };

12、其他

  • parallel: require('os').cpus().length > 1, // 是否为 Babel 或 TypeScript 使用 thread-loader。该选项在系统的 CPU 有多于一个内核时自动启用,仅作用于生产构建。
  • pwa: {}, // PWA 插件相关配置
  • pluginOptions: {} // 第三方插件配置

很好的pwa插件相关配置

pwa介绍及使用

二、优化打包chunk-vendors.js

当运行项目并且打包的时候,会发现chunk-vendors.js这个文件非常大,那是因为webpack将所有的依赖全都压缩到了这个文件里面,这时我们可以将其拆分,将所有的依赖都打包成单独的js;

  1. /*
  2. 利用splitChunks将每个依赖包单独打包,在生产环境下配置,代码如下
  3. */
  4. configureWebpack: (config) => {
  5. if (process.env.NODE_ENV === 'production') {
  6. // 为生产环境修改配置...
  7. config.mode = 'production'
  8. // 将每个依赖包打包成单独的js文件
  9. let optimization = {
  10. runtimeChunk: 'single',
  11. splitChunks: {
  12. chunks: 'all',
  13. maxInitialRequests: Infinity,
  14. minSize: 20000, // 依赖包超过20000bit将被单独打包
  15. cacheGroups: {
  16. vendor: {
  17. test: /[\\/]node_modules[\\/]/,
  18. name (module) {
  19. // get the name. E.g. node_modules/packageName/not/this/part.js
  20. // or node_modules/packageName
  21. const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1]
  22. // npm package names are URL-safe, but some servers don't like @ symbols
  23. return `npm.${packageName.replace('@', '')}`
  24. }
  25. }
  26. }
  27. }
  28. }
  29. Object.assign(config, {
  30. optimization
  31. })
  32. }
  33. }

三、打包时去除打印信息

上面已经提到过去掉打印的操作(console、debug)这里详细讲解一下

  1. 首先下载相关插件 uglifyjs-webpack-plugin

    npm i -D uglifyjs-webpack-plugin

  2. 在vue.config.js文件中引入,并在configureWebpack的optimization中添加如下代码
  1. const UglifyPlugin = require('uglifyjs-webpack-plugin')
  2. module.exports = {
  3. configureWebpack: (config) => {
  4. if (process.env.NODE_ENV === 'production') {
  5. // 为生产环境修改配置...
  6. config.mode = 'production'
  7. // 将每个依赖包打包成单独的js文件
  8. let optimization = {
  9. /*以下代码适用于uglifyjs-webpack-plugin 2.1.1及以前的版本*/
  10. minimizer: [new UglifyPlugin({
  11. uglifyOptions: {
  12. compress: {
  13. warnings: false,
  14. drop_console: true, // console
  15. drop_debugger: false,
  16. pure_funcs: ['console.log'] // 移除console
  17. }
  18. }
  19. })]
  20. }
  21. Object.assign(config, {
  22. optimization
  23. })
  24. }
  25. }
  26. }

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

  1. minimizer: [new UglifyPlugin({
  2. uglifyOptions: {
  3. warnings: false,
  4. compress: {
  5. drop_console: false, // console
  6. drop_debugger: false,
  7. pure_funcs: ['console.log'] // 移除console
  8. }
  9. }
  10. })]

四、开启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配置
  1. const CompressionPlugin = require("compression-webpack-plugin");
  2. module.exports = {
  3. configureWebpack: (config) => {
  4. if (process.env.NODE_ENV === 'production') {
  5. // 为生产环境修改配置...
  6. config.mode = 'production';
  7. if(openGzip){
  8. config.plugins = [
  9. ...config.plugins,
  10. new CompressionPlugin({
  11. test:/\.js$|\.html$|.\css/, //匹配文件名
  12. threshold: 10240,//对超过10k的数据压缩
  13. deleteOriginalAssets: false //不删除源文件
  14. })
  15. ]
  16. }
  17. } else {
  18. // 为开发环境修改配置...
  19. config.mode = 'development';
  20. }
  21. }
  22. }
  1. package.js 配置
  1. {
  2. "name": "demo-cli3",
  3. "version": "1.0.0",
  4. "openGizp": false,
  5. ...
  6. }

五、vue-cli3 图片压缩【image-webpack-loader】使用

  1. 下载image-webpack-loader

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

  2. 在vue.config.js中修改相关配置

    4M的图片使用默认设置压缩成1.4M,自定义的设置可以更小
  1. module.exports = {
  2. ...
  3. // 默认设置
  4. const defaultOptions = {
  5. bypassOnDebug: true
  6. }
  7. // 自定义设置
  8. const customOptions = {
  9. mozjpeg: {
  10. progressive: true,
  11. quality: 50
  12. },
  13. optipng: {
  14. enabled: true,
  15. },
  16. pngquant: {
  17. quality: [0.5, 0.65],
  18. speed: 4
  19. },
  20. gifsicle: {
  21. interlaced: false,
  22. },
  23. // 不支持WEBP就不要写这一项
  24. webp: {
  25. quality: 75
  26. }
  27. }
  28. chainWebpack: config => {
  29. config.module.rule('images')
  30. .test(/\.(gif|png|jpe?g|svg)$/i)
  31. .use('image-webpack-loader')
  32. .loader('image-webpack-loader')
  33. .options(customOptions)
  34. .end()
  35. }
  36. }

六、 .px2rem 响应样式

  1. 安装

npm i -S lib-flexible postcss-px2rem

  1. 引入 lib-flexible

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

  1. import 'lib-flexible'
  2. # 注意事项: 由于flexible会动态给页面header中添加<meta name='viewport' >标签,所以务必请把目录 public/index.html 中的这个标签删除!!
  1. 配置postcss-px2rem

项目中vue.config.js中进行如下的配置

  1. module.exports = {
  2. css: {
  3. loaderOptions: {
  4. css: {},
  5. postcss: {
  6. plugins: [ require('postcss-px2rem')({ remUnit: 37.5 })
  7. ]
  8. }
  9. }
  10. }
  11. }

七、多页面应用开发与配置

搭建项目

1. 创建项目

和我们正常创建项目相同,这里通过vue-cli3脚手架进行创建

vue create 项目name

选择自己需要的依赖并进行下一步

2. 搭建文件结构

  • 新建pages存放每个页面相关内容
  • pages---下创建相关页面存放文件
  • 页面文件内放入main.js 与 router.js

3. 配置路由

  1. import Vue from 'vue'
  2. import VueRouter from 'vue-router'
  3. Vue.use(VueRouter)
  4. // const originalPush = VueRouter.prototype.push
  5. // VueRouter.prototype.push = function push(location) {
  6. // return originalPush.call(this, location).catch((err) => err)
  7. // }
  8. const routes = [
  9. {
  10. path: '/login',
  11. name: 'login',
  12. component: () => import('./views/index.vue'),
  13. // component:()=>import('./reset.vue'),
  14. meta: {
  15. title: '这里是动态title'
  16. },
  17. children: [
  18. /*
  19. 单页面应用的写法
  20. {
  21. path: 'reset',
  22. name: 'reset',
  23. component: () => import('./reset.vue')
  24. },
  25. */
  26. // ***多页面的写法
  27. {
  28. path: 'editJobs',
  29. components: {
  30. 'editJobs': () => import('./views/reset.vue'),
  31. },
  32. },],
  33. },
  34. // {
  35. // path: '/',
  36. // redirect: '/'
  37. // }
  38. ]
  39. export default new VueRouter({
  40. mode: 'hash',
  41. base: process.env.BASE_URL,
  42. routes
  43. })

4. 配置vue.config.js

  1. // 打包多入口文件基本配置
  2. function getPagesInfo() {
  3. let pages = {}
  4. const glob = require('glob') // 引入glob模块,用于扫描全部src/pages/**/main.js(返回的是一个数组)
  5. glob.sync('src/pages/**/main.js').forEach((entry, i) => {
  6. let name = entry.slice(10, -8)
  7. pages[name] = {
  8. entry: entry,
  9. template: 'public.index.html',
  10. filename: name + '.html',
  11. title: '',
  12. chunks: ["chunk-vendors", "chunk-common", name]
  13. }
  14. })
  15. return pages
  16. }
  17. module.exports = {
  18. pages: getPagesInfo(),
  19. publicPath: './kk',
  20. assetsDir: 'static',
  21. };

注意事项

设置页面动态标题

  1. 下载 vue-wechat-title

npm i -S vue-wechat-title

  1. main.js中全局引入
  1. import VueWechatTitle from 'vue-wechat-title'
  2. Vue.use(VueWechatTitle)
  1. App.vue中设置
  1. <template>
  2. <!-- 动态设置title -->
  3. <div id="app" v-wechat-title='$route.meta.title'>
  4. <router-view/>
  5. </div>
  6. </template>

路由子模块设置

  1. 路由配置方法
  1. const routes = [
  2. {
  3. path: '/login',
  4. name: 'login',
  5. component: () => import('./views/index.vue'),
  6. meta: {
  7. title: '这里是动态title'
  8. },
  9. children: [
  10. // ***多页面的写法
  11. {
  12. path: 'editJobs',
  13. components: {
  14. 'editJobs': () => import('./views/reset.vue'),
  15. },
  16. },],
  17. },
  18. ]
  1. 页面中渲染写法
  1. <template>
  2. <div>
  3. login
  4. <router-link :to="{ name: 'reset' }" tag="li">我的收藏</router-link>
  5. 这里的name对应的是route配置里的名字(别忘了地址连里面的path)
  6. <router-view name="editJobs">待完善信息</router-view>
  7. </div>
  8. </template>

vue.config.js完整代码

  1. // 打包多入口文件基本配置
  2. let developmentPath = './';//开发环境-npm run serve时引用文件路径
  3. let productionPath = './';//生产环境-npm run build打包后引用文件路径
  4. const UglifyJsPlugin = require('uglifyjs-webpack-plugin')//生产环境取消打印
  5. const CompressionWebpackPlugin = require('compression-webpack-plugin')//gzip压缩
  6. const productionGzipExtensions = ['js', 'css']
  7. const Version = 'V6.1'
  8. const Timestamp = new Date().getTime()
  9. function getPagesInfo() {
  10. let pages = {}
  11. const glob = require('glob') // 引入glob模块,用于扫描全部src/pages/**/main.js(返回的是一个数组)
  12. glob.sync('src/pages/**/main.js').forEach((entry, i) => {
  13. let name = entry.slice(10, -8)
  14. pages[name] = {
  15. entry: entry,
  16. template: 'public.index.html',
  17. filename: name + '.html',
  18. title: '',
  19. chunks: ["chunk-vendors", "chunk-common", name]
  20. }
  21. })
  22. return pages
  23. }
  24. // 打包相关
  25. module.exports = {
  26. pages: getPagesInfo(),//多页面应用配置
  27. publicPath: process.env.NODE_ENV === 'production' ? productionPath : developmentPath, // 基本路径-引用文件的路 __dirname + '/server/dist', //build之后静态文件输出路径
  28. assetsDir: 'static',//静态资源大包位置
  29. outputDir: __dirname + '/server/dist', //build之后静态文件输出路径
  30. lintOnSave: process.env.NODE_ENV !== 'production',// 打包的时候eslint-loader检查
  31. productionSourceMap: false,//source map 检查
  32. // 启动服务器
  33. devServer: {
  34. index: '/login.html', //默认打开文件
  35. open: true, //自动打开浏览器
  36. host: 'localhost', //默认打开域名
  37. port: 8080, //默认打开端口号
  38. https: false, //开启关闭https请求
  39. hotOnly: false, //热更
  40. // 反向代理
  41. proxy: {
  42. // 配置跨域
  43. '/api': {
  44. target: 'http://dev.aabb.cn:8082/', //代理地址,这里设置的地址会代替axios中设置的baseURL
  45. ws: true, //// proxy websockets
  46. changeOrigin: true,// 如果接口跨域,需要进行这个参数配置
  47. pathRewrite: { //pathRewrite方法重写url
  48. '^/api': '/',
  49. },
  50. },
  51. },
  52. },
  53. // webpack配置 链式
  54. chainWebpack: (config) => {
  55. // 1、取消预加载增加加载速度
  56. config.plugins.delete('preload')
  57. config.plugins.delete('prefetch')
  58. // 2、vue中使用SVG图标,并且想批量导入,然后需要使用的时候直接添加就可以
  59. config.module
  60. .rule('svg')
  61. .exclude.add(resolve('src/assets/icons'))
  62. .end()
  63. config.module
  64. .rule('icons')
  65. .test(/\.svg$/)
  66. .include.add(resolve('src/assets/icons'))
  67. .end()
  68. .use('svg-sprite-loader')
  69. .loader('svg-sprite-loader')
  70. .options({
  71. symbolId: 'icon-[name]',
  72. })
  73. .end()
  74. // 3、图片处理
  75. const imagesRule = config.module.rule('images')
  76. imagesRule.uses.clear() //清除原本的images loader配置
  77. imagesRule
  78. .test(/\.(jpg|gif|png|svg)$/)
  79. .exclude.add(path.join(__dirname, '../node_modules')) //不对node_modules里的图片转base64
  80. .end()
  81. .use('url-loader')
  82. .loader('url-loader')
  83. .options({ name: 'img/[name].[hash:8].[ext]', limit: 6000000 })
  84. config.optimization.splitChunks({
  85. cacheGroups: {
  86. vendors: {
  87. name: 'chunk-vendors',
  88. minChunks: pageNum,
  89. test: /node_modules/,
  90. priority: -10,
  91. chunks: 'initial',
  92. },
  93. elementUI: {
  94. name: 'chunk-elementUI', // split elementUI into a single package
  95. priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
  96. test: /[\\/]node_modules[\\/]_?element-ui(.*)/, // in order to adapt to cnpm
  97. },
  98. commons: {
  99. name: 'chunk-commons',
  100. test: resolve('src/components'), // can customize your rules
  101. minChunks: 3, // minimum common number
  102. priority: 5,
  103. reuseExistingChunk: true,
  104. },
  105. },
  106. })
  107. },
  108. // webpack配置
  109. configureWebpack: (config) => {
  110. // 为生产环境修改配置
  111. if (process.env.NODE_ENV === 'production') {
  112. config.plugins.push(
  113. // 1、取消打印
  114. new UglifyJsPlugin({
  115. uglifyOptions: {
  116. compress: {
  117. drop_debugger: true,//生产环境自动删除debugger
  118. drop_console: true, //生产环境自动删除console
  119. },
  120. warnings: false,
  121. },
  122. sourceMap: false, //关掉sourcemap 会生成对于调试的完整的.map文件,但同时也会减慢打包速度
  123. parallel: true, //使用多进程并行运行来提高构建速度。默认并发运行数:os.cpus().length - 1。
  124. }),
  125. // 2、gzip压缩
  126. new CompressionWebpackPlugin({
  127. filename: '[path].gz[query]',
  128. algorithm: 'gzip',
  129. test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
  130. threshold: 10240,
  131. minRatio: 0.8,
  132. })
  133. )
  134. }
  135. // 在这里配置后,减少了压缩的包内容,需要在public/index.html通过cdn方式再引入,注意对应的版本
  136. config.externals = {
  137. vue: 'Vue',
  138. 'vue-router': 'VueRouter',
  139. vuex: 'Vuex',
  140. axios: 'axios',
  141. jquery: '$',
  142. moment: 'moment',
  143. 'mint-ui': 'MINT'
  144. },
  145. // 别名配置
  146. Object.assign(config, {
  147. // 开发生产共同配置
  148. resolve: {
  149. alias: {
  150. '@': path.resolve(__dirname, './src'),
  151. '@c': path.resolve(__dirname, './src/components'),
  152. '@p': path.resolve(__dirname, './src/pages')
  153. }
  154. }
  155. }),
  156. config.output.filename = `[name].${Version}.${Timestamp}.js` //打包生成的文件
  157. config.output.chunkFilename = `[name].${Version}.${Timestamp}.js`
  158. },
  159. // css相关
  160. css: {
  161. loaderOptions: {
  162. // 配置全局sass
  163. scss: {
  164. additionalData: `@import "@/assets/css/reset.scss";@import "@/assets/css/globle.scss";` //注意配置的键名
  165. },
  166. // lib-flexible
  167. postcss: {
  168. plugins: [
  169. //remUnit这个配置项的数值是多少呢??? 通常我们是根据设计图来定这个值,原因很简单,便于开发。
  170. //假如设计图给的宽度是750,我们通常就会把remUnit设置为75,这样我们写样式时,可以直接按照设计图标注的宽高来1:1还原开发。
  171. require('postcss-px2rem')({
  172. remUnit: 37.5
  173. })
  174. ]
  175. }
  176. }
  177. },
  178. parallel: require('os').cpus().length > 1, // 是否为 Babel 或 TypeScript 使用 thread-loader。该选项在系统的 CPU 有多于一个内核时自动启用,仅作用于生产构建。
  179. pwa: {}, // PWA 插件相关配置
  180. pluginOptions: {}, // 第三方插件配置
  181. };

vue-cli3.x中的webpack配置,优化及多页面应用开发的更多相关文章

  1. vue-cli 中的 webpack 配置详解

    本篇文章主要介绍了 vue-cli 2.8.2 中的 webpack 配置详解, 做个学习笔记 版本 vue-cli 2.8.1 (终端通过 vue -V 可查看) vue 2.2.2 webpack ...

  2. 使用 vue-cli-service inspect 来查看一个 Vue CLI 3 项目的 webpack 配置信息(包括:development、production)

    使用 vue-cli-service inspect 来查看一个 Vue CLI 3 项目的 webpack 配置信息(包括:development.production) --mode 指定环境模式 ...

  3. webpack配置优化

    1.使用alias简化路径 alias: { 'vue$': 'vue/dist/vue.esm.js', '@': resolve('src') } 2.overlay界面弹出编译错误 devSer ...

  4. vue-cli中的webpack配置

    编辑模式下显示正常,打开的时候不知道为啥排版有问题.segementfalut链接在这里 版本号 vue-cli 2.8.1 (终端通过vue -V 可查看) vue 2.2.2 webpack 2. ...

  5. vue cli 中关于vue.config.js中chainWebpack的配置

    Vue CLI  的官方文档上写:调整webpack配置最简单的方式就是在vue.config.js中的configureWebpack选项提供一个对象. Vue CLI 内部的 webpack 配置 ...

  6. Vue.js 第5章 webpack配置

    为什么我们需要打包构建工具:因为我们以后做项目的时候,会使用到很多种不同的工具或者语言,这些工具或者语言其实浏览器并不支持 webpack 是一个现代 JavaScript 应用程序的模块打包器(mo ...

  7. 前端学习笔记系列一:11@vue/cli3.x中实现跨域的问题

    由于浏览器的同源访问策略,vue开发时前端服务器通常与后端api服务器并非是相同的服务器,因此需要使用一个代理服务器实现跨域访问.在@vue/cli3.x根目录下创建一个vue.config.js文件 ...

  8. vue cli3项目中使用qrcodejs2生成二维码

    组件的形式创建 1.下载依赖 npm install qrcodejs2 2.创建一个.vue的组件放置代码(我创建的是qrcodejs2.vue) //template中的代码 <templa ...

  9. Vue项目中使用webpack配置了别名,引入的时候报错

    chainWebpack(config) { config.resolve.alias .set('@', resolve('src')) .set('assets', resolve('src/as ...

随机推荐

  1. SAML 2.0 流程分析(2)

  2. xmind2020 zen 10.3.1安装破解教程

    hi大家好,xmind zen 2020 10.3.1是一款优秀的思维导图工具,我和我爸爸都在用,功能包括去掉xmind zen水印.上传图片等功能,支持windows操作系统! 文章教大家安装并解锁 ...

  3. 构建前端第9篇之(上)---Vue组件引入,使用

    张艳涛写于2020-1-25日 一.想写下vue引入组件和插件的理解 今天是星期一,周末也看俩两天,在这个几天了,比较迷,主要是从开始学习import指令开始的,import 是es6的语法, imp ...

  4. vue源码解析之observe

    一. vue文档中有"由于 JavaScript 的限制,Vue 不能检测以下数组的变动",是否真是由于JavaScript的限制,还是出于其他原因考虑 当你利用索引直接设置一个数 ...

  5. etcd学习(5)-etcd的Raft一致性算法原理

    ETCD的Raft一致性算法原理 前言 Raft原理了解 raft选举 raft中的几种状态 任期 leader选举 日志复制 安全性 leader宕机,新的leader未同步前任committed的 ...

  6. sqli-labs靶机

    第一关   1' 第二关   1 第三关    1') 第四关    1'') 第五关   1'     +         extractvalue报错注入 第六关   1 "  +    ...

  7. 学习笔记-CCS-MSP430F5529[快速入门篇二]

    由于2021的全国电赛延期了,从今天开始打算好好整理一下使用CCS编程的经验,本篇笔记会好好整理一下我备赛期间用CCS写的程序,包括外部中断,定时器部分的定时中断,定时器输入捕获,PWM波输出,UAR ...

  8. MySQL Utilities工具教程

    一.MySQL Utilities介绍 MySQL Utilities 提供一组命令行工具用于维护和管理 MySQL 服务器,包括: 管理工具 (克隆.复制.比较.差异.导出.导入)复制工具 (安装. ...

  9. CYPEESS USB3.0程序解读之---GPIO

    CPRESS 官方给出的SDK1.1中(目前最新的SDK),提供了大量的例程供我们开发软件的时候作参考,就像STM32的开发一样提供了库一样,但是又不是库,仅仅是参考例程. 首先看一个简单一点的GPI ...

  10. sqlplus登录用户被锁问题

    oracle有三个默认的用户名和密码: 1.用户名:sys密码:change_on_install 2.用户名:system密码:manager 3.用户名:scott密码:tiger   当登录用户 ...