前端系列-3 前端打包工具和插件介绍(npm+babel+webpack)

背景

最近接触了两个前端项目,分别是vue2和vue3,感觉有点生疏。作为后端开发,前端知识容易遗忘,想着将之前的学习笔记整理成电子版发出来,以便后续简单复习即可快速恢复。前端系基于这个目的创建,将用于收集前端技术文章。

1.npm和nodejs

1.1 nodejs

说明:nodejs是一个基于ChromeV8引擎的JS运行环境,使用了事件驱动、非阻塞式I/O模型、优化的JS编译技术的JS运行时环境;基于此,JS可用于开发服务端语言。NodeJS与V8引擎的最新版本是保持同步, 因此支持ES6语法。

安装:https://nodejs.cn/download/

node -v 查看是否安装成功

1.2 npm

说明: Node Package Manager, NodeJs默认的包管理工具,相当于Python的pip,Java的maven.

安装:在安装NodeJs时会自动安装

npm -v 查看是否安装成功

1.2.1 语法:

(1) npm config get/set
用于获取和设置全局配置,可配置项包括:prefix, cache, registry, proxy。
cache和prefix分别是npm的缓存和 全局安装包的路径;
proxy代理地址(公司内部一般会进行代理设置)
register 设置包镜像地址,可设置为国内的镜像地址:

npm config set registry https://registry.npm.taobao.org/

(2) npm init
用于项目初始化; 在当前目录生成一个package.json文件

(3) npm install/uninstall
npm install/uninstall 语句用于安装和卸载安装包

# -g表示全局安装, -D表示开发环境安装
npm install -g nodemon

安装完成后会在当前项目/全局路径下生产一个node_modules文件夹,用于存放安装包.

(3) npm list
查看已经安装的包

# -g表示全局安装
npm list -g

(4) npm的发布
需要注册npm账号,使用npm login命令登录,使用npm publish发布

1.2.2 配置文件:

.npmrc作为npm的配置文件(键值对集合),在指定npm命令时会读取.npmrc文件,存在相同的键时,优先级顺序为:项目根目录下的.npmrc文件>用户主目录下的.npmrc文件>npm内置的默认配置。上述npm config set语句的执行结果会同步到.npmrc文件文件中,因此机器重启不会丢失修改的配置。

1.2.3 package.json文件:

(1) 坐标属性(必选)
name和version用于全局唯一标识安装包;

(2) 描述类属性:
description, keywords ,contributors,bugs,author等描述类属性,可选;

(3) 依赖配置:
常使用的依赖包括dependencies和devDependencies,其中dependencies表示生产环境中运行需要的依赖,devDependencies表示开发环境需要的依赖。
一般生产环境中不需要 Webpack、Eslint、Babel 等打包工具,因此这些依赖会被放在devDependencies中。

格式如下:

"devDependencies": {
    "babel": "^6.23.0"
}
#固定版本: 安装时只安装这个指定的版本;
#波浪号: 主版本号、次版本号下允许的最新版本;
#插入号: 主版本号下允许的最低版本;
#latest:安装最新的版本

执行npm install时会自动将依赖项记录到package.json文件中。

(4) 脚本

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
}

当命令行执行 npm run test时,执行test命令对应的语句.

2.babel

JS不断发展,浏览器的适配速度没有跟上,引入了一个问题:用高级(ES6+)的JS语法开发的代码,无法在支持低版本(ES5)JS语法的浏览器上运行。babel作为转译工具,可以实现将ES6转译为ES5,为该问题提供了一个解决方案。label常被集成到webpack中进行打包;随着vue3的出现, vite+esbuild的占有率相比webpack+babel更高。

2.1.组成

babel是一个工具链集,由以下部分组成:
[1] 核心@babel/core:
babel的核心包,集成了整个Babel的工作流,类似计算机主板的作用。
[2] 编译器 @babel/parser,@babel/traverse,@babel/generator:
parser对源码进行解析得到AST(抽象语法树),traverse对语法书进行遍历,并调用插件对其进行转义,得到新的语法树;generator根据新的语法树生成ES5代码;
[3] 插件和预设:
babel整体提供了一个执行流程的框架,实际的转义工作需要依赖于具体的插件。如: @babel/plugin-transform-arrow-functions插件的作用是将ES6的箭头函数语法转换为ES5的普通函数语法, @babel/plugin-transform-for-of插件的作用是将ES6的for…of循环语法转换为ES5可理解的语法等。预设是对插件进行的一些组装或者条件组装,从而减少了重复工作(通过引入一个预设而不需要引入多个插件)。

