Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

简单了解 webpack 到写一个插件 #18

Open
NoName4Me opened this issue Jul 18, 2018 · 1 comment
Open

简单了解 webpack 到写一个插件 #18

NoName4Me opened this issue Jul 18, 2018 · 1 comment
Labels

Comments

@NoName4Me
Copy link
Owner

初始化一个 webpack 项目

# 创建并进入目录
mkdir webpack-abc && cd webpack-abc

# 初始化项目
npm init -y

# 安装 webpack
npm install webpack webpack-cli -D

# 创建两个目录
mkdir src dist
  • 创建 index.html,拷贝到 dist 下。
<!-- index.html -->
<body>
  <script src="app.js"></script>
</body>
// 创建 src/index.js
const el = docuemnt.createElement('div');
el.innerHTML = "<h1>Hi~ webpack</h1>"
document.body.appendChild(el);

// webpack.config.js
const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'app.js',
    path: path.resolve(__dirname, 'dist')
  }
};

// package.json 中增加脚本
//    "dev": "./node_modules/.bin/webpack"
// 默认会使用 webpack.config.js,也可以手动指定(--config)

执行 npm build,可以看到dist下生成一个 app.js

使用 html-webpack-plugin 插件

npm install html-webpack-plugin -D

# 清空一下 dist 目录,我们要用插件自动生成
rm dist/*

更新 webpack 配置:

// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'app.js',
    path: path.resolve(__dirname, 'dist')
  },
  plugins: [new HtmlWebpackPlugin()]
};

执行 npm run dev,发现 dist 目录下自动生成了 index.html,内容为:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Webpack App</title>
  </head>
  <body>
  <script type="text/javascript" src="app.js"></script></body>
</html>

里面的 title 是默认的,也自动插入了 app.js这个脚本,这个插件可以配置很多东西,比如:

new HtmlWebpackPlugin({
  title: 'webpack demo',
  hash: true, // src="app.js?fe21381200fd032766c9"
  template: './src/index.test.html' // 指定具体模板
})

html-webpack-plugin 的更多配置见官方doc

写一个 hello-world-plugin

function HelloWorldPlugin(options) {
  // [1] 一个 js 命名函数
  // 使用 options 设置插件实例……
}

// [2] 插件函数 prototype 上定义一个 apply 方法
HelloWorldPlugin.prototype.apply = function(compiler) {
  // [3] 指定一个挂载到 webpack 自身的事件钩子
  compiler.plugin('emit', function(compilation /* [4] 处理 webpack 内部实例的特定数据 */, callback) {
    console.log('Hello World!');
    // [5] 功能完成后调用 webpack 提供的回调
    callback();
  });
}
  • 实战: 根据 html-webpack-plugin 事件插入自定义脚本
// 定义 RT 功能的一个插件
function InsertCustomScriptPlugin(options) {
  // ...
}

InsertCustomScriptPlugin.prototype.apply = function(compiler) {
  if (compiler.hooks) {
    // webpack 4 support
    compiler.hooks.compilation.tap('ApiProxyPlugin', compilation => {
      console.log('The compiler is starting a new compilation...');

      compilation.hooks.htmlWebpackPluginAfterHtmlProcessing.tapAsync(
        'InsertCustomScriptPlugin',
        (htmlPluginData, callback) => {
          htmlPluginData.html += '<script type="text/javascript">alert("helllo")</script>';

          callback(null, htmlPluginData);
        }
      );
    });
  } else {
    // Hook into the html-webpack-plugin processing
    compiler.plugin('compilation', function(compilation) {
      compilation.plugin('html-webpack-plugin-after-html-processing', function(
        htmlPluginData,
        callback
      ) {
        htmlPluginData.html += '<script type="text/javascript">alert("helllo")</script>';
        callback(null, htmlPluginData);
      });
    });
  }
}

module.exports = InsertCustomScriptPlugin;

使用自定义插件:

// webpack.config.js
const InsertCustomScriptPlugin = require('your/plugin')
// ...
plugins: [new HtmlWebpackPlugin(), new InsertCustomScriptPlugin()]

可以看到 <script type="text/javascript">alert("helllo")</script>' 被插入到了 dist/index.html 里。

@NoName4Me NoName4Me added the label Jul 18, 2018
@NoName4Me
Copy link
Owner Author

【不借助 html 里的模版,直接在插件内给页面的 head/body 里插入自定义内容】
htmlWebpackPluginAlterAssetTags 事件示例: jantimon/html-webpack-plugin#1001 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant