一篇了解模块打包工具之 ——webpack(1)

news2024/11/17 11:44:39

本篇采用问题引导的方式来学习webpack,借此梳理一下自己对webpack的理解,将所有的知识点连成一条线,形成对webpack的记忆导图。

最终目标,手动构建一个vue项目,目录结构参考vue-cli创建出来的项目

一、问问题

1. 第一个问题: webpack起因

首先为什么会有webpack⬆️因为有模块化,总要把所有的模块串联起来⬆️模块化是什么,模块化能让一整个代码拆分成,功能独立、互不影响、又可以频繁复用的多个代码块 这样代码更符合高内聚低耦合的设计原则⬆️为什么需要模块化, 又是因为业务逻辑日益复杂,需要更多的js代码来实现,代码量越来越多,一个js文件是不够的

2.第二个问题: webpack作用

我们期望webpack能帮我们做什么事,达到什么目的,最终产物是什么?

我们希望webpack能帮我们构建所有项目文件,产出一个能在浏览器上运行的html文件,一方面在开发阶段,快速看到代码效果,方便开发;另一方面,页面能部署在服务器上,能在网络上访问的到,投入使用。

3.第三个问题: webpack打包逻辑

所有的代码是怎么互相依赖,能将代码实现的所有功能呈现在html页面上⬆️换句话说所有的webpack怎么处理所有的互相依赖的js、css文件,甚至是图片、字体这些资源,处理完之后怎么放在html上面⬆️所有文件的源头是什么,从哪个文件着手开始打包⬆️webpack会处理所有文件的最顶层文件,比如root.js,如果root文件中依赖其他js css ,就会处理相应的文件⬆️root.js没有依赖到的文件,或者说没有在root中引入的文件,会被打包吗?如果没有又该怎么处理?⬆️打包后的最终物 root.js --> output.js⬆️将output.js放入html页面中。

4. 第四个问题:webpack需要哪些基本配置

要想产出html,webpack默认有哪些配置?自定义配置又需要哪些基本配置,如果自定义一个配置文件会和默认配置冲突吗?配置文件的书写,是采用什么规范?

  • 从第三个问题得知,打包入口是必须的
  • 既然有输入input,必然有产出output
  • html也得有,不然产出无处可用

在配置文件中他们有具体的名字:

  • entry
  • output
  • plugins: [ new HtmlWebpackPlugin()]

不会冲突,webpack内部会将自定义和默认合并;我们只需要在自定义配置文件中写,需要改变哪些默认配置即可;

webpack代码本身是基于commonJs规范,所以,webpack.config.js也要用commonJs规范。

5. 第五个问题:哪些文件需要做转化 --》 转化成浏览器能认识的代码

入口文件中怎么依赖其他文件⬆️require 和 import 都可以吗require是commonjs规范import 是es6规范⬆️在本地浏览一个html页面,html中用script标签引入一个js文件, 文件中使用了require和import, 浏览器能正常浏览吗?⬆️实际上是不能的,so 使用webpack打包后的js文件,放入html中就是可以的 ⬆️显见webpack的作用之一, 统一模块引用规范,转化成浏览器都能认识的代码。⬆️然后,此外,哪些文件需要转化⬆️.css.less.scss.sass.js.tses6之后规范的js.png.jpeg.jpg.svg.gif…woff.vue⬆️用什么来转化, loader/plugins

二、解决问题

1. 准备工作

- 初始化一个项目
// mkdir learn-webpack
// cd learn-webpack
// npm init / npm init -y
//生成package.js
{"name": "learn-webpack","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1"},"keywords": [],"author": "","license": "ISC","devDependencies": {}
} 
  • 注意项目名字不能包含中文,和特殊字符,否则npm init -y时会失败,名字不合法* 也不能和npm上的包名字冲突,名字唯一,否则在项目中安装同名包失败;* 比如我给项目命名webpack,下载webpack,结果失败,内心
