Webpack5——2022保姆级基础教程

Webpack

  • 1、Webpack
  • 2、下载使用
  • 3、配置Webpack
    • 3.1 模式mode
    • 3.2 入口entry
    • 3.3 依赖图
    • 3.4 出口output
    • 3.5 loader
      • 配置使用
      • 内联使用
      • style-loader
      • less-loader
      • Browserslistrc配置
      • postcss-loader
      • importLoaders属性
      • file-loader处理图片
        • img.src
        • background-image url
        • 设置图片名称与输出
      • url-loader
      • asset
      • babel-loader
      • polyfill
    • 3.6 插件plugins
      • clean-webpack-plugin
      • html-webpack-plugin
      • copy-webpack-plugin

1、Webpack

Webpack是一个现代 JavaScript 应用程序的静态模块打包器

  • 打包:可以把js、css等资源按模块的方式进行处理然后再统一打包输出
  • 静态:最终产出的静态资源都可以直接部署到静态资源服务器上进行使用
  • 模块:webpack支持不同规范的模块化开发(ESmodule、commonJS等)

2、下载使用

先建一个文件夹,用VScode打开,并执行npm init -y进行初始化

之后在总端执行如下命令安装webpackwebpack脚手架,这里的-- save -dev(-D)表示安装到开发依赖中,项目上线后不会用到该插件。

npm install --save-dev webpack
npm install --save-dev webpack-cli

如图所示
Webpack5——2022保姆级基础教程_第1张图片
之后我们简单的使用一下webpack

如下我们创建两个文件夹dist和src,并分别在这两个文件夹里创建index.htmlindex.js
Webpack5——2022保姆级基础教程_第2张图片
index.js

alert("hello");

之后在终端执行npx webpack,它会以index.js作为入口文件,然后在dist文件夹中生成一个main.js文件。

接着我们在index.html中引入main.js文件

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>Documenttitle>
head>
<body>
    <script src="main.js">script>
body>
html>

在浏览器中打开 index.html,如图所示。
Webpack5——2022保姆级基础教程_第3张图片


扩展: 除了执行npx webpack可以打包静态文件外,我们还可以配置package.json中的scripts。在下面这个配置中,执行npm run build也可以打包静态文件。

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

3、配置Webpack

webpack是高度可配置的,我们可以自己配置适合自己项目的webpack.config.js文件。如下所示,在package.json的同级目录下创建webpack.config.js文件。
Webpack5——2022保姆级基础教程_第4张图片
注意:名字可以自定义,比如这里我定义为my.config.js,在package.json中的scripts中修改命令即可。

"build":"webpack --config my.config.js"

3.1 模式mode

提供 mode 配置选项,告知 webpack 使用相应模式的内置优化。其可取值为
productiondevelopmentnone

  • development指的是开发环境,开发环境就是我们写代码的环境
  • production生产环境,,生产环境就是代码放到线上的环境。production会专门对正式环境做一些优化如移除map文件,添加代码压缩
module.exports = {
  mode: 'production'
};

Webpack5——2022保姆级基础教程_第5张图片

3.2 入口entry

入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。

比如上面那个例子,我们的入口文件就是src中的index.js

我们可以在 webpack.config.js 配置中配置 entry 属性,来指定一个入口起点(或多个入口起点),默认值为 ./src。

module.exports = {
 // webpack从这里开始打包
  entry: './src/index.js'
};

注意:可以使用相对路径

3.3 依赖图

一个文件依赖于另一个文件,webpack 就把此视为文件之间有依赖关系 。这使得 webpack 可以接收非代码资源(例如图像或 web 字体),并且可以把它们作为 依赖提供给你的应用程序。

webpack 从命令行或配置文件中定义的一个模块列表开始,处理你的应用程序。 从这些 入口起点 开始,webpack 递归地构建一个 依赖图 ,这个依赖图包含着应用程序所需的每个模块,然后将所有这些模块打包为少量的 bundle ,通常只有一个 ,可由浏览器加载。

3.4 出口output

output中指明webpack如何输出结果的相关选项,比如输出的文件路径,输出的文件名字等

这里需要注意的是 output.path必须为绝对路径,否则会报错 。这里使用 Node.js 的 path 模块。

  • path.resolve() 方法将路径或路径片段的序列解析为绝对路径。
  • __dirname表示当前文件所在目录
const path = require('path');

module.exports = {
 output: {
		// 所有输出文件的目标路径,必须是绝对路径
	   path: path.resolve(__dirname, "dist"), // string
	   // 输出的文件名
	   filename: 'build.js'  
    }
}

publicPath也是一个配置,指定index.html内部的引用路径,默认为空。

没有配置时引用如下,

output: {
// 所有输出文件的目标路径,必须是绝对路径
  path: path.resolve(__dirname, "dist"), // string 
  },

