const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const CompressionPlugin=require('compression-webpack-plugin');
const isPro=['production'].includes(process.env.NODE_ENV);
var path=require('path');
const cdn = {
css: [],
js: [
'https://unpkg.com/[email protected]/dist/vue.min.js',
// vue-router
'https://unpkg.com/[email protected]/dist/vue-router.min.js',
// axios
'https://unpkg.com/[email protected]/dist/axios.min.js',
// vuex
'https://unpkg.com/[email protected]/dist/vuex.min.js',
]
};
module.exports = {
// 基本路径
publicPath: './',
// 输出文件目录
outputDir: 'dist',
// eslint-loader 是否在保存的时候检查
lintOnSave: false,
runtimeCompiler: true, // 是否需要增加原始的template渲染,默认false
productionSourceMap: false, // 是否需要生产环境的map包默认true
// 默认在生成的静态资源文件名中包含hash以控制缓存
// filenameHashing: true,
// // 构建多页面应用,页面的配置
// pages: {
// index: {
// // page 的入口
// entry: 'src/main.js',
// // 模板来源
// template: 'public/index.html',
// // 在 dist/index.html 的输出
// filename: 'index.html',
// // 当使用 title 选项时,template 中的 title 标签需要是 <%= htmlWebpackPlugin.options.title %>
// title: 'Index Page',
// // 在这个页面中包含的块,默认情况下会包含
// // 提取出来的通用 chunk 和 vendor chunk。
// chunks: ['chunk-vendors', 'chunk-common', 'index']
// },
// // 当使用只有入口的字符串格式时,模板会被推导为 `public/subpage.html`,并且如果找不到的话,就回退到 `public/index.html`。
// // 输出文件名会被推导为 `subpage.html`。
// // subpage: 'src/subpage/main.js'
// },
devServer: {
port: 8090,
https: false,
open: true,
proxy: {
'/': {
target: 'http://xxx',
ws: false,
changeOrigin: true,
},
}
},
configureWebpack: (config) => {
if (isPro) {
// 为生产环境修改配置...
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
// const htmlPlugin=require('html-webpack-plugin');
return {
plugins: [
new BundleAnalyzerPlugin(),
new CompressionPlugin({
test: /\.js$|\.html$|\.css/,
threshold: 10240,
deleteOriginalAssets: false
}),
],
optimization: {
minimizer: [
new UglifyJsPlugin({
uglifyOptions: {
compress: {
warnings: false,
drop_console: true, // console
drop_debugger: true,
pure_funcs: ['console.log']// 移除console
}
}
})
],
// splitChunks: {
// cacheGroups: {
// commons: {
// // test: /[\\/]src[\\/]utils[\\/]/,
// name: 'commons3',
// minSize: 30000,
// minChunks: 3,
// chunks: 'all',
// priority: 10,
// reuseExistingChunk: true // 这个配置允许我们使用已经存在的代码块
// },
// }}
},
externals: {
'vue': 'Vue',
'vuex': 'Vuex',
'vue-router': 'VueRouter',
'axios': 'axios',
// 'echarts': 'echarts',
}
};
} else {
return {
externals: {
'vue': 'Vue',
'vuex': 'Vuex',
'vue-router': 'VueRouter',
'axios': 'axios'
}
};
// 为开发环境修改配置...
}
},
// 配置
chainWebpack: config => {
// 此处配置可以在index.html遍历引入cdn 详见下面
config.plugin('html')
.tap(args => {
args[0].cdn = cdn;
return args;
});
config.module
.rule('images')
.use('image-webpack-loader')
.loader('image-webpack-loader')
.options({
bypassOnDebug: true
})
.end()
.use('url-loader')
.loader('url-loader')
.tap(options => Object.assign(options, { limit: 10240 }))
.end();
config.resolve.alias
.set('@@', path.join(__dirname, 'src/components'));
},
// css相关配置
css: {
// 启用 CSS modules
modules: false,
// 是否使用css分离插件
extract: isPro,
// 开启 CSS source maps?
sourceMap: !isPro,
// css预设器配置项
// loaderOptions: {},
},
};
index.html使用
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
<% } %>