Webpack学习

一、webpack是什么

核心概念

webpack是一种前端资源构建工具,一个静态模块打包器。

在webpack看来,前端所有资源文件(js/json/css/img/less)等都会作为模块处理

他根据模块依赖关系进行静态分析,打包生成对应静态资源

webpack 五个核心概念
  1. Entry

入口指示,webpack以哪个文件为入口起点进行开始打包,分析构建依赖关系图

  1. Output

输出指示,webpack打包后资源输出到哪里去,以及怎么命名

  1. Loader

在module文件下,让webpack能够去处理那些非js文件(webpack自身只理解js文件),主要是翻译作用,比如css和img

  1. Plugins

插件可以用于执行范围更广得任务,插件范围包括,从打包和压缩,一直到重新定义环境中得变量等

  1. Mode

模式指示webpack使用相应模式得配置

image-20220224192500994

开发环境打包不会压缩代码,生产环境会压缩

**注意:**webpack只能处理js/json,不能处理css/img等其他资源

二、webpack配置开发环境

配置文件

webpack.config.js 是webpack配置文件

作用:指示webpack 干哪些活(当你运行 webpack 指令时,会加载那些配置)

所有构建工具都是基于node.js平台运行的~模块化默认采用commonjs.

Loader配置
  1. 把less文件转为css文件并且压缩
const {resolve} = require('path') //绝对路径写法

module.exports ={
  entry:'./src/index.js', //入口
  output:{
    filename:'build.js', //输出文件名
    // __dirname nodejs的变量,代表当前文件绝对路径
    path:resolve(__dirname,'build') //输出到当前目录build目录下
  },
  module:{ 
    rules:[
      // 详细的loader配置,不同文件配置不同loader
      {
        test:/\.css$/, //匹配那些文件
        use:[  //使用哪些loader进行处理,use数组中顺序:从右到左,从上到下依次执行
          'style-loader',  //创建style标签,将js中的样式资源插入进行,添加到head中生效
          'css-loader'  //将css文件变成commonjs模块加载js中,里面内容是样式字符串
        ]
      },
      {
        test:/\.less$/,
        use:[
          'style-loader',
          'css-loader',
          'less-loader' //将less文件编译成css文件,需要下载less-loader和less
        ]
      }
    ]
  },
  plugins:[  //详细的plugins配置

  ],
  mode:'development', //开发环境
}
  1. 压缩图片

    下载url-loader file-loader html-loader

...
module:{ 
    rules:[
      {
      test:/\.(jpg|png|gif)$/, // 处理图片资源
      loader:'url-loader',  // 使用一个loader可以用loader多个用use数组
      options:{  
        limit:9*1024, // 图片大小小于9kb,就会被base64处理
        esModule:false,
          nmae:'[hash:10].[ext]',  //[hash:10]取hash的前10位,[ext]取原先扩展名
          outputPath:'imgs' // 把所有打包图片放到imgs文件夹
      },
      //  v5 版本已经废弃url-loader方法需要添加type: 'javascript/auto',才可以使用
      type: 'javascript/auto',
      },
       {
      test:/\.html$/,
      loader:'html-loader' //处理html文件的img图片(负责引入img,从而被url-loader处理)
      }
    ],
  },
      ...
  1. 打包其他资源

    下载file-loader

{
        exclude:/\.(css|js|html|less|jpg|png|gif)$/, //排除css|js|html|less|jpg|png|gif资源,不然会报错,打包其他的资源
        loader:'file-loader',
       options:{  
          name:'[hash:10].[ext]',  //[hash:10]取hash的前10位,[ext]取原先扩展名
          outputPath:'media'  //把所有其他打包文件放到media文件夹
        },
      }
plugins配置

下载 ==》引入 ==> 使用

  1. 打包html文件,html-webpack-plugin插件

功能:会默认创建一个空的html,自动引入打包的所有资源(css,js)

需求:需要有结构的html文件

const HtmlWebpackPlugin = require('html-webpack-plugin') //引入
...
plugins:[  //详细的plugins配置
    new HtmlWebpackPlugin({
      template:'./src/2.html' //复制'./src/2.html'文件,并自动引入打包输出的所有资源(css,js),原文件如果引入,就引了2次,注意
    })
  ],
  ...
