Webpack教程四:Loader

目录

一、什么是Loader

二、打包图片

2.1、file-loader

2.2、url-loader

2.3、file-loader和url-loader的比较

三、打包CSS文件

3.1、style-loader和css-loader

3.2、sass-loader

3.3、postcss-loader

3.4、处理sass文件中引入另外sass文件的情况

3.5、CSS模块化

四、打包字体、图标


一、什么是Loader

    前面章节已经展示了如何使用webpack打包js文件,那么怎么使用webpack打包其他类型的文件呢?(比如图片、css样式文件、json文件等等)

    答案是使用loader,webpack最出色的功能之一就是,除了能引入js文件之外,还可以通过loader引入任何其他类型的文件。

    因此,loader是一个打包方案,能对特定类型的文件用相应的方案进行打包。

二、打包图片

    webpack的loader机制支持打包图片,打包图片主要用到的两个loader是file-loaderurl-loader

2.1、file-loader

    我们先来看file-loader

    首先,先安装file-loader

   然后,清空webpack-demo目录下的src文件夹,并随便放入一张图片:

   在src文件夹中再加入一个index.js文件:

   index.js:

import Icon from './dog.jpg';

console.log(Icon);
var element = document.getElementById('webContent');

var icon = new Image();
icon.src = Icon;

element.appendChild(icon);

    然后,为了让file-loader能够起作用,还需配置wepback.config.js文件:

    webpack.config.js:

const path = require('path');

module.exports = {
    mode: 'development',
    entry: {
        main: './src/index.js'              
    },                
    output: {
        filename: 'main.js',                
        path: path.resolve(__dirname, 'dist')    
    },
    module: {
        rules: [
            {
                test: /\.(png|svg|jpg|gif$)/,           // 文件后缀名匹配通配符
                use: [
                    'file-loader'                       // 使用的loader
                ]
            }
        ]
    }
}

    最后,进行打包操作:

   打包后生成了一个新的以哈希值命名的图片文件,可以在dist文件夹中找到:

    我们可以使用浏览器打开dist.html

    图片已经被成功打包,并在项目中显示出效果了!

    另外,还可以对file-loader进行更多配置:

    webpack.config.js:

const path = require('path');

module.exports = {
    mode: 'development',
    entry: {
        main: './src/index.js'              
    },                
    output: {
        filename: 'main.js',                
        path: path.resolve(__dirname, 'dist')    
    },
    module: {
        rules: [
            {
                test: /\.(png|svg|jpg|gif$)/,           // 文件后缀名匹配通配符
                use: [{
                    loader: 'file-loader',              // 使用的loader
                    options: {
                        name: '[name].[ext]'            // 打包出的图片文件仍保持原有命名
                    }
                }]
            }
        ]
    }
}

    进行打包操作:

    可以看到生成的图片文件文件名与原始文件一致。

2.2、url-loader

    还可以使用url-loader来打包图片,它与file-loader的不同之处在于url-loader将图片打包成base64的形式加载到main.js文件中。

    首先,让我们来安装url-loader:

    然后,重新配置webpack.config.js

    webpack.config.js:

const path = require('path');

module.exports = {
    mode: 'development',
    entry: {
        main: './src/index.js'              
    },                
    output: {
        filename: 'main.js',                
        path: path.resolve(__dirname, 'dist')    
    },
    module: {
        rules: [
            {
                test: /\.(png|svg|jpg|gif$)/,           // 文件后缀名匹配通配符
                use: [{
                    loader: 'url-loader',               // 使用的loader
                    options: {
                        limit: 10240                    // 当图片小于10kb时,使用base64的方式进行打包
                    }
                }]
            }
        ]
    }
}

    进行打包操作:

    可以明显发现,这次打包没有生成新图片文件,这是因为dog.jpg这个图片文件大小只有8kb,所以url-loader以base64的形式对该图片文件进行打包。

    我们打开main.js文件:

    可以发现,图片真的以base64位的形式被打包,并被加载到main.js文件中。

    可以用浏览器打开dist.html文件:

    效果和之前一致!

2.3、file-loader和url-loader的比较

    file-loader实际上只将图片进行了文件目录的转移,而ulr-loader却可以将图片文件以base64位的形式进行处理,因此:

  • 当图片很小时    ——    适合用url-loader,因为图片将以base64位的形式加载到main.js,因此浏览器将只请求一个main.js文件,而不用多发起一次对图片的http请求。
  • 当图片比较大时    ——    适合用file-loader,因为能让main.js更快地加载出来。

三、打包CSS文件

3.1、style-loader和css-loader

    为了让webpack能够打包css文件,需要安装style-loadercss-loader,并对webpack.config.js进行配置。

    先来安装style-loader和css-loader:

    再对webpack.config.js进行配置:

const path = require('path');