// 项目依赖
// npm install webpack webpack-cli -D 
// 使用项目的webpack包 的三种做法
// npx webpack 
// 或者 ./node_modules/.bin/webpack
// 或者 package.js中这样写,在执行npm run build"scripts": {"build": "webpack"},

//全局依赖
// npm install webpack webpack-cli -g 
// webpack 使用全局的webpack包 
  • -D 等价于 --save-dev => 开发使用依赖
  • -S 等价于 --save 等价于 什么都不写 ==》 开发和生产都使用依赖
  • webpack有默认的配置,什么都不用配置就能打包,但是需要一个入口文件;
  • webpack命令的默认入口是 package.json同级目录下的 src/index.js
  • 先创建入口文件在,根据webapck的位置,执行不同的打包命令

2. 自定义配置文件

注:以下学习都是通过npm run build的方式打包

打包默认配置文件名称是webpack.config.js默认路径是和package.js同级,或者说是根目录下

若想要自定义名称 自定义位置 需要这样写: webpack --config ./build/learn.config.js

3. entry

  • 默认入口 ‘./src/index.js’
  • 自定义入口
{// 单入口,单出口entry: './src/main.js'//多入口, 单出口(将main.js 和 other.js合并到一个文件)entry: ['./src/main.js', './src/other.js']//多入口,多出口(main.js 和 other.js 还是两个文件)entry: {main: './src/main.js', other: './src/other.js'}// 或entry: {main: {import: './src/main.js'}, other: './src/other.js'}
} 
  • 入口路径是个相对路径;
  • 必须以’./'开头;
  • 是相对于项目根目录的位置,而不是config文件的位置;
  • 即便同上面自定义配置文件位置是: learn-webpack/build/learn.config.js, 入口仍然是’./src/other.js’

4. output

  • 默认出口 learn-webpack/dist/main.js
  • 自定义出口
const path = require('path')
output: {path:path.resolve(__dirname,'../../bundle'),filename: './js/[name]_[contenthash:8].js',publicPath: '/assets/'} 
  • path是一个绝对路径
  • filename可以直接是一个文件名字, 如main.js,也可以是路径,这个路径和path做拼接得到最终路径
  • 中括号里的值是占位符,name就是多入口里的名字,contentehash是哈希值,用来防止打包出来的文件重名,:数字,指定hash位数;
  • publicPath用于页面找不到指定资源时,在这里找,‘/assets/’ 就是打包后文件夹 dist/assets,当html引入一个不存在的资源时,会从assets中找;具体用法后面再说;

5. devserver

为了能更好的看到打包的效果,先开启一个本地服务,在浏览器上能看到效果;具体配置项的意义后文再解释;

npm install webpack-dev-server html-webpack-plugin -D

//package.json中添加脚本命令
// 最终如下, 执行npm run serve时 会自动开启一个本地服务
 "scripts": {"build": "webpack --config ./build/learn.config.js","serve": "webpack serve --config ./build/learn.config.js"}
// learn.config.js中添加 devServer和plugins 配置项
const HtmlWebpackPlugin = require('html-webpack-plugin')
const path = require('path')
module.exports = {//....mode: 'development', // 解决下图错误devServer:{devMiddleware: {writeToDisk: true// 开启本地服务的同时,仍然写入打包后的文件,默认是false,看不到打包后的文件}},plugins: [new HtmlWebpackPlugin() // 自动创建一个index.html文件,部署在本地服务器上]
}
// 执行 npm run serve

// 访问 http://localhost:8080/ 

6. loader

