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

打印 上一主题 下一主题

主题 863|帖子 863|积分 2589

背景

最近接触了两个前端项目,分别是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 设置包镜像地址,可设置为国内的镜像地址:
  1. npm config set registry https://registry.npm.taobao.org/
复制代码
(2) npm init
用于项目初始化; 在当前目次天生一个package.json文件
(3) npm install/uninstall
npm install/uninstall 语句用于安装和卸载安装包
  1. # -g表示全局安装, -D表示开发环境安装
  2. npm install -g nodemon
复制代码
安装完成后会在当前项目/全局路径下生产一个node_modules文件夹,用于存放安装包.
(3) npm list
查看已经安装的包
  1. # -g表示全局安装
  2. 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中。
格式如下:
  1. "devDependencies": {
  2.     "babel": "^6.23.0"
  3. }
  4. #固定版本: 安装时只安装这个指定的版本;
  5. #波浪号: 主版本号、次版本号下允许的最新版本;
  6. #插入号: 主版本号下允许的最低版本;
  7. #latest:安装最新的版本
复制代码
执行npm install时会自动将依赖项记载到package.json文件中。
(4) 脚本
  1. "scripts": {
  2.     "test": "echo "Error: no test specified" && exit 1"
  3. }
复制代码
当命令行执行 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作为编译期间使用的依赖,使用如下命令进行安装:
  1. npm install --save-dev @babel/core @babel/cli @babel/preset-env
复制代码
2.2.2 配置依赖

在项目根目次下新建.babelrc文件,在.babelrc配置文件中进行插件和预设的配置。一般而言,配置preset-env能满足大部分场景:
  1. {
  2.     "plugins": [],
  3.     "presets": ['@babel/preset-env']
  4. }
复制代码
plugins和presets的运行顺序为: plugins -> presets, plugins是从前去后执行, presets是从后往前执行。
也可以将配置放在package.json中,如下所示:
  1. {
  2.   "dependencies": {
  3.    //...
  4.   },
  5.   //...
  6.    
  7.   "babel": {
  8.     "presets": [
  9.       "env"
  10.     ],
  11.     "comments": false
  12.   }
  13. }
复制代码
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
  1. import {print} from "./module1";
  2. print();
  3. // 1.箭头函数
  4. var a = () => {};
复制代码
module1.js
  1. function fetchData() {  
  2.   // 2.Promise
  3.   return new Promise((resolve, reject) => {  
  4.     setTimeout(() => {  resolve('hello world');}, 1000);  
  5.   });  
  6. }  
  7. export var print = function() {
  8. fetchData().then(data => {  
  9.   console.log('数据获取成功:', data);  
  10. }).catch(error => {  
  11.   console.error('数据获取失败:', error);  
  12. });
  13. }
复制代码
step4: 修改package.json, 添加构建脚本命令:
  1. {
  2. // ...
  3.   "scripts": {
  4.       // 编译src目录下的js文件,并输出到lib目录下
  5. "build": "babel src -d lib"
  6.   }
  7. }
复制代码
step5: 在项目根路径下添加babel配置文件:
  1. {
  2.     "plugins": [],
  3. "presets": [
  4.         [
  5.             "@babel/preset-env",
  6.             {
  7.                 "corejs": 3,
  8.                 "useBuiltIns": "usage"
  9.             }
  10.         ]
  11.     ]
  12. }
复制代码
step6: 在项目路径下,执行npm run build, 得到的js如下所示:
index.js:
  1. "use strict";
  2. var _module = require("./module1");
  3. (0, _module.print)();
  4. // 1.箭头函数已转换
  5. var a = function a() {};
复制代码
module1.js:
  1. "use strict";
  2. // 在module1模块中引入promise,模拟ES6
  3. require("core-js/modules/es.object.define-property.js");
  4. Object.defineProperty(exports, "__esModule", {
  5.   value: true
  6. });
  7. exports.print = void 0;
  8. require("core-js/modules/es.object.to-string.js");
  9. require("core-js/modules/es.promise.js");
  10. require("core-js/modules/web.timers.js");
  11. function fetchData() {
  12.   return new Promise(function (resolve, reject) {
  13.     setTimeout(function () {
  14.       resolve('hello world');
  15.     }, 1000);
  16.   });
  17. }
  18. var print = exports.print = function print() {
  19.   fetchData().then(function (data) {
  20.     console.log('数据获取成功:', data);
  21.   })["catch"](function (error) {
  22.     console.error('数据获取失败:', error);
  23.   });
  24. };
复制代码
3.webpack

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

  1. #webpack是全局的工具,也可以通过-g安装至全局
  2. npm i webpack webpack-cli -D
  3. npm i webpack-dev-server -D
复制代码
3.2 配置文件

webpack的配置文件放在项目根路径下,名称为webpack.config.js:
  1. module.exports = {
  2.     entry: "打包入口",
  3.     output: "打包出口",
  4.     mode: "运行环境",
  5.     module: {},//配置loader
  6.     plugins: [] //插件配置
  7. };
