本文拟通过一篇完整的配置文档做为例子,讲解webpack配置的全过程。帮助webpack小白快手搭建工程,同时也帮助大家全面理解webpack配置。
话不多说,上代码!👩🏫
const path = require('path');
//const FileManagerPlugin = require('file-manager-plugin');
const cleanWebpackPlugin = require('clean-webpack-plugin');
module.exports={
mode:'development', //打包模式,三种 none|development|production,默认为production ----------说明①
//source-map 包含全部信息
//cheap-module-source-map 不包含列信息,但包含loader映射
//cheap-source-map 不包含 列 信息,也不包含loader的map。比如es6=》es5的map。
//eaval(快) cheap(不包含列和loader) inline(行内,不生成map文件) source-map module(映射loader) 这些词互相组装成属性
devtool:'eval-cheap-module-source-map', //cheap-source-map 不包含 列 信息,也不包含loader的map。比如es6=》es5的map。source-map包含全部信息
entry:"src/index.js", //一个入口文件 等于{main:'src/index.js'}
/* entry:{ //多个入口文件
app:'./src/app.js',
search:'./src/search.js'
}*/
output:{ //打包后的文件配置
path:__dirname+'dist', //打包后的输出目录
filename:'[name].js', //打包后的文件名称 [name]则为entry里的key,默认为main
//打包文件bundle.js将已此目录访问 如/bundle.js==》/test/bundle.js,比如放cdn地址
publicPath:'/'
},
//开发服务器配置,注意-打包后的文件在内存中
devServer:{
//静态文件访问目录,注意不影响output 输出的文件访问
contentBase:path.join(__dirname,'asset'),
//writeToDisk:true, //默认false 是否将打包的文件输出到硬盘,默认为否,只在内存中
compress:true, //启用压缩
port:5000, //端口号
//webpack-dev-server 就是一个express服务器,如下设置等同于mock 方便测试用
before(app){
app.get('/api/users', function(req, res) {
res.json([{id:1,name:'zhufeng'}])
})
},
//代理
proxy: {
"/api": {
target: 'http://localhost:3000',
pathRewrite:{"^/api":""}
}
}
//虚拟目录,该地址也可指向生成地址,使该地址可访问
// publicPath:'http://localhost:8080/test'
},
//webpack --watch 与 watch:true 为两种开启watch的方式,选择一种即可
watch:true,
//监听配置
watchOptions:{
//不需要监控的目录
ignored:/node_modules/,
//防抖时长
aggregateTimeout: 200,
//一秒内轮询次数,询问文件系统文件是否更改的次数
poll:1000
},
module:{
//--说明② 常用loader介绍。注意多个loader从右向左解析。
rules:[
{
test:/\.jsx?$/,
loader:'eslint-loader',
enforce:'pre', //强制指定loader的运行顺序
options:{fix:true}, //启动自动修复
include:resolve(__dirname,'src'), //loader应用到哪个目录
//exclude:/node_modules/ //排除目录
},
{test:/\.jsx?$/,use:[{
loader:'babel-loader',
options:{
//预设
presets:[
//preset-env 可以转换JS语法 es6-》es5。但只转换基本的,不转换promise Map Set等
["@babel/preset-env",{
useBuiltIns:'usage', //按需加载polyfill
corejs:{version:3}, //指定版本,与useBuiltIns(usage和entry时)配合
//指定要兼容哪些浏览器
target:{
chrome:'60',
firefox:'60',
ie:'9',
safari:'10',
edge:'10'
}
}]
],
plugins:[
//支持 装饰器 符号
[
'@babel/plugin-proposal-decorators',
{legacy:true}
],
//支持类属性定义
[
'@babel/plugin-proposal-class-properties',
{loose:true}
]
]
}
}]},
{test:/\.txt$/,use:'raw-loader'}, //test 正则表达式,匹配文件名
{test:/\.css$/,use:['style-loader','css-loader']}, //use String 一个loader;|String Array 多个loader;|Object Array 多个带参数配置的loader
{test:/\.(jpg|png|gif|bmp)$/,use:[{
loader:'url-loader',
options:{
name:'[hash:10].[ext]', //将文件改名为 哈希值的前十位+原来的扩展名
//name:'[path][name].[ext]',
esModule:false,
limit:8*1024,
//以下两项等同于直接在name中配置 images/[hash:10].[ext]
outputPath:'images', //指定输出图片的images目录
publicPath:'/images' //访问图片的话也需要去image目录,与outputPath一致
}
}]}
]
},
plugins:[
new webpack.SourceMapDevToolPlugin({
append: '\n//# sourceMappingURL=http://127.0.0.1:8081/[url]',
filename: '[file].map',
}),
//
new miniCssExtractPlugin({
filename:'css/[name].css'
}),
/* new FileManagerPlugin({
events: {
onEnd: {
copy: [{
source: './dist/*.map',
destination: 'C:/aprepare/zhufengwebpack2021/1.basic/sourcemap',
}],
delete: ['./dist/*.map'],
},
},
}), */
//打包之前先清空目录
new cleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: ['**/*'],
})
]
}
命令行传递参数,使用双横杠
为webpack传参 --修改打包模式
$ webpack --mode=development
为devServer传参 --启用压缩
$ webpack serve --compress
webpack内置插件
DefinePlugin,定义全局变量,mode对应的process.env.NODE_ENV
webpack-dev-server,开发服务器,对应devServer配置
配置辅助说明
说明①:mode 打包模式
development:开启详细debug信息
production:代码压缩
说明② 常用loader介绍。webpack只能解析js和json文件格式,so需要加载loader以处理其他文件格式。
raw-loader 普通文件loader
style-loader 将cssy以<style>标签插入到hmtl中
css-loader 解析css中的@import等语法
url-loader
该loader为file-loader的增强版,file-loader为将文件复制到指定输出目录。url-loader在此基础上可以将小于指定体积的文件已base64字符串形式内嵌
eslint-loader
默认调用 .eslintrc.js配置文件
.eslintrc.js
//.eslintrc.js
module.exports = {
root:true, //根配置文件(因为配置文件可继承)
parser:"babel-eslint", //需要一个parser解析器把代码转换成AST抽象语法树
//继承airbnb,需要安装 eslint-config-airbnb,不用自己手动配置
extend:'airbnb',
//指定解析器选项
parserOptions: {
sourceType: "module",
ecmaVersion: 2015
},
//指定脚本的运行环境
env: {
browser: true,
},
// 启用的规则及其各自的错误级别
rules: {
"indent": ["error",2], //缩进风格
"quotes": "off", //引号类型
"no-console": "off", //禁止使用console
}
}
自动修复,推荐vscode 插件 ESLint
babel-loader
babel-loader 作用是内部调用babel-core
presets:Array [pluginName,optionsObject] 预设,是插件的集合。
- 1、babel-core 作用是进行 语法树与代码 之间的转换
- 2、babel/preset-env es6转换成es5
es6代码 => es6语法树 babelCore
es6语法树 =》es5语法树 preset-env
es5语法树 =》es5语代码 babelCore
babel/preset-env 选项说明
useBuiltIns: ‘usage’|‘entry’|false
false 默认值。不对polyfill处理,全部引入。
usage 按需加载。
entry 在入口文件手工引入polyfill。根据配置的target浏览器,引入浏览器不兼容的polyfill,这里需要指定 core-js的版本
plugins:
@babel/plugin-proposal-decorators
legacy: Boolean 默认false;true为用stage1的语法(用废弃的语法)
@babel/plugin-proposal-class-properties
loose:Boolean 默认 false; 定义类属性的方式
true 则为 this.x=1
false 则为
Object.defineProperty(this,'x',{
configurable:true,
enumerable:true,
writable:true,
value:'1'
});
sourcemap调试
1、测试环境
测试环境调试是用SourceMapDevToolPlugin插件,将sourcemap文件地址设为本地服务器
//部分webpack.config.js
devtool:false,
plugins:[
new webpack.SourceMapDevToolPlugin({
append: '\n//# sourceMappingURL=http://127.0.0.1:8081/[url]',
filename: '[file].map',
}),
//将生成的sourcemap文件剪切到其他目录,使dist目录不存在sourcemap,且本地保留sourcemap以备调试
new FileManagerPlugin({
events: {
onEnd: {
copy: [{
source: './dist/*.map',
destination: 'C:/aprepare/zhufengwebpack2021/1.basic/sourcemap',
}],
delete: ['./dist/*.map'],
},
},
}),
]
2、开发环境
将devtool设为hidden-source-map,本地保留sourcemap,在chrome调试工具中,source 右键“add sourcemap”。
devtool:'hidden-source-map'