开发服务器 devServer

开发服务器用来自动化(自动编译,自动打开浏览器,自动刷新浏览器)

特点:只会在内存中编译打包,不会有任何输出,所以压缩的文件我们看不到,只会出现在内存中

启动 devserver 指令:npx webpack server

module.exports ={
  entry:'./src/index.js', //入口
  output:{
    filename:'build.js', //输出文件名
    // __dirname nodejs的变量,代表当前文件绝对路径
    path:resolve(__dirname,'build') //输出到当前目录build目录下
  },
  module:{ 
    rules:[
      ...
    ],
  },
  plugins:[  //详细的plugins配置
      ...
  ],
  mode:'development', //开发环境
  devServer:{
    static:resolve(__dirname,'build'),  //项目构建后路径,__dirname nodejs的变量,代表当前文件绝对路径
    compress:true, //启动gzip压缩
    port:8080, //端口号3000
    open:true,  // 自动打开浏览器
  }
}

image-20220227155931824

三、webpack配置生产环境

css配置
  1. 提取css为单独文件

安装 mini-css-extract-plugin 插件

const miniCssExtractPlugin = require('mini-css-extract-plugin') //导入
	...
    rules:[
      // 详细的loader配置,不同文件配置不同loader
      {
        test:/\.css$/, //匹配那些文件
        use:[  //使用哪些loader进行处理,use数组中顺序:从右到左,从上到下依次执行
          // 'style-loader',  //创建style标签,将js中的样式资源插入进行,添加到head中生效
          miniCssExtractPlugin.loader,  //取代style-loader,提取css生产单独文件
          'css-loader'  //将css文件变成commonjs模块加载js中,里面内容是样式字符串
        ]
      },
    ],
	...
    plugins:[  //详细的plugins配置
    new miniCssExtractPlugin({
      filename:'css/built.css'  //输出到指定目录下
    })
  ],
  1. css兼容性处理

    下载 postcss-loader postcss-preset-env

process.env.NODE_ENV='development' //兼容默认生产环境,在当前文件目录配置,node环境变量,可以变为开发环境

...
rules:[
      // 详细的loader配置,不同文件配置不同loader
      {
        test:/\.css$/, //匹配那些文件
        use:[  //使用哪些loader进行处理,use数组中顺序:从右到左,从上到下依次执行
          // 'style-loader',  //创建style标签,将js中的样式资源插入进行,添加到head中生效
          miniCssExtractPlugin.loader,  //取代style-loader,提取css生产单独文件
          'css-loader',  //将css文件变成commonjs模块加载js中,里面内容是样式字符串
          {
            loader:'postcss-loader',  //postcss-preset-env帮助postcss-loader找postcss.json中的browserslist里面配置,通过配置找到指定css兼容样式
            options:{
             postcssOptions:{
               plugins:[['postcss-preset-env',{}]] //postcss-loader插件
             }
            }
          }
        ]
      },
      {
        test:/\.less$/,
        use:[  //使用哪些loader进行处理,use数组中顺序:从右到左,从上到下依次执行
          // 'style-loader',  //创建style标签,将js中的样式资源插入进行,添加到head中生效
          miniCssExtractPlugin.loader,  //取代style-loader,提取css生产单独文件
          'css-loader',  //将css文件变成commonjs模块加载js中,里面内容是样式字符串
          {
            loader:'postcss-loader',  //postcss-preset-env帮助postcss-loader找postcss.json中的browserslist里面配置,通过配置找到指定css兼容样式
            options:{
             postcssOptions:{
               plugins:[['postcss-preset-env',{}]] //postcss-loader插件
             }
            }
          }
        ]
      },
...
    
   //在package.json文件配置兼容的浏览器
    ...
     "webpack": "^5.69.1",
    "webpack-cli": "^4.9.2"
  },
  "browserslist":{  
    "development":[  //开发环境
      "last 1 chrome version",  //兼容谷歌浏览器最近版本,下面3个同理
      "last 1 firefox version", 
      "last 1 safari version" 
    ],
    "production":[  //生产环境
      ">0.02%",  //兼容百分98浏览器
      "not dead",  //出去丢弃的ie10浏览器
      "not op_mini all"  //出去不在使用的op浏览器
    ]
  }
