视频加载失败

Babel与webpack

2583 字
13 分钟
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

创建源码:

src/index.js
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-demo
cd webpack-demo
npm 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 webpack
node dist/bundle.js

entry和output#

  • webpacke的4核心概念:entry、output、loader、plugins
  • entry输入:就是程序入口
  • output输出:打包之后路径

loader#

Loader 的作用:让 Webpack 能“读懂”非 JS 文件

试试babel-loader,ES6 → ES5

npm i -D babel-loader
const 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、打包分析、注入环境变量

区别:

对比LoaderPlugin
作用转换文件扩展功能
作用范围单个模块整个构建流程
时机加载阶段编译生命周期
写法rulesplugins

举例: 清理 dist,插件clean-webpack-plugin ,每次打包前清空 dist目录

npm install --save-dev clean-webpack-plugin
const { 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-plugin
const 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-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',
    // },
    {
    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,
    },

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

Babel与webpack
https://f.youzi177.cn/posts/2026102202babel-yu-webpack/
作者
小封鸭
发布于
2026-10-21
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
小封鸭
小楼一夜听春雨,深巷明朝卖杏花
公告
欢迎来到我的博客。这里主要记录前端全栈和日常内容
分类
标签
最新动态
站点统计
文章
60
分类
3
标签
12
总字数
107,734
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
EdgeOne Pages
博客版本
Firefly v6.16.8
文章许可
CC BY-NC-SA 4.0
文章目录