webpack系列(一) -- 前提引入

192 阅读1分钟

介绍

本系列将会对webpack部分进行总结归纳

本章将会介绍

  • 在老前端时代前端项目是什么样的
  • 为解决原生开发问题二提出的方案
  • 为什么要用webpack

1. 老代码

对于原生写法,就是一个html页面。将各种js堆在最下面一把梭

img

需要关注的点:

  • 所有外部引入的包都绑定到全局的 window 对象上,如 jquery的window.$ 或 lodash的 window._
  • script 加载是从上到下的,因此需要将依赖的 script 放在上面先加载,否则会出现找不到的情况
  • 所有的 script 都被加载在全局,就会导致全局变量被覆盖错乱的情况,完全不可控。时常会出现,不知道啥时候 哪个文件 哪里出了问题。

有时也有人把所有js写在一个文件中,也会出现上面的问题,就引出了应该如何解决作用域混乱的问题

2. 作用域问题

使用IIFE(Immediately-invoked Function Expression),立即执行函数 来看个例子

// 在以前面试的时候作用域/闭包配上变量提升的题着实刷吐
// 看看这个简单题输出的是什么
​
(() => {
    const name = 'cc123nice';
    console.log(name);
})();
​
console.log(name);
​
// 最后一行的name实际上就是 window.name

由此可以看出,对于引用js文件全都写成自执行函数, 函数作用域内的变量不会对外(window)影响,就避免了我们上面说到的作用域问题了。但这就是我们的银弹了吗?

往往一个js文件会相互引用值,引来引去,对于自执行函数来说需要引用相关值都需要写入在一个文件中,若使用这种方式维护,那么恭喜你~新的万行屎山将在你的手中诞生!

为避免文件过长,因此 我们需要看看如何将 文件进行拆分

3. 文件拆分

3.1 CommonJS模块

模块化 commonJSnode 推出的 require方法

// utils.js
const add = (a, b) => a + b;
const multiply = (a, b) => a * b;
​
module.exports = {
    add,
    multiply
}
​
// my.js
const {multiply} = require('./utils');
console.log(multiply(2,3))

使用node运行能正常输出(毕竟是node产出的),在浏览器运行时就会出现错误,因为浏览器不支持!

3.2 AMD模块

用require.js实现AMD规范的模块化

// add.js
const add = (a, b) => a + b;
define([], () => add);
​
// main.js
require(["jquery","underscore", "./add.js"], ($, _, add) => {
  // 对应操作
});
​
// html中引入
<script
  src="https://cdn.bootcdn.net/ajax/libs/require.js/2.3.6/require.min.js" 
  data-main="./2.js"
></script>

很好理解

  • 通过 define 导出方法
  • 借用 require 引入。第一项的列表是引入的地址,第二项回调函数是对应的对象。

还有CMD模块,有兴趣可以去了解。但用这种形式写代码时还是会有心智负担,来看看ESM模块

3.3 ES6 module

使用es6模块形式导入导出是目前最常用的

相信在很多代码库中都会发现 esm 文件夹,其实就是这个的缩写

// add.js
const add = (a, b) => a + b;
export {add};
​
// html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script type="module">
        import {add} from "./1.js";
        console.log(add(1,2));
    </script>
</body>
</html>

若不给 script 指定 type="module" 会出现这个报错

image-20220416170733600

但若是直接打开html文件会报另一个错,是因为需要启动服务才能运行,这边推荐使用 anywhere 这个库随心所欲起服务。

image-20220416171548992

相信大家对比使用下来 esm 使用起来是最方便实用的。

但对于一个文件中有多个引入时肯定会出现引用顺序的问题,要一个人去人为去管理注意在大项目中是很难做到的,更别提交接了~那么有什么好方法去避免出现这种情况呢?这是就要拿出我们的主角 webpack 了。