复制代码
如上所示,常用的配置有:
**[1] entry配置打包入口:**可以配置单个文件大概多个文件
  1. // 指定一个打包入口:
  2. module.exports = {
  3.     entry: "./src/index.js", //打包⼊⼝⽂件
  4. }
  5. // 指定多个打包入口
  6. module.exports = {
  7.     entry: {
  8.         index: './src/index.js',
  9.         index2: './src/index2.js'
  10.     }
  11. }
复制代码
[2] output配置打包的出口
  1. const path = require('path');
  2. module.exports = {
  3.     output:{
  4.         //_dirname 是一个全局变量,根目录的绝对路径
  5.         path:path.join(__dirname, './dist'),  //输出文件存放路径
  6.         filename:'bundle.js'   //输出文件的名称
  7.     }
  8. }
复制代码
[3] mode执行情况信息
可以设置为develop大概production,develop打包时不会进行文件压缩,速度较快,使用于开辟情况;部署时,使用production模式打包。
[4] module配置loader
如下所示为处理css的loader:
  1. module.exports = {
  2.     module: {
  3.         rules: [
  4.             {test: /\.css$/i,  use: ["style-loader", "css-loader"]}
  5.         ]
  6.     }
  7. }
复制代码
上面涉及到的test: /\.css$/i为正则表达式,匹配后,才会使用style-loader和css-loader.
其中:/表示正则表达式的开始大概结束,\转义字符,.表示点号;$表示末了,i表示忽略大小写。loader执行顺序为反向,即css-loader读取css文件处理后交给style-loader,style-loader处理后将模块信息生存到内存中,转交给webpack,webpack对模块进行打包。
在webpack配置style-loader和css-loader时,需要包管当前情况已经安装了相应的依赖,否则需要执行以下命令:
  1. npm install style-loader css-loader -D
复制代码
[5] plugins配置插件
常用插件有html-webpack-plugin和webpack-parallel-uglify-plugin等.
  1. module.exports = {
  2.     plugins:[htmlPlugin,cleanPlugin]
  3. }
复制代码
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的配置文件中进行如下配置:
  1. module.exports = {
  2. module: {
  3.   rules: [  
  4.             // exclude用于排除文件
  5.    {test:/\.js$/,use:'babel-loader',exclude:/node_modules/}
  6.   ]
  7. }
  8. }
复制代码
配置后,webpack打包时,如果碰到高级语法的js文件,会经过babel-loader转换。
3.5 案例先容

3.5.1 项目初始化

执行npm init -y初始化项目后,得到一个package.json文件:
  1. {
  2.   "name": "demo",
  3.   "version": "1.0.0",
  4.   "description": "",
  5.   "main": "index.js",
  6.   "scripts": {
  7.     "test": "echo "Error: no test specified" && exit 1"
  8.   },
  9.   "keywords": [],
  10.   "author": "",
  11.   "license": "ISC"
  12. }
复制代码
预备项目的资源文件,目次树设计为:
  1. -src
  2. -index.js
  3. -module1.js
  4. -index.html
  5. -package.json
  6. -package-lock.json
复制代码
index.html
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.   <title>demo</title>
  5. </head>
  6. <body>
  7.   <script src="./dist/bundle.js"></script>
  8. </body>
  9. </html>
复制代码
index.js
  1. // index.js
  2. import {getMessage} from "./module1";
  3. console.log(getMessage());
复制代码
module1.js
  1. // module1.js
  2. export function getMessage(){
  3. return "[webpack] hello world
  4. ";
  5. }
复制代码
3.5.2 安装和配置babel

安装babel:
  1. npm install --save-dev @babel/core @babel/cli @babel/preset-env
复制代码
配置babel:
在根目次下新建babel的配置文件.babelrc:
  1. {
  2.     "plugins": [],
  3. "presets": [
  4.         [
  5.             "@babel/preset-env",
  6.             {
  7.                 "corejs": 3,
  8.                 "useBuiltIns": "usage"
  9.             }
  10.         ]
  11.     ]
  12. }
复制代码
3.5.3 安装和配置webpack

安装webpack:
  1. npm i webpack webpack-cli webpack-dev-server -D
复制代码
安装babel-loader:
  1. npm install babel-loader -D
复制代码
配置webpack:
在根目次下创建webpack.config.js文件并配置:
  1. const path = require("path")
  2. module.exports = {
  3. mode:"development",
  4. entry:"./src/index.js",
  5. output:{
  6.   filename:"main.js",
  7.   path: path.resolve(__dirname, "dist"),
  8. },
  9. module: {
  10.   rules: [
  11.    {test:/\.js$/,use:'babel-loader',exclude:/node_modules/}
  12.   ]
  13. }
  14. }
复制代码
3.5.4 运行结果

配置package.json文件:
  1. "scripts": {
  2.     //添加build命令
  3.     "build": "npx webpack"
  4. }
复制代码
运行npm run build命令:
  1. > demo@1.0.0 build
  2. > npx webpack
  3. asset main.js 4.13 KiB [emitted] (name: main)
  4. runtime modules 670 bytes 3 modules
  5. cacheable modules 132 bytes
  6.   ./src/index.js 66 bytes [built] [code generated]
  7.   ./src/module1.js 66 bytes [built] [code generated]
  8. webpack 5.91.0 compiled successfully in 1265 ms
复制代码
在浏览器中查看打印信息如下:
  1. [webpack] hello world
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

耶耶耶耶耶

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表