参考

 module: {rules: [{test: /\.css$/, //匹配规则,对哪些文件使用一下loaderuse: [''] // 解析匹配到的文件需要使用的loader }, ] } 
6.1 css
打包效果
.css文件解析步骤
  • 首先读取css文件 《— css-loader (官方解释:translates CSS into CommonJS)
  • 再将css转为style节点插入html中 《— style-loader(官方解释:creates style nodes from JS strings)
loader解析顺序

自右向左,或者 自下而上

css适配浏览器

期望转换成如下效果:

{user-select: none;
}
{ 
 -webkit-user-select: none; -moz-user-select: none;user-select: none;
} 

需要使用另外一个loader,就是postcss-loader

less/sass/scss/stylus转换成普通的css
  • 解析不同的类css文件都需要对应的loader;
  • loder就是模块源代码转换工具;css文件也可看称是一个文件,通过import引用;
  • 类css文件解析成css之后,仍然需要loader执行之后的工作,即读取css文件,生成style节点;
  • css解析工作,只存在于开发阶段,生产阶段只需要使用解析后的css文件,无需相应的loader,所以,loader只需要安装到开发环境,-S 或 --save-dev;
  • postcss-loader是用于代码转换的,该loader应该在css-loader读取文件之前执行;
// 解析css 文件
npm install css-loader -D
npm install style-loader -D
npm install postcss-loader postcss -D
npm install less-loader less -D
npm install sass-loader sass -D
npm install stylus-loader stylus -D

// postcss-loader less-loader sass-loader stylus-loader
// 比如解析less文件,真正将less代码转换成css代码的工具是less包提供的方法;less-loader本质上使用了less包的方法,才能将代码转换成普通css;
// 所以像less、sass、 stylus、postcss也需要安装;
// sass和scss,这两个都是用sass处理的; 
less等工具的单独使用(了解)

参考如下:lesssassstyluspostcss

// 如果单独使用这些工具,该怎么用?
// 比如单独使用less包,这就和less-loader没什么关系了,只需要安装less工具

//less 
//less 本质上又依赖lessc工具,lessc就是less compiler,安装less时,会自动帮我们安装lessc,所以无需再安装
npm install less -D
npx lessc input.less output.css

//sass
npm install sass -D
npx sass input.scss output.css

//styl
npm install stylus -D
npx stylus < ./src/css/common.styl > demo.css

// postcss
// postcss 需要其他插件 比如自动添加前缀autoprefixer
// 此外 还可使用其他的插件
npm install postcss autoprefixer -D
npx postcss --use autoprefixer -o output.css input.css 
入口文件引入css文件
// learn-webpack/src/main.js
import './css/common.css'
import './css/common.less'
import './css/common.scss'
import './css/common.sass'
import './css/common.styl'
console.log('main'); 
不同css类型文件解析
 module: {rules: [{test: /\.(css|less)$/,use: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader']},{test: /\.(scss|sass)$/,use: ['style-loader', 'css-loader','postcss-loader', 'sass-loader']},{test: /\.(styl)$/,use: ['style-loader', 'css-loader','postcss-loader', 'stylus-loader']}]} // 不同写法
 // 单个loader写法,以postcss-loader为例{test: /\.css$/,use: 'postcss-loader'},
// 多个loader{test: /\.css$/,use: ['style-loader', 'css-loader', 'postcss-loader']}
// loader需要配置项时{test: /\.css$/,use: ['style-loader', 'css-loader',{loader:'postcss-loader',options: {postcssOptions: {plugins: ['autoprefixer']}}}]}
// postcss的配置项写在单独的文件
// postcss.config.js
module.exports = {plugins: ['postcss-preset-env'// postcss-preset-env包含autoprefixer等常用的插件]
} 
6.2 图片
图片存在形式
  • img元素
  • css中背景图片background-image
图片打包产物
  • 图片文件
  • base64形式
打包效果
需要的loader

webpack4的常见同法

  • file-loader可以将图片打包成图片文件
  • url-loader将图片打包成base64,本质上依赖file-loader
  • 使用url-loader时,配置图片大小限制,limit, 超过指定大小的图片则打包成图片文件 webpack5中 file-loader已经被弃用
  • 5中使用asset
入口文件引用
// learn-webpack/src/main.js
import image from './img/ngla.png'
const img1 = new Image()
img1.src = image
img1.width = 200
document.body.appendChild(img1) 
图片解析配置
// file-loader{test: /\.(png|jpe?g|svg|gif)$/,use: [{loader: 'file-loader',options: {esModule: false,outputPath: './images',// 图片出口路径,相对路径,相对于output.pathname: '[name]_[hash:6].[ext]', // 图片名称[]中的时占位符},}],type: 'javascript/auto'}

//url-loader{test: /\.(png|jpe?g|svg|gif)$/,use: [{loader: 'url-loader',options: {esModule: false,outputPath: './images',name: '[name]_[hash:6].[ext]',limit: 100 * 1024 // 图片大小限制,单位是byte,超过100kb的图片,打包成图片文件,余下的是base64}}],type: 'javascript/auto'}
// webpack5用法{test: /\.(png|jpe?g|svg|gif)$/,type: 'asset',generator: {filename: './images/[name]_[hash:6][ext]'},parser: {dataUrlCondition: {maxSize: 100 * 1024}}}// 注{use: [{options: {esModule: false}}],type: 'javascript/auto'}
// 这两个配置项是为了解决webpack5种file-loader废弃的问题;
// type: 'javascript/auto'必须写在use项后; 
6.3 font

同图片一样,可以用file-loader 或 url-loader 或 asset

入口文引入
import './css/font-awesome.css'

const icon = document.createElement('i')
icon.classList.add('fa','fa-user')
icon.style.width = '100px'
icon.style.height = '100px'
icon.style.color = '#ff0'
document.body.appendChild(icon) 
font文件解析配置
// asset{test: /\.(eot|ttf|woff|woff2)$/,type: 'asset/resource',generator: {filename: './fonts/[name][ext]'}}// url-loader{test: /\.(eot|ttf|woff|woff2)$/,use: [{loader: 'file-loader',options: {esModule: false,name: './fonts/[name].[ext]'}}],type: 'javascript/auto'} 
6.4 js

浏览器本身是能识别js代码,但是对于es6之后的代码,部分浏览器不能识别,所以需要将es6之后的代码转换成兼容的js

需要的loader
  • babel-loader @babel/core @babel/preset-env
  • 代码转换实际用的是@babel/core, loader中依赖了@babel/core
  • @babel/core又依赖了插件才能实现转换
  • 常见的插件有@babel/preset-env,能处理箭头函数等
打包效果
// 在入口文件中写一个箭头函数并且打印
function test(){[1, 2, 3].map(item => item)
}
console.log(test); 

控制台效果

配置
 {test: /\.js$/,use: [{loader: 'babel-loader',options: {presets: ['@babel/preset-env']}}]}
 // babel-loader的配置可以单独拿出来,成独立文件
 // 创建package.js同级文件babel.config.jsmodule.exports = {plugins: [// 插件...],presets: [// 预设...'@babel/preset-env']} 
6.5 vue
需要的loader

vue-loader

打包效果
  • 创建App.vue文件
// learn-webpack/src/App.vue
<template><div style="color: #fff">{{msg}}</div>
</template>

<script> export default{name: 'App',data(){return {msg: 'hello'}}} </script> 
  • 入口文件 引入App.vue,并挂载到id为app的节点上
// learn-webpack/src/main.js
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.mount('#app') 
  • 自定义本地服务html文件
// learn-webpack/public/index.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><div id="app"></div>
</body>
</html> 
配置
const { VueLoaderPlugin} = require('vue-loader/dist/index')

module.exports = { // ...module: {rules: [ {test: /\.vue$/,use: ['vue-loader'] }]},plugins: [new HtmlWebpackPlugin({template: './public/index.html'// 相对路径,自定义html模板}),new VueLoaderPlugin()// 加载vue必备的插件]
} 
报错解决
  • 缺少配置,按照提示修改
const { DefinePlugin } = require('webpack')
module.exports = { // ...plugins: [new DefinePlugin({__VUE_OPTIONS_API__: true,__VUE_PROD_DEVTOOLS__: false}),]
} 

----下期见

最后

整理了一套《前端大厂面试宝典》,包含了HTML、CSS、JavaScript、HTTP、TCP协议、浏览器、VUE、React、数据结构和算法,一共201道面试题,并对每个问题作出了回答和解析。

有需要的小伙伴,可以点击文末卡片领取这份文档,无偿分享

部分文档展示:



文章篇幅有限,后面的内容就不一一展示了

有需要的小伙伴,可以点下方卡片免费领取

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Echarts 仪表盘倾斜一定角度显示,非中间对称

第024个点击查看专栏目录大多数的情况下&#xff0c;制作的仪表盘都是中规中矩&#xff0c;横向中间对称&#xff0c;但是生活中的汽车&#xff0c;摩托车等仪表盘确是要倾斜一定角度的&#xff0c;Echarts中我们就模拟一个带有倾斜角度的仪表盘。核心代码见示例源代码 文章目录…

搞明白redis的这些问题,你就是redis高手

什么是redis? Redis 本质上是一个 Key-Value 类型的内存数据库&#xff0c; 整个数据库加载在内存当中进行操作&#xff0c; 定期通过异步操作把数据库数据 flush 到硬盘上进行保存。 因为是纯内存操作&#xff0c; Redis 的性能非常出色&#xff0c; 每秒可以处理超过 10 万…

JS 快速创建二维数组 fill方法的坑点

JS 快速创建二维数组 坑 在算法中&#xff0c;创建二维数组遇到的一个坑 const arr new Array(5).fill(new Array(2).fill(1))我们如果想要修改其中一个元素的值 arr[0][1] 5我们可以发现所有数组中的第二个元素都发生了改变 查看MDN&#xff0c;我们会发现&#xff0c;当…

2023前端二面经典手写面试题

实现一个call call做了什么: 将函数设为对象的属性执行&删除这个函数指定this到函数并传入给定参数执行函数如果不传入参数&#xff0c;默认指向为 window // 模拟 call bar.mycall(null); //实现一个call方法&#xff1a; Function.prototype.myCall function(context…

一篇搞懂springboot多数据源

好文推荐 https://zhuanlan.zhihu.com/p/563949762 mybatis 配置多数据源 参考文章 https://blog.csdn.net/qq_38353700/article/details/118583828 使用mybatis配置多数据源我接触过的有两种方式&#xff0c;一种是通过java config的方式手动配置两个数据源&#xff0c;…

01、SVN 概述

SVN 概述1 概述2 功能3 工作原理4 基本操作1 概述 Apache下的一个开源的项目Subversion&#xff0c;通常缩写为 SVN&#xff0c;是一个版本控制系统版本控制系统是一个软件&#xff0c;它可以伴随我们软件开发人员一起工作&#xff0c;让编写代码的完整的历史保存下来目前它的…

数仓基础与hive入门

目录1、数仓数据仓库主流开发语言--SQL2、Apache Hive入门2.1 hive定义2.2 为什么使用Hive2.3 Hive和Hadoop关系2.4 场景设计&#xff1a;如何模拟实现Hive功能2.5 Apache Hive架构、组件3、Apache Hive安装部署3.1 metastore配置方式4、Hive SQL语言&#xff1a;DDL建库、建表…

内存保护_2:RTA-OS内存保护逻辑及配置说明

上一篇 | 返回主目录 | 下一篇 内存保护_2&#xff1a;RTA-OS内存保护逻辑及配置说明3 OS配置说明3.1 OS一些基本概念及相互关系3.1.1 基本概念3.1.2 相互关系3.2 内存保护基本逻辑&#xff08;RTA-OS&#xff09;3.2.1 应用集的基本分类3.2.2 内存保护与应用集的关系3.3 OS等级…

七大排序(Java)

目录 一、插入排序 1. 直接插入排序 2. 希尔排序 二、选择排序 1. 直接选择排序 2. 堆排序 三、交换排序 1. 冒泡排序 2. 快速排序 四、归并排序 五、总结 一、插入排序 1. 直接插入排序 抓一张牌&#xff0c;在有序的牌中&#xff0c;找到合适的位置并且插入。 时间…

三战阿里测试岗,成功上岸,面试才是测试员涨薪真正的拦路虎...

第一次面试阿里记得是挂在技术面上&#xff0c;当时也是技术不扎实&#xff0c;准备的不充分&#xff0c;面试官出的面试题确实把我问的一头雾水&#xff0c;还没结束我就已经知道我挂了这次面试。 第二次面试&#xff0c;我准备的特别充分&#xff0c;提前刷了半个月的面试题…

防止jar被反编译 不安装jdk运行jar

防止jar被反编译1.pom.xml<repositories><repository><id>jitpack</id><url>https://jitpack.io</url></repository> </repositories><dependencies><dependency><groupId>org.openjfx</groupId><…

RabbitMQ死信队列

目录 一、概念 二、出现死信的原因 三、实战 &#xff08;一&#xff09;代码架构图 &#xff08;二&#xff09;消息被拒 &#xff08;三&#xff09;消息TTL过期 &#xff08;四&#xff09;队列达到最大长度 一、概念 先从概念解释上搞清楚这个定义&#xff0c;死信&…

Spark 3.3.x 读取 HBase 2.x 异常(无法正常连接或读取数据)

无法连接 1. 先检查集群中的 HBase 服务、ZooKeeper 服务是否正常启动&#xff0c;有没有挂掉。 2. Spark 中的 HBase 版本是否与集群一致&#xff0c;代码中的相关包是否导入正确。 3. 连接参数&#xff08;地址、端口&#xff09;是否设置正确&#xff0c;如下所示&#x…

pyqt 制作exe步骤

之前的博客记录 使用pycharmpyqt 编写一个桌面端&#xff08;mac&#xff09;_python开发桌面工具mac_Y_Hungry的博客-CSDN博客 python开发exe程序界面及打包环境配置_Y_Hungry的博客-CSDN博客 1.编写代码 2.打包 pyinstaller -w --add-data "logo.ico;." --add…

Redis常见的数据类型命令

文章目录Redis 常见的数据类型及命令一、常见的NoSQL二、Redis 简介三、key 键的一些操作命令四、Redis的五种基本数据结构1、String&#xff08;字符串&#xff09;介绍常用命令1.1 set/get1.2 append1.3 strlen1.4 setex1.5 mset/mget1.6 setrange/getrange1.7 setnx1.8 incr…

数据库管理工具的使用

目录 摘要 一、Navicat是什么&#xff1f; 二、使用步骤 1.如何下载与安装 2.如何连接远程数据库 总结 摘要 本文主要介绍数据库管理工具的使用 一、Navicat是什么&#xff1f; 它是一款数据库管理工具&#xff0c;将此工具连接数据库,你可以从中看到各种数据库的详细…

JavaScript 面向对象【快速掌握知识点】

目录 类和对象 属性和方法 继承 多态 封装 类和对象 类是用于定义对象的模板或蓝图&#xff1b;它包含对象的属性和方法&#xff0c;我们可以使用class关键字来定义类。 class Person {constructor(name, age) {this.name name;this.age age;}sayHello() {console.log(H…

JSP+SQL电量监视系统设计与实现

技术&#xff1a;Java、JSP等摘要&#xff1a;电脑界常有一股又一股的风潮&#xff0c;在这风潮中&#xff0c;JBuilder 是使用最广泛的工具之一。JBuilder6 提供了可视化集成开发工具&#xff0c;支持开发人员构建标准的爪哇应用系统。其开放的环境、基于组建的开发方式和丰富…

【软件测试面试题】2023年测试人面试专属,最全接口测试面试题大全(附回答)

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 1、HTTP和HTTPS协议…

2022年全国职业院校技能大赛(中职组)网络安全竞赛试题A(9)

目录 竞赛内容 模块A 基础设施设置与安全加固 一、项目和任务描述&#xff1a; 二、服务器环境说明 三、具体任务&#xff08;每个任务得分以电子答题卡为准&#xff09; A-1任务一 登录安全加固&#xff08;Windows&#xff09; 1.密码策略 a.更改或创建密码时执行复杂…