我对Webpack的理解

先下载nodejs,因为webpack里面有东西要依赖nodejs

1.了解

  1. 事实上随着前端的快速发展,目前前端的开发已经变的越来越复杂了:

1.比如开发过程中我们需要通过模块化的方式来开发;
比如也会使用一些高级的特性来加快我们的开发效率或者安全性,比如通过ES6+、TypeScript开发脚本逻辑,
通过sass、less等方式来编写css样式代码;
2.比如开发过程中,我们还希望实时的监听文件的变化来并且反映到浏览器上,提高开发的效率;
比如开发完成后我们还需要将代码进行压缩、合并以及其他相关的优化;
但是对于很多的前端开发者来说,并不需要思考这些问题,日常的开发中根本就没有面临这些问题:
这是因为目前前端开发我们通常都会直接使用三大框架来开发:Vue、React、Angular; p但是事实上,这三大框架的创建过程我们都是借助于脚手架(CLI)的;
事实上Vue-CLI、create-react-app、Angular-CLI都是基于webpack来帮助我们支持模块化、less、
TypeScript、打包优化等的;

2.定义–官方的解释:

webpack是一个静态的模块化打包工具,为现代的JavaScript应用程序;
我们来对上面的解释进行拆解:

打包bundler:webpack可以将帮助我们进行打包,所以它是一个打包工具
静态的static:这样表述的原因是我们最终可以将代码打包成最终的静态资源(部署到静态服务器);
模块化module:webpack默认支持各种模块化开发,ES Module、CommonJS、AMD等;
现代的modern:我们前端说过,正是因为现代前端开发面临各种各样的问题,才催生了webpack的出现和发展

打包的对象

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

1.理解webpack webpack-Cli安装关系

webpack的安装目前分为两个:webpack、webpack-cli
那么它们是什么关系呢?
执行webpack命令,会执行node_modules下的.bin目录下的webpack; p webpack在执行时是依赖webpack-cli的,如果没有安装就会报错;
而webpack-cli中代码执行时,才是真正利用webpack进行编译和打包的过程;
所以在安装webpack时,我们需要同时安装webpack-cli(第三方的脚手架事实上是没有使用webpack-cli的,而是类似于自
己的vue-service-cli的东西)

全局安装和局部安装(多个项目使用多个webpack版本进行打包编译,避免一个低版本的项目使用高版本打包出现报错)

小知识:
命令解析 输入 npm run bulid 就是 输入 npm run bulid 是等价的
“scripts”: {
“bulid”:“webpack”
}

2.掌握webpack打包入口和出口

打包入口没有设置就找 /src/index.js文件,找不到就报错,所以我们使用命令 就可以修改入口和出口了!但是

npx webpack --entry ./src/main.js --output-path ./bulid

把他设置到

"scripts": {
	    "bulid":"npx webpack --entry ./src/main.js --output-path ./bulid"
}

这个句子太长了不适合而且配置巨多,不适合放在这里的,所以应该有了webpack的配置文件

重点来了

所以就出现了webpack.config.js进行webpack的配置

const path=require('path')

module.exports = {
	// 相对路径
  entry: './src/main.js',
  output: {
    // 这里使用绝对路径,不可以用相对路径
    // path:"D:/Desktop/webpack-test/bulid"
    // 这里是一个拼接函数path.resolve()    __dirname是当前文件的绝对路径拼接上 ./build路径 
    // 先定位文件夹,之后才是里面的文件
    path:path.resolve(__dirname,'./build'),
    filename:"bundle.js"
  },
}

webpack使用的是node.js的common.js模块化语法,出现了require

3. 指定配置文件

但是如果我们的配置文件并不是webpack.config.js的名字,而是其他的名字呢?

比如我们将webpack.config.js修改成了 wk.config.js; 这个时候我们可以通过 --config 来指定对应的配置文件;
但是每次这样执行命令来对源码进行编译,会非常繁琐,所以我们可以在package.json中增加一个新的脚本:
指定配置文件
webpack --config wk.config.js
之后我们执行 npm run build来打包即可。

3.1心得

