vue.config.js 建立的時候沒有,需要手動建立
const path = require('path');
const webpack = require('webpack');
const UglifyPlugin = require('uglifyjs-webpack-plugin');
const CompressionPlugin = require("compression-webpack-plugin");
// const PurgeCssWebpackPlugin = require("purgecss-webpack-plugin"); // 主要的作用刪除無意義的css,只能配合 mini-css-extract-plugin
// const glob = require("glob"); // 主要功能就是查詢匹配的檔案,配合PurgeCssWebpackPlugin
const {
BundleAnalyzerPlugin
} = require('webpack-bundle-analyzer');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); //壓縮css外掛
//const AddCdnPlguin = require("add-asset-html-cdn-webpack-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin')
//const SpeedMeasureWebpackPlugin = require('speed-measure-webpack-plugin');
// const smw = new SpeedMeasureWebpackPlugin();
let {
version,
openGizp
} = require('./package.json'); //版本號和是否開啓壓縮
const production = process.env.NODE_ENV != 'development';
let buildReport = process.env.npm_lifecycle_event.includes('build:report'); //是否顯示打包分析介面
// const ExtractTextPlugin = require('extract-text-webpack-plugin');
// var OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
function resolve(dir) {
return path.join(__dirname, dir) //此處使用path.resolve 或path.join 可自行調整
}
module.exports = {
// 基本路徑
publicPath: production ? '' : '/',
// devtool: production ? 'none' : 'source-map',
// 輸出檔案目錄
outputDir: 'dist',
assetsDir: './', //放置生成的靜態資源 (js、css、img、fonts) 的 (相對於 outputDir 的) 目錄。
indexPath: 'index.html', //指定生成的 index.html 的輸出路徑 (相對於 outputDir)。也可以是一個絕對路徑。
// 生產環境是否生成 sourceMap 檔案
productionSourceMap: false,
// pages: {
// index: {
// entry: 'src/main.js', // page 的入口
// template: 'public/index.html', // 模板來源
// filename: 'index.html', // 在 dist/index.html 的輸出
// title: 'Index Page', // 當使用 title 選項時,template 中的 title 標籤需要是 <title><%= htmlWebpackPlugin.options.title %></title>
// chunks: ['chunk-vendors', 'chunk-common', 'index'] // 在這個頁面中包含的塊,預設情況下會包含 // 提取出來的通用 chunk 和 vendor chunk。
// }
// //subpage: 'src/main.js' //不太理解
// // 當使用只有入口的字串格式時,
// // 模板會被推導爲 `public/subpage.html`
// // 並且如果找不到的話,就回退到 `public/index.html`。
// // 輸出檔名會被推導爲 `subpage.html`。
// },
lintOnSave: false,//設定是否在開發環境下每次儲存程式碼時都啓用 eslint驗證
css: {
loaderOptions: {
//設定全域性scss變數或者mixin....
sass: {
//老版本是data,新版本是prependData
prependData: `@import "@/style/global.scss";`,
}
},
extract: false,
sourceMap: false,
requireModuleExtension: true,
},
filenameHashing: true, //檔案hash
parallel: require('os').cpus().length > 1,
devServer: {
// publicPath: path.join(__dirname, "dist"),
contentBase: path.resolve(__dirname, './dist'), // webpack啓動服務會在dist目錄下
compress: true, //gzip 可以提升返回頁面的速度
port: 8080,//伺服器埠號
clientLogLevel: "none",
// lazy: true,
filename: "bundle.js",
open: true,
proxy: {
"/api": {
// target: "http://192.168.0.148:8080",
target: "http://zhcl.4000750222.com/testCoupon/",
pathRewrite: {
"^/api": ""
}
}
}
//在本地伺服器開啓gzip,線上伺服器都支援gzip不需要設定
// before(app) {
// app.get(/.*.(js)$/, (req, res, next) => {
// req.url = req.url + '.gz';
// res.set('Content-Encoding', 'gzip');
// next();
// })
// }
},
configureWebpack: (config) => {
var optimization;
if (production) {
// 將每個依賴包打包成單獨的js檔案
optimization = {
minimizer: [
// new UglifyPlugin({
// parallel: true,
// uglifyOptions: {
// mangle: true,
// output: { //刪除註釋
// comments: false
// },
// warnings: false,
// compress: {
// drop_console: true, // console
// drop_debugger: false,
// pure_funcs: ['console.log'] // 移除console
// }
// }
// })
// new OptimizeCssAssetsPlugin({
// assetNameRegExp: /\.css$/g, //一個正則表達式,指示應優化/最小化的資產的名稱。提供的正則表達式針對設定中ExtractTextPlugin範例導出的檔案的檔名執行,而不是源CSS檔案的檔名。預設爲/\.css$/g
// cssProcessor: require('cssnano'), //用於優化\最小化CSS的CSS處理器,預設爲cssnano
// cssProcessorOptions: {
// safe: true,
// discardComments: {
// removeAll: true
// }
// }, //傳遞給cssProcessor的選項,預設爲{}
// canPrint: true //一個布爾值,指示外掛是否可以將訊息列印到控制檯,預設爲true
// }),
],
runtimeChunk: 'single',
splitChunks: {
// inital 只操作同步的 all 所有的 async 非同步的
chunks: "all", // 預設支援非同步的程式碼分割 import()
minSize: 30000, // 檔案超過30k 我就會抽離他
maxSize: 0,
minChunks: 2, // 最少模組參照2次才抽離
maxAsyncRequests: 5, // 最多5個請求
maxInitialRequests: 3, // 最多首屏載入3個請求
automaticNameDelimiter: "-", // xxx~a~b
automaticNameMaxLength: 30, // 最長名字打大小
name: true,
// maxInitialRequests: 10,
// minSize: 50000, // 依賴包超過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 `${packageName.replace('@', '')}`
// }
// },
vendor: {
chunks: 'all',
test: /node_modules/,
name: 'vendor',
minChunks: 1,
maxInitialRequests: 5,
minSize: 0,
priority: 100
},
common: {
chunks: 'all',
test: /[\\/]src[\\/]js[\\/]/,
name: 'common',
minChunks: 2,
maxInitialRequests: 5,
minSize: 0,
priority: 60
},
styles: {
name: 'styles',
test: /\.(sa|sc|c)ss$/,
chunks: 'all',
enforce: true
},
runtimeChunk: {
name: 'manifest'
}
}
}
};
Object.assign(config, {
// externals: {
// 'vue': 'Vue',
// 'element-ui': 'ElementUI',
// 'vue-router': 'VueRouter',
// 'vuex': 'Vuex'
// },
optimization,
output: {
...config.output,
filename: `js/[name].[chunkhash].${version}.js`,
chunkFilename: `js/[name].[chunkhash].${version}.js`
},
plugins: [
...config.plugins,
// new PurgeCssWebpackPlugin({
// paths: glob.sync('./src/**/*', {
// nodir: true
// }),
// extractors: [{
// extractor: class Extractor {
// static extract(content) {
// const validSection = content.replace(
// /<style([\s\S]*?)<\/style>+/gim,
// ""
// );
// return validSection.match(/[A-Za-z0-9-_:/]+/g) || [];
// }
// },
// extensions: ["html", "vue"]
// }],
// whitelist: ["html", "body"],
// whitelistPatterns: [/el-.*/],
// whitelistPatternsChildren: [/^token/, /^pre/, /^code/]
// }),
new OptimizeCssAssetsPlugin({
assetNameRegExp: /\.css$/g, //一個正則表達式,指示應優化/最小化的資產的名稱。提供的正則表達式針對設定中ExtractTextPlugin範例導出的檔案的檔名執行,而不是源CSS檔案的檔名。預設爲/\.css$/g
cssProcessor: require('cssnano'), //用於優化\最小化CSS的CSS處理器,預設爲cssnano
cssProcessorOptions: {
safe: true,
discardComments: {
removeAll: true
}
}, //傳遞給cssProcessor的選項,預設爲{}
canPrint: true //一個布爾值,指示外掛是否可以將訊息列印到控制檯,預設爲true
})
// new webpack.ProvidePlugin({
// moment: "moment"
// })
]
})
} else {
// 爲開發環境修改設定...
}
},
// transpileDependencies: ['webpack-dev-server/client'],
chainWebpack: config => {
if (production) {
config.optimization.minimize(true);
// config.plugin('cdn').use(
// new HtmlWebpackPlugin({
// title: '測試專案',
// template: resolve('./build_template/index.html'),
// // cdn(自定義屬性)載入的資源,不需要手動新增至index.html中,
// // 順序按陣列索引載入
// cdn: {
// css:['https://cdn.bootcss.com/element-ui/2.12.0/theme-chalk/index.css'],
// js: [
// 'https://cdn.bootcss.com/vue/2.6.10/vue.min.js',
// 'https://cdn.bootcss.com/element-ui/2.12.0/index.js',
// 'https://cdn.bootcss.com/vue-router/3.0.0/vue-router.min.js',
// // 'https://cdn.bootcss.com/vuex/3.1.1/vuex.min.js',
// // "https://cdn.bootcss.com/vue/2.6.10/vue.min.js",
// // "https://cdn.bootcss.com/vue-router/3.0.2/vue-router.min.js",
// // "https://cdn.bootcss.com/element-ui/2.12.0/index.js",
// "https://cdn.bootcss.com/axios/0.19.0-beta.1/axios.min.js",
// "https://cdn.bootcss.com/echarts/4.2.1-rc1/echarts-en.common.min.js",
// "https://cdn.bootcss.com/moment.js/2.24.0/moment.min.js",
// "https://cdn.bootcss.com/mathjs/6.2.1/math.min.js",
// "https://cdn.bootcss.com/xlsx/0.14.3/xlsx.full.min.js"
// ]
// },
// minify: {
// //是否對大小寫敏感,預設false
// caseSensitive: true,
// //是否簡寫boolean格式的屬性如:disabled="disabled" 簡寫爲disabled 預設false
// collapseBooleanAttributes: true,
// //是否去除空格,預設false
// collapseWhitespace: true,
// //是否壓縮html裡的css(使用clean-css進行的壓縮) 預設值false;
// minifyCSS: true,
// //是否壓縮html裡的js(使用uglify-js進行的壓縮)
// minifyJS: true,
// //Prevents the escaping of the values of attributes
// preventAttributesEscaping: true,
// //是否移除屬性的引號 預設false
// removeAttributeQuotes: true,
// //是否移除註釋 預設false
// removeComments: true,
// //從指令碼和樣式刪除的註釋 預設false
// removeCommentsFromCDATA: true,
// //是否刪除空屬性,預設false
// removeEmptyAttributes: true,
// // 若開啓此項,生成的html中沒有 body 和 head,html也未閉合
// removeOptionalTags: false,
// //刪除多餘的屬性
// removeRedundantAttributes: true,
// //刪除script的型別屬性,在h5下面 下麪script的type預設值:text/javascript 預設值false
// removeScriptTypeAttributes: true,
// //刪除style的型別屬性, type="text/css" 同上
// removeStyleLinkTypeAttributes: true,
// //使用短的文件型別,預設false
// useShortDoctype: true,
// }
// })
// )
// config.plugin('css-assets').use(new OptimizeCssAssetsPlugin({
// assetNameRegExp: /\.css$/g, //一個正則表達式,指示應優化/最小化的資產的名稱。提供的正則表達式針對設定中ExtractTextPlugin範例導出的檔案的檔名執行,而不是源CSS檔案的檔名。預設爲/\.css$/g
// cssProcessor: require('cssnano'), //用於優化\最小化CSS的CSS處理器,預設爲cssnano
// cssProcessorOptions: {
// safe: true,
// discardComments: {
// removeAll: true
// }
// }, //傳遞給cssProcessor的選項,預設爲{}
// canPrint: true //一個布爾值,指示外掛是否可以將訊息列印到控制檯,預設爲true
// }))
if (buildReport) {
config.plugin('webpack-report') // 打包分析
.use(BundleAnalyzerPlugin, [{
analyzerMode: 'static',
}]);
}
if (openGizp) {
config.plugin(openGizp).use(new CompressionPlugin({
//test: /\.js$|\.html$|.\css/, //匹配檔名
test: /\.(js|css|json|txt|html|svg|mp3)(\?.*)?$/i, //匹配檔名
filename: '[path].gz[query]',
algorithm: 'gzip',
minRatio: 0.8,
threshold: 10240, //對超過10k的數據壓縮
deleteOriginalAssets: false //是否刪除原始檔
}))
}
// 壓縮圖片
config.module.rule("images")
.use('url-loader')
.loader('url-loader')
.tap(options => Object.assign(options, { limit: 7000}))
// config.module.rule('images')
// .test(/\.(png|jpe?g|gif|svg)(\?.*)?$/)
// .use('image-webpack-loader')
// .loader('image-webpack-loader')
// .options({ bypassOnDebug: true })
// config.module
// .rule("images")
// .use("image-webpack-loader")
// .loader("image-webpack-loader")
// .options({
// mozjpeg: {
// progressive: true,
// quality: 65
// },
// optipng: {
// enabled: false
// },
// pngquant: {
// quality: [0.65, 0.90],
// speed: 4
// },
// gifsicle: {
// interlaced: false
// },
// webp: {
// quality: 75
// }
// });
}
// config
// .entry('index')
// .add('babel-polyfill')
// .end();
// set('jquery$', 'jquery/dist/jquery.min.js');
//設定音訊播放loader
// 修復HMR
config.resolve.symlinks(true);
// 移除 prefetch 外掛
config.plugins.delete('prefetch');
// 移除 preload 外掛
config.plugins.delete('preload');
config.resolve.alias
.set('@', resolve('src'))
.set('@assets', resolve('./src/assets'))
}
}