webpack知识点(比针还细)

webpack

前言:

        现今的很多网页其实可以看做是功能丰富的应用,它们拥有着复杂的JavaScript代码和一大堆依赖包。为了简化开发的复杂度,前端社区涌现出了很多好的实践方法

模块化

        让我们可以把复杂的程序细化为小的文件;类似于TypeScript这种在JavaScript基础上拓展的开发语言:使我们能够实现目前版本的JavaScript不能直接使用的特性,并且之后还能转换JavaScript文件使浏览器可以识别;Scss,less等CSS预处理器;

        这些改进确实大大的提高了我们的开发效率,但是利用它们开发的文件往往需要进行额外的处理才能让

浏览器识别,而手动处理又是非常繁琐的,这就为WebPack类的工具的出现提供了需求。

什么是webpack?

        WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一

        些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其转换和打包为合适的格式供浏览器。

新建项目

下面我们来创建一个webpack项目:

        1.先在根目录下使用npm init命令创建package.json文件,然后再创建其他的文件以及文件夹。

以下是目录的结构:

webpack_demo/
┣ src/
┃ ┣ components/
┃ ┃ ┣ common.js
┃ ┃ ┗ util.js
┃ ┗ app.js
┣ index.html
┗ package.json
 

        2.我们现在创建一个src文件夹,然后在里边创建一个app.js文件(需要打包的文件)以及一个components文件夹,在components文件夹中创建两个文件,一个是common.js文件,另一个是util.js文件,两个文件里边是要默认导出的数据。然后在app.js文件里边导入components文件夹里的两个文件并暴露出去。

        3.在根目录下创建一个index.html文件,引入app.js。

        4.此时我们是运行是无法打印components文件夹里的两个文件中需要打印的内容。我们需要使用webpack的命令将components中的两个文件打包成一个文件,从而使浏览器能够识别。我们可以使用:

npx webpack ./src/app.js 

        这个命令将 两个文件打包合并成一个文件,这个文件默认会放在dist文件夹中,并且会命名为main.js。

5.我们还可以对main.js文件进行压缩,可以使用:

 npx webpack --config ./webpack.config.js

命令进行打包压缩。

webpack 的配置

基本配置

        entry**:**表示 webpack 的入口,指定打包的文件,可以一个或多个。

        output**:**表示输出文件的路径和文件名。

        mode**:**表示打包环境,可设置 production 或 development 值。

const path = require('path')
module.exports = {
entry: './src/app.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'main.js',
clean: true
},
mode: 'development'
}

Loader

格式:

module.exports = {
....
module: {
rules: []
}
}

处理css

        先在 src 下创建 css 文件夹,然后新建一个 css 文件,里边写一些样式代码,在 index.html 中新增

div,使样式生效,然后在 app.js 中引入,此时项目结构为:

webpack_demo/
┣ src/
┃ ┣ components/
┃ ┃ ┣ common.js
┃ ┃ ┗ util.js
┃ ┣ css/
┃ ┃ ┗ index.css
┃ ┗ app.js
┣ index.html
┣ package.json
┗ webpack.config.js
我们先安装css的依赖
pnpm i css-loader style-loader -D

插入的内容
module: {
rules: [
{
test: /\.css$/,
//解析的顺序是从右往左的,所以loader的顺序是有要求的
use: ['style-loader', 'css-loader']
}
]
}
index.css 的内容为
.box1 {
width: 100px;
height: 100px;
background-color: red;
}
我们需要再app.js中引入css文件,app.js 内的内容为:
import common from "./components/common";
import util from "./components/util";
import './css/index.css' // 新增的引入 css
common()
util()
index.html 的内容为
<script src="./dist/main.js"></script>
<body>
<div class="box1"></div> <!-- 新增的div -->
</body>

完成以上步骤后重新打包

处理 Sass、Less

        他的步骤和css的步骤是一样的,同样我们也要安装他们的依赖包

pnpm i less less-loader sass sass-loader -D
插入的内容
{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader'],
},
// 处理 sass
{
test: /\.s[ac]ss$/,
use: ['style-loader', 'css-loader', 'sass-loader'],
}

