Webpack 基础用法及解析

Webpack 基础用法及解析

  • loader特点

    • loader的执行顺序和代码书写的顺序是相反的,即:最后一个loader最先执行,第一个loader最后执行
    • 第一个执行的loader会接收源文件做为参数,下一次执行的loader会接收前一个loader执行的返回值做为参数
    • use 属性的值需要是一个由 Loader 名称组成的数组,Loader 的执行顺序是由后到前的;
    • 每一个 Loader 都可以通过 URL querystring 的方式传入参数,例如 css-loader?minimize 中的 minimize 告诉 css-loader 要开启 CSS 压缩。
  • loader编写原则

    • 单一原则: 每个 Loader 只做一件事;
    • 链式调用: Webpack 会按顺序链式调用每个 Loader;
    • 统一原则: 遵循 Webpack 制定的设计规则和结构,输入与输出均为字符串,各个 Loader 完全独立,即插即用;
  • 解析ES6

    • 使用babel-loader,babel的配置文件是.babelrc

    • npm i @babel/core @babel/preset-env babel-loader -D
      
  • 解析CSS

    • CSS-loader用于加载.css文件,并且转换成commonjs对象

    • style-loader将样式通过<style>标签插入到head

    • npm i style-loader css-loader -D
      
    • loader的调用是链式调用的,因此需要将style-loader 放至 css-loader之前

  • 解析lesssass

    • npm i less less-loader -D
      
  • 解析图片

    • file-loader用于处理文件

    • npm i file-loader -D
      
  • 使用url-loader

    • url-loader也可以处理图片和字体,可以设置较小资源自动base64

    • npm i url-loader -D
      
    • 接收一个参数options

      • module:{
            rules:[
                {
                    test:/\.(png|svg|jpg|gif)$/,
                    use:[
                        loader:'url-loader',
                        options{
                            limit:10240
                        }
                    ]
                }
            ]
        }
        
  • webpack文件监听

    • 文件监听是在发现源码发生改变时,自动重新构建出新的输出文件

    • webpack开启监听模式,有俩种方式:

      • 启动webpack命令时,带上--watch参数

        • "scripts":{
              "build":"webpack",
              "watch":"webpack --watch"
          }
          /*******唯一缺陷:每次需要手动刷新浏览器*******/
          npm  run watch
          
        • watch是放进本地的磁盘中去

          扫描二维码关注公众号,回复: 8781251 查看本文章
      • 在配置webpack.config.js中设置watch:true

  • 文件监听的原理分析
    • 轮询判断文件的最后编辑时间是否变化

    • 某个文件发生了变化,并不会立刻告诉监听者,二十先缓存起来,等aggregateTimeout

      • module.export = {
            //默认 false ,也就是不开启
            watch : true,
            //只有开启监听模式, watchOptions 才有意义
            watchOptions:{
                //默认为空,不监听的文件或者文件夹,支持正则匹配
                ignored:/node_modules/,//不监听node_modules,会提升性能
                //监听到变化发生后会等300ms 再去执行,默认300ms,
                aggregateTimeout:300,
                //判断文件是否发生变化是通过不停询问系统指定文件有没有变化实现的,默认每秒问1000次
                poll:1000
            }
        }
        

    webpack的热更新及原理分析

    • 热更新:webpack-dev-server
      • WDS不刷新浏览器

      • WDS不输出文件,而是放在内存

      • WDS优势:是没有磁盘的IO,构建速度会更快

      • 使用HotModuleReplacementPlugin插件

      • "scripts":{
            "build":"webpack",
            "dev":"webpack-dev-server--open"
        }
        
      • 启用热模块更换,也称为HMR,HMR 绝对不能在生产中使用。

      • 首先导入 webpack	   const webpack = require('webpack')
        将 mode 换成开发环境 , mode: development
        
        plugins:[
            new webpack.HotModuleReplacementPlugin({
              // Options...
            });
        ],
         devServer:{
         //contentbase代表html页面所在的相对目录,如果我们不配置项,devServer默认html所在的目   //录就是项目的根目录
             contentBase:'./dist',
             hot:true
         }
        
    • 热更新:使用webpack-dev-middleware
      • WDMwebpack输出的文件传输给服务器

      • 适用于灵活的定制场景

      •   const path = require('path');
          const HtmlWebpackPlugin = require('html-webpack-plugin');
          const { CleanWebpackPlugin } = require('clean-webpack-plugin');
        
          module.exports = {
            mode: 'development',
            entry: {
              app: './src/index.js',
              print: './src/print.js',
            },
            devtool: 'inline-source-map',
            devServer: {
              contentBase: './dist',
            },
            plugins: [
              new CleanWebpackPlugin(),
              new HtmlWebpackPlugin({
                title: 'Output Management',
              }),
            ],
            output: {
              filename: '[name].bundle.js',
              path: path.resolve(__dirname, 'dist'),
        +     publicPath: '/',
            },
          };
        
    • 热更新原理分析

      • Webpack Compile:将JS编译成Bundle
      • HMR Serve:将热更新的文件输出给HMR Rumtime
      • Bundle server:提供文件在浏览器的访问
      • HMR Rumtime:会被注入到浏览器,更新文件的变化
      • bundle.js:构建输出的文件
      • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hbMvjE6w-1579333594145)(C:\Users\36584\AppData\Roaming\Typora\typora-user-images\1579312892510.png)]
    • 热更新的过程

      • 启动阶段,是在文件系统进行编译,将初始代码进行Webpack Compile进行打包编译 ,打包之后,把编译好的文件传输给 Bundle Server,( Bundle Server其实就是一个服务器),就可以让浏览器访问 1 ==> 2 ==> A ==> B
      • 本地文件变更阶段,还是会经过Webpack Compile编译,服务端HMR Server通知浏览器端HMR Runtime,之后更新代码

