og

webpack4.0基本的一些配置记录

webpack.jpg

本文代码地址: https://github.com/dongke404/webpack-demo

webpack安装

  • 安装本地webpack
  • yarn add webpack webpack-cli -D
  • yarn add webpack-dev-server -D 开发模式用于打包生成在内存中便于开发调试的插件

0配置打包

        
  • 1
npx webpack

需要安装的一些第三方插件,loader的作用

  • yarn add html-webpack-plugin -D 用于将html文件打包进去的插件
  • yarn add css-loader style-loader less-loader
  • yarn add mini-css-extract-plugin -D 常用于抽离css,变为link标签引入模式
  • yarn add postcss-loader autoprefixer -D 加浏览器前缀
  • yarn add optimize-css-assets-webpack-plugin -D 通常用于压缩css 使用之后要使用下面的uglifyjs,对js也压缩
  • yarn add uglifyjs-webpack-plugin -D 通常用于压缩js
  • yarn add babel-loader @babel/core @babel/preset-env -D 常用于将es6语法转换成es5
  • yarn add @babel/plugin-proposal-class-properties -D 常用来解析es7类class语法
  • yarn add @babel/plugin-proposal-decorators -D 常用来解析es7装饰器语法
  • yarn add @babel/plugin-transform-runtime
  • yarn add file-loader -D常用于图片打包
  • yarn add url-loader -D 常用于图片打包,限制大小转换成base64
  • yarn add clean-webpack-plugin -D 常用于将原来打包的文件删除重新生成
  • yarn add copy-webpack-plugin -D 常用于将指定的文件也拷贝到打包文件里
  • yarn add webpack-merge -D 常用于区分开发生产环境,来组合配置文件
  • yarn add @babel/preset-react -D 常用于解析react的jsx语法
  • yarn add happypack 实现多线程打包