在这里插入图片描述
Webpack5——2022保姆级基础教程_第6张图片
配置后,

output: {
// 所有输出文件的目标路径,必须是绝对路径
  path: path.resolve(__dirname, "dist"), // string 
  publicPath:'./'
  },

在这里插入图片描述

Webpack5——2022保姆级基础教程_第7张图片
注意:如果是使用webpack-dev-server的话,规则是:域名+publicPath+filename,配置./是不对的,要配置为/或者不配置。

3.5 loader

loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 用于对模块的源代码进行转换。

本质上,webpack loader 将所有类型的文件,转换为应用程序的依赖图可以直接引用的模块。

比如,我们在没有配置的情况下引入.css文件,执行npm run build,就会报错,因为webpack无法处理它。
在这里插入图片描述
loader允许你直接在 JavaScript 模块中 import CSS文件, 如图所示执行npm i css-loader -D
在这里插入图片描述

配置使用

module.rules 允许你在 webpack 配置中指定多个 loader。

在 webpack 的配置中 loader 有两个目标:

  • test 属性,一般为一个正则表达式,用于匹配我们需要处理的文件类型。
  • use 属性,表示进行转换时,应该使用哪个 loader。
module.exports={
    mode: 'production',
    entry:'./src/index.js',
    module:{
        rules:[
        	// 写法一
            { test: /\.css$/, use: 'css-loader' },
            // 写法二 ,可写多个loader
            { test: /\.css$/, use: ['css-loader'] }
            
        ]
    }
}

内联使用

使用!将资源中的 loader 分开

import 'css-loader!../css/index.css'

style-loader

css-loader处理后的文件并没有呈现在页面上,这时我们需要style-loader将css文件挂载在页面上。loader执行顺序是从下往上(右往左)执行,所以要先写style-loader,再写css-loader

{ test: /\.css$/, use: ['style-loader','css-loader'] }

less-loader

less-loader用于处理less文件

使用时,需要在入口文件中导入import '../css/myless.less',并且进行如下配置。

{ 
    test: /\.less$/, 
    use: ['style-loader','css-loader','less-loader'] 
}

Browserslistrc配置

browserslist就是一个用特定语句查询浏览器列表的工具,在webpack中自动带有,通过配置可以帮助我们筛选出哪些要兼容的平台。

可在package.json中配置如下

"browserslist":[
    ">1%",
    "last 4 version",
    "not dead"
]
  • ">1%"全球市场占有率大于 1% 的浏览器
  • "last 4 version"查找所有浏览器的最后 4 个版本
  • dead表示查找超过 24 个月没被官方维护的浏览器

然后在终端执行npx browserslist,如图所示
Webpack5——2022保姆级基础教程_第8张图片
也可以新建一个文件.browserslistrc,在里面配置。
Webpack5——2022保姆级基础教程_第9张图片

postcss-loader

不同的浏览器兼容性不同。例如user-select,有些浏览器可能需要加前缀才可以使用。对于如下样式

#one{
    color: #123456;
    user-select: none;
}

我们在没有配置webpack的情况下使用谷歌浏览器打开,样式正常。可是如果用其他浏览器打开就可能存在问题,即user-select无效。
Webpack5——2022保姆级基础教程_第10张图片
这时我们可以借助postcss-loaderpostcss-preset-env 来解决兼容性问题,执行如下命令下载包

npm i postcss-loader -D
npm i postcss-preset-env -D

webpack.config.js中配置如下

 { 
     test: /\.css$/, 
     use: [
         'style-loader',
         'css-loader',
         {
             loader:'postcss-loader',
             options:{
                 postcssOptions:{
                     plugins:['postcss-preset-env']
                 }
             }
         }
     ] 
 },

这样user-select就会兼容多个版本

Webpack5——2022保姆级基础教程_第11张图片
css兼容性转换可以在这个网站体会Autoprefixer

除了在webpack.config.js进行配置,还可以将其抽取出为单独的文件
Webpack5——2022保姆级基础教程_第12张图片

{ 
     test: /\.css$/, 
     use: [
         'style-loader',
         'css-loader',
         'postcss-loader'
     ] 
 },

importLoaders属性

正常情况下,我们使用的@import语句导入的css样式不会经过postcss-loader,因为在发现该文件时已经交给css-loader进行处理了,不会倒回去给postcss-loader再处理一次兼容性问题。

若想处理该问题,我们需要配置importLoaders属性。若值为1,则表示每发现一个css文件就倒退给上一个loader进行处理,即postcss-loader。同理可以取2,3,…

{ 
    test: /\.css$/, 
    use: [
        'style-loader',
        {
            loader:'css-loader',
            options:{
                importLoaders:1
            }
        },
        'postcss-loader'
    ] 
},

