WebPack

作者: Poppy11 | 来源:发表于2022-09-08 17:11 被阅读0次

    1.为什么需要使用打包工具

    在现在的前端开发中,我们一般会使用React,Vue等前端开发框架,ES6模块语法,Less/Sass等css预处理器语法进行开发。
    但是浏览器不认识这些代码,所以需要编译成浏览器能识别的HTML,JS,CSS才能运行,所以需要打包工具。
    并且打包工具还能压缩代码,做兼容性处理,提升代码性能等。


    2.WebPack是什么?

    WebPack是静态资源打包工具。它会以一个文件或者多个文件作为打包的入口,将项目所有文件编译组合成一个或者多个文件输出出去。
    输出的文件就是编译好的文件,就可以在浏览器运行了。
    我们将WebPack输出的文件叫做bundle
    WebPack本身功能较少,只能处理JS资源,一旦遇到样式资源、图片资源、HTML资源等其他资源就会报错。
    其实学习WebPack主要就是学习如何处理其他资源。


    3.基本配置

    五大核心概念
    Webpack 将来都通过 webpack.config.js 文件进行配置,来增强 Webpack 的功能
    我们会对Webpack配置文件区分为开发模式和生产模式来进行配置。

    • entry(入口)
      指示Webpack从哪个文件开始打包。
    • output(输出)
      指示Webpack打包的文件输出到哪里去,如何命名等。
    • loader(加载器)
      webpack本身只能处理js等资源,其它资源都需要借助loader,Webpack才能解析。
    • plugins(插件)
      扩展Webpack的功能。
    • mode(模式)
      开发模式:仅能编译JS中的ES Module语法。
      生产模式:能编译JS中的ES Module语法,并且进行JS压缩。
    • 常用Loader

    loaders,这里面是Webpack官方文档,可以在这里面寻找我们所需要的loader。但凡遇到Webpack无法识别的资源,都需要去官方寻找loader。loader写在module模块中的rules数组中。

    module:{
      rules:[
         {
           test: /\.css$/,
           use: ["style-loader", "css-loader"],
         },
      ]
    }
    

    css-loader
    less-loader
    scss-loader
    babel-loader
    babel-loader的作用就是将ES6语法编写的代码转化为向后兼容的JavaScript语法,以便能够运行在当前和旧版本的浏览器和其它环境中。并且可以开启缓存,避免重复进行balbel编译。
    babel主要用法是使用present预设, 扩展babel的功能,主要使用的预设有如下几点:
    1.@babel/preset-env:智能预设,将ES6语法编译为普通的JS代码
    2.@babel/preset/react:用来编译React JSX语法的预设
    3.@babel/preset-typescript:用来编译TypeScript语法的预设

    Babel 对一些公共方法使用了非常小的辅助代码,比如 _extend。默认情况下会被添加到每一个需要它的文件中。
    可以引入 Babel runtime 作为一个独立模块,来避免重复引入。

    {
          test: /\.m?js$/,
          exclude: /node_modules/,
          use: {
            loader: 'babel-loader',
            options: {
              presets: ['@babel/preset-env'],
              cacheDirectory:true, //开启babel缓存
              cacheCompression:false, //关闭缓存文件压缩
              plugins: ['@babel/plugin-transform-runtime']
            }
          }
        }
    

    postcss-loader
    postcss-loader一般用于css兼容性处理,我们除了按照官网所需要的配置loader,我们还需要在package.json设置browserslist数组控制当前项目兼容的浏览器

     "browserslist":["last 2 version","> 1%","not dead"]
    

    thread-loader
    配置多进程处理耗时loader,例如我们在项目中遇到耗时的loader,例如babel编译,eslint检查。我们就可以多线程打包。我们可以通过node知道目前CPU核数,然后开启多个进程数。要把该loader放在需要多线程处理的loader之前。

    const os = require("os");
    const threads = os.cpus().length;
    {
          test: /\.m?js$/,
          exclude: /node_modules/,
          use:[
          {
            loader:'thread-loader',
            options:{
              works:threads
            }
          },
          {
            loader: 'babel-loader',
            options: {
              presets: ['@babel/preset-env'],
              cacheDirectory:true, //开启babel缓存
              cacheCompression:false //关闭缓存文件压缩
            }
          }
          ]
        }
    
    • 常用Plugin

    html-webpack-plugin
    该插件会生成一个HTML文件,并且将我们输出的JS、CSS文件,会自动引入到该HTML中,并且我们还可以配置template,也就是模板HTML。

    new HtmlWebpackPlugin({
      template:path.resolve(__dirname,'public/index.html')
    })
    

    mini-css-extract-plugin
    之前的css文件是被JS加载执行生成style标签,所以会存在闪屏的问题,需要等待JS执行完了,样式才生效,该插件可以单独输出样式文件,然后html-webpack-plugin则会通过link标签帮助我们引入到HTML中。
    css-minimizer-webpack-plugin
    主要作用是压缩CSS
    terser-webpack-plugin
    主要作用是压缩JS,生产环境下会默认使用此插件,并且可以自定义配置多线程进行压缩。

    const TerserPlugin = require("terser-webpack-plugin");
    const os = require("os");
    const threads = os.cpus().length;
    new TerserPlugin({
      parallel:threads 
    })
    

    image-minimizer-webpack-plugin
    主要作用是用于压缩图片
    eslint-webpack-plugin
    主要是配置ESLint,ESLint是来检测 js 和 jsx 语法的工具,一般会在根目录创建.eslintrc.js,一般我们很少手写规则,一般会继承已有的规则。

    // 例如在React项目中,我们可以这样写配置
    module.exports = {
      extends: ["react-app"],
      rules: {
        // 我们的规则会覆盖掉react-app的规则
        // 所以想要修改规则直接改就是了
        eqeqeq: ["warn", "smart"],
      },
    };
    
    • 资源模块

    webpack5中,自身都可以进行图片处理,因为内置了资源模块,不需要使用file-loader和url-loader进行处理,
    type: "asset/resource"type: "asset"的区别:

    1. type: "asset/resource" 相当于file-loader, 将文件转化成 Webpack 能识别的资源,其他不做处理
    2. type: "asset" 相当于url-loader, 将文件转化成 Webpack 能识别的资源,同时小于某个大小的资源会处理成 data URI 形式

    图片处理
    我们需要进行优化,也就是对图片小于一定大小,该图片转换为Base64形式。

     {
            test: /\.(png|jpe?g|gif|webp|svg)$/,
            type: "asset",
            parser: {
              dataUrlCondition: {
                maxSize: 10 * 1024, 
              },
            },
    },
    

    输出图片文件地址和文件名配置,添加下述generator配置,hash值可以选择生成10位或者不设置

    {
            test: /\.(png|jpe?g|gif|webp|svg)$/,
            type: "asset",
            parser: {
              dataUrlCondition: {
                maxSize: 10 * 1024,
              },
            },
            generator: {
              filename: "static/image/[hash:10][ext][query]",
            },
    },
    

    字体以及其它资源处理
    因为我们仅仅只需要生成文件,不需要转换成base64形式,所以type只需要设置为asset/resource,test中若有其它资源后缀名,继续添加就好。

    {
            test: /\.(ttf|woff2?)$/,
            type: "asset/resource",
            generator: {
              filename: "static/media/[hash:10][ext][query]",
            },
    },
    
    
    • 每次打包时自动清空文件夹
    output{
      clean:true
    }
    
    • 开发服务器,文件发生变化,自动编译打包

    webpack-dev-server,在src目录下的文件,如果发生改变则会自动编译打包。不会输出任何资源,在内存中编译打包。

      devServer: {
        host: "localhost", // 启动服务器域名
        port: "3000", // 启动服务器端口号
        open: true, // 是否自动打开浏览器
      },
    

    运行命令: npx webpack serve

    4.开发模式和生产模式

    开发模式我们需要配置devServer等,热更新,不需要输出资源。但是生产模式我们则不需要配置服务器,并且也需要输出资源等。所以我们则需要配置不同的webpackConfig。
    但是我们可以只写一份webpack.config.js。我们可以使用cross-env来区分不同的环境。

      "scripts": {
        "start": "npm run dev",
        "dev": "cross-env NODE_ENV=development webpack serve --config ./config/webpack.config.js",
        "build": "cross-env NODE_ENV=production webpack --config ./config/webpack.config.js"
      },
    

    在webpack.config.js文件中,我们就可以通过process来区分不同的环境

    const isProduction = process.env.NODE_ENV === "production";
    

    5.SourceMap(快速定位错误)

    SourceMap(源代码映射)是一个用来生成源代码与构建后代码一一映射的文件的方案。从而让浏览器提示源代码文件出错的位置。
    一般我们通过查看dev-tool文档,来使用不同的SourceMap方案。一般我们则只需要考虑两种情况

    • 开发模式 cheap-module-source-map
      • 打包编译速度快,只包含行映射
    • 生产模式 source-map
      • 打包编译速度慢,包含行/列映射
    devtool:"cheap-module-source-map"
    

    6.HMR(热模块替换)

    HotModuleReplacement,在开发环境开发代码时,我们每次打包编译都会耗时,会重新刷新页面,如果项目更大的话,耗时会更久。我们可以配合devServer来使用HMR。来实现某个文件更新,只针对某个文件进行重新编译打包。devServer-hot
    样式具备了热模块替换功能,style-loader已经实现了。

    devServer{
      hot:true
    }
    

    但是JS如果更新文件,还是会重新打包,刷新页面,所以我们需要特殊的配置

    import count from './js/count';
    count(1,2);
    if(module.hot){
      module.hot.accept('./js/count');
    }
    

    一般开发实际项目会使用vue-loader或者react-refresh-webpack-plugin来帮助实现热模块替换功能。

    7.代码分割

    多文件打包

    entry:{
      app:"./src/app.js",
      main:"./src/main.js",
    },
    output:{
      path:path.resolve(__dirname,"dist"),
      filename:"[name].js"
    }
    

    公共代码打包独立文件
    split-chunks

     optimization: {
        splitChunks: {
             chunks: 'all',
        },
    }
    

    8.PWA

    work-box-plugin 渐进式网络应用程序,是一种可以提供类似于native app体验的Web app技术,其中最重要的是,在离线时应用程序能够继续运行。

    9.Oneof

    使用 OneOf 让资源文件一旦被某个 loader 处理了,就不会继续遍历了,打包速度更快。

     module: {
        rules: [
          {
            oneOf: [
              {
                test: /\.css$/i,
                use: getStyleLoaders(),
              },
              {
                test: /\.less$/i,
                use: getStyleLoaders("less-loader"),
              },
              {
                test: /\.jsx?$/,
                exclude: /(node_modules)/,
                use: {
                  loader: "babel-loader",
                  options: {
                    cacheDirectory: true,
                    cacheCompression: false,
                  },
                },
              },
              {
                test: /\.(jpe?g|png|gif|svg)$/i,
                type: "asset",
                parser: {
                  dataUrlCondition: {
                    maxSize: 4 * 1024,
                  },
                },
              },
            ],
          },
        ],
      },
    

    相关文章

      网友评论

          本文标题:WebPack

          本文链接:https://www.haomeiwen.com/subject/wwyonrtx.html