我们使用的语法规范都是common.js和es6的规范(浏览器无法识别),webpack就是帮我们进行编译成浏览器可以运行的的代码

Js创建单独对象语法

const divEl=document.createElement("div")
divEl.className="title"
divEl.innerHTML="你好啊"
document.body.appendChild(divEl)

4. Css-loader模块

ERROR in ./src/css/index.css 1:0
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> .title {
|   color: red;
|   font-size: 30px;
 @ ./src/main.js 3:0-24

上面的错误信息告诉我们需要一个loader来加载这个css文件,但是loader是什么呢?
1.loader 可以用于对模块的源代码进行转换;
我们可以将css文件也看成是一个模块,我们是通过import来加载这个模块的;
2.在加载这个模块时,webpack其实并不知道如何对其进行加载,我们必须制定对应的loader来完成这个功能; 那么我们需要一个什么样的loader呢?
3.对于加载css文件来说,我们需要一个可以读取css文件的loader; p这个loader最常用的是css-loader;
css-loader的安装:
npm install css-loader -D

webpack的配置

const path = require('path')

module.exports = {
  entry: './src/main.js',
  output: {
    // 这里使用绝对路径,不可以用相对路径
    // path:"D:/Desktop/webpack-test/bulid"
    // 这里是一个拼接函数
    path: path.resolve(__dirname, './build'),
    filename: 'bundle.js',
  },
  // 记载模块
  module: {
    rules: [
      // 当我们遇到.css结尾的文件,使用设置的loader进行加载
      {
        test: /\.css$/, //正则表达式
        // 可能需要多个loader,所以是数组
        use: ['css-loader'],
      },
    ],
  },
}

进行module配置

5. 认识Style-locder

我们已经可以通过css-loader来加载css文件了
但是你会发现这个css在我们的代码中并没有生效(页面没有效果)。 这是为什么呢?
安装style-loader:
npm install style-loader -D

重点

1.因为css-loader只是负责将.css文件进行解析,并不会将解析之后的css插入到页面中;
2.如果我们希望再完成插入style的操作,那么我们还需要另外一个style-loader;

配置

那么我们应该如何使用style-loader: 在配置文件中,添加style-loader;
注意:因为loader的执行顺序是从右向左(或者说从下到上,或者说从后到前的),所以我们需要将style-loader写到css-loader的前面;

 use: ['style-loader', 'css-loader'],

6.Less的使用

这个时候我们就可以使用less-loader,来自动使用less工具转换less到css

 {
        // i是忽略大小写
        test: /\.less$/i,
        use: ['style-loader', 'css-loader', 'less-loader'],
      },

7. file-loader模块

要处理jpg、png等格式的图片,我们也需要有对应的loader:file-loader(否则就会报错,无法解析)

  • file-loader的作用就是帮助我们处理import/require()方式引入的一个文件资源,并且会将它放到我们输出的文件夹中;

7.1 怎么样算是一个模块

处理import/require()方式引入的一个文件资源,

错误做法

正确做法

import nhlt from '../img/nhlt.jpg'
const imgEl = document.createElement('img')
imgEl.src = nhlt
document.body.appendChild(imgEl)

错误做法:

const imgEl = document.createElement('img')
imgEl.src = "../scr/nglt.jpg"
document.body.appendChild(imgEl)

我们就是想导入图片显示在html上面,但是他不是一个模块,应该使用require() 或者 import 的方式导入才是一个模块(!!!打包前,图片模块webpack会帮我们处理好图片路径引入的问题,不会出现路径无效的问题),在js文件中(不是css文件)而不是使用图片绝对/相对路径导入,这样才会出现在模块化图之中

图片配置:
{
        test: /\.(png|gif|svg|jpe?g)$/i,
        use: {
          loader: 'file-loader',
          options: {
            // 文件夹名字
            outputPath: 'img',
            name:"[name]_[hash:6].png"
          },
        },
      },

[name] 就是原本文件名字
[hash:6] 就是6个hash值
可以使用PlaceHolders — 完整知识

[ext]: 处理文件的扩展名;
[name]:处理文件的名称;
[hash]:文件的内容,使用MD4的散列函数处理,生成的一个128位的hash值(32个十六进制);
[contentHash]:在file-loader中和[hash]结果是一致的(在webpack的一些其他地方不一样,后面会讲到);
[hash:]:截图hash的长度,默认32个字符太长了;
[path]:文件相对于webpack配置文件的路径;

8.url-loader模块

url-loader和file-loader的工作方式是相似的,但是可以将较小的文件,转成base64的URI。

    在网络请求一个中,优先请求html,在请求中图片越多,服务器压力越大,请求时间越长,而且真实开发中也有海量图片,这是一个难题
     解决的办法有:精灵图,bse64

webapck的url-loader默认打包的图片会转化为base64

在这里插入图片描述
在dom变成这样

 {
        test: /\.(png|gif|svg|jpe?g)$/i,
        use: {
          loader: 'url-loader',
          options: {
            // 文件夹名字
            outputPath: 'img',
            name:"[name]_[hash:6].png",
            // 小于100kb的为bse64,大于100kb的是模块化打包
            limit:1024*100
          },
        },
  },

9. webpack5的特点(asset资源模块)(重点)

  1. 我们当前使用的webpack版本是webpack5: 在webpack5之前,加载这些资源我们需要使用一些loader,比如raw-loader 、url-loader、file-loader;
  2. 在webpack5开始,我们可以直接使用资源模块类型(asset module type),来替代上面的这些loader;
  3. 资源模块类型(asset module type),通过添加 4 种新的模块类型,来替换所有这些 loader: passet/resource 发送一个单独的文件并导出 URL。之前通过使用 file-loader 实现;

passet/inline 导出一个资源的 data URI。之前通过使用 url-loader 实现;
passet/source 导出资源的源代码。之前通过使用 raw-loader 实现;
passet 在导出一个 data URI 和发送一个单独的文件之间自动选择。之前通过使用 url-loader,并且配置资源体
积限制实现;

asset/resource
{ 
        test: /\.(jpe?g|png|gif|svg)$/i,
        type: 'asset/resource',

上面的代码是打包的图片是没有放在文件夹和base64的

{ 
        test: /\.(jpe?g|png|gif|svg)$/i,
        type: 'asset',
        // 命名
        generator:{
          filename:"img/[name]_[hash:6][ext]"
        },
        //base64
        parser: {
          dataUrlCondition: {
            maxSize: 100 * 1024,
          },
        },
      },

10.字体模块

 <i class="iconfont icon-ashbin"></i>

使用file-loader模块进行打包,

{
        test:/\.(eot|ttf|woff2?)$/,
        use:{
          loader:"file-loader",
          options:{
            name:"font/[name]_[hash:4].[ext]"
          }
        }
      }

loader是加载模块的

plugin插件

Webpack的另一个核心是Plugin,官方有这样一段对Plugin的描述:
pWhile loaders are used to transform certain types of modules, plugins can be leveraged to perform a
wider range of tasks like bundle optimization, asset management and injection of environment
variables

区别: 1.Loader是用于特定的模块类型进行转换;
2.Plugin可以用于执行更加广泛的任务,比如打包优化、资源管理、环境变量注入等;

1. CleanWebpackPlugin插件

下载: npm install clean-webpack-plugin -D

插件都是Class类,之后调用里面的hook函数
插件需要实例化才能使用,因为插件是类,需要实例化

const path = require('path')
// 这里引入插件
const { CleanWebpackPlugin } = require('clean-webpack-plugin')

module.exports = {
  entry: './src/main.js',
  output: {
    path: path.resolve(__dirname, './build'),
    filename: 'bundle.js',
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader', 'postcss-loader'],
      },
      {
        test: /\.less$/,
        use: ['style-loader', 'css-loader', 'less-loader'],
      },

      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        type: 'asset',

        parser: {
          dataUrlCondition: {
            maxSize: 100 * 1024,
          },
        },
      },
      {
        test: /\.(eot|ttf|woff2?)$/,
        use: {
          loader: 'file-loader',
          options: {
            name: 'font/[name]_[hash:4].[ext]',
          },
        },
      },
    ],
  },
  // 这里进行实例化
  plugins: [new CleanWebpackPlugin()],
}