处理图片:

        我们需要再src文件夹中在新建一个文件夹用于放置图片
webpack_demo/
┣ src/
┃ ┣ components/
┃ ┃ ┣ common.js
┃ ┃ ┗ util.js
┃ ┣ css/
┃ ┃ ┣ index.css
┃ ┃ ┣ index.less
┃ ┃ ┗ index.sass
┃ ┣ images/
┃ ┃ ┣ 1.jpg
┃ ┃ ┗ 2.jpg
┃ ┗ app.js
┣ index.html
┣ package.json
┗ webpack.config.js
我们现在index.css文件中将图片设置好
.img1 {
width: 150px;
height: 200px;
background-image: url('../images/1.jpg');
background-size: cover;
}
.img2 {
width: 150px;
height: 200px;
background-image: url('../images/2.jpg');
background-size: cover;
}
index.html 中新增的内容为
<div class="img1"></div>
<div class="img2"></div>

        因为内置了依赖包所以我们不用下载依赖包

新增的loader
{
test: /\.(png|jpe?g|gif|svg|webp)$/,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 200 * 1024
}
}
}

更改 放置图片的路径

        图片打包后的输出目录与 main.js 在同一目录,那如果要把图片打包放到dist/static/images 目录下呢,那么就可以 使用 generator 字段:

{
test: /\.(png|jpe?g|gif|svg|webp)$/,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 200 * 1024
}
},
generator: {
filename: 'static/images/[hash][ext][query]'
}
}

generator 中的 filename 指定存放的目录

[hash]: 表示hash值,后面可携带自定义位数,例如[hash:8]

[ext]:原文件扩展名

[query]:添加之前的query参数

处理字体图标:

        老样子,在 src 下新建一个 fonts 文件夹,然后在阿里巴巴矢量图标库中下载图标(这里使用 Font class的使用方式),将下载的字体文件放到 fonts 文件夹中,将下载的 iconfont.css 文件放到 css 文件夹中,然后在 app.js 中引入,并在 index.html 中新增标签:

目录结构
webpack_demo/
┣ src/
┃ ┣ components/
┃ ┃ ┣ common.js
┃ ┃ ┗ util.js
┃ ┣ css/
┃ ┃ ┣ iconfont.css
┃ ┃ ┣ index.css
┃ ┃ ┣ index.less
┃ ┃ ┗ index.sass
┃ ┣ fonts/
┃ ┃ ┣ iconfont.ttf
┃ ┃ ┣ iconfont.woff
┃ ┃ ┗ iconfont.woff2
┃ ┣ images/
┃ ┃ ┣ 1.jpg
┃ ┃ ┗ 2.jpg
┃ ┗ app.js
┣ index.html
┣ package.json
┗ webpack.config.js
在app.js中引入iconfont.css
import './css/iconfont.css'
index.html 新增内容为
<span style="font-size: 36px; color: red;" class="iconfont icon-aixin">
</span>
增加loader
{
test: /\.(ttf|woff|woff2)$/,
type: 'asset/resource',
generator: {
filename: 'static/font/[hash][ext][query]'
}
}

处理 CSS 兼容性

        通过 loader,可以将一些较新的 CSS 语法能够在低版本浏览器中使用,而这个 loader 就是 postcssloader,但这个 loader 还依赖 postcss 和 postcss-preset-env,所以需要安装三个模块:

安装依赖包
pnpm i postcss-loader postcss postcss-preset-env -D

修改css的loader

        除了修改以上配置以外,在 package.json 中新增:"browserslist": ["ie >= 7"]

{
"name": "webpack_demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "webpack --config ./webpack.config.js"
},
"author": "",
"devDependencies": {
....
},
"browserslist": ["ie >= 7"]
}

在 index.css 中新增 display: flex;

完成以上步骤后打包

处理 JS 兼容性

        通过 loader ,还可以将 JS 语法在较低的浏览器版本中使用,主要就是通过 babel,同样需要安装三个模块,一个 loader,一个核心库,一个预设,分别就是 babel-loader、@babel/core、@babel/presetenv:

