zoukankan      html  css  js  c++  java
  • webpack打包理解

    webpack打包理解(将所有依赖文件打包到一个文件中)

    由于前端代码变得越来越多,越来越复杂, 纯粹脚本化的代码书写方式已经不能满足工程化得需求。

    前端模块被抽象出来, 不仅仅包括js模块, 其它如css都算作一个模块。

    将这些模块打包到同一个js文件中,就叫webpack打包。

    打包原理

    https://www.jianshu.com/p/e24ed38d89fd

    webpack只是一个打包模块的机制,只是把依赖的模块转化成可以代表这些包的静态文件。并不是什么commonjs或者amd之类的模块化规范。webpack就是识别你的 入口文件。识别你的模块依赖,来打包你的代码。至于你的代码使用的是commonjs还是amd或者es6的import。webpack都会对其进行分析。来获取代码的依赖。webpack做的就是分析代码。转换代码,编译代码,输出代码。

    如下,会将 a和b打包到bundle.js文件中,因为a依赖b, a是入库文件。

    // webpack.config.js
    module.exports = {
      entry:'./a.js',
      output:{
        filename:'bundle.js'
      }
    };
    
    // a.js
    var b = require('./b.js');
    
    console.log('a');
    
    b.b1();
    
    // b.js
    exports.b1 = function () {
      console.log('b1')
    };
    
    exports.b2 = function () {
      console.log('b2')
    };


    https://cnodejs.org/topic/5867bb575eac96bb04d3e301

    打包中的文件管理

    重点来了: webpack是如何进行资源的打包的呢?

    总结:

    • 每个文件都是一个资源,可以用require导入js
    • 每个入口文件会把自己所依赖(即require)的资源全部打包在一起,一个资源多次引用的话,只会打包一份
    • 对于多个入口的情况,其实就是分别独立的执行单个入口情况,每个入口文件不相干(可用CommonsChunkPlugin优化)

    变量作为依赖模块情况

    https://stackoverflow.com/questions/37241662/using-require-with-a-variable-vs-using-a-string-in-webpack

    let appleIcons = _.map(appleIcons, appleIcon => {
      appleIcon.href = require(appleIcon.href);
      return appleIcon;
    }); 
    

    Inside of the loop I want to require the image but it throws an error ".*$:11 Uncaught Error: Cannot find module".

    从第一部分, 打包原理我们知道, webpack是对代码做静态解析, 并不去运行代码, 只做语法解析。

    如果 require的参数一个常量字符串, 则可以明确定位依赖模块。 例如 require("b.js")

    但是在代码逻辑组织上, 往往会出现require的参数为变量的情况,如上面那个情况。

    对于这种情况webpack有自己的打包规则, 以保证打包后的代码, 满足运行代码依赖需求。

    解法

    https://segmentfault.com/a/1190000015648036

    于是我查看了官方文档,发现有一个黄条提示。

    clipboard.png

    emmm,看来问题出在这里了。

    这个现象其实是与webpack import()的实现高度相关的。由于webpack需要将所有import()的模块都进行单独打包,所以在工程打包阶段,webpack会进行依赖收集。

    此时,webpack会找到所有import()的调用,将传入的参数处理成一个正则,如:

    import('./app'+path+'/util') => /^./app.*/util$/
    

    也就是说,import参数中的所有变量,都会被替换为【.*】,而webpack就根据这个正则,查找所有符合条件的包,将其作为package进行打包。

    clipboard.png

    因此,如果我们直接传入一个变量,webpack就会把 (整个电脑的包都打包进来[不闹]) 认为你在逗他,并且抛出一个WARNING: Critical dependency: the request of a dependency is an expression。

    所以import的正确姿势,应该是尽可能静态化表达包所处的路径,最小化变量控制的区域

    如我们要引用一堆页面组件,可以使用import('./pages/'+ComponentName),这样就可以实现引用的封装,同时也避免打包多余的内容。

    官方说明

    https://webpack.js.org/guides/dependency-management/#require-context

    require with expression

    A context is created if your request contains expressions, so the exact module is not known on compile time.

    Example:

    require('./template/' + name + '.ejs');
    

    webpack parses the require() call and extracts some information:

    Directory: ./template
    Regular expression: /^.*.ejs$/
    

    context module

    A context module is generated. It contains references to all modules in that directory that can be required with a request matching the regular expression. The context module contains a map which translates requests to module ids.

    Example:

    {
      "./table.ejs": 42,
      "./table-row.ejs": 43,
      "./directory/folder.ejs": 44
    }
    

    The context module also contains some runtime logic to access the map.

    This means dynamic requires are supported but will cause all possible modules to be included in the bundle.

  • 相关阅读:
    发布google在线翻译程序(附源码)
    基于MVP架构设计ASP.Net的应用研究
    发布最新C#3.5开发的ReSharper4.0 for VS2005/2008 注册机
    基于元数据驱动模型架构在ASP.Net的应用研究
    Silverlight整合Asp.net AjAX的技术应用
    在WCF中的异常处理方法
    Windows Server 2008 的十四大最新功能特性技术总结
    微软Asp.Net架构与项目团队管理建设模型分析
    在Biztalk应用中调用程序集的方法
    Visual Studio 2008和ASP.NET 3.5的最新技术探索
  • 原文地址:https://www.cnblogs.com/lightsong/p/10269800.html
Copyright © 2011-2022 走看看