作用:这个插件的作用就是清除dist文件里面的东西,之后重新生成新的文件,这样我们自动清除里面无关文件和无须手动清除(因为之前,每次修改了一些配置,重新打包时,都需要手动删除dist文件夹)

2. HtmlWebpackPlugin插件

插件是第三方开发的,有时候会出现使用方法不同的情况
出现原因:

我们的HTML文件是编写在根目录下的,而最终打包的dist文件夹中是没有index.html文件的。
在进行项目部署的时,必然也是需要有对应的入口文件index.html; 所以我们也需要对index.html进行打包处理

默认情况下是根据ejs的一个模板来生成的;
p在html-webpack-plugin的源码中,有一个default_index.ejs模块;

如果我们想在自己的模块中加入一些比较特别的内容:
p比如添加一个noscript标签,在用户的JavaScript被关闭时,给予响应的提示;
比如在开发vue或者react项目时,我们需要一个可以挂载后续组件的根标签

 new HtmlWebpackPlugin({
      template: '',
      title:""
    }),

template:指定我们要使用的模块所在的路径; ptitle:在进行htmlWebpackPlugin.options.title读取时,就会读到该信息;
我们设置的模板就是要先设置好这些设置,在vue-cli才会生成这个html文件,才会用在挂载上.

3.DefinePlugin允许在编译时创建配置的全局常量,是一个webpack内置的插件(不需要单独安装)

