webpack4学习笔记(四)

栏目: JavaScript · 发布时间: 6年前

内容简介:这是我花了几个星期学习webpack4的学习笔记。内容不够细,因为一些相对比较简单的,就随意带过了。希望文章能给大家带来帮助。如有错误,希望及时指出。例子都在配置

前言

这是我花了几个星期学习webpack4的学习笔记。内容不够细,因为一些相对比较简单的,就随意带过了。希望文章能给大家带来帮助。如有错误,希望及时指出。例子都在 learn-webpack 仓库上。如果你从中有所收获的话,希望你能给我的 github 点个 star

编写loader

// index.js
console.log('hello, atie')

配置 webpack.config.js

// webpack.config.js

module: {
  rules: [
    {
      test: /\.js$/,
      include: /src/,
      loader: path.resolve(__dirname, './loaders/replaceLoader.js')
    }
  ]
},
// 函数不能使用箭头函数
module.exports = function(source) {
    console.log(source, 'source')
    return source.replace('atie', 'world')
}

loader 文件其实就是导出一个函数, source 就是 webpack 打包出的 js 字符串。这里的 loader 就是将上面的 console.log('hello, atie') 替换为 console.log('hello, world')

打包下代码,不出所料。控制台就会打印出 hello, world

当你想要给loader传参时,可配置如下

module: {
  rules: [
    {
      test: /\.js$/,
      include: /src/,
      use: [{
        loader: path.resolve(__dirname, './loaders/replaceLoader.js'),
        options: {
          name: 'haha'
        }
      }]
    }
  ]
},

通过给 loader 添加 options

这样 loader 中就可以通过 this.query 获取该参数了

module.exports = function(source) {
      // 控制台输出:console.log('hello atie') { name: 'haha' } source
    console.log(source, this.query, 'source')
    return source.replace('atie', 'world')
}

当然变量不一定非要通过 this.query 来获取

可通过 loader-utils 这个包来获取传入的变量

安装: npm i loader-utils -D

const loaderUtils = require('loader-utils')

// 函数不能使用箭头函数
module.exports = function(source) {
    // console.log(source, this.query, 'source')
    const options = loaderUtils.getOptions(this)
    console.log(options, 'options') // { name: 'haha' } 'options'
    return source.replace('atie', 'world')
}

打印出来的与上面 this.query 一致

上面都是直接通过 return 返回的,那么我们还有没有其他方法返回 loader 翻译后的代码呢?`

这里就会用到 callback

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

上面的代码就可以改写成

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

callback 优势在于它可以传递多余的参数

module.exports = function(source) {
    setTimeout(() => {
        return source.replace('atie', 'world')
    }, 1000)
}

当我们把 return 包到异步方法里,打包的时候就会报错,那么我们该怎么办呢?

这个时候就需要用到 this.async()

module.exports = function(source) {
    const callback = this.async()
    setTimeout(() => {
        callback(null, source.replace('atie', 'world'))
    }, 2000)
}

通过调用 this.async() 返回的 callback 方法来返回结果

use中的loader执行顺序,先右后左,先下后上

编写plugin

在根目录下新建 plugins 文件夹,并新建 copyright-webpack-plugin.js ,内容如下:

class Copyright {
    constructor() {
        console.log('this is plugin')
    }
    apply(compiler) {
    }
}
module.exports = Copyright

注意:apply这个方法必须存在,不然插件被执行的时候会报错。

配置 webpack.config.js ,如下:

const Copyrgiht = require('./plugins/copyright-webpack-plugin.js')

...

plugins: [
  new Copyrgiht()
]

执行下打包命令后

this is plugin
Hash: 479baeba2207182096f8
Version: webpack 4.30.0
Time: 615ms
Built at: 2019-05-08 23:05:08
     Asset       Size  Chunks             Chunk Names
 bundle.js   3.77 KiB    main  [emitted]  main
index.html  182 bytes          [emitted]

控制台打印出了 this is plugin

接下来,我们继续探索插件的奥秘

在使用插件的时候还可以传参

// webpack.config.js
plugins: [
  new Copyrgiht({
    name: 'atie'
  })
]
class Copyright {
    constructor(options) {
        // console.log(options, 'this is plugin')
          this.options = options
    }
    apply(compiler) {
          console.log(this.options)
    }
}

执行下打包命令:

{ name: 'atie' }
Hash: 479baeba2207182096f8
Version: webpack 4.30.0
Time: 742ms
Built at: 2019-05-08 23:24:10
     Asset       Size  Chunks             Chunk Names
 bundle.js   3.77 KiB    main  [emitted]  main
index.html  182 bytes          [emitted]

控制就会输出 {name: 'atie'}

webpack 在调用 apply 会传递一个 compiler 参数,这个参数可以做很多事情,具体可以参考 webpack 官网

这里介绍下钩子

class Copyright {
    apply(compiler) {
        compiler.hooks.emit.tapAsync('Copyright', (compilation,callback) => {
            console.log(compilation.assets, '以具有延迟的异步方式触及 run 钩子。');
            compilation.assets['copyright.txt'] = {
                source: function() {
                    return 'copyright by atie'
                },
                size: function() {
                    return 17
                }
            }
            callback()
        })
    }
}

module.exports = Copyright

该钩子是在文件生成前触发的。我们在文件生成前,在 asset 对象上在加一个文件对象

打包之后

.
├── bundle.js
├── copyright.txt
└── index.html

可以看到多了一个 copyright.txt ,也就是我们上面创建的文件。点开该文件还会看到里面的内容正是 copyright by atie


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

程序设计语言

程序设计语言

斯科特 / 裘宗燕 / 电子工业出版社 / 2005-1 / 88.00元

这是一本很有特色的教材,其核心是讨论程序设计语言的工作原理和技术。本书融合了传统的程序设计语言教科书和编译教科书的有关知识,并增加了一些有关汇编层体系结构的材料,以满足没学过计算机组织的学生们的需要。书中通过各种语言的例子,阐释了程序设计语言的重要基础概念,讨论了各种概念之间的关系,解释了语言中许多结构的形成和发展过程,以及它们演化为今天这种形式的根源。书中还详细讨论了编译器的工作方式和工作过程,......一起来看看 《程序设计语言》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具