Webpack-第二集

  • loader:file-loader:处理静态资源模块
    loader:file-loader
    原理是把打包入口中识别出的资源模块,移动到输出目录,并且返回一个地址名称

    所以我们什么时候用file-loader呢?
    场景:就是当我们需要模块,仅仅是从源代码挪移到打包目录,就可以使用files-loader来处理,txt、svg、csv、excel、图片资源等等

npm install file-loader -D

案例:

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

import pic from "./logo.png";
var img = new Image(); img.src = pic; img.classList.add("logo");
var root = document.getElementById("root"); root.append(img);
//css
 @font-face { 
  font-family: "webfont"; 
   font-display: swap; 
    src: url("webfont.woff2") format("woff2");
   }
 
body {  
background: blue; 
 font-family: "webfont" !important;
 }
 
 
//webpack.config.js 
{  
test: /\.(eot|ttf|woff|woff2|svg)$/,  
use: "file-loader" 
}

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

案例:

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

样式处理:
Css-loader 分析css模块之间的关系,并合成⼀个css
Style-loader 会把css-loader⽣成的内容,以style挂载到⻚⾯的heade部分

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

Less样式处理
less-load 把less语法转换成css

npm install less less-loader --save-dev

案例:
loader有顺序,从右到左,从下到上

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

样式⾃动添加前缀:

https://caniuse.com/
Postcss-loader
npm i postcss-loader autoprefixer -D
新建postcss.config.js

//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%"]
        })]
};

loader 处理webpack不⽀持的格式⽂件,模块
⼀个loader只处理⼀件事情
loader有执⾏顺序

如何⾃⼰编写⼀个Loader

⾃⼰编写⼀个Loader的过程是⽐较简单的,
Loader就是⼀个函数,声明式函数,不能⽤箭头函数
拿到源代码,作进⼀步的修饰处理,再返回处理后的源码就可以了
官⽅⽂档:https://webpack.js.org/contribute/writing-a-loader/
接⼝⽂档:https://webpack.js.org/api/loaders/
简单案例

  • 创建⼀个替换源码中字符串的loader
//index.js 
console.log("hello world");


//replaceLoader.js 
module.exports = function (source) {
    console.log(source, this, this.query); 
    return source.replace('world', 'china')
};


//需要⽤声明式函数,因为要上到上下⽂的this,⽤到this的数据,该函数接受⼀个参数,是源码

  • 在配置⽂件中使⽤loader
//需要使⽤node核⼼模块path来处理路径 
const path = require('path')
module: {
    rules: [{
        test: /\.js$/,
        use: path.resolve(__dirname, "./loader/replaceLoader.js")
    }]
},

  • 如何给loader配置参数,loader如何接受参数?
    this.query
    loader-utils
//webpack.config.js 
module: {
    rules: [
        {
            test: /\.js$/,
            use: [
                {
                    loader: path.resolve(__dirname, "./loader/replaceLoader.js"),

                    options: {
                        name: "china"
                    }
                }
            ]
        }]
},
//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("world", options.name);
    return source.replace("world", options.name);
}    
  • this.callback :如何返回多个信息,不⽌是处理好的源码呢,可以使⽤this.callback来处理
//replaceLoader.js 
const loaderUtils = require("loader-utils");//官⽅推荐处理loader,query的⼯具

module.exports = function (source) {
    const options = loaderUtils.getOptions(this);
    const result = source.replace("kkb", options.name);
    this.callback(null, result);
};


// this.callback(
//     err: Error | null,
//     content: string | Buffer,
//     sourceMap ?: SourceMap,
//     meta ?: any
// );

  • this.async:如果loader⾥⾯有异步的事情要怎么处理呢
const loaderUtils = require("loader-utils");

module.exports = function (source) {
    const options = loaderUtils.getOptions(this);
    setTimeout(() => {
        const result = source.replace("world", options.name);
        return result;
    }, 1000);
};
 //先⽤setTimeout处理下试试,发现会报错

我们使⽤this.asycn来处理,他会返回this.callback

const loaderUtils = require("loader-utils");

module.exports = function (source) {
    const options = loaderUtils.getOptions(this);

    //定义⼀个异步处理,告诉webpack,这个loader⾥有异步事件,在⾥⾯调⽤下这个异步  
    //callback 就是 this.callback 注意参数的使⽤ 
    const callback = this.async();
    setTimeout(() => {
        const result = source.replace("kkb", options.name);
        callback(null, result);
    }, 3000);
};

  • 多个loader的使⽤
//replaceLoader.js
module.exports = function (source) {
    return source.replace("开课吧", "word");
};
//replaceLoaderAsync.js 
const loaderUtils = require("loader-utils");
module.exports = function (source) {
    const options = loaderUtils.getOptions(this);
    //定义⼀个异步处理,告诉webpack,这个loader⾥有异步事件,在⾥⾯调⽤下这个异步
    const callback = this.async();
    setTimeout(() => {
        const result = source.replace("world", options.name);
        callback(null, result);
    }, 3000);
};

//webpack.config.js
module: {
    rules: [
        {
            test: /\.js$/,
            use: [
                path.resolve(__dirname, "./loader/replaceLoader.js"),
                {
                    loader: path.resolve(__dirname, "./loader/replaceLoaderAsync.js"),
                    options: { name: "china" }
                }]        // use: [path.resolve(__dirname, "./loader/replaceLoader.js")]
        }]
},

顺序,⾃下⽽上,⾃右到左

  • 处理loader的路径问题
resolveLoader: {
    modules: ["node_modules", "./loader"]
},
module: {
    rules: [
        {
            test: /\.js$/,
            use: [
                "replaceLoader",
                {
                    loader: "replaceLoaderAsync",
                    options: {
                        name: "china"
                    }
                }]
            // use: [path.resolve(__dirname, "./loader/replaceLoader.js")]    
        }]
},

参考:loader API
https://webpack.js.org/api/loaders

mini-css-extract-plugin

const MiniCssExtractPlugin = require("mini-css-extract-plugin");


{
    test: /\.css$/,
    use: [MiniCssExtractPlugin.loader, "css-loader"]
}
new MiniCssExtractPlugin({ filename: "[name][chunkhash:8].css" })

chunk:⼀个⼊⼝肯定是⼀个chunk,但是⼀个chunk不⼀定只有⼀个依赖

hash :
Chunkhash
Contenthash

  • 未完待续 。。。。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值