chst365's blog chst365's blog
首页
  • Git
  • 网络
  • 操作系统
  • 浏览器
  • webpack
  • JavaScript
  • TypeScript
  • 性能
  • 工程化
  • React
  • 编程题
  • React技术揭秘
  • 算法
  • Node
  • 编码解码
  • NodeJS系列
  • Linux系列
  • JavaScript系列
  • HTTP系列
  • GIT系列
  • ES6系列
  • 设计模式系列
  • CSS系列
  • 小程序系列
  • 数据结构与算法系列
  • React系列
  • Vue3系列
  • Vue系列
  • TypeScript系列
  • Webpack系列
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

chst365

DIV工程师
首页
  • Git
  • 网络
  • 操作系统
  • 浏览器
  • webpack
  • JavaScript
  • TypeScript
  • 性能
  • 工程化
  • React
  • 编程题
  • React技术揭秘
  • 算法
  • Node
  • 编码解码
  • NodeJS系列
  • Linux系列
  • JavaScript系列
  • HTTP系列
  • GIT系列
  • ES6系列
  • 设计模式系列
  • CSS系列
  • 小程序系列
  • 数据结构与算法系列
  • React系列
  • Vue3系列
  • Vue系列
  • TypeScript系列
  • Webpack系列
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 浏览器

  • webpack

    • 一、基础篇:webpack与构建发展简史
    • 二、基础篇:webpack 基础用法
      • 1. 核心概念
        • 1.1 Entry
      • 1.2 Output
      • 1.3 Loaders
        • 常见的 Loaders 有哪些?
        • Loaders 的用法
      • 1.4 plugins
        • 常见的 Plugins 有哪些?
        • Plugins 的用法
      • 1.5 Mode
        • Mode 的内置函数功能
      • 1.6 解析 ES6
        • 资源解析:增加 ES6 的 babel preset 配置
      • 1.7 解析 React JSX
      • 1.8 解析 CSS
      • 1.9 解析 Less 和 SaSS
      • 1.10 解析图片、字体
        • file-loader 用于处理文件
        • url-loader 也可以处理图片和字体
      • 1.11 webpack 中的文件监听
        • 文件监听的原理分析
      • 1.12 热更新
        • webpack-dev-server
        • webpack-dev-middleware
        • 热更新的原理分析
      • 1.13 文件指纹策略:chunkhash、contenthash 和 hash
        • 什么是文件指纹?
        • 文件指纹如何生成
        • JS 的文件指纹设置
        • CSS 的文件指纹设置
        • 图片的文件指纹设置
      • 1.14 HTML、CSS 和 JS 代码压缩
        • 代码压缩
        • JS 文件的压缩
        • CSS 文件的压缩
        • HTML 文件的压缩
    • 三、基础篇:webpack 进阶用法
    • 四、进阶篇:编写可维护的 webpack 构建配置
    • 五、进阶篇:webpack 构建速度和体积优化策略
  • TypeScript

  • 性能

  • 工程化

  • React

  • JavaScript

  • 编程题

  • React技术揭秘

  • 算法

  • 前端
  • webpack
chst365
2020-05-30
目录

二、基础篇:webpack 基础用法

# 二、基础篇:webpack 基础用法

# 1. 核心概念

# 1.1 Entry

Entry 用来指定 webpack 的打包入口

# 理解依赖图的含义

依赖图的入口是 entry 对于非代码比如图片、字体依赖也会不断加入到依赖图中 -w722

# Entry 的用法

  • 单入口:entry 是一个字符串
    module.exports = {
        entry: './path/to/my/entry/file.js'
    };
    
    1
    2
    3
  • 多入口:entry 是一个对象
    module.exports = {
        entry: {
            app: './src/app.js',
            adminApp: './src/adminApp.js'
        }
    };
    
    1
    2
    3
    4
    5
    6

# 1.2 Output

Output 用来告诉 webpack 如何将编译后的文件输出到磁盘

