webpack打包优化(vue)

:使用 vue-cli 自动构建的项目,没有webpack的设置文件;需要更改webpack 设置可以在vue.config.js中进行修改

configureWebpack:返回一个对象

chainWebpack:函数的链式操作

const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin')

const path = require('path')

function resolve(dir){

  return path.join(__dirname,dir)

}

module.exports = {

publicPath: './', // router hash 模式使用

  outputDir: 'dist',//输出内容的文件夹

  assetsDir: 'static',//编译内容的文件夹

  productionSourceMap: false,// 打包时不会生成 .map 文件,加快打包速度 

  lintOnSave: false ,//关闭格式检查

  devServer: { // 开发服务器

    host: needHost,

    port: port,

    open: false,

    overlay: {

      warnings: false,

      errors: true

    },

    proxy: {

      '/api': {

        target: 'xxxxxxx',

        secure: false,

        changeOrigin: true, //是否跨域

        logLevel: 'debug',

        pathRewrite: {

          '^/api': '' // pathRewrite 表示的意思是 把/api 替换为空

        }

      }

    }

  },

  configureWebpack: {

      optimization: {

        runtimeChunk: true

    },

     plugins: [

       new ScriptExtHtmlWebpackPlugin({

         inline: /runtime~.+\.js$/  //正则匹配runtime文件名

       })

     ]

  },

  chainWebpack: config => {

// set preserveWhitespace  

  config.module     

 .rule('vue')     

 .use('vue-loader') 

 .loader('vue-loader')      

.tap(options => {        

options.compilerOptions.preserveWhitespace = true       

 return options     

 })      .end()

 config.when(process.env.NODE_ENV === 'development', config => config.devtool('cheap-source-map')) // 设置调试查看源代码

    config.optimization.splitChunks({

      chunks:'all',

      cacheGroups:{

        commons:{

          name:'chunk-commons',

          test:resolve('src/components'),

          minChunks:3,

          priority:5,

          reuseExistingChunk:true

        },

        libs:{

          name:'chunk-libs',

          chunks:'initial',

          test:/[\\/]node_modules[\\/]/,

          priority:10

        }

      }

    })

    config.plugin('preload')

      .tap(args => {

        args[0].fileBlacklist.push(/runtime~.+\.js$/) //正则匹配runtime文件名,去除该文件的preload

        return args

      })

  }

}

工具模块

const path = require('path')

function resolve(dir){

return path.join(__dirname,dir)

}

基础配置

publicPath: './', // router hash 模式使用

  outputDir: 'dist',//输出内容的文件夹

  assetsDir: 'static',//编译内容的文件夹

  productionSourceMap: false,// 打包时不会生成 .map 文件,加快打包速度 

  lintOnSave: false ,//关闭格式检查

开发服务器代理

  devServer: { // 开发服务器

    host: needHost,

    port: port,

    open: false,

    overlay: {

      warnings: false,

      errors: true

    },

    proxy: {

      '/api': {

        target: 'xxxxxxx',

        secure: false,

        changeOrigin: true, //是否跨域

        logLevel: 'debug',

        pathRewrite: {

          '^/api': '' // pathRewrite 表示的意思是 把/api 替换为空

        }

      }

    }

  },

快捷引用

// resolve.alias 设置引入别名
config.resolve.alias

      .set('@', resolve('src'))

      .set('assets', resolve('src/assets'))

      .set('api', resolve('src/api'))

      .set('views', resolve('src/views'))

      .set('components', resolve('src/components'))

preserveWhitespace  

vue打包保留标签的空白

cheap-source-map

根据环境变量, 设置调试查看源代码