file-loader处理图片

img.src

如图所示,webpack默认不能打包处理require请求的图片
Webpack5——2022保姆级基础教程_第13张图片
这时可以借助file-loader进行处理

npm i file-loader -D

webpack中的配置

 {
     test:/\.(png|svg|gif|jpe?g)$/,
     use:['file-loader']
 }

require得到的是esModule,需要使用default得到具体的值

 oImg.src=require('../my.png').default

如果实在不想加default,可配置为

{
     test:/\.(png|svg|gif|jpe?g)$/,
     use:[
         {
             loader:'file-loader',
             options:{
                 esModule:false
             }
         }
     ]
 }

或者采用import xxx from 图片资源 ,此时可以直接使用xxx

注意:如果不是使用require,而是使用oImg.src='../my.png',那么webpage可以处理。

background-image url

background-image: url(../my.png);会被css-loader处理,会把url替换为require,require得到的又是esMoudle。

.bgBox{
    width: 240px;
    height: 310px;
    border: 1px solid #000;
    background-image: url(../my.png);
}

因为不能写default,所以需要在配置文件中解决

{ 
     test: /\.css$/, 
     use: [
         'style-loader',
         {
             loader:'css-loader',
             options:{
                 importLoaders:1,
                 esModule:false
             }
         },
         'postcss-loader'
     ] 
 },
设置图片名称与输出
  • [ext]:扩展名
  • [name]:文件名
  • [hash]:文件内容([contentHash类似])
  • [hash:]
test:/\.(png|svg|gif|jpe?g)$/,
use:[
     {
         loader:'file-loader',
         options:{
             esModule:false,
             name:'[name].[hash:6].[ext]',
             outputPath:'img'
            // name:'img/[name].[hash:6].[ext]',
         }
     }
 ]

Webpack5——2022保姆级基础教程_第14张图片

url-loader

  • file-loader 可以解析项目中的url引入(不仅限于css),根据我们的配置,将图片拷贝到相应的路径,再根据我们的配置,修改打包后文件引用路径,使之指向正确的文件。如果图片较多,会发很多http请求,会降低页面性能。
  • url-loaderbase-64 URL的方式加入到文件中,好处就是可以减少请求次数。但体积受限,如果图片较大,会消耗性能。

url-loader内置了file-loader。可以配置limit参数,小于limit字节的文件会被转为 base-64 URL,大于limit的还会使用file-loader进行copy。

{
  test:/\.(png|svg|gif|jpe?g)$/,
  use:[
      {
          loader:'url-loader',
          options:{
              esModule:false,
              name:'MY/[name].[hash:6].[ext]',
              // outputPath:'img'
              limit:25*1024
          }
      }
  ]
}

如图,因为图片大小为19.5KB所以转化为base-64 URL
Webpack5——2022保姆级基础教程_第15张图片
如果把limit改为15,则结果如下
Webpack5——2022保姆级基础教程_第16张图片

asset

  • asset/resource——> file-loader
  • asset/inline ——> url-loader
  • asset/source ——> raw-loader (它允许你以字符串的形式导入文件)
  • asset ——>自动选择导出为单独文件或者 dataURL形式。 功能为url-loader设置limit 限制实现。
// asset/resource——> file-loader
{
     test:/\.(png|svg|gif|jpe?g)$/,
     type: 'asset/resource',
     generator: {
         filename: 'static/[name][hash:4][ext]'
     }
 }
 // asset/inline ——> url-loader
{
     test:/\.(png|svg|gif|jpe?g)$/,
     type: 'asset/inline'
 }
// asset
 {
    test:/\.(png|svg|gif|jpe?g)$/,
    type: 'asset',
    generator: {
        filename: 'static/[name].[hash:4][ext]'
    },
    parser: {
        dataUrlCondition: {
          maxSize: 4 * 1024 
        }
    }
    
}
// asset/source ——> raw-loader
{
   test: /\.(ttf|woff2?)$/,
   type: 'asset/source'
}

asset处理字体图标

{
	test:/\.(ttf|woff2?)$/,
	type: 'asset/resource',
    generator: {
        filename: 'font/[name][hash:4][ext]'
    }
}

babel-loader

babel-loader配合@babel/preset-env可以解决JS兼容性问题,这里所兼容的浏览器需要参照Browserslistrc配置

1、下载

npm i babel-loader -D
npm i @babel/preset-env -D

2、配置

{
   test:/\.js$/,
   use:[
       {
           loader:'babel-loader',
           options:{
               presets:['@babel/preset-env']
           }
       }
   ]
}

3、示例

const title='前端'
const foo = ()=>{
    console.log(title);
}
foo()

