• Webpack打包工具


    Webpack是一个打包模块化javascript的工具,在webpack里一切文件皆模块,通过loader转换文件,通过plugin注入钩子,最后输出由多个模块组合成的文件,webpack专注于构建模块化项目。

    本质上,webpack是javascript应用程序的静态模块打包器。当webpack处理应用程序时,它会递归地构建一个依赖图,其中包含应用程序所需的每个模块,然后将所有这些模块打包成一个或多个bundle。

          webpack可以看做是模块打包机,他做的事情是分析项目结构,找到js模块以及其他一些浏览器不能直接被运行的拓展语言(scss、typescript)等,并将其打包为合适的格式以供浏览器使用。

     

    webpack的几个概念:

    (1)Entry:指示webpack应该使用哪个模块来作为构建其内部依赖图的开始。进入入口起点后,webpack会找出哪些模块和库是入口起点依赖的。

    (2)Output:告诉webpack在哪里输出它所创建的bundles,以及如何命名这些文件。

    (3)Loader:模块转换器,让webpack能够处理那些非javascript文件(webpack自身只理解js)。loader可以将所有的类型文件转换为webpack能够处理的有效模块,然后你可以利用webpack的打包能力,对它们进行处理。

    (4)Plugins:扩展插件,loader被用来转换某些类型的模块,而插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。

    (5)Chunk :代码块,一个Chunk由多个模块组合而成,用于代码合并与分割。

     webpack配置:

    const path=require('path');
    module.export={
        entry:'./main.js',
        output:{
            //将所有依赖的模块合并输出到bundle.js文件中
            filename:'bundle.js',
            //将输出文件都放到dist目录下
            path:path.resolve(__dirname,'./dist')
        },
        module:{
            rules:[
                {
                    //用正则去匹配要用该loader转换的css文件
                    test:/.css$/,
                    use:['style-loader','css-loader?minimize']     
                } 
    ]
    }
    //module.rules数组配置了一组规则,告诉webpack在遇到哪些文件时使用哪些loader去加载和转换
    }

    向loader传入属性的方式:

    (1)每个loader都可以通过URL querystring的方式传入参数,例如css-loader?minimize中的minimize告诉loader要开启CSS压缩。

    (2)通过Object实现

    use:[
        {
            loader:'style-loader'
        },
        {
            loader:'css-loader',
            options:{
                 minimize:true 
            }
        }       
    ]

    1、常用的Loader有哪些?分别有什么作用

    • style-loader:将css代码注入到js中,通过DOM操作去加载css;
    • css-loader:允许将css文件通过require的方式引入;
    • less-loader:将less代码转换为css代码;
    • sass-loader:将sass代码转换为css代码;
    • image-loader:加载并且压缩图片文件;
    • babel-loader:用babel来转换ES6文件到ES5;
    • ts-loader:将ts文件转换为js文件

     2、几个常见的Plugin

    html-webpack-plugin:为html文件中引入的外部资源,可以生成创建html入口文件。

    commonChuckPlugin:提取公共代码。

    3、webpack与grunt、gulp有什么不同?

    webpack与Grunt、Gulp没有什么可比性,它可以看做模块打包机,通过分析项目结构,找到js文件以及其他一些浏览器不能直接运行的拓展语言,并将其转换和打包为合适的格式供浏览器使用。

    Grunt/Gulp是一种能够优化前端的开发流程的工具,而Webpack是一种模块化的解决方案,不过Webpack的优点使得Webpack在很多场景下可以替代Gulp/Grunt类的工具

      (1)他们的工作方式也有较大的区别:

      Grunt/glup的工作方式是:在一个配置文件中,指明对某些文件进行类似编译,组合,压缩等任务的具体步骤,工具之后可以自动替你完成这些任务。

      webpack的工作方式是:把你的项目当做一个整体,通过一个给定的主文件(main.js),Webpack将从这个文件开始找到你的项目所有的依赖文件,然后使用loaders处理他们,最后打包为一个(或多个)浏览器可识别的js文件。

          (2)三者都是前端构建工具,grunt和glup在早期比较流行,现在webpack相对来说比较主流,不过一些轻量级的任务还是会用glup来处理,比如单独打包CSS文件等。

       (3)grunt/glup强调的是前端开发的工作流程,我们可以通过一系列的task,定义task处理事务(例如文件压缩、雪碧图、处理server)然后定义执行顺序,来让grunt/glup执行这些task,从而构建项目的整个前端开发流程。

    虽然它们都是前端自动化构建工具,但是严格上讲,grunt/glup旨在规范前端开发流程,模块化不是它强调的东西;而webpack更明显强调模块化开发,而那些文件压缩合并、预处理等功能,不过是他附带的功能。

    4、Webpack的构建流程是什么?从读取配置到输出文件的过程

     初始化参数:从配置文件和Shell语句中读取与合并参数,得出最终的参数;

    开始编译:用上一步得到的参数初始化Compiler对象,加载所有配置的插件,执行对象的run方法开始执行编译;

    确定入口:根据配置中的entry找出所有的入口文件;

    编译模块:从入口文件出发,调用所有配置的Loader对模块进行翻译,再找出该模块依赖的模块,递归本步骤直到所有依赖的文件都经过本步骤的处理;

    完成模块编译:在使用loader翻译完所有模块后,得到每个模块被翻译后的最终内容以及它们之间的依赖关系;

    输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的Chunk,再把每个Chunk转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会;

    输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。

    一个个独立的模块文件被合并到了一个单独的bundle.js的原因是:浏览器不能像node.js那样快速地在本地加载一个个模块文件,而必须通过网络请求去加载还未得到的文件。如果模块数量很多,则加载时间会很长,因此将所有模块都存放在了数组中,执行一次网络加载。

    5、编写Loader

    Webpack是运行在Node.js上的,一个Loader其实就是一个Node.js模块,这个模块需要导出一个函数,这个导出函数的工作就是获得处理前的原内容,对原内容执行处理后,返回处理后的内容。

    //一个最简单的Loader源码
    module.export=function(src){//src为文件的原内容
         //该函数需要返回处理后的内容,这里直接返回了原内容,相当于没有做任何转换
         return src;
    }

    如果一个文件可以使用多个loader,loader的执行顺序和本身的顺序是相反的,即最后一个loader先执行,第一个loader最后一个执行;

    第一个执行的loader接收源文件内容作为参数,其他loader接收前一个执行的loader的返回值作为参数,最后执行的loader会返回此模块的js源码。

    编写Loader的思路:

          编写Loader时需要遵循单一原则,每个Loader只需要完成一种转换。每个Loader拿到的是源文件内容,可以通过返回值的方式将处理后的内容输出,也可以调用this.callback()方法,将内容返回给webpack。还可以通过this.async()生成一个callback函数,再用这个callback将处理后的内容输出出去。

    //需求
    //1.处理.txt文件,2.对字符串进行反转操作,3.首字母大写
    //reverse-loader.js
    module.export=function(src){
        if(src){
            src=src.split('').reverse().join();
        }
        return src;
    }
    
    //upperCase-loader.js
    module.export=function(src){
        src=src.charAt(0).toUpperCase()+src.slice(1);
        return `module.export='${src}'`;
    }
    //配置webpack
    module:{
        rules:[
            {
                test:/.txt$/,
                use:[
                    './upperCase-loader.js',
                    './reverse-loader.js'
                ]
            }
        ]
    }
                

    6、编写Plugin

    webpack通过Plugin机制让其更灵活,以适应各种应用场景,在webpack运行的生命周期中会广播许多事件,Plugin可以监听这些事件,在合适的时机通过webpack提供的API改变输出结果。

    //一个最基础的Plugin源码
    class BasicPlugin{
        //在构造函数中获取用户为该插件传入的配置
        constructor(options){
    
        }
        //Webpack会调用BasicPlugin实例的apply方法为插件传入compiler对象
        apply(compiler){
            compiler.plugin('compilation',function(compilation){
    
            })
        }
    }
    module.exports=BasicPlugin;
    
    //在使用这个Plugin时,相关的配置代码如下:
    const BasicPlugin=require('./BasicPlugin.js');
    module.exports={
        plugins:[
            new BasicPlugin(options),
        ]
    }

    PS:

    Compiler对象:包含了webpack环境的所有配置信息,包含options、loaders、plugins等信息。这个对象在webpack启动时被实例化,它是全局唯一的,可以理解为webpack实例。

    Compilation对象:包含了当前模块资源、编译生成资源、变化的文件等。当webpack以开发模式运行时,每当检测到一个文件发生变化,便有一个新的Compilation被创建。

    7、Webpack的热替换是如何做到的?说明其原理?

    webpack --watch需要刷新整个页面。

    模块热替换能做到在不重新加载整个网页的情况下,将已更新的模块替换老模块,再重新执行一次来实现实时预览。  webpack-dev-server --hot

    8、如何利用webpack来优化前端性能(提高性能和体验)

    用webpack优化前端性能是指优化webpack的输出结果,让打包的最终结果在浏览器运行快速高效。

    (1)剔除不必要的代码(引入但未使用) tree shaking

      比如引入lodash包,里面有许多和js相关的遍历方法,但是实际中我们只用到了其中一两个,此时打包的时候如果把所有方法都打进去,会很浪费,tree shaking就是去除多于代码。具体使用方法是用UglifyJsPlugin可以在构建的过程中对冗余的代码进行删除。

    (2)利用CDN加速,在构建过程中,将引用的静态资源路径修改为CDN上对应的路径。可以利用webpack对于output参数和各loader的publicPath参数来修改资源路径。

    (3)删除死代码,将代码中永远不会走到的片段删除掉。可以通过在启动webpack时追加参数--optimize-minimize来实现。

    (4)提取公共代码。

    (5)资源压缩

     js压缩、css压缩、图片资源压缩(配合url-loader使用)

    9、html-webpack-plugin

    作用是当使用webpack打包时,创建一个html文件,并把webpack打包后的静态文件自动插入到这个html文件当中。

     html-webpack-plugin默认将会在output.path的目录下创建一个index.html文件,并在这个文件中插入一个script标签。

    也可以生成多个html文件。

    loader与plugin的区别:

    【loader】对模块源码的转换,loader描述了webpack如何处理非javascript模块,可以将文件从不同语言转成js。

    【plugin】目的在于解决loader无法实现的其他事情,从打包优化和压缩,到重新定义环境变量,功能强大到可以用来处理各种各样的任务。webpack提供了很多开箱即用的插件:CommonChunkPlugin主要用于提取第三方库和公共代码,避免首屏加载的bundle文件或者按需加载的bundle文件体积过大,导致加载时间过长。

  • 相关阅读:
    [原创]基于asp.ent MVC的无刷新文件上传组件
    ATL 开发 Com 学习笔记
    杀毒软件—美杜杉(medusa)使用观后感1
    IIS gzip压缩
    常用网页播放器代码
    [转]安装AspNetMVC1RC2出错
    Asp.net 异步请求 IHttpAsyncHandler
    发几个小的测式软件
    [转]关于document.cookie的使用
    boost Serialization
  • 原文地址:https://www.cnblogs.com/xiaoan0705/p/10298548.html
Copyright © 2020-2023  润新知