文章目录
- 1. TypeScript支持(ts-loader)
- 1.1. ts-loader
- 1.1.1. webpack.config.js
- 1.1.2. tsconfig.json
- 1.1.3. src/index.ts
- 1.2. 使用babel-loader将ts转换为js
- 1.2.1. webpack.config.js
- 1.2.2. src/index.ts
- 2. 代码规范检查(Eslint)
- 2.1. webpack.config.js
- 2.2. .eslintrc
- 2.3. src/index.ts
- 3. 图片处理(png/jpg/gif/svg等)
- 3.1. asset模块
- 3.1. webpack.config.js
- 3.1.2. .eslintrc
- 3.1.3. src/index.js
- 3.2. 图片压缩(优化)
- 3.2.1. 安装 `image-webpack-loader`
- 3.2.2. webpack.config.js
- 3.3. 响应式图片
- 3.3.1. 安装
- 3.3.2. webpack.config.js
- 3.3.3. src/index.js
- 3.4. 雪碧图
- 3.4.1. 安装
- 3.4.2. src/images/icons
- 3.4.3. webpack.config.js
- 3.4.4. src/index.js
- 3.4.5. icon.less
1. TypeScript支持(ts-loader)
TypeScript
是一种静态类型的编程语言,是 JavaScript
的一个超集。它由 微软开发,提供了许多 JavaScript
不支持的功能,比如类型检查、接口和类。
1.1. ts-loader
ts-loader
是 Webpack
中的一个加载器,用于将 TypeScript
代码转换成 JavaScript
代码。它是基于 typescript
编译器实现的,支持所有 TypeScript
的语法和特性,可以帮助开发者在 Webpack
中使用 TypeScript
进行开发。
1.1.1. webpack.config.js
将入口文件改为index.ts, 在module中配置ts-loader:
具体代码如下:
const path = require("path"); // nodeJs 的 path 模块
const HtmlWebpackPlugin = require("html-webpack-plugin"); // 生成html的插件,并自动将打包后的 JS、CSS 文件引入 HTML 文件中
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // 将css代码从js文件中拆分出来
module.exports = {
mode: "development", // 模式为开发模式
devtool: false, // 不生成sourcemap
entry: "./src/index.ts", // entry:默认的路径是src/index.js,也可以自定义
output: {
path: path.resolve(__dirname, "dist"), // 打包文件的输出位置
filename: "main.js", // 打包后的文件名
clean: true, // 在新的打包之前清除历史文件
},
devServer: {
static: path.join(__dirname, "public"), // 静态资源路径
compress: true, // 是否开始gzip压缩
host: "localhost", // 服务器主机名
port: 80, // 服务器端口名
open: true, //启动项目后是否自动打开浏览器
hot: true, // 是否启动模块热替功能
historyApiFallback: true, // 处理单页应用的路由问题
watchFiles: ["src/**/*.js", "src/**/*.css"], // 需要监听的文件列表,当这些文件发生变化时,自动重启服务器
},
module: {
rules: [
{
test: /\.ts$/, // 匹配以 .ts 结尾的文件
use: ["ts-loader"],
exclude: /node_modules/, // 不匹配的文件。排除 node_modules 文件夹,不进行 ts 匹配
},
{
test: /\.js$/, // 匹配以 .js 结尾的文件
use: [
{
loader: "babel-loader",
// options: { // 可以直接在这里配置预设,也可以在 .babelrc 文件中配置,也可以在babel.config.js 中配置
// presets: ["@babel/preset-env"]
// }
},
],
},
{
test: /\.css$/, // 匹配以 .css 结尾的文件
use: [
process.env.NODE_ENV === "development"
? "style-loader"
: MiniCssExtractPlugin.loader,
"css-loader",
"postcss-loader",
], // 注意:loader执行顺序是从后往前执行,顺序不能改变
},
{
test: /\.less$/, // 匹配以 .less 结尾的文件
use: [
process.env.NODE_ENV === "development"
? "style-loader"
: MiniCssExtractPlugin.loader,
"css-loader",
"postcss-loader",
"less-loader",
],
},
{
test: /\.scss$/, // 匹配以 .scss 结尾的文件
use: [
process.env.NODE_ENV === "development"
? "style-loader"
: MiniCssExtractPlugin.loader,
"css-loader",
"postcss-loader",
"sass-loader",
],
},
],
},
plugins: [
// 插件使用时,像构造函数一样直接 new 即可
// template:模板文件的路径
// filename:打包后生成的文件名
// chunk:代码块
new HtmlWebpackPlugin({ template: "./src/index.html" }),
new MiniCssExtractPlugin(),
],
};
1.1.2. tsconfig.json
要使用ts,必须配置tsconfig.json文件
具体代码如下:
{
"compilerOptions": {
"noImplicitAny": true, // 不能有隐藏的 any 类型
"moduleResolution": "node" // 使用 nodeJs 的模块规则
}
}
1.1.3. src/index.ts
新建一个ts文件,随便写点ts代码:
具体代码如下:
let arr: number[] = [1, 2, 3];
console.log(arr);
运行 npm run build,查看main.js文件,可以看到ts代码已经被转换成了js代码:
注意:此处如果编译报以下错误,那么需要安装parse-json:
npm install --save parse-json
1.2. 使用babel-loader将ts转换为js
@babel/preset-typescript
是一个babel的一个预设,用于将ts代码转换为js代码
1.2.1. webpack.config.js
配置@babel/preset-typescript:
具体代码如下:
{
test: /\.ts$/, // 匹配以 .ts 结尾的文件
// use: ["ts-loader"], // 由于ts-loader存在一定的性能问题,因此这里我们可以配置 @babel/preset-typescript 来转换ts代码
use: [
{
loader: "babel-loader",
options: {
presets: ["@babel/preset-typescript"],
},
},
],
exclude: /node_modules/, // 不匹配的文件。排除 node_modules 文件夹,不进行 ts 转换
},
1.2.2. src/index.ts
添加一点ts代码:
具体代码如下:
let arr: number[] = [1, 2, 3];
console.log(arr);
type Add = () => void;
let add: Add = () => {
console.log("这是一个函数");
};
add();
运行 npm run build 后,可以看到刚添加的ts代码已经被转换成js代码了:
2. 代码规范检查(Eslint)
-
ESLint 是一款 JavaScript 代码检查工具,它可以帮助开发者在编写代码时检查错误、保持一致的风格和避免常见的陷阱。ESLint 可以使用预定义的规则,也可以通过自定义规则来满足特定的项目需求。
-
ESLint 可以与各种编辑器集成,包括 Visual Studio Code、Sublime Text 和 Atom 等。它还可以与构建工具集成,例如 Webpack 和 Gulp。
-
ESLint 的配置文件是一个 JSON 文件,其中包含要使用的规则和其他选项。ESLint 支持多种配置文件格式,包括
.eslintrc
、.eslintrc.js
、.eslintrc.yaml
和.eslintrc.json
。开发者可以根据项目的需求选择适合自己的配置文件格式。
2.1. webpack.config.js
配置eslint插件:
const EslintPlugin = require("eslint-webpack-plugin");
module.exports = {
// ......
plugins: [
// ......
new EslintPlugin({
// 这些类型的文件需要进行 eslint 代码检查
extensions: ["js", "jsx", "ts", "tsx"],
}),
],
};
2.2. .eslintrc
更多eslint规则
配置eslint规则:
具体代码如下:
{
"parser": "@typescript-eslint/parser", // 解释器
"plugins": ["@typescript-eslint"], // 插件
"root": true,
"env": {
"node": true,
"es6": true
},
"extends": [
"eslint:recommended" // 继承 recommended 代码规范
],
"parserOptions": {
"ecmaVersion": 2021 // es 规范
},
"rules": { // 配置一些规则
"no-console": "warn", // 不允许调用 console 对象,否则会报警告
"no-unused-vars": "warn" // 未使用的变量报警告
}
}
2.3. src/index.ts
let arr: number[] = [1, 2, 3];
console.log(arr);
type Add = () => void;
let add: Add = () => {
console.log("这是一个函数");
};
add();
let a: string = 'hello world';
编译后,可以看到此时报了一些警告:
按要求解决完代码中的console和变量:
let arr: number[] = [1, 2, 3];
arr.push(4);
type Add = () => void;
let add: Add = () => {
};
add();
let a: string = 'hello world';
a + "你好";
再次编译已经没有警告了:
3. 图片处理(png/jpg/gif/svg等)
3.1. asset模块
在 Webpack 5
中,可以使用 type: 'asset/xxxx'
配置选项来处理图片等资源文件。
type 类型有四种:
asset/resource
:每个资源文件作为单独的文件输出,并返回 URL。asset/inline
:生成 base64 编码的字符串直接嵌入到输出的 JavaScript bundle 中。可以减少请求,但会加大体积。asset/source
:将文件处理和捆绑为原始源代码。文件内容会作为字符串加载,并可直接在捆绑包中使用。asset
:会自动选择导出数据 URI 还是生成单独的文件,可以设置文件大小限制来实现。
3.1. webpack.config.js
module.exports = {
// ......
entry: "./src/index.js", // entry:默认的路径是src/index.js,也可以自定义
// ......
devServer: {
// ......
},
module: {
rules: [
{
test: /\.png$/,
type: "asset/resource",
},
{
test: /\.jpg$/,
type: "asset/inline",
},
{
test: /\.bmp$/,
type: "asset/source",
},
{
test: /\.svg$/,
type: "asset",
parser: {
dataUrlCondition: {
maxSize: 1024, // 小于1024的"asset/resource",大于1024的"asset/inline"
},
},
},
// ......
],
},
};
3.1.2. .eslintrc
注意:需要在eslintrc文件中添加browser:true,否则index.js中使用document对象会报错。
3.1.3. src/index.js
测试一下asset这几种状态:
// 图片处理
let imgPng = require("./images/baidu.png");
let imgJpg = require("./images/hao123.jpg");
let imgBmp = require("./images/360.bmp");
let imgSvg = require("./images/google.svg");
let image = document.createElement("img");
image.src = imgPng;
console.log(image, "png");
image.src = imgJpg;
console.log(image, "jpg");
image.src = imgBmp;
console.log(image, "jpg");
image.src = imgSvg;
console.log(image, "jpg");
-
asset/resource
运行 npm run dev 后,查看控制台: -
asset/inline
运行 npm run dev 后,查看控制台:
-
asset/source
运行 npm run dev 后,查看控制台:
-
asset
先看一下这个图片的大小是1829 byte,我们会测试一次大于设置的尺寸,测试一次小于设置的尺寸。
1.测试大于maxSize:
运行 npm run dev 后,查看控制台:2.测试小于maxSize:
运行 npm run dev 后,查看控制台:
3.2. 图片压缩(优化)
image-webpack-loader
可以在Webpack
打包过程中对图片进行优化和压缩,从而减小图片文件的大小,提高页面加载速度和响应速度- optipng:用于压缩PNG图片的配置项
- pngquant:同样用于压缩PNG图片的配置项,可以设置图片质量和压缩速度
- svgo:用于压缩SVG图片的配置项,包含多个插件
- gifsicle:用于压缩Gif图片的配置项
- webp:用于将JPG/PNG图片压缩并转换为WebP图片格式的配置项
3.2.1. 安装 image-webpack-loader
cnpm install image-webpack-loader --save
3.2.2. webpack.config.js
module.exports = {
// ......
module: {
rules: [
// ......
{
// 匹配文件的正则表达式,这里表示匹配JPG、PNG、GIF和SVG格式的图片文件
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
{
// 使用image-webpack-loader对图片进行优化和压缩
loader: "image-webpack-loader",
options: {
// 是否禁用图片优化和压缩
disable: process.env.NODE_ENV === "development",
mozjpeg: {
progressive: true, // 是否开启渐进式JPEG,可以有效提升JPEG图片加载速度
quality: 65, // 压缩JPEG图片的质量,取值范围为0到100,值越大质量越好但文件越大
},
optipng: {
enabled: true, // 是否开启PNG图片的优化,可以有效提升PNG图片加载速度
},
pngquant: {
// 压缩PNG图片的质量范围,取值范围为0到1,值越大质量越好但文件越大
// 第一个数字表示压缩质量的下限,第二个数字表示压缩质量的上限
quality: [0.65, 0.9],
speed: 4, // 压缩PNG图片的速度,取值范围为1到10,值越大速度越快但质量越低
},
svgo: {
plugins: [
// 压缩SVG图片的插件列表,这里包含removeViewBox和cleanupIDs两个插件
{
//用于删除SVG图片中的viewBox属性
//viewBox属性是用来指定SVG视口范围的,它的值是一个矩形框的坐标和宽高
removeViewBox: false,
},
{
//用于删除SVG图片中的无用ID属性
cleanupIDs: true,
},
],
},
gifsicle: {
interlaced: true, // 是否开启GIF图片的隔行扫描,可以有效提升GIF图片加载速度
},
},
},
],
},
// ......
],
},
};
运行npm run build后,可以看到图片体积明显变小了:
3.3. 响应式图片
- 响应式图片是指能够根据设备屏幕大小和分辨率等因素动态调整显示大小和清晰度的图片。
responsive-loader
是一个webpack
的loader
,用于实现响应式图片的功能。它可以根据设备屏幕大小和像素密度等因素自动调整图片大小和清晰度,从而提高网站的用户体验和性能。sizes
:用于指定不同尺寸的图片大小。在这个例子中,我们指定了3个不同的图片大小,分别是375px(iphone6/7/8/X尺寸)
、768px(ipad尺寸)
、1024px(ipadPro尺寸)
。当加载图片时,responsive-loader
会根据设备的屏幕大小和像素密度等因素自动选择最合适的图片大小。adapter
:用于指定图片处理库。在这个例子中,我们使用了sharp
库,它是一个高性能的图片处理库,可以用来自动调整图片大小和清晰度。
srcset
和sizes
是HTML
中img
标签的两个属性,用于实现响应式图片的功能。srcset
属性用于指定不同尺寸和清晰度的图片版本,它的值是一个以逗号分隔的图片列表,每个图片元素包含了图片URL
和对应的宽度或像素密度等信息。sizes
属性用于指定图片在不同屏幕尺寸下的显示大小,它的值是一个以逗号分隔的尺寸列表,每个尺寸元素包含了媒体查询和对应的尺寸信息。
3.3.1. 安装
cnpm i responsive-loader sharp --save
3.3.2. webpack.config.js
module.exports = {
module: {
rules: [
// ......
{
test: /\.png$/,
//oneOf是一个优化选项,用于提高打包的速度
oneOf: [
{
//resourceQuery是一个用于匹配请求资源的URL中查询字符中是否包含sizes,如果包含则切图,不包含则执行下面的asset/resource
resourceQuery: /sizes/,
use: [
{
loader: "responsive-loader",
options: {
adapter: require("responsive-loader/sharp"),
},
},
],
},
{
type: "asset/resource",
},
],
},
// ......
],
},
};
3.3.3. src/index.js
import bgPng from "./images/bg.png?sizes[]=375,sizes[]=768,sizes[]=1024";
console.log(bgPng, "bgPng");
let image = new Image();
// let image = document.createElement("img"); // 等效上一行的写法
image.srcset = bgPng.srcSet;
// 屏幕宽度大于768px,则使用768px图片,并且图片宽度是屏幕的可视区域宽度
image.sizes = `(min-width: 768) 768px,100vw`;
document.body.appendChild(image);
运行npm run build,可以看到图片被打包成不同尺寸:
运行npm run dev启动项目,切换不同屏幕尺寸可以看到效果如下:
也可以通过审查这个元素去查看图片渲染大小:
3.4. 雪碧图
- 雪碧图(Sprite)是指将多个小图片(如图标、小按钮等)合并成一张大图片,通过CSS的
background-position
属性来控制显示不同的小图片。它的优点是减少HTTP请求次数,提高页面的加载速度和性能。 webpack-spritesmith
是一个webpack
插件,用于生成雪碧图。它可以将多个小图片合并成一张大图片,并在生成的CSS
文件中自动生成background-position
属性和样式代码,简化了雪碧图的生成和使用过程。
3.4.1. 安装
cnpm install --save webpack-spritesmith
3.4.2. src/images/icons
准备一个 icons
文件夹,放入事先下载的png图片:
3.4.3. webpack.config.js
const path = require("path"); // nodeJs 的 path 模块
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // 将css代码从js文件中拆分出来
const WebpackSpritesmith = require("webpack-spritesmith"); // 生成雪碧图插件
module.exports = {
module: {
rules: [
// ......
{
test: /\.less$/, // 匹配以 .less 结尾的文件
use: [
process.env.NODE_ENV === "development"
? "style-loader"
: MiniCssExtractPlugin.loader,
"css-loader",
"postcss-loader",
// "less-loader",
{
loader: "less-loader",
options: {
lessOptions: {
paths: [path.resolve(__dirname, "src/sprite")],
},
},
},
],
},
// ......
],
},
plugins: [
// ......
new WebpackSpritesmith({
// 具体配置可查看github
src: {
//指定输入的文件
cwd: path.resolve(__dirname, "src/images/icons"),
glob: "**/*.png",
},
target: {
//指定输出的文件路径
image: path.resolve(__dirname, "src/sprite/sprite.png"),
css: path.resolve(__dirname, "src/sprite/sprite.less"),
},
apiOptions: {
// 指定CSS文件应使用相对路径引用精灵图
cssImageRef: "sprite/sprite.png",
},
spritesmithOptions: {
algorithm: "top-down",
padding: 10,
},
}),
],
};
3.4.4. src/index.js
/**
* 6.雪碧图测试代码
*/
import "./icon.less";
let img1 = document.createElement("img");
img1.classList.add("icon-baidu");
document.body.appendChild(img1);
let img2 = document.createElement("img");
img2.classList.add("icon-hao123");
document.body.appendChild(img2);
let img3 = document.createElement("img");
img3.classList.add("icon-360");
document.body.appendChild(img3);
3.4.5. icon.less
@import "./sprite/sprite.less"; // 引用雪碧图文件
.icon-baidu {
.sprite(@baidu);
}
.icon-hao123 {
.sprite(@hao123);
}
.icon-360 {
.sprite(@360);
}
运行 npm run dev 查看效果:
-
首先根据我们的配置,生成一个src/sprite/sprite.less和一个src/sprite/sprite.png文件
-
其次我们在src/icon.less中导入的样式会生效
-
然后就可以看到页面上已经将图片渲染出来了,并且是采用的雪碧图,是通过background-position属性实现的,减少了http请求,有效的提高了加载性能