一个常用的配置文件webpack.config.js

        
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
let path = require("path") let HtmlWebpackPlugin = require("html-webpack-plugin") //用于将html文件打包进去的插件 let MiniCssExtractPlugin = require("mini-css-extract-plugin") let OptimizeCcss = require("optimize-css-assets-webpack-plugin") let UglifyjsPlugin = require("uglifyjs-webpack-plugin") let { CleanWebpackPlugin } = require("clean-webpack-plugin") let CopyWebpackPlugin = require("copy-webpack-plugin") let { BannerPlugin } = require("webpack") let { DefinePlugin } = require("webpack") let { IgnorePlugin } = require("webpack") let { DllReferencePlugin } = require("webpack") module.exports = { devServer: {//开发服务器的配置 hot: true,//启用热更新 port: 3000, //监听端口 progress: true, //进度条显示 contentBase: "./build", //内存中打包的文件夹名 proxy: { "/api": { //代理设置 target: 'http://localhost:5000', pathRewrite: { '/api': '' } //把带/api重写成/ } } }, optimization: {//各优化项 minimizer: [ new UglifyjsPlugin({ cache: true, parallel: true, //变一行 sourceMap: true } ),//压缩js new OptimizeCcss({}),//压缩css ], splitChunks: { //分割代码块 常用于多个入口导入公共模块的时候 老版本commonChunkPlugins cacheGroups: {//缓存组 common: {//公共的模块 chunks: "initial", //表示从入口处开始找 miniSize: 0, //表示公用模块大于0字节就抽离 minChunks: 2,//表示模块被引用两次就抽离 }, vendor: { priority: 1,//表示权重,先抽离第三方模块 test: /node_modules/,//抽离第三方包 chunks: "initial", //表示从入口处开始找 miniSize: 0, //表示第三方包大于0字节就抽离 minChunks: 2,//表示第三方包被引用两次就抽离 } } } }, mode: "development",//模式 默认两种 production development //单页面 entry: "./src/index.js", //入口 output: { filename: "bundle.[hash:8].js", //打包后的文件名 [hash:8]表示每次更改后生成不同名字的打包文件,只显示八位hash,用于解决缓存问题 path: path.resolve(__dirname, "build"),//路径必须是绝对路径 // publicPath:"http://www.kedong.me" //添加公共路径,常用于文件cdn }, plugins: [//数组 放着所有webpack插件(插件都是对象) new HtmlWebpackPlugin({ template: './src/index.html', //模板的位置 filename: "index.html", //打包后的名字 minify: {//压缩代码 removeAttributeQuotes: true,//删除属性的双引号 collapseWhitespace: true, //打包成一行 }, hash: true //这个可以避免缓存带来的麻烦。默认为true }), new MiniCssExtractPlugin({ //具体见https://www.npmjs.com/package/mini-css-extract-plugin filename: "main.css" //抽离出的样式的名字 }), // new CleanWebpackPlugin(), //表示先删除build再打包 常用于生产环境 new CopyWebpackPlugin({ patterns: [ { from: 'doc', to: 'doc' }, ] }), new BannerPlugin("make 2020 by kirkdong"),//添加声明 new DefinePlugin({ //定义环境 便于开发生产的替换 DEV: JSON.stringify("dev") }), new IgnorePlugin(/\.\/locale/, /moment/), //可以忽略掉moment包下的./locale new DllReferencePlugin({//Dll动态链接库的引用 manifest: path.resolve(__dirname, "build", "manifest.json") }) ], //-----------多页面部分------------ // entry: { // home: "./src/index.js", // other: "./src/index.js" // }, // output: { // filename: "[name].js", // path: path.resolve(__dirname, "build"), // }, // plugins: [//数组 放着所有webpack插件(插件都是对象) // new HtmlWebpackPlugin({ // template: './src/index.html', // filename: "home.html", // chunks: ["home"], // }), // new HtmlWebpackPlugin({ // template: './src/index.html', // filename: "other.html", // chunks: ["other"] // }), // new MiniCssExtractPlugin({ // filename: "main.css" //抽离出的样式的名字 // }) // ], //-----------多页面部分结束------------ //源码映射工具,会单独生成一个sourcemap文件 出错会标识当前报错的列合行 devtool: "source-map",//增加映射文件可以帮我们调试源代码 //devtool:"eval-source-map",//不会产生单独的文件,会错误显示行和列 //devtool:"cheap-source-map",//不会产生列 但是是一个单独的映射文件,产生后可以保存 //devtool:"cheap-moudle-evel-source-map" //不会产生文件,集成在打包文件中,不会产生列 watch: true,//监控文件实时变化进行打包 watchOptions: { //监控的配置 poll: 1000, //每秒检查一次变动 ignored: /node_modules/, //忽略指定文件的变化 aggregateTimeout: 300, //防抖功能 300ms }, // resolve: {//解析第三方包 common 更多配置自行查阅 // module: [path.resolve("node_modules"),] //表示只去node_modules目录下找 // }, externals: {//不打包的第三方模块 jquery: "jQuery" }, module: {//模块 noParse: /jquery/, //表示不去解析jquery的依赖库 //loader rules: [ //webpack打包样式 //规则 css-loader 主要负责解析@import语法 //style-loader 把css插入到head标签中 //loader特点 希望单一,所以use一般用一个数组可以用来组合使用 //loader执行顺序默认从右向左 //loader可以写成对象形势 //MiniCssExtractPlugin.loader //'psotcss-loader' 添加浏览器前缀 需要 添加postcss.config.js文件 package.json 添加"browserslist": ["iOS >= 6","Android >= 4","IE >= 9"] // { test: /\.css$/, use: [{ loader: 'style-loader' ,options:{insert:'top'}}, 'css-loader'] }, // { test: /\.less$/, use: [{ loader: 'style-loader' ,options:{insert:'top'}}, 'css-loader','less-loader'] }, { test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader'] }, { test: /\.less$/, use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader', 'postcss-loader'] }, //webpack打包Js { test: /\.js$/, include: path.resolve(__dirname, "src"), //需要的目录 exclude: /node_modules/, //排除的目录 use: { //用"babel-loader"将es6->es5 loader: "babel-loader", options: {//优化项 presets: [ '@babel/preset-env', "@babel/preset-react" //解析react语法 ], plugins: [ ["@babel/plugin-proposal-decorators", { "legacy": true }],//常用来解析es7装饰器语法 ["@babel/plugin-proposal-class-properties", { "loose": true }],//常用来解析es7类class语法 "@babel/plugin-transform-runtime" ], }, }, }, //webpack打包图片 { test: /\.(htm|html)$/i, loader: 'html-withimg-loader' }, // {//常用于图片打包 // test: /\.(png|jpg|gif)$/, // use: { // loader: 'file-loader', // options: { // esModule: false // } // } // }, { test: /\.(png|jpg|gif)$/, //做限制,图片小于50k用base64 否则用file-loader use: { loader: 'url-loader', options: { limit: 50 * 1024, outputPath: "/img/", //将生成的图片放到img目录下 esModule: false, // publicPath:"http://www.kedong.me" //单给图片添加公共路径,常用于图片当做cdn } } }, ] } }

