likes
comments
collection
share

深入浅出webpack系列解读(1)

作者站长头像
站长
· 阅读数 64

相信从事前端开发的小伙伴们一定听过webpack,但是很多人对webpack的认知仅仅停留在npm run build然后出一个dist文件夹,而并不了解webpack实际上大有所为

面试官问你了解webpack的啥,你大概也只能说出一二就草草了之( Ꙭ)

这一系列的文章就带你来领略webpack之美、之博大精深,我会尽可能地用简洁精炼的语言来总结webpack的学习重点,大家可以放心食用~

先放一个目录,这一个系列大概会总结下来的几个部分

遵循的认知学习模式是,从 应用理解 再到 造轮子

入门 重在教你如何使用webpack

配置 在框架中的实战应用、构建离线应用、加载图片SVG等

优化 缩小文件的搜索范围、自动刷新、开启模块热更新、使用Tree Shaking等

原理 编写Loader、Plugin、调试webpack等

好啦,接下来那就让我们来开启webpack的大门吧~

模块化

在认识webpack之前,我们需要了解一个很重要的概念模块化

模块化是指将一个复杂的系统分解为多个模块以方便编码

就好比我们面临一个巨大的仓库,里面存放了各种各样的物品,各物品之间相互关联,而我们如果不借助任何工具整理起来会很困难,但此时我们如果将物品分成一个个模块来整理,就会轻松很多

然而我们还需要了解的是,在不同的环境下,我们需要用到的模块化标准不同

CommonJS

node.js中采用的就是这种规范,写过node的同学应该都知道

核心思想:

通过require方法来同步加载依赖的其他模块,通过module.exports导出需要暴露的接口

采用CommonJS导入及导出的代码如下:

//导入
const moduleA = require('./moduleA');
//导出
module.exports = moduleA.someFunc;

CommonJS的优点

  • 代码可复用性高

  • 基于node.js环境下运行

  • 通过npm发布的很多第三方模块都采用了这个规范

CommonJS的缺点

CommonJS的缺点主要在于,这样的代码无法直接在浏览器环境下运行,必须通过工具转换成标准的ES5

AMD

AMD规范和CommonJS最大的不同就是,它采用了异步的方式去加载依赖的模块

// 定义一个模块
define('module', ['dep'], function (dep) {
    return exports;
});
//导入和使用
require(['module'], function (module) {
});

这种javascript模块化规范可以直接在浏览器中运行,还可以并行加载多个依赖,不过需要导入像requirejs这样的库之后才可以正常使用

ES6模块化

从ES6 开始,JavaScript 原生引入了模块概念,而且现在主流浏览器也都有了很好的支持,而在ES6模块化中,一个文件就是模块,拥有独立的作用域,且导出的模块都自动处于 严格模式下,即:'use strict'

导入分为两种模式

  • 静态导入
  • 动态导入
静态导入

在浏览器中,import 语句只能在声明了 type="module" 的 script 的标签中使用。

import defaultExport from "module-name";
import * as name from "module-name";
import { export } from "module-name";
import { export as alias } from "module-name";
import { export1 , export2 } from "module-name";
import { foo , bar } from "module-name/path/to/specific/un-exported/file";
import { export1 , export2 as alias2 , [...] } from "module-name";
import defaultExport, { export [ , [...] ] } from "module-name";
import defaultExport, * as name from "module-name";
import "module-name";

静态导入方式不支持延迟加载,import 必须这模块的最开始

document.onclick = function () {

    // import 必须放置在当前模块最开始加载
    // import m1 from './m1.js'

    // console.log(m1);

}
动态导入

此外,还有一个类似函数的动态 import(),它不需要依赖 type="module" 的 script 标签。

关键字 import 可以像调用函数一样来动态的导入模块。以这种方式调用,将返回一个 promise

import('./m.js')
  .then(m => {
    //...
});
// 也支持 await
let m = await import('./m.js');