# Output 的用法

  • 单入口配置

    module.exports = {
        entry: './path/to/my/entry/file.js',
        output: {
            filename: 'bundle.js',
            path: __dirname + '/dist'
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
  • 多入口配置

    module.exports = {
        entry: {
            app: './src/app.js',
            search: './src/search.js'
        },
        output: {
            filename: '[name].js',          //  通过占位符确保文件名称的唯一
            path: __dirname + '/dist'
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

# 1.3 Loaders

webpack 开箱即用只支持 JS 和 JSON 两种文件类型,通过 Loaders 去支持其他文件类型并且把它们转化成有效的模块,并且可以添加到依赖图中。

本身是一个函数,接受源文件作为参数,返回转换的结果。

# 常见的 Loaders 有哪些?

名称 描述
babel-loader 转换 ES6、ES7 等 JS 新特性语法
css-loader 支持.css 文件的加载和解析
less-loader 将 less 文件转换成 css
ts-loader 将 Ts 转换成 JS
file-loader 进行图片、字体等的打包
raw-loader 将文件以字符串的形式导入
thread-loader 多进程打包 JS 和 CSS

# Loaders 的用法

const path = require('path');

module.exports = {
    output: {
        filename: 'bundle.js'
    },
    module: {
        rules: [
            { test: /\.txt$/, use: 'raw-loader' }       // test 指定匹配规则   use 指定使用的 loader 名称
        ]
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

# 1.4 plugins

插件用于 bundle 文件的优化,资源管理和环境变量注入

作用于整个构建过程

# 常见的 Plugins 有哪些?

名称 描述
CommonsChunkPlugin 将 chunks 相同的模块代码提前成公共 js
CleanWebpackPlugin 清理构建目录
ExtractTextWebpackPlugin 将 CSS 从 bundle 文件里提取成一个独立的 CSS 文件
CopyWebpackPlugin 将文件或者文件夹拷贝到输出目录
HtmlWebpackPlugin 创建 html 文件去承载输出的 bundle
UglifyjsWebpackPlugin 压缩 JS
ZipWebpackPlugin 将打包出的资源生成一个 zip 包

# Plugins 的用法

const path = require('path');
module.exports = {
    output: {
        filename: 'bundle.js'
    },
    plugins: [
        new HtmlWebpackPlugin({templatee: './src/index.html'})          // 放到 plugins 数组里
    ]
}
1
2
3
4
5
6
7
8
9

# 1.5 Mode

Mode 用来指定当前的构建环境是:production、development 还是 none 设置 mode 可以使用 webpack 内置的函数,默认值为 production

# Mode 的内置函数功能

选型 描述
development 设置 process.env.NODE_ENV 的值为 development .开启 NamedChunksPlugin 和 NamedModulesPlugin .
production 设置 process.env.NODE_ENV 的值为 production .开启 FlagDependencyUsagePlugin,FlagIncludedChunksPlugin,ModuleConcatenationPlugin,NoEmitOnErrorsPlugin,OccurrenceOrderPlguin,SideEffectsFlagPlugin 和 TerserPlugin
none 不开启任何优化选型

# 1.6 解析 ES6

使用 babel-loader babel 的配置文件是:.babelrc

const path = require('path');
module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                use: 'babel-loader'
            }
        ]
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 资源解析:增加 ES6 的 babel preset 配置

{
    "presets": [
        "@babel/preset-env"                 // 增加 ES6 的 babel preset 配置
    ],
    "plugins": [
        "@babel/proposal-class-properties"
    ]
}
1
2
3
4
5
6
7
8

# 1.7 解析 React JSX

{
    "presets": [
        "@babel/preset-env",
        "@babel/preset-react"                   // 增加 React 的 babel preset 配置
    ],
    "plugins": [
        "@babel/proposal-class-properties"
    ]
}
1
2
3
4
5
6
7
8
9

# 1.8 解析 CSS

css-loader 用于加载 .css 文件,并且转换成 commonjs 对象 style-loader 将样式通过<style>标签插入到 head 中

const path = require('path');
module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    'css-loader'
                ]
            }
        ]
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 1.9 解析 Less 和 SaSS

less-loader 用于将 less 转换成 css

const path = require('path');
module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    'css-loader',
                    'less-loader'
                ]
            }
        ]
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 1.10 解析图片、字体

# file-loader 用于处理文件