插件的转换可以分为两种类型:
(1)语法转义,如箭头函数和for…of的转换,可通过babel语法插件实现;
(2)API和内置对象的转义,Promise、Array、Symbol等的转换,需要使用pollyfill(垫片)机制实现。pollyfill实现原理较为简单,直接在全局对象中引入ES6中新增API的定义(垫片),来模拟一个ES6环境;从而可以运行ES6的API。

**说明:**直接在全局对象中引入ES6的垫片是babel6中的 babel-polyfill的实现方式,容易造成全局污染;在babel7中不再建议使用babel-polyfill,推荐使用 @babel/polyfill替代方案,@babel/polyfill采用了更加模块化的方式来引入垫片。二者底层是对core.js和regenerator-runtime这两个库的封装。

2.2 使用方式

2.2.1 安装babel

babel作为编译期间使用的依赖,使用如下命令进行安装:

npm install --save-dev @babel/core @babel/cli @babel/preset-env

2.2.2 配置依赖

在项目根目录下新建.babelrc文件,在.babelrc配置文件中进行插件和预设的配置。一般而言,配置preset-env能满足大部分场景:

{
    "plugins": [],
    "presets": ['@babel/preset-env']
}

plugins和presets的运行顺序为: plugins -> presets, plugins是从前往后执行, presets是从后往前执行。

也可以将配置放在package.json中,如下所示:

{
  "dependencies": {
   //...
  },
  //...
    
  "babel": {
    "presets": [
      "env"
    ],
    "comments": false
  }
}

preset-env预设会根据指定的目标环境自动确定需要哪些Babel插件和polyfills,从而进行必要的代码转换。preset-env中支持配置浏览器的版本,babel保证生成的代码可以被对应的浏览器所识别。

2.2.3 案例介绍

step1: 执行npm init -y快速创建一个项目;

step2: 执行npm install --save-dev @babel/core @babel/cli @babel/preset-env安装babel;

step3: 新建src文件夹和src/index.js和src/module1.js文件(index.js依赖module1.js模块):
index.js

import {print} from "./module1";
print();

// 1.箭头函数
var a = () => {};

module1.js

function fetchData() {  
  // 2.Promise
  return new Promise((resolve, reject) => {  
    setTimeout(() => {  resolve('hello world');}, 1000);  
  });  
}  

export var print = function() {
 fetchData().then(data => {  
  console.log('数据获取成功:', data);  
 }).catch(error => {  
  console.error('数据获取失败:', error);  
 });
}

step4: 修改package.json, 添加构建脚本命令:

{
 // ...
  "scripts": {
      // 编译src目录下的js文件,并输出到lib目录下
 "build": "babel src -d lib"
  }
}

step5: 在项目根路径下添加babel配置文件:

{
    "plugins": [], 
 "presets": [
        [
            "@babel/preset-env",
            {
                "corejs": 3,
                "useBuiltIns": "usage"
            }
        ]
    ]
}

step6: 在项目路径下,执行npm run build, 得到的js如下所示:

index.js:

"use strict";

var _module = require("./module1");
(0, _module.print)();
// 1.箭头函数已转换
var a = function a() {};

module1.js:

"use strict";
// 在module1模块中引入promise,模拟ES6
require("core-js/modules/es.object.define-property.js");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.print = void 0;
require("core-js/modules/es.object.to-string.js");
require("core-js/modules/es.promise.js");
require("core-js/modules/web.timers.js");
function fetchData() {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      resolve('hello world');
    }, 1000);
  });
}
var print = exports.print = function print() {
  fetchData().then(function (data) {
    console.log('数据获取成功:', data);
  })["catch"](function (error) {
    console.error('数据获取失败:', error);
  });
};

3.webpack

webpack是一个前端项目的打包工具,默认仅支持对低版本JS的打包, 可通过loader方式增加可处理文件的类型,另外通过插件机制对webpack的功能进行增强。

3.1 安装webpack

#webpack是全局的工具,也可以通过-g安装至全局
npm i webpack webpack-cli -D

npm i webpack-dev-server -D

3.2 配置文件

webpack的配置文件放在项目根路径下,名称为webpack.config.js:

module.exports = {
    entry: "打包入口",
    output: "打包出口", 
    mode: "运行环境",
    module: {},//配置loader 
    plugins: [] //插件配置
};

