webpack5打包原理及应用(静态资源篇)

webpack5打包原理及应用(静态资源篇)

file-loader 使用

首先记得安装file-loader

通过创建一个元素,设置其src属性引入图片

// 新建一个pack-image.js文件如下:
function packImg () {
    // 创建容器对象
    const containerElement = document.createElement('div');

    // 创建img标签 设置src属性
    const imgElement = document.createElement('img');

    imgElement.src = require('../img/webpack.jpg');

    containerElement.append(imgElement);

    return containerElement;
}

document.body.append(packImg())

// 在入口文件中
import './js/pack-image'

正常来说会产生如下错误:
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.
原因是:webpack只能处理JavaScript格式的代码,任何非js的文件都必须转化成js代码才能进行相应的处理,所以需要加入对应的loader进行代码转化

通过安装 file-loader,并在webpack.config.js进行相应 module.rules 配置:

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

// 但是此时的html中src属性为 [object Module]  这是由于webpack版本区别导致的
// 解决方案一:可以对pack-image.js文件进行如下变更:
imgElement.src = require('../img/webpack.jpg'); => imgElement.src = require('../img/webpack.jpg').default; 

// 解决方案二:通过设置options配置项,不转为esModule
{
    test: /\.(png|gif|jpe?g)$/,
    use: {
        loader: 'file-loader',
        options: {
            esModule: false
        }
    }
}

// 解决方案三:不进行方案二的配置方式,在pack-image.js不用commonjs的方式进行导入图片,而是es6module的方式进行导入
import imgSrc from '../img/webpack.jpg'
imgElment.src = imgSrc

设置css的background-image 中 url 的值的方式引入图片

创建 css-bg.js 文件,内容如下

function cssBg(){
    const elementDiv = document.createElement('div');

    elementDiv.className = 'bgImg';

    return elementDiv;
}

document.body.append(cssBg());

css文件中放入如下内容

.bgImg {
    height: 280px;
    width: 650px;
    border: 1px solid #ddd;
    background-image: url('../../img/vue.jpeg');
}

在入口文件中

import './js/pack-image'
import './asset/css/index.css'
import './js/css-bg'

备注:上述的操作无法正常将图片显示在页面中,其中原因是会在dist(指定output文件为dist文件夹)文件夹中会出现两份文件,其中一份是图片文件(35fa0d198e2015047db5f823fe54c707.jpeg),另一份是图片后缀格式,但内容则是module.exports = __webpack_public_path__ + "35fa0d198e2015047db5f823fe54c707.jpeg";也就是导入目标图片文件的commonjs语法
出现原因:css会将url的内容默认处理为模块引入的方式
解决方案:设置css-loader打包器中的options属性的esModule为false

设置打包的图片文件名称和路径

webpack.config.js中进行配置具体配置如下:

{
    test: /\.(png|gif|jpe?g)$/,
    use: {
        loader: 'file-loader',
        options: {
            // esModule: false,
            name: '[name]-[hash:8].[ext]',
            outputPath: 'img'
        }
    }
}
// 也可只配置name属性加入路径 'img/[name]-[hash:8].[ext]' 不配置outputPath
// 打印生成的文件名称分别为:vue-35fa0d19.jpeg, vue-35fa0d19.jpeg 并且位于dist/img路径下

相应name属性中的展位符说明如下

/**
 * name 占位符
 * [ext]: 扩展名
 * [name]: 文件名
 * [hash]: 文件内容
 * [contentHash]: (此处暂同hash一致)
 * [hash:]: 可以截取hash长度
 * [path]: 文件路径
 */

url-loader的使用

备注:首先安装url-loader
设置 webpack.config.js rules如下:

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

实际上url-loader是能够起到和file-loader相似的作用:

  1. url-loader 是将图片转化base64 放入文件中,减少请求次数
  2. file-loader 是将图片拷贝到指定目录,分开请求
  3. url-loader 内部也是可以调用 file-loader的
  4. 具体体现在可以设置limit,图片大小超出阈值就进行文件拷贝

asset 打包使用

首先在没有file-loader和url-loader情况下进行打包配置
设置 webpack.config.js 文件module下的 rules 规则

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

// 如果需要配置打包生成的路径,则可以通过设置output下的assetModuleFilename
// 备注:但这种是类似于全局的配置,不适合全局资源的处理
assetModuleFilename: 'img/[name]-[hash:6][ext]' // 此处的[ext]会默认取出 `.` 故前面不需要 `.`

// 下面的方法可以为单独的匹配规则设定对应的生成文件名
{
    test: /\.(png|gif|jpe?g)$/,
    type: 'asset/resource',
    // 可以指定单独的生成的文件名
    generator: {
        filename: 'img/[name]-[hash:6][ext]'
    }
}

// 此种方式类似于前述的 url-loader 可以将图片转化成base64
{
    test: /\.(png|gif|jpe?g)$/,
    type: 'asset/inline',
}

// 此种方式可以进行较多的限制,更多自定义设置
{
    test: /\.(png|gif|jpe?g)$/,
    type: 'asset',
    generator: {
        filename: 'img/[name]-[hash:6][ext]'
    },
    parser: {
        dataUrlCondition: {
            maxSize: 24 * 1024 // 超出这个阈值将使用generator指定的方式进行拷贝
        }
    }
}

asset module type的配置

  1. asset/resource => file-loader
  2. asset/inline => url-loader
  3. asset/source => raw-loader (用的不多)
  4. asset 进行限制

字体打包使用

使用font-awesome进行测试,将下载下来的css和字体文件放置在asset/font中,通过配置font-awesome.css字体文件的指定路径对应起来
如果直接进行构建,则会出现 You may need an appropriate loader to handle this file type 报错

可以进行asset module的配置处理,做好匹配规则 => 进行产出

// 在 `webpack.config.js` 中配置如下:
{
    test: /\.(eot|svg|otf|ttf|woff2?)$/,
    type: 'asset/resource',
    generator: {
        filename: 'font/[name]-[hash:3][ext]'
    }
}

备注:进行类似于静态图片的配置,产出的字体将放置在generator指定的dist/font中去

你可能感兴趣的:(前端学习,webpack)