webpack.config.common.js
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
/*
entry: 指定需要打包的文件
* */
entry: './src/js/index.js',
/*
output: 指定打包之后的文件输出的路径和输出的文件名称
* */
output: {
/*
filename: 指定打包之后的JS文件的名称
* */
filename: 'js/bundle.js',
/*
path: 指定打包之后的文件存储到什么地方
* */
path: path.resolve(__dirname, 'bundle')
},
/*
module: 告诉webpack如何处理webpack不能够识别的文件
* */
module: {
rules: [
// 检查编码规范的规则
{
// enforce: "pre"作用: 让当前的loader再其它loader之前执行
enforce: "pre",
test: /\.js$/,
exclude: /node_modules/,
include: path.resolve(__dirname, "src"),
loader: 'eslint-loader',
options: {
// eslint options (if necessary)
fix: true
},
},
// 打包JS规则
{
test: /\.js$/,
exclude: /node_modules/, // 告诉webpack不处理哪一个文件夹
loader: 'babel-loader',
options: {
presets: [['@babel/preset-env', {
targets: {
// "chrome": "58",
}
// useBuiltIns: "usage"
}]],
plugins: [
['@babel/plugin-proposal-class-properties', { loose: true }],
[
'@babel/plugin-transform-runtime',
{
absoluteRuntime: false,
corejs: 2,
helpers: true,
regenerator: true,
useESModules: false
}
]
]
}
},
// 打包字体图标规则
{
test: /\.(eot|json|svg|ttf|woff|woff2)$/,
use: [
{
loader: 'file-loader',
options: {
// 指定打包后文件名称
name: '[name].[ext]',
// 指定打包后文件存放目录
outputPath: 'font/'
}
}
]
},
// 打包图片规则
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
// 指定图片限制的大小
limit: 1024,
// 指定打包后文件名称
name: '[name].[ext]',
// 指定打包后文件存放目录
outputPath: 'images/',
publicPath: 'http://127.0.0.1:9090/images'
}
},
{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true,
quality: 65
},
// optipng.enabled: false will disable optipng
optipng: {
enabled: false
},
pngquant: {
quality: [0.65, 0.90],
speed: 4
},
gifsicle: {
interlaced: false
},
// the webp option will enable WEBP
webp: {
quality: 75
}
}
}
]
},
{
test: /\.(htm|html)$/i,
loader: 'html-withimg-loader'
},
// 打包CSS规则
{
test: /\.css$/,
use: [
{
// loader: "style-loader"
loader: MiniCssExtractPlugin.loader,
options: {
hmr: true
}
},
{
loader: 'css-loader',
options: {
// modules: true // 开启CSS模块化
}
},
{
loader: 'postcss-loader'
}
]
},
// 打包LESS规则
{
test: /\.less$/,
use: [{
loader: 'style-loader'
}, {
loader: 'css-loader'
}, {
loader: 'less-loader'
}, {
loader: 'postcss-loader'
}]
},
// 打包SCSS规则
{
test: /\.scss$/,
use: [{
loader: 'style-loader'
}, {
loader: 'css-loader'
}, {
loader: 'sass-loader'
}, {
loader: 'postcss-loader'
}]
}
]
},
/*
plugins: 告诉webpack需要新增一些什么样的功能
* */
plugins: [
new CleanWebpackPlugin(),
new CopyWebpackPlugin([{
from: './doc',
to: 'doc'
}]),
new MiniCssExtractPlugin({
filename: 'css/[name].css'
}),
]
};
webpack.config.dev.js
const Webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const Merge = require("webpack-merge");
const CommonConfig = require("./webpack.config.common.js");
const DevConfig = {
/*
devServer: 自动检测文件变化配置
* */
devServer: {
contentBase: './bundle',
open: true,
port: 9090,
proxy: [{
context: ['/user', '/login'],
target: 'http://127.0.0.1:3000',
changeOrigin: true, // 域名跨域
secure: false, // https跨域
pathRewrite: { '': '/api' } // 路径重写, 将路径中的api替换为空
}],
hot: true, // 开启热更新, 只要开启了热更新就不会自动刷新网页了
hotOnly: true // 哪怕不支持热更新也不要刷新网页
},
/*
配置sourcemap
development: cheap-module-eval-source-map
production: cheap-module-source-map
* */
devtool: 'cheap-module-eval-source-map',
/*
mode: 指定打包的模式, 模式有两种
一种是开发模式(development): 不会对打包的JS代码进行压缩
还有一种就是上线(生产)模式(production): 会对打包的JS代码进行压缩
* */
mode: 'development', // "production" | "development"
/*
plugins: 告诉webpack需要新增一些什么样的功能
* */
plugins: [
new HtmlWebpackPlugin({
// 指定打包的模板, 如果不指定会自动生成一个空的
template: './src/index.html',
}),
new Webpack.HotModuleReplacementPlugin()
]
};
module.exports = Merge(CommonConfig, DevConfig);
webpack.config.prod.js
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const TerserJSPlugin = require('terser-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const Merge = require("webpack-merge");
const CommonConfig = require("./webpack.config.common.js");
const ProdConfig = {
/*
optimization: 配置webpack的优化项
* */
optimization: {
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})]
},
/*
配置sourcemap
development: cheap-module-eval-source-map
production: cheap-module-source-map
* */
devtool: 'cheap-module-source-map',
/*
mode: 指定打包的模式, 模式有两种
一种是开发模式(development): 不会对打包的JS代码进行压缩
还有一种就是上线(生产)模式(production): 会对打包的JS代码进行压缩
* */
mode: 'production', // "production" | "development"
/*
plugins: 告诉webpack需要新增一些什么样的功能
* */
plugins: [
new HtmlWebpackPlugin({
// 指定打包的模板, 如果不指定会自动生成一个空的
template: './src/index.html',
minify: {
// 告诉htmlplugin打包之后的html文件需要压缩
collapseWhitespace: true,
}
}),
]
};
module.exports = Merge(CommonConfig, ProdConfig);
postcss.config.js
module.exports = {
plugins: {
autoprefixer: {
overrideBrowserslist: [
'ie >= 8', // 兼容IE7以上浏览器
'Firefox >= 3.5', // 兼容火狐版本号大于3.5浏览器
'chrome >= 35', // 兼容谷歌版本号大于35浏览器,
'opera >= 11.5' // 兼容欧朋版本号大于11.5浏览器,
]
},
// "postcss-pxtorem": {
// rootValue: 100, // 根元素字体大小
// // propList: ['*'] // 可以从px更改到rem的属性
// propList: ["height"]
// }
'postcss-sprites': {
// 告诉webpack合并之后的图片保存到什么地方
spritePath: './bundle/images',
// 告诉webpack合并图片的时候如何分组
groupBy: function(image) {
// url: '../images/animal/animal1.png',
const path = image.url.substr(0, image.url.lastIndexOf('/'));
// console.log(path, "!!!!!!");
const name = path.substr(path.lastIndexOf('/') + 1);
// console.log(name, "!!!!!!!!");
return Promise.resolve(name);
},
//
filterBy: function(image) {
const path = image.url;
if (!/\.png$/.test(path)) {
return Promise.reject(new Error('不打包'));
}
return Promise.resolve();
}
}
}
};