如上所示,常用的配置有:
**[1] entry配置打包入口:**可以配置单个文件或者多个文件

// 指定一个打包入口:
module.exports = {
    entry: "./src/index.js", //打包⼊⼝⽂件
}


// 指定多个打包入口
module.exports = {
    entry: {
        index: './src/index.js',
        index2: './src/index2.js'
    }
}

[2] output配置打包的出口

const path = require('path');
module.exports = {
    output:{
        //_dirname 是一个全局变量,根目录的绝对路径
        path:path.join(__dirname, './dist'),  //输出文件存放路径
        filename:'bundle.js'   //输出文件的名称
    }
}

[3] mode执行环境信息

可以设置为develop或者production,develop打包时不会进行文件压缩,速度较快,使用于开发环境;部署时,使用production模式打包。

[4] module配置loader

如下所示为处理css的loader:

module.exports = {
    module: {
        rules: [
            {test: /\.css$/i,  use: ["style-loader", "css-loader"]}
        ]
    }
}

上面涉及到的test: /\.css$/i为正则表达式,匹配后,才会使用style-loader和css-loader.
其中:/表示正则表达式的开始或者结束,\转义字符,.表示点号;$表示结尾,i表示忽略大小写。loader执行顺序为反向,即css-loader读取css文件处理后交给style-loader,style-loader处理后将模块信息保存到内存中,转交给webpack,webpack对模块进行打包。

在webpack配置style-loader和css-loader时,需要保证当前环境已经安装了相应的依赖,否则需要执行以下命令:

npm install style-loader css-loader -D

[5] plugins配置插件

常用插件有html-webpack-plugin和webpack-parallel-uglify-plugin等.

module.exports = {
    plugins:[htmlPlugin,cleanPlugin]
}

3.3 webpack打包流程

webpack中认为每个文件是一个模块,多个关联的模块可以编组为一个Chunk, 打包的产物为一个或多个Bundle。具体而言,webpack从配置文件中entry配置的打包入口出发,根据模块的依赖关系构建依赖图,并将依赖关系分割成不同的Chunk, 每个Chunk平行地构建(可以提高打包速度),每个chunk生成一个bundle。对于chunk中每个模块, 构建流程如下:
[1] 当前模块是js文件且不包含高级语法:webpack直接处理;

否则: [2] 是否配置loader ? 调用loader加载模块并将处理后的模块信息转交给webpack : 报错。

3.4 webpack整合babel

根据babel章节中介绍的内容配置babel,然后在webpack的配置文件中进行如下配置:

module.exports = {
 module: {
  rules: [  
            // exclude用于排除文件
   {test:/\.js$/,use:'babel-loader',exclude:/node_modules/}
  ]
 }
}

配置后,webpack打包时,如果遇到高级语法的js文件,会经过babel-loader转换。

3.5 案例介绍

3.5.1 项目初始化

执行npm init -y初始化项目后,得到一个package.json文件:

