Webpack——必知必会

文章目录

  • npm要装的都在这里
  • 使用配置文件
  • 处理CSS
      • css
      • less
  • 处理CSS兼容性
      • browserslist
      • postcss
      • @import
  • 资源文件
      • 图片
      • 背景图片
      • 自定义图片名称
      • url-loader
      • asset
      • 图标字体
  • 插件
      • 自动清理输出文件夹
      • 自动生成根html
      • 拷贝public文件夹
  • 处理JS兼容性
      • babel-loader
      • polyfill
  • 搭建服务器
  • 最终配置
  • 待补充

偏架构的东西,解决问题即可。

npm要装的都在这里

结尾有现成的package.json

核心工具:

webpack webpack-cli webpack-dev-server

CSS:

css-loader style-loader

less less-loader

CSS兼容性

browserslist

postcss postcss-loader

autoprefixer
postcss-preset-env

资源文件

file-loader url-loader

插件

clean-webpack-plugin

html-webpack-plugin

copy-webpack-plugin

JS兼容性

@babel/core babel-loader

@babel/plugin-transform-arrow-functions
@babel/plugin-transform-block-scoping

@babel/preset-env

@babel/polyfill
core-js
regenerator-runtime

使用配置文件

项目结构:
Webpack——必知必会_第1张图片
webpack.config.js

let path = require("path");

module.exports = {
	mode: "development",
	entry: "./src/index.js",
	output: {
		filename: "build.js",
		path: path.resolve(__dirname, "build")
	}
}

执行脚本

"build": "webpack --config webpack.config.js"

处理CSS

css

JS中引入样式文件

import "./a.css";

css-loader:处理css的导入,转为文件名数组
style-loader:读取数组,写入,包裹上style标签。

顺序:从后往前。

let path = require("path");

module.exports = {
	mode: "development",
	entry: "./src/index.js",
	output: {
		filename: "build.js",
		path: path.resolve(__dirname, "build")
	}, module: {
		rules: [
			{
				test: /\.css$/,
				use: ['style-loader','css-loader']
			}
		]
	}
}

less

rules: [
	{
		test: /\.css$/,
		use: ['style-loader', 'css-loader']
	}, {
		test: /\.less$/,
		use: ['style-loader', 'css-loader', 'less-loader']
	}
]

处理CSS兼容性

browserslist

作用:看看符合条件的浏览器版本有哪些。

在package.json中配置

"browserslist": [
  ">1%",
  "last 4 version",
  "not dead"
]

命令行调用

browserslist

postcss

处理JS中的CSS。

CSS=>样式树=>一番修改=>CSS。

插件决定怎么修改。

autoprefixer:自动加浏览器前缀插件。
postcss-preset-env:一堆流行的插件。

let postcss = {
	loader: "postcss-loader",
	options: {
		postcssOptions: {
			plugins: ["postcss-preset-env"]
		}
	}
}

rules: [
	{
		test: /\.css$/,
		use: ['style-loader', 'css-loader', postcss]
	}, {
		test: /\.less$/,
		use: ['style-loader', 'css-loader', postcss, 'less-loader']
	}
]

效果:
Webpack——必知必会_第2张图片

@import

效果:
处理css中导入的css的兼容性。

把css-loader换成:

let css={
	loader:"css-loader",
	options: {
		importLoaders:1
	}
}

1代表向前提交一级(postcss)
否则会漏掉。

资源文件

图片

let file={
	loader: "file-loader",
	options: {
		esModule: false
	}
}

{
	test: /\.jpg$/,
	use: [file]
}
function addImg(src) {
	let e = document.createElement("img");
	e.src = src;
	document.body.appendChild(e);
}

let img = require("./a.jpg");

addImg(img);

Webpack——必知必会_第3张图片

背景图片

body{
    background-image: url("./a.jpg");
}
let css = {
	loader: "css-loader",
	options: {
		importLoaders: 1,
		esModule: false
	}
}

Webpack——必知必会_第4张图片

自定义图片名称

let file = {
	loader: "file-loader",
	options: {
		esModule: false,
		name: "img/[name][hash:6].[ext]"
	}
}

url-loader

图片会被转码,收集进js中。

小图片适用,可以减少请求次数。

let file = {
	loader: "url-loader",
	options: {
		esModule: false
	}
}

按文件大小选择方式:

let file = {
	loader: "url-loader",
	options: {
		esModule: false,
		name: "img/[name][hash:6].[ext]",
		limit: 24 * 1024
	}
}

24kb以下:编码。
以上:单独的文件。

asset

asset/resource:单独的文件
asset/inline:编码。

let file = {
	type: "asset",
	generator: {
		filename: "img/[name][hash:6].[ext]"
	}, parser: {
		dataUrlCondition: {
			maxSize: 24 * 1024
		}
	}
}
{
	test: /\.jpg$/,
	...file
}

图标字体

举例:https://www.bootcss.com/p/font-awesome/

有用的文件夹:css,font

function addTag(tagName, attrName, attrValue) {
	let e = document.createElement(tagName);
	e.setAttribute(attrName, attrValue);
	document.body.appendChild(e);
}

/*let img = require("./a.jpg");*/

/*
addImg(img);*/
require("./Font-Awesome-3.2.1/css/font-awesome.min.css")

addTag("i", "class", " icon-cloud-download");
{
	test: /\.(jpg|otf|eot|svg|ttf|woff)$/,
	...file
}

Webpack——必知必会_第5张图片

插件

自动清理输出文件夹

let Clean = require("clean-webpack-plugin").CleanWebpackPlugin;

module.exports = {
	mode: "development",
	entry: "./src/index.js",
	output: {
		//...
	}, plugins: [
		new Clean()
	]
}

自动生成根html

let Html = require('html-webpack-plugin');

plugins: [
	new Clean(), new Html()
]

设置HTML模版

new Html({
	template: "./public/index.html"
})

拷贝public文件夹

let Copy = require('copy-webpack-plugin');

new Copy({
	patterns: [
		{
			from: "public",
			globOptions: {
				ignore: ['**/index.html']
			}
		}
	]
})

处理JS兼容性

babel-loader

@babel/plugin-transform-arrow-functions:箭头函数
@babel/plugin-transform-block-scoping:块级作用域

@babel/preset-env:流行的插件集合

let babel = {
	loader: "babel-loader",
	options: {
		presets: ["@babel/preset-env"]
	}
}

{
	test: /\.js$/,
	use: [babel]
}

效果:

Webpack——必知必会_第6张图片
Webpack——必知必会_第7张图片

polyfill

效果:提供Promise函数。

let babel = {
	loader: "babel-loader",
	options: {
		presets: [["@babel/preset-env", {
			useBuiltIns: 'usage',
			corejs: 3
		}]]
	}
}
{
	test: /\.js$/,
	exclude:/node_modules/,
	use: [babel]
}

搭建服务器

运行服务器:

"scripts": {
  "build": "webpack --config webpack.config.js",
  "serve": "webpack serve --config webpack.config.js"
}

配置模块热更新:
1,配置文件中

target: "web",
devServer: {
	hot: true
}

2,入口JS

require("./a")
if (module.hot) {
	module.hot.accept(["./a.js"])
}

这样,a.js才能热更新。

测试方法:在页面中添加输入框,输入一些内容,更新模块代码。
Webpack——必知必会_第8张图片

最终配置

package.json

