# Webpack使用

TIP

Webpack 是一个用于现代 JavaScript 应用程序的静态模块打包工具。当 webpack 处理应用程序时,它会在内部构建一个 依赖图(dependency graph),此依赖图对应映射到项目所需的每个模块,并生成一个或多个 bundle

# 一 安装

# 1 安装

npm init -y

npm i webpack webpack-cli -D

mkdir webpack.config.js

# 2 入口

  • 入口起点(entry point)指示 webpack 构建的入口起点
  • 默认值是 ./src/index.js,可以配置一个或多个
module.exports = {
	entry: './src/index.js',
}

# 3 出口

  • output 属性告诉 webpack 构建的bundle,输出存放的目录
  • 主要输出文件的默认值是 ./dist/main.js,其他生成文件默认放置在 ./dist 文件夹中
const {resolve} = require('path');

module.exports = {
	// 入口
	entry: './src/index.js',
	// 出口
	output: {
		path: resolve(__dirname, 'dist'),
		filename: 'main.js'
	}
}

# 4 loader

  • loader 让 webpack 能把其他非JS和JSON模块转化为JS模块,以便webpack能识别和处理
  • loader 有test和use 两个属性,前者表示匹配某个文件,后者表示如何转化
npm i raw-loader -D
// 例如,读取.txt文件的loader配置如下
const {resolve} = require('path');

module.exports = {
	entry: './src/index.js',
	output: {
		path: resolve(__dirname, 'dist'),
		filename: 'main.js'
	},
	module: {
		rules: [
			// 解析 .txt
			{ test: /\.txt$/, use: 'raw-loader' }
		
		]
	}
}

# 5 插件

  • 插件用于 打包优化,资源管理,注入环境变量
npm i html-webpack-plugin -D
const {resolve} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 引入插件

module.exports = {
	entry: './src/index.js',
	output: {
		path: resolve(__dirname, 'dist'),
		filename: 'main.js'
	},
	module: {
		rules: [
			// 解析 .txt
			{ test: /\.txt$/, use: 'raw-loader' }
		
		]
	},
	plugins: [
		// 使用插件
		new HtmlWebpackPlugin({
			template: './src/index.html'
		})
	]
}

# 6 模式

  • mode 模式用于区分构建环境,通常为开发环境和生产环境
  • mode 取值development,production 具体见mode
module.exports = {
	mode: 'development', // 当前模式为开发环境
}
  • 模式配置方式
// 1 没有任何配置,webpack的mode默认为production,webpack serve的mode默认为development

// package.json的执行命令配置
"scripts": {
  "build": "webpack",
  "start": "webpack serve"
},

// index.js程序中读取
console.log(process.env.NODE_ENV); // development | production

// webpack.config.js配置文件中读取
console.log('NODE_ENV',process.env.NODE_ENV); // undefined
// 1 命令行加 --mode用来设置模块内的process.env.NODE_ENV,配置文件读取不了

// package.json的执行命令配置
"scripts": {
  "build": "webpack --mode=production",
  "start": "webpack --mode=development serve"
},

// index.js程序中读取
console.log(process.env.NODE_ENV); // development | production

// webpack.config.js配置文件中读取
console.log('NODE_ENV',process.env.NODE_ENV); // undefined
// 2 命令行加 --env用来设置webpack配置文件的函数参数,模块内读取不了

// package.json的执行命令配置
"scripts": {
  "build": "webpack --mode=production",
  "start": "webpack --mode=development serve"
},

// index.js程序中读取
console.log(process.env.NODE_ENV); // development | production

// webpack.config.js配置文件中读取
console.log('NODE_ENV',process.env.NODE_ENV); // undefined

# 二 开发环境

# 1 开发服务器

npm i webpack-dev-server -D
  • 配置文件
// webpack.config.js
module.exports = {
	// 配置静态服务器
	devServer: {
		contentBase: resolve(__dirname, 'static'), // 提供静态资源目录
		writeToDisk: true, // 打包文件写入硬盘,以便于调试
		compress: true, // 是否开启gzip压缩
		port: 3000, // 端口号
		open: true // 自动打开浏览器
	}
}
  • 启动文件
"scripts": {
	"start": "webpack serve"
}

# 2 处理CSS

npm i style-loader css-loader -D
  • 配置文件
// webpack.config.js
module.exports = {
	// loader
	module: {
		rules: [
			{ test: /\.css$/, use: ['style-loader', 'css-loader'] }, // 解析css
		]
	}
}

# 3 处理Less

npm i less less-loader -D
  • 配置文件
// webpack.config.js
module.exports = {
	// loader
	module: {
		rules: [
			{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] }, // 解析less
		]
	}
}

