Webpack 4.X 自定义 loader 和 plugins

Loader

因为webpack只识别js文件,遇到非js文件,需要利用loader处理

我们开发常用的loader:诸如:babel-loader url-loader style-loader css-loader postcss-loader 等等


今天,我们手写一个简单的loader,用来写入我们要编译的源代码

开始的搭建项目步骤我们就不多说了,这里我们用到webpack 4.X版本,要搭配webpack-cli来使用

npm init
npm i webpack webpack-cli -D
npm i cross-env -D — 配置跨平台环境变量

package.json

{
  "name": "webpack_test",
  "version": "1.0.0",
  "description": "webpack_test",
  "main": "index.js",
  "scripts": {
    "start": "cross-env NODE_TYPE=development webpack --progress --colors --config webpack.config.js --mode=development",
    "build": "cross-env NODE_TYPE=production webpack -p --progress --colors --config webpack.config.js --mode=production"
  },
  "keywords": [
    "webpack"
  ],
  "author": "[email protected]",
  "license": "MIT",
  "devDependencies": {
    "cross-env": "^7.0.2",
    "webpack": "^4.43.0",
    "webpack-cli": "^3.3.12"
  }
}

接下来,我们进入正题:

index.js 源代码

export default function () {
  console.log('init')
}

webpack.config.js 配置

const path = require('path')
module.exports = {
  entry: path.resolve(__dirname, 'src/index.js'),
  output: {
    filename: "js/[name].[hash:8].js",
    path:path.resolve(__dirname,'build'),
  },
  module: {
    rules: [
      {
        test: /\.(js)$/,
        use: {
          loader: path.resolve(__dirname, './loader/write-stream-loader.js'),
          options: {
            name: ''
          }
        }
      }
    ]
  },
}

这里,我们新建一个loader文件夹,用来存放我们自定义loader

loader/write-stream-loader.js

const loaderUtils = require('loader-utils') // 引入loader提供的util工具插件
const fs = require('fs') // 引入fs文件系统

module.exports = function (source) {
	console.log(source)
	// 获取options参数,object类型
	let option = loaderUtils.getOptions(this)
	console.log(option)
	// 创建写入流
	let writeaStream = fs.createWriteStream('result.txt')
	// 写入源代码
	writeStream.write(source,'UTF-8')
	// 标记结束
	writeStream.end()
	// 写入完成回调
	writeStream.on('finish', () => {
		console.log()
		console.log('写入完成')
	})
	return source
}

接下来,我们执行webpack编译,执行npm run build开始打包

building for production


可以看到,源代码options参数打印出来了,并且写入成功了
在这里插入图片描述
我们进入result.txt文件中,可以看到源代码写入成功了
在这里插入图片描述
至此,我们就完成了自定义loader的编写,这里要注意,我们用到了webpack 4.X版本

Plugins

webpack中的plugins也是webpack的核心内容之一,作为hook函数,是为了在编译打包过程中发挥自身应有的作用

看过源码同学大概有一个基本的认知,他是一个class构造函数,通过原型的apply方法执行。最后生成实例继承Tapable。其compiler对象是plugins的心脏,暴露其生命周期hook函数

因为我们想通过plugin,在生成资源前导出一个说明文档,所以我们这里用到emit生命周期函数


plugins/set-readme-webpack-plugin.js

class SetReadmeWebpackPlugin {
  constructor(options) {
    this.name = options.name || 'hello world'
  }

  apply(compiler) {
    compiler.hooks.emit.tap('SetReadmeWebpackPlugin', compilation => {
      compilation.assets['readme.txt'] = {
        source: () => this.name,
        size: () => 20
      }
    })
  }
}

module.exports = SetReadmeWebpackPlugin

我们在webpack中使用

webpack.config.js

const path = require('path')
const SetReadmeWebpackPlugin = require('./plugins/set-readme-webpack-plugin')

module.exports = {
  entry: path.resolve(__dirname, 'src/index.js'),
  output: {
    filename: "js/[name].[hash:8].js",
    path: path.resolve(__dirname, 'build'),
  },
  plugins: [
    new SetReadmeWebpackPlugin({
      name: 'readme'
    })
  ]
}

接下来,我们执行npm run build,我们通过控制台可以看到options输出,并且创建了readme.txt文档
在这里插入图片描述
至此,我们完成了自定义plugins的编写


附文章
Webpack 4.X 从零配置SPA单页应用
Webpack 4.X 配置cdn加载资源
Webpack 各版本 ( v1 - v4 ) 的区别
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章