阅读 247

Webpack4散记(1)写一个插件

想学习一下写webpack插件,起步就遇到障碍。

从网上找了一个demo,是通过二次调用html-webpack-plugin来对index.html进行自定义修改。但运行时遇到报错。关键信息:

[webpack-cli] Error: Plugin could not be registered at 'html-webpack-plugin-before-html-processing'. Hook was not found.
BREAKING CHANGE: There need to exist a hook at 'this.hooks'. To create a compatibility layer for this hook, hook into 'this._pluginCompat'.
...
复制代码

搜索了一下,资料不多,大致找到原因是webpack4Tapable对象重写造成hook找不到引发的。

没有深究,毕竟不想去改webpack的源代码。继续搜索时,发现有人提到一个替代插件:webpack-contrib/html-webpack-plugin

网上也有人说了安装会失败,我也是。

在npm上搜了一下webpack-contrib/html-webpack-plugin,发现原来包名其实应当是html-webpack-plugin-from-webpack-contrib

npm i html-webpack-plugin-from-webpack-contrib -D
复制代码

html-webpack-plugin的引用更改为:

const HtmlWebpackPlugin = require('html-webpack-plugin-from-webpack-contrib')
复制代码

完整webpack.config

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin-from-webpack-contrib')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const MyFirstPlugin = require('../plugin/my-first-plugin')

module.exports = {
    // mode: 'production',
    mode: 'development',
    entry: './src/plugin/index.js',
    output: {
        path: path.resolve(__dirname, '../dist/plugin'),
        filename: 'index.js'
    },
    plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
            template: './src/plugin/index.html',
            filename: './index.html',
            inject: 'body'
        }),
        new MyFirstPlugin(),
    ]
}
复制代码

完整插件代码

class MyFirstPlugin {
    apply(compiler) {
        compiler.hooks.compilation.tap('MyFirstPlugin', compilation => {
            compilation.plugin('html-webpack-plugin-before-html-processing', htmlPluginData => {
                htmlPluginData.html += '<div id="hidden-holder"></div>'
            })
        })
    }
}

module.exports = MyFirstPlugin
复制代码

编译结果符合预期

<!DOCTYPE html>
<html>
<head></head>
<body>
<div id="app"></div>
<script type="text/javascript" src="index.js"></script></body>
</html><div id="hidden-holder"></div>
复制代码

以上

文章分类
前端
文章标签