面试官:Webpack

56 阅读5分钟

Webpack

本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler) 。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph) ,其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundleWebpack中文文档

Webpack的作用

简单来说webpack就是一个打包工具。但是webpack能做的事情以及作用是很多的。

  • js高级语法转换兼容
  • css兼容/预处理语言处理(less、scss)
  • 代码压缩混淆
  • jsx转换
  • 图片压缩
  • ...

Webpack基础配置

我们在安装完webpack之后,可以在package.json文件中自定义打包指令,并在webpack.config.js文件中自定义配置项。

  1. 初始化package.json

    npm init
    
  2. 安装webpack

    npm i webpack webpack-cli        
    
  3. 在package.json运行命令

    "scripts": {
      "dev": "webpack", //自定义 webpack 指令为 dev
      "test": "echo "Error: no test specified" && exit 1"
    },      
    
  4. 配置打包模式,根目录创建webpack.config.js

    module.exports = {
      mode: 'development' // development 开发阶段 production 发布阶段
    }
    

打包的出入口

在webpack.config.js文件中,entry是打包的入口配置,也就是我们从哪个文件开始打包;output是打包的出口配置,也就是完成打包以后,在哪里、创建什么样的文件。

  1. 通过entry配置打包多入口, key是打包生成后的名字,value是打包路径

    module.exports = {
      entry: {
        main: './src/main.js', //第一个打包入口是src文件夹下的main.js文件
        app: './src/app.js'    //第二个打包入口是src文件夹下的app.js文件
      }
    }
    
  2. 配置output多出口,output中的filename需要修改为[name]占位

    module.exports = {
      output: {
        path: __dirname + '/dist/',  //配置打包后的文件保存在哪里,__dirname是当前文件所在的绝对路径
        filename: '[name].js'  //出口文件的名称,name是entry配置中的key(打包生成后的名字)
      }
    }
    
  3. 打包测试

    npm run dev
    

loader

webpack默认只能处理js文件,如果想处理其他类型文件则借助各种loader实现

css-loader与style-loader

  • css-loader:负责加载css文件,并将css文件转换为commonjs对象
  • tyle-loader:负责将样式生成style标签插入到DOM中(行内式样式)

