const path = require('path');
const webpack = require('webpack');
// 删除已经更改标签
const CleanWebpackPlugin = require('clean-webpack-plugin');
// 分离CSS
// const ExtractTextPlugin = require("extract-text-webpack-plugin");// webpack3
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // webpack4
// 在 HTML 中新增标签
const HtmlWebpackPlugin = require("html-webpack-plugin");
// 使用optimize-css-assets-webpack-plugin压缩单独的css文件
const optimizeCss = require('optimize-css-assets-webpack-plugin');
//使用uglify-js进行js文件的压缩
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
// 自动补全CSS前缀
const autoprefixer = require('autoprefixer');
// vue 插件
const VueLoaderPlugin = require('vue-loader/lib/plugin')
// 这是 packet.json 中 dependencies 下的
const VENOR = [
"lodash",
]
module.exports = {
// bundle 和 vendor 都是自己随便取名的,会映射到 [name] 中
entry: {
bundle: "./src/index.js",
vendor: VENOR
}, // 入口文件
output: {
path: path.resolve(__dirname, '../dist'), // 必须使用绝对地址,输出文件夹
// 既然我们希望缓存生效,就应该每次在更改代码以后修改文件名
// [chunkhash]会自动根据文件是否更改而更换哈希
filename: '[name].[hash].js', // 打包后输出文件的文件名
publicPath: process.env.NODE_ENV === 'production' ? "./" : "/" // 知道如何寻找资源
},
module: {
rules: [{
// js文件使用babel
test: /\.js$/,
use: "babel-loader",
exclude: /node_modules/,
},
{
test: /\.html$/,
loader: 'html-loader'
},
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.(png|jpg|jpeg|gif)$/,
use: [{
loader: "url-loader",
options: {
name: "[name]-[hash:5].min.[ext]",
limit: 1000, // size <= 1KB
publicPath: "static/",
outputPath: "static/"
}
}, ]
},
// 处理字体文件
{
test: /\.(otf|eot|svg|ttf|woff|woff2)$/,
use: [{
loader: 'url-loader',
options: {
name: '[name].[ext]', // 打包后的文件名称
outputPath: '', // 默认是dist目录
publicPath: 'dist/fonts', // 图片的url前面追加'dist/images'
useRelativePath: true, // 使用相对路径
limit: 50000 // 表示小于1K的图片会被转化成base64格式
}
}]
},
// webpack 3
// {
// test: /\.css$/,
// loader: ExtractTextPlugin.extract({
// // 必须这样写,否则会报错
// fallback: 'style-loader',
// use: [{
// loader: 'css-loader',
// options: {
// modules: true
// }
// }]
// })
// },
// webpack4
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader, // replace ExtractTextPlugin.extract({..})
"css-loader",
"postcss-loader"
]
},
// {
// test: /\.less$/,
// loader: ExtractTextPlugin.extract({
// // 必须这样写,否则会报错
// fallback: 'style-loader',
// use: [
// "css-loader",
// "less-loader"
// ]
// })
// }, // webpack3
{
test: /\.less$/,
exclude: '/node_modules',
use: [{
loader: 'style-loader'
},
{
loader: MiniCssExtractPlugin.loader
},
{
loader: 'css-loader',
options: {
importLoaders: 1
}
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: (loader) => [
require('postcss-import')({ root: loader.resourcePath }),
require('postcss-cssnext')(),
require('cssnano')()
]
}
},
{
loader: 'less-loader', //
options: {
importLoaders: 1
}
}
]
},
]
},
resolve: { //解析模块的可选项
modules: [
"node_modules",
path.resolve(__dirname, 'src')
],
extensions: [".wasm", ".mjs", ".js", ".json", ".jsx"],
alias: { //模块别名列表
utils: path.resolve(__dirname, 'src/uils')
}
},
// webpack4 用来代替webpack.optimize.CommonsChunkPlugin
optimization: {
runtimeChunk: {
name: 'manifest'
},
minimizer: [
// UglifyJsPlugin
// cache 启用文件缓存。默认的缓存路径为: node_modules/.cache/uglifyjs-webpack-plugin.
// cacheKeys 允许重写默认的cache keys.
// parallel 使用多进程并行运行来提高构建速度。默认并发运行次数:os.cpus().length- 1。
// sourceMap 使用sourceMap将错误消息位置映射到模块(这会减慢编译速度)。如果您使用自己的minify函数,请阅读minify部分以正确处理sourceMap。
// minify 允许覆盖默认的minify函数。默认插件使用uglify-js包。
// uglifyOptions
// extractComments 启用/禁用提取注释
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: true,
exclude: /node_modules/,
uglifyOptions: {
warnings: false,
parse: {},
compress: {},
mangle: true, // Note `mangle.properties` is `false` by default.
output: null,
toplevel: false,
nameCache: null,
ie8: false,
keep_fnames: false,
},
extractComments: true,
}),
//压缩CSS
new optimizeCss({
cssProcessor: require('cssnano'), //引入cssnano配置压缩选项
cssProcessorOptions: {
discardComments: { removeAll: true }
},
canPrint: true //是否将插件信息打印到控制台
}) // 普通压缩
],
splitChunks: {
chunks: "initial", // 必须三选一: "initial" | "all"(默认就是all) | "async"
minSize: 0, // 最小尺寸,默认0
minChunks: 1, // 最小 chunk ,默认1
maxAsyncRequests: 1, // 最大异步请求数, 默认1
maxInitialRequests: 1, // 最大初始化请求书,默认1
name: () => {}, // 名称,此选项课接收 function
cacheGroups: { // 这里开始设置缓存的 chunks
priority: "0", // 缓存组优先级 false | object |
vendor: { // key 为entry中定义的 入口名称
chunks: "initial", // 必须三选一: "initial" | "all" | "async"(默认就是异步)
test: /react|lodash/, // 正则规则验证,如果符合就提取 chunk
name: "vendor", // 要缓存的 分隔出来的 chunk 名称
minSize: 0,
minChunks: 1,
enforce: true,
maxAsyncRequests: 1, // 最大异步请求数, 默认1
maxInitialRequests: 1, // 最大初始化请求书,默认1
reuseExistingChunk: true // 可设置是否重用该chunk(查看源码没有发现默认值)
},
css: {
name: 'css',
test: /\.css$/,
chunks: 'all',
enforce: true
},
less: {
name: 'less',
test: /\.less$/,
chunks: 'all',
enforce: true
}
}
}
},
// 插件列表
plugins: [
new VueLoaderPlugin(),
// 输出的文件路径
// new ExtractTextPlugin("css/[name].[hash].css"), // webpack 3
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: "[name].css",
chunkFilename: "style/[name].[id].[hash].css"
}), // webpack 4
// new webpack.optimize.CommonsChunkPlugin({
// // vendor 的意义和之前相同
// // manifest文件是将每次打包都会更改的东西单独提取出来,保证没有更改的代码无需重新打包,这样可以加快打包速度
// names: ['vendor', 'manifest'],
// // 配合 manifest 文件使用
// minChunks: Infinity
// }), // webpack4弃用
// 只删除 dist 文件夹下的 bundle 和 manifest 文件
new CleanWebpackPlugin(['dist/bundle.*.js', 'dist/less.*.js', 'dist/css.*.js', 'dist/vendor.*.js', 'dist/styles.*.js', 'dist/style/css.*.css', 'dist/style/less.*.css', "dist/manifest.*.js"], {
// 打印 log
verbose: true,
// 删除文件
dry: false
}),
// 注意在之前 HTML 文件中请务必删除之前引入的 JS 文件
/**title : 用于生成的HTML文件的标题。
filename : 用于生成的HTML文件的名称,默认是index.html。你可以在这里指定子目录(例如:assets/admin.html)
template : 模板的路径。支持加载器,例如 html!./index.html。
inject :true | ‘head’ | ‘body’ | false 。把所有产出文件注入到给定的 template或templateContent。当传入 true或者 ‘body’时所有javascript资源将被放置在body元素的底部,“head”则会放在head元素内。
favicon : 给定的图标路径,可将其添加到输出html中。
minify : {…} | false 。传一个html-minifier 配置object来压缩输出。
hash : true | false。如果是true,会给所有包含的script和css添加一个唯一的webpack编译hash值。这对于缓存清除非常有用。
cache : true | false 。如果传入true(默认),只有在文件变化时才 发送(emit)文件。
showErrors : true | false 。如果传入true(默认),错误信息将写入html页面。
chunks : 只允许你添加chunks 。(例如:只有单元测试块 )
chunksSortMode : 在chunk被插入到html之前,你可以控制它们的排序。允许的值 ‘none’ | ‘auto’ | ‘dependency’ | {function} 默认为‘auto’.
excludeChunks : 允许你跳过一些chunks(例如,不要单元测试的 chunk).
xhtml : 用于生成的HTML文件的标题。
title : true | false。如果是true,把link标签渲染为自闭合标签,XHTML要这么干的。默认false。
*/
new HtmlWebpackPlugin({
filename: path.resolve(__dirname, "../dist/index.html"),
template: './index.html',
inject: 'body',
minify: {
removeComments: true, //移除注释
collapseWhitespace: true, // 压缩空白节点
collapseInlineTagWhitespace: true, //压缩行级元素的空白,会保留 和实体空格
}
}),
new webpack.ProvidePlugin({
_: 'lodash',
}),
new webpack.HotModuleReplacementPlugin()
],
devServer: {
host: 'localhost', //服务器的ip地址
port: 8080, //端口
open: true, //自动打开页面
hot: true, //开启热更新
inline: true
}
}
对应的package.json
{
"name": "a-vue",
"version": "1.0.0",
"description": "",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --profile --progress --colors --mode production --config config/webpack.base.js",
"dev": "webpack-dev-server --mode development --config config/webpack.base.js"
},
"author": "wy",
"license": "ISC",
"dependencies": {
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-stage-2": "^6.24.1",
"happypack": "^5.0.0",
"lodash": "^4.17.2",
"vue": "^2.5.21"
},
"devDependencies": {
"autoprefixer": "^9.4.3",
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-env": "^1.6.0",
"babel-preset-react": "^6.16.0",
"clean-webpack-plugin": "^1.0.0",
"css-loader": "^0.28.11",
"cssnano": "^4.1.8",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"file-loader": "^1.1.11",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^4.0.0-beta.3",
"imagemin": "^5.3.1",
"imagemin-pngquant": "^5.1.0",
"img-loader": "^2.0.0",
"less": "^3.9.0",
"less-loader": "^4.1.0",
"mini-css-extract-plugin": "^0.5.0",
"optimize-css-assets-webpack-plugin": "^5.0.1",
"postcss-cssnext": "^3.1.0",
"postcss-import": "^12.0.1",
"postcss-loader": "^2.1.6",
"postcss-sprites": "^4.2.1",
"style-loader": "^0.18.2",
"uglifyjs-webpack-plugin": "^2.1.0",
"url-loader": "^1.0.1",
"vue-loader": "^15.4.2",
"vue-style-loader": "^4.1.2",
"vue-template-compiler": "^2.5.21",
"webpack": "^4.16.0",
"webpack-cli": "^3.0.8",
"webpack-dev-server": "^3.1.14"
}
}