提交 0c213cb7 编写于 作者: yma16's avatar yma16

perf:gzip打包优化-build分支

上级 080e6cca
'use strict' "use strict";
const path = require('path') const path = require("path");
const utils = require('./utils') const utils = require("./utils");
const webpack = require('webpack') const webpack = require("webpack");
const config = require('../config') const config = require("../config");
const merge = require('webpack-merge') const merge = require("webpack-merge");
const baseWebpackConfig = require('./webpack.base.conf') const baseWebpackConfig = require("./webpack.base.conf");
const CopyWebpackPlugin = require('copy-webpack-plugin') const CopyWebpackPlugin = require("copy-webpack-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin') const HtmlWebpackPlugin = require("html-webpack-plugin");
const ExtractTextPlugin = require('extract-text-webpack-plugin') const ExtractTextPlugin = require("extract-text-webpack-plugin");
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') const OptimizeCSSPlugin = require("optimize-css-assets-webpack-plugin");
const UglifyJsPlugin = require('uglifyjs-webpack-plugin') const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const env = process.env.NODE_ENV === 'testing' const env =
? require('../config/test.env') process.env.NODE_ENV === "testing"
: require('../config/prod.env') ? require("../config/test.env")
: require("../config/prod.env");
// cdn 引入
let externalModules = {};
//cdn 配置
let externalConfig = [];
if (process.env.NODE_ENV === "production") {
//生产环境
externalModules = {
vue: "Vue",
"vue-router": "VueRouter",
vuex: "Vuex",
axios: "axios",
"element-ui": "element-ui",
echarts: "echarts",
'vuex-persistedstate':'persistedstate',
'highlight':'hljs'
};
externalConfig = [
{ js: "https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js", css: "" },
{
js: "https://cdn.bootcdn.net/ajax/libs/vue-router/3.0.1/vue-router.min.js",
css: "",
},
{ js: "https://unpkg.com/axios/dist/axios.min.js", css: "" },
{ js: "https://cdn.bootcss.com/vuex/3.6.2/vuex.min.js", css: "" },
{
js: "https://unpkg.com/element-ui/lib/index.js",
css: "https://unpkg.com/element-ui/lib/theme-chalk/index.css",
},
{
js: "https://cdn.jsdelivr.net/npm/echarts@5.3.3/dist/echarts.min.js",
css: "",
},
{
js: "https://cdn.bootcdn.net/ajax/libs/highlight.js/11.6.0/highlight.min.js",
css: "",
},
{
js: "",
css: "https://cdn.bootcdn.net/ajax/libs/github-markdown-css/5.1.0/github-markdown-dark.css",
},
{js:'https://cdn.bootcdn.net/ajax/libs/vuex-persistedstate/4.1.0/vuex-persistedstate.es.min.js',css:''}
];
}
const webpackConfig = merge(baseWebpackConfig, { const webpackConfig = merge(baseWebpackConfig, {
externals: externalModules, //打包忽略
module: { module: {
rules: utils.styleLoaders({ rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap, sourceMap: config.build.productionSourceMap,
extract: true, extract: true,
usePostCSS: true usePostCSS: true,
}) }),
}, },
devtool: config.build.productionSourceMap ? config.build.devtool : false, devtool: config.build.productionSourceMap ? config.build.devtool : false,
output: { output: {
path: config.build.assetsRoot, path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash].js'), filename: utils.assetsPath("js/[name].[chunkhash].js"),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') chunkFilename: utils.assetsPath("js/[id].[chunkhash].js"),
}, },
plugins: [ plugins: [
// http://vuejs.github.io/vue-loader/en/workflow/production.html // http://vuejs.github.io/vue-loader/en/workflow/production.html
new webpack.DefinePlugin({ new webpack.DefinePlugin({
'process.env': env "process.env": env,
}), }),
new UglifyJsPlugin({ new UglifyJsPlugin({
uglifyOptions: { uglifyOptions: {
compress: { compress: {
warnings: false warnings: false,
} },
}, },
sourceMap: config.build.productionSourceMap, sourceMap: config.build.productionSourceMap,
parallel: true parallel: true,
}), }),
// extract css into its own file // extract css into its own file
new ExtractTextPlugin({ new ExtractTextPlugin({
filename: utils.assetsPath('css/[name].[contenthash].css'), filename: utils.assetsPath("css/[name].[contenthash].css"),
// Setting the following option to `false` will not extract CSS from codesplit chunks. // Setting the following option to `false` will not extract CSS from codesplit chunks.
// Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
// It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
...@@ -57,26 +103,27 @@ const webpackConfig = merge(baseWebpackConfig, { ...@@ -57,26 +103,27 @@ const webpackConfig = merge(baseWebpackConfig, {
new OptimizeCSSPlugin({ new OptimizeCSSPlugin({
cssProcessorOptions: config.build.productionSourceMap cssProcessorOptions: config.build.productionSourceMap
? { safe: true, map: { inline: false } } ? { safe: true, map: { inline: false } }
: { safe: true } : { safe: true },
}), }),
// generate dist index.html with correct asset hash for caching. // generate dist index.html with correct asset hash for caching.
// you can customize output by editing /index.html // you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin // see https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({ new HtmlWebpackPlugin({
filename: process.env.NODE_ENV === 'testing' filename:
? 'index.html' process.env.NODE_ENV === "testing" ? "index.html" : config.build.index,
: config.build.index, template: "index.html",
template: 'index.html',
inject: true, inject: true,
minify: { minify: {
removeComments: true, removeComments: true,
collapseWhitespace: true, collapseWhitespace: true,
removeAttributeQuotes: true removeAttributeQuotes: true,
// more options: // more options:
// https://github.com/kangax/html-minifier#options-quick-reference // https://github.com/kangax/html-minifier#options-quick-reference
}, },
// necessary to consistently work with multiple chunks via CommonsChunkPlugin // necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'dependency' chunksSortMode: "dependency",
cdnConfig: externalConfig, // cdn配置
onlyCss: true, //dev下只加载css
}), }),
// keep module.id stable when vendor modules does not change // keep module.id stable when vendor modules does not change
new webpack.HashedModuleIdsPlugin(), new webpack.HashedModuleIdsPlugin(),
...@@ -84,66 +131,81 @@ const webpackConfig = merge(baseWebpackConfig, { ...@@ -84,66 +131,81 @@ const webpackConfig = merge(baseWebpackConfig, {
new webpack.optimize.ModuleConcatenationPlugin(), new webpack.optimize.ModuleConcatenationPlugin(),
// split vendor js into its own file // split vendor js into its own file
new webpack.optimize.CommonsChunkPlugin({ new webpack.optimize.CommonsChunkPlugin({
name: 'vendor', name: "vendor",
minChunks (module) { minChunks(module) {
// any required modules inside node_modules are extracted to vendor // any required modules inside node_modules are extracted to vendor
return ( return (
module.resource && module.resource &&
/\.js$/.test(module.resource) && /\.js$/.test(module.resource) &&
module.resource.indexOf( module.resource.indexOf(path.join(__dirname, "../node_modules")) === 0
path.join(__dirname, '../node_modules') );
) === 0 },
)
}
}), }),
// extract webpack runtime and module manifest to its own file in order to // extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated // prevent vendor hash from being updated whenever app bundle is updated
new webpack.optimize.CommonsChunkPlugin({ new webpack.optimize.CommonsChunkPlugin({
name: 'manifest', name: "manifest",
minChunks: Infinity minChunks: Infinity,
}), }),
// This instance extracts shared chunks from code splitted chunks and bundles them // This instance extracts shared chunks from code splitted chunks and bundles them
// in a separate chunk, similar to the vendor chunk // in a separate chunk, similar to the vendor chunk
// see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
new webpack.optimize.CommonsChunkPlugin({ new webpack.optimize.CommonsChunkPlugin({
name: 'app', name: "app",
async: 'vendor-async', async: "vendor-async",
children: true, children: true,
minChunks: 3 minChunks: 3,
}), }),
// copy custom myblog_static assets // copy custom myblog_static assets
new CopyWebpackPlugin([ new CopyWebpackPlugin([
{ {
from: path.resolve(__dirname, '../myblog_static'), from: path.resolve(__dirname, "../myblog_static"),
to: config.build.assetsSubDirectory, to: config.build.assetsSubDirectory,
ignore: ['.*'] ignore: [".*"],
} },
]) ]),
] ],
}) });
if (config.build.productionGzip) { if (config.build.productionGzip) {
const CompressionWebpackPlugin = require('compression-webpack-plugin') const CompressionWebpackPlugin = require("compression-webpack-plugin");
webpackConfig.plugins.push( webpackConfig.plugins.push(
new CompressionWebpackPlugin({ new CompressionWebpackPlugin({
filename: '[path].gz[query]', filename: "[path].gz[query]",
algorithm: 'gzip', algorithm: "gzip",
test: new RegExp( test: new RegExp(
'\\.(' + "\\.(" + config.build.productionGzipExtensions.join("|") + ")$"
config.build.productionGzipExtensions.join('|') +
')$'
), ),
threshold: 10240, threshold: 10240,
minRatio: 0.8 minRatio: 0.8,
}) })
) );
} }
if (config.build.bundleAnalyzerReport) { if (config.build.bundleAnalyzerReport) {
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin const BundleAnalyzerPlugin =
webpackConfig.plugins.push(new BundleAnalyzerPlugin()) require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
webpackConfig.plugins.push(new BundleAnalyzerPlugin());
}
if (config.build.isIgnoreLogs) {
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
let optimization = [
new UglifyJsPlugin({
uglifyOptions: {
compress: {
warnings: false,
drop_debugger: true, //去掉debugger
drop_console: true, // 去掉console
pure_funcs: ["console.log"], // 移除console
},
},
sourceMap: config.build.productionSourceMap,
parallel: true,
}),
];
webpackConfig.plugins.push(...optimization);
} }
module.exports = webpackConfig module.exports = webpackConfig;
...@@ -81,6 +81,7 @@ module.exports = { ...@@ -81,6 +81,7 @@ module.exports = {
productionGzip: true, productionGzip: true,
productionGzipExtensions: ["js", "css"], productionGzipExtensions: ["js", "css"],
isIgnoreLogs:true,
// Run the build command with an extra argument to // Run the build command with an extra argument to
// View the bundle analyzer report after build finishes: // View the bundle analyzer report after build finishes:
// `npm run build --report` // `npm run build --report`
......
...@@ -6,23 +6,25 @@ ...@@ -6,23 +6,25 @@
<title>yma16前端日记</title> <title>yma16前端日记</title>
<link <link
rel="shortcut icon" rel="shortcut icon"
href="myblog_static/utils/fx_background/image/logo.ico" href="./myblog_static/utils/fx_background/image/logo.ico"
/> />
<!-- up --> <!-- up -->
<link <link
rel="stylesheet" rel="stylesheet"
href="myblog_static/utils/fx_background/css/core.css" href="./myblog_static/utils/fx_background/css/core.css"
/> />
<style> <style>
body { body {
background: url(myblog_static/utils/fx_background/image/background.png);
background-size: cover;
background-repeat: no-repeat;
overflow: hidden; overflow: hidden;
} }
</style> </style>
<!-- cdn -->
<% htmlWebpackPlugin.options.cdnConfig.forEach(function(item){ if(item.css){ %>
<link href="<%= item.css %>" rel="stylesheet" />
<% }}) %>
<!-- -->
</head> </head>
<!-- 阿里 --> <!-- 阿里 -->
<style type="text/css"> <style type="text/css">
...@@ -34,7 +36,10 @@ ...@@ -34,7 +36,10 @@
overflow: hidden; overflow: hidden;
} }
</style> </style>
<!-- cdn -->
<% htmlWebpackPlugin.options.cdnConfig.forEach(function(item){ if(item.js && !htmlWebpackPlugin.options.onlyCss){ %>
<script type="text/javascript" src="<%= item.js %>"></script>
<% }}) %>
<body> <body>
<div id="app"></div> <div id="app"></div>
<div id="canvas"> <div id="canvas">
...@@ -43,8 +48,9 @@ ...@@ -43,8 +48,9 @@
<div id="beautiful"></div> <div id="beautiful"></div>
</div> </div>
</body> </body>
<!-- built files will be auto injected -->
<!-- <script src="myblog_static/utils/fx_background/js/jquery-2.1.4.min.js"></script>-->
<!-- 资源-->
<script src="https://eqcn.ajz.miesnfu.com/wp-content/plugins/wp-3d-pony/live2dw/lib/L2Dwidget.min.js"></script> <script src="https://eqcn.ajz.miesnfu.com/wp-content/plugins/wp-3d-pony/live2dw/lib/L2Dwidget.min.js"></script>
<!-- 我的阿里图标库 --> <!-- 我的阿里图标库 -->
<script src="https://yongma16.xyz/static/aliyunIcon/icon.js"></script> <script src="https://yongma16.xyz/static/aliyunIcon/icon.js"></script>
......
// The Vue build version to load with the `import` command // The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias. // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue' // import Vue from 'vue'
import VueRouter from 'vue-router' // import VueRouter from 'vue-router'
import axios from 'axios' // import axios from 'axios'
import cookies from 'vue-cookies' // import cookies from 'vue-cookies'
import hljs from 'highlight.js' // import hljs from 'highlight.js'
import useRouter from './router' import useRouter from './router'
import App from './App' import App from './App'
import importElementComponents from './importElement' import importElementComponents from './importElement'
import importEchartsComponents from './importEchartsComponents' import importEchartsComponents from './importEchartsComponents'
// 样式 // 样式
import 'github-markdown-css/github-markdown.css' // import 'github-markdown-css/github-markdown.css'
import 'highlight.js/styles/github.css' import 'highlight.js/styles/github.css'
import 'nprogress/nprogress.css' import 'nprogress/nprogress.css'
// 路由 const env = process.env.NODE_ENV
const router = useRouter(Vue, VueRouter) // 生产环境
if (env === 'production') {
// 按需引入elementui try {
importElementComponents(Vue) // 路由
const router = useRouter(Vue, VueRouter)
// 按需引入echarts // 按需引入elementui
importEchartsComponents(Vue) importElementComponents(Vue)
Vue.config.productionTip = false // 按需引入echarts
Vue.use(cookies) importEchartsComponents(Vue)
Vue.use(hljs) Vue.config.productionTip = false
Vue.directive('highlight', function (el) { Vue.use(cookies)
Vue.use(hljs)
Vue.directive('highlight', function (el) {
const blocks = el.querySelectorAll('pre code') const blocks = el.querySelectorAll('pre code')
blocks.forEach(block => { blocks.forEach((block) => {
hljs.highlightBlock(block) hljs.highlightBlock(block)
}) })
}) })
// cookie // cookie
Vue.prototype.$cookies = cookies Vue.prototype.$cookies = cookies
// axios // axios
Vue.use(axios)
Vue.prototype.$axios = axios
window.$axios_w = axios
Vue.prototype.$cookies.set('user_session', 'null')
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
} catch (e) {
throw Error(e)
}
} else {
// 路由
const router = useRouter(Vue, VueRouter)
Vue.use(axios) // 按需引入elementui
Vue.prototype.$axios = axios importElementComponents(Vue)
window.$axios_w = axios
Vue.prototype.$cookies.set('user_session', 'null') // 按需引入echarts
importEchartsComponents(Vue)
new Vue({ Vue.config.productionTip = false
Vue.use(cookies)
Vue.use(hljs)
Vue.directive('highlight', function (el) {
const blocks = el.querySelectorAll('pre code')
blocks.forEach((block) => {
hljs.highlightBlock(block)
})
})
// cookie
Vue.prototype.$cookies = cookies
// axios
Vue.use(axios)
Vue.prototype.$axios = axios
window.$axios_w = axios
Vue.prototype.$cookies.set('user_session', 'null')
new Vue({
el: '#app', el: '#app',
router, router,
components: { App }, components: { App },
template: '<App/>' template: '<App/>'
}) })
}
import Vue from 'vue' // import Vue from 'vue'
import Vuex from 'vuex' // import Vuex from 'vuex'
import persistedstate from 'vuex-persistedstate' import persistedstate from 'vuex-persistedstate'
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册