为了方便开发,我们可以将webpack配置文件分成三个部分

公共:webpack.common.js

开发:webpack.dev.js

生产:webpack.prod.js

webpack.common.js

        
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
//开发生产公共配置 let path = require("path") let HtmlWebpackPlugin = require("html-webpack-plugin") //用于将html文件打包进去的插件 let MiniCssExtractPlugin = require("mini-css-extract-plugin") let CopyWebpackPlugin = require("copy-webpack-plugin") let { BannerPlugin } = require("webpack") let { DefinePlugin } = require("webpack") let { IgnorePlugin } = require("webpack") let { DllReferencePlugin } = require("webpack") module.exports = { //单页面 entry: "./src/index.js", //入口 output: { filename: "bundle.[hash:8].js", //打包后的文件名 [hash:8]表示每次更改后生成不同名字的打包文件,只显示八位hash,用于解决缓存问题 path: path.resolve(__dirname, "build"),//路径必须是绝对路径 // publicPath:"http://www.kedong.me" //添加公共路径,常用于文件cdn }, plugins: [//数组 放着所有webpack插件(插件都是对象) new HtmlWebpackPlugin({ template: './src/index.html', //模板的位置 filename: "index.html", //打包后的名字 minify: {//压缩代码 removeAttributeQuotes: true,//删除属性的双引号 collapseWhitespace: true, //打包成一行 }, hash: true //这个可以避免缓存带来的麻烦。默认为true }), new MiniCssExtractPlugin({ //具体见https://www.npmjs.com/package/mini-css-extract-plugin filename: "main.css" //抽离出的样式的名字 }), new CopyWebpackPlugin({ patterns: [ { from: 'doc', to: 'doc' }, ] }), new BannerPlugin("make 2020 by kirkdong"),//添加声明 new DefinePlugin({ //定义环境 便于开发生产的替换 DEV: JSON.stringify("dev") }), new IgnorePlugin(/\.\/locale/, /moment/), //可以忽略掉moment包下的./locale new DllReferencePlugin({//Dll动态链接库的引用 manifest: path.resolve(__dirname, "build", "manifest.json") }) ], //-----------多页面部分------------ // entry: { // home: "./src/index.js", // other: "./src/index.js" // }, // output: { // filename: "[name].js", // path: path.resolve(__dirname, "build"), // }, // plugins: [//数组 放着所有webpack插件(插件都是对象) // new HtmlWebpackPlugin({ // template: './src/index.html', // filename: "home.html", // chunks: ["home"], // }), // new HtmlWebpackPlugin({ // template: './src/index.html', // filename: "other.html", // chunks: ["other"] // }), // new MiniCssExtractPlugin({ // filename: "main.css" //抽离出的样式的名字 // }) // ], //-----------多页面部分结束------------ // resolve: {//解析第三方包 common 更多配置自行查阅 // module: [path.resolve("node_modules"),] //表示只去node_modules目录下找 // }, externals: {//不打包的第三方模块 jquery: "jQuery" }, module: {//模块 noParse: /jquery/, //表示不去解析jquery的依赖库 //loader rules: [ //webpack打包样式 //规则 css-loader 主要负责解析@import语法 //style-loader 把css插入到head标签中 //loader特点 希望单一,所以use一般用一个数组可以用来组合使用 //loader执行顺序默认从右向左 //loader可以写成对象形势 //MiniCssExtractPlugin.loader //'psotcss-loader' 添加浏览器前缀 需要 添加postcss.config.js文件 package.json 添加"browserslist": ["iOS >= 6","Android >= 4","IE >= 9"] // { test: /\.css$/, use: [{ loader: 'style-loader' ,options:{insert:'top'}}, 'css-loader'] }, // { test: /\.less$/, use: [{ loader: 'style-loader' ,options:{insert:'top'}}, 'css-loader','less-loader'] }, { test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader'] }, { test: /\.less$/, use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader', 'postcss-loader'] }, //webpack打包Js { test: /\.js$/, include: path.resolve(__dirname, "src"), //需要的目录 exclude: /node_modules/, //排除的目录 use: { //用"babel-loader"将es6->es5 loader: "babel-loader", options: {//优化项 presets: [ '@babel/preset-env', "@babel/preset-react" //解析react语法 ], plugins: [ ["@babel/plugin-proposal-decorators", { "legacy": true }],//常用来解析es7装饰器语法 ["@babel/plugin-proposal-class-properties", { "loose": true }],//常用来解析es7类class语法 "@babel/plugin-transform-runtime" ], }, }, }, //webpack打包图片 { test: /\.(htm|html)$/i, loader: 'html-withimg-loader' }, // {//常用于图片打包 // test: /\.(png|jpg|gif)$/, // use: { // loader: 'file-loader', // options: { // esModule: false // } // } // }, { test: /\.(png|jpg|gif)$/, //做限制,图片小于50k用base64 否则用file-loader use: { loader: 'url-loader', options: { limit: 50 * 1024, outputPath: "/img/", //将生成的图片放到img目录下 esModule: false, // publicPath:"http://www.kedong.me" //单给图片添加公共路径,常用于图片当做cdn } } }, ] } }

