构建Webpack知识体系 | 青训营

58 阅读4分钟

安装依赖

  1. 初始化项目:

    使用webpack的项目必须是node项目

    初始化项目后目录下会生成package.json​文件夹

    npm init -y
    
  2. 安装依赖

    -D表示安装为开发依赖

    安装依赖后会生成一个node_modules​文件夹

    在package.json文件中这两个依赖归于devDependencies属性中

    npm i -D webpack webpack-cli
    
  3. 在项目中创建src文件夹,在其中创建项目文件

    项目目录结构:

    项目目录下src目录,其中存放的是源码

    项目目录下dist目录,其中存放的是源码被webpack打包后的代码

    项目目录下node_modules、package.json、webpack.json​等文件,为项目配置文件

  4. 打包项目代

    npm webpack
    

    打包代码后项目目录下会生成一个dist文件夹,文件夹中存在main.js文件

    webpack会将src文件夹中所有代码文件集合格式化写入main.js文件中

    每一次项目代码修改后都需要重新打包代码

配置文件

在webpack配置文件webpack.config.js中可以配置webpack使用属性

  1. 创建文件

    在src文件夹同级路径下新建文件webpack.config.js

  2. 配置属性

    • mode

      指定打包模式

      module.exports = {
          mode: "production"//产品模式
          mode: "development"//开发模式
      }
      
    • entry

      指定打包时的入口文件

      默认查找文件名为index.js

      //webpack.config.js
      //由于webpack是在node中使用的,所以要遵循commomJS的模块化规范
      //将代码导出时需要使用module.exports
      module.exports = {
         //可以使用路径字符串   
         entry: "./othername/othername.js",
         //可以存放数组,会将多个文文件打包到一起
         entry: ["./a.js", "./b.js"]
         //可以存放对象,会将文件打包成多个文件 
         entry: {
             main1: "./a.js",
             main2: "./b.js"
         }
      }
      
    • output

      文件打包后产生文件的路径

      const path = require("path")
      module.exports = {
        output: {
         //打包的目录,必须为绝对路径
         //路径默认为dist文件夹
         path: path.resolve(__dirname, "hello")
         //打包后的文件名
         filename: "main.js",
         //由于每次打包后都会生成新文件,会导致文件冗杂
         //所以需要自动清除前一次打包后生成的文件
         clean: true,
        }
      }
      

      当设置的filename文件名只有一个,而需要打包的文件有多个时,会产生冲突,可以使用动态指定文件名的方式

      filename: "[name].js"
      //这样打包的文件会根据属性entry所设定的来
      
    • module​​

      一般用于配置加载器

      配置webpack打包不同类型文件时的加载规则,如ts文件、css文件等

      如,webpack默认只会处理js类型的文件,当需要处理其他类型文件如css等时,需要引入相关的loader

      由于每次执行命令打包文件后,webpack都会删除以前的文件,所以dist目录下不能存放手写的文件,只能存放被打包后的文件

      因此,需要将css等文件通过引入的方式写入js文件中,才能实现css文件的生效

      • 引入其他文件

        项目目录下创建style目录用于存放css文件,assets目录用于存放图片等资源

        //index.js
        import "./style/index.css"
        import image1 from "./assets/image.jpg"
        
      • 安装loader

        loader​可以对除js外的文件进行处理

        npm i css-loader -D
        
      • 配置loader​​

        注意此处的loader​的编写顺序,先执行的写在后面,后执行的写在前面

        css-loader​比style-loader​先执行,所以要写在后面

        module.exports = {
           //属性名为module
           module: {
              //针对一种文件类型会有一个对象,所有的对象存在rule数组中
              rule: [
                 //css文件打包配置
                 {
                     //test - 处理文件的类型,需要使用正则表达式
                     test: /\.css$/i,
                     //use - 使用的loaders
                     use: [
                        //使css文件生效的loader
                        "style-loader",
                        //将css文件代码写入js文件的loader,仅使用该loader css代码不会执行
                        "css-loader"
                     ]
                 },
                 //图片资源打包配置
                 {
                     test: /\.jpg$/i,
                     //图片类型资源数据可以直接使用type进行配置
                     type: "asset/resource"
                 }
              ]
           }
        }
        
      • babel

        js部分新特性在浏览器中兼容性不好,需要通过babel将新特性代码转换为旧代码,提升兼容性

        • 安装babel-code

          npm i -D babel-loader @babel/core @babel/preset-env
          
        • 引入babel-loader

          module.exports = {
             module: {
                rule: [
                   rule: /\.js$/,
                   //排除部分文件,提高效率
                   exclude: /node_modules | bower_components)/,
                   use: {
                      loader: "babel-loader",
                      options: {
                         //给babel的使用配置预设置
                         preset: ["@babel/preset-env"]
                      }
                   }
                ]
             }
          }
          
        • 设置浏览器兼容列表

          package.json​文件中可以配置代码需要兼容的浏览器,在babel官方git仓库中可以查找可用的值

    • resolve

      • extensions

        告诉webpack哪些文件可以作为模块文件

        如,webpack并不知道ts文件可以作为模板文件,当引入ts模块文件时,会报错

        使用下面的配置可以告诉webpack可以将扩展名为.ts/.js​的文件作为模块文件

        module.exports = {
           resolve: {
              extensions: ['.ts', '.js']
           }
        }
        
    • sourceMap

      将源码和打包后的代码进行映射

      配置该属性后,可以在页面开发者工具面板查看未打包的源码,并且在源码进行断点时可以在打包后的代码中查找到相应位置

      module.exports = {
         devtool: "inline-source-map"
      }
      