const { DefinePlugin } = require('webpack')
new DefinePlugin({
      BASE_URL:'"./"'
    })

4. source-map

devtool: "source-map",

打包后,多建立js映射文件,方便调试!
最大的好处就是报错的时候,能在控制台看到我们是打包之前是哪个文件出错误了,而不是一个打包后的bundle.js文件

5. CopyWebpackPlugin模块

在vue的打包过程中,如果我们将一些文件放到public的目录下,那么这个目录会被复制到dist文件夹中。
这个复制的功能,我们可以使用CopyWebpackPlugin来完成;

安装CopyWebpackPlugin插件:
接下来配置CopyWebpackPlugin即可:
复制的规则在patterns中设置;
from:设置从哪一个源中开始复制;
to:复制到的位置,可以省略,会默认复制到打包的目录下;
globOptions:设置一些额外的选项,其中可以编写需要忽略的文件:
.DS_Store:mac目录下回自动生成的一个文件;
index.html:也不需要复制,因为我们已经通过HtmlWebpackPlugin完成了index.html的生成;

new CopyWebpackPlugin({
      patterns: [
        {
          from: "public",
          to: "./",
          globOptions: {
            ignore: [
              "**/index.html"
            ]
          }
        }
      ]
    })

6.mode模式

不同模式下会帮我们自动配置很多东西的

Mode配置选项,可以告知webpack使用响应模式的内置优化:
默认值是production(什么都不设置的情况下);
可选值有:‘none’ | ‘development’ | ‘production’;

在这里插入图片描述

7. Vue-cli生成webpack.config.js

npm install generate-asset-webpack-plugin --save-dev

8. Babel

1.作用:

开发中,我们想要使用ES6+的语法,想要使用TypeScript,开发React项目,它们都是离不开Babel的; 所以,学习Babel对于我们理解代码从编写到线上的转变过程至关重要; n那么,Babel到底是什么呢?
pBabel是一个工具链,主要用于旧浏览器或者环境中将ECMAScript 2015+代码转换为向后兼容版本的
JavaScript; 包括:语法转换、源代码转换等;

2.

babel本身可以作为一个独立的工具(和postcss一样),不和webpack等构建工具配置来单独使用。(使用命令行更新ts的文件)
如果我们希望在命令行尝试使用babel,需要安装如下库:
@babel/core:babel的核心代码,必须安装;
@babel/cli:可以让我们在命令行使用babel;

npm install @babel/cli @babel/core -D

使用babel来处理我们的源代码:
src:是源文件的目录;
–out-dir:指定要输出的文件夹dist;
npx babel src --out-dir dist

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@追求卓越

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值