pnpm i babel-loader @babel/core @babel/preset-env -D

babel-loader 使用 Babel 加载 ES2015+ 代码并将其转换为 ES5

        @babel/core Babel 编译的核心包

        @babel/preset-env Babel 编译的预设,可以理解为 Babel 插件的超集

增加loader
{
test: /\.js$/,
exclude: /node_modules/,
use: ['babel-loader']
}
新增bable.config.js

在项目根目录新建一个 babel.config.js 配置文件

module.exports = {
presets: ['@babel/preset-env']
}

在app.js文件中新增测试代码

function count(...arg) {
console.log(arg[0] + arg[1])
}
count(1,2)

Plugin

        webpack 的插件能够增强 webapck 的功能,本身 webpack 只是解析依赖从而打包,loader 使

webpack 能够转化文件,而 plugins 则使 webpack 能够拥有压缩,提取等更大强大的功能。

        webpack 的插件主要在 plugins 字段上,是个数组,也就是可以使用多个插件,每个插件在使用的时候都必须传入一个 new 实例。

提取 CSS 为单独文件

安装这个插件
pnpm i mini-css-extract-plugin -D
然后修改 webpack 的配置

引入 mini-css-extract-plugin,然后在 plugins 中设置,最后将 style-loader 替换成

MiniCssExtractPlugin.loader

打包
手动引入

        打包后确实将 css 提取到单独的文件里了,但是 html 中还需要手动引入

自动引入 JS CSS

        上面打包后,不管是 JS 还是 CSS 打包为单独文件时,在 index.html 中都需要手动引入相应的资源,如果修改了 webpack 打包 JS 和 CSS 文件的路径,那么 index.html 也需要修改。

基于以上问题,可以通过 HtmlWebpackPlugin 插件解决。

安装依赖
pnpm i html-webpack-plugin -D
修改webpack配置

        先引入 html-webpack-plugin,然后将其添加到 plugins 中,同时将 index.html 中引入 css 和 js 的代码

注释。

打包后,可看到在 dist 下有一个 index.html

压缩 CSS

安装依赖
pnpm i css-minimizer-webpack-plugin -D
修改 webpack :

        还是那样,引入 css-minimizer-webpack-plugin,然后在 plugins 中添加,最后修改 mode(cssminimizer-webpack-plugin 默认在生产模式在才生效),打包后效果如下

自动清空打包目录

        每次打包的时候,打包目录都会遗留上次打包的文件,为了保持打包目录的纯净,我们需要在打包前将打包目录清空这里我们可以使用插件 clean-webpack-plugin 来实现

安装

pnpm i clean-webpack-plugin -D

配置

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
// 引入插件
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
// ...
plugins:[ // 配置插件
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new CleanWebpackPlugin() // 引入插件
]
}

DevServer

        devserver 可以在本地启动一个服务,使我们可以使用 http 协议去访问 index.html ,并且当修改代码时,能够监听当前项目的文件变动从而实现自动打包,而不用每次修改后都要手动打包:

        在 webpack 配置中添加 devServe 字段,里边配置 host、port等。同时还需要安装 webpack-dev

server 模块:

安装

pnpm i webpack-dev-server -D

        同时,webpack 打包命令也需要添加一个 serve 参数才能调用 webpack-dev-server:

        启动 server 前,可以先将 dist 目录下的文件清空,然后再运行 npm run dev,可以发现 dist 下并没有

        生成任何文件,这是因为server 打包后是放在内存中的,所以 dist 下也不需要任何文件,server 一般是在开发环境下使用的,如果在生产环境,就需要打包到本地了。

开发模式与生产模式

        经过上面的配置,webpack 配置是有 development production 区分的,在开发环境下,通过 devserver 启动,就不会生成 dist 文件夹,而生产模式下又恰恰需要,为了避免在两种模式打包而需要 来回修改 webpack 的配置文件的内容,可以通过判断当前打包环境,从而决定是否需要 devServer 或者 设置 mode 值等:

