vue-cli3.0 日常优化

Posted xiao旭

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue-cli3.0 日常优化相关的知识,希望对你有一定的参考价值。

1.项目第三方库 cdn引入

vue.config.js 中

// 是否为生产环境
const isProduction = process.env.NODE_ENV !== \'development\'
// 本地环境是否需要使用cdn
const devNeedCdn = false

// cdn链接
const cdn = {
  // cdn:模块名称和模块作用域命名(对应window里面挂载的变量名称)
  externals: {
    vue: \'Vue\',
    // vuex: \'Vuex\',
    \'vue-router\': \'VueRouter\',
    axios: \'axios\',
    vant: \'vant\',
  },
  // cdn的css链接
  css: [
    \'https://cdn.jsdelivr.net/npm/vant@2.9/lib/index.css\',
  ],
  // cdn的js链接
  js: [
    \'https://cdn.staticfile.org/vue/2.6.10/vue.min.js\',
    // \'https://cdn.staticfile.org/vuex/3.0.1/vuex.min.js\',
    \'https://cdn.staticfile.org/vue-router/3.0.3/vue-router.min.js\',
    \'https://cdn.bootcss.com/axios/0.19.2/axios.min.js\',
    \'https://cdn.jsdelivr.net/npm/vant@2.12/lib/vant.min.js\',
    // \'https://cdn.bootcss.com/moment.js/2.24.0/moment.min.js\',
    // \'https://cdn.bootcss.com/echarts/3.7.1/echarts.min.js\'
  ]
}

module.exports = {
    chainWebpack:config => {
        
      // 配置cdn引入
      config.plugin(\'html\').tap(args => {
        args[0].cdn = cdn
        return args
      })
        
    }
    configureWebpack:config => {
    // 用cdn方式引入,则构建时要忽略相关资源
    if (isProduction || devNeedCdn) config.externals = cdn.externals
}

pulic / index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover">
    <meta name="format-detection" content="telephone=yes"/>
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">

    <!-- 引入样式文件 -->
    <% for (var i in htmlWebpackPlugin.options.cdn &&
    htmlWebpackPlugin.options.cdn.css) { %>
    <link rel="stylesheet" href="<%= htmlWebpackPlugin.options.cdn.css[i] %>">
    <% } %>
      
    <!-- 引入js文件 -->
    <% for (var i in htmlWebpackPlugin.options.cdn &&
    htmlWebpackPlugin.options.cdn.js) { %>
    <script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
    <% } %>

  </head>
  <body>
    <div id="app"></div>
  </body>
</html>

2.将每个依赖包打包成单独的js/css文件

vue.config.js

module.exports = {
      chainWebpack: config => {
          
        // 将每个依赖包打包成单独的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
          })

          Object.assign(config, {
              output:{
                  ...config.output,
                  filename: `js/[name].[chunkhash].${version}.js`,
chunkFilename: `js/[name].[chunkhash].${version}.js`
},
});

3.项目自动引入 第三方插件样式 去掉 使用cdn引入样式

babel.config.js中

