webpack

115 阅读3分钟

本文记录自己在学习webpack的一些基础知识,包括webpack5的拆包与微前端 乾坤的学习

webpack概述及模块化

概述

描述:webpack 是一个模块打包器。它的主要目标是将 JavaScript 文件打包在一起,打包后的文件用于在浏览器中使用,但它也能够胜任转换(transform)、打包(bundle)或包裹(package)任何资源(resource or asset)。

那么提起模块化,串一下模块化的知识吧:

模块化的演进

graph LR
文件划分方式--> 命名空间方式--> IIFE-->IIFE依赖参数
文件划分:

缺陷:-

  • 模块直接在全局工作,大量模块成员污染全局作用域;
  • 没有私有空间,所有模块内的成员都可以在模块外部被访问或者修改;
  • 一旦模块增多,容易产生命名冲突;
  • 无法管理模块与模块之间的依赖关系;
  • 在维护的过程中也很难分辨每个成员所属的模块。
命名空间:

每个模块只暴露一个全局对象,所有模块成员都挂载到这个全局对象中,具体做法是在第一阶段的基础上,通过将每个模块“包裹”为一个全局对象的形式实现,这种方式就好像是为模块内的成员添加了“命名空间”,所以我们又称之为命名空间方式。解决一个命名冲突问题;

// module-b.js 
window.moduleB = { data: 'something' method1: function () { console.log('moduleB#method1') } }
IIFE:
// module-a.js 
;(function () { var name = 'module-a' function method1 () { console.log(name + '#method1') } window.moduleA = { method1: method1 } })()

这种方式带来了私有成员的概念,私有成员只能在模块成员内通过闭包的形式访问,这就解决了前面所提到的全局作用域污染和命名冲突的问题。

IIFE依赖参数:
// module-a.js 
;(function ($) { // 通过参数明显表明这个模块的依赖 
var name = 'module-a' 
function method1 () { console.log(name + '#method1') 
$('body').animate({ margin: '200px' }) 
} 
window.moduleA = { method1: method1 } })(jQuery)

在 IIFE 的基础之上,我们还可以利用 IIFE 参数作为依赖声明使用,这使得每一个模块之间的依赖关系变得更加明显。

模块化规范:

CommonJs

同步!!!CommonJS 规范,它是 Node.js 中所遵循的模块规范,该规范约定,一个文件就是一个模块,每个模块都有单独的作用域,通过 module.exports 导出成员,再通过 require 函数载入模块。

amd(Asynchronous Module Definition)

异步模块定义规范,require.js
通过define和require

提前执行,依赖前置

在 AMD 规范中约定每个模块通过 define() 函数定义,这个函数默认可以接收两个参数,第一个参数是一个数组,用于声明此模块的依赖项;第二个参数是一个函数,参数与前面的依赖项一一对应,每一项分别对应依赖项模块的导出成员,这个函数的作用就是为当前模块提供一个私有空间。如果在当前模块中需要向外部导出成员,可以通过 return 的方式实现。

image.png

image.png

cmd

淘宝的sea.js
延迟执行,依赖就近 as lazy as possible

和amd区别就是依赖的执行时机

es6 import export

语法糖 啊 wip。。。

webpack简单看看

打包原理

loader

Webpack 是用 Loader(加载器)来处理每个模块的,而内部默认的 Loader 只能处理 JS 模块,如果需要加载其他类型的模块就需要配置不同的 Loader。这也就引出了我们今天的主角:Loader。

image.png

css loader:

css-loader 的作用是将 CSS 模块转换为一个 JS 模块,具体的实现方法是将我们的 CSS 代码 push 到一个数组中

style-loader:

plugin(tapeble)

webpack5及微前端的应用