module.exports = {
    mode: 'development',
    entry: {
        main: './src/index.js'              
    },                
    output: {
        filename: 'main.js',                
        path: path.resolve(__dirname, 'dist')    
    },
    module: {
        rules: [
            {
                test: /\.(png|svg|jpg|gif$)/,           // 文件后缀名匹配通配符
                use: [{
                    loader: 'url-loader',               // 使用的loader
                    options: {
                        limit: 10240                    // 当图片小于10kb时,使用base64的方式进行打包
                    }
                }]
            },
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    'css-loader'
                ]
            }
        ]
    }
}

    现在就可以来测试一下webpack能不能打包css文件了,首先在src文件夹下创建一个dog.css文件:

    dog.css:

.dog {
    width: 300px;
    height: 300px;
}

    修改index.js

    index.js:

import Icon from './dog.jpg';
import './dog.css';

var element = document.getElementById('webContent');

var icon = new Image();
icon.src = Icon;
icon.classList.add('dog');

element.appendChild(icon);

    进行打包:

    用浏览器打开dist.html,可以发现css样式文件已经起作用:

3.2、sass-loader

    webpack不仅可以打包css文件,还可以打包sass文件,不过需要sass-loader

    首先安装sass-loader:

    再配置webpack.config.js

    webpack.config.js:

const path = require('path');

module.exports = {
    mode: 'development',
    entry: {
        main: './src/index.js'              
    },                
    output: {
        filename: 'main.js',                
        path: path.resolve(__dirname, 'dist')    
    },
    module: {
        rules: [
            {
                test: /\.(png|svg|jpg|gif$)/,           // 文件后缀名匹配通配符
                use: [{
                    loader: 'url-loader',               // 使用的loader
                    options: {
                        limit: 10240                    // 当图片小于10kb时,使用base64的方式进行打包
                    }
                }]
            },
            {
                test: /\.scss$/,
                use: [
                    'style-loader',
                    'css-loader',
                    'sass-loader'
                ]
            }
        ]
    }
}

    现在可以测试webpack能不能打包sass文件,首先修改dog.css文件名为dog.scss,然后再修改dog.scss内容:

    dog.scss

body {
    .dog {
        width: 300px;
        height: 300px;
    }
}

    进行打包:

    再用浏览器打开dist.html,可以发现效果与之前一样:

3.3、postcss-loader

    许多css样式的书写需要添加厂商前缀,我们可以使用postcss-loader来完成添加厂商前缀的操作,但现在我们先来看不添加厂商前缀的示例。

    修改dog.scss文件:

    dog.scss:

body {
    .dog {
        width: 300px;
        height: 300px;
        transform: translate(100px, 100px);
    }
}

    进行打包,然后用浏览器打开dist.html

    果然有偏移效果,在浏览器中查看样式:

    可以发现,transform之前并没有添加前缀,接下来我们使用postcss-loader来让transform之前添加厂商前缀。

    首先,安装postcss-loader:

   因为还需要autoprefixer插件的配合,所以安装autoprefixer

   然后在webpack-demo根目录创建一个postcss.config.js,并为其添加内容:

    postcss.config.js:

module.exports = {
    plugins: [
        require('autoprefixer')
    ]
}

    再配置webpack.config.js:

const path = require('path');

module.exports = {
    mode: 'development',
    entry: {
        main: './src/index.js'              
    },                
    output: {
        filename: 'main.js',                
        path: path.resolve(__dirname, 'dist')    
    },
    module: {
        rules: [
            {
                test: /\.(png|svg|jpg|gif$)/,           // 文件后缀名匹配通配符
                use: [{
                    loader: 'url-loader',               // 使用的loader
                    options: {
                        limit: 10240                    // 当图片小于10kb时,使用base64的方式进行打包
                    }
                }]
            },
            {
                test: /\.scss$/,
                use: [
                    'style-loader',
                    'css-loader',
                    'sass-loader',
                    'postcss-loader'
                ]
            }
        ]
    }
}

    进行打包:

   用浏览器打开dist.html,可以发现transform已经添加了厂商前缀:

3.4、处理sass文件中引入另外sass文件的情况

    在webpack打包sass文件的过程中,它内部调用的loader的顺序是postcss-loader、sass-loader、css-loader和style-loader,也就是webpack.config.js文件中从use数组中从下往上调用:

    现在,在src根目录创建一个dog2.scss文件:

    dog2.scss:

body {
    .dog {
        transform: translate(100px, 100px);
    }
}

    再修改dog.scss文件:

    dog.scss:

@import './dog2.scss';

body {
    .dog {
        width: 300px;
        height: 300px;
    }
}

    因为dog2.scss作为引入的方式加载到dog.scss,所以webpack会直接调用css-loader,而不会在调用css-loader之前先调用postcss-loader和sass-loader,为了解决这个问题,可以对css-loader进行配置:

    webpack.config.js:

const path = require('path');