...
  1. 压缩css

下载插件css-minimizer-webpack-plugin

const cssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin') //导入
plugins:[  //详细的plugins配置
    new cssMinimizerWebpackPlugin() //压缩插件使用
  ],
js位置
  1. 语法检查eslint

下载eslint-loader eslint检查基本配置

下载eslint-config-airbnb-base eslint-plugin-import 检查的规范,可以自己选择

...
rules: [
      {
        test:/\.js$/,
        exclude:/node_modules/, //不检查node_modules里面js文件
        loader:'eslint-loader',
        options:{
          fix:true  //自动格式化
        }
      },
      ...
    
    // package.json 里配置
    ...
     "webpack": "^5.69.1",
    "webpack-cli": "^4.9.2"
  },
  "eslintConfig": {
    "extends": "airbnb-base" // 配置eslink规则
  }
}
  1. js兼容性处理

下载 babel-loader @babel/core @babel/preset-env @babel/polyfill

 rules: [
 ...
      {
        test:/\.js$/,
        exclude:/node_modules/, //不检查node_modules里面js文件
        use: [{
          loader: 'eslint-loader',
          options: {
            fix:true,  //自动格式化
          }
        },{
          loader: 'babel-loader',
          options: {
                  presets: ['@babel/preset-env']  //只能把部门高级语法转为低级语法,兼容浏览器
                }
        }]
      },
 		...
    ],
     
     // 可以把剩下高级语法转为低级语法,兼容浏览器,在js入口文件文件导入,如main.js
     import '@babel/polyfill';
压缩html与js

把环境变为生产环境自动压缩js和html,还得配置minify

plugins: [ // 详细的plugins配置
    new HtmlWebpackPlugin({
      template: './src/2.html', // 复制'./src/2.html'文件,并自动引入打包输出的所有资源(css,js)
      minify:{  //压缩html配置项
        collapseWhitespace:true,  // 移除空格
        removeComments:true  // 移除注释
      }
    }),
  ],
  mode: 'production', // 生产环境
  devServer: {
    static: resolve(__dirname, 'build'), // 项目构建后路径,__dirname nodejs的变量,代表当前文件绝对路径
        ...

四、webpack 性能优化

开发环境:优化打包构建速度;优化代码调试

生产环境:优化打包构建速度;优化代码运行性能

HMR:热模块替换

作用:一个模块发生变化,只会重新打包这一个模块(而不是打包所有模块),极大提升构建速度

样式文件:可以使用HMR功能:因为style-loader内部实现了

js文件:默认不能使用HMR功能–》需要修改js代码,添加支持HMR功能的代码

注意:HMR功能对js处理,只能处理非入口js文件其他文件

html文件:默认不能使用HMR功能,同时会导致问题:html文件不能热更新了(不用做HMR功能)

解决:修改entry入口,将html文件引入

entry: ['./src/index.js','./src/2.html'], // 入口,导致问题:html文件不能热更新了,将html文件引入

devServer: {
    static: resolve(__dirname, 'build'), // 项目构建后路径,__dirname nodejs的变量,代表当前文件绝对路径
    compress: true, // 启动gzip压缩
    port: 8080, // 端口号3000
    open: true, // 自动打开浏览器
    //开启HMR功能//当修改了webpack配置,新配置要想生效,必须重新webpack服务
    hot:true
  },
source-map优化代码调试

作用:提供源代码到构建后代码映射技术(如构建后代码出错,通过映射关系可以追踪到源代码)

...
devServer: {
    static: resolve(__dirname, 'build'), // 项目构建后路径,__dirname nodejs的变量,代表当前文件绝对路径
    compress: true, // 启动gzip压缩
    port: 8080, // 端口号3000
    open: true, // 自动打开浏览器
    //开启HMR功能//当修改了webpack配置,新配置要想生效,必须重新webpack服务
    hot:true
  },
  devtool:'eval-source-map'  // 优化代码调试配置
};

