淘先锋技术网

首页 1 2 3 4 5 6 7
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const { Compilation } = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const TerserWebpackPlugin = require('terser-webpack-plugin');

class MyPlugin {
	apply(compiler) {
		console.log('MyPlugin Start...');

		// emit | thisCompilation
		compiler.hooks.thisCompilation.tap('MyPlugin', (compilation) => {
			// compilation => 打包的上下文

			compilation.hooks.processAssets.tap(
				{
					name: 'MyPlugin',
					stage: Compilation.PROCESS_ASSETS_STAGE_ADDITIONS, // see below for more stages
				},
				(assets) => {
					console.log('List of assets and their sizes:');
					Object.entries(assets).forEach(([pathname, source]) => {
						console.log(`${pathname}: ${source.size()} bytes`);
						if (pathname.endsWith('.js')) {
							const withoutComments = source
								.source()
								.replace(/\/\*\*+\*\//g, '');
							compilation.assets[pathname] = {
								source: () => withoutComments,
								size: () => withoutComments.length,
							};
						}
					});
				},
			);

			// for (let name in compilation.assets) {
			// 	// console.log(name); // 文件名
			// 	// console.log('- ', compilation.assets[name]); // 文件
			// 	// console.log(compilation.assets[name].source()); // 文件资源
			// 	if (name.endsWith('.js')) {
			// 		const contents = compilation.assets[name].source();
			// 		const withoutComments = contents.replace(/\/\*\*+\*\//g, '');
			// 		compilation.assets[name] = {
			// 			source: () => withoutComments,
			// 			size: () => withoutComments.length,
			// 		};
			// 	}
			// }
		});
	}
}

module.exports = {
	mode: 'none', // production | development | none
	entry: './src/index.js',
	output: {
		filename: 'bundle.js',
		path: path.join(__dirname, 'dist'), // 打包路径及打包文件名
		// publicPath: 'dist/',
	},
	devtool: 'nosources-source-map', // dev开发环境可用source-map方便查找错误
	devServer: {
		hot: true,
		open: true,
	},
	optimization: {
		// 使用这个属性就是告诉webpack,我要自定义压缩配置
		minimizer: [
			new TerserWebpackPlugin({
				terserOptions: {
					compress: {
						pure_funcs: ['console.log'], // 打包的js文件去除console.log
					},
				},
			}), // 开启js压缩
			new OptimizeCssAssetsWebpackPlugin(), // 开启css压缩
		],
	},
	module: {
		rules: [
			{
				test: /\.css$/,
				use: [
					// 'style-loader', // 样式通过 style 标签注入,当css包 < 150kb 建议直接用style-loader
					MiniCssExtractPlugin.loader, // 样式通过link标签引入
					'css-loader',
				],
			},
			{
				test: /(\.png|\.jpg|\.jpeg)$/,
				use: {
					loader: 'url-loader', // url-loader 不处理的图片会调用file-loader生成单个文件
					options: {
						limit: 100 * 1024, // 10kb 以下图片用url转成base64图片地址,否则生成单个文件资源
					},
				},
			},
			{
				test: /\.js$/,
				use: {
					loader: 'babel-loader',
					options: {
						presets: ['@babel/preset-env'],
					},
				},
			},
		],
	},
	plugins: [
		new CleanWebpackPlugin(), // 每次打包删除上次打包文件
		new HtmlWebpackPlugin({
			title: 'webpack plugin sample', // 打包生成 html
			// meta: {
			// 	viewport: 'width=device-width', // 设置打包生成html文件的viewport规则
			// },
			template: './index.html', // 按照模版打包 模版中可用 <%= htmlWebpackPlugin.options %> 访问这里的变量
		}),
		new CopyWebpackPlugin({
			patterns: [
				{
					from: path.join(__dirname, 'public'), // 复制项目中的文件到打包dist文件夹中, 一般就是复制一些static静态小型图片
					to: __dirname + '/dist',
				},
			],
		}),
		// new MyPlugin(), // 自定义插件 - 删除打包js的注释
		new MiniCssExtractPlugin(), // 生成css打包文件
		// new OptimizeCssAssetsWebpackPlugin(), // 压缩css打包文件
	],
};