webpack 之 常用的 loader

781 阅读2分钟

小知识,大挑战!本文正在参与“  程序员必备小知识  ”创作活动

本文同时参与 「掘力星计划」  ,赢取创作大礼包,挑战创作激励金

file-loader(处理静态资源模块)

原理:

把打包⼊⼝中识别出的资源模块,移动到输出⽬录,并且返回⼀个地址名称

使用场景:

是当我们需要模块,仅仅是从源代码挪移到打包⽬录,就可以使⽤file-loader来处理, txt,svg,csv,excel,图⽚资源啦等等

案例:

module: {
 rules: [
     {
         test: /\.(png|jpe?g|gif)$/,
         //use使⽤⼀个loader可以⽤对象,字符串,两个loader需要⽤数组
         use: {
             loader: "file-loader",
             // options额外的配置,⽐如资源名称
             options: {
                 // placeholder 占位符 [name]⽼资源模块的名称
                 // [ext]⽼资源模块的后缀
                 name: "[name]_[hash].[ext]",
                 //打包后的存放位置
                 outputPath: "images/"
             }
        }
     }
 ]
}

url-loader(file-loader加强版本)

原理:

url-loader内部使⽤了file-loader,所以可以处理file-loader所有的事情,但是遇到jpg格式的模块, 会把该图⽚转换成base64格式字符串,并打包到js⾥。对⼩体积的图⽚⽐较合适,⼤图⽚不合适。

案例:

module: {
 rules: [
     {
         test: /\.(png|jpe?g|gif)$/,
         use: {
             loader: "url-loader",
             options: {
                 name: "[name]_[hash].[ext]",
                 outputPath: "images/",
                 //⼩于2048,才转换成base64
                 limit: 2048
             }
         }
     }
 ]
}

css-loader style-loader

Css-loader 分析css模块之间的关系,并合成⼀个css

Style-loader 会把css-loader⽣成的内容,以style挂载到⻚⾯的header部分

案例:

{
     test: /\.css$/,
     use: ["style-loader", "css-loader"]
}
{
 test:/\.css$/,
 use:[{
     loader:"style-loader",
     options: {
         injectType: "singletonStyleTag" // 将所有的style标签合并成⼀个
     }
     },"css-loader"]
}

less-loader

作用:

less-loader 把less语法转换成css

loader有顺序,从右到左,从下到上

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

Postcss-loader

样式⾃动添加前缀:

//webpack.config.js
{
 test: /\.css$/,
 use: ["style-loader", "css-loader", "postcss-loader"]
},
//postcss.config.js
module.exports = {
 plugins: [
 require("autoprefixer")({
 overrideBrowserslist: ["last 2 versions", ">1%"]
 })
 ]
}

px2rem-loader

场景: 移动端 CSS px ⾃动转换成 rem

module.exports = {
    module: {
        rules: [
        {
            test: /\.less$/,
            use: [
                'style-loader',
                'css-loader',
                'less-loader',
                + {
                + loader: "px2rem-loader",
                + options: {
                + remUnit: 75,
                + remPrecision: 8
                + }
                + }
            ]
        }
        ]
    }
}

raw-loader 资源内联

资源内联的意义

代码层⾯:

  1. ⻚⾯框架的初始化脚本
  2. 上报相关打点
  3. css 内联避免⻚⾯闪动 请求层⾯:
  4. 减少 HTTP ⽹络请求数
  5. ⼩图⽚或者字体内联 (url-loader) HTML 和 JS 内联
// raw-loader 内联 html
<script>${require(' raw-loader!babel-loader!. /meta.html')}</script>
// raw-loader 内联 JS
<script>${require('raw-loader!babel-loader!../node_modules/lib-flexible')}</script>

CSS 内联:

⽅案⼀:借助 style-loader

module.exports = {
    module: {
        rules: [
            {
            test: /\.scss$/,
            use: [
                {
                    loader: 'style-loader',
                    options: {
                        insertAt: 'top', // 样式插入到 <head>
                        singleton: true, //将所有的style标签合并成一个
                    }
                },
                "css-loader",
                "sass-loader"
            ],
            },
        ]
    },
};

⽅案⼆:html-inline-css-webpack-plugin

手写 loader

Loader就是⼀个函数,声明式函数,不能⽤箭头函数

拿到源代码,作进⼀步的修饰处理,再返回处理后的源码就可以了

  1. 创建⼀个替换源码中字符串的loader
//index.js
console.log("hello kkb");
//replaceLoader.js
module.exports = function(source) {
 console.log(source, this, this.query);
 return source.replace('kkb','zzh')
}
  1. 在配置⽂件中使⽤loader
/需要使⽤node核⼼模块path来处理路径
const path = require('path')
module: {
 rules: [
 {
 test: /\.js$/,
 use: path.resolve(__dirname, "./loader/replaceLoader.js")
 }
 ]
 },
  1. 如何给loader配置参数,loader如何接受参数
  • this.query
  • loader-utils
//webpack.config.js
module: {
 rules: [
 {
 test: /\.js$/,
 use: [
 {
 loader: path.resolve(__dirname, "./loader/replaceLoader.js"),
 options: {
 name: "zzh"
 }
 }
 ]
 }
 ]
 },
 
//replaceLoader.js
//const loaderUtils = require("loader-utils");//官⽅推荐处理loader,query的⼯具
module.exports = function(source) {
 //this.query 通过this.query来接受配置⽂件传递进来的参数
 //return source.replace("kkb", this.query.name);
 const options = loaderUtils.getOptions(this);
 const result = source.replace("kkb", options.name);
 return source.replace("kkb", options.name);
}