image-20220226223842803

oneOf

以下loader只会匹配一个,注意:不能有两个配置处理同一种类型文件

 module: {
    rules: [
        ...
      {
        //以下loader只会匹配一个//注意:不能有两个配置处理同一种类型文件
        oneOf:[
          // 详细的loader配置,不同文件配置不同loader
      {
        test: /\.css$/, // 匹配那些文件
        use: [...commonCssLoader],// 使用哪些loader进行处理,use数组中顺序:从右到左,从上到下依次执行 
      },
     ]
      }
    ],
  },
      ...
缓存优化

image-20220226232554658

 use: [{
          loader: 'eslint-loader',
          options: {
            fix:true,  //自动格式化
          }
        },{
          loader: 'babel-loader',
          options: {
                  presets: [
                    [
                    '@babel/preset-env',
                  ],
                 
                  ],
                  cacheDirectory:true // 加在打包html和js的loader里面
                },
        }],
      },
          
          output: {
    filename: 'build.[contenthash:10].js', // 输出文件名
    // __dirname nodejs的变量,代表当前文件绝对路径
    path: resolve(__dirname, 'build'), // 输出到当前目录build目录下
  }, 
      
       new miniCssExtractPlugin({
      filename: 'css/built.[contenthash:10].css', // 输出到指定目录下
    }),
          通过哈希命名,使更改的文件才会更新,不会刷新缓存
tree shaking:去除无用代码

前提:1. 必须使用es6 模块化 2. 开始production 生产环境

作用:减少代码体积

在package.json中配置

“sideEffects”:false 所有代码都没有副作用(都可以进行tree shaking,把引入进来没用使用的都不会打包,比如css)

问题:可能会把css/@babel/polyfill (副作用)文件干掉

"sideEffects":["*.css","*.less"] css和less结尾文件不进行tree shaking

code split 代码分割
entry: 
    {   // 多入口,每一组生成单独文件,单入口只生成一个文件
      index:'./src/index.js', 
      test:'./src/index.less',
      index:'./src/2.html'
    },
    
   // 入口
  output: {
    filename: '[name].[contenthash:10].js', // 输出文件名,[name]多入口属性名作为文件名
    // __dirname nodejs的变量,代表当前文件绝对路径
    path: resolve(__dirname, 'build'), // 输出到当前目录build目录下
  },
      
      ...
       plugins: [ // 详细的plugins配置
           ...
  ],
  optimization:{  //可以将node_modeules中代码单独打包一个chunk最终输出,自动分析多入口chunk中,有没有公共依赖,有打包一个chunk
    splitChunks:{
      chunks:'all'
    }
  },
  mode: 'production', // 开发环境
      ...
PWA渐进式网络开发应用程序
多进程打包

下载:thread-loader

进程启动大概为600ms,进程通信也有开销

只有工作消耗时间比较长,才需要多进程打包

externals拒绝打包
	...
},
  mode: 'production', // 开发环境
  externals:{
    jquery:'jQuery' //拒绝jquery被打包进来,但是要手动引入cdn
  },
  devServer: {
    static: resolve(__dirname, 'build'), // 项目构建后路径,__dirname nodejs的变
        ...
dll技术

作用:对某些库(第三方库,jquery、react、vue。。。)进行单独打包,只用打包一次,下次不用打包

resolve解析模块

image-20220227154948284


}
},
mode: ‘production’, // 开发环境


###### PWA渐进式网络开发应用程序

###### 多进程打包

下载:`thread-loader`

进程启动大概为600ms,进程通信也有开销

只有工作消耗时间比较长,才需要多进程打包

###### externals拒绝打包

```js
	...
},
  mode: 'production', // 开发环境
  externals:{
    jquery:'jQuery' //拒绝jquery被打包进来,但是要手动引入cdn
  },
  devServer: {
    static: resolve(__dirname, 'build'), // 项目构建后路径,__dirname nodejs的变
        ...
dll技术

作用:对某些库(第三方库,jquery、react、vue。。。)进行单独打包,只用打包一次,下次不用打包

resolve解析模块

[外链图片转存中…(img-ETQhVbME-1645966040848)]

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

25氪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值