module.exports = {
    mode: 'development',
    entry: {
        main: './src/index.js'              
    },                
    output: {
        filename: 'main.js',                
        path: path.resolve(__dirname, 'dist')    
    },
    module: {
        rules: [
            {
                test: /\.(png|svg|jpg|gif$)/,           // 文件后缀名匹配通配符
                use: [{
                    loader: 'url-loader',               // 使用的loader
                    options: {
                        limit: 10240                    // 当图片小于10kb时,使用base64的方式进行打包
                    }
                }]
            },
            {
                test: /\.scss$/,
                use: [
                    'style-loader',
                    {
                      loader: 'css-loader',
                      options: {
                          importLoaders: 2
                      }  
                    },
                    'sass-loader',
                    'postcss-loader'
                ]
            }
        ]
    }
}

    现在可以进行打包了:

3.5、CSS模块化

    webpack支持CSS模块化,具体是什么意思呢?

    在src根目录下,创建一个createImg.js:

    createImg.js:

import Icon from './dog.jpg';

function createImg() {
    var element = document.getElementById('webContent');

    var icon = new Image();
    icon.src = Icon;
    icon.classList.add('dog');

    element.appendChild(icon);
}

export default createImg;

    修改src目录下的index.js:

    index.js:

import Icon from './dog.jpg';
import './dog.scss';
import createImg from './createImg.js';

createImg();

var element = document.getElementById('webContent');

var icon = new Image();
icon.src = Icon;
icon.classList.add('dog');

element.appendChild(icon);

    进行打包:

    然后用浏览器打开dist.html:

    可以发现,新创建的图片和之前的图片有相同的样式,也就是dog.scss样式文件中指定的效果。

    现在我们想让只有其中的一张图片具有dog.scss文件中的样式,这也就是CSS模块化的意思,只将某个CSS文件作用于页面中的某些部分

    可以这样来做,首先修改webpack.config.js文件以开启CSS模块化:

    webpack.config.js:

const path = require('path');

module.exports = {
    mode: 'development',
    entry: {
        main: './src/index.js'              
    },                
    output: {
        filename: 'main.js',                
        path: path.resolve(__dirname, 'dist')    
    },
    module: {
        rules: [
            {
                test: /\.(png|svg|jpg|gif$)/,           // 文件后缀名匹配通配符
                use: [{
                    loader: 'url-loader',               // 使用的loader
                    options: {
                        limit: 10240                    // 当图片小于10kb时,使用base64的方式进行打包
                    }
                }]
            },
            {
                test: /\.scss$/,
                use: [
                    'style-loader',
                    {
                      loader: 'css-loader',
                      options: {
                          importLoaders: 2,
                          modules: true
                      }  
                    },
                    'sass-loader',
                    'postcss-loader'
                ]
            }
        ]
    }
}

    再修改index.js文件:

    index.js:

import Icon from './dog.jpg';
import style from './dog.scss';
import createImg from './createImg.js';

createImg();

var element = document.getElementById('webContent');

var icon = new Image();
icon.src = Icon;
icon.classList.add(style.dog);

element.appendChild(icon);

    进行打包,然后用浏览器打开dist.html文件:

    可以发现,dog.scss文件样式只作用于其中的一张图片。

四、打包字体、图标

    如何使用webpack来打包字体和图标呢?

    我们可以去阿里巴巴矢量图标库下载图标来测试一下。

    这里我随便下载了一个图标:

    在webpack-demo的src文件夹下新建一个fonts文件夹,将iconfont.eot、iconfont.svg、iconfont.ttf、iconfont.woff、iconfont.woff2这几个文件拷贝进去。

    然后在src文件夹下新建一个iconfont.scss,将iconfont.css里的全部内容复制到iconfont.scss里,并作路径修改:

    iconfont.scss

    修改index.js:

    index.js:

import './iconfont.scss';

var webContent = document.getElementById('webContent');
webContent.innerHTML = '<i class="iconfont iconWIFI"></i>';

    最后,还要修改webpack.config.js:

    webpack.config.js:

const path = require('path');

module.exports = {
    mode: 'development',
    entry: {
        main: './src/index.js'              
    },                
    output: {
        filename: 'main.js',                
        path: path.resolve(__dirname, 'dist')    
    },
    module: {
        rules: [
            {
                test: /\.(png|svg|jpg|gif$)/,           // 文件后缀名匹配通配符
                use: [{
                    loader: 'url-loader',               // 使用的loader
                    options: {
                        limit: 10240                    // 当图片小于10kb时,使用base64的方式进行打包
                    }
                }]
            },
            {
                test: /\.scss$/,
                use: [
                    'style-loader',
                    {
                      loader: 'css-loader',
                      options: {
                          importLoaders: 2
                      }  
                    },
                    'sass-loader',
                    'postcss-loader'
                ]
            },
            {
                test: /\.(woff|woff2|eot|ttf)$/,
                use: [
                    'file-loader'
                ]
            }
        ]
    }
}

    现在可以进行打包了:

    使用浏览器打开dist.html

    图标显示出来了!

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值