编写一个loader的流程和编写一个plugin的流程----[Webpack Less全局变量注入方案][env-html-plugin.js]

Webpack Less全局变量注入方案

项目初始化

  • 使用npm init -y初始化项目
  • 安装webpack相关依赖:webpackwebpack-cli

基础配置

  • 创建入口文件index.js
  • 配置基础webpack配置(对象方式)
  • 设置入口、输出、模式等基本配置

Less支持配置

  • 安装less相关依赖:lessless-loadercss-loaderstyle-loader
  • 创建全局变量文件gloable-less-var.less
  • main.less中使用全局变量

自定义Loader开发

  • 创建less-vars-loader.js
  • 实现自动注入全局变量的功能
  • 使用fspath模块读取全局变量文件

自定义Plugin开发

  • 创建env-html-plugin.js
  • 实现在HTML中注入环境变量的功能
  • 使用webpack的compilation hooks
  • 在HtmlWebpackPlugin处理后修改HTML内容

Webpack配置优化

  • 安装webpack-chain用于链式配置
  • 使用chain方式配置less-vars-loader
  • 使用.before('less-loader')确保执行顺序
  • 合并chain配置和基础配置

关键配置点

// 基础配置(对象方式)
const webpackConfig = {
  mode: 'development',
  entry: './index.js',
  output: { ... },
  module: {
    rules: [
      {
        test: /\.less$/,
        use: ['style-loader', 'css-loader', 'less-loader']
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }),
    new EnvHtmlPlugin()
  ]
};

// Chain配置(只用于less-vars-loader)
const chainConfig = new Config();
chainConfig.module
  .rule('less')
  .test(/\.less$/)
  .use('less-vars-loader')
    .loader(path.resolve(__dirname, 'loaders/less-vars-loader.js'))
    .before('less-loader')
    .end();

执行顺序

  • less-vars-loader(注入全局变量)
  • less-loader(处理less语法)
  • css-loader(处理css)
  • style-loader(将样式注入到页面)
  • env-html-plugin(注入环境变量)

环境变量配置

  • 使用cross-env设置环境变量
  • 开发环境:npm run dev
  • 生产环境:npm run build

最终效果

  • 自动将全局变量注入到所有less文件中
  • 无需手动在每个less文件中导入全局变量
  • 保持了配置的清晰和可维护性
  • HTML中自动显示当前环境变量

方案优点

  1. 实现了全局变量的自动注入
  2. 保持了配置的灵活性(混合使用对象和chain方式)
  3. 确保了loader的正确执行顺序
  4. 代码结构清晰,易于维护
  5. 支持环境变量的动态注入

loader代码

	const fs = require('fs');
	const path = require('path');

	module.exports = function(source) {
		// 获取全局变量文件的内容
		const globalVarsPath = path.resolve(__dirname, '../src/styles/gloable-less-var.less');
		const globalVars = fs.readFileSync(globalVarsPath, 'utf-8');

		// 将全局变量添加到源文件的开头
		return `${globalVars}\n${source}`;
	}; 

plugin代码

const HtmlWebpackPlugin = require('html-webpack-plugin');
class EnvHtmlPlugin {
	constructor(options = {}) {
		this.options = options;
	}

	apply(compiler) {
		compiler.hooks.compilation.tap('EnvHtmlPlugin', (compilation) => {
			// 获取HtmlWebpackPlugin的hooks
			HtmlWebpackPlugin.getHooks(compilation).beforeEmit.tapAsync(
				'EnvHtmlPlugin',
				(data, cb) => {
					// 获取环境变量
					const env = process.env.NODE_ENV || 'development';
					
					// 在body标签后添加h1元素
					data.html = data.html.replace(
						/<body[^>]*>/,
						`$&<h1>Current Environment: ${env}</h1>`
					);
					
					cb(null, data);
				}
			);
		});
	}
}

module.exports = EnvHtmlPlugin; 
posted @ 2025-04-24 11:00  Math点PI  阅读(65)  评论(0)    收藏  举报