Webpack笔记

Webpack笔记

模块化

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

当项目变大时这种方式将变得难以维护,需要用模块化的思想来组织代码。

CommonJS

CommonJS 是一种使用广泛的 JavaScript 模块化规范

核心思想:

  1. 是通过 require 方法来同步地加载依赖的其他模块
  2. 通过 module.exports 导出需要暴露的接口。
/ 导入
const moduleA = require('./moduleA');

// 导出
module.exports = moduleA.someFunc;

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

AMD

AMD 也是一种 JavaScript 模块化规范,与 CommonJS 最大的不同在于它采用异步的方式去加载依赖的模块。 AMD 规范主要是为了解决针对浏览器环境的模块化问题,最具代表性的实现是 requirejs

// 定义一个模块
define('module', ['dep'], function(dep) {
  return exports;
});

// 导入和使用
require(['module'], function(module) {
});

AMD 的优点在于:

  • 可在不转换代码的情况下直接在浏览器中运行;
  • 可异步加载依赖;
  • 可并行加载多个依赖;
  • 代码可运行在浏览器环境和 Node.js 环境下。

AMD 的缺点在于JavaScript 运行环境没有原生支持 AMD,需要先导入实现了 AMD 的库后才能正常使用。

ES6 模块化

它将逐渐取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。

// 导入
import { readFile } from 'fs';
import React from 'react';
// 导出
export function hello() {};
export default {
  // ...
};

ES6模块虽然是终极模块化方案,但它的缺点在于目前无法直接运行在大部分 JavaScript 运行环境下,必须通过工具转换成标准的 ES5 后才能正常运行。

常见的构建工具及对比

构建就是做这件事情,把源代码转换成发布到线上的可执行 JavaScrip、CSS、HTML 代码,包括如下内容。

  • 代码转换:TypeScript 编译成 JavaScript、SCSS 编译成 CSS 等。
  • 文件优化:压缩 JavaScript、CSS、HTML 代码,压缩合并图片等。
  • 代码分割:提取多个页面的公共代码、提取首屏不需要执行部分的代码让其异步加载。
  • 模块合并:在采用模块化的项目里会有很多个模块和文件,需要构建功能把模块分类合并成一个文件。
  • 自动刷新:监听本地源代码的变化,自动重新构建、刷新浏览器。
  • 代码校验:在代码被提交到仓库前需要校验代码是否符合规范,以及单元测试是否通过。
  • 自动发布:更新完代码后,自动构建出线上发布代码并传输给发布系统。

构建其实是工程化、自动化思想在前端开发中的体现,把一系列流程用代码去实现,让代码自动化地执行这一系列复杂的流程。 构建给前端开发注入了更大的活力,解放了我们的生产力。

Npm Script

Npm Script 是一个任务执行者。Npm 是在安装 Node.js 时附带的包管理器,Npm Script 则是 Npm 内置的一个功能,允许在 package.json 文件里面使用 scripts 字段定义任务:

{
  "scripts": {
    "dev": "node dev.js",
    "pub": "node build.js"
  }
}

里面的 scripts 字段是一个对象,每个属性对应一段 Shell 脚本,以上代码定义了两个任务 devpub。 其底层实现原理是通过调用 Shell 去运行脚本命令,例如执行 npm run pub 命令等同于执行命令 node build.js

Npm Script的优点是内置,无须安装其他依赖。其缺点是功能太简单,虽然提供了 prepost 两个钩子,但不能方便地管理多个任务之间的依赖。

Gulp

Gulp 是一个基于流的自动化构建工具。 除了可以管理和执行任务,还支持监听文件、读写文件。Gulp 被设计得非常简单,只通过下面5个方法就可以胜任几乎所有构建场景:

  • 通过 gulp.task 注册一个任务;
  • 通过 gulp.run 执行任务;
  • 通过 gulp.watch 监听文件变化;
  • 通过 gulp.src 读取文件;
  • 通过 gulp.dest 写文件。

Gulp 的最大特点是引入了流的概念,同时提供了一系列常用的插件去处理流,流可以在插件之间传递,大致使用如下:

// 引入 Gulp
var gulp = require('gulp'); 
// 引入插件
var jshint = require('gulp-jshint');
var sass = require('gulp-sass');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');