模式: mode 配置选项,告知 webpack 使用相应模式的内置优化,默认值为 production
另外还有 development none ,他们的区别如下      
选项
描述
        development
                开发模式,打包更加快速,省了代码优化步骤
        production
                生产模式,打包比较慢,会开启 tree-shaking 和 压缩代码
        none
                不使用任何默认优化选项

        添加 build 命令
        上面就是通过判断 process.env.NODE_ENV 的值来决定是否使用 devServer
上面配置好后,还需要在 package.json scripts 中添加 build 命令,以便方便打包:

build 就不需要 serve 参数了,运行 npm run build 进行打包,这样虽然可以打包,但是会发现有
warning ,提示 mode 没有设置,这时打印 process.env.NODE_ENV 的值为 undefined ,所以会报
warning
可以使用 cross-env 模块来设置 node 的环境变量:
pnpm i cross-env -D
同时修改 scripts

webpack的优化

       1、OneOf

        oneOf 的作用是可以减少匹配 loader 的时间,因为使用了 OneOf ,当匹配到某一个规则时,只使用第 一个。
// webpack.config.js
 
module.exports = {
  module: {
    rules: [
      {
        oneOf: [
          {
            test: /\.css$/,
            use: ['style-loader', 'css-loader'],
          },
          {
            test: /\.scss$/,
            use: ['style-loader', 'css-loader', 'sass-loader'],
          },
          //OneOf配置内的其他规则
        ],
      },
    ],
  },
};

include/Exclude

        Include/Exclude 的作用就顾名思义了,可以指定处理文件时,只包含哪些文件或者排除哪些文件,两者 不能同时使用。
// webpack.config.js
 
module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
        },
      },
      //具有包含和排除配置的其他规则
    ],
  },
};
        Include/Exclude 也可以提升代码打包速度,毕竟不管是 Include 还是 Exclude 都排除掉了一部分的文 件。

SourceMap

        sourcemap 可以在打包后增强代码调试,因为打包后的代码是压缩过的,当代码报错时就会提示错误的 位置。sourcemap 会影响打包的速度。
// webpack.config.js
 
module.exports = {
  devtool: 'source-map',
  //其他配置项
};

Babel缓存

        Babel 缓存同样可以提升代码打包速度, Babel 的缓存可以在第一次打包时将转换过的代码缓存起来,下 次再进行打包时就可以避免部分代码的再次转换,从而提升打包速度。Babel 缓存的开启在 Babel 的配置中使用 cacheDirectory
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            cacheDirectory: true, // 启用缓存
          }
        }
      }
    ]

化resolve配置

        在 webpack 中,alias 用于创建模块的别名,以便更轻松地引用模块。要配置 alias,可以在 webpack 的配置文件中使用 resolve.alias 选项。通过将 resolve.alias 添加到 webpack 配置中,可以使用短名称来引用长路径,使代码更易读和易维护。
        

const path = require('path');
module.exports = {
  resolve: {
    alias: {
      // 将 'components' 别名指向 './src/components' 目录
      components: path.resolve(__dirname, 'src/components'),
      // 将 'utils' 别名指向 './src/utils' 目录
      utils: path.resolve(__dirname, 'src/utils')
    }
  }
};

extensions

        在Webpack中,extensions 选项用于配置在导入模块时可以省略的文件扩展名。这使开发时能够在导入模块时不必指定完整的文件名,从而简化代码。通过配置 extensions 选项,可以告诉Webpack在导入模块时自动解析指定的文件扩展名。例如:

resolve: {
  extensions: ['.js', '.jsx']
}

thread-loader

  thread-loader 是JS代码块进行处理的 Webpack 加载器。它可以将这些代码块放入 worker 池中以进行并行处理,从而提高构建性能。

首先在终端输入以下命令进行安装

pnpm i -D thread-loader

        要在 Webpack 中使用 thread-loader,需要webpack.config.js 文件中配置相应的 loader 规则:

 
use: [
    {
        loader: 'thread-loader', // 开启多进程打包
        options: {
            worker: 3,
        }
    },
    'babel-loader',
]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值