{
  "name": "demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

准备项目的资源文件,目录树设计为:

-src
 -index.js
 -module1.js
-index.html
-package.json
-package-lock.json

index.html

<!DOCTYPE html>
<html>
 <head>
  <title>demo</title>
 </head>
 <body>
  <script src="./dist/bundle.js"></script>
 </body>
</html>

index.js

// index.js
import {getMessage} from "./module1";
console.log(getMessage());

module1.js

// module1.js
export function getMessage(){
 return "[webpack] hello world";
}

3.5.2 安装和配置babel

安装babel:

npm install --save-dev @babel/core @babel/cli @babel/preset-env

配置babel:

在根目录下新建babel的配置文件.babelrc:

{
    "plugins": [], 
 "presets": [
        [
            "@babel/preset-env",
            {
                "corejs": 3,
                "useBuiltIns": "usage"
            }
        ]
    ]
}

3.5.3 安装和配置webpack

安装webpack:

npm i webpack webpack-cli webpack-dev-server -D

安装babel-loader:

npm install babel-loader -D

配置webpack:

在根目录下创建webpack.config.js文件并配置:

const path = require("path")

module.exports = {
 mode:"development",
 entry:"./src/index.js",
 output:{
  filename:"main.js",
  path: path.resolve(__dirname, "dist"),
 },
 
 module: {
  rules: [
   {test:/\.js$/,use:'babel-loader',exclude:/node_modules/}
  ]
 }
}

3.5.4 运行结果

配置package.json文件:

"scripts": {
    //添加build命令
    "build": "npx webpack"
}

运行npm run build命令:

> demo@1.0.0 build
> npx webpack

asset main.js 4.13 KiB [emitted] (name: main)
runtime modules 670 bytes 3 modules
cacheable modules 132 bytes
  ./src/index.js 66 bytes [built] [code generated]
  ./src/module1.js 66 bytes [built] [code generated]
webpack 5.91.0 compiled successfully in 1265 ms

在浏览器中查看打印信息如下:

[webpack] hello world

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/579429.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

BIO、NIO与AIO

一 BIO 同步并阻塞(传统阻塞型)&#xff0c;服务器实现模式为一个连接一个线程&#xff0c;即客户端有连接请求时服务器端就需要启动一个线程进行处理. BIO&#xff08;Blocking I/O&#xff0c;阻塞I/O&#xff09;模式是一种网络编程中的I/O处理模式。在BIO模式中&#xf…

鸿蒙内核源码分析(任务调度篇) | 任务是内核调度的单元

任务即线程 在鸿蒙内核中&#xff0c;广义上可理解为一个任务就是一个线程 官方是怎么描述线程的 基本概念 从系统的角度看&#xff0c;线程是竞争系统资源的最小运行单元。线程可以使用或等待CPU、使用内存空间等系统资源&#xff0c;并独立于其它线程运行。 鸿蒙内核每个…

[蓝桥杯2024]-PWN:fd解析(命令符转义,标准输出重定向)

查看保护 查看ida 这里有一次栈溢出&#xff0c;并且题目给了我们system函数。 这里的知识点没有那么复杂 完整exp&#xff1a; from pwn import* pprocess(./pwn) pop_rdi0x400933 info0x601090 system0x400778payloadb"ca\\t flag 1>&2" print(len(paylo…

SAP PP学习笔记07 - 作业手顺(工艺路线Routing)

上一章讲了BOM的相关知识。 SAP PP学习笔记07 - 简单BOM&#xff0c;派生BOM&#xff0c;多重BOM&#xff0c;批量修改工具 CEWB_sap半成品有多个bom-CSDN博客 本章来讲作业手顺&#xff08;工艺路线Routing&#xff09;的相关知识。 1&#xff0c;作业手顺(工艺路线 Routing…

四、线段、矩形、圆、椭圆、自定义多边形、边缘轮廓和文本绘制(OpenCvSharp)

功能实现&#xff1a; 对指定图片上进行绘制线段、矩形、圆、椭圆、自定义多边形、边缘轮廓以及自定义文本 一、布局 用到了一个pictureBox和八个button 二、引入命名空间 using System; using System.Collections.Generic; using System.Drawing; using System.Windows.F…

Dockerfile镜像构建实战

一、构建Apache镜像 cd /opt/ #建立工作目录 mkdir /opt/apache cd apache/vim Dockerfile #基于的基础镜像 FROM centos:7 #维护镜像的用户信息 MAINTAINER this is apache image <cyj> #镜像操作指令安装Apache软件 RUN yum install -y httpd #开启80端口 EXPOSE 80 #…

远程桌面连接不上个别服务器的问题分析与解决方案

在日常的IT运维工作中&#xff0c;远程桌面连接&#xff08;RDP&#xff0c;Remote Desktop Protocol&#xff09;是我们经常使用的工具之一&#xff0c;用于管理和维护远程服务器。然而&#xff0c;有时我们可能会遇到无法连接到个别服务器的情况。针对这一问题&#xff0c;我…

《Kafka 3.x.x 入门到精通》

Kafka 3.x.x 入门到精通 Kafka是一个由Scala和Java语言开发的&#xff0c;经典高吞吐量的分布式消息发布和订阅系统&#xff0c;也是大数据技术领域中用作数据交换的核心组件之一。以高吞吐&#xff0c;低延迟&#xff0c;高伸缩&#xff0c;高可靠性&#xff0c;高并发&#x…

【论文浅尝】Porting Large Language Models to Mobile Devices for Question Answering

Introduction 移动设备上的大型语言模型(LLM)增强了自然语言处理&#xff0c;并支持更直观的交互。这些模型支持高级虚拟助理、语言翻译、文本摘要或文本中关键术语的提取(命名实体提取)等应用。 LLMs的一个重要用例也是问答&#xff0c;它可以为大量的用户查询提供准确的和上…

LeetCode 热题 100 题解:二叉树部分(1 ~ 5)

题目一&#xff1a;二叉树的中序遍历&#xff08;No. 948&#xff09; 94. 二叉树的中序遍历 - 力扣&#xff08;LeetCode&#xff09; 题目难度&#xff1a;简单 给定一个二叉树的根节点 root &#xff0c;返回 它的 中序 遍历 。 示例 1&#xff1a; 输入&#xff1a;roo…

【Django】初识Django快速上手

Django简介 Django是一个高级的、开源的Python Web框架&#xff0c;旨在快速、高效地开发高质量的Web应用程序 https://developer.mozilla.org/zh-CN/docs/Learn/Server-side/Django/Introduction 安装Django pip install Django如果要知道安装的Django的版本&#xff0c;可…

关于两步到位Chrome永久停止更新

全程就两个步骤&#xff01;&#xff01;敲重点&#xff01;&#xff01;&#xff01; 好使记得点赞关注我&#xff01; 1.找到Chrome包下的hosts文件 默认路径大概是 C:\Windows\System32\drivers\etc\hosts &#xff0c;不记得了可以通过Everything查找 在hosts 文件中 …

移动端日志采集与分析最佳实践

前言 做为一名移动端开发者&#xff0c;深刻体会日志采集对工程师来说具有重要意义&#xff0c;遇到问题除了 debug 调试就是看日志了&#xff0c;通过看日志可以帮助我们了解应用程序运行状况、优化用户体验、保障数据安全依据&#xff0c;本文将介绍日志采集的重要性、移动端…

开源博客项目Blog .NET Core源码学习(19:App.Hosting项目结构分析-7)

本文学习并分析App.Hosting项目中后台管理页面的主页面。如下图所示&#xff0c;开源博客项目的后台主页面采用layui预设类layui-icon-shrink-right设置样式&#xff0c;点击主页面中的菜单&#xff0c;其它页面采用弹框或者子页面形式显示在主页面的内容区域。   后台主页面…

JavaScript算法描述【排序与搜索】六大经典排序|合并两个有序数组|第一个错误的版本

&#x1f427;主页详情&#xff1a;Choice~的个人主页 &#x1f4e2;作者简介&#xff1a;&#x1f3c5;物联网领域创作者&#x1f3c5; and &#x1f3c5;阿里专家博主&#x1f3c5; and &#x1f3c5;华为云享专家&#x1f3c5; ✍️人生格言&#xff1a;最慢的步伐不是跬步&…

C++ 笔试练习笔记【1】:字符串中找出连续最长的数字串 OR59

文章目录 OR59 字符串中找出连续最长的数字串题目思路分析实现代码 注&#xff1a;本次练习题目出自牛客网 OR59 字符串中找出连续最长的数字串 题目思路分析 首先想到的是用双指针模拟&#xff0c;进行检索比较输出 以示例1为例&#xff1a; 1.首先i遍历str直到遍历到数字&a…

unity 专项一 localPosition与anchoredPosition(3D)的区别

一 、RectTransform 概念 1、RectTransform继承自Transform&#xff0c;用于描述矩形的坐标(Position)&#xff0c;尺寸(Size)&#xff0c;锚点(anchor)和中心点(pivot)等信息&#xff0c;每个2D布局下的元素都会自动生成该组件。 2、当我们在处理UI组件时&#xff0c;往往容易…

【微信小程序调用百度API实现图像识别实战】-前后端加强版

前言&#xff1a;基于前面两篇图像识别项目实战文章进行了改造升级。 第一篇 入门【微信小程序调用百度API实现图像识别功能】----项目实战 第二篇 前后端结合 【微信小程序调用百度API实现图像识别实战】----前后端分离 这一篇主要讲述的是在第二篇的基础上新增意见反馈功能&a…

ZooKeeper 搭建详细步骤之一(单机模式)

搭建模式简述 ZooKeeper 的搭建模式包括单机模式、集群模式和伪集群模式&#xff0c;分别适用于不同的场景和需求&#xff0c;从简单的单节点测试环境到复杂的多节点高可用生产环境。在实际部署时&#xff0c;应根据系统的可用性要求、数据量、并发负载等因素选择合适的部署模式…

mysql UNION 联合查询

mysql UNION 联合查询 业务需要拉数据&#xff0c;这里需要对查询不同格式的数据进行组装&#xff0c;此处采用联合查询 注意1&#xff1a;null as 设备关爱 &#xff0c;结果为null&#xff0c;表头为设备关爱 注意2&#xff1a; UNION 或者 UNION ALL 联合查询自行选用 注意3…