// 编译 SCSS 任务
gulp.task('sass', function() {
  // 读取文件通过管道喂给插件
  gulp.src('./scss/*.scss')
    // SCSS 插件把 scss 文件编译成 CSS 文件
    .pipe(sass())
    // 输出文件
    .pipe(gulp.dest('./css'));
});

// 合并压缩 JS
gulp.task('scripts', function() {
  gulp.src('./js/*.js')
    .pipe(concat('all.js'))
    .pipe(uglify())
    .pipe(gulp.dest('./dist'));
});

// 监听文件变化
gulp.task('watch', function(){
  // 当 scss 文件被编辑时执行 SCSS 任务
  gulp.watch('./scss/*.scss', ['sass']);
  gulp.watch('./js/*.js', ['scripts']);    
});

Gulp 的优点是好用又不失灵活,既可以单独完成构建也可以和其它工具搭配使用。其缺点是和 Grunt 类似,集成度不高,要写很多配置后才可以用,无法做到开箱即用。

Webpack

Webpack 是一个打包模块化 JavaScript 的工具,在 Webpack 里一切文件皆模块,通过 Loader 转换文件,通过 Plugin 注入钩子,最后输出由多个模块组合成的文件。Webpack 专注于构建模块化项目。

一切文件:JavaScript、CSS、SCSS、图片、模板,在 Webpack 眼中都是一个个模块,这样的好处是能清晰的描述出各个模块之间的依赖关系,以方便 Webpack 对模块进行组合和打包。 经过 Webpack 的处理,最终会输出浏览器能使用的静态资源。

Rollup

Rollup 是一个和 Webpack 很类似但专注于 ES6 的模块打包工具。 Rollup 的亮点在于能针对 ES6 源码进行 Tree Shaking 以去除那些已被定义但没被使用的代码,以及 Scope Hoisting 以减小输出文件大小提升运行性能。 然而 Rollup 的这些亮点随后就被 Webpack 模仿和实现。 由于 Rollup 的使用和 Webpack 差不多,这里就不详细介绍如何使用了,而是详细说明它们的差别:

  • Rollup 是在 Webpack 流行后出现的替代品;
  • Rollup 生态链还不完善,体验不如 Webpack;
  • Rollup 功能不如 Webpack 完善,但其配置和使用更加简单;
  • Rollup 不支持 Code Spliting,但好处是打包出来的代码中没有 Webpack 那段模块的加载、执行和缓存的代码。

Rollup 在用于打包 JavaScript 库时比 Webpack 更加有优势,因为其打包出来的代码更小更快。 但功能不够完善,很多场景都找不到现成的解决方案。

安装 Webpack

在用 Webpack 执行构建任务时需要通过 webpack 可执行文件去启动构建任务,所以需要安装 webpack 可执行文件。

在开始给项目加入构建前,你需要先新建一个 Web 项目,方式包括:

  • 新建一个目录,再进入项目根目录执行 npm init 来初始化最简单的采用了模块化开发的项目;

推荐安装到本项目,原因是可防止不同项目依赖不同版本的 Webpack 而导致冲突。

要安装 Webpack 到本项目,可按照你的需要选择以下任意命令运行:

# npm i -D 是 npm install --save-dev 的简写,是指安装模块并保存到 package.json 的 devDependencies
# 安装最新稳定版
npm i -D webpack

# 安装指定版本
npm i -D webpack@<version>

# 安装最新体验版本
npm i -D webpack@beta
或者
yarn add webpack --dev

安装完后你可以通过这些途径运行安装到本项目的 Webpack:

  • 在项目根目录下对应的命令行里通过 node_modules/.bin/webpack 运行 Webpack 可执行文件。

  • Npm Script 里定义的任务会优先使用本项目下的 Webpack,代码如下:

    "scripts": {
        "start": "webpack --config webpack.config.js"
    }
    

Webpack 在执行构建时默认会从项目根目录下的 webpack.config.js 文件读取配置,所以你需要新建它

const path = require('path');

module.exports = {
  // JavaScript 执行入口文件
  entry: './main.js',
  output: {
    // 把所有依赖的模块合并输出到一个 bundle.js 文件
    filename: 'bundle.js',
    // 输出文件都放到 dist 目录下
    path: path.resolve(__dirname, './dist'),
  }
};