//style  true 会自动引入vant css样式  打包的时候会一起打包到 第三方的css样式中
//  开发时 引用配置    
module.exports = {
  presets: [\'@vue/cli-plugin-babel/preset\'],
  plugins: [
    [
      \'import\',
      { libraryName: \'vant\', libraryDirectory: \'es\', style: false },
      \'vant\'
    ]
  ]
};

vant 在使用cdn引入时 main.js 入口文件需要改造

//去掉vant引入
//import vant from \'vant\'

// 通过 CDN 引入时不会自动注册 Lazyload 组件
// 可以通过下面的方式手动注册
Vue.use(vant.Row);
Vue.use(vant.Col);
Vue.use(vant.Icon);
Vue.use(vant.Cell);

4.定义文件夹的缩写路径

vue.config.js

const path = require(\'path\')

function resolve (dir) {
  return path.join(__dirname, dir)
}

module.exports = {
    
    chainWebpack:config => {
        
         // 定义文件夹的路径
    	config.resolve.alias
          .set(\'@\', resolve(\'src\'))
          .set(\'@st\', resolve(\'static\'))	
        
    }
}

5.移除打包后文件的预加载prefetch/preload

vue.config.js

module.exports = {
    chainWebpack:config=>{
        // production 生产环境   development  开发环境
        if (process.env.NODE_ENV === \'production\') {
            // 为生产环境修改配置...
            // 移除 prefetch 插件
            config.plugins.delete("prefetch");
            // 移除 preload 插件
            config.plugins.delete(\'preload\');
            // 压缩代码
            config.optimization.minimize(true);
            // 分割代码
            // config.optimization.splitChunks({
            //   chunks: \'all\',
            // })
        }
	}
}

preload 是告诉浏览器页面必定需要的资源,浏览器一定会加载这些资源

prefetch 是告诉浏览器页面可能需要的资源,浏览器不一定会加载这些资源

6.不生成相应的 map文件

module.exports = { 
	productionSourceMap: false,
}

//productionSourceMap控制是否在生产环境下生成map文件,
//而devtool是开发调试的配置,如果你配置成source-map,那就会生成这个文件,配置成false就行了。

如果不生效,依然会有map文件生成

检查configureWebpack配置中的devtool选项

module.exports = { 
    configureWebpack(config){
        config.devtool=config.mode==="production"?false:"source-map";
    }
}

map文件的作用在于:项目打包后,代码都是经过压缩加密的,如果运行时报错,输出的错误信息无法准确得知是哪里的代码报错。也就是说map文件相当于是查看源码的一个东西。如果不需要定位问题,并且不想被看到源码,就把productionSourceMap 置为false,既可以减少包大小,也可以加密源码

------------恢复内容开始------------

#### 1.项目第三方库 cdn引入

vue.config.js 中

// 是否为生产环境
const isProduction = process.env.NODE_ENV !== \'development\'
// 本地环境是否需要使用cdn
const devNeedCdn = false

// cdn链接
const cdn = {
  // cdn:模块名称和模块作用域命名(对应window里面挂载的变量名称)
  externals: {
    vue: \'Vue\',
    // vuex: \'Vuex\',
    \'vue-router\': \'VueRouter\',
    axios: \'axios\',
    vant: \'vant\',
  },
  // cdn的css链接
  css: [
    \'https://cdn.jsdelivr.net/npm/vant@2.9/lib/index.css\',
  ],
  // cdn的js链接
  js: [
    \'https://cdn.staticfile.org/vue/2.6.10/vue.min.js\',
    // \'https://cdn.staticfile.org/vuex/3.0.1/vuex.min.js\',
    \'https://cdn.staticfile.org/vue-router/3.0.3/vue-router.min.js\',
    \'https://cdn.bootcss.com/axios/0.19.2/axios.min.js\',
    \'https://cdn.jsdelivr.net/npm/vant@2.12/lib/vant.min.js\',
    // \'https://cdn.bootcss.com/moment.js/2.24.0/moment.min.js\',
    // \'https://cdn.bootcss.com/echarts/3.7.1/echarts.min.js\'
  ]
}

module.exports = {
    chainWebpack:config => {
        
      // 配置cdn引入
      config.plugin(\'html\').tap(args => {
        args[0].cdn = cdn
        return args
      })
        
    }
    configureWebpack:config => {
    // 用cdn方式引入,则构建时要忽略相关资源
    if (isProduction || devNeedCdn) config.externals = cdn.externals
}

pulic / index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover">
    <meta name="format-detection" content="telephone=yes"/>
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">

    <!-- 引入样式文件 -->
    <% for (var i in htmlWebpackPlugin.options.cdn &&
    htmlWebpackPlugin.options.cdn.css) { %>
    <link rel="stylesheet" href="<%= htmlWebpackPlugin.options.cdn.css[i] %>">
    <% } %>
      
    <!-- 引入js文件 -->
    <% for (var i in htmlWebpackPlugin.options.cdn &&
    htmlWebpackPlugin.options.cdn.js) { %>
    <script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
    <% } %>

  </head>
  <body>
    <div id="app"></div>
  </body>
</html>

2.将每个依赖包打包成单独的js/css文件

vue.config.js

module.exports = {
      chainWebpack: config => {
          
        // 将每个依赖包打包成单独的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
          })

          Object.assign(config, {
              output:{
                  ...config.output,
                  filename: `js/[name].[chunkhash].${version}.js`,
chunkFilename: `js/[name].[chunkhash].${version}.js`
},
});

3.项目自动引入 第三方插件样式 去掉 使用cdn引入样式

babel.config.js中

//style  true 会自动引入vant css样式  打包的时候会一起打包到 第三方的css样式中
//  开发时 引用配置    
module.exports = {
  presets: [\'@vue/cli-plugin-babel/preset\'],
  plugins: [
    [
      \'import\',
      { libraryName: \'vant\', libraryDirectory: \'es\', style: false },
      \'vant\'
    ]
  ]
};

vant 在使用cdn引入时 main.js 入口文件需要改造

//去掉vant引入
//import vant from \'vant\'

// 通过 CDN 引入时不会自动注册 Lazyload 组件
// 可以通过下面的方式手动注册
Vue.use(vant.Row);
Vue.use(vant.Col);
Vue.use(vant.Icon);
Vue.use(vant.Cell);

4.定义文件夹的缩写路径

vue.config.js

const path = require(\'path\')

function resolve (dir) {
  return path.join(__dirname, dir)
}

module.exports = {
    
    chainWebpack:config => {
        
         // 定义文件夹的路径
    	config.resolve.alias
          .set(\'@\', resolve(\'src\'))
          .set(\'@st\', resolve(\'static\'))	
        
    }
}

5.移除打包后文件的预加载prefetch/preload

vue.config.js

module.exports = {
    chainWebpack:config=>{
        // production 生产环境   development  开发环境
        if (process.env.NODE_ENV === \'production\') {
            // 为生产环境修改配置...
            // 移除 prefetch 插件
            config.plugins.delete("prefetch");
            // 移除 preload 插件
            config.plugins.delete(\'preload\');
            // 压缩代码
            config.optimization.minimize(true);
            // 分割代码
            // config.optimization.splitChunks({
            //   chunks: \'all\',
            // })
        }
	}
}

preload 是告诉浏览器页面必定需要的资源,浏览器一定会加载这些资源

prefetch 是告诉浏览器页面可能需要的资源,浏览器不一定会加载这些资源

6.不生成相应的 map文件

module.exports = { 
	productionSourceMap: false,
}

//productionSourceMap控制是否在生产环境下生成map文件,
//而devtool是开发调试的配置,如果你配置成source-map,那就会生成这个文件,配置成false就行了。

如果不生效,依然会有map文件生成

检查configureWebpack配置中的devtool选项

module.exports = { 
    configureWebpack(config){
        config.devtool=config.mode==="production"?false:"source-map";
    }
}

map文件的作用在于:项目打包后,代码都是经过压缩加密的,如果运行时报错,输出的错误信息无法准确得知是哪里的代码报错。也就是说map文件相当于是查看源码的一个东西。如果不需要定位问题,并且不想被看到源码,就把productionSourceMap 置为false,既可以减少包大小,也可以加密源码

以上是关于vue-cli3.0 日常优化的主要内容,如果未能解决你的问题,请参考以下文章

webpack优化 -- happypack

vue-cli 3.0生成的项目run build后为空白页

vue-cli 3.0 实现A-Z字母滑动选择城市列表

Vue技术栈 使用Vue-Cli 3.0创建一个项目

Vue技术栈 使用Vue-Cli 3.0创建一个项目

Vue-cli3.0项目下axios请求本地json文件的数据