# 4 处理Sass

npm i node-sass sass-loader -D
  • 配置文件
// webpack.config.js
module.exports = {
	// loader
	module: {
		rules: [
			{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }, // 解析sass
		]
	}
}

# 5 处理图片

  • file-loader 解决CSS等文件中的引入图片路径问题
  • url-loader 是对file-loader的增强,可以配置limit限制图片大小,做对应处理
  • html-loader 解决html中引入图片路径问题
  • 安装命令
npm i file-loader url-loader html-loader -D
  • 配置文件
// webpack.config.js
module.exports = {
	// loader
	module: {
		rules: [
			// 解析css中带有url中的图片
			{
				test: /\.(jpg|png|bmp|gif|svg)$/,
				use: [{
					loader: 'url-loader',
					options: {
						name: '[hash:10].[ext]',
						limit: 8192 // 图片小于limit就转为base64内嵌,大于就保持原样引入
					}
				}]
			},
			// 解析html中的src图片
			{ test: /\.html$/, use: ['html-loader'] }, 
		]
	}
}

# 6 babel处理ES6+

npm i babel-loader @babel/core @babel/preset-env -D
  • 配置文件
// webpack.config.js
module.exports = {
	// loader
	module: {
		rules: [
			 // 解析es6
			{
				test: /\.js$/,
				exclude: /node_modules/,
				use: [{
					loader: 'babel-loader',
					options: {
						presets: [
							[
								"@babel/preset-env",
								// false 不对polyfill做操作,直接引入所有的polyfill 代价非常多非常大
								/* {
										useBuiltIns: 'usage', // 按需加载polyfill
										// debug: true,
										corejs: { version: 3 }, // 指定corejs的版本号 2或者3 polyfill
										targets: { // 指定要兼容哪些浏览器
											chrome: '60',
										},
									}, */
							]
						]
					},
				}],
			},
		]
	}
}

# 7 babel处理装饰器

npm i @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties -D
  • 配置文件
// webpack.config.js
module.exports = {
	// loader
	module: {
		rules: [
			 // 解析es6
			{
				test: /\.js$/,
				exclude: /node_modules/,
				use: [{
					loader: 'babel-loader',
					options: {
						presets: [
							[ "@babel/preset-env"]
						],
						// 插件-装饰器
						plugins: [
							["@babel/plugin-proposal-decorators", { legacy: true }],
							["@babel/plugin-proposal-class-properties", { loose: true }],
						],
					},
				}],
			},
		]
	}
}

# 8 babel处理polyfill

npm i babel-loader @babel/core @babel/preset-env -D
  • 配置文件
// webpack.config.js
module.exports = {
	// loader
	module: {
		rules: [
			 // 解析es6
			{
				test: /\.js$/,
				exclude: /node_modules/,
				use: [{
					loader: 'babel-loader',
					options: {
						presets: [
							[
								"@babel/preset-env",
								// false 不对polyfill做操作,直接引入所有的polyfill 代价非常多非常大
								/* {
										useBuiltIns: 'usage', // 按需加载polyfill
										// debug: true,
										corejs: { version: 3 }, // 指定corejs的版本号 2或者3 polyfill
										targets: { // 指定要兼容哪些浏览器
											chrome: '60',
										},
									}, */
							]
						]
					},
				}],
			},
		]
	}
}

polyfill 解决方案

  • polyfill.io
  • polyfill.io自动化的 JavaScript Polyfill 服务
  • polyfill.io通过分析请求头信息中的 UserAgent 实现自动加载浏览器所需的 polyfills
// 页面头部引入js,会根据不同的浏览器下载对应兼容性polyfills
<script src="https://polyfill.io/v3/polyfill.min.js"></script>

# 9 处理Eslint

npm i babel-loader @babel/core @babel/preset-env -D
  • 配置文件
// webpack.config.js
module.exports = {
	// loader
	module: {
		rules: [
			 // 解析es6
			{
				test: /\.js$/,
				exclude: /node_modules/,
				use: [{
					loader: 'babel-loader',
					options: {
						presets: [
							[
								"@babel/preset-env",
								// false 不对polyfill做操作,直接引入所有的polyfill 代价非常多非常大
								/* {
										useBuiltIns: 'usage', // 按需加载polyfill
										// debug: true,
										corejs: { version: 3 }, // 指定corejs的版本号 2或者3 polyfill
										targets: { // 指定要兼容哪些浏览器
											chrome: '60',
										},
									}, */
							]
						]
					},
				}],
			},
		]
	}
}

# eslint
npm i eslint eslint-loader babel-eslint -D

# 第三方类库

# 第三方插件

npm i lodash -S

# 三 生产环境