vue打包配置


vue.config.js 基本配置

module.exports = {
	publicPath: './', // 默认为'/',
	outputDir: process.env.outputDir || 'dist', // 'dist', 生产环境构建文件的目录
	assetsDir: '', // 相对于outputDir的静态资源(js、css、img、fonts)目录
	lintOnSave: false, // eslint
	runtimeCompiler: true, // 是否使用包含运行时编译器的 Vue 构建版本
	productionSourceMap: false, // 生产环境的 source map
	parallel: require('os').cpus().length > 1,
	pwa: {}
}

自定义路径别名

const path = require('path')
const resolve = dir => path.join(__dirname, dir)
module.exports = {
	chainWebpack: config => {
		// 添加别名
		config.resolve.alias
			.set('@', resolve('src'))
			.set('assets', resolve('src/assets'))
			.set('components', resolve('src/components'))
			.set('views', resolve('src/views'))
			.set('static', resolve('src/static'))
	}
}

修复热更新失效

module.exports = {
	chainWebpack: config => {
		// 修复HMR
		config.resolve.symlinks(true)
	}
}

配置 externals

module.exports = {
	configureWebpack: config => {
		config.externals = {
			vue: 'Vue',
			'element-ui': 'ELEMENT',
			'vue-router': 'VueRouter',
			vuex: 'Vuex',
			axios: 'axios'
		}
	}
}

为 sass 提供全局样式以及全局变量

去除 console.log()

npm i babel-plugin-transfrom-remove-console -D

babel.config.js文件中添加

const prodPlugin = [] // 生产环境所需要用到的插件
if (process.env.NODE_ENV === 'production') {
	prodPlugin.push([
		'transform-remove-console',
		{
			// 保留error和warn
			exclude: ['error', 'warn']
		}
	])
}

module.exports = {
	plugins: [...prodPlugin]
}

移动端适配

① 将px转换为rem;② 将px转换为vw

vuecli创建的项目本身就自带postcss-pxtorem

安装插件yarn add amfe-flexibleyarn add postcss-pxtorem

依赖项autoautoprefixer版本为 8.0.0

// main.js
import 'amfe-flexible'
// .postcssrc.js
module.exports = {
	// 配置使用 postcss-pxtorem 插件
	// 作用:把 px 转为 rem
	plugins: {
		'postcss-pxtorem': {
			rootValue: 192,
			propList: ['*'],
			selectorBlackList: ['.van-'], // 要忽略的选择器并保留为px。
			propList: ['*'], // 将px更改为rem的属性。
			minPixelValue: 2 // 设置要替换的最小像素值。
		}
	}
}

使用.postcssrc.js配置

module.exports = {
	plugins: {
		'postcss-pxtorem': {
			rootValue: 32, // 换算的基数
			selectorBlackList: ['.van-'], // 要忽略的选择器并保留为px。
			propList: ['*'], // 将px更改为rem的属性。
			minPixelValue: 2 // 设置要替换的最小像素值。
		}
	}
}

移动端调试

vConsole是腾讯开发的一个用于调试移动端项目的插件。

yarn add vconsole

main.js中,将vconsole添加到开发环境下使用,生产环境不会使用到。

import vconsole from 'vconsole'
if (proceee.env.NODE_ENV === 'development') {
	new vconsole()
}

moment变得更小

const webpack = require('webpack')
module.expots = {
	chainWebpack: config => {
		// 优化moment 去掉国际化内容
		config
			.plugin('ignore')
			// 忽略/moment/locale下的所有文件
			.use(new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/))
	}
}

此时因为去掉了所有所有的国际化内容,导致不能显示中文语言,需要单独引入

import moment from 'moment'
// 手动引入所需要的语言包
import 'moment/locale/zh-cn'
// 指定使用的语言
moment.locale('zh-cn')

开启 Gzip 压缩

new CompressionWebpackPlugin({
	algorithm: 'gzip',
	test: /\.(js|css)$/, // 匹配文件名
	threshold: 10000, // 对超过10k的数据压缩
	deleteOriginalAssets: false, // 不删除源文件
	minRatio: 0.8 // 压缩比
})

本地代理

