vue.config.js的基础配置
/**
* webpack概念
Entry: 入口, webpack执行构建的第一步从entry开始。
module:模块,在webpack里一切皆模块,一个模块对应一个文件。webpack会从配置的entry开始递归找出所依赖的模块。
chunk:代码块,一个chunk由多个模块组合而成,用于代码合并和分割。
loader:模块转换器,用于将模块的原内容按照需求转换换成新内容
plugin:扩展插件,在webpack构建流程中的特定时机注入扩展逻辑,来改变构建结果或做我们想做的事情。
output: 输出结果,在webpack进过一系列处理并得出最终想要的代码输出结果
resolve:配置寻找模块的规则
plugins: 配置扩展插件
DevServer:配置devsever
*/
const path = require("path");
const UglifyPlugin = require("uglifyjs-webpack-plugin");
// const CompressionPlugin = require("compression-webpack-plugin"); // 压缩
// const ScriptExtHtmlWebpackPlugin = require("script-ext-html-webpack-plugin"); // 解决入口文件的hash更新,利于缓存
// const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin; // 查看打包详情
// const SkeletonWebpackPlugin = require('vue-skeleton-webpack-plugin') //骨架屏渲染
const webpack = require("webpack");
module.exports = {
publicPath: "./", // 部署应用包时的基本Url,'./'打包出来后可以部署在任意路径,process.env.NODE_ENV === 'production'? ... : '/'
outputDir: "dist", // 运行时生成的生产环境构建文件的目录(默认''dist'',构建之前会被清除)(构建时传入 --no-clean 可关闭该行为)
assetsDir: "static", //放置生成的静态资源(js、css、img、fonts)的(相对于 outputDir 的)目录(默认'')
indexPath: "index.html", //指定生成的 index.html 的输出路径(相对于 outputDir)也可以是一个绝对路径。
filenameHashing: true, // 文件名哈希-控制浏览器缓存问题-浏览器会先去缓存查找当前域名是否已存在这个文件
pages: {
//pages 里配置的路径和文件名在你的文档目录必须存在 否则启动服务会报错
index: {
//除了 entry 之外都是可选的
entry: "src/main.js", // page 的入口,每个“page”应该有一个对应的 JavaScript 入口文件
template: "public/index.html", // 模板来源
filename: "index.html", // 在 dist/index.html 的输出
title: "webpack练习", // 当使用 title 选项时,在 template 中使用:<title><%= htmlWebpackPlugin.options.title %></title>
favicon: path.resolve("./public/favicon.ico"),
chunks: ["chunk-vendors", "chunk-common", "index"], // 在这个页面中包含的块,默认情况下会包含,提取出来的通用 chunk 和 vendor chunk,vendor 是指提取涉及 node_modules 中的公共模块
},
// subpage: 'src/subpage/main.js'//官方解释:当使用只有入口的字符串格式时,模板会被推导为'public/subpage.html',若找不到就回退到'public/index.html',输出文件名会被推导为'subpage.html'
},
lintOnSave: true, // 是否在保存的时候检查-效果与warning一样
runtimeCompiler: true, // 设置为true,就可以在Vue组件中使用template选项,但是会让应用增加10kb左右
productionSourceMap: false, // 生产环境是否生成 sourceMap 文件 --定位。source map定位的时浏览器控制台输出语句在项目文件的位置。
// transpileDependencies: [], //默认情况下 babel-loader 会忽略所有 node_modules 中的文件。如果你想要通过 Babel 显式转译一个依赖,可以在这个选项中列出来。
crossorigin: undefined,
integrity: false, // 在生成的HTML中的<link rel="stylesheet">和<script>标签上启用Subresource Integrity(SRI)。如果你构建后的文件是部署在 CDN 上的,启用该选项可以提供额外的安全性。
// 该选项在系统的 CPU 有多于一个内核时自动启用,仅作用于生产构建。
parallel: require("os").cpus().length > 1,
css: {
extract: false, // 是否使用css分离插件 ExtractTextPlugin,将组件内的css提取到单独的css文件
sourceMap: false, // 开启 CSS source maps-样式定位
requireModuleExtension: true, // 是否仅对文件名包含module的css相关文件使用 CSS Modules
loaderOptions: {
css: {
modules: {
localIdentName: "[local]_[hash:base64:8]", // 设定 CSS Modules 命名规则
},
},
}, // css预设器配置项 详见https://cli.vuejs.org/zh/config/#css-loaderoptions
// modules: false, // 启用 CSS modules for all css / pre-processor files.
},
devServer: {
// 环境配置
host: "localhost", // 默认localhost,如果希望服务器外部可访问,可设置ip地址
hot: true, //hot配置是否启用模块的热替换功能,devServer的默认行为是在发现源代码被变更后,通过自动刷新整个页面来做到事实预览,开启hot后,将在不刷新整个页面的情况下通过新模块替换老模块来做到实时预览。
port: 8080,
https: false,
hotOnly: false, // // hot 和 hotOnly 的区别是在某些模块不支持热更新的情况下,前者会自动刷新页面,后者不会刷新页面,而是在控制台输出热更新失败
open: true, //配置自动启动浏览器
// https: false, // 启用https
overlay: {
warnings: true,
errors: true,
}, // 错误、警告在页面弹出
proxy: {
// 配置多个代理(配置一个 proxy: 'http://localhost:4000' )
"/api": {
target: "<url>", // 目标接口域名
secure: false, // false为http访问,true为https访问
ws: true, // websocket
changeOrigin: true, // 是否跨域
pathRewrite: {
"^/api": "", // 重写接口--相当于字符串的replace
},
},
},
},
pluginOptions: {
// 第三方插件配置
// ...
},
// webpack配置
configureWebpack: (config) => {
// console.log(config)
if (process.env.NODE_ENV === "production") {
// 为生产环境修改配置...
config.mode = "production";
// 将每个依赖包打包成单独的js文件
const optimization = {
// runtimeChunk: true,
// 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("@", "")}`;
// },
// },
// },
// },
// splitChunks: {
// chunks: "all",
// cacheGroups: {
// libs: {
// name: "chunk-libs",
// test: /[\\/]node_modules[\\/]/,
// priority: 10,
// chunks: "initial", // 只打包初始时依赖的第三方
// },
// elementUI: {
// name: "chunk-elementUI", // 单独将 elementUI 拆包
// priority: 20, // 权重要大于 libs 和 app 不然会被打包进 libs 或者 app
// test: /[\\/]node_modules[\\/]element-ui[\\/]/,
// },
// commons: {
// name: "chunk-commons",
// test: resolve("src/components"), // 可自定义拓展你的规则
// minChunks: 2, // 最小共用次数
// priority: 5,
// reuseExistingChunk: true,
// },
// },
// },
// 移除console
minimizer: [
new UglifyPlugin({
uglifyOptions: {
// 在UglifyJs删除没有用到的代码时不输出警告
warnings: false,
compress: {
// 删除所有的 `console` 语句,可以兼容ie浏览器
drop_console: true, // console
drop_debugger: false,
pure_funcs: ["console.log"], // 移除console
// 内嵌定义了但是只用到一次的变量
// collapse_vars: true,
// 提取出出现多次但是没有定义成变量去引用的静态值
// reduce_vars: true,
},
output: {
// 最紧凑的输出
beautify: false,
// 删除所有的注释
comments: false,
},
},
}),
// new OptimizeCSSAssetsPlugin() // 压缩css的注释
],
};
// const plugins = [
// new ScriptExtHtmlWebpackPlugin({
// inline: /runtime~.+\.js$/, //正则匹配runtime文件名
// }),
// new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
// ];
Object.assign(config, {
optimization,
// plugins,
});
} else {
// 为开发环境修改配置...
config.mode = "development";
// config.plugins = [
// // 查看打包详细配置
// new BundleAnalyzerPlugin(),
// ];
}
// config为被解析的配置
Object.assign(config, {
// 开发生产共同配置,新增一些别名设置
resolve: {
extensions: [".js", ".vue", ".json"], //文件优先解析后缀名顺序
alias: {
vue$: "vue/dist/vue.esm.js",
"@": path.resolve(__dirname, "./src"),
"@c": path.resolve(__dirname, "./src/components"),
"@p": path.resolve(__dirname, "./src/pages"),
"@v": path.resolve(__dirname, "./src/views"),
}, // 别名配置
},
});
},
chainWebpack: (config) => {
// console.log(config);
// 链式操作
// 开启图片压缩
config.module
.rule("images")
.test(/\.(png|jpe?g|gif|svg)(\?.*)?$/)
.use("url-loader")
.loader("url-loader")
.options({
limit: 10240, // 图片小于10k转为base64,默认4k
})
.end() // 回到上层-loader
.test(/\.(png|jpe?g|gif|svg)(\?.*)?$/)
.use("image-webpack-loader")
.loader("image-webpack-loader")
.options({
bypassOnDebug: true,
})
.end();
// 配置Jquery--在main.js中import $ from 'jquery'
config.plugin("provide").use(webpack.ProvidePlugin, [
{
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery",
Popper: ["popper.js", "default"],
},
]);
// config.plugin("preload").tap((args) => {
// args[0].fileBlacklist.push(/runtime~.+\.js$/); //正则匹配runtime文件名,去除该文件的preload
// return args;
// });
// 开启js、css压缩,需nginx配置
// if (process.env.NODE_ENV === "production") {
// config.plugin("compressionPlugin").use(
// new CompressionPlugin({
// test: /\.js$|\.html$|.\css/, // 匹配文件名
// threshold: 10240, // 对超过10k的数据压缩
// deleteOriginalAssets: false, // 是否删除源文件
// })
// );
// }
},
};
需要什么自己提取,此文章仅做个记录。另外package.json配置
{
"name": "webpack",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"webBuild": "webpack --config build/webpack.config.js",
"start": "webpack-dev-server",
"stylelint": "stylelint src/**/*.{html,vue,css,sass,scss} --fix",
"inspect": "vue-cli-service inspect --mode development",
"consoleInspect": "vue-cli-service inspect --mode development >> webpack.config.development.js"
},
"dependencies": {
"@babel/polyfill": "^7.12.1",
"core-js": "^3.6.5",
"vue": "^2.6.11",
"vue-router": "^3.2.0",
"vuex": "^3.4.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0",
"@vue/cli-plugin-vuex": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"autoprefixer": "^10.2.6",
"babel-eslint": "^10.1.0",
"clean-webpack-plugin": "^4.0.0-alpha.0",
"compression-webpack-plugin": "^6.1.1",
"css-loader": "^3.6.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.2.2",
"image-webpack-loader": "^7.0.1",
"jquery": "^3.6.0",
"lint-staged": "^9.5.0",
"mini-css-extract-plugin": "^1.6.0",
"node-sass": "^4.14.1",
"sass": "^1.26.5",
"sass-loader": "^8.0.2",
"style-loader": "^2.0.0",
"uglifyjs-webpack-plugin": "^2.2.0",
"vue-loader": "^15.9.7",
"vue-style-loader": "^4.1.3",
"vue-template-compiler": "^2.6.14",
"webpack": "^4.46.0",
"webpack-bundle-analyzer": "^4.4.2",
"webpack-cli": "^4.7.2"
},
"gitHooks": {
"pre-commit": "lint-staged"
},
"lint-staged": {
"*.{js,jsx,vue}": [
"vue-cli-service lint",
"git add"
]
}
}