在项目根目录下执行 webpack 命令运行 Webpack 构建,你会发现目录下多出一个 dist 目录,里面有个 bundle.js 文件, bundle.js 文件是一个可执行的 JavaScript 文件

核心概念

  • Entry:入口,Webpack 执行构建的第一步将从 Entry 开始,可抽象成输入。
  • Module:模块,在 Webpack 里一切皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。
  • Chunk:代码块,一个 Chunk 由多个模块组合而成,用于代码合并与分割。
  • Loader:模块转换器,用于把模块原内容按照需求转换成新内容。
  • Plugin:扩展插件,在 Webpack 构建流程中的特定时机注入扩展逻辑来改变构建结果或做你想要的事情。
  • Output:输出结果,在 Webpack 经过一系列处理并得出最终想要的代码后输出结果。

ebpack 启动后会从 Entry 里配置的 Module 开始递归解析 Entry 依赖的所有 Module。 每找到一个 Module, 就会根据配置的 Loader 去找出对应的转换规则,对 Module 进行转换后,再解析出当前 Module 依赖的 Module。 这些模块会以 Entry 为单位进行分组,一个 Entry 和其所有依赖的 Module 被分到一个组也就是一个 Chunk。最后 Webpack 会把所有 Chunk 转换成文件输出。 在整个流程中 Webpack 会在恰当的时机执行 Plugin 里定义的逻辑。

path常见的API

  • 从路径中获取信息

    • dirname:获取文件的父文件夹;
    • basename:获取文件名;
    • extname:获取文件扩展名;
  • 路径的拼接:path.join

  • 拼接绝对路径:path.resolve

    • path.resolve() 方法会把一个路径或路径片段的序列解析为一个绝对路径;
    • 给定的路径的序列是从右往左被处理的,后面每个 path 被依次解析,直到构造完成一个绝对路径;

Webpack的作用

  • JavaScript的打包:
    • 将ES6转换成ES5的语法;
    • TypeScript的处理,将其转换成JavaScript;
  • Css的处理:
    • CSS文件模块的加载、提取;
    • Less、Sass等预处理器的处理;
  • 资源文件img、font:
    • 图片img文件的加载;
    • 字体font文件的加载;
  • HTML资源的处理:
    • 打包HTML资源文件;
  • 处理vue项目的SFC文件.vue文件;

webpack核心概念

  • entry: 入口模块文件路径
  • output: 输出bundle文件路径
  • module: 模块,webpack构建对象
  • bundle: 输出文件,webpack构建产物
  • chunk: 中间文件,webpack构建的中间产物
  • loader: 文件转换器
  • plugin: 插件,执行特定任务
npm install webpack webpack-cli –g # 全局安装
npm install webpack webpack-cli –D # 局部安装
  • 执行webpack命令,会执行node_modules下的.bin目录下的webpack;
  • webpack在执行时是依赖webpack-cli的,如果没有安装就会报错;
  • 而webpack-cli中代码执行时,才是真正利用webpack进行编译和打包的过程;
  • 所以在安装webpack时,我们需要同时安装webpack-cli

局部构建步骤

  1. 第一步:创建package.json文件,用于管理项目的信息、库依赖等
    • npm init
  2. 第二步:安装局部的webpack
    • npm install webpack webpack-cli -D
  3. 第三步:使用局部的webpack
    • npx webpack
  4. 第四步:在package.json中创建scripts脚本,执行脚本打包即可
    • npm run build

image-20220814014540704

Webpack配置文件

webpack有一个默认的配置文件webpack.config.js,这个文件需要手动的创建,位于项目根目录中。

webpack的配置文件会暴露出一个对象,格式如下:

   module.exports = {
      //配置项
    }

常用配置项将要说明

  • entry:打包的入口文件,一个字符串或者一个对象
  • output:配置打包的结果,一个对象
  • fileName:定义输出文件名,一个字符串
  • path:定义输出文件路径,一个字符串
  • module:定义对模块的处理逻辑,一个对象
  • loaders:定义一系列的加载器,一个数组
  • resolve:影响对模块的解析,一个对象
  • extensions:自动补全识别后缀,是一个数组
  • plugins:定义插件,一个数组
posted @   一星一辰  阅读(37)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示