webpack.dev.js

        
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
//开发时所用配置 let { smart } = require('webpack-merge') let common = require('./webpack.common.js') module.exports = smart(common, { mode: "development", devServer: {//开发服务器的配置 hot: true,//启用热更新 port: 3000, //监听端口 progress: true, //进度条显示 contentBase: "./build", //内存中打包的文件夹名 proxy: { "/api": { //代理设置 target: 'http://localhost:5000', pathRewrite: { '/api': '' } //把带/api重写成/ } } }, //源码映射工具,会单独生成一个sourcemap文件 出错会标识当前报错的列合行 devtool: "source-map",//增加映射文件可以帮我们调试源代码 //devtool:"eval-source-map",//不会产生单独的文件,会错误显示行和列 //devtool:"cheap-source-map",//不会产生列 但是是一个单独的映射文件,产生后可以保存 //devtool:"cheap-moudle-evel-source-map" //不会产生文件,集成在打包文件中,不会产生列 watch: true,//监控文件实时变化进行打包 watchOptions: { //监控的配置 poll: 1000, //每秒检查一次变动 ignored: /node_modules/, //忽略指定文件的变化 aggregateTimeout: 300, //防抖功能 300ms }, })

webpack.prod.js

        
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
//生产环境所用配置 let { smart } = require('webpack-merge') let common = require('./webpack.common.js') let OptimizeCcss = require("optimize-css-assets-webpack-plugin") let UglifyjsPlugin = require("uglifyjs-webpack-plugin") let { CleanWebpackPlugin } = require("clean-webpack-plugin") module.exports = smart(common, { mode: "production", optimization: {//各优化项 minimizer: [ new UglifyjsPlugin({ cache: true, parallel: true, //变一行 sourceMap: true } ),//压缩js new OptimizeCcss({}),//压缩css ], splitChunks: { //分割代码块 常用于多个入口导入公共模块的时候 老版本commonChunkPlugins cacheGroups: {//缓存组 common: {//公共的模块 chunks: "initial", //表示从入口处开始找 minSize: 0, //表示公用模块大于0字节就抽离 minChunks: 2,//表示模块被引用两次就抽离 }, vendor: { priority: 1,//表示权重,先抽离第三方模块 test: /node_modules/,//抽离第三方包 chunks: "initial", //表示从入口处开始找 minSize: 0, //表示第三方包大于0字节就抽离 minChunks: 2,//表示第三方包被引用两次就抽离 } } } }, plugins: [//数组 放着所有webpack插件(插件都是对象) // new CleanWebpackPlugin(), //表示先删除build再打包 常用于生产环境 ], })

下面是一个单独打包react的配置,用作动态链接库

可以提前打包好,省的每次打包时在一起打包

生成的dll文件需要在html文件中引入

记得在配置文件里配置这个相应的插件new DllReferencePlugin

npx webpack webpack.config.react.js

        
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
//单独打包react react-dom 做动态链接库 let path=require("path") let webpack=require("webpack") module.exports={ mode:"development", entry:{ react:["react","react-dom"] }, output:{ filename:'_dll_[name].js', path:path.resolve(__dirname,"build"), library:"_dll_[name]", //_dll_react libraryTarget:"var" // commonjs var this .... }, plugins:[ new webpack.DllPlugin({//name==library name:"_dll_[name]", path:path.resolve(__dirname,"build","manifest.json") }) ] }

之后有时间学习时还会介绍tapable,手写webpack和一些loader的实现

——THE END——

Article at   2020/05/23 21:59  Published  code  Category,viewed  171  times

Relevant tags:    webpack 

Address:   https://www.kedong.me/article/15

Copyright Notice: Freely reproduced for non-commercial use