说明:根据B站学习视频 :【2020新课程】Webpack从原理到实战完整版-深入浅出,简单易学,前端工程师必学经典内容 学习整理,如有错误,欢迎随时指正,互相学习。
文章转自:https
文章目录
什么是webpack
一个现代JavaScript应用程序的静态模块打包器
默认:只对js进行处理,其他类型文件需要配置loader或者插件进行处理。
打包:将各个依赖文件进行梳理打包,形成一个JS依赖文件
为什么需要打包
随着前端项目的复杂化,依赖文件的关系难以梳理,耦合程度较高,代码难以维护。急需专门的工具对代码进行管理,另外把所有依赖包都打包成为一个js文件(bundle.js)文件,会有效降低文件请求次数,一定程度提升性能。
作用域
作用域定义 运行时变量、函数、对象可访问性,它决定了代码中变量和其他资源的可见性
全局作用域
var a = 1;
window.a; // 1
global.a; // 1
局部作用域
function a(){
var v = 1;
}
window.v; // undefine
变量冲突
如果在传统js写法中,引入多个script,就很容易造成全局作用域冲突而导致不可预测的问题。如下如果 三个js中都定义了a变量那么必然辉出现问题(这是打包工具解决的问题之一)
<body>
<script scr="./moduleA.js"></sciprt>
<script scr="./moduleB.js"></sciprt>
<script scr="./moduleC.js"></sciprt>
</body>
变量冲突解决方案
解决方式1:使用变量作用域形成局部作用域,通过一个js对象封装作用域
// 定义模块内的局部作用域,以moduleA为例
var Susan = {
name: “susan”,
sex: “female”,
tell: function(){
console.log(“im susan”)
}
}
该方式无法保护作用域内部变量的安全性,作用域内的变量如 上述的name 被修改后,影响模块的功能
什么是立即执行函数?就是函数定义完立即被调用。可以点击这里进行参考。
什么是自由变量?简单来说是跨作用域的变量,可以点击进行这里参考。(里面有一个句很好的知识点:创建这个函数的时候,这个函数的作用域就已经决定了,而是不是在调用的时候)
代码参考如下:
写法1
// 定义模块内的闭包作用域(模块作用域)
var SusanModule = (function(){
var Susan = {
// 自由变量
name: "susan",
// 自由变量
sex: "female",
// 只允许访问tell方法,不能访问和修改其他属性
return {
tell: function(){
console.log("im susan")
}
}
})()
写法2
// 定义模块内的闭包作用域(模块作用域)
(function(window){
var name = "susan"
var sex = "female"
functioon tell(){
console.log("im ", this.name)
}
window.susanModule = {tell}
})(window)// window作为参数传给
如此通过作用域解进行模块化开发,决了变量冲突问题。
模块化方案发展
模块化开发可以降低耦合,增加代码重用性,随着技术发展,出现过很多模块化方案,如:AMD、COMMOnjs、ES6MODULE
AMD
Asynchronous Module DeFinition(异步模块定义)目前很少使用,通过define函数来定义模块,
// 求和模块
define("getSum", ["math"], funtion(math){//参数分别为 模块id,依赖模块,模块立即执行方法
return function (a,b){
log("sum:"+ math.sum(a, b))
}
})
COMMOnjs
2009年出的规范,后来nodejs采用commonjs模块化规范
// 通过require函数来引用
const math = require("./math");
// 通过exports将其导出
exports.getSum = function(a,b){
return a + b;
}
ES6MODULE
目前用的最多的就是这个
// 通过import函数来引用
import math from "./math";
// 通过export将其导出
export function sum(a, b){
return a + b;
}
webpack打包机制
经过以上发展,webpack 应运而生,它将所有文件打包成一个文件。输出文件的大致结构如下:
(function(module) {
var installedModules = {};
function __webpack_require__(moduleId){
// SOME CODE
}
// 。。。
return __webpack_require__(0); // entry file
})([ /* modules array */])
//核心方法
function __webpack_require__(moduleId){
// check if module is in cache
if(installedModules[moduleId]){
return installedModules[moduleId].exports;
}
// create a new module (and put into cache)
var module = installedModules[moduleId] = {
i: moduleId,
l: false,
exports: {}
};
// exe the module func
modules[moduleId].call{
module.exports,
module,
module.exports,
__webpack_require__
};
// flag the module as loaded
module.l = true;
// return the exxports of the module
return module.exports;
}
webpack打包机制
- 从入口文件开始,分析整个应用的依赖树
- 将每个依赖模块包装起来,放到一个数组中等待调用
- 实现模块加载的方法,并把它放到模块执行的环境中,确保模块间可以互相调用
- 把执行入口文件的逻辑放在一个函数表达式中,并立即执行这个函数
常用的webpack plugins
babel
作用: 将高版本语法ES6转换为低版本语法
使用方法(直接编译):babel -index.js --presets=@babel preset-env
使用方法一:package.json中,加入babel配置参数
"babel": {
"presets" : ["@babel/preset-env"]
}
使用方法二:在package.json文件同目录下,设置.babelrc文件里面配置同方法一
html-webpack-plugin
作用:
为html文件中引入的外部资源如script、link动态添加每次compile后的hash,防止引用缓存的外部文件问题
可以生成创建html入口文件,比如单页面可以生成一个html文件入口,配置N个html-webpack-plugin可以生成N个页面入口
webpack HRM 模块热更新
不需要刷新浏览器的情况下更新dom
使用方法:plugin中加入:webpack.HotModuleReplacementPlugin()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。