什么是文件指纹 生产环境中

  • 打包输出的文件名的后缀
  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-95Xv6ijI-1579333594156)(C:\Users\36584\AppData\Roaming\Typora\typora-user-images\1579317143791.png)]
  • 文件指纹好处:作为版本的管理,发版的时候只会更新变更的文件,替换其变更的文件指纹,其余不变,另外,对于没有修改的,会使用本地的缓存,加快访问

文件指纹如何生成

  • Hash:和整个的项目的构建相关,只要项目文件有修改整个项目构建的hash值就会更改
  • Chunkhash:和webpack打包的chunk有关,不同的entry会生成不同的chunkhahs
  • Contentthash:跟还有文件内容来定义hash,文件内容不变,则contenthash不变,比如修改js但是css并没有修改,此时css并不需要更换文件指纹

JS的文件指纹设置

  • 设置outputfilename,使用[chunkhash]

    • output :{
          filename:'[name][chunkhash:8].js',
          path:_dirname + '/dist'
      }
      

CSS的文件指纹设置

  • 设置NibiCssExtractPluginfilename使用[contenthash]

    • npm i mini-css-extract-plugin -D

    • plugins:[
          new MiniCssExtractPlugin({
              filename:'[name][contenthash:8]'
          })
      ]
      
    • 插件是把css独立提取为一个文件,插件的loader是无法与style-loader同时使用,因为它们之间的功能是互斥的style-loader是把样式提取到heade里面,而插件是将其提取出来,所以在使用的时候是将style-loader替换成MiniCssExtractPlugin.loader

图片的文件指纹设置

  • 设置file-loader的name,使用[hash]

    • module :{
          rules:[{
              test:/\.(png|svg|jpg|gif)$/,
              use:[{
                  loader:'file-loader',
                  options:{
                      name:'img/[name][hash:8].[ext]'
                  }
              }]
          }]
      }
      //hash:8 取哈希值的前8位,md 是有32位
      //[ext]  图片的后缀
      

代码压缩

  • JS文件的压缩
    • 内置了uglifyjs-webpack-plugins

CSS文件的压缩

  • 使用optimeize-css-assets-webpack-plugin

  • 同时使用cssnano

  • plugins:[
        new OptimeizeCSSAssetsPlugin({
            assetNameRegExp:/\.css$/g,
            cssProcessor:require('cssnano')
        })
    ]
    

html文件得压缩

  • 修改html-webpack-plugin,设置压缩参数

  • plugins:[
        new HtmlWebpackPlugin({
            template:path.join(_dirname,'src/search.html'),
            filename:'search.html', //指定打包出来之后得文件名称
            chunks:['search'],
            inject:true,
            minify:{
                html:true,
                collapseWhitespace:true,
                preserveLineBreaks:false,
                minifyCSS:true,
                minifyJS:true,
                removeComments:false
            }
        })
    ]
    
发布了76 篇原创文章 · 获赞 6 · 访问量 3453

猜你喜欢

转载自blog.csdn.net/weixin_43550660/article/details/104030955