注意:css-loader只将文件转化为对象,并不能实现插入,因此需要配合style-loader或者mini-css-extract-plugin使用

  1. 安装包

    mini-css-extract-plugin       
    
  2. 配置插件和loader

    module.exports = {
      //module表示配置依赖的loader项
      module: {
        //通过rules配置具体规则
        rules: [
          {
            test: /.css$/,  //通过test匹配具体文件类型
            use: ['css-loader', 'postcss-loader'] //通过use配置使用的依赖
          }
        ]
      },
    
  3. 打包测试

    npm run dev
    

postcss-loader

  • postcss-loader可以进一步打包css,例如添加前缀,px转rem,px转vw等等

注意:我们在webpack.config.js文件中配置使用postcss-loader来处理css文件。并在src文件夹下的postcss.config.js文件中配置postcss使用到的具体配置项(如:autoprefixer)

  1. 安装包autoprefixer 自动给css添加前缀

    npm i postcss-loader autoprefixer  
    
  2. 配置loader

    module.exports = {
      module: {
        rules: [
          {
            test: /.css$/,
            use: [
              {
                loader: 'style-loader',
              },
              {
                loader: 'css-loader',
                options: {
                  modules: true
                }
              },
              'postcss-loader'
            ]
          }
        ]
      }
    }    
    
  3. 配置postcss.config.js

    module.exports = {
      plugins: [
        require('autoprefixer')
      ]
    }
    

file-loader

目前webpack5 默认支持打包图片和字体等资源,对于较大的图片生成独立的 文件,对于较小的转化为base64格式的文件。

  1. 配置打包图片,asset会自动将打包的资源文件打包为单独的文件还是url进行自动切换

    module.exports = {
      module: {
        rules: [
          {
            test: /.(png|jpg|gif|jpeg)$/i,
            type: 'asset'
          }
        ]
      }
    }    
    

Webpack4.0 需要借助file-loader

  1. 安装file-loader

    npm i file-loader   
    
  2. 配置loader

    module.exports = {
      module: {
        rules: [
          {
            test: /.(png|jpg|gif)$/,
            use: ['file-loader']
          }
        ]
      }
    }
    

babel-loader

用于处理语法降级,例如将最新的JS语言转化为webpack可以识别的JS语言。

  1. 装包

    npm i @babel/core @babel/preset-env babel-loader -D  
    
  2. 配置解析js的loader

    module.exports = {
      module: {
        rules: [
          {
            test: /.js$/,
            use: 'babel-loader'
          }
        ]
      }
    }     
    
  3. 配置babel配置, 根目录创建.babelrc文件

    {
      "presets": [
        "@babel/preset-env"
      ]
    } 
    

plugin

plugins 为webpack的插件。可以扩展webpack的功能使其更加丰富

html-webpack-plugin

简化了 HTML 文件的创建,可以根据模版html(通常为public文件下的)生成新的html,并自动引入打包的js文件

  1. 安装包

    npm i html-webpack-plugin   
    
  2. 配置插件

    const HtmlWebpackPlugin = require('html-webpack-plugin')
    module.exports = {
      plugins: [new HtmlWebpackPlugin({
        template: './public/index.html',
        filename: 'index.html'
      })]
    }  
    
  3. 打包测试

    npm run dev
    

mini-css-extract-plugin

可以将css文件单独打包,生成新的css文件,注意mini-css-extract-plugin还要配合css-loader使用,同时该插件和style-loader不可同时使用,因为style-loader将css样式动态通过style标签插入到dom中

  1. 安装包

    mini-css-extract-plugin  
    
  2. 配置插件和loader

    const HtmlWebpackPlugin = require('html-webpack-plugin')
    const MiniCssExtractPlugin = require("mini-css-extract-plugin");
    module.exports = {
      module: {
        rules: [
          {
            test: /.css$/,
            use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader']
          }
        ]
      },
      plugins: [new HtmlWebpackPlugin({
        template: './public/index.html',
        filename: 'index.html'
      }), new MiniCssExtractPlugin()]
    }   
    
  3. 打包测试

    npm run dev
    

Webpack热更新

实现webpack检测文件发生变化进行自动打包

特点:

  • 会以服务的方式运行打包的项目
  • 打包的文件并不没有在磁盘中,而是在内存中,所以打包速度会更快
  • 文件发生变化自动打包
  1. 安装包

    npm i webpack-dev-server    
    
  2. 修改package.json

    • open:自动打开浏览器
    • port:端口号
    "scripts": {
        "dev": "webpack server --open --port=8083",
        "test": "echo "Error: no test specified" && exit 1"
      },  
    
  3. 运行打包

    npm run dev
    

总结

webpack是一款可以实现语法降级、文件压缩、css处理等功能的JavaScript 应用程序。 我们可以在package.json文件中自定义打包指令,并在webpack.config.js文件中自定义配置项。由于webpack默认只能处理JS文件,因此我们可以为其安装loader和plugin,使其功能更加强大。对于loader,我们常用的有css-loader、style-loader、bable-loader等;对于plugin,我们常用的有html-webpack-plugin、mini-css-extract-plugin等。

由于webpack默认只能处理JS语言,因此我们在遇到css文件的时候,需要借助css-loader来对文件进行处理。但是css-loder只能将css语言转换为commonjs对象,无法进行插入,因此需要借助style-loader来将处理后的css以行内式的方式插入在文件中,或是通过mini-css-extract-plugin打包为独立的css文件夹。当遇到rem等less语言等特殊的css语言时,还可以使用postcss-loader、less-loader等对其进行处理。对于高级的JS语法,webpack也是无法识别的,因此需要借助bable-loader来进行语法降级处理。以上这些loader都可以在webpack.config.js文件中共通过module对象下面的rule数组进行配置,在rule数组中,我们通过test属性,使用正则表达式来匹配需要处理的文件类型,再通use属性来配置需要使用的loader。但是需要注意,postcss-loader所使用的的插件需要在postcss.config.js文件中进行配置。

对于文件的生成,我们通常使用html-webpack-plugin来指定打包的html模板,以及生成打包文件的位置及名称。