/*

  source-map:  一种 提供源代码到构建后代码映射 技术 (如果构建后代码出错,可以通过映射追踪到源代码错误)

  格式:[inline- | hidden- | eval-][nosources-][cheap-[module-]]source-map

    可以任意排列,但[]的顺序不能乱

  具体介绍

  source-map: 在外部生成一个文件

    在控制台会显示 错误代码准确信息 和 源代码的错误位置

  inline-source-map: 内嵌到bundle.js中

    只生成一个source-map

    在控制台会显示 错误代码准确信息 和 源代码的错误位置

  hidden-source-map: 外部

    错误代码错误原因,源代码的错误位置

    不能追踪源代码错误,只能提示到构建后代码的错误位置

  eval-source-map: 内嵌

    每一个文件都生成对应的source-map

    错误代码准确信息,源代码的错误位置

  nosources-source-map: 外部

    错误代码准确信息,没有任何源代码信息

  cheap-source-map: 外部

    错误代码准确信息,源代码的错误位置

    只能精准到行

  cheap-module-source-map: 外部

    错误代码准确信息,源代码的错误位置

    module会将loader的source-map加入

    内嵌与外部的区别: 1.外部生成单独的文件,内嵌没有 2.内嵌构建速度快

    这么多source-map如何选择?

    开发环境:速度快,调试更友好

      速度快( eval>inline>cheap>··· )

        组合eval-cheap-source-map > eval-source-map

      调试更友好

        source-map > cheap-module-source-map > cheap-source-map

      最终结果:cheap-module-source-map 和 eval-source-map (vuecli与react脚手架默认)

    生产环境:源代码要不要隐藏?调试要不要更友好

      内嵌会让代码体积变大,所以在生产环境下不用内嵌

      nosources-source-map  全部隐藏

      hidden-source-map  只隐藏源代码,会提示构建后代码错误信息

      最终结果:source-map 和 cheap-module-source-map

*/

runtimeChunk

根据路由驱动页面的 runtime 代码默认情况是包含在 build 后的 app.hash.js 内的,如果我们改动其他路由,就会导致 runtime 代码改变。从而不光我们改动的路由对应的页面 js 会变,含 runtime 代码的 app.hash.js 也会变,对用户体验是非常不友好的。

为了解决这个问题要设定 runtime 代码单独抽取打包;

script-ext-html-webpack-plugin

但是 runtime 代码由于只是驱动不同路由页面的关系,代码量比较少,请求 js 的时间都大于执行时间了,所以使用 script-ext-html-webpack-plugin 插件将其内链在 index.html 中比较友好。所有这两个一般配合使用。

configureWebpack:

optimization: {

        runtimeChunk: true

    },

    plugins: [

      new ScriptExtHtmlWebpackPlugin({

        inline: /runtime~.+\.js$/  //正则匹配runtime文件名

      })

    ]

chainWebpack:

  config

    .plugin('ScriptExtHtmlWebpackPlugin')

    .after('html')

    .use('script-ext-html-webpack-plugin', [

      {

        // `runtime` must same as runtimeChunk name. default is `runtime`

        inline: /runtime\..*\.js$/

      }

    ])

    .end()

    config.optimization.runtimeChunk('single')

splitChunks

如果使用了某些长期不会改变的库,像 element-ui ,打包完成有 600 多 KB ,包含在默认 vendor 中显然不合适,每次用户都要加载这么大的文件体验不好,所以要单独打包:

chainWebpack:

 config.optimization.splitChunks({

        chunks: 'all',

        cacheGroups: {

          commons: {

            name: 'chunk-commons',

            test: resolve('src/components'), // can customize your rules

            minChunks: 3, //  minimum common number

            priority: 5,

            reuseExistingChunk: true

          },

          libs: {

            name: 'chunk-libs',

            chunks: 'initial', // only package third parties that are initially dependent

            test: /[\\/]node_modules[\\/]/,

            priority: 10

          },

          elementUI: {

            name: 'chunk-elementUI',

            priority: 20,

            test: /[\\/]node_modules[\\/]_?element-ui(.*)/

          },

        }

      })

preload 预加载

提前预加载提高切换路由的体验

config.plugin('preload').tap(() => [

      {

        rel: 'preload',

        fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/],

        include: 'initial'

      }

    ])

    config.plugins.delete('prefetch')

这里要把 runtime 代码的 preload 去掉。

环境配置

.env.production 线上环境打包 // vue-cli-service serve 

.env.test  测试环境打包 // vue-cli-service test:unit

.env.development 开发环境打包  // vue-cli-service build 和 vue-cli-service test:e2eo

.emv.staging 使用mode 打包  -- vue-cli-service -- mode staging

.env.local. 本地环境变量,会被 git 忽略上传

环境变量

NODE_ENV、BASE_URL、VUE_APP_  开头的变量才能通过 webpacl.DefinePlugin静态的嵌入到客户端的代码中

 html-webpack-plugin

会处理 public/index.html 文件。在构建过程中,资源链接会被自动注入。

可以配置多页面入口:

{

  entry: 'index.js',

  output: {

    path: __dirname + '/dist',

    filename: 'index_bundle.js'

  },

  plugins: [

    new HtmlWebpackPlugin(), 

    new HtmlWebpackPlugin({  

      filename: 'test.html',

      template: 'src/assets/test.html'

    })

  ]

}

可以修改默认参数:

Options:{

title:

filename:

.....

}

config导出

导出vue默认webpack设置

vue inspect > output,js

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容