Babel与webpack
Babel 是什么
Babel 是一个 JavaScript 编译器(转译器),负责把新的 JavaScript 代码转换成旧环境也能运行的代码。
为什么需要 Babel?
现代浏览器支持,但老浏览器(比如 IE)不支持箭头函数。Babel 可以把它转换成:
const fn = (a, b) => a + b;
//转换var fn = function (a, b) { return a + b;};Babel 能干什么?
转换 ES6+ 语法:箭头函数、类、模板字符串、解构赋值,转换模块语法,转换实验性语法,编译 JSX以前 Node 不支持 ESM 时,经常这么干。Babel 不是打包工具,是负责代码转换
import { add } from './math.js';//转换成const { add } = require('./math');Babel 的使用方式
Babel 的使用方式其实就三步:安装 Babel-配置 Babel-执行编译
初始化项目
npm init -y安装 Babel
npm install -D @babel/core @babel/cli @babel/preset-env创建源码:
const fn = (a, b) => a + b;console.log(fn(1, 2));配置 Babel:
//babel.config.json{ "presets": ["@babel/preset-env"]}//或者//.babelrc{ "presets": ["@babel/preset-env"]}执行编译
npx babel src -d dist生成:dist/index.js
"use strict";var fn = function fn(a, b) { return a + b;};console.log(fn(1, 2));package.json 配置脚本
{ "scripts": { "build": "babel src -d dist" }}指定目标环境:如果这里不设置,Babel(@babel/preset-env)默认会根据**目标环境(targets)**决定是否转换,现代环境下就不转换了
{ "presets": [ [ "@babel/preset-env", { "targets": { "chrome": "80" } } ] ]}//只兼容 Chrome80+配合 browserslist,Babel 会自动根据目标浏览器决定转换哪些语法。
//package.json{ "browserslist": [ ">1%", "last 2 versions", "not dead" ]}使用 Babel 前的准备工作
- 安装nodejs和npm ;推荐使用nvm
- 初始化项目(Babel 的使用方式已经有讲解)
- 安装bable需要的包(Babel 的使用方式已经有讲解)
使用 Babel 编译 ES6 代码
- Babel 的使用方式已经有讲解
Webpack是什么
- Webpack 是一个静态模块打包工具(Static Module Bundler)。
- webpack是静态模块打包器,当webpack处理应用程序时,会将所有这些模块打包成一个或多个文件
- 模块:webpack可以处理js/css/图片、图标字体等单位文件
- 静态:开发过程中存在于本地的js/css/图片/图标字体等文件,就是静态的
- 动态内容webpack没办法处理
Webpack 初体验
初始化项目
mkdir webpack-democd webpack-demonpm init -y安装webpack需要的包
npm i webpack webpack-cli -D创建示例代码:
src/math.js
export function add(a, b) { return a + b;}src/index.js
import { add } from './math';
console.log(add(1, 2));配置webpack
const path = require('path');module.exports = { mode: 'development', // development开发模式 production生产模式 entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist'), },};development(开发模式):不压缩、可读性强、调试友好、构建快
production(生产模式):代码压缩、Tree Shaking、性能优化、文件更小
打包测试
npx webpacknode dist/bundle.jsentry和output
- webpacke的4核心概念:entry、output、loader、plugins
- entry输入:就是程序入口
- output输出:打包之后路径
loader
Loader 的作用:让 Webpack 能“读懂”非 JS 文件
试试babel-loader,ES6 → ES5
npm i -D babel-loaderconst path = require('path');
module.exports = { mode: 'development', entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist'), }, module: { rules: [ { test: /\.(js|jsx)$/, use: ['babel-loader'], exclude: [path.join(__dirname, './node_modules')], //排除node_modules }, ], },};Loader 可以链式执行,执行顺序是 从右到左
use: ['style-loader', 'css-loader', 'postcss-loader']plugins
Plugin 用来“增强 Webpack 的能力”,而不是转换单个文件。
做什么:监听 Webpack 整个生命周期,做“全局事情”,比如打包前清空 dist、自动生成 HTML、压缩 JS、提取 CSS、打包分析、注入环境变量
区别:
| 对比 | Loader | Plugin |
|---|---|---|
| 作用 | 转换文件 | 扩展功能 |
| 作用范围 | 单个模块 | 整个构建流程 |
| 时机 | 加载阶段 | 编译生命周期 |
| 写法 | rules | plugins |
举例: 清理 dist,插件clean-webpack-plugin ,每次打包前清空 dist目录
npm install --save-dev clean-webpack-pluginconst { CleanWebpackPlugin } = require('clean-webpack-plugin');plugins: [new CleanWebpackPlugin()]从 Webpack 5 开始,官方已经内置了类似功能,可以直接使用
module.exports = { output: { clean: true }};举例: 插件HtmlWebpackPlugin,该插件将为你生成一个 HTML5 文件, 在 body 中使用 script 标签引入你所有 webpack 生成的 bundle
npm install --save-dev html-webpack-pluginconst HtmlWebpackPlugin = require('html-webpack-plugin');plugins: [ new HtmlWebpackPlugin()],HtmlWebpackPlugin进阶使用:多个js入口文件,多个html,a.html引入a.js,b.html引入b.js;并且配置压缩minify
const path = require('path');const { CleanWebpackPlugin } = require('clean-webpack-plugin');const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = { mode: 'development',
entry: { index: './src/index.js', search: './src/search.js', },
output: { filename: '[name].js', path: path.resolve(__dirname, 'dist'), clean: true, }, module: { rules: [ { test: /\.(js|jsx)$/, use: ['babel-loader'], exclude: [path.join(__dirname, './node_modules')], //排除node_modules }, ], }, plugins: [ new HtmlWebpackPlugin({ // template: 'index.html',不写模板,自动创建,demo样式可以这样 filename: 'index.html', //重命名 chunks: ['index'], //指定引入 minify: { collapseWhitespace: true, keepClosingSlash: true, removeComments: true, removeRedundantAttributes: true, removeScriptTypeAttributes: true, removeStyleLinkTypeAttributes: true, useShortDoctype: true, }, }), new HtmlWebpackPlugin({ // template: 'search.html', filename: 'search.html', //重命名 chunks: ['search'], //指定引入 minify: { collapseWhitespace: true, keepClosingSlash: true, removeComments: true, removeRedundantAttributes: true, removeScriptTypeAttributes: true, removeStyleLinkTypeAttributes: true, useShortDoctype: true, }, }), ],};处理CSS文件
webpack不认识除js以外的文件,所以这里需要loader
安装:
npm install -D style-loader css-loader配置 Webpack
const path = require('path');
module.exports = { mode: 'development',
entry: './src/index.js',
output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') },
module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'] //⚠️loader 执行顺序是从右到左 } ] }};Webpack 实际做了这些事:
1:css-loader 阶段:把style.css转换成 JS 模块,类似:export default "body { background: pink; }";
2:style-loader 阶段:把 CSS 插入 DOM,类似:
const style = document.createElement('style');style.innerHTML = "body { background: pink; }";document.head.appendChild(style);进阶处理CSS,使用link方式引入
安装插件:mini-css-extract-plugin
npm install -D mini-css-extract-plugin使用:
const MiniCssExtractPlugin = require('mini-css-extract-plugin'){ test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'], //换MiniCssExtractPlugin.loader },new MiniCssExtractPlugin({ filename: 'css/[name].css', }),完整:
const path = require('path');const { CleanWebpackPlugin } = require('clean-webpack-plugin');const HtmlWebpackPlugin = require('html-webpack-plugin');const MiniCssExtractPlugin = require('mini-css-extract-plugin');module.exports = { mode: 'production',
entry: { index: './src/index.js', search: './src/search.js', },
output: { filename: '[name].js', path: path.resolve(__dirname, 'dist'), clean: true, }, module: { rules: [ { test: /\.(js|jsx)$/, use: ['babel-loader'], exclude: [path.join(__dirname, './node_modules')], //排除node_modules }, { test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'], //换MiniCssExtractPlugin.loader }, { test: /\.(png|jpg|jpeg|gif)$/i, type: 'asset/resource', }, { test: /\.(png|jpg|jpeg)$/i, use: [ { loader: 'image-webpack-loader', options: { mozjpeg: { quality: 70, }, }, }, ], }, ], }, plugins: [ new HtmlWebpackPlugin({ // template: 'index.html',不写模板,自动创建,demo样式可以这样 filename: 'index.html', //重命名 chunks: ['index'], //指定引入 minify: { collapseWhitespace: true, keepClosingSlash: true, removeComments: true, removeRedundantAttributes: true, removeScriptTypeAttributes: true, removeStyleLinkTypeAttributes: true, useShortDoctype: true, }, }), new HtmlWebpackPlugin({ // template: 'search.html', filename: 'search.html', //重命名 chunks: ['search'], //指定引入 minify: { collapseWhitespace: true, keepClosingSlash: true, removeComments: true, removeRedundantAttributes: true, removeScriptTypeAttributes: true, removeStyleLinkTypeAttributes: true, useShortDoctype: true, }, }), new MiniCssExtractPlugin({ filename: 'css/[name].css', }), ],};使用file-loader处理CSS中的图片
-
webpack不会处理远程的图片,所以,如果图片是在外部服务器的,webpack不会处理,可以正常执行
-
注意:在webpack4之前,处理本地css图片是需要这个包的,但是webpack5新增了Asset Modules,并且默认开启,所以在webpack5即便什么都不做,也不会出错,file-loader在webpack5不推荐使用
-
file-loader使用 ⚠2026年6月25日,webpack5下这插件不能使用,有问题,推荐新写法
npm install -D file-loaderconst path = require('path');const { CleanWebpackPlugin } = require('clean-webpack-plugin');const HtmlWebpackPlugin = require('html-webpack-plugin');const MiniCssExtractPlugin = require('mini-css-extract-plugin');module.exports = {mode: 'production',entry: {index: './src/index.js',search: './src/search.js',},output: {filename: '[name].js',path: path.resolve(__dirname, 'dist'),clean: true,},module: {rules: [{test: /\.(js|jsx)$/,use: ['babel-loader'],exclude: [path.join(__dirname, './node_modules')], //排除node_modules},{test: /\.css$/,use: [MiniCssExtractPlugin.loader, 'css-loader'], //换MiniCssExtractPlugin.loader},// webpack5新特性// {// test: /\.(png|jpg|jpeg|gif)$/i,// type: 'asset/resource',// },{test: /\.(png|jpg|jpeg|gif)$/i,use: [{loader: 'file-loader',options: {name: '[name].[hash].[ext]',outputPath: 'images',},},],},],},plugins: [new HtmlWebpackPlugin({// template: 'index.html',不写模板,自动创建,demo样式可以这样filename: 'index.html', //重命名chunks: ['index'], //指定引入minify: {collapseWhitespace: true,keepClosingSlash: true,removeComments: true,removeRedundantAttributes: true,removeScriptTypeAttributes: true,removeStyleLinkTypeAttributes: true,useShortDoctype: true,},}),new HtmlWebpackPlugin({// template: 'search.html',filename: 'search.html', //重命名chunks: ['search'], //指定引入minify: {collapseWhitespace: true,keepClosingSlash: true,removeComments: true,removeRedundantAttributes: true,removeScriptTypeAttributes: true,removeStyleLinkTypeAttributes: true,useShortDoctype: true,},}),new MiniCssExtractPlugin({filename: 'css/[name].css',}),],};webpack新写法:asset/resource
const path = require('path');const { CleanWebpackPlugin } = require('clean-webpack-plugin');const HtmlWebpackPlugin = require('html-webpack-plugin');const MiniCssExtractPlugin = require('mini-css-extract-plugin');module.exports = {mode: 'production',entry: {index: './src/index.js',search: './src/search.js',},output: {filename: '[name].js',path: path.resolve(__dirname, 'dist'),clean: true,},module: {rules: [{test: /\.(js|jsx)$/,use: ['babel-loader'],exclude: [path.join(__dirname, './node_modules')], //排除node_modules},{test: /\.css$/,use: [MiniCssExtractPlugin.loader, 'css-loader'], //换MiniCssExtractPlugin.loader},// webpack5新特性{test: /\.(png|jpg|jpeg|gif)$/i,type: 'asset/resource',generator: {filename: 'img/[name].[contenthash][ext]', //img文件夹下创建图片},},],},plugins: [new HtmlWebpackPlugin({// template: 'index.html',不写模板,自动创建,demo样式可以这样filename: 'index.html', //重命名chunks: ['index'], //指定引入minify: {collapseWhitespace: true,keepClosingSlash: true,removeComments: true,removeRedundantAttributes: true,removeScriptTypeAttributes: true,removeStyleLinkTypeAttributes: true,useShortDoctype: true,},}),new HtmlWebpackPlugin({// template: 'search.html',filename: 'search.html', //重命名chunks: ['search'], //指定引入minify: {collapseWhitespace: true,keepClosingSlash: true,removeComments: true,removeRedundantAttributes: true,removeScriptTypeAttributes: true,removeStyleLinkTypeAttributes: true,useShortDoctype: true,},}),new MiniCssExtractPlugin({filename: 'css/[name].css',}),],};
使用html-withimg-loader处理HTML中的图片
处理html的图片
安装
npm install -D html-withimg-loader使用
const path = require('path');const { CleanWebpackPlugin } = require('clean-webpack-plugin');const HtmlWebpackPlugin = require('html-webpack-plugin');const MiniCssExtractPlugin = require('mini-css-extract-plugin');module.exports = { mode: 'production',
entry: { index: './src/index.js', search: './src/search.js', },
output: { filename: '[name].js', path: path.resolve(__dirname, 'dist'), clean: true, }, module: { rules: [ { test: /\.(js|jsx)$/, use: ['babel-loader'], exclude: [path.join(__dirname, './node_modules')], //排除node_modules }, { test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'], //换MiniCssExtractPlugin.loader }, // webpack5新特性 { test: /\.(png|jpg|jpeg|gif)$/i, type: 'asset/resource', generator: { filename: 'img/[name].[contenthash][ext]', //img文件夹下创建图片 }, }, // 处理html的图片,没有这个loader会报错 { test: /\.html$/, use: ['html-withimg-loader'], }, //webpack5 推荐使用html-loader // { // test: /\.html$/, // loader: 'html-loader', // }, ], }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', //不写模板,自动创建,demo样式可以这样 filename: 'index.html', //重命名 chunks: ['index'], //指定引入 minify: { collapseWhitespace: true, keepClosingSlash: true, removeComments: true, removeRedundantAttributes: true, removeScriptTypeAttributes: true, removeStyleLinkTypeAttributes: true, useShortDoctype: true, }, }), new HtmlWebpackPlugin({ // template: 'search.html', filename: 'search.html', //重命名 chunks: ['search'], //指定引入 minify: { collapseWhitespace: true, keepClosingSlash: true, removeComments: true, removeRedundantAttributes: true, removeScriptTypeAttributes: true, removeStyleLinkTypeAttributes: true, useShortDoctype: true, }, }), new MiniCssExtractPlugin({ filename: 'css/[name].css', }), ],};webpack5推荐html-loader
npm install -D html-loader //webpack5 推荐使用html-loader{ test: /\.html$/, loader: 'html-loader', },使用file-loader处理JS中的图片
JS 中的图片不是“被处理”,而是“被 import 之后交给 loader 处理”
webpack5也不推荐使用,也无需使用,因为asset/resource已经处理了,使用file-loader也会出问题,不要用
安装:
npm install -D file-loader使用
{ test: /\.(png|jpg|jpeg|gif)$/i, use: [ { loader: 'file-loader', options: { name: '[name].[hash].[ext]', outputPath: 'images', }, }, ],}使用url-loader处理图片
url-loader 是 Webpack 4 时代非常经典的图片 loader,但现在已经基本被 Webpack5 的 Asset Modules 取代了。
webpack5替代方案
{ test: /\.(png|jpg|jpeg|gif)$/i, type: 'asset', parser: { dataUrlCondition: { maxSize: 10 * 1024 // 10kb以下转base64 } }}使用webpack-dev-server搭建开发环境
-
让 webpack 在内存里打包 + 自动刷新浏览器 + 支持热更新
-
如果不用它,现在是这样开发:
写代码 → npx webpack → 打包到 dist → 手动刷新浏览器 -
用了 dev-server:
写代码 → 自动编译 → 浏览器自动更新(不用刷新) -
安装
npm install -D webpack-dev-server -
使用
devServer: {static: {directory: path.join(__dirname, 'dist'),},port: 8080,open: true,hot: true,},
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!














