webpack 配置
2021-09-06 本文已影响0人
A_走在冷风中
配置demo
const webpack = require('webpack')
const path = require('path')
const { cleanWebpackPlugin } = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
const TerserWebpackPlugin = require('terser-webpack-plugin')
const InlineChunkHtmlPlugin = require('inline-chunk-html-plugin')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const PurgeCSSPlugin = require('purgecss-webpack-plugin')
// 删除 build.js 内的注释
class Myplugin {
apply(compiler) {
console.log('Myplugin 启动')
// 第一个参数是方法名称
compiler.hook.emit.tap('Myplugin', (compilation) => {
// compilation => 可以理解为此次打包的上下文
// compilation.assets 资源文件对象
for (const name in compilation.assets) {
// console.log(name) //资源文件名称
// console.log(compilation.assets[name].source());//获取资源文件内容
if (name.endsWith('.js')) {
//判断是否以 .js 为结尾
const contents = compilation.assets[name].source()
const withoutComments = contents.replace(/\/\*\*+\*\//g, '')
compilation.assets.name = {
source: () => withoutComments,
size: () => withoutComments.length,
}
}
}
})
}
}
module.exports = {
entry: './src/main.css', //知道webpack打包入口路径
output: {
filename: 'bundle.js', //输出文件名
path: path.join(__dirname, 'output'), //输出文件目录(要求绝对路径)
publicPath: 'dist/', //打包后根目录文件夹
},
devtool: 'source-map',
// Webpack Dev Serve 配置选项
devServer: {
hot: true, //开启 HMR
contentBase: ['./public'], //静态资源路径
proxy: {
//代理配置
'/api': {
//什么开头的地址配置到 xx地址
// http://loaclhost:8080/api/users => https://api.github.com/api/users
target: 'https://api.github.com',
pathRewite: {
// http://loaclhost:8080/api/users => https://api.github.com/users
'^/api': '',
},
// 不能使用 localhost:8080 作为请求 github 的主机名
changeOrigin: true,
},
},
},
module: {
rules: [
{
test: /.js$/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
},
},
},
{
test: /.css$/, //正则表达式,用来匹配文件路径
use: [
'style-loader', //通过style-loader将css-loader转换为style注入
'css-loader',
], //loader使用路径,从后向前执行
},
{
test: /.png$/,
use: 'file-loader',
},
{
test: /.png$/,
use: {
loader: 'url-loader',
options: {
//配置项
limit: 10 * 1024, //10kb以下文件转换为 dataurl,其他自动转换为file-loader形式
},
},
},
{
test: /.html$/,
use: {
loader: 'html-loader',
options: {
attrs: ['img:src', 'a:href'], //针对a标签中静态资源打包处理
},
},
},
{
test: /.md$/,
use: {
loader: [
'html-loader',
'./markdown-loader', //相对路径
],
},
},
{
test: /\.jsx?$/,
use: ['babel-loader'],
},
{
test: /\.ts$/,
use: ['ts-loader'],
},
{
test: /\.vue$/,
use: ['vue-loader'],
},
],
},
optimization: {
//代码压缩功能配置
usedExports: true, //只导出外部使用了的成员
// minimize:true,//压缩代码,删除未引用代码
minimize: [
new TerserWebpackPlugin(), //开启js压缩
// new OptimizeCssAssetsWebpackPlugin(), //这样只有打包的时候有效,但是js压缩插件会失效,所以还需要写js压缩
// 被弃用 可使用purgecss-webpack-plugin 插件
new PurgeCSSPlugin(),
],
concarenateModules: true, //合并模块代码
// sideEffects: true, //没有用到的模块是否有副作用 是否可以清除
usedExports: true, // 标记不被使用的函数
// package.json中配置sideEffects 可添加不被删除的文件
splitChunks: {
chunks: 'initial', // async initial all
minSize: 20000, //所拆分的文件最小值(默认)
maxSize: 20000,
minChunks: 1, //至少被引用次数
cacheGroups: {
//对拆包的过程进行分组
//自定义键值对
syVendors: {
test: /[\\/]node_modules[\\/]/,
filename: 'js/[id]_vendor.js',
priority: -10, //优先级
},
default: {
minChunks: 2,
filename: 'js/syy_[id].js',
priority: -20,
},
},
},
},
plugins: [
new cleanWebpackPlugin(),
// 生成index.html
new HtmlWebpackPlugin({
//对html文件配置
title: 'webpack Plugin Sample',
meta: {
viewport: 'width=device-width',
},
template: './src/index.html', //指定模板文件渲染index
}),
// 用于生成about.html
new HtmlWebpackPlugin({
filename: 'about.html',
}),
//将runtime中的css导入html中
new PurgeCSSPlugin({
paths: glob.sync(`${resolveApp('./src')}/**/*`, { nodir: true }),
safelist: function () {
return {
standard: ['body', 'html', 'ef'],
}
},
}),
// 开发过程中一般不会使用,所以在 devServer 中配置
new CopyWebpackPlugin([
'public', //将public下所有文件输出到dist目录
]),
new Myplugin(),
new webpack.HotModuleReplacementPlugin(), //开启HMR需要的插件
new webpack.DefinePlugin({
API_BASE_URL: "'http://api.example/com'", //变量会挂载到 env.API_BASE_URL
}),
new MiniCssExtractPlugin(), //使用这个就不需要使用style-loader,会将css生成.css文件
new OptimizeCssAssetsWebpackPlugin(), //压缩生成的.css文件,可以将他写到 optimization/minizer 数组下
//资源压缩
new CompressionPlugin({
test: /\.(css|js)$/,
minRatio: 0.8,
threshold: 0,
algorithm: 'gzip',
}),
//往当前html中注入内容,不用单发请求,根据实际情况来使用
new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime.*\.js/]),
new BundleAnalyzerPlugin(), //打包时间和内容分析
],
}
区分打包环境
paths.js
const path = require('path')
const appDir = process.cwd()
const resolveApp = (relativePath) => {
return path.resolve(appDir, relativePath)
}
module.exports = resolveApp
webpack.common.js
const resolveApp = require('./paths')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { merge } = require('webpack-merge')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
// 时间分析
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin')
const smp = new SpeedMeasurePlugin()
// 导入其它的配置
const prodConfig = require('./webpack.prod')
const devConfig = require('./webpack.dev')
// 定义对象保存 base 配置信息
const commonConfig = (isProduction) => {
return {
entry: './src/main.css', //知道webpack打包入口路径
output: {
filename: 'bundle.js', //输出文件名
path: path.join(__dirname, 'output'), //输出文件目录(要求绝对路径)
publicPath: 'dist/', //打包后根目录文件夹
},
resolve: {
extensions: ['.js', '.json', '.ts', '.jsx', '.vue'],
alias: {
'@': resolveApp('./src'),
},
},
optimization: {
runtimeChunk: true,
},
devtool: 'source-map',
// Webpack Dev Serve 配置选项
module: {
rules: [
{
test: /.js$/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
},
},
},
{
test: /\.css$/,
use: [
isProduction ? MiniCssExtractPlugin.loader : 'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1,
esModule: false,
},
},
'postcss-loader',
],
sideEffects: true,
},
{
test: /.png$/,
use: 'file-loader',
},
{
test: /.png$/,
use: {
loader: 'url-loader',
options: {
//配置项
limit: 10 * 1024, //10kb以下文件转换为 dataurl,其他自动转换为file-loader形式
},
},
},
{
test: /.html$/,
use: {
loader: 'html-loader',
options: {
attrs: ['img:src', 'a:href'], //针对a标签中静态资源打包处理
},
},
},
{
test: /.md$/,
use: {
loader: [
'html-loader',
'./markdown-loader', //相对路径
],
},
},
{
test: /\.jsx?$/,
use: ['babel-loader'],
},
{
test: /\.ts$/,
use: ['ts-loader'],
},
{
test: /\.vue$/,
use: ['vue-loader'],
},
],
},
plugins: [
//输出文件内容
new HtmlWebpackPlugin({
//自定义title
title: 'copyWebpackPlugin',
template: './public/index.html',
}),
],
}
}
module.exports = (env) => {
const isProduction = env.production
process.env.NODE_ENV = isProduction ? 'production' : 'development'
// 依据当前的打包模式来合并配置
const config = isProduction ? prodConfig : devConfig
const mergeConfig = merge(commonConfig(isProduction), config)
return smp.wrap(mergeConfig)
}
webpack.dev.js
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
mode: 'development',
devtool: 'cheap-module-source-map',
target: 'web',
devServer: {
hot: true, //开启 HMR
contentBase: ['./public'], //静态资源路径
proxy: {
//代理配置
'/api': {
//什么开头的地址配置到 xx地址
// http://loaclhost:8080/api/users => https://api.github.com/api/users
target: 'https://api.github.com',
pathRewite: {
// http://loaclhost:8080/api/users => https://api.github.com/users
'^/api': '',
},
// 不能使用 localhost:8080 作为请求 github 的主机名
changeOrigin: true,
},
},
},
plugins: [
new ReactRefreshWebpackPlugin(),
new VueLoaderPlugin(), //vue 热更新
],
}
webpack.prod.js
const webpack = require('webpack')
const resolveApp = require('./paths')
const { cleanWebpackPlugin } = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
const TerserWebpackPlugin = require('terser-webpack-plugin')
const InlineChunkHtmlPlugin = require('inline-chunk-html-plugin')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const PurgeCSSPlugin = require('purgecss-webpack-plugin')
// 删除 build.js 内的注释
class Myplugin {
apply(compiler) {
console.log('Myplugin 启动')
// 第一个参数是方法名称
compiler.hook.emit.tap('Myplugin', (compilation) => {
// compilation => 可以理解为此次打包的上下文
// compilation.assets 资源文件对象
for (const name in compilation.assets) {
// console.log(name) //资源文件名称
// console.log(compilation.assets[name].source());//获取资源文件内容
if (name.endsWith('.js')) {
//判断是否以 .js 为结尾
const contents = compilation.assets[name].source()
const withoutComments = contents.replace(/\/\*\*+\*\//g, '')
compilation.assets.name = {
source: () => withoutComments,
size: () => withoutComments.length,
}
}
}
})
}
}
module.exports = {
optimization: {
//代码压缩功能配置
usedExports: true, //只导出外部使用了的成员
// minimize:true,//压缩代码,删除未引用代码
minimize: [
new TerserWebpackPlugin(), //开启js压缩
// new OptimizeCssAssetsWebpackPlugin(), //这样只有打包的时候有效,但是js压缩插件会失效,所以还需要写js压缩
// 被弃用 可使用purgecss-webpack-plugin 插件
new PurgeCSSPlugin(),
],
concarenateModules: true, //合并模块代码
// sideEffects: true, //没有用到的模块是否有副作用 是否可以清除
usedExports: true, // 标记不被使用的函数
// package.json中配置sideEffects 可添加不被删除的文件
splitChunks: {
chunks: 'initial', // async initial all
minSize: 20000, //所拆分的文件最小值(默认)
maxSize: 20000,
minChunks: 1, //至少被引用次数
cacheGroups: {
//对拆包的过程进行分组
//自定义键值对
syVendors: {
test: /[\\/]node_modules[\\/]/,
filename: 'js/[id]_vendor.js',
priority: -10, //优先级
},
default: {
minChunks: 2,
filename: 'js/syy_[id].js',
priority: -20,
},
},
},
},
plugins: [
new cleanWebpackPlugin(),
// 生成index.html
new HtmlWebpackPlugin({
//对html文件配置
title: 'webpack Plugin Sample',
meta: {
viewport: 'width=device-width',
},
template: './src/index.html', //指定模板文件渲染index
}),
// 用于生成about.html
new HtmlWebpackPlugin({
filename: 'about.html',
}),
//将runtime中的css导入html中
new PurgeCSSPlugin({
paths: glob.sync(`${resolveApp('./src')}/**/*`, { nodir: true }),
safelist: function () {
return {
standard: ['body', 'html', 'ef'],
}
},
}),
// 开发过程中一般不会使用,所以在 devServer 中配置
new CopyWebpackPlugin([
'public', //将public下所有文件输出到dist目录
]),
new Myplugin(),
new webpack.HotModuleReplacementPlugin(), //开启HMR需要的插件
new webpack.DefinePlugin({
API_BASE_URL: "'http://api.example/com'", //变量会挂载到 env.API_BASE_URL
}),
new MiniCssExtractPlugin(), //使用这个就不需要使用style-loader,会将css生成.css文件
new OptimizeCssAssetsWebpackPlugin(), //压缩生成的.css文件,可以将他写到 optimization/minizer 数组下
//资源压缩
new CompressionPlugin({
test: /\.(css|js)$/,
minRatio: 0.8,
threshold: 0,
algorithm: 'gzip',
}),
//往当前html中注入内容,不用单发请求,根据实际情况来使用
new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime.*\.js/]),
new BundleAnalyzerPlugin(), //打包时间和内容分析
],
}