Webpack5——2022保姆级基础教程_第17张图片
兼容性的浏览器除了Browserslistrc配置,还可以写在webpack.config.js中。如果两个都有,那么webpack.config.js中的生效

{
  loader:'babel-loader',
  options:{
      presets:[
          [
              '@babel/preset-env',
              {targets:'chrome 91'}
          ]
      ]
  }
}

除此之外,我们还可以将其抽取出为单独的文件
Webpack5——2022保姆级基础教程_第18张图片
webpack中的配置就可以简写

{
     test:/\.js$/,
     use:['babel-loader']
 }

polyfill

babel-loader配合preset-env可以解决大部分js兼容性问题,包括const、箭头函数等。但是对于generator生成器或者是promise等更新的语法时,不能解决兼容问题,这时需要polyfill。

polyfill在webpack5之前其实不用处理,默认已经加进去了。但是到了webpack5之后由于要优化打包深度,去掉了,所以现在需要自己安装配置。

在官方文档中不建议直接使用@babel/polyfill,而是用core-jsregenerator-runtime替代它。
Webpack5——2022保姆级基础教程_第19张图片
1、下载

npm i core-js regenerator-runtime

2、在babel.config.js中进行配置

module.exports={
    presets:[
        [
            '@babel/preset-env',
            {
                // 默认为fasle,不对当前JS处理做polyfill填充
                // usage:依据用户源代码当中所用到的新语法进行填充
                // entry:依据筛选出来的浏览器决定填充什么
                useBuiltIns:'entry',
                // 默认是2, 但是我们下载的是3
                corejs:3
            }
        ]
    ]
}

useBuiltIns:'entry'需要在index.js中引入以下两个包,否则不生效

import "core-js/stable";
import "regenerator-runtime/runtime";

注意:推荐使用usage,因为其打包出来的体积比entry小很多。

为了防止对node_modules中的包进行填充,需要配置exclude:/node_modules/

{
      test:/\.js$/,
      exclude:/node_modules/,
      use:['babel-loader']
  }

3.6 插件plugins

loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件目的在于解决 loader 无法实现的其他事。

1、webpack 附带了各种内置插件,可以通过 webpack.[plugin-name] 访问这些插件

2、想要使用一个插件,你只需要 require() 它,然后把它添加到 plugins 数组中。多数插件可以通过选项(option)自定义。你也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new 操作符来创建它的一个实例。

3、每一个插件本质上就是一个类

clean-webpack-plugin

clean-webpack-plugin插件在webpack打包开始之前,将我们指定的出口文件夹下的文件全部删除(一定要指定出口output才会生效)。

1、执行如下命令进行安装

npm i clean-webpack-plugin -D

2、在webpack.config.js中导入并配置

const path = require('path');
const {CleanWebpackPlugin} = require('clean-webpack-plugin')

module.exports={
    mode: 'development',
    entry:'./src/index.js',
    output: {
		// 所有输出文件的目标路径,必须是绝对路径
	   path: path.resolve(__dirname, "dist"), // string 
    },
    plugins:[
        new CleanWebpackPlugin()
    ]
}

html-webpack-plugin

可以生成创建html入口文件,比如单页面可以生成一个html文件入口,配置N个html-webpack-plugin可以生成N个页面入口

1、下载

npm i html-webpack-plugin -D

2、webpack.config.js中进行配置

var HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports= {
    ...
    plugins: [
        new HtmlWebpackPlugin({
        	title:'Html-Joney'
        })
    ]
}

注意:new里面的配置选项可以参照HtmlWebpackPlugin,我这里是把html的标题变为Html-Joney,默认为Webpack App
Webpack5——2022保姆级基础教程_第20张图片
当然我们也可以自定义生成的模板

new HtmlWebpackPlugin({
    title:'Html-Joney',
    template:'./public/index.html'
})

./public/index.html

DOCTYPE html>
<html lang="">
  <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>
        <%= htmlWebpackPlugin.options.title %>
    title>
  head>
  <body >
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.strong>
    noscript>
    <div id="app">div>
    
  body>
html>

如果我们需要一些常量,就用到了webpack自带的插件DefinePlugin

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

这里用""表明里面是字符串,不是./变量

// 没打包前
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
// 打包后
<link rel="icon" href="./favicon.ico">

copy-webpack-plugin

copy-webpack-plugin 用于拷贝文件或者整个目录到构建目录

1、下载

npm i copy-webpack-plugin -D

2、在webpack.config.js中的plugins中配置如下。可以省略to配置,默认会输出到output配置中的文件,也就是dist文件夹中,to:'public'表示输出到dist/public中。ignore表示忽视public中的Index.html文件

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

Webpack5——2022保姆级基础教程_第21张图片

你可能感兴趣的:(#,Webpack,webpack,javascript)