// const { HashedModuleIdsPlugin } = require('webpack')
module.exports = {
	devServer: {
		open: true, // 自动启动浏览器
		host: '0.0.0.0', // localhost
		port: 6090,
		https: false,
		hotOnly: true, // 热更新
		proxy: {
			'^/sso': {
				target: process.env.VUE_APP_SSO, // 接口的域名
				ws: true, //开启WebSocket
				secure: false, // 如果是https接口,需要配置这个参数
				changeOrigin: true // 如果接口跨域,需要进行此参数的配置
                // http://localhost:8080/sso => http://192.168.1.28:3333/sso
			},
            '/api': {
				changeOrigin: true,
				target: 'http://192.168.1.28:3333',
				// 重写路径
				pathRewrite: {
					'^/api': ''
				}
				// http://localhost:8080/api/login => http://192.168.1.28:3333/login
		}
	}
}

环境变量

// .env.dev
VUE_APP_TITLE="项目1-开发环境"
  "scripts": {
    "dev": "vue-cli-service serve --mode dev",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
console.log(process.env.VUE_APP_TITLE)

只打包改变的文件

const { HashedModuleIdsPlugin } = require('webpack')
module.exports = {
	chainWebpack: config => {
		if (process.env.NODE_ENV === 'production') {
			const plugins = [new HashedModuleIdsPlugin()]
			plugins.push()
		}
	}
}

页面加载进度条

安装npm i nprogress

// [main.js]
// 加载进度条包对应js和css
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
// axios请求拦截
axios.interceptors.request.use(config => {
	NProgress.start() // 在request中展示进度条
	// ......
})

axios.interceptors.request.use(config => {
	NProgress.done() // 在response中隐藏进度
	// ......
})

开启打包日志

安装npm i webpack-bundle-analyzer

module.exports = {
	chainWebpack: config => {
		if (process.env.NODE_ENV === 'production') {
			config
				.plugin('webpack-bundle-analyzer')
				.use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
		}
	}
}

一份较完整的配置

const path = require('path')
const { HashedModuleIdsPlugin } = require('webpack')
const resolve = dir => path.join(__dirname, dir)
const externals = {
  vue: 'Vue',
  'vue-router': 'VueRouter',
  vuex: 'Vuex',
  'view-design': 'iview'
}
// cnd预加载
const cdn = {
  dev: {
    css: [
      'https://unpkg.com/view-design@4.6.0-beta.4/dist/styles/iview.css'
    ],
    js: []
  },
  // 生产环境
  build: {
    css: [
      'https://unpkg.com/view-design@4.6.0-beta.4/dist/styles/iview.css'
    ],
    js: [
      'https://cdn.bootcdn.net/ajax/libs/vue/2.6.6/vue.min.js',
      'https://cdn.bootcdn.net/ajax/libs/vue-router/3.5.1/vue-router.min.js',
      'https://cdn.bootcdn.net/ajax/libs/vuex/3.6.2/vuex.min.js',
      'https://unpkg.com/view-design@4.6.0-beta.4/dist/iview.min.js'
      // 'https://cdn.bootcdn.net/ajax/libs/crypto-js/4.0.0/crypto-js.min.js'
    ]
  }
}

module.exports = {
  publicPath: process.env.NODE_ENV === 'production' ? './' : '/', // 默认为'/',
  outputDir: process.env.outputDir || 'dist', // 'dist', 生产环境构建文件的目录
  // assetsDir: 'assets', // 相对于outputDir的静态资源(js、css、img、fonts)目录
  productionSourceMap: false, // 生产环境的 source map
  devServer: {
    open: true,
    hotOnly: true
  },
  configureWebpack: config => {
    const plugins = []
    // 打包分析
    if (process.env.NODE_ENV === 'production') {
      // 打包时npm包转CDN
      config.externals = externals
      // 用于根据模块的相对路径生成 hash 作为模块 id, 一般用于生产环境
      plugins.push(new HashedModuleIdsPlugin())
      // 开启分离js
      config.optimization = {
        runtimeChunk: 'single',
        splitChunks: {
          chunks: 'all',
          maxInitialRequests: Infinity,
          minSize: 1000 * 60,
          cacheGroups: {
            vendor: {
              test: /[\\/]node_modules[\\/]/,
              name (module) {
                // 排除node_modules 然后吧 @ 替换为空 ,考虑到服务器的兼容
                const packageName = module.context.match(
                  /[\\/]node_modules[\\/](.*?)([\\/]|$)/
                )[1]
                return `npm.${packageName.replace('@', '')}`
              }
            }
          }
        }
      }
    }
    return { plugins }
  },
  chainWebpack: config => {
    config.resolve.symlinks(true)
    // webpack 会默认给commonChunk打进chunk-vendors,所以需要对webpack的配置进行delete
    config.optimization.delete('splitChunks')
    config.resolve.alias
      .set('@', resolve('src'))
      .set('assets', resolve('src/assets'))
      .set('components', resolve('src/components'))
      .set('views', resolve('src/views'))
      .set('static', resolve('src/static'))
      .set('utils', resolve('src/utils'))
    config.plugin('html').tap(args => {
      if (process.env.NODE_ENV === 'production') {
        args[0].cdn = cdn.build
        args[0].prod = true
      }
      if (process.env.NODE_ENV === 'development') {
        args[0].cdn = cdn.dev
      }
      args[0].title = process.env.title
      return args
    })
    if (process.env.NODE_ENV === 'production') {
      // 打包性能分析
      config
        .plugin('webpack-bundle-analyzer')
        .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
    }
  }
}
<% for (var i in
htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %>
<link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="stylesheet"/>
<% } %>
    

<% for (var i in
htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
<script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>" async></script>
<% } %>

vuerouter

vue-router3路由重复点击报错问题

const originalPush = Router.prototype.push
Router.prototype.push = function push(location) {
  return originalPush.call(this, location).catch(err => err)
}


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM