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 ) 的區別
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章