zoukankan      html  css  js  c++  java
  • webpack的理解、总结

    weabpck的基础应用

     https://blog.zhangjd.me/2016/06/19/webpack-your-bags/

    https://juejin.im/post/5cc26dfef265da037b611738#heading-9


    wbepck插件实现

    https://www.cnblogs.com/MuYunyun/p/8875908.html

    https://juejin.im/post/5ba34e54e51d450e5162789b#heading-56 

    总结 

    核心概念:

    webpack的模块打包工具,通过分析模块的依赖,最终将所有的模块打包成一份,或者多份的(bundder)
    提供html引用,webpack仅仅提供了打包功能和一套文件处理机制,通过plugin和loader对代码进行预编译和打包
    entry:webpck项目的入口文件,开始编译、打包
    output:webpack的输出文件的路径
    module:模块,webpack的任何的一个文件都可以作为一个模块,对于文件进行加载解析
    loader:模块加载器
    plugin:拓展插件,plugin 可以通过webpack有相应的事件钩子,介入到打包过程中的任意环节
    loader
     由于loader只能识别js,对于css/img/html等类型的文件无法加载,因此就需要不同类型文件进行转化,
     原理
     通过babylon 将es6/7转换成AST树
     通过bable-traverse 对ast 进行遍历转译,生成新的AST树
     新的AST树,通过generator的方式解析成为es6
    1)babylon:babel里面用来将js代码词法分析,生成ast,他的结构有些像acron,它的返回的结构里面包含着ast和tokens。
    require("babylon").parse("code", {
      // parse in strict mode and allow module declarations
      sourceType: "module",
      plugins: [
        // enable jsx and flow syntax
        "jsx",
        "flow"
      ]
    });
    sourceType: module表示的是在严格模式下解析并且允许模块定义(即能识别import和expor语法);script识别不了。
    2)babel-traverse:功能就像estraverse一样,主要是给plugin提供遍历ast节点的功能;
    var babylon = require('babylon');
    var result = babylon.parse(code, { sourceType: "module",});
    console.log('result:', result);
    import traverse from "babel-traverse";
    traverse(result, {
        enter(node) {
           console.log(node);
        }
    });
    3)babel-generator:将ast生成js代码;
    var babylon = require('babylon');
    var result = babylon.parse(code, { sourceType: "module",});
    console.log('result:', result);
    import traverse from "babel-traverse";
    import generate from 'babel-generator';
    traverse(result, {
        enter(node) {
           console.log(node);
        }
    });
    var conde1 = generate(result);
    console.log('generate:', conde1);
    loader还有一些特性
    1,按照链式相反方向执行
    2,loader可以同步也可以异步:例如( style-loader 是同步的(看源码就知道,直接 return);而 less-loader 却是异步的,)
    3,基于node环境,拥有较高的权限,可以对文件进行增删查改的操作
    有哪些loader
    1,file-oder:加载文件资源,比如字体、图片等,具有移动/命名/复制等功能
    2,url-loader:通常加载小图片,可以设置limit,如果小于一个值,就转换成base64,减少http请求
    3,style-loader:将style代码以css标签插入到代码中
    4,sass/less-loader:css的预处理器,在css中增加了很多新的语法,来增强开发效率
    5,css-loader:分析@import和url(),引入css文件与对应的资源
    6,babel-loader:加载js/jsx文件,将es6/es7转换成es5,
    7,ts-loader:加载ts/tsx文件,编译typeSCRIPT
    8,postcss-loader:用于css兼容处理,具有众多的功能,例如,添加前缀,单位转换等
    plugin
      Webpack 会触发许多事件钩子,Plugin 可以监听这些事件,根据需求在相应的时间点对打包内容进行定向的修改。
      class Plugin{
      // 注册插件时,会调用 apply 方法
      // apply 方法接收 compiler 对象
      // 通过 compiler 上提供的 Api,可以对事件进行监听,执行相应的操作
      apply(compiler){
      // compilation 是监听每次编译循环
      // 每次文件变化,都会生成新的 compilation 对象并触发该事件
        compiler.plugin('compilation',function(compilation) {})
      }
    }
    注册插件:
    // webpack.config.js
    module.export = {
    plugins:[
    new Plugin(options),
    ]
    }
    Compiler 全局唯一,且从启动生存到结束,它包含了当前 Webpack 中的所有配置信息,如 options, loaders, plugins 等信息,
    Compilation 对应每次编译,每轮编译循环均会重新创建,它包含了当前的输入资源,输出资源,变化的文件等,同时通过它提供的 api,可以监听每次编译过程中触发

    的事件钩子;

    常用 Plugin:
    1,UglifyJsPlugin :压缩、混淆代码
    2,CommonsChunkPlugin:代码分割
    3,ProvidePlugin:自动加载模块
    4,html-webpack-plugin:加载html,并且引入css/js文件
    5,extract-text-webpack-plugin/mini-css-extract-plugin ;抽离样式,生成css文件
    6,optimize-css-assets-webpack-plugin:css去重
    7,webpack-bundle-analyzer:代码分析
    8,compression-webpack-plugin:使用gzip压缩js和css
    9,happypack:使用多线程,加快代码构建
    10,EnvironmentPlugin:定义局部的变量
    编译优化:
    https://juejin.im/post/5bb8ef58f265da0a972e3434
    代码优化
    1,消除无用的代码
      例如:uglifyJs消除无用代码
    2,采用tree-shaking
      删除引用但未被使用的代码
      但是具有一些副作用(Uglify不做程序流的分析,但是rollup做了)
      存在一些副作用
      webbpack:不进行babel转义可以进行tree-shaking
      但是经过babel编译后,不能够treeShaking
      1,Webpack Tree shaking不会清除IIFE(立即调用函数表达式)
      2,如果使用第三方的模块,可以尝试直接从文件路径引用的方式使用(这并不是最佳的方式)
      import { fn } from 'module'; 
    => 
    import fn from 'module/XX';
    解决办法:
    1,我们可以设定使用loose: true来使得Babel在转化时使用宽松的模式
    2, 添加sideEffects标记
      //package.json
      {
        "sideEffects": false,
      }
    3,对函数外部变量产生影响的行为    
    3,code-spliting:代码分割
       1,按照页面分割:不同页面打包成不同的文件;
       2,按照功能进行分割:
         将类似于播放器,计算库等大模块进行拆分后再懒加载引入;
         提取复用的业务代码,减少冗余代码;
       3,按照修改频率进行分割
       将第三方库等不常修改的代码单独打包,而且不改变其文件 hash 值,能最大化运用浏览器的缓存;
    4,scope hoisting:作用域提升,
       将分散的模块划分到同一个作用域中,避免了代码的重复引入,有效减少打包后的代码体积和运行时的内存损耗;

     https://segmentfault.com/a/1190000012600832

    编译性能的优化
    1,升级最新webpack,能有效地提高编译性能
    2,使用 dev-server / 模块热替换 (HMR) 提升开发体验;
    监听文件变动 忽略 node_modules 目录能有效提高监听时的编译效率;
    3, 缩小编译范围:
    modules: 指定模块路径,减少递归搜索;
    mainFields: 指定入口文件描述字段,减少搜索;
    noParse: 避免对非模块化文件的加载;
    includes/exclude: 指定搜索范围/排除不必要的搜索范围;
    alias: 缓存目录,避免重复寻址;
    4,babel-loader:
    忽略node_moudles,避免编译第三方库中已经被编译过的代码;
    使用cacheDirectory,可以缓存编译结果,避免多次重复编译;
    5,多进程并发:
    HappyPack: 多进程并发文件的 Loader 解析;
    webpack-parallel-uglify-plugin: 可多进程并发压缩 js 文件,提高压缩速度;
    6,第三方库模块缓存:
    DLLPlugin 和 DLLReferencePlugin 可以提前进行打包并缓存,避免每次都重新编译;
    7,使用分析:
    Webpack Analyse / webpack-bundle-analyzer 对打包后的文件进行分析,寻找可优化的地方;
    配置profile:true,对各个编译阶段耗时进行监控,寻找耗时最多的地方;
  • 相关阅读:
    谷歌火狐浏览器限制的端口
    Web Api 内部数据思考 和 利用http缓存优化 Api
    Web Api 端点设计 与 Oauth
    FI-FBV0
    Others-SAP hybris 介绍
    ABAP-表修改日志存储
    TR-银行通信相关文档
    ABAP-Eclipse ADT中创建ABAP CDS视图
    TR-业务流程图
    FPM-OVP增强实例-银行账户
  • 原文地址:https://www.cnblogs.com/yayaxuping/p/10840334.html
Copyright © 2011-2022 走看看