如何在webpack中设置favicon--webpack入门教程(四)

本文主要想介绍前端webpack打包中,与favicon图标相关的配置。包括在html-webpack-plugin中设置favicon,和自定义favicon的打包路径两个方面。本文的demo基于我之前关于webpack的一篇文章,可以移步:超详细!webpack入门教程(一)

0,需求

favicon(收藏夹图标)是一个网站的必备,在浏览器的地址栏、收藏夹中都可以看到favicon,通过favicon可以快速区分不同的网站。

考虑到一个实际的项目场景:在一个前端项目发布上线后,如果想在线上环境直接替换favicon图标,比较方便的一个方式是在webpack打包的时候,就配置好favicon的打包路径。到线上环境只要直接去对应路径,找到对应的favicon后替换即可。那么如何在webpack打包时,自定义地控制favicon的打包路径呢?通过下面的项目实例可以快速了解一下。

1,项目实例

1.1 初始项目

本文的demo基于超详细!webpack入门教程(一) 的示例做了些修改。具体构建过程,可以参考上述文章。

初始的项目的文件目录是:

初始项目文件目录

index.html的内容是:

<!DOCTYPE html>
<html>
    <head>
        <link rel="shortcut icon" href='./images/favicon.ico' />
        <meta charset="UTF-8"> 
        <title>set favicon</title> 
    </head>
    <body> 
        <div>hello</div> 
        <script src='./dist/js/app.js'></script> 
    </body> 
</html>

webpack.config.js:

const path = require('path');

module.exports = {
    entry: {
        app: __dirname + '/src/app.js',//唯一入口文件,__dirname是nodejs里的一个全局变量,它指向的是我们项目的根目录
    },
    output: {
        path: path.resolve(__dirname, './dist'),//打包后的文件存放的地方
        filename: 'js/app.js',
    }
};

在package.json的目录下打开命令窗口,执行:

npm run dev

可以看到打包后新增加了一个dist文件夹,里面有打包后的js文件。不过这里只是打包了js,下面要通过html-webpack-plugin,生成一个html文件。安装html-webpack-plugin:

npm install html-webpack-plugin --save-dev

webpack.config.js中增加配置:

const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    ...
    plugins: [
        new HtmlWebpackPlugin({ //根据模板插入css/js等生成最终HTML
            filename: '../view/index.html', //生成的html存放路径,相对于path的路径
            template: './index.html', //html模板路径
            inject: 'body', //js插入的位置,true/'head'/'body'/false
            minify: { //压缩HTML文件
                removeComments: true, //移除HTML中的注释
                collapseWhitespace: false //删除空白符与换行符
            }
        }),
    ]
    };

执行:

npm run dev

现在的目录结构是:

目录结构

可以从项目中看到打包后没有打包favicon图标。

1.2 html-webpack-plugin中设置favicon

在html-webpack-plugin中设置favicon属性,属性值是favicon所在的路径。

favicon: './images/favicon.ico',//favicon路径

添加该属性后,就会根据webpack.config.js中设置的output的path路径,在生成的html文件中生成一个link标签:

<link rel="shortcut icon" href="favicon.ico">

如果此时在浏览器中打开打包后的index.html,会发现报错找不到图标

原因是图标的路径不对,修改方式是在output中增加个publicPath属性,该属性是作用是,在打包后的index.html中,资源统一会加上的路径:

output: {
    ...
    publicPath: '../dist/', //模板、样式、脚本、图片等资源在打包后的index.html中统一会加上的路径
    },

可以发现打包后的index.html中link中的路径增加了上述路径:

<link rel="shortcut icon" href="../dist/favicon.ico">

浏览器中已经可以看到favicon,此处用的是腾讯云的图标:

1.3 自定义favicon的打包路径

上述打包的favicon路径,是根据output的path属性值和publicPath属性决定的,注意publicPath会给所有的资源路径都统一加上其属性值,这里除了favicon,js也增加了该路径。那么该如何直接指定favicon的打包路径呢。

这里用了url-loader,通过test匹配到favicon.ico图标后,会根据设置的name属性,将favicon打包到指定位置。

要先安装url-loader:

npm run url-loader  --save-dev

webpack.config.js中增加:

module.exports = {
    ...
    module: {
        rules: [
            //图片加载器,雷同file-loader,更适合图片,可以将较小的图片转成base64,减少http请求
            {
                test: /\.(ico)$/,
                loader: 'url-loader',
                options: {
                    limit: 50,
                    name: 'config/images/[name].[ext]'//相对于path的路径
                }
            },
        ]
    }
};

注意

(1)这里的name属性值是相对于output的path值而言:

(2)只增加上述配置对打包到指定路径是没有效果的,还必须配合使用html-loader,来处理引用的静态资源。默认配置的参数是atttrs=’img:src’,处理图片的src引用的资源,这里需要增加配置:'link:href',即可处理link标签的href引用的资源:

需要先安装html-loader、file-loader:

npm install html-loader --save-dev
npm install file-loader --save-dev

webpack.config.js中增加配置:

module: {
    rules: [
        ...
        //html模板加载器,可以处理引用的静态资源,默认配置参数attrs=img:src,处理图片的src引用的资源
        {
            test: /\.html$/,
            loader: "html-loader",
            options: {
                attrs: ['img:src', 'link:href']
            }
        },
    ]
}

重新打包后,发现确实在指定路径下生成了favicon:

目录结构

不过看下打包后生成的html文件可以发现,这里同时有两个link标签:

<!DOCTYPE html>
<html>

<head>
    <link rel="shortcut icon" href="../dist/config/images/favicon.ico">
    <meta charset="UTF-8">
    <title>set favicon</title>
    <link rel="shortcut icon" href="../dist/favicon.ico">
</head>

<body>
    <div>hello</div>
    <script type="text/javascript" src="../dist/js/app.js"></script>
</body>

</html>

其中,第一个link的href值是指定的路径,第二个link的href值是因为html-webpack-plugin中设置了favicon属性后生成的,可以看出后者的优先级更高。因此,在webpack.config.js的html-webpack-plugin中不需要再额外设置favicon属性:

plugins: [
    new HtmlWebpackPlugin({ //根据模板插入css/js等生成最终HTML
        filename: '../view/index.html', //生成的html存放路径,相对于path的路径
        template: './index.html', //html模板路径
        inject: 'body', //js插入的位置,true/'head'/'body'/false
        minify: { //压缩HTML文件
            removeComments: true, //移除HTML中的注释
            collapseWhitespace: false //删除空白符与换行符
        }
    }),
],

重新打包后可以看到,只有按照loader中指定路径的link标签:

<!DOCTYPE html>
<html>

<head>
    <link rel="shortcut icon" href="../dist/config/images/favicon.ico">
    <meta charset="UTF-8">
    <title>set favicon</title>
</head>

<body>
    <div>hello</div>
    <script type="text/javascript" src="../dist/js/app.js"></script>
</body>

</html>

浏览器打开打包后的html可以看到:

2,小结

favicon图标在webpack打包中是很小的一个配置,不过从实际线上运维角度出发,还是有值得注意的地方。本文从无到有,比较详细地分步介绍了如何配置这么一个小小的favicon。建议如果是要在loader中处理favicon,就不要同时在html-webpack-plugin中设置favicion属性。如有问题,欢迎指正。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励