const path = require('path');
module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    module: {
        rules: [
            // 解析图片
            {
                test: /\.(png|svg|jpg|gif)$/,
                use: [
                    'file-loader'
                ]
            },
            // 解析字体
            {
                test: /\.(woff|woff2|eot|ttf|otf)$/,
                use: [
                    'file-loader'
                ]
            },
        ]
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# url-loader 也可以处理图片和字体

可以设置较小资源自动 base64

const path = require('path');
module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    module: {
        rules: [
            // 解析图片
            {
                test: /\.(png|svg|jpg|gif)$/,
                use: [{
                    loader: 'url-loader',
                    options: {
                        limit: 10240
                    }
                }]
            },
            // 解析字体
            {
                test: /\.(woff|woff2|eot|ttf|otf)$/,
                use: [
                    'file-loader'
                ]
            },
        ]
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# 1.11 webpack 中的文件监听

文件监听是在发现源码发生变化时,自动重新构建出新的输出文件。 webpack 开启监听模式,有两种方式:

  • 启动 webpack 命令时,带上 --watch 参数
  • 在配置 webpack.config.js 中设置 watch: true
{
"name": "hello-webpack",
"version": "1.0.0",
"description": "Hello webpack",
"main": "index.js",
"scripts": {
"build": "webpack ",
+ "watch": "webpack --watch"
},
"keywords": [],
"author": "",
"license": "ISC"
}
1
2
3
4
5
6
7
8
9
10
11
12
13

唯一缺陷: 每次需要手动刷新浏览器

# 文件监听的原理分析

轮询判断文件的最后编辑时间是否变化 某个文件发生了变化,并不会立刻告诉监听者,而是先缓存起来,等 aggregateTimeout

module.export = {
//默认 false,也就是不不开启
watch: true, //只有开启监听模式时,watchOptions才有意义 wathcOptions: {
//默认为空,不监听的文件或者文件夹,支持正则匹配
ignored: /node_modules/,
//监听到变化发生后会等300ms再去执行,默认300ms
aggregateTimeout: 300, //判断文件是否发生变化是通过不停询问系统指定文件有没有变化实现的,默认每秒问1000次 poll: 1000
} }
1
2
3
4
5
6
7
8

# 1.12 热更新

# webpack-dev-server

WDS 不刷新浏览器 WDS 不输出文件,而是放在内存中 使用 HotModuleReplacementPlugin 插件

{
"name": "hello-webpack",
"version": "1.0.0",
"description": "Hello webpack",
"main": "index.js",
"scripts": {
"build": "webpack ",
"dev": "webpack-dev-server --open"
},
"keywords": [],
"author": "",
"license": "ISC"
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# webpack-dev-middleware

WDM 将 webpack 输出的文件传输给服务器 适用于灵活的定制场景

const express = require('express');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');

const app = express();
const config = require('./webpack.config.js');
const compiler = webpack(config);

app.use(webpackDevMiddleware(compiler, {
    publicPath: config.output.publicPath
}));

app.listen(3000, function () {
    console.log('Example app listening on port 3000\n');
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 热更新的原理分析

Webpack Compile: 将 JS 编译成 Bundle HMR Server: 将热更新的文件输出给 HMR Rumtime Bundle server: 提供文件在浏览器的访问 HMR Rumtime: 会被注入到浏览器,更新文件的变化 bundle.js: 构建输出的文件 -w713

# 1.13 文件指纹策略:chunkhash、contenthash 和 hash

# 什么是文件指纹?

打包后输出的文件名的后缀 -w865

# 文件指纹如何生成

Hash: 和整个项目的构建相关,只要项目文件有修改,整个项目构建的 hash 值就会更改 Chunkhash: 和 webpack 打包的 chunk 有关,不同的 entry 会生成不同的 chunkhash 值 Contenthash: 根据文件内容来定义 hash,文件内容不变,则 contenthash 不变

# JS 的文件指纹设置

设置 output 的 filename,使用 [chunkhash]

module.exports = {
    entry: {
        app: './src/app.js',
        search: './src/search.js'
    },
    output: {
        filename: '[name][chunkhash:8].js',
        path: __dirname + '/dist'
    }
}
1
2
3
4
5
6
7
8
9
10

# CSS 的文件指纹设置

设置 MiniCssExtractPlugin 的 filename, 使用 [contenthash]

module.exports = {
    entry: {
        app: './src/app.js',
        search: './src/search.js'
    },
    output: {
        filename: '[name][chunkhash:8].js',
        path: __dirname + '/dist'
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: `[name][contenthash:8].css`
        });
    ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 图片的文件指纹设置

设置 file-loader 的 name,使用 [hash]

占位符名称 含义
[ext] 资源后缀名
[name] 文件名称
[path] 文件的相对路径
[folder] 文件所在的文件夹
[contenthash] 文件的内容 hash,默认是 md5 生成
[hash] 文件内容的 hash,默认是 md5 生成
[emoji] 一个随机的指代文件内容的 emoj
const path = require('path');
module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    module: {
        rules: [
            {
                test: /\.(png|svg|jpg|gif)$/,
                use: [{
                    loader: 'file-loader',
                    options: {
                        name: 'img/[name][hash:8].[ext]'
                    }
                }]
            }
        ]
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 1.14 HTML、CSS 和 JS 代码压缩

# 代码压缩

  • HTML 压缩
  • CSS 压缩
  • JS 压缩 -w628

# JS 文件的压缩

内置了 uglifyjs-webpack-plugin

# CSS 文件的压缩

使用 optimize-css-assets-webpack-plugin 同时使用 cssnano

module.exports = {
    entry: {
        app: './src/app.js',
        search: './src/search.js'
    },
    output: {
        filename: '[name][chunkhash:8].js',
        path: __dirname + '/dist'
    },
    plugins: [
        new OptimizeCSSAssetsPlugin({
            assetNameRegExp: /\.css$/g,
            cssProcessor: require('cssnano')
        })
    ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# HTML 文件的压缩

修改 html-webpack-plugin,设置压缩参数

module.exports = {
    entry: {
        app: './src/app.js',
        search: './src/search.js'
    },
    output: {
        filename: '[name][chunkhash:8].js',
        path: __dirname + '/dist'
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: path.join(__dirname, 'src/search.html'),
            filename: 'search.html',
            chunks: ['search' ],
            inject: true,
            minify: {
                html5: true,
                collapseWhitespace: true,
                preservelLinBreaks: false,
                minifyCSS: true,
                minifyJS: true,
                removeComments: false
            }
        })
    ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#工程化#webpack
上次更新: 2021/09/14, 13:59:36
一、基础篇:webpack与构建发展简史
三、基础篇:webpack 进阶用法

← 一、基础篇:webpack与构建发展简史 三、基础篇:webpack 进阶用法→

最近更新
01
面试官
03-27
02
this&指针&作用域&闭包
03-27
03
前端
03-27
更多文章>
Theme by Vdoing | Copyright © 2019-2025 chst365 | 豫ICP备17031889号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式