插件

html-webpack-plugin

在打包文件后自动生成相关的html页面

使用html-webpack-plugin​插件后,打包代码后会自动生成以template​配置的文件为模板的新同名文件

同时,该html文件中会自动引入编译好的js文件

  1. 安装插件

    npm i html-webpack-plugin
    
  2. 引入插件:

    //webpack.config.js
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    
    module.exports = {
       plugins: [
          //设置页面标题
          new HtmlWebpackPlugin({
             title: "WELCOME"template: "./src/index.html"
          })
       ]
    }
    

webpack-dev-server

将代码部署到开发服务器上,当代码被修改时页面会自动刷新,不用重新打包

但是注意,启用服务器后,dist目录下的代码不是最新的,因为webpack将代码打包到服务器上了,所以需要手动执行打包命令更新dist中的代码

  1. 安装

    yarn add -D webpack-dev-server
    
  2. 启用服务器

    yarn webpack serve --open
    

clean-webpack-plugin

可以在每次重新编译前都清空dist目录下的旧文件,保证每次修改后dist目录下的文件都是新的

  1. 安装

    npm i clean-webpack-plugin
    
  2. 引入插件

    无需配置,直接引入即可

    //webpack.config.js
    const {CleanWebpackPlugin} = require('clean-webpack-plugin');
    
    module.exports = {
       plugins: [
          //设置页面标题
          new CleanWebpackPlugin()
       ]
    }
    

babel

主要是为了帮助编译完成后生成的js文件能够兼容不同版本的浏览器

  1. 安装依赖

    @babel/core​核心内容

    @babel/preset-env​浏览器兼容插件

    babel-loader​帮助插件和webpack相融合的加载器

    core-js​模拟js运行环境的插件,帮助旧版本浏览器模拟运行新版本js

    npm i @babel/core @babel/preset-env babel-loader core-js
    
  2. 在配置文件配置插件

    以配置ts文件的babel为例

    //webpack.config.js
    module.exports = {
      module: {
        rules: [
          // 配置ts文件的加载规则
          {
             // 针对的文件类型
             test: /\.ts$/,
             // 排除掉node包中的文件
             exclude: /node-modules/,
             // 配置要使用的loader:此处用到两个loader,ts-loader不需要其他配置,因此直接在use数组中;babel-loader需要进行配置,因此使用对象包裹起来
             use: [
               // 配置babel
               {
                  // 指定加载器
                  loader: "babel-loader",
                  // options实际上是对babel-loader的选项配置
                  options: {
                    // 配置预定义的环境
                    presets: [
                         [// 指定环境插件
                         "@babel/preset-env",
                         // 配置信息
                         {
                             // 配置需要兼容的浏览器
                             targets: {
                                "chrome": "58",
                                "ie": "11"
                             },
                             // 指定corejs的版本
                             "corejs": "3"  // 版本为3的corejs
                             // 使用corejs的方式:因为corejs的功能很多,但是不需要都用上,所以可以按需加载节省空间
                             "userBuildIns": "usage"
                         }
                       ]
                    ]
                  }
               },
               // 配置ts加载器
               'ts-loader'
             ]
           }
        ]
      }
    }