Webpack 如何解决作用域问题

1,020 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情

如何解决作用域问题

那我们究竟该如何解决作业问题呢?

早期,我们使用的是 grunt 以及 gulp 这两个工具来管理我们的项目资源,这两个工具我们称之为任务执行器。

它们是将所有的项目文件拼接在一起,其实事实上是利用了 JS 的立即调用函数表达式,英文 Immediately invoke function expressions,简称 IIFE。这样就解决了大型项目的作用问题

当脚本被封装在 IIFE 内部的时候,我们可以安全的拼接或者是组合所有的文件了,而不必担心作用冲突。

什么是 IIFE 呢?我们用代码来演示一下。在当前文件夹的根目录新建一个 index-03.html 文件,并且在该文件中引用一个 index-03.js 文件。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script src="./index-03.js"></script>
</body>
</html>

在 index-03.js 文件里使用 function 定义立即调用的函数表达式。

;(function(){
    var myName="麦兜编程";
}())


console.log(myName)

在浏览器访问 html 文件所在路径。

image.png

可以看到,在浏览器的控制台上输出“myName is not defined”错误,说明我们这个 myName 是不能访问的。

那就说明当函数变成了一个立即调动的表达式的时候,表达式的变量是不能够在外部访问的,也就是说它不会污染我们的 window 环境,也就解决了作用问题。

但你可能会说,我们如果是想在 window上面去暴露一个变量,或者我们写一大段代码,但是有暴露的内容该怎么办呢?

我们把一个立即调用的函数表达式赋给一个变量,同时将函数体里的变量给暴露,供外部访问。

var result=(function(){
    var myName="麦兜编程"
    return myName
})()


console.log(result)

可以看到,浏览器控制输出“麦兜编程”。

image.png

这样实现方式,既解决了作用域的问题,又可以在外部去暴露我们想暴露的内容。

介绍到这里,我们知道 gulp 和 grunt 是采用这种方式解决了作用问题,但是大家现在来思考一个问题,如果我们想要去修改两文件中的一段代码,我们得需要重新编译这段代码。

我们再思考一下,假如我们这个代码有 1 万行,但是我们只改了一行,那么这个文件也要重新编译,或者这个文件也会被同时的加载。

给大家举个例子,我们在当前目录下面创建一个新的 index-04.html 文件,在该文件中引入 lodash.js 库,并且在 JS 中调用 lodash 提供给我们的“_”对象中 _.join() 方法,该方法可以把数组中任何字符串通过某个符给拼接起来,join 方法中有两个参数,第一个参数是数组,第二参数是拼接的连接符,比如“-”。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.js"></script>
</head>
<body>
    <script>
        const srt= _.join(['麦兜编程','Webpack 全面学习指南'],'-')
        console.log(srt)
    </script>
</body>
</html>

在浏览器访问 index-04.html 路径,在浏览器的控制输出 “麦兜编程-Webpack 全面学习指南”。

image.png

我们思考一个问题,现在我们为了使用 lodash 库中的一个 join 方法,我们却把整个 lodash 的库文件全都下载下来。

通过浏览器打开 lodash 文件,发现该文件非常的庞大,那就意味着我们为了使用 lodash 库中的一个方法,就要把整个的文件都需要下载下来。

那么我们能不能想一个办法,把这个文件给拆成一个一个方法模块或者我们来实现一个方法的懒加载?答案是肯定能。

如果是我们通过手工的方法来实现,那工作量可就非常大。那么我们又该如何实现呢?