通过 import() 方法导入返回的数据会被包装在一个对象中,即使是 default 也是如此

构建内核

如今前端生态已经越来越复杂多样,各种框架技术层出不穷,但源代码都不能直接运行,必须通过转换后才可以正常运行,比如vue的语法,其实是不能直接拿到浏览器里面去运行的,浏览器能识别的代码只有html、css和js

所以我们不难理解,所谓构建做的就是这样一件事情,将源代码转换成可执行的html、css和javascript代码,具体包括以下几个内容:

  1. 代码转换:将TS编译成js、将scss编译成css等

  2. 文件优化:压缩js、css、html代码、压缩合并图片

  3. 代码分割:提取多个页面的公共代码,提取首屏不需要执行部分的代码让其异步加载

  4. 模块合并:在采用模块化的项目里会有很多个模块和文件,需要通过构建功能将模块分类合并成一个文件(就像我前面举的仓库整理的栗子)

  5. 自动刷新:在代码被提交到仓库前需要校验代码是否符合规范,以及单元测试是否通过

  6. 自动发布:更新代码后,自动构建出线上发布代码并传输给发布系统

构建为前端注入了更大的活力,解放了我们的生产力,看到这里,大家应该已经意识到webpack做的事情远比我们想象的多得多

其实过去包括现在,有许许多多这样的构建工具,gulp、grunt等等包括现在起来的vite,但webpack还是目前为止难以打败的神作,所以我们学习它只能说稳赚不亏~(˶‾᷄ꈊ‾᷅˵)~

初识webpack

官网的描述是这样的webpack 是一个用于现代 JavaScript 应用程序的 静态模块打包工具

在webpack中一切文件皆是模块,当然包括图片文件、文本文件等等,然后通过loader转换文件,通过plugin注入钩子,最后输出多个由模块组合成的文件

初来的小伙伴们现在可能还不理解什么是loader和plugin,没关系后面我会有详细的介绍和总结,大家先在这里留个心眼,这俩是webpack中很重要的组成部分

loader就是比如说,现在有一个文本文件txt,但导入模块的时候,只能识别js,那么要怎么把文本文件转换成能识别的js文件呢,这时候就需要用到loader了

而plugin负责解决loader无法解决的问题,是一个功能更强大、灵活度更高的工具

我们来看看webpack有什么优点

  • 专注于处理模块化项目,能做到开箱即用、一步到位

  • 可以通过plugin扩展,完整好用又不失灵活

  • 使用场景不局限于web开发

  • 爽翻天的开发体验

  • ……

哈哈,我只能说对webpack赞不绝口ʕु•̫͡•ʔु ✧

安装webpack

首先确保你的电脑安装了v5.0.0以上的Node.js

在开始为项目加入构建前,需要新建一个web项目,有如下方式:

  • 新建一个目录,再进入项目根目录执行npm init来初始化最简单的采用了模块化开发的项目
  • 用脚手架工具直接/快速生成一个最符合自己需求的项目(比如vue-cli)

安装webpack到本项目

第一步

npm i -Dnpm install --sava-dev的缩写

或者我们在拉取了他人的项目之后习以为常的npm install操作,即安装模块并保存到package.json的devDependencies

第二步

安装最新的稳定版本npm i -D webpack

安装webpack到全局

执行命令npm i -g webpack,安装到全局之后,我们可以在任何项目共用一个webpack可执行文件,但还是推荐大家安装webpack到局部,因为不同项目之间的依赖版本可能存在差异,避免引起不必要的报错

最后,整理的部分知识小节送给大家~

深入浅出webpack系列解读(1)

后期会持续输出webpack系列文章,欢迎大家点赞关注~ฅ՞•ﻌ•՞ฅ

我是dazzlingwen,热爱前端的小小白,期待也和我同样热爱前端的小伙伴们一起进步、一起成长~

转载自:https://juejin.cn/post/7140265534574034958
评论
请登录