{
  "name": "demo",
  "version": "1.0.0",
  "description": "",
  "scripts": {
    "build": "webpack --config webpack.build.js",
    "serve": "webpack serve --config webpack.build.js",
    "dist": "webpack --config webpack.dist.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.17.5",
    "@babel/polyfill": "^7.12.1",
    "@babel/preset-env": "^7.16.11",
    "autoprefixer": "^10.4.2",
    "babel": "^6.23.0",
    "babel-cli": "^6.26.0",
    "babel-loader": "^8.2.3",
    "clean-webpack-plugin": "^4.0.0",
    "copy-webpack-plugin": "^10.2.4",
    "core-js": "^3.21.1",
    "css-loader": "^6.6.0",
    "file-loader": "^6.2.0",
    "html-webpack-plugin": "^5.5.0",
    "less": "^4.1.2",
    "less-loader": "^10.2.0",
    "postcss": "^8.4.7",
    "postcss-loader": "^6.2.1",
    "postcss-preset-env": "^7.4.1",
    "regenerator-runtime": "^0.13.9",
    "style-loader": "^3.3.1",
    "url-loader": "^4.1.1",
    "webpack": "5.69.1",
    "webpack-cli": "4.9.2",
    "webpack-dev-server": "^4.7.4"
  },
  "browserslist": [
    ">1%",
    "last 4 version",
    "not dead"
  ]
}

生产配置:

生产环境没有dev-server。

let path = require("path");

let Clean = require("clean-webpack-plugin").CleanWebpackPlugin;
let Html = require('html-webpack-plugin');
let Copy = require('copy-webpack-plugin');
let css = {
	loader: "css-loader",
	options: {
		importLoaders: 1,
		esModule: false
	}
}
let postcss = {
	loader: "postcss-loader",
	options: {
		postcssOptions: {
			plugins: ["postcss-preset-env"]
		}
	}
}
let babel = {
	loader: "babel-loader",
	options: {
		presets: [["@babel/preset-env", {
			useBuiltIns: 'usage',
			corejs: 3
		}]]
	}
}
let file = {
	type: "asset",
	generator: {
		filename: "file/[name][hash:6].[ext]"
	}, parser: {
		dataUrlCondition: {
			maxSize: 24 * 1024
		}
	}
}
module.exports = {
	mode: "production",
	entry: "./src/index.js",
	output: {
		filename: "dist.js",
		path: path.resolve(__dirname, "dist")
	}, module: {
		rules: [
			{
				test: /\.css$/,
				use: ['style-loader', css, postcss]
			}, {
				test: /\.less$/,
				use: ['style-loader', css, postcss, 'less-loader']
			}, {
				test: /\.(jpg)$/,
				...file
			}, {
				test: /\.(otf|eot|svg|ttf|woff)$/,
				...file
			}, {
				test: /\.js$/,
				exclude: /node_modules/,
				use: [babel]
			}
		]
	}, plugins: [
		new Clean(),
		new Html({
			template: "./public/index.html"
		}), new Copy({
			patterns: [
				{
					from: "public",
					globOptions: {
						ignore: ['**/index.html']
					}
				}
			]
		})
	]
}

开发配置:

开发环境不需要考虑兼容性。

let path = require("path");

let Clean = require("clean-webpack-plugin").CleanWebpackPlugin;
let Html = require('html-webpack-plugin');
let Copy = require('copy-webpack-plugin');
let css = {
	loader: "css-loader",
	options: {
		importLoaders: 1,
		esModule: false
	}
}
let file = {
	type: "asset",
	generator: {
		filename: "file/[name][hash:6].[ext]"
	}, parser: {
		dataUrlCondition: {
			maxSize: 24 * 1024
		}
	}
}
module.exports = {
	mode: "development",
	entry: "./src/index.js",
	output: {
		filename: "build.js",
		path: path.resolve(__dirname, "build")
	}, module: {
		rules: [
			{
				test: /\.css$/,
				use: ['style-loader', css]
			}, {
				test: /\.less$/,
				use: ['style-loader', css, 'less-loader']
			}, {
				test: /\.(jpg)$/,
				...file
			}, {
				test: /\.(otf|eot|svg|ttf|woff)$/,
				...file
			}
		]
	}, plugins: [
		new Clean(),
		new Html({
			template: "./public/index.html"
		}), new Copy({
			patterns: [
				{
					from: "public",
					globOptions: {
						ignore: ['**/index.html']
					}
				}
			]
		})
	],
	target: "web",
	devServer: {
		hot: true
	}
}

待补充

  • React,以及热更新。
  • Vue,以及热更新。
  • 路径问题。
  • Source Map
  • TypeScript

你可能